Index: docs/LanguageExtensions.rst
===================================================================
--- docs/LanguageExtensions.rst	(revision 204924)
+++ docs/LanguageExtensions.rst	(working copy)
@@ -112,10 +112,18 @@
 ``__has_attribute``
 -------------------
 
-This function-like macro takes a single identifier argument that is the name of
-an attribute.  It evaluates to 1 if the attribute is supported by the current
-compilation target, or 0 if not.  It can be used like this:
+This function-like macro determines whether an attribute is supported by the 
+current compilation target, depending on the syntax used for the attribute.  It 
+evaluates to 1 if the attribute is supported, or 0 if not.
 
+Supported attribute syntaxes are: GNU-style ``__attribute__((ident))``, 
+C++11-style ``[[ident]]`` and ``[[scope::ident]]``, and Microsoft Visual Studio-
+style ``__declspec(ident)``.  If the exact syntax is not important, or if the 
+attribute is implemented as a keyword, a single identifier argument is also 
+accepted.
+
+It can be used like this:
+
 .. code-block:: c++
 
   #ifndef __has_attribute         // Optional of course.
@@ -127,13 +135,31 @@
   #define ALWAYS_INLINE __attribute__((always_inline))
   #else
   #define ALWAYS_INLINE
+  #endif  
+  ...
+  #if __has_attribute(__attribute__((dllexport)))
+    void foo(void) __attribute__((dllexport));
+  #elif __has_attribute(__declspec(dllexport))
+    __declspec(dllexport) void foo(void);
   #endif
   ...
+  #if __has_attribute([[clang::fallthrough]])
+  #define FALLTHROUGH [[clang::fallthrough]]
+  #else
+  #define FALLTHROUGH
+  #endif
 
+
 The attribute name can also be specified with a preceding and following ``__``
 (double underscore) to avoid interference from a macro with the same name.  For
-instance, ``__always_inline__`` can be used instead of ``always_inline``.
+instance, ``__always_inline__`` can be used instead of ``always_inline``.  For 
+C++11-style attributes, the name can be bracketed with double underscores, but 
+the scope cannot.
 
+You can test whether the extended-syntax form of ``__has_attribute`` is
+supported using the feature-test macro: ``__has_feature(__has_attribute_syntax)``. 
+If the extended-syntax is not supported, only the single identifier form of
+``__has_attribute`` is supported.
 
 Include File Checking Macros
 ============================
Index: include/clang/Basic/Attributes.h
===================================================================
--- include/clang/Basic/Attributes.h	(revision 0)
+++ include/clang/Basic/Attributes.h	(working copy)
@@ -0,0 +1,39 @@
+//===--- Attributes.h - Attributes header -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ATTRIBUTES_H
+#define LLVM_CLANG_BASIC_ATTRIBUTES_H
+
+#include "llvm/ADT/Triple.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+enum class AttrSyntax {
+  /// Is the attribute identifier generally known for any syntax?
+  Generic,
+  /// Is the identifier known as a GNU-style attribute?
+  GNU,
+  /// Is the identifier known as a __declspec-style attribute?
+  Declspec,
+  // Is the identifier known as a C++-style attribute?
+  CXX
+};
+
+/// HasAttribute -  Return true if we recognize and implement the attribute
+/// specified by the given identifier.
+bool HasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+                  const IdentifierInfo *Attr, const llvm::Triple &T,
+                  const LangOptions &LangOpts);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_ATTRIBUTES_H
Index: include/clang/Basic/CMakeLists.txt
===================================================================
--- include/clang/Basic/CMakeLists.txt	(revision 204924)
+++ include/clang/Basic/CMakeLists.txt	(working copy)
@@ -28,6 +28,12 @@
   SOURCE Attr.td
   TARGET ClangAttrList)
 
+clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE Attr.td
+  TARGET ClangAttrHasAttributeImpl
+  )
+
 # ARM NEON
 clang_tablegen(arm_neon.inc -gen-arm-neon-sema
   SOURCE arm_neon.td
Index: include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- include/clang/Basic/DiagnosticLexKinds.td	(revision 204924)
+++ include/clang/Basic/DiagnosticLexKinds.td	(working copy)
@@ -396,6 +396,8 @@
 
 def err_feature_check_malformed : Error<
   "builtin feature check macro requires a parenthesized identifier">;
+def warn_attribute_feature_check_unknown : Warning<
+  "unsupported attribute feature check syntax">, InGroup<UnknownAttributes>;
 
 def err_warning_check_malformed : Error<
   "builtin warning check macro requires a parenthesized string">;
Index: include/clang/Basic/Makefile
===================================================================
--- include/clang/Basic/Makefile	(revision 204924)
+++ include/clang/Basic/Makefile	(working copy)
@@ -6,6 +6,7 @@
 	DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
 	DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
 	DiagnosticSerializationKinds.inc \
+	AttrHasAttributeImpl.inc \
 	DiagnosticIndexName.inc DiagnosticGroups.inc AttrList.inc arm_neon.inc \
 	Version.inc
 
@@ -48,6 +49,12 @@
 	$(Verb) $(ClangTableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \
 	  -I $(PROJ_SRC_DIR)/../.. $<
 
+$(ObjDir)/AttrHasAttributeImpl.inc.tmp : Attr.td $(CLANG_TBLGEN) \
+                                  $(ObjDir)/.dir
+	$(Echo) "Building Clang __has_attribute implementation with tblgen"
+	$(Verb) $(ClangTableGen) -gen-clang-attr-has-attribute-impl -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
 $(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir
 	$(Echo) "Building Clang arm_neon.inc with tblgen"
 	$(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $<
Index: include/clang/CMakeLists.txt
===================================================================
--- include/clang/CMakeLists.txt	(revision 204924)
+++ include/clang/CMakeLists.txt	(working copy)
@@ -1,7 +1,6 @@
 add_subdirectory(AST)
 add_subdirectory(Basic)
 add_subdirectory(Driver)
-add_subdirectory(Lex)
 add_subdirectory(Parse)
 add_subdirectory(Sema)
 add_subdirectory(Serialization)
Index: include/clang/Lex/CMakeLists.txt
===================================================================
--- include/clang/Lex/CMakeLists.txt	(revision 204924)
+++ include/clang/Lex/CMakeLists.txt	(working copy)
@@ -1,5 +0,0 @@
-clang_tablegen(AttrSpellings.inc -gen-clang-attr-spelling-list
-  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
-  SOURCE ../Basic/Attr.td
-  TARGET ClangAttrSpellings
-  )
Index: include/clang/Lex/Makefile
===================================================================
--- include/clang/Lex/Makefile	(revision 204924)
+++ include/clang/Lex/Makefile	(working copy)
@@ -1,13 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrSpellings.inc 
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/AttrSpellings.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
-                                  $(ObjDir)/.dir
-	$(Echo) "Building Clang attribute spellings with tblgen"
-	$(Verb) $(ClangTableGen) -gen-clang-attr-spelling-list -o $(call SYSPATH, $@) \
-		-I $(PROJ_SRC_DIR)/../../ $<
Index: include/clang/Makefile
===================================================================
--- include/clang/Makefile	(revision 204924)
+++ include/clang/Makefile	(working copy)
@@ -1,5 +1,5 @@
 CLANG_LEVEL := ../..
-DIRS := AST Basic Driver Lex Parse Sema Serialization
+DIRS := AST Basic Driver Parse Sema Serialization
 
 include $(CLANG_LEVEL)/Makefile
 
Index: lib/Basic/Attributes.cpp
===================================================================
--- lib/Basic/Attributes.cpp	(revision 0)
+++ lib/Basic/Attributes.cpp	(working copy)
@@ -0,0 +1,22 @@
+#include "clang/Basic/Attributes.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace clang {
+
+/// HasAttribute -  Return true if we recognize and implement the attribute
+/// specified by the given identifier.
+bool HasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+                         const IdentifierInfo *Attr, const llvm::Triple &T,
+                         const LangOptions &LangOpts) {
+  StringRef Name = Attr->getName();
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
+    Name = Name.substr(2, Name.size() - 4);
+
+#include "clang/Basic/AttrHasAttributeImpl.inc"
+
+  return false;
+}
+
+} // end namespace clang
Index: lib/Basic/CMakeLists.txt
===================================================================
--- lib/Basic/CMakeLists.txt	(revision 204924)
+++ lib/Basic/CMakeLists.txt	(working copy)
@@ -4,6 +4,7 @@
   )
 
 add_clang_library(clangBasic
+  Attributes.cpp
   Builtins.cpp
   CharInfo.cpp
   Diagnostic.cpp
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp	(revision 204924)
+++ lib/Lex/PPMacroExpansion.cpp	(working copy)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/Attributes.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -882,6 +883,7 @@
            .Case("attribute_overloadable", true)
            .Case("attribute_unavailable_with_message", true)
            .Case("attribute_unused_on_fields", true)
+           .Case("__has_attribute_syntax", true)
            .Case("blocks", LangOpts.Blocks)
            .Case("c_thread_safety_attributes", true)
            .Case("cxx_exceptions", LangOpts.Exceptions)
@@ -1047,20 +1049,6 @@
            .Default(false);
 }
 
-/// HasAttribute -  Return true if we recognize and implement the attribute
-/// specified by the given identifier.
-static bool HasAttribute(const IdentifierInfo *II, const llvm::Triple &T) {
-  StringRef Name = II->getName();
-  // Normalize the attribute name, __foo__ becomes foo.
-  if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
-    Name = Name.substr(2, Name.size() - 4);
-
-  // FIXME: Do we need to handle namespaces here?
-  return llvm::StringSwitch<bool>(Name)
-#include "clang/Lex/AttrSpellings.inc"
-        .Default(false);
-}
-
 /// EvaluateHasIncludeCommon - Process a '__has_include("path")'
 /// or '__has_include_next("path")' expression.
 /// Returns true if successful.
@@ -1369,10 +1357,131 @@
     // __COUNTER__ expands to a simple numeric value.
     OS << CounterValue++;
     Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__has_attribute) {
+    // __has_attribute specifies the attribute syntax desired in one of four
+    // ways: __declspec, __attribute__, [[]] (in C++11 mode), and generically
+    // via a single identifier.
+    SourceLocation StartLoc = Tok.getLocation();
+    bool IsValid = false;
+    bool ShouldErr = false;
+    AttrSyntax Syntax;
+    IdentifierInfo *Feature = 0, *Scope = 0;
+
+    // Read the opening paren.
+    LexUnexpandedToken(Tok);
+    if (Tok.is(tok::l_paren)) {
+      // Read the next token to determine what syntax is desired.
+      bool ShouldLexRParen = false;
+      LexUnexpandedToken(Tok);
+      if (Tok.is(tok::kw___attribute)) {
+        Syntax = AttrSyntax::GNU;
+
+        // Lex the two open parens, followed by anything we can get an
+        // IdentifierInfo out of, and two right parens. Note that we do not
+        // support attribute arguments.
+        LexUnexpandedToken(Tok);
+        if (Tok.is(tok::l_paren)) {
+          LexUnexpandedToken(Tok);
+          if (Tok.is(tok::l_paren)) {
+            LexUnexpandedToken(Tok);
+            if (Feature = Tok.getIdentifierInfo()) {
+              LexUnexpandedToken(Tok);
+              if (Tok.is(tok::r_paren)) {
+                LexUnexpandedToken(Tok);
+                ShouldLexRParen = Tok.is(tok::r_paren);
+              }
+            }
+          }
+        }
+      } else if (Tok.is(tok::kw___declspec)) {
+        Syntax = AttrSyntax::Declspec;
+
+        // Lex the open paren, followed by anything we can get an
+        // IdentifierInfo out of, and a right paren. Note that we do not
+        // support attribute arguments.
+        LexUnexpandedToken(Tok);
+        if (Tok.is(tok::l_paren)) {
+          LexUnexpandedToken(Tok);
+          if (Feature = Tok.getIdentifierInfo()) {
+            LexUnexpandedToken(Tok);
+            ShouldLexRParen = Tok.is(tok::r_paren);
+          }
+        }
+      } else if (Tok.is(tok::l_square)) {
+        Syntax = AttrSyntax::CXX;
+
+        // Lex the second open square bracket, followed by anything we can get
+        // an IdentifierInfo out of, and two right square brackets for the
+        // simple case. However, it can also have a scope specified.
+        LexUnexpandedToken(Tok);
+        if (Tok.is(tok::l_square)) {
+          LexUnexpandedToken(Tok);
+          if (Feature = Tok.getIdentifierInfo()) {
+            LexUnexpandedToken(Tok);
+            // If there's a ::, then we just lexed the Scope and not the
+            // Feature. Otherwise, we expect a ].
+            if (Tok.is(tok::coloncolon)) {
+              Scope = Feature;
+              LexUnexpandedToken(Tok);
+              Feature = Tok.getIdentifierInfo();
+
+              // Lex what we hope is the start of the closing square brackets.
+              LexUnexpandedToken(Tok);
+            }            
+            if (Tok.is(tok::r_square)) {
+              LexUnexpandedToken(Tok);
+              ShouldLexRParen = Tok.is(tok::r_square);
+            }
+          }
+        }
+      } else {
+        // Generic attribute syntax requires something we can get an
+        // IdentifierInfo out of, and nothing more.
+        Syntax = AttrSyntax::Generic;
+        if (Feature = Tok.getIdentifierInfo())
+          ShouldLexRParen = true;
+      }
+
+      if (ShouldLexRParen) {
+        // If the right paren is missing, the feature test itself has an
+        // invalid form that we want to err on.
+        LexUnexpandedToken(Tok);
+        if (Tok.is(tok::r_paren))
+          IsValid = true;
+        else
+          ShouldErr = true;
+      } else {
+        // Eat tokens until ')'.
+        while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eod) &&
+               Tok.isNot(tok::eof))
+          LexUnexpandedToken(Tok);
+      }
+    } else
+      // If the left paren is missing, the feature test itself has an invalid
+      // form that we want to err on.
+      ShouldErr = true;
+
+    // If the attribute is invalid, we will warn that this syntax is
+    // unsupported, but not emit an error for it. This allows us to be forward-
+    // compatible with future attribute syntaxes.
+    bool Value = false;
+    if (!IsValid) {
+      Diag(StartLoc, ShouldErr ? diag::err_feature_check_malformed :
+                                 diag::warn_attribute_feature_check_unknown);
+      Value = 0;
+    } else
+      Value = HasAttribute(Syntax, Scope, Feature,
+                            getTargetInfo().getTriple(),
+                            getLangOpts());
+
+    // If we did not emit an error, then the current token needs to be replaced
+    // with a numeric constant.
+    OS << (int)Value;
+    if (!ShouldErr)
+      Tok.setKind(tok::numeric_constant);
   } else if (II == Ident__has_feature   ||
              II == Ident__has_extension ||
-             II == Ident__has_builtin   ||
-             II == Ident__has_attribute) {
+             II == Ident__has_builtin) {
     // The argument to these builtins should be a parenthesized identifier.
     SourceLocation StartLoc = Tok.getLocation();
 
@@ -1395,11 +1504,9 @@
     bool Value = false;
     if (!IsValid)
       Diag(StartLoc, diag::err_feature_check_malformed);
-    else if (II == Ident__has_builtin) {
+    else if (II == Ident__has_builtin)
       // Check for a builtin is trivial.
       Value = FeatureII->getBuiltinID() != 0;
-    } else if (II == Ident__has_attribute)
-      Value = HasAttribute(FeatureII, getTargetInfo().getTriple());
     else if (II == Ident__has_extension)
       Value = HasExtension(*this, FeatureII);
     else {
Index: test/Preprocessor/has_attribute.c
===================================================================
--- test/Preprocessor/has_attribute.c	(revision 204924)
+++ test/Preprocessor/has_attribute.c	(working copy)
@@ -48,3 +48,35 @@
 #if !__has_attribute(dllexport)
   int does_not_have_dllexport();
 #endif
+
+// CHECK: has_gnu_weakref
+#if __has_attribute(__attribute__((weakref)))
+  int has_gnu_weakref();
+#endif
+
+// CHECK: does_not_have_gnu_selectany
+#if !__has_attribute(__attribute__((selectany)))
+  int does_not_have_gnu_selectany();
+#endif
+
+// Because we're in C mode, there are no C++11-style attribute features.
+// CHECK: does_not_have_cxx11_carries_dep
+#if !__has_attribute([[carries_dependency]])
+  int does_not_have_cxx11_carries_dep();
+#endif
+
+// CHECK: has_declspec_selectany
+#if __has_attribute(__declspec(selectany))
+  int has_declspec_selectany();
+#endif
+
+// CHECK: does_not_have_declspec_weak_ref
+#if !__has_attribute(__declspec(weak_ref))
+  int does_not_have_declspec_weak_ref();
+#endif
+
+// CHECK: does_not_have_bad_syntax
+#if !__has_attribute([bad_syntax]) // expected-warning {{unsupported attribute feature check syntax}}
+  // Unknown syntax implies an unsupported attribute.
+  int does_not_have_bad_syntax();
+#endif
Index: test/Preprocessor/has_attribute.cpp
===================================================================
--- test/Preprocessor/has_attribute.cpp	(revision 0)
+++ test/Preprocessor/has_attribute.cpp	(working copy)
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -E %s -o - | FileCheck %s
+
+// CHECK: has_cxx11_carries_dep
+#if __has_attribute([[carries_dependency]])
+  int has_cxx11_carries_dep();
+#endif
+
+// CHECK: has_clang_fallthrough
+#if __has_attribute([[clang::fallthrough]])
+  int has_clang_fallthrough();
+#endif
+
+// CHECK: does_not_have_selectany
+#if !__has_attribute([[selectany]])
+  int does_not_have_selectany();
+#endif
+
+// The attribute name can be bracketed with double underscores.
+// CHECK: has_clang_fallthrough_2
+#if __has_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_attribute([[__clang__::fallthrough]])
+  int does_not_have___clang___fallthrough();
+#endif
+
+// Test that C++11, target-specific attributes behave properly.
+// CHECK: does_not_have_mips16
+#if !__has_attribute([[gnu::mips16]])
+  int does_not_have_mips16();
+#endif
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp	(revision 204924)
+++ utils/TableGen/ClangAttrEmitter.cpp	(working copy)
@@ -1720,22 +1720,16 @@
   OS << "  }\n";
 }
 
-// Emits the list of spellings for attributes.
-void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("llvm::StringSwitch code to match attributes based on "
-                       "the target triple, T", OS);
-
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-  
-  for (auto I : Attrs) {
-    Record &Attr = *I;
-
+static void GenerateHasAttrSpellingStringSwitch(
+    const std::vector<Record *> &Attrs, raw_ostream &OS,
+    const std::string &Variety = "", const std::string &Scope = "") {
+  for (const auto *Attr : Attrs) {
     // It is assumed that there will be an llvm::Triple object named T within
     // scope that can be used to determine whether the attribute exists in
     // a given target.
     std::string Test;
-    if (Attr.isSubClassOf("TargetSpecificAttr")) {
-      const Record *R = Attr.getValueAsDef("Target");
+    if (Attr->isSubClassOf("TargetSpecificAttr")) {
+      const Record *R = Attr->getValueAsDef("Target");
       std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
 
       Test += "(";
@@ -1760,15 +1754,81 @@
         }
         Test += ")";
       }
-    } else
+      
+      // If this is the C++11 variety, also add in the LangOpts test.
+      if (Variety == "CXX11")
+        Test += " && LangOpts.CPlusPlus11";      
+    } else if (Variety == "CXX11")
+      // C++11 mode should be checked against LangOpts, which is presumed to be
+      // present in the caller.
+      Test = "LangOpts.CPlusPlus11";
+    else
       Test = "true";
 
-    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
     for (const auto &S : Spellings)
-      OS << ".Case(\"" << S.name() << "\", " << Test << ")\n";
+      if (Variety.empty() || (Variety == S.variety() &&
+                              (Scope.empty() || Scope == S.nameSpace())))
+        OS << "    .Case(\"" << S.name() << "\", " << Test << ")\n";
   }
+  OS << "    .Default(false);\n";
 }
 
