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/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index abca58d..7e1eaf8 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/StringMatcher.h"
@@ -1128,6 +1129,8 @@
     if (SemaHandler || Ignored) {
       std::vector<StringRef> Spellings =
         getValueAsListOfStrings(Attr, "Spellings");
+      std::vector<StringRef> Namespaces =
+        getValueAsListOfStrings(Attr, "Namespaces");
 
       for (std::vector<StringRef>::const_iterator I = Spellings.begin(),
            E = Spellings.end(); I != E; ++I) {
@@ -1136,16 +1139,35 @@
                                                  : Spellings.front());
         StringRef Spelling = NormalizeAttrSpelling(*I);
 
+        for (std::vector<StringRef>::const_iterator NI = Namespaces.begin(),
+             NE = Namespaces.end(); NI != NE; ++NI) {
+          SmallString<64> Buf;
+          Buf += *NI;
+          Buf += "::";
+          Buf += Spelling;
+
+          if (SemaHandler)
+            Matches.push_back(
+              StringMatcher::StringPair(
+                Buf.str(),
+                "return AttributeList::AT_" + AttrName.str() + ";"));
+          else
+            Matches.push_back(
+              StringMatcher::StringPair(
+                Buf.str(),
+                "return AttributeList::IgnoredAttribute;"));
+        }
+
         if (SemaHandler)
           Matches.push_back(
             StringMatcher::StringPair(
               Spelling,
-              std::string("return AttributeList::AT_")+AttrName.str() + ";"));
+              "return AttributeList::AT_" + AttrName.str() + ";"));
         else
           Matches.push_back(
             StringMatcher::StringPair(
               Spelling,
-              std::string("return AttributeList::IgnoredAttribute;")));
+              "return AttributeList::IgnoredAttribute;"));
       }
     }
   }