Add ParsedAttrInfo::handleDeclAttribute

This makes it possible for plugin attributes to actually do something, and also
removes a lot of boilerplate for simple attributes in SemaDeclAttr.cpp.

Differential Revision: https://reviews.llvm.org/D31342
This commit is contained in:
John Brawn 2020-02-28 14:51:30 +00:00
parent 9adc7fc3cd
commit fa0320dd8d
7 changed files with 144 additions and 173 deletions

View File

@ -63,6 +63,53 @@ registering it using ``PragmaHandlerRegistry::Add<>``:
static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description"); static PragmaHandlerRegistry::Add<ExamplePragmaHandler> Y("example_pragma","example pragma description");
Defining attributes
===================
Plugins can define attributes by declaring a ``ParsedAttrInfo`` and registering
it using ``ParsedAttrInfoRegister::Add<>``:
.. code-block:: c++
class ExampleAttrInfo : public ParsedAttrInfo {
public:
ExampleAttrInfo() {
Spellings.push_back({ParsedAttr::AS_GNU,"example"});
}
AttrHandling handleDeclAttribute(Sema &S, Decl *D,
const ParsedAttr &Attr) const override {
// Handle the attribute
return AttributeApplied;
}
};
static ParsedAttrInfoRegistry::Add<ExampleAttrInfo> Z("example_attr","example attribute description");
The members of ``ParsedAttrInfo`` that a plugin attribute must define are:
* ``Spellings``, which must be populated with every `Spelling
</doxygen/structclang_1_1ParsedAttrInfo_1_1Spelling.html>`_ of the
attribute, each of which consists of an attribute syntax and how the
attribute name is spelled for that syntax. If the syntax allows a scope then
the spelling must be "scope::attr" if a scope is present or "::attr" if not.
* ``handleDeclAttribute``, which is the function that applies the attribute to
a declaration. It is responsible for checking that the attribute's arguments
are valid, and typically applies the attribute by adding an ``Attr`` to the
``Decl``. It returns either ``AttributeApplied``, to indicate that the
attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't.
The members of ``ParsedAttrInfo`` that may need to be defined, depending on the
attribute, are:
* ``NumArgs`` and ``OptArgs``, which set the number of required and optional
arguments to the attribute.
* ``diagAppertainsToDecl``, which checks if the attribute has been used on the
right kind of declaration and issues a diagnostic if not.
* ``diagLangOpts``, which checks if the attribute is permitted for the current
language mode and issues a diagnostic if not.
* ``existsInTarget``, which checks if the attribute is permitted for the given
target.
Putting it all together Putting it all together
======================= =======================

View File

@ -2455,6 +2455,9 @@ Attributes that do not require custom semantic handling should set the
attributes are assumed to use a semantic handler by default. Attributes attributes are assumed to use a semantic handler by default. Attributes
without a semantic handler are not given a parsed attribute ``Kind`` enumerator. without a semantic handler are not given a parsed attribute ``Kind`` enumerator.
"Simple" attributes, that require no custom semantic processing aside from what
is automatically provided, should set the ``SimpleHandler`` field to ``1``.
Target-specific attributes may share a spelling with other attributes in Target-specific attributes may share a spelling with other attributes in
different targets. For instance, the ARM and MSP430 targets both have an different targets. For instance, the ARM and MSP430 targets both have an
attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic
@ -2481,12 +2484,11 @@ Boilerplate
All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp
<https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaDeclAttr.cpp>`_, <https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaDeclAttr.cpp>`_,
and generally starts in the ``ProcessDeclAttribute()`` function. If the and generally starts in the ``ProcessDeclAttribute()`` function. If the
attribute is a "simple" attribute -- meaning that it requires no custom semantic attribute has the ``SimpleHandler`` field set to ``1`` then the function to
processing aside from what is automatically provided, add a call to process the attribute will be automatically generated, and nothing needs to be
``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the switch statement. done here. Otherwise, write a new ``handleYourAttr()`` function, and add that to
Otherwise, write a new ``handleYourAttr()`` function, and add that to the switch the switch statement. Please do not implement handling logic directly in the
statement. Please do not implement handling logic directly in the ``case`` for ``case`` for the attribute.
the attribute.
Unless otherwise specified by the attribute definition, common semantic checking Unless otherwise specified by the attribute definition, common semantic checking
of the parsed attribute is handled automatically. This includes diagnosing of the parsed attribute is handled automatically. This includes diagnosing

View File