+// Emits the list of spellings for attributes.
+void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader("Code to implement the __has_attribute logic", OS);
+
+  // Separate all of the attributes out into four group: generic, C++11, GNU,
+  // and declspecs. Then generate a big switch statement for each of them.
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::vector<Record *> Declspec, GNU;
+  std::map<std::string, std::vector<Record *>> CXX;
+
+  // Walk over the list of all attributes, and split them out based on the
+  // spelling variety.
+  for (auto *R : Attrs) {
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
+    for (const auto &SI : Spellings) {
+      std::string Variety = SI.variety();
+      if (Variety == "GNU")
+        GNU.push_back(R);
+      else if (Variety == "Declspec")
+        Declspec.push_back(R);
+      else if (Variety == "CXX11") {
+        CXX[SI.nameSpace()].push_back(R);
+      }
+    }
+  }
+
+  OS << "switch (Syntax) {\n";
+  OS << "case AttrSyntax::Generic:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(Attrs, OS);
+  OS << "case AttrSyntax::GNU:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU");
+  OS << "case AttrSyntax::Declspec:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
+  OS << "case AttrSyntax::CXX: {\n";
+  // C++11-style attributes are further split out based on the Scope.
+  for (std::map<std::string, std::vector<Record *>>::iterator I = CXX.begin(),
+                                                              E = CXX.end();
+       I != E; ++I) {
+    if (I != CXX.begin())
+      OS << " else ";
+    if (I->first.empty())
+      OS << "if (!Scope || Scope->getName() == \"\") {\n";
+    else
+      OS << "if (Scope->getName() == \"" << I->first << "\") {\n";
+    OS << "  return llvm::StringSwitch<bool>(Name)\n";
+    GenerateHasAttrSpellingStringSwitch(I->second, OS, "CXX11", I->first);
+    OS << "}";
+  }
+  OS << "\n}\n";
+  OS << "}\n";
+}
+
 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Code to translate different attribute spellings "
                        "into internal identifiers", OS);
