Skip to content

Commit 8ee40b7

Browse files
committed
Attribute tablegen now understands that attribute arguments can be optional. This allows for automated checking of the number of arguments expected vs number of arguments given for attributes. Greatly reduces the amount of manual checking required.
llvm-svn: 190368
1 parent 6c88b35 commit 8ee40b7

File tree

10 files changed

+238
-271
lines changed

10 files changed

+238
-271
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,39 +42,40 @@ def NonBitField : SubsetSubject<Field, "non-bit field",
4242
[{!S->isBitField()}]>;
4343

4444
// A single argument to an attribute
45-
class Argument<string name> {
45+
class Argument<string name, bit optional> {
4646
string Name = name;
47+
bit Optional = optional;
4748
}
4849

49-
class BoolArgument<string name> : Argument<name>;
50-
class IdentifierArgument<string name> : Argument<name>;
51-
class IntArgument<string name> : Argument<name>;
52-
class StringArgument<string name> : Argument<name>;
53-
class ExprArgument<string name> : Argument<name>;
54-
class FunctionArgument<string name> : Argument<name>;
55-
class TypeArgument<string name> : Argument<name>;
56-
class UnsignedArgument<string name> : Argument<name>;
57-
class SourceLocArgument<string name> : Argument<name>;
58-
class VariadicUnsignedArgument<string name> : Argument<name>;
59-
class VariadicExprArgument<string name> : Argument<name>;
50+
class BoolArgument<string name, bit opt = 0> : Argument<name, opt>;
51+
class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>;
52+
class IntArgument<string name, bit opt = 0> : Argument<name, opt>;
53+
class StringArgument<string name, bit opt = 0> : Argument<name, opt>;
54+
class ExprArgument<string name, bit opt = 0> : Argument<name, opt>;
55+
class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>;
56+
class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
57+
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
58+
class SourceLocArgument<string name, bit opt = 0> : Argument<name, opt>;
59+
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
60+
class VariadicExprArgument<string name> : Argument<name, 1>;
6061

6162
// A version of the form major.minor[.subminor].
62-
class VersionArgument<string name> : Argument<name>;
63+
class VersionArgument<string name, bit opt = 0> : Argument<name, opt>;
6364

6465
// This one's a doozy, so it gets its own special type
6566
// It can be an unsigned integer, or a type. Either can
6667
// be dependent.
67-
class AlignedArgument<string name> : Argument<name>;
68+
class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>;
6869

6970
// An integer argument with a default value
70-
class DefaultIntArgument<string name, int default> : IntArgument<name> {
71+
class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
7172
int Default = default;
7273
}
7374

7475
// This argument is more complex, it includes the enumerator type name,
7576
// a list of strings to accept, and a list of enumerators to map them to.
7677
class EnumArgument<string name, string type, list<string> values,
77-
list<string> enums> : Argument<name> {
78+
list<string> enums, bit opt = 0> : Argument<name, opt> {
7879
string Type = type;
7980
list<string> Values = values;
8081
list<string> Enums = enums;
@@ -122,6 +123,10 @@ class Attr {
122123
bit Ignored = 0;
123124
// Set to true if each of the spellings is a distinct attribute.
124125
bit DistinctSpellings = 0;
126+
// Set to true if the attribute's parsing does not match its semantic
127+
// content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of
128+
// common attribute error checking.
129+
bit HasCustomParsing = 0;
125130
// Any additional text that should be included verbatim in the class.
126131
code AdditionalMembers = [{}];
127132
}
@@ -168,7 +173,7 @@ def Aligned : InheritableAttr {
168173
let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">,
169174
Keyword<"alignas">, Keyword<"_Alignas">];
170175
let Subjects = [NonBitField, NormalVar, Tag];
171-
let Args = [AlignedArgument<"Alignment">];
176+
let Args = [AlignedArgument<"Alignment", 1>];
172177
let Accessors = [Accessor<"isGNU", [GNU<"aligned">, CXX11<"gnu","aligned">]>,
173178
Accessor<"isC11", [Keyword<"_Alignas">]>,
174179
Accessor<"isAlignas", [Keyword<"alignas">,
@@ -223,6 +228,7 @@ def Availability : InheritableAttr {
223228
.Case("macosx", "OS X")
224229
.Default(llvm::StringRef());
225230
} }];
231+
let HasCustomParsing = 1;
226232
}
227233

228234
def Blocks : InheritableAttr {
@@ -296,7 +302,7 @@ def Const : InheritableAttr {
296302

297303
def Constructor : InheritableAttr {
298304
let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">];
299-
let Args = [IntArgument<"Priority">];
305+
let Args = [IntArgument<"Priority", 1>];
300306
}
301307

302308
def CUDAConstant : InheritableAttr {
@@ -346,12 +352,12 @@ def OpenCLImageAccess : Attr {
346352

347353
def Deprecated : InheritableAttr {
348354
let Spellings = [GNU<"deprecated">, CXX11<"gnu", "deprecated">];
349-
let Args = [StringArgument<"Message">];
355+
let Args = [StringArgument<"Message", 1>];
350356
}
351357

352358
def Destructor : InheritableAttr {
353359
let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">];
354-
let Args = [IntArgument<"Priority">];
360+
let Args = [IntArgument<"Priority", 1>];
355361
}
356362

357363
def ExtVectorType : Attr {
@@ -409,7 +415,7 @@ def IBOutlet : InheritableAttr {
409415

410416
def IBOutletCollection : InheritableAttr {
411417
let Spellings = [GNU<"iboutletcollection">];
412-
let Args = [TypeArgument<"Interface">, SourceLocArgument<"InterfaceLoc">];
418+
let Args = [TypeArgument<"Interface", 1>, SourceLocArgument<"InterfaceLoc">];
413419
}
414420

415421
def Malloc : InheritableAttr {
@@ -513,7 +519,7 @@ def NoThrow : InheritableAttr {
513519
def NSBridged : InheritableAttr {
514520
let Spellings = [GNU<"ns_bridged">];
515521
let Subjects = [Record];
516-
let Args = [IdentifierArgument<"BridgedType">];
522+
let Args = [IdentifierArgument<"BridgedType", 1>];
517523
}
518524

519525
def NSReturnsRetained : InheritableAttr {
@@ -678,7 +684,7 @@ def TransparentUnion : InheritableAttr {
678684

679685
def Unavailable : InheritableAttr {
680686
let Spellings = [GNU<"unavailable">];
681-
let Args = [StringArgument<"Message">];
687+
let Args = [StringArgument<"Message", 1>];
682688
}
683689

684690
def ArcWeakrefUnavailable : InheritableAttr {
@@ -724,6 +730,7 @@ def VectorSize : TypeAttr {
724730
def VecTypeHint : InheritableAttr {
725731
let Spellings = [GNU<"vec_type_hint">];
726732
let Args = [TypeArgument<"TypeHint">, SourceLocArgument<"TypeLoc">];
733+
let HasCustomParsing = 1;
727734
}
728735

729736
def Visibility : InheritableAttr {
@@ -768,6 +775,8 @@ def WeakImport : InheritableAttr {
768775

769776
def WeakRef : InheritableAttr {
770777
let Spellings = [GNU<"weakref">, CXX11<"gnu", "weakref">];
778+
// A WeakRef that has an argument is treated as being an AliasAttr
779+
let Args = [StringArgument<"Aliasee", 1>];
771780
}
772781

773782
def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr {
@@ -969,6 +978,7 @@ def ArgumentWithTypeTag : InheritableAttr {
969978
UnsignedArgument<"TypeTagIdx">,
970979
BoolArgument<"IsPointer">];
971980
let Subjects = [Function];
981+
let HasCustomParsing = 1;
972982
}
973983

974984
def TypeTagForDatatype : InheritableAttr {
@@ -978,6 +988,7 @@ def TypeTagForDatatype : InheritableAttr {
978988
BoolArgument<"LayoutCompatible">,
979989
BoolArgument<"MustBeNull">];
980990
let Subjects = [Var];
991+
let HasCustomParsing = 1;
981992
}
982993

983994
// Microsoft-related attributes

clang/include/clang/Sema/AttributeList.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ class AttributeList { // TODO: This should really be called ParsedAttribute
463463
/// defined in Attr.td. This index is used by an attribute
464464
/// to pretty print itself.
465465
unsigned getAttributeSpellingListIndex() const;
466+
467+
bool hasCustomParsing() const;
468+
unsigned getMinArgs() const;
469+
unsigned getMaxArgs() const;
466470
};
467471

468472
/// A factory, from which one makes pools, from which one creates

clang/include/clang/Sema/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index
1717
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
1818
SOURCE ../Basic/Attr.td
1919
TARGET ClangAttrSpellingListIndex)
20+
21+
clang_tablegen(AttrParsedAttrImpl.inc -gen-clang-attr-parsed-attr-impl
22+
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
23+
SOURCE ../Basic/Attr.td
24+
TARGET ClangAttrParsedAttrImpl)

clang/lib/Sema/AttributeList.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,28 @@ unsigned AttributeList::getAttributeSpellingListIndex() const {
145145

146146
}
147147

148+
struct ParsedAttrInfo {
149+
unsigned NumArgs : 4;
150+
unsigned OptArgs : 4;
151+
unsigned HasCustomParsing : 1;
152+
};
153+
154+
namespace {
155+
#include "clang/Sema/AttrParsedAttrImpl.inc"
156+
}
157+
158+
const ParsedAttrInfo& getInfo(const AttributeList& A) {
159+
return AttrInfoMap[A.getKind()];
160+
}
161+
162+
unsigned AttributeList::getMinArgs() const {
163+
return getInfo(*this).NumArgs;
164+
}
165+
166+
unsigned AttributeList::getMaxArgs() const {
167+
return getMinArgs() + getInfo(*this).OptArgs;
168+
}
169+
170+
bool AttributeList::hasCustomParsing() const {
171+
return getInfo(*this).HasCustomParsing;
172+
}

clang/lib/Sema/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ add_dependencies(clangSema
6060
ClangAttrList
6161
ClangAttrParsedAttrList
6262
ClangAttrParsedAttrKinds
63+
ClangAttrParsedAttrImpl
6364
ClangAttrSpellingListIndex
6465
ClangAttrTemplateInstantiate
6566
ClangCommentNodes

0 commit comments

Comments
 (0)