The attached patch refactors a string switch table about attributes into
the Attrs.td file. Any behaviour change is incidental (ie., the table was
out of sync before this change), this is a refactoring.

Please review!

Nick
Index: lib/Parse/CMakeLists.txt
===================================================================
--- lib/Parse/CMakeLists.txt	(revision 192945)
+++ lib/Parse/CMakeLists.txt	(working copy)
@@ -18,6 +18,7 @@
 add_dependencies(clangParse
   ClangAttrClasses
   ClangAttrExprArgs
+  ClangAttrGNUAttrs
   ClangAttrLateParsed
   ClangAttrList
   ClangAttrParsedAttrList
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp	(revision 192945)
+++ lib/Parse/Parser.cpp	(working copy)
@@ -23,6 +23,7 @@
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
+#include "clang/Parse/AttrGNUAttrs.inc"
 
 namespace {
 /// \brief A comment handler that passes comments found by the preprocessor
@@ -979,7 +980,7 @@
   if (Tok.isNot(tok::equal)) {
     AttributeList *DtorAttrs = D.getAttributes();
     while (DtorAttrs) {
-      if (!IsThreadSafetyAttribute(DtorAttrs->getName()->getName()) &&
+      if (IsGCCAttribute(DtorAttrs->getName()->getName()) &&
           !DtorAttrs->isCXX11Attribute()) {
         Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition)
           << DtorAttrs->getName()->getName();
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp	(revision 192945)
+++ lib/Parse/ParseDecl.cpp	(working copy)
@@ -27,6 +27,8 @@
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
 
+#include "clang/Parse/AttrGNUAttrs.inc"
+
 //===----------------------------------------------------------------------===//
 // C99 6.7: Declarations.
 //===----------------------------------------------------------------------===//
@@ -1052,7 +1054,7 @@
   // Consume the previously pushed token.
   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
 
-  if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
+  if (OnDefinition && IsGCCAttribute(LA.AttrName.getName())) {
     // FIXME: Do not warn on C++11 attributes, once we start supporting
     // them here.
     Diag(Tok, diag::warn_attribute_on_function_definition)
Index: include/clang/Parse/CMakeLists.txt
===================================================================
--- include/clang/Parse/CMakeLists.txt	(revision 192945)
+++ include/clang/Parse/CMakeLists.txt	(working copy)
@@ -3,6 +3,11 @@
   SOURCE ../Basic/Attr.td
   TARGET ClangAttrExprArgs)
 
+clang_tablegen(AttrGNUAttrs.inc -gen-clang-attr-gnu-attrs-list
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE ../Basic/Attr.td
+  TARGET ClangAttrGNUAttrs)
+
 clang_tablegen(AttrLateParsed.inc -gen-clang-attr-late-parsed-list
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE ../Basic/Attr.td
Index: include/clang/Parse/Makefile
===================================================================
--- include/clang/Parse/Makefile	(revision 192945)
+++ include/clang/Parse/Makefile	(working copy)
@@ -1,6 +1,6 @@
 CLANG_LEVEL := ../../..
 TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrExprArgs.inc AttrLateParsed.inc
+BUILT_SOURCES = AttrExprArgs.inc AttrGNUAttrs.inc AttrLateParsed.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
@@ -12,8 +12,14 @@
 	$(Verb) $(ClangTableGen) -gen-clang-attr-expr-args-list -o $(call SYSPATH, $@) \
 		-I $(PROJ_SRC_DIR)/../../ $<
 
+$(ObjDir)/AttrGNUAttrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+                                   $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute table of GNU attributes with tblgen"
+	$(Verb) $(ClangTableGen) -gen-clang-attr-gnu-attrs-list -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
 $(ObjDir)/AttrLateParsed.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
                                    $(ObjDir)/.dir
 	$(Echo) "Building Clang attribute late-parsed table with tblgen"
 	$(Verb) $(ClangTableGen) -gen-clang-attr-late-parsed-list -o $(call SYSPATH, $@) \
-		-I $(PROJ_SRC_DIR)/../../ $<
\ No newline at end of file
+		-I $(PROJ_SRC_DIR)/../../ $<
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td	(revision 192945)
+++ include/clang/Basic/Attr.td	(working copy)
@@ -117,6 +117,8 @@
   list<Argument> Args = [];
   // Accessors which should be generated for the attribute.
   list<Accessor> Accessors = [];
+  // Set to true for attributes which are defined by GCC.
+  bit GCC = 0;
   // Set to true for attributes with arguments which require delayed parsing.
   bit LateParsed = 0;
   // Set to false to prevent an attribute from being propagated from a template
@@ -176,6 +178,7 @@
 def Alias : InheritableAttr {
   let Spellings = [GNU<"alias">, CXX11<"gnu", "alias">];
   let Args = [StringArgument<"Aliasee">];
+  let GCC = 1;
 }
 
 def Aligned : InheritableAttr {
@@ -188,6 +191,7 @@
                    Accessor<"isAlignas", [Keyword<"alignas">,
                                           Keyword<"_Alignas">]>,
                    Accessor<"isDeclspec",[Declspec<"align">]>];
+  let GCC = 1;
 }
 
 def AlignMac68k : InheritableAttr {
@@ -198,16 +202,19 @@
 def AllocSize : InheritableAttr {
   let Spellings = [GNU<"alloc_size">, CXX11<"gnu", "alloc_size">];
   let Args = [VariadicUnsignedArgument<"Args">];
+  let GCC = 1;
 }
 
 def AlwaysInline : InheritableAttr {
   let Spellings = [GNU<"always_inline">, CXX11<"gnu", "always_inline">];
+  let GCC = 1;
 }
 
 def TLSModel : InheritableAttr {
   let Spellings = [GNU<"tls_model">, CXX11<"gnu", "tls_model">];
   let Subjects = [Var];
   let Args = [StringArgument<"Model">];
+  let GCC = 1;
 }
 
 def AnalyzerNoReturn : InheritableAttr {
@@ -266,6 +273,7 @@
 def CDecl : InheritableAttr {
   let Spellings = [GNU<"cdecl">, CXX11<"gnu", "cdecl">, Keyword<"__cdecl">,
                    Keyword<"_cdecl">];
+  let GCC = 1;
 }
 
 // cf_audited_transfer indicates that the given function has been
@@ -303,23 +311,29 @@
 def Cleanup : InheritableAttr {
   let Spellings = [GNU<"cleanup">, CXX11<"gnu", "cleanup">];
   let Args = [FunctionArgument<"FunctionDecl">];
+  let GCC = 1;
 }
 
 def Cold : InheritableAttr {
   let Spellings = [GNU<"cold">, CXX11<"gnu", "cold">];
+  let GCC = 1;
 }
 
 def Common : InheritableAttr {
   let Spellings = [GNU<"common">, CXX11<"gnu", "common">];
+  let GCC = 1;
 }
 
 def Const : InheritableAttr {
-  let Spellings = [GNU<"const">, GNU<"__const">, CXX11<"gnu", "const">];
+  let Spellings = [GNU<"const">, GNU<"__const">, CXX11<"gnu", "const">,
+	           CXX11<"gnu", "__const">];
+  let GCC = 1;
 }
 
 def Constructor : InheritableAttr {
   let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">];
   let Args = [IntArgument<"Priority", 1>];
+  let GCC = 1;
 }
 
 def CUDAConstant : InheritableAttr {
@@ -371,11 +385,13 @@
   let Spellings = [GNU<"deprecated">,
                    CXX11<"gnu", "deprecated">, CXX11<"","deprecated">];
   let Args = [StringArgument<"Message", 1>];
+  let GCC = 1;
 }
 
 def Destructor : InheritableAttr {
   let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">];
   let Args = [IntArgument<"Priority", 1>];
+  let GCC = 1;
 }
 
 def ExtVectorType : Attr {
@@ -392,6 +408,7 @@
 def FastCall : InheritableAttr {
   let Spellings = [GNU<"fastcall">, CXX11<"gnu", "fastcall">,
                    Keyword<"__fastcall">, Keyword<"_fastcall">];
+  let GCC = 1;
 }
 
 def Final : InheritableAttr {
@@ -409,19 +426,23 @@
   let Spellings = [GNU<"format">, CXX11<"gnu", "format">];
   let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
               IntArgument<"FirstArg">];
+  let GCC = 1;
 }
 
 def FormatArg : InheritableAttr {
   let Spellings = [GNU<"format_arg">, CXX11<"gnu", "format_arg">];
   let Args = [IntArgument<"FormatIdx">];
+  let GCC = 1;
 }
 
 def GNUInline : InheritableAttr {
   let Spellings = [GNU<"gnu_inline">, CXX11<"gnu", "gnu_inline">];
+  let GCC = 1;
 }
 
 def Hot : InheritableAttr {
   let Spellings = [GNU<"hot">, CXX11<"gnu", "hot">];
+  let GCC = 1;
 }
 
 def IBAction : InheritableAttr {
@@ -439,6 +460,7 @@
 
 def Malloc : InheritableAttr {
   let Spellings = [GNU<"malloc">, CXX11<"gnu", "malloc">];
+  let GCC = 1;
 }
 
 def MaxFieldAlignment : InheritableAttr {
@@ -449,10 +471,12 @@
 
 def MayAlias : InheritableAttr {
   let Spellings = [GNU<"may_alias">, CXX11<"gnu", "may_alias">];
+  let GCC = 1;
 }
 
 def MSABI : InheritableAttr {
   let Spellings = [GNU<"ms_abi">, CXX11<"gnu", "ms_abi">];
+  let GCC = 1;
 }
 
 def MSP430Interrupt : InheritableAttr, TargetSpecificAttr {
@@ -464,15 +488,18 @@
 def Mips16 : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GNU<"mips16">, CXX11<"gnu", "mips16">];
   let Subjects = [Function];
+  let GCC = 1;
 }
 
 def Mode : Attr {
   let Spellings = [GNU<"mode">, CXX11<"gnu", "mode">];
   let Args = [IdentifierArgument<"Mode">];
+  let GCC = 1;
 }
 
 def Naked : InheritableAttr {
   let Spellings = [GNU<"naked">, CXX11<"gnu", "naked">];
+  let GCC = 1;
 }
 
 def NeonPolyVectorType : TypeAttr {
@@ -487,10 +514,12 @@
 
 def ReturnsTwice : InheritableAttr {
   let Spellings = [GNU<"returns_twice">, CXX11<"gnu", "returns_twice">];
+  let GCC = 1;
 }
 
 def NoCommon : InheritableAttr {
   let Spellings = [GNU<"nocommon">, CXX11<"gnu", "nocommon">];
+  let GCC = 1;
 }
 
 def NoDebug : InheritableAttr {
@@ -499,11 +528,13 @@
 
 def NoInline : InheritableAttr {
   let Spellings = [GNU<"noinline">, CXX11<"gnu", "noinline">];
+  let GCC = 1;
 }
 
 def NoMips16 : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GNU<"nomips16">, CXX11<"gnu", "nomips16">];
   let Subjects = [Function];
+  let GCC = 1;
 }
 
 def NonNull : InheritableAttr {
@@ -517,22 +548,26 @@
         return true;
     return false;
   } }];
+  let GCC = 1;
 }
 
 def NoReturn : InheritableAttr {
   let Spellings = [GNU<"noreturn">, CXX11<"gnu", "noreturn">];
   // FIXME: Does GCC allow this on the function instead?
   let Subjects = [Function];
+  let GCC = 1;
 }
 
 def NoInstrumentFunction : InheritableAttr {
   let Spellings = [GNU<"no_instrument_function">,
                    CXX11<"gnu", "no_instrument_function">];
   let Subjects = [Function];
+  let GCC = 1;
 }
 
 def NoThrow : InheritableAttr {
   let Spellings = [GNU<"nothrow">, CXX11<"gnu", "nothrow">];
+  let GCC = 1;
 }
 
 def NSBridged : InheritableAttr {
@@ -625,6 +660,7 @@
 
 def Packed : InheritableAttr {
   let Spellings = [GNU<"packed">, CXX11<"gnu", "packed">];
+  let GCC = 1;
 }
 
 def PnaclCall : InheritableAttr {
@@ -640,15 +676,18 @@
   let Args = [EnumArgument<"PCS", "PCSType",
                            ["aapcs", "aapcs-vfp"],
                            ["AAPCS", "AAPCS_VFP"]>];
+  let GCC = 1;
 }
 
 def Pure : InheritableAttr {
   let Spellings = [GNU<"pure">, CXX11<"gnu", "pure">];
+  let GCC = 1;
 }
 
 def Regparm : InheritableAttr {
   let Spellings = [GNU<"regparm">, CXX11<"gnu", "regparm">];
   let Args = [UnsignedArgument<"NumParams">];
+  let GCC = 1;
 }
 
 def ReqdWorkGroupSize : InheritableAttr {
@@ -672,26 +711,31 @@
 def Section : InheritableAttr {
   let Spellings = [GNU<"section">, CXX11<"gnu", "section">];
   let Args = [StringArgument<"Name">];
+  let GCC = 1;
 }
 
 def Sentinel : InheritableAttr {
   let Spellings = [GNU<"sentinel">, CXX11<"gnu", "sentinel">];
   let Args = [DefaultIntArgument<"Sentinel", 0>,
               DefaultIntArgument<"NullPos", 0>];
+  let GCC = 1;
 }
 
 def StdCall : InheritableAttr {
   let Spellings = [GNU<"stdcall">, CXX11<"gnu", "stdcall">,
                    Keyword<"__stdcall">, Keyword<"_stdcall">];
+  let GCC = 1;
 }
 
 def SysVABI : InheritableAttr {
   let Spellings = [GNU<"sysv_abi">, CXX11<"gnu", "sysv_abi">];
+  let GCC = 1;
 }
 
 def ThisCall : InheritableAttr {
   let Spellings = [GNU<"thiscall">, CXX11<"gnu", "thiscall">,
                    Keyword<"__thiscall">, Keyword<"_thiscall">];
+  let GCC = 1;
 }
 
 def Pascal : InheritableAttr {
@@ -700,6 +744,7 @@
 
 def TransparentUnion : InheritableAttr {
   let Spellings = [GNU<"transparent_union">, CXX11<"gnu", "transparent_union">];
+  let GCC = 1;
 }
 
 def Unavailable : InheritableAttr {
@@ -730,10 +775,12 @@
 
 def Unused : InheritableAttr {
   let Spellings = [GNU<"unused">, CXX11<"gnu", "unused">];
+  let GCC = 1;
 }
 
 def Used : InheritableAttr {
   let Spellings = [GNU<"used">, CXX11<"gnu", "used">];
+  let GCC = 1;
 }
 
 def Uuid : InheritableAttr {
@@ -745,6 +792,7 @@
 def VectorSize : TypeAttr {
   let Spellings = [GNU<"vector_size">, CXX11<"gnu", "vector_size">];
   let Args = [ExprArgument<"NumBytes">];
+  let GCC = 1;
 }
 
 def VecTypeHint : InheritableAttr {
@@ -759,6 +807,7 @@
   let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
+  let GCC = 1;
 }
 
 def TypeVisibility : InheritableAttr {
@@ -783,10 +832,12 @@
   let Spellings = [GNU<"warn_unused_result">,
                    CXX11<"clang", "warn_unused_result">,
                    CXX11<"gnu", "warn_unused_result">];
+  let GCC = 1;
 }
 
 def Weak : InheritableAttr {
   let Spellings = [GNU<"weak">, CXX11<"gnu", "weak">];
+  let GCC = 1;
 }
 
 def WeakImport : InheritableAttr {
@@ -797,6 +848,7 @@
   let Spellings = [GNU<"weakref">, CXX11<"gnu", "weakref">];
   // A WeakRef that has an argument is treated as being an AliasAttr
   let Args = [StringArgument<"Aliasee", 1>];
+  let GCC = 1;
 }
 
 def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr {
@@ -806,7 +858,10 @@
 // Attribute to disable AddressSanitizer (or equivalent) checks.
 def NoSanitizeAddress : InheritableAttr {
   let Spellings = [GNU<"no_address_safety_analysis">,
-                   GNU<"no_sanitize_address">];
+                   GNU<"no_sanitize_address">,
+                   CXX11<"gnu", "no_address_safety_analysis">,
+                   CXX11<"gnu", "no_sanitize_address">];
+  let GCC = 1;
 }
 
 // Attribute to disable ThreadSanitizer checks.
@@ -1031,14 +1086,17 @@
 
 def MsStruct : InheritableAttr {
   let Spellings = [Declspec<"ms_struct">];
+  let GCC = 1;
 }
 
 def DLLExport : InheritableAttr, TargetSpecificAttr {
   let Spellings = [Declspec<"dllexport">];
+  let GCC = 1;
 }
 
 def DLLImport : InheritableAttr, TargetSpecificAttr {
   let Spellings = [Declspec<"dllimport">];
+  let GCC = 1;
 }
 
 def ForceInline : InheritableAttr {
@@ -1047,6 +1105,7 @@
 
 def SelectAny : InheritableAttr {
   let Spellings = [Declspec<"selectany">];
+  let GCC = 1;
 }
 
 def Win64 : InheritableAttr {
Index: utils/TableGen/TableGen.cpp
===================================================================
--- utils/TableGen/TableGen.cpp	(revision 192945)
+++ utils/TableGen/TableGen.cpp	(working copy)
@@ -25,6 +25,7 @@
 enum ActionType {
   GenClangAttrClasses,
   GenClangAttrExprArgsList,
+  GenClangAttrGNUAttrsList,
   GenClangAttrImpl,
   GenClangAttrList,
   GenClangAttrPCHRead,
@@ -63,6 +64,8 @@
         clEnumValN(GenClangAttrExprArgsList, "gen-clang-attr-expr-args-list",
                    "Generate a clang attribute expression "
                    "arguments list"),
+        clEnumValN(GenClangAttrGNUAttrsList, "gen-clang-attr-gnu-attrs-list",
+                   "Generate a clang attribute list of GNU attributes"),
         clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
                    "Generate clang attribute implementations"),
         clEnumValN(GenClangAttrList, "gen-clang-attr-list",
@@ -144,6 +147,9 @@
   case GenClangAttrExprArgsList:
     EmitClangAttrExprArgsList(Records, OS);
     break;
+  case GenClangAttrGNUAttrsList:
+    EmitClangAttrGNUAttrsList(Records, OS);
+    break;
   case GenClangAttrImpl:
     EmitClangAttrImpl(Records, OS);
     break;
Index: utils/TableGen/TableGenBackends.h
===================================================================
--- utils/TableGen/TableGenBackends.h	(revision 192945)
+++ utils/TableGen/TableGenBackends.h	(working copy)
@@ -31,6 +31,7 @@
 
 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrExprArgsList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrGNUAttrsList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp	(revision 192945)
+++ utils/TableGen/ClangAttrEmitter.cpp	(working copy)
@@ -906,7 +906,7 @@
     "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
     "    break;\n";
 
-  for (unsigned I = 0; I < Spellings.size(); ++ I) {
+  for (unsigned I = 0; I < Spellings.size(); ++I) {
     llvm::SmallString<16> Prefix;
     llvm::SmallString<8> Suffix;
     // The actual spelling of the name and namespace (if applicable)
@@ -1207,6 +1207,45 @@
   }
 }
 
+void EmitClangAttrGNUAttrsList(RecordKeeper &Records, raw_ostream &OS) {
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  OS << "  static bool IsGCCAttribute(StringRef AttrName) {\n";
+  OS << "    return llvm::StringSwitch<bool>(AttrName)";
+  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
+       I != E; ++I) {
+    Record &R = **I;
+    if (!R.getValueAsBit("GCC"))
+      continue;
+
+    std::vector<std::string> GNUNames;
+    std::vector<std::string> CXX11Names;
+
+    std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
+    for (std::vector<Record*>::iterator
+             SI = Spellings.begin(), SE = Spellings.end(); SI != SE; ++SI) {
+      if ((*SI)->getValueAsString("Variety") == "CXX11") {
+        if ((*SI)->getValueAsString("Namespace") == "gnu")
+          CXX11Names.push_back((*SI)->getValueAsString("Name"));
+      } else if ((*SI)->getValueAsString("Variety") == "GNU") {
+        GNUNames.push_back((*SI)->getValueAsString("Name"));
+      }
+    }
+    std::sort(GNUNames.begin(), GNUNames.end());
+    std::sort(CXX11Names.begin(), CXX11Names.end());
+    assert(GNUNames.size() == CXX11Names.size() &&
+           "For GCC attributes, GNU spellings must match CXX11 spellings.");
+    for (unsigned i = 0, e = GNUNames.size(); i != e; ++i) {
+      assert(GNUNames[i] == CXX11Names[i] &&
+             "For GCC attributes, GNU spellings must match CXX11 spellings");
+      OS << "        .Case(\"" << GNUNames[i] << "\", true)\n";
+    }
+
+  }
+  OS << "        .Default(false);\n";
+  OS << "  }\n";
+}
+
 // Emits the class method definitions for attributes.
 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute classes' member function definitions", OS);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to