Support accepting __gnu__ as a scoped attribute namespace that aliases to gnu.

This is useful in libstdc++ to avoid clashes with identifiers in the user's namespace.

llvm-svn: 345132
diff --git a/clang/test/Preprocessor/has_attribute.cpp b/clang/test/Preprocessor/has_attribute.cpp
index 2cfa005..53d1fb0 100644
--- a/clang/test/Preprocessor/has_attribute.cpp
+++ b/clang/test/Preprocessor/has_attribute.cpp
@@ -18,17 +18,21 @@
 // The attribute name can be bracketed with double underscores.
 // CHECK: has_clang_fallthrough_2
 #if __has_cpp_attribute(clang::__fallthrough__)
-  int has_clang_fallthrough_2();
-#endif
-
-// The scope cannot be bracketed with double underscores.
-// CHECK: does_not_have___clang___fallthrough
-#if !__has_cpp_attribute(__clang__::fallthrough)
-  int does_not_have___clang___fallthrough();
-#endif
-
-// Test that C++11, target-specific attributes behave properly.
-
+  int has_clang_fallthrough_2();

+#endif

+

+// The scope cannot be bracketed with double underscores unless it is for gnu.

+// CHECK: does_not_have___clang___fallthrough

+#if !__has_cpp_attribute(__clang__::fallthrough)

+  int does_not_have___clang___fallthrough();

+#endif

+// CHECK: has_gnu_const

+#if __has_cpp_attribute(__gnu__::__const__)

+  int has_gnu_const();

+#endif

+

+// Test that C++11, target-specific attributes behave properly.

+

 // CHECK: does_not_have_mips16
 #if !__has_cpp_attribute(gnu::mips16)
   int does_not_have_mips16();
diff --git a/clang/test/SemaCXX/attr-gnu.cpp b/clang/test/SemaCXX/attr-gnu.cpp
index a553f0d..9eb4234 100644
--- a/clang/test/SemaCXX/attr-gnu.cpp
+++ b/clang/test/SemaCXX/attr-gnu.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -fms-compatibility -verify %s
-
-void f() {
-  // GNU-style attributes are prohibited in this position.
+// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -fms-compatibility -verify %s

+

+void f() {

+  // GNU-style attributes are prohibited in this position.

   auto P = new int * __attribute__((vector_size(8))); // expected-error {{an attribute list cannot appear here}} \
                                                       // expected-error {{invalid vector element type 'int *'}}
 
@@ -40,6 +40,13 @@
 void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}}
 void tu() {
   int x = 2;
-  tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}}
-  tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}}
-}
+  tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}}

+  tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}}

+}

+

+[[gnu::__const__]] int f2() { return 12; }

+[[__gnu__::__const__]] int f3() { return 12; }

+[[using __gnu__ : __const__]] int f4() { return 12; }

+

+static_assert(__has_cpp_attribute(gnu::__const__));

+static_assert(__has_cpp_attribute(__gnu__::__const__));