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