Handle C++11 attribute namespaces automatically.

Now, as long as the 'Namespaces' variable is correct inside Attr.td, the
generated code will correctly admit a C++11 attribute only when it has the
appropriate namespace(s).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158661 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index 8e70293..93f8c5d 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -95,13 +95,15 @@
                                       SourceLocation TokLoc, int Arg) {
   Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
                                       C.IntTy, TokLoc);
-  return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 0);
+  return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1,
+                AttributeList::AS_GNU);
 }
 
 #include "clang/Sema/AttrParsedAttrKinds.inc"
 
 AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
-                                           const IdentifierInfo *ScopeName) {
+                                           const IdentifierInfo *ScopeName,
+                                           Syntax SyntaxUsed) {
   StringRef AttrName = Name->getName();
 
   // Normalize the attribute name, __foo__ becomes foo.
@@ -109,10 +111,14 @@
       AttrName.size() >= 4)
     AttrName = AttrName.substr(2, AttrName.size() - 4);
 
-  // FIXME: implement attribute namespacing correctly.
   SmallString<64> Buf;
   if (ScopeName)
-    AttrName = ((Buf += ScopeName->getName()) += "___") += AttrName;
+    Buf += ScopeName->getName();
+  // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
+  // unscoped.
+  if (ScopeName || SyntaxUsed == AS_CXX11)
+    Buf += "::";
+  Buf += AttrName;
 
-  return ::getAttrKind(AttrName);
+  return ::getAttrKind(Buf);
 }
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 912d7c6..60b2d1e 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -48,7 +48,7 @@
 static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
                                   SourceRange Range) {
   switch (A.getKind()) {
-  case AttributeList::AT_clang___fallthrough:
+  case AttributeList::AT_fallthrough:
     return handleFallThroughAttr(S, St, A, Range);
   default:
     // if we're here, then we parsed an attribute, but didn't recognize it as a
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 2ad5bcb..0bdf75b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2728,8 +2728,7 @@
     .create(&S.Context.Idents.get("objc_ownership"), SourceLocation(),
             /*scope*/ 0, SourceLocation(),
             &S.Context.Idents.get(attrStr), SourceLocation(),
-            /*args*/ 0, 0,
-            /*declspec*/ false, /*C++0x*/ false);
+            /*args*/ 0, 0, AttributeList::AS_GNU);
   spliceAttrIntoList(*attr, chunk.getAttrListRef());
 
   // TODO: mark whether we did this inference?