Index: utils/TableGen/TableGen.cpp
===================================================================
--- utils/TableGen/TableGen.cpp	(revision 204924)
+++ utils/TableGen/TableGen.cpp	(working copy)
@@ -29,7 +29,7 @@
   GenClangAttrList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
-  GenClangAttrSpellingList,
+  GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
   GenClangAttrASTVisitor,
   GenClangAttrTemplateInstantiate,
@@ -72,7 +72,8 @@
                    "Generate clang PCH attribute reader"),
         clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
                    "Generate clang PCH attribute writer"),
-        clEnumValN(GenClangAttrSpellingList, "gen-clang-attr-spelling-list",
+        clEnumValN(GenClangAttrHasAttributeImpl,
+                   "gen-clang-attr-has-attribute-impl",
                    "Generate a clang attribute spelling list"),
         clEnumValN(GenClangAttrSpellingListIndex,
                    "gen-clang-attr-spelling-index",
@@ -159,8 +160,8 @@
   case GenClangAttrPCHWrite:
     EmitClangAttrPCHWrite(Records, OS);
     break;
-  case GenClangAttrSpellingList:
-    EmitClangAttrSpellingList(Records, OS);
+  case GenClangAttrHasAttributeImpl:
+    EmitClangAttrHasAttrImpl(Records, OS);
     break;
   case GenClangAttrSpellingListIndex:
     EmitClangAttrSpellingListIndex(Records, OS);
Index: utils/TableGen/TableGenBackends.h
===================================================================
--- utils/TableGen/TableGenBackends.h	(revision 204924)
+++ utils/TableGen/TableGenBackends.h	(working copy)
@@ -35,7 +35,7 @@
 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS);