@ -513,6 +513,8 @@ class Attr {
bit ASTNode = 1; bit ASTNode = 1;
// Set to true for attributes which have handler in Sema. // Set to true for attributes which have handler in Sema.
bit SemaHandler = 1; bit SemaHandler = 1;
// Set to true if this attribute doesn't need custom handling in Sema.
bit SimpleHandler = 0;
// Set to true for attributes that are completely ignored. // Set to true for attributes that are completely ignored.
bit Ignored = 0; bit Ignored = 0;
// Set to true if the attribute's parsing does not match its semantic // Set to true if the attribute's parsing does not match its semantic
@ -681,6 +683,7 @@ def Artificial : InheritableAttr {
let Spellings = [GCC<"artificial">]; let Spellings = [GCC<"artificial">];
let Subjects = SubjectList<[InlineFunction]>; let Subjects = SubjectList<[InlineFunction]>;
let Documentation = [ArtificialDocs]; let Documentation = [ArtificialDocs];
let SimpleHandler = 1;
} }
def XRayInstrument : InheritableAttr { def XRayInstrument : InheritableAttr {
@ -692,6 +695,7 @@ def XRayInstrument : InheritableAttr {
Accessor<"neverXRayInstrument", Accessor<"neverXRayInstrument",
[Clang<"xray_never_instrument">]>]; [Clang<"xray_never_instrument">]>];
let Documentation = [XRayDocs]; let Documentation = [XRayDocs];
let SimpleHandler = 1;
} }
def XRayLogArgs : InheritableAttr { def XRayLogArgs : InheritableAttr {
@ -948,6 +952,7 @@ def OSConsumesThis : InheritableAttr {
let Spellings = [Clang<"os_consumes_this">]; let Spellings = [Clang<"os_consumes_this">];
let Subjects = SubjectList<[NonStaticCXXMethod]>; let Subjects = SubjectList<[NonStaticCXXMethod]>;
let Documentation = [RetainBehaviorDocs]; let Documentation = [RetainBehaviorDocs];
let SimpleHandler = 1;
} }
def Cleanup : InheritableAttr { def Cleanup : InheritableAttr {
@ -972,6 +977,7 @@ def Common : InheritableAttr {
def Const : InheritableAttr { def Const : InheritableAttr {
let Spellings = [GCC<"const">, GCC<"__const">]; let Spellings = [GCC<"const">, GCC<"__const">];
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def ConstInit : InheritableAttr { def ConstInit : InheritableAttr {
@ -983,6 +989,7 @@ def ConstInit : InheritableAttr {
let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>]; let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>];
let Documentation = [ConstInitDocs]; let Documentation = [ConstInitDocs];
let LangOpts = [CPlusPlus]; let LangOpts = [CPlusPlus];
let SimpleHandler = 1;
} }
def Constructor : InheritableAttr { def Constructor : InheritableAttr {
@ -1113,6 +1120,7 @@ def CXX11NoReturn : InheritableAttr {
let Spellings = [CXX11<"", "noreturn", 200809>]; let Spellings = [CXX11<"", "noreturn", 200809>];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [CXX11NoReturnDocs]; let Documentation = [CXX11NoReturnDocs];
let SimpleHandler = 1;
} }
// Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
@ -1121,6 +1129,7 @@ def OpenCLKernel : InheritableAttr {
let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def OpenCLUnrollHint : InheritableAttr { def OpenCLUnrollHint : InheritableAttr {
@ -1190,6 +1199,7 @@ def RenderScriptKernel : Attr {
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [RenderScriptKernelAttributeDocs]; let Documentation = [RenderScriptKernelAttributeDocs];
let LangOpts = [RenderScript]; let LangOpts = [RenderScript];
let SimpleHandler = 1;
} }
def Deprecated : InheritableAttr { def Deprecated : InheritableAttr {
@ -1214,6 +1224,7 @@ def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Spellings = [Declspec<"empty_bases">]; let Spellings = [Declspec<"empty_bases">];
let Subjects = SubjectList<[CXXRecord]>; let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [EmptyBasesDocs]; let Documentation = [EmptyBasesDocs];
let SimpleHandler = 1;
} }
def AllocSize : InheritableAttr { def AllocSize : InheritableAttr {
@ -1285,6 +1296,7 @@ def FlagEnum : InheritableAttr {
let Spellings = [Clang<"flag_enum">]; let Spellings = [Clang<"flag_enum">];
let Subjects = SubjectList<[Enum]>; let Subjects = SubjectList<[Enum]>;
let Documentation = [FlagEnumDocs]; let Documentation = [FlagEnumDocs];
let SimpleHandler = 1;
} }
def EnumExtensibility : InheritableAttr { def EnumExtensibility : InheritableAttr {
@ -1299,6 +1311,7 @@ def Flatten : InheritableAttr {
let Spellings = [GCC<"flatten">]; let Spellings = [GCC<"flatten">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [FlattenDocs]; let Documentation = [FlattenDocs];
let SimpleHandler = 1;
} }
def Format : InheritableAttr { def Format : InheritableAttr {
@ -1344,6 +1357,7 @@ def IBAction : InheritableAttr {
// of the compiler. However, this node needs to exist in the AST because // of the compiler. However, this node needs to exist in the AST because
// external tools rely on it. // external tools rely on it.
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def IBOutlet : InheritableAttr { def IBOutlet : InheritableAttr {
@ -1384,6 +1398,7 @@ def LifetimeBound : DeclOrTypeAttr {
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>; let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
let Documentation = [LifetimeBoundDocs]; let Documentation = [LifetimeBoundDocs];
let LangOpts = [CPlusPlus]; let LangOpts = [CPlusPlus];
let SimpleHandler = 1;
} }
def TrivialABI : InheritableAttr { def TrivialABI : InheritableAttr {
@ -1393,6 +1408,7 @@ def TrivialABI : InheritableAttr {
let Subjects = SubjectList<[CXXRecord]>; let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [TrivialABIDocs]; let Documentation = [TrivialABIDocs];
let LangOpts = [CPlusPlus]; let LangOpts = [CPlusPlus];
let SimpleHandler = 1;
} }
def MaxFieldAlignment : InheritableAttr { def MaxFieldAlignment : InheritableAttr {
@ -1407,6 +1423,7 @@ def MayAlias : InheritableAttr {
// FIXME: this is a type attribute in GCC, but a declaration attribute here. // FIXME: this is a type attribute in GCC, but a declaration attribute here.
let Spellings = [GCC<"may_alias">]; let Spellings = [GCC<"may_alias">];
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def MIGServerRoutine : InheritableAttr { def MIGServerRoutine : InheritableAttr {
@ -1512,12 +1529,14 @@ def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
let Spellings = [CXX11<"", "no_unique_address", 201803>]; let Spellings = [CXX11<"", "no_unique_address", 201803>];
let Subjects = SubjectList<[NonBitField], ErrorDiag>; let Subjects = SubjectList<[NonBitField], ErrorDiag>;
let Documentation = [NoUniqueAddressDocs]; let Documentation = [NoUniqueAddressDocs];
let SimpleHandler = 1;
} }
def ReturnsTwice : InheritableAttr { def ReturnsTwice : InheritableAttr {
let Spellings = [GCC<"returns_twice">]; let Spellings = [GCC<"returns_twice">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def DisableTailCalls : InheritableAttr { def DisableTailCalls : InheritableAttr {
@ -1530,12 +1549,14 @@ def NoAlias : InheritableAttr {
let Spellings = [Declspec<"noalias">]; let Spellings = [Declspec<"noalias">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [NoAliasDocs]; let Documentation = [NoAliasDocs];
let SimpleHandler = 1;
} }
def NoCommon : InheritableAttr { def NoCommon : InheritableAttr {
let Spellings = [GCC<"nocommon">]; let Spellings = [GCC<"nocommon">];
let Subjects = SubjectList<[Var]>; let Subjects = SubjectList<[Var]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def NoDebug : InheritableAttr { def NoDebug : InheritableAttr {
@ -1548,30 +1569,35 @@ def NoDuplicate : InheritableAttr {
let Spellings = [Clang<"noduplicate">]; let Spellings = [Clang<"noduplicate">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [NoDuplicateDocs]; let Documentation = [NoDuplicateDocs];
let SimpleHandler = 1;
} }
def Convergent : InheritableAttr { def Convergent : InheritableAttr {
let Spellings = [Clang<"convergent">]; let Spellings = [Clang<"convergent">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [ConvergentDocs]; let Documentation = [ConvergentDocs];
let SimpleHandler = 1;
} }
def NoInline : InheritableAttr { def NoInline : InheritableAttr {
let Spellings = [GCC<"noinline">, Declspec<"noinline">]; let Spellings = [GCC<"noinline">, Declspec<"noinline">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"nomips16">]; let Spellings = [GCC<"nomips16">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> { def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"nomicromips">]; let Spellings = [GCC<"nomicromips">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [MicroMipsDocs]; let Documentation = [MicroMipsDocs];
let SimpleHandler = 1;
} }
def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> { def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
@ -1666,6 +1692,7 @@ def NoSplitStack : InheritableAttr {
let Spellings = [GCC<"no_split_stack">]; let Spellings = [GCC<"no_split_stack">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSplitStackDocs]; let Documentation = [NoSplitStackDocs];
let SimpleHandler = 1;
} }
def NonNull : InheritableParamAttr { def NonNull : InheritableParamAttr {
@ -1763,6 +1790,7 @@ def NoInstrumentFunction : InheritableAttr {
let Spellings = [GCC<"no_instrument_function">]; let Spellings = [GCC<"no_instrument_function">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def NotTailCalled : InheritableAttr { def NotTailCalled : InheritableAttr {
@ -1775,6 +1803,7 @@ def NoStackProtector : InheritableAttr {
let Spellings = [Clang<"no_stack_protector">]; let Spellings = [Clang<"no_stack_protector">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [NoStackProtectorDocs]; let Documentation = [NoStackProtectorDocs];
let SimpleHandler = 1;
} }
def NoThrow : InheritableAttr { def NoThrow : InheritableAttr {
@ -1837,6 +1866,7 @@ def NSConsumesSelf : InheritableAttr {
let Spellings = [Clang<"ns_consumes_self">]; let Spellings = [Clang<"ns_consumes_self">];
let Subjects = SubjectList<[ObjCMethod]>; let Subjects = SubjectList<[ObjCMethod]>;
let Documentation = [RetainBehaviorDocs]; let Documentation = [RetainBehaviorDocs];
let SimpleHandler = 1;
} }
def NSConsumed : InheritableParamAttr { def NSConsumed : InheritableParamAttr {
@ -1849,6 +1879,7 @@ def ObjCException : InheritableAttr {
let Spellings = [Clang<"objc_exception">]; let Spellings = [Clang<"objc_exception">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def ObjCMethodFamily : InheritableAttr { def ObjCMethodFamily : InheritableAttr {
@ -1893,6 +1924,7 @@ def ObjCRootClass : InheritableAttr {
let Spellings = [Clang<"objc_root_class">]; let Spellings = [Clang<"objc_root_class">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def ObjCNonLazyClass : Attr { def ObjCNonLazyClass : Attr {
@ -1900,12 +1932,14 @@ def ObjCNonLazyClass : Attr {
let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>;
let LangOpts = [ObjC]; let LangOpts = [ObjC];
let Documentation = [ObjCNonLazyClassDocs]; let Documentation = [ObjCNonLazyClassDocs];
let SimpleHandler = 1;
} }
def ObjCSubclassingRestricted : InheritableAttr { def ObjCSubclassingRestricted : InheritableAttr {
let Spellings = [Clang<"objc_subclassing_restricted">]; let Spellings = [Clang<"objc_subclassing_restricted">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [ObjCSubclassingRestrictedDocs]; let Documentation = [ObjCSubclassingRestrictedDocs];
let SimpleHandler = 1;
} }
def ObjCExplicitProtocolImpl : InheritableAttr { def ObjCExplicitProtocolImpl : InheritableAttr {
@ -1945,6 +1979,7 @@ def ObjCRuntimeVisible : Attr {
let Spellings = [Clang<"objc_runtime_visible">]; let Spellings = [Clang<"objc_runtime_visible">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [ObjCRuntimeVisibleDocs]; let Documentation = [ObjCRuntimeVisibleDocs];
let SimpleHandler = 1;
} }
def ObjCClassStub : Attr { def ObjCClassStub : Attr {
@ -1952,6 +1987,7 @@ def ObjCClassStub : Attr {
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [ObjCClassStubDocs]; let Documentation = [ObjCClassStubDocs];
let LangOpts = [ObjCNonFragileRuntime]; let LangOpts = [ObjCNonFragileRuntime];
let SimpleHandler = 1;
} }
def ObjCBoxable : Attr { def ObjCBoxable : Attr {
@ -1970,6 +2006,7 @@ def Overloadable : Attr {
let Spellings = [Clang<"overloadable">]; let Spellings = [Clang<"overloadable">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [OverloadableDocs]; let Documentation = [OverloadableDocs];
let SimpleHandler = 1;
} }
def Override : InheritableAttr { def Override : InheritableAttr {
@ -2027,6 +2064,7 @@ def AArch64VectorPcs: DeclOrTypeAttr {
def Pure : InheritableAttr { def Pure : InheritableAttr {
let Spellings = [GCC<"pure">]; let Spellings = [GCC<"pure">];
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def Regparm : TypeAttr { def Regparm : TypeAttr {
@ -2350,6 +2388,7 @@ def ArcWeakrefUnavailable : InheritableAttr {
let Spellings = [Clang<"objc_arc_weak_reference_unavailable">]; let Spellings = [Clang<"objc_arc_weak_reference_unavailable">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def ObjCGC : TypeAttr { def ObjCGC : TypeAttr {
@ -2368,6 +2407,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
let Spellings = [Clang<"objc_requires_property_definitions">]; let Spellings = [Clang<"objc_requires_property_definitions">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def Unused : InheritableAttr { def Unused : InheritableAttr {
@ -2382,6 +2422,7 @@ def Used : InheritableAttr {
let Spellings = [GCC<"used">]; let Spellings = [GCC<"used">];
let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>; let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def Uuid : InheritableAttr { def Uuid : InheritableAttr {
@ -2443,6 +2484,7 @@ def WarnUnused : InheritableAttr {
let Spellings = [GCC<"warn_unused">]; let Spellings = [GCC<"warn_unused">];
let Subjects = SubjectList<[Record]>; let Subjects = SubjectList<[Record]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def WarnUnusedResult : InheritableAttr { def WarnUnusedResult : InheritableAttr {
@ -2465,6 +2507,7 @@ def Weak : InheritableAttr {
let Spellings = [GCC<"weak">]; let Spellings = [GCC<"weak">];
let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Subjects = SubjectList<[Var, Function, CXXRecord]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def WeakImport : InheritableAttr { def WeakImport : InheritableAttr {
@ -2484,6 +2527,7 @@ def LTOVisibilityPublic : InheritableAttr {
let Spellings = [Clang<"lto_visibility_public">]; let Spellings = [Clang<"lto_visibility_public">];
let Subjects = SubjectList<[Record]>; let Subjects = SubjectList<[Record]>;
let Documentation = [LTOVisibilityDocs]; let Documentation = [LTOVisibilityDocs];
let SimpleHandler = 1;
} }
def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
@ -2500,6 +2544,7 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr,
TargetSpecificAttr<TargetAnyX86> { TargetSpecificAttr<TargetAnyX86> {
let Spellings = [GCC<"no_caller_saved_registers">]; let Spellings = [GCC<"no_caller_saved_registers">];
let Documentation = [AnyX86NoCallerSavedRegistersDocs]; let Documentation = [AnyX86NoCallerSavedRegistersDocs];
let SimpleHandler = 1;
} }
def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{ def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{
@ -2551,6 +2596,7 @@ def CFICanonicalJumpTable : InheritableAttr {
let Spellings = [Clang<"cfi_canonical_jump_table">]; let Spellings = [Clang<"cfi_canonical_jump_table">];
let Subjects = SubjectList<[Function], ErrorDiag>; let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [CFICanonicalJumpTableDocs]; let Documentation = [CFICanonicalJumpTableDocs];
let SimpleHandler = 1;
} }
// C/C++ Thread safety attributes (e.g. for deadlock, data race checking) // C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
@ -2563,6 +2609,7 @@ def GuardedVar : InheritableAttr {
let Spellings = [Clang<"guarded_var", 0>]; let Spellings = [Clang<"guarded_var", 0>];
let Subjects = SubjectList<[Field, SharedVar]>; let Subjects = SubjectList<[Field, SharedVar]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def PtGuardedVar : InheritableAttr { def PtGuardedVar : InheritableAttr {
@ -2582,6 +2629,7 @@ def ScopedLockable : InheritableAttr {
let Spellings = [Clang<"scoped_lockable", 0>]; let Spellings = [Clang<"scoped_lockable", 0>];
let Subjects = SubjectList<[Record]>; let Subjects = SubjectList<[Record]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def Capability : InheritableAttr { def Capability : InheritableAttr {
@ -2678,6 +2726,7 @@ def NoThreadSafetyAnalysis : InheritableAttr {
let Spellings = [Clang<"no_thread_safety_analysis">]; let Spellings = [Clang<"no_thread_safety_analysis">];
let Subjects = SubjectList<[Function]>; let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def GuardedBy : InheritableAttr { def GuardedBy : InheritableAttr {
@ -2814,6 +2863,7 @@ def ConsumableAutoCast : InheritableAttr {
let Spellings = [Clang<"consumable_auto_cast_state", 0>]; let Spellings = [Clang<"consumable_auto_cast_state", 0>];
let Subjects = SubjectList<[CXXRecord]>; let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def ConsumableSetOnRead : InheritableAttr { def ConsumableSetOnRead : InheritableAttr {
@ -2823,6 +2873,7 @@ def ConsumableSetOnRead : InheritableAttr {
let Spellings = [Clang<"consumable_set_state_on_read", 0>]; let Spellings = [Clang<"consumable_set_state_on_read", 0>];
let Subjects = SubjectList<[CXXRecord]>; let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def CallableWhen : InheritableAttr { def CallableWhen : InheritableAttr {
@ -2929,6 +2980,7 @@ def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Spellings = [Declspec<"novtable">]; let Spellings = [Declspec<"novtable">];
let Subjects = SubjectList<[CXXRecord]>; let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [MSNoVTableDocs]; let Documentation = [MSNoVTableDocs];
let SimpleHandler = 1;
} }
def : IgnoredAttr { def : IgnoredAttr {
@ -2954,6 +3006,7 @@ def MSStruct : InheritableAttr {
let Spellings = [GCC<"ms_struct">]; let Spellings = [GCC<"ms_struct">];
let Subjects = SubjectList<[Record]>; let Subjects = SubjectList<[Record]>;
let Documentation = [Undocumented]; let Documentation = [Undocumented];
let SimpleHandler = 1;
} }
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> { def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
@ -3002,6 +3055,7 @@ def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def SelectAny : InheritableAttr { def SelectAny : InheritableAttr {
let Spellings = [Declspec<"selectany">, GCC<"selectany">]; let Spellings = [Declspec<"selectany">, GCC<"selectany">];
let Documentation = [SelectAnyDocs]; let Documentation = [SelectAnyDocs];
let SimpleHandler = 1;
} }
def Thread : Attr { def Thread : Attr {
@ -3277,12 +3331,14 @@ def ExcludeFromExplicitInstantiation : InheritableAttr {
let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Subjects = SubjectList<[Var, Function, CXXRecord]>;
let Documentation = [ExcludeFromExplicitInstantiationDocs]; let Documentation = [ExcludeFromExplicitInstantiationDocs];
let MeaningfulToClassTemplateDefinition = 1; let MeaningfulToClassTemplateDefinition = 1;
let SimpleHandler = 1;
} }
def Reinitializes : InheritableAttr { def Reinitializes : InheritableAttr {
let Spellings = [Clang<"reinitializes", 0>]; let Spellings = [Clang<"reinitializes", 0>];
let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>; let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>;
let Documentation = [ReinitializesDocs]; let Documentation = [ReinitializesDocs];
let SimpleHandler = 1;
} }
def NoDestroy : InheritableAttr { def NoDestroy : InheritableAttr {

View File

@ -68,7 +68,7 @@ struct ParsedAttrInfo {
std::vector<Spelling> Spellings; std::vector<Spelling> Spellings;
ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind = ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
AttributeCommonInfo::UnknownAttribute) AttributeCommonInfo::NoSemaHandlerAttribute)
: AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0), : AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0),
IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0), IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0),
IsSupportedByPragmaAttribute(0) {} IsSupportedByPragmaAttribute(0) {}
@ -99,6 +99,18 @@ struct ParsedAttrInfo {
llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules, llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
const LangOptions &LangOpts) const { const LangOptions &LangOpts) const {
} }
enum AttrHandling {
NotHandled,
AttributeApplied,
AttributeNotApplied
};
/// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
/// Decl then do so and return either AttributeApplied if it was applied or
/// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
const ParsedAttr &Attr) const {
return NotHandled;
}
static const ParsedAttrInfo &get(const AttributeCommonInfo &A); static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
}; };

View File

@ -140,7 +140,8 @@ const ParsedAttrInfo &ParsedAttrInfo::get(const AttributeCommonInfo &A) {
return *Ptr; return *Ptr;
// If we failed to find a match then return a default ParsedAttrInfo. // If we failed to find a match then return a default ParsedAttrInfo.
static ParsedAttrInfo DefaultParsedAttrInfo; static ParsedAttrInfo DefaultParsedAttrInfo(
AttributeCommonInfo::UnknownAttribute);
return DefaultParsedAttrInfo; return DefaultParsedAttrInfo;
} }

View File

@ -6747,6 +6747,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
switch (AL.getKind()) { switch (AL.getKind()) {
default: default:
if (AL.getInfo().handleDeclAttribute(S, D, AL) != ParsedAttrInfo::NotHandled)
break;
if (!AL.isStmtAttr()) { if (!AL.isStmtAttr()) {
// Type attributes are handled elsewhere; silently move on. // Type attributes are handled elsewhere; silently move on.
assert(AL.isTypeAttr() && "Non-type attribute not handled"); assert(AL.isTypeAttr() && "Non-type attribute not handled");
@ -6769,15 +6771,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSimpleAttributeWithExclusions<Mips16Attr, MicroMipsAttr, handleSimpleAttributeWithExclusions<Mips16Attr, MicroMipsAttr,
MipsInterruptAttr>(S, D, AL); MipsInterruptAttr>(S, D, AL);
break; break;
case ParsedAttr::AT_NoMips16:
handleSimpleAttribute<NoMips16Attr>(S, D, AL);
break;
case ParsedAttr::AT_MicroMips: case ParsedAttr::AT_MicroMips:
handleSimpleAttributeWithExclusions<MicroMipsAttr, Mips16Attr>(S, D, AL); handleSimpleAttributeWithExclusions<MicroMipsAttr, Mips16Attr>(S, D, AL);
break; break;
case ParsedAttr::AT_NoMicroMips:
handleSimpleAttribute<NoMicroMipsAttr>(S, D, AL);
break;
case ParsedAttr::AT_MipsLongCall: case ParsedAttr::AT_MipsLongCall:
handleSimpleAttributeWithExclusions<MipsLongCallAttr, MipsShortCallAttr>( handleSimpleAttributeWithExclusions<MipsLongCallAttr, MipsShortCallAttr>(
S, D, AL); S, D, AL);
@ -6813,9 +6809,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_WebAssemblyImportName: case ParsedAttr::AT_WebAssemblyImportName:
handleWebAssemblyImportNameAttr(S, D, AL); handleWebAssemblyImportNameAttr(S, D, AL);
break; break;
case ParsedAttr::AT_IBAction:
handleSimpleAttribute<IBActionAttr>(S, D, AL);
break;
case ParsedAttr::AT_IBOutlet: case ParsedAttr::AT_IBOutlet:
handleIBOutlet(S, D, AL); handleIBOutlet(S, D, AL);
break; break;
@ -6840,9 +6833,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AlwaysInline: case ParsedAttr::AT_AlwaysInline:
handleAlwaysInlineAttr(S, D, AL); handleAlwaysInlineAttr(S, D, AL);
break; break;
case ParsedAttr::AT_Artificial:
handleSimpleAttribute<ArtificialAttr>(S, D, AL);
break;
case ParsedAttr::AT_AnalyzerNoReturn: case ParsedAttr::AT_AnalyzerNoReturn:
handleAnalyzerNoReturnAttr(S, D, AL); handleAnalyzerNoReturnAttr(S, D, AL);
break; break;
@ -6874,9 +6864,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Constructor: case ParsedAttr::AT_Constructor:
handleConstructorAttr(S, D, AL); handleConstructorAttr(S, D, AL);
break; break;
case ParsedAttr::AT_CXX11NoReturn:
handleSimpleAttribute<CXX11NoReturnAttr>(S, D, AL);
break;
case ParsedAttr::AT_Deprecated: case ParsedAttr::AT_Deprecated:
handleDeprecatedAttr(S, D, AL); handleDeprecatedAttr(S, D, AL);
break; break;
@ -6904,15 +6891,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_OptimizeNone: case ParsedAttr::AT_OptimizeNone:
handleOptimizeNoneAttr(S, D, AL); handleOptimizeNoneAttr(S, D, AL);
break; break;
case ParsedAttr::AT_FlagEnum:
handleSimpleAttribute<FlagEnumAttr>(S, D, AL);
break;
case ParsedAttr::AT_EnumExtensibility: case ParsedAttr::AT_EnumExtensibility:
handleEnumExtensibilityAttr(S, D, AL); handleEnumExtensibilityAttr(S, D, AL);
break; break;
case ParsedAttr::AT_Flatten:
handleSimpleAttribute<FlattenAttr>(S, D, AL);
break;
case ParsedAttr::AT_SYCLKernel: case ParsedAttr::AT_SYCLKernel:
handleSYCLKernelAttr(S, D, AL); handleSYCLKernelAttr(S, D, AL);
break; break;
@ -6948,27 +6929,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Restrict: case ParsedAttr::AT_Restrict:
handleRestrictAttr(S, D, AL); handleRestrictAttr(S, D, AL);
break; break;
case ParsedAttr::AT_LifetimeBound:
handleSimpleAttribute<LifetimeBoundAttr>(S, D, AL);
break;
case ParsedAttr::AT_MayAlias:
handleSimpleAttribute<MayAliasAttr>(S, D, AL);
break;
case ParsedAttr::AT_Mode: case ParsedAttr::AT_Mode:
handleModeAttr(S, D, AL); handleModeAttr(S, D, AL);
break; break;
case ParsedAttr::AT_NoAlias:
handleSimpleAttribute<NoAliasAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoCommon:
handleSimpleAttribute<NoCommonAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoSplitStack:
handleSimpleAttribute<NoSplitStackAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoUniqueAddress:
handleSimpleAttribute<NoUniqueAddressAttr>(S, D, AL);
break;
case ParsedAttr::AT_NonNull: case ParsedAttr::AT_NonNull:
if (auto *PVD = dyn_cast<ParmVarDecl>(D)) if (auto *PVD = dyn_cast<ParmVarDecl>(D))
handleNonNullAttrParameter(S, PVD, AL); handleNonNullAttrParameter(S, PVD, AL);
@ -6987,9 +6950,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AllocAlign: case ParsedAttr::AT_AllocAlign:
handleAllocAlignAttr(S, D, AL); handleAllocAlignAttr(S, D, AL);
break; break;
case ParsedAttr::AT_Overloadable:
handleSimpleAttribute<OverloadableAttr>(S, D, AL);
break;
case ParsedAttr::AT_Ownership: case ParsedAttr::AT_Ownership:
handleOwnershipAttr(S, D, AL); handleOwnershipAttr(S, D, AL);
break; break;
@ -7045,9 +7005,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_ObjCRuntimeName: case ParsedAttr::AT_ObjCRuntimeName:
handleObjCRuntimeName(S, D, AL); handleObjCRuntimeName(S, D, AL);
break; break;
case ParsedAttr::AT_ObjCRuntimeVisible:
handleSimpleAttribute<ObjCRuntimeVisibleAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCBoxable: case ParsedAttr::AT_ObjCBoxable:
handleObjCBoxable(S, D, AL); handleObjCBoxable(S, D, AL);
break; break;
@ -7065,12 +7022,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
S.AddXConsumedAttr(D, AL, parsedAttrToRetainOwnershipKind(AL), S.AddXConsumedAttr(D, AL, parsedAttrToRetainOwnershipKind(AL),
/*IsTemplateInstantiation=*/false); /*IsTemplateInstantiation=*/false);
break; break;
case ParsedAttr::AT_NSConsumesSelf:
handleSimpleAttribute<NSConsumesSelfAttr>(S, D, AL);
break;
case ParsedAttr::AT_OSConsumesThis:
handleSimpleAttribute<OSConsumesThisAttr>(S, D, AL);
break;
case ParsedAttr::AT_OSReturnsRetainedOnZero: case ParsedAttr::AT_OSReturnsRetainedOnZero:
handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>( handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
S, D, AL, isValidOSObjectOutParameter(D), S, D, AL, isValidOSObjectOutParameter(D),
@ -7104,9 +7055,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_VecTypeHint: case ParsedAttr::AT_VecTypeHint:
handleVecTypeHint(S, D, AL); handleVecTypeHint(S, D, AL);
break; break;
case ParsedAttr::AT_ConstInit:
handleSimpleAttribute<ConstInitAttr>(S, D, AL);
break;
case ParsedAttr::AT_InitPriority: case ParsedAttr::AT_InitPriority:
handleInitPriorityAttr(S, D, AL); handleInitPriorityAttr(S, D, AL);
break; break;
@ -7137,12 +7085,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Unavailable: case ParsedAttr::AT_Unavailable:
handleAttrWithMessage<UnavailableAttr>(S, D, AL); handleAttrWithMessage<UnavailableAttr>(S, D, AL);
break; break;
case ParsedAttr::AT_ArcWeakrefUnavailable:
handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCRootClass:
handleSimpleAttribute<ObjCRootClassAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCDirect: case ParsedAttr::AT_ObjCDirect:
handleObjCDirectAttr(S, D, AL); handleObjCDirectAttr(S, D, AL);
break; break;
@ -7150,27 +7092,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleObjCDirectMembersAttr(S, D, AL); handleObjCDirectMembersAttr(S, D, AL);
handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL); handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
break; break;
case ParsedAttr::AT_ObjCNonLazyClass:
handleSimpleAttribute<ObjCNonLazyClassAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCSubclassingRestricted:
handleSimpleAttribute<ObjCSubclassingRestrictedAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCClassStub:
handleSimpleAttribute<ObjCClassStubAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCExplicitProtocolImpl: case ParsedAttr::AT_ObjCExplicitProtocolImpl:
handleObjCSuppresProtocolAttr(S, D, AL); handleObjCSuppresProtocolAttr(S, D, AL);
break; break;
case ParsedAttr::AT_ObjCRequiresPropertyDefs:
handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, AL);
break;
case ParsedAttr::AT_Unused: case ParsedAttr::AT_Unused:
handleUnusedAttr(S, D, AL); handleUnusedAttr(S, D, AL);
break; break;
case ParsedAttr::AT_ReturnsTwice:
handleSimpleAttribute<ReturnsTwiceAttr>(S, D, AL);
break;
case ParsedAttr::AT_NotTailCalled: case ParsedAttr::AT_NotTailCalled:
handleSimpleAttributeWithExclusions<NotTailCalledAttr, AlwaysInlineAttr>( handleSimpleAttributeWithExclusions<NotTailCalledAttr, AlwaysInlineAttr>(
S, D, AL); S, D, AL);
@ -7179,24 +7106,15 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSimpleAttributeWithExclusions<DisableTailCallsAttr, NakedAttr>(S, D, handleSimpleAttributeWithExclusions<DisableTailCallsAttr, NakedAttr>(S, D,
AL); AL);
break; break;
case ParsedAttr::AT_Used:
handleSimpleAttribute<UsedAttr>(S, D, AL);
break;
case ParsedAttr::AT_Visibility: case ParsedAttr::AT_Visibility:
handleVisibilityAttr(S, D, AL, false); handleVisibilityAttr(S, D, AL, false);
break; break;
case ParsedAttr::AT_TypeVisibility: case ParsedAttr::AT_TypeVisibility:
handleVisibilityAttr(S, D, AL, true); handleVisibilityAttr(S, D, AL, true);
break; break;
case ParsedAttr::AT_WarnUnused:
handleSimpleAttribute<WarnUnusedAttr>(S, D, AL);
break;
case ParsedAttr::AT_WarnUnusedResult: case ParsedAttr::AT_WarnUnusedResult:
handleWarnUnusedResult(S, D, AL); handleWarnUnusedResult(S, D, AL);
break; break;
case ParsedAttr::AT_Weak:
handleSimpleAttribute<WeakAttr>(S, D, AL);
break;
case ParsedAttr::AT_WeakRef: case ParsedAttr::AT_WeakRef:
handleWeakRefAttr(S, D, AL); handleWeakRefAttr(S, D, AL);
break; break;
@ -7206,9 +7124,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_TransparentUnion: case ParsedAttr::AT_TransparentUnion:
handleTransparentUnionAttr(S, D, AL); handleTransparentUnionAttr(S, D, AL);
break; break;
case ParsedAttr::AT_ObjCException:
handleSimpleAttribute<ObjCExceptionAttr>(S, D, AL);
break;
case ParsedAttr::AT_ObjCMethodFamily: case ParsedAttr::AT_ObjCMethodFamily:
handleObjCMethodFamilyAttr(S, D, AL); handleObjCMethodFamilyAttr(S, D, AL);
break; break;
@ -7224,37 +7139,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Sentinel: case ParsedAttr::AT_Sentinel:
handleSentinelAttr(S, D, AL); handleSentinelAttr(S, D, AL);
break; break;
case ParsedAttr::AT_Const:
handleSimpleAttribute<ConstAttr>(S, D, AL);
break;
case ParsedAttr::AT_Pure:
handleSimpleAttribute<PureAttr>(S, D, AL);
break;
case ParsedAttr::AT_Cleanup: case ParsedAttr::AT_Cleanup:
handleCleanupAttr(S, D, AL); handleCleanupAttr(S, D, AL);
break; break;
case ParsedAttr::AT_NoDebug: case ParsedAttr::AT_NoDebug:
handleNoDebugAttr(S, D, AL); handleNoDebugAttr(S, D, AL);
break; break;
case ParsedAttr::AT_NoDuplicate:
handleSimpleAttribute<NoDuplicateAttr>(S, D, AL);
break;
case ParsedAttr::AT_Convergent:
handleSimpleAttribute<ConvergentAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoInline:
handleSimpleAttribute<NoInlineAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoInstrumentFunction: // Interacts with -pg.
handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoStackProtector:
// Interacts with -fstack-protector options.
handleSimpleAttribute<NoStackProtectorAttr>(S, D, AL);
break;
case ParsedAttr::AT_CFICanonicalJumpTable:
handleSimpleAttribute<CFICanonicalJumpTableAttr>(S, D, AL);
break;
case ParsedAttr::AT_StdCall: case ParsedAttr::AT_StdCall:
case ParsedAttr::AT_CDecl: case ParsedAttr::AT_CDecl:
case ParsedAttr::AT_FastCall: case ParsedAttr::AT_FastCall:
@ -7279,9 +7169,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Pointer: case ParsedAttr::AT_Pointer:
handleLifetimeCategoryAttr(S, D, AL); handleLifetimeCategoryAttr(S, D, AL);
break; break;
case ParsedAttr::AT_OpenCLKernel:
handleSimpleAttribute<OpenCLKernelAttr>(S, D, AL);
break;
case ParsedAttr::AT_OpenCLAccess: case ParsedAttr::AT_OpenCLAccess:
handleOpenCLAccessAttr(S, D, AL); handleOpenCLAccessAttr(S, D, AL);
break; break;
@ -7300,38 +7187,17 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_InternalLinkage: case ParsedAttr::AT_InternalLinkage:
handleInternalLinkageAttr(S, D, AL); handleInternalLinkageAttr(S, D, AL);
break; break;
case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
handleSimpleAttribute<ExcludeFromExplicitInstantiationAttr>(S, D, AL);
break;
case ParsedAttr::AT_LTOVisibilityPublic:
handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, AL);
break;
// Microsoft attributes: // Microsoft attributes:
case ParsedAttr::AT_EmptyBases:
handleSimpleAttribute<EmptyBasesAttr>(S, D, AL);
break;
case ParsedAttr::AT_LayoutVersion: case ParsedAttr::AT_LayoutVersion:
handleLayoutVersion(S, D, AL); handleLayoutVersion(S, D, AL);
break; break;
case ParsedAttr::AT_TrivialABI:
handleSimpleAttribute<TrivialABIAttr>(S, D, AL);
break;
case ParsedAttr::AT_MSNoVTable:
handleSimpleAttribute<MSNoVTableAttr>(S, D, AL);
break;
case ParsedAttr::AT_MSStruct:
handleSimpleAttribute<MSStructAttr>(S, D, AL);
break;
case ParsedAttr::AT_Uuid: case ParsedAttr::AT_Uuid:
handleUuidAttr(S, D, AL); handleUuidAttr(S, D, AL);
break; break;
case ParsedAttr::AT_MSInheritance: case ParsedAttr::AT_MSInheritance:
handleMSInheritanceAttr(S, D, AL); handleMSInheritanceAttr(S, D, AL);
break; break;
case ParsedAttr::AT_SelectAny:
handleSimpleAttribute<SelectAnyAttr>(S, D, AL);
break;
case ParsedAttr::AT_Thread: case ParsedAttr::AT_Thread:
handleDeclspecThreadAttr(S, D, AL); handleDeclspecThreadAttr(S, D, AL);
break; break;
@ -7350,24 +7216,15 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AssertSharedLock: case ParsedAttr::AT_AssertSharedLock:
handleAssertSharedLockAttr(S, D, AL); handleAssertSharedLockAttr(S, D, AL);
break; break;
case ParsedAttr::AT_GuardedVar:
handleSimpleAttribute<GuardedVarAttr>(S, D, AL);
break;
case ParsedAttr::AT_PtGuardedVar: case ParsedAttr::AT_PtGuardedVar:
handlePtGuardedVarAttr(S, D, AL); handlePtGuardedVarAttr(S, D, AL);
break; break;
case ParsedAttr::AT_ScopedLockable:
handleSimpleAttribute<ScopedLockableAttr>(S, D, AL);
break;
case ParsedAttr::AT_NoSanitize: case ParsedAttr::AT_NoSanitize:
handleNoSanitizeAttr(S, D, AL); handleNoSanitizeAttr(S, D, AL);
break; break;
case ParsedAttr::AT_NoSanitizeSpecific: case ParsedAttr::AT_NoSanitizeSpecific:
handleNoSanitizeSpecificAttr(S, D, AL); handleNoSanitizeSpecificAttr(S, D, AL);
break; break;
case ParsedAttr::AT_NoThreadSafetyAnalysis:
handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, AL);
break;
case ParsedAttr::AT_GuardedBy: case ParsedAttr::AT_GuardedBy:
handleGuardedByAttr(S, D, AL); handleGuardedByAttr(S, D, AL);
break; break;
@ -7419,12 +7276,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Consumable: case ParsedAttr::AT_Consumable:
handleConsumableAttr(S, D, AL); handleConsumableAttr(S, D, AL);
break; break;
case ParsedAttr::AT_ConsumableAutoCast:
handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, AL);
break;
case ParsedAttr::AT_ConsumableSetOnRead:
handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, AL);
break;
case ParsedAttr::AT_CallableWhen: case ParsedAttr::AT_CallableWhen:
handleCallableWhenAttr(S, D, AL); handleCallableWhenAttr(S, D, AL);
break; break;
@ -7448,16 +7299,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_TypeTagForDatatype: case ParsedAttr::AT_TypeTagForDatatype:
handleTypeTagForDatatypeAttr(S, D, AL); handleTypeTagForDatatypeAttr(S, D, AL);
break; break;
case ParsedAttr::AT_AnyX86NoCallerSavedRegisters:
handleSimpleAttribute<AnyX86NoCallerSavedRegistersAttr>(S, D, AL);
break;
case ParsedAttr::AT_RenderScriptKernel:
handleSimpleAttribute<RenderScriptKernelAttr>(S, D, AL);
break;
// XRay attributes. // XRay attributes.
case ParsedAttr::AT_XRayInstrument:
handleSimpleAttribute<XRayInstrumentAttr>(S, D, AL);
break;
case ParsedAttr::AT_XRayLogArgs: case ParsedAttr::AT_XRayLogArgs:
handleXRayLogArgsAttr(S, D, AL); handleXRayLogArgsAttr(S, D, AL);
break; break;
@ -7466,11 +7309,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handlePatchableFunctionEntryAttr(S, D, AL); handlePatchableFunctionEntryAttr(S, D, AL);
break; break;
// Move semantics attribute.
case ParsedAttr::AT_Reinitializes:
handleSimpleAttribute<ReinitializesAttr>(S, D, AL);
break;
case ParsedAttr::AT_AlwaysDestroy: case ParsedAttr::AT_AlwaysDestroy:
case ParsedAttr::AT_NoDestroy: case ParsedAttr::AT_NoDestroy:
handleDestroyAttr(S, D, AL); handleDestroyAttr(S, D, AL);

View File

@ -3661,6 +3661,20 @@ static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
OS << "}\n\n"; OS << "}\n\n";
} }
static void GenerateHandleDeclAttribute(const Record &Attr, raw_ostream &OS) {
// Only generate if Attr can be handled simply.
if (!Attr.getValueAsBit("SimpleHandler"))
return;
// Generate a function which just converts from ParsedAttr to the Attr type.
OS << "virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,";
OS << "const ParsedAttr &Attr) const {\n";
OS << " D->addAttr(::new (S.Context) " << Attr.getName();
OS << "Attr(S.Context, Attr));\n";
OS << " return AttributeApplied;\n";
OS << "}\n\n";
}
static bool IsKnownToGCC(const Record &Attr) { static bool IsKnownToGCC(const Record &Attr) {
// Look at the spellings for this subject; if there are any spellings which // Look at the spellings for this subject; if there are any spellings which
// claim to be known to GCC, the attribute is known to GCC. // claim to be known to GCC, the attribute is known to GCC.
@ -3742,6 +3756,7 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
GenerateTargetRequirements(Attr, Dupes, OS); GenerateTargetRequirements(Attr, Dupes, OS);
GenerateSpellingIndexToSemanticSpelling(Attr, OS); GenerateSpellingIndexToSemanticSpelling(Attr, OS);
PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS); PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
GenerateHandleDeclAttribute(Attr, OS);
OS << "static const ParsedAttrInfo" << I->first << " Instance;\n"; OS << "static const ParsedAttrInfo" << I->first << " Instance;\n";
OS << "};\n"; OS << "};\n";
OS << "const ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first OS << "const ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first