forked from OSchip/llvm-project
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:
parent
9adc7fc3cd
commit
fa0320dd8d
|
@ -63,6 +63,53 @@ registering it using ``PragmaHandlerRegistry::Add<>``:
|
|||
|
||||
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
|
||||
=======================
|
||||
|
||||
|
|
|
@ -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
|
||||
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
|
||||
different targets. For instance, the ARM and MSP430 targets both have an
|
||||
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
|
||||
<https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaDeclAttr.cpp>`_,
|
||||
and generally starts in the ``ProcessDeclAttribute()`` function. If the
|
||||
attribute is a "simple" attribute -- meaning that it requires no custom semantic
|
||||
processing aside from what is automatically provided, add a call to
|
||||
``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the switch statement.
|
||||
Otherwise, write a new ``handleYourAttr()`` function, and add that to the switch
|
||||
statement. Please do not implement handling logic directly in the ``case`` for
|
||||
the attribute.
|
||||
attribute has the ``SimpleHandler`` field set to ``1`` then the function to
|
||||
process the attribute will be automatically generated, and nothing needs to be
|
||||
done here. Otherwise, write a new ``handleYourAttr()`` function, and add that to
|
||||
the switch statement. Please do not implement handling logic directly in the
|
||||
``case`` for the attribute.
|
||||
|
||||
Unless otherwise specified by the attribute definition, common semantic checking
|
||||
of the parsed attribute is handled automatically. This includes diagnosing
|
||||
|
|
|
@ -513,6 +513,8 @@ class Attr {
|
|||
bit ASTNode = 1;
|
||||
// Set to true for attributes which have handler in Sema.
|
||||
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.
|
||||
bit Ignored = 0;
|
||||
// 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 Subjects = SubjectList<[InlineFunction]>;
|
||||
let Documentation = [ArtificialDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def XRayInstrument : InheritableAttr {
|
||||
|
@ -692,6 +695,7 @@ def XRayInstrument : InheritableAttr {
|
|||
Accessor<"neverXRayInstrument",
|
||||
[Clang<"xray_never_instrument">]>];
|
||||
let Documentation = [XRayDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def XRayLogArgs : InheritableAttr {
|
||||
|
@ -948,6 +952,7 @@ def OSConsumesThis : InheritableAttr {
|
|||
let Spellings = [Clang<"os_consumes_this">];
|
||||
let Subjects = SubjectList<[NonStaticCXXMethod]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Cleanup : InheritableAttr {
|
||||
|
@ -972,6 +977,7 @@ def Common : InheritableAttr {
|
|||
def Const : InheritableAttr {
|
||||
let Spellings = [GCC<"const">, GCC<"__const">];
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ConstInit : InheritableAttr {
|
||||
|
@ -983,6 +989,7 @@ def ConstInit : InheritableAttr {
|
|||
let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>];
|
||||
let Documentation = [ConstInitDocs];
|
||||
let LangOpts = [CPlusPlus];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Constructor : InheritableAttr {
|
||||
|
@ -1113,6 +1120,7 @@ def CXX11NoReturn : InheritableAttr {
|
|||
let Spellings = [CXX11<"", "noreturn", 200809>];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [CXX11NoReturnDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
// 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 Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def OpenCLUnrollHint : InheritableAttr {
|
||||
|
@ -1190,6 +1199,7 @@ def RenderScriptKernel : Attr {
|
|||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [RenderScriptKernelAttributeDocs];
|
||||
let LangOpts = [RenderScript];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Deprecated : InheritableAttr {
|
||||
|
@ -1214,6 +1224,7 @@ def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
|
|||
let Spellings = [Declspec<"empty_bases">];
|
||||
let Subjects = SubjectList<[CXXRecord]>;
|
||||
let Documentation = [EmptyBasesDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def AllocSize : InheritableAttr {
|
||||
|
@ -1285,6 +1296,7 @@ def FlagEnum : InheritableAttr {
|
|||
let Spellings = [Clang<"flag_enum">];
|
||||
let Subjects = SubjectList<[Enum]>;
|
||||
let Documentation = [FlagEnumDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def EnumExtensibility : InheritableAttr {
|
||||
|
@ -1299,6 +1311,7 @@ def Flatten : InheritableAttr {
|
|||
let Spellings = [GCC<"flatten">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [FlattenDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Format : InheritableAttr {
|
||||
|
@ -1344,6 +1357,7 @@ def IBAction : InheritableAttr {
|
|||
// of the compiler. However, this node needs to exist in the AST because
|
||||
// external tools rely on it.
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def IBOutlet : InheritableAttr {
|
||||
|
@ -1384,6 +1398,7 @@ def LifetimeBound : DeclOrTypeAttr {
|
|||
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
|
||||
let Documentation = [LifetimeBoundDocs];
|
||||
let LangOpts = [CPlusPlus];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def TrivialABI : InheritableAttr {
|
||||
|
@ -1393,6 +1408,7 @@ def TrivialABI : InheritableAttr {
|
|||
let Subjects = SubjectList<[CXXRecord]>;
|
||||
let Documentation = [TrivialABIDocs];
|
||||
let LangOpts = [CPlusPlus];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def MaxFieldAlignment : InheritableAttr {
|
||||
|
@ -1407,6 +1423,7 @@ def MayAlias : InheritableAttr {
|
|||
// FIXME: this is a type attribute in GCC, but a declaration attribute here.
|
||||
let Spellings = [GCC<"may_alias">];
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def MIGServerRoutine : InheritableAttr {
|
||||
|
@ -1512,12 +1529,14 @@ def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
|
|||
let Spellings = [CXX11<"", "no_unique_address", 201803>];
|
||||
let Subjects = SubjectList<[NonBitField], ErrorDiag>;
|
||||
let Documentation = [NoUniqueAddressDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ReturnsTwice : InheritableAttr {
|
||||
let Spellings = [GCC<"returns_twice">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def DisableTailCalls : InheritableAttr {
|
||||
|
@ -1530,12 +1549,14 @@ def NoAlias : InheritableAttr {
|
|||
let Spellings = [Declspec<"noalias">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [NoAliasDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoCommon : InheritableAttr {
|
||||
let Spellings = [GCC<"nocommon">];
|
||||
let Subjects = SubjectList<[Var]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoDebug : InheritableAttr {
|
||||
|
@ -1548,30 +1569,35 @@ def NoDuplicate : InheritableAttr {
|
|||
let Spellings = [Clang<"noduplicate">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [NoDuplicateDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Convergent : InheritableAttr {
|
||||
let Spellings = [Clang<"convergent">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [ConvergentDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoInline : InheritableAttr {
|
||||
let Spellings = [GCC<"noinline">, Declspec<"noinline">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> {
|
||||
let Spellings = [GCC<"nomips16">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> {
|
||||
let Spellings = [GCC<"nomicromips">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [MicroMipsDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
|
||||
|
@ -1666,6 +1692,7 @@ def NoSplitStack : InheritableAttr {
|
|||
let Spellings = [GCC<"no_split_stack">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [NoSplitStackDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NonNull : InheritableParamAttr {
|
||||
|
@ -1763,6 +1790,7 @@ def NoInstrumentFunction : InheritableAttr {
|
|||
let Spellings = [GCC<"no_instrument_function">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NotTailCalled : InheritableAttr {
|
||||
|
@ -1775,6 +1803,7 @@ def NoStackProtector : InheritableAttr {
|
|||
let Spellings = [Clang<"no_stack_protector">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [NoStackProtectorDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoThrow : InheritableAttr {
|
||||
|
@ -1837,6 +1866,7 @@ def NSConsumesSelf : InheritableAttr {
|
|||
let Spellings = [Clang<"ns_consumes_self">];
|
||||
let Subjects = SubjectList<[ObjCMethod]>;
|
||||
let Documentation = [RetainBehaviorDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NSConsumed : InheritableParamAttr {
|
||||
|
@ -1849,6 +1879,7 @@ def ObjCException : InheritableAttr {
|
|||
let Spellings = [Clang<"objc_exception">];
|
||||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCMethodFamily : InheritableAttr {
|
||||
|
@ -1893,6 +1924,7 @@ def ObjCRootClass : InheritableAttr {
|
|||
let Spellings = [Clang<"objc_root_class">];
|
||||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCNonLazyClass : Attr {
|
||||
|
@ -1900,12 +1932,14 @@ def ObjCNonLazyClass : Attr {
|
|||
let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>;
|
||||
let LangOpts = [ObjC];
|
||||
let Documentation = [ObjCNonLazyClassDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCSubclassingRestricted : InheritableAttr {
|
||||
let Spellings = [Clang<"objc_subclassing_restricted">];
|
||||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [ObjCSubclassingRestrictedDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCExplicitProtocolImpl : InheritableAttr {
|
||||
|
@ -1945,6 +1979,7 @@ def ObjCRuntimeVisible : Attr {
|
|||
let Spellings = [Clang<"objc_runtime_visible">];
|
||||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [ObjCRuntimeVisibleDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCClassStub : Attr {
|
||||
|
@ -1952,6 +1987,7 @@ def ObjCClassStub : Attr {
|
|||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [ObjCClassStubDocs];
|
||||
let LangOpts = [ObjCNonFragileRuntime];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCBoxable : Attr {
|
||||
|
@ -1970,6 +2006,7 @@ def Overloadable : Attr {
|
|||
let Spellings = [Clang<"overloadable">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [OverloadableDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Override : InheritableAttr {
|
||||
|
@ -2027,6 +2064,7 @@ def AArch64VectorPcs: DeclOrTypeAttr {
|
|||
def Pure : InheritableAttr {
|
||||
let Spellings = [GCC<"pure">];
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Regparm : TypeAttr {
|
||||
|
@ -2350,6 +2388,7 @@ def ArcWeakrefUnavailable : InheritableAttr {
|
|||
let Spellings = [Clang<"objc_arc_weak_reference_unavailable">];
|
||||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ObjCGC : TypeAttr {
|
||||
|
@ -2368,6 +2407,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
|
|||
let Spellings = [Clang<"objc_requires_property_definitions">];
|
||||
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Unused : InheritableAttr {
|
||||
|
@ -2382,6 +2422,7 @@ def Used : InheritableAttr {
|
|||
let Spellings = [GCC<"used">];
|
||||
let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Uuid : InheritableAttr {
|
||||
|
@ -2443,6 +2484,7 @@ def WarnUnused : InheritableAttr {
|
|||
let Spellings = [GCC<"warn_unused">];
|
||||
let Subjects = SubjectList<[Record]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def WarnUnusedResult : InheritableAttr {
|
||||
|
@ -2465,6 +2507,7 @@ def Weak : InheritableAttr {
|
|||
let Spellings = [GCC<"weak">];
|
||||
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def WeakImport : InheritableAttr {
|
||||
|
@ -2484,6 +2527,7 @@ def LTOVisibilityPublic : InheritableAttr {
|
|||
let Spellings = [Clang<"lto_visibility_public">];
|
||||
let Subjects = SubjectList<[Record]>;
|
||||
let Documentation = [LTOVisibilityDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
|
||||
|
@ -2500,6 +2544,7 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr,
|
|||
TargetSpecificAttr<TargetAnyX86> {
|
||||
let Spellings = [GCC<"no_caller_saved_registers">];
|
||||
let Documentation = [AnyX86NoCallerSavedRegistersDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{
|
||||
|
@ -2551,6 +2596,7 @@ def CFICanonicalJumpTable : InheritableAttr {
|
|||
let Spellings = [Clang<"cfi_canonical_jump_table">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
let Documentation = [CFICanonicalJumpTableDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
// 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 Subjects = SubjectList<[Field, SharedVar]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def PtGuardedVar : InheritableAttr {
|
||||
|
@ -2582,6 +2629,7 @@ def ScopedLockable : InheritableAttr {
|
|||
let Spellings = [Clang<"scoped_lockable", 0>];
|
||||
let Subjects = SubjectList<[Record]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Capability : InheritableAttr {
|
||||
|
@ -2678,6 +2726,7 @@ def NoThreadSafetyAnalysis : InheritableAttr {
|
|||
let Spellings = [Clang<"no_thread_safety_analysis">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def GuardedBy : InheritableAttr {
|
||||
|
@ -2814,6 +2863,7 @@ def ConsumableAutoCast : InheritableAttr {
|
|||
let Spellings = [Clang<"consumable_auto_cast_state", 0>];
|
||||
let Subjects = SubjectList<[CXXRecord]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def ConsumableSetOnRead : InheritableAttr {
|
||||
|
@ -2823,6 +2873,7 @@ def ConsumableSetOnRead : InheritableAttr {
|
|||
let Spellings = [Clang<"consumable_set_state_on_read", 0>];
|
||||
let Subjects = SubjectList<[CXXRecord]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def CallableWhen : InheritableAttr {
|
||||
|
@ -2929,6 +2980,7 @@ def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
|
|||
let Spellings = [Declspec<"novtable">];
|
||||
let Subjects = SubjectList<[CXXRecord]>;
|
||||
let Documentation = [MSNoVTableDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def : IgnoredAttr {
|
||||
|
@ -2954,6 +3006,7 @@ def MSStruct : InheritableAttr {
|
|||
let Spellings = [GCC<"ms_struct">];
|
||||
let Subjects = SubjectList<[Record]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
||||
|
@ -3002,6 +3055,7 @@ def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
|||
def SelectAny : InheritableAttr {
|
||||
let Spellings = [Declspec<"selectany">, GCC<"selectany">];
|
||||
let Documentation = [SelectAnyDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Thread : Attr {
|
||||
|
@ -3277,12 +3331,14 @@ def ExcludeFromExplicitInstantiation : InheritableAttr {
|
|||
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
|
||||
let Documentation = [ExcludeFromExplicitInstantiationDocs];
|
||||
let MeaningfulToClassTemplateDefinition = 1;
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def Reinitializes : InheritableAttr {
|
||||
let Spellings = [Clang<"reinitializes", 0>];
|
||||
let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>;
|
||||
let Documentation = [ReinitializesDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoDestroy : InheritableAttr {
|
||||
|
|
|
@ -68,7 +68,7 @@ struct ParsedAttrInfo {
|
|||
std::vector<Spelling> Spellings;
|
||||
|
||||
ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
|
||||
AttributeCommonInfo::UnknownAttribute)
|
||||
AttributeCommonInfo::NoSemaHandlerAttribute)
|
||||
: AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0),
|
||||
IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0),
|
||||
IsSupportedByPragmaAttribute(0) {}
|
||||
|
@ -99,6 +99,18 @@ struct ParsedAttrInfo {
|
|||
llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
|
||||
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);
|
||||
};
|
||||
|
|
|
@ -140,7 +140,8 @@ const ParsedAttrInfo &ParsedAttrInfo::get(const AttributeCommonInfo &A) {
|
|||
return *Ptr;
|
||||
|
||||
// If we failed to find a match then return a default ParsedAttrInfo.
|
||||
static ParsedAttrInfo DefaultParsedAttrInfo;
|
||||
static ParsedAttrInfo DefaultParsedAttrInfo(
|
||||
AttributeCommonInfo::UnknownAttribute);
|
||||
return DefaultParsedAttrInfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -6747,6 +6747,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
|
||||
switch (AL.getKind()) {
|
||||
default:
|
||||
if (AL.getInfo().handleDeclAttribute(S, D, AL) != ParsedAttrInfo::NotHandled)
|
||||
break;
|
||||
if (!AL.isStmtAttr()) {
|
||||
// Type attributes are handled elsewhere; silently move on.
|
||||
assert(AL.isTypeAttr() && "Non-type attribute not handled");
|
||||
|
@ -6769,15 +6771,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
handleSimpleAttributeWithExclusions<Mips16Attr, MicroMipsAttr,
|
||||
MipsInterruptAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NoMips16:
|
||||
handleSimpleAttribute<NoMips16Attr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_MicroMips:
|
||||
handleSimpleAttributeWithExclusions<MicroMipsAttr, Mips16Attr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NoMicroMips:
|
||||
handleSimpleAttribute<NoMicroMipsAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_MipsLongCall:
|
||||
handleSimpleAttributeWithExclusions<MipsLongCallAttr, MipsShortCallAttr>(
|
||||
S, D, AL);
|
||||
|
@ -6813,9 +6809,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_WebAssemblyImportName:
|
||||
handleWebAssemblyImportNameAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_IBAction:
|
||||
handleSimpleAttribute<IBActionAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_IBOutlet:
|
||||
handleIBOutlet(S, D, AL);
|
||||
break;
|
||||
|
@ -6840,9 +6833,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_AlwaysInline:
|
||||
handleAlwaysInlineAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Artificial:
|
||||
handleSimpleAttribute<ArtificialAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_AnalyzerNoReturn:
|
||||
handleAnalyzerNoReturnAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -6874,9 +6864,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_Constructor:
|
||||
handleConstructorAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_CXX11NoReturn:
|
||||
handleSimpleAttribute<CXX11NoReturnAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Deprecated:
|
||||
handleDeprecatedAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -6904,15 +6891,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_OptimizeNone:
|
||||
handleOptimizeNoneAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_FlagEnum:
|
||||
handleSimpleAttribute<FlagEnumAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_EnumExtensibility:
|
||||
handleEnumExtensibilityAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Flatten:
|
||||
handleSimpleAttribute<FlattenAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_SYCLKernel:
|
||||
handleSYCLKernelAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -6948,27 +6929,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_Restrict:
|
||||
handleRestrictAttr(S, D, AL);
|
||||
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:
|
||||
handleModeAttr(S, D, AL);
|
||||
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:
|
||||
if (auto *PVD = dyn_cast<ParmVarDecl>(D))
|
||||
handleNonNullAttrParameter(S, PVD, AL);
|
||||
|
@ -6987,9 +6950,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_AllocAlign:
|
||||
handleAllocAlignAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Overloadable:
|
||||
handleSimpleAttribute<OverloadableAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Ownership:
|
||||
handleOwnershipAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7045,9 +7005,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_ObjCRuntimeName:
|
||||
handleObjCRuntimeName(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ObjCRuntimeVisible:
|
||||
handleSimpleAttribute<ObjCRuntimeVisibleAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ObjCBoxable:
|
||||
handleObjCBoxable(S, D, AL);
|
||||
break;
|
||||
|
@ -7065,12 +7022,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
S.AddXConsumedAttr(D, AL, parsedAttrToRetainOwnershipKind(AL),
|
||||
/*IsTemplateInstantiation=*/false);
|
||||
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:
|
||||
handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
|
||||
S, D, AL, isValidOSObjectOutParameter(D),
|
||||
|
@ -7104,9 +7055,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_VecTypeHint:
|
||||
handleVecTypeHint(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ConstInit:
|
||||
handleSimpleAttribute<ConstInitAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_InitPriority:
|
||||
handleInitPriorityAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7137,12 +7085,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_Unavailable:
|
||||
handleAttrWithMessage<UnavailableAttr>(S, D, AL);
|
||||
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:
|
||||
handleObjCDirectAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7150,27 +7092,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
handleObjCDirectMembersAttr(S, D, AL);
|
||||
handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
|
||||
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:
|
||||
handleObjCSuppresProtocolAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ObjCRequiresPropertyDefs:
|
||||
handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Unused:
|
||||
handleUnusedAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ReturnsTwice:
|
||||
handleSimpleAttribute<ReturnsTwiceAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NotTailCalled:
|
||||
handleSimpleAttributeWithExclusions<NotTailCalledAttr, AlwaysInlineAttr>(
|
||||
S, D, AL);
|
||||
|
@ -7179,24 +7106,15 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
handleSimpleAttributeWithExclusions<DisableTailCallsAttr, NakedAttr>(S, D,
|
||||
AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Used:
|
||||
handleSimpleAttribute<UsedAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Visibility:
|
||||
handleVisibilityAttr(S, D, AL, false);
|
||||
break;
|
||||
case ParsedAttr::AT_TypeVisibility:
|
||||
handleVisibilityAttr(S, D, AL, true);
|
||||
break;
|
||||
case ParsedAttr::AT_WarnUnused:
|
||||
handleSimpleAttribute<WarnUnusedAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_WarnUnusedResult:
|
||||
handleWarnUnusedResult(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Weak:
|
||||
handleSimpleAttribute<WeakAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_WeakRef:
|
||||
handleWeakRefAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7206,9 +7124,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_TransparentUnion:
|
||||
handleTransparentUnionAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ObjCException:
|
||||
handleSimpleAttribute<ObjCExceptionAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ObjCMethodFamily:
|
||||
handleObjCMethodFamilyAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7224,37 +7139,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_Sentinel:
|
||||
handleSentinelAttr(S, D, AL);
|
||||
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:
|
||||
handleCleanupAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NoDebug:
|
||||
handleNoDebugAttr(S, D, AL);
|
||||
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_CDecl:
|
||||
case ParsedAttr::AT_FastCall:
|
||||
|
@ -7279,9 +7169,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_Pointer:
|
||||
handleLifetimeCategoryAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_OpenCLKernel:
|
||||
handleSimpleAttribute<OpenCLKernelAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_OpenCLAccess:
|
||||
handleOpenCLAccessAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7300,38 +7187,17 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_InternalLinkage:
|
||||
handleInternalLinkageAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
|
||||
handleSimpleAttribute<ExcludeFromExplicitInstantiationAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_LTOVisibilityPublic:
|
||||
handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, AL);
|
||||
break;
|
||||
|
||||
// Microsoft attributes:
|
||||
case ParsedAttr::AT_EmptyBases:
|
||||
handleSimpleAttribute<EmptyBasesAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_LayoutVersion:
|
||||
handleLayoutVersion(S, D, AL);
|
||||
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:
|
||||
handleUuidAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_MSInheritance:
|
||||
handleMSInheritanceAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_SelectAny:
|
||||
handleSimpleAttribute<SelectAnyAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_Thread:
|
||||
handleDeclspecThreadAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7350,24 +7216,15 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_AssertSharedLock:
|
||||
handleAssertSharedLockAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_GuardedVar:
|
||||
handleSimpleAttribute<GuardedVarAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_PtGuardedVar:
|
||||
handlePtGuardedVarAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_ScopedLockable:
|
||||
handleSimpleAttribute<ScopedLockableAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NoSanitize:
|
||||
handleNoSanitizeAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NoSanitizeSpecific:
|
||||
handleNoSanitizeSpecificAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_NoThreadSafetyAnalysis:
|
||||
handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_GuardedBy:
|
||||
handleGuardedByAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7419,12 +7276,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_Consumable:
|
||||
handleConsumableAttr(S, D, AL);
|
||||
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:
|
||||
handleCallableWhenAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7448,16 +7299,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case ParsedAttr::AT_TypeTagForDatatype:
|
||||
handleTypeTagForDatatypeAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_AnyX86NoCallerSavedRegisters:
|
||||
handleSimpleAttribute<AnyX86NoCallerSavedRegistersAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_RenderScriptKernel:
|
||||
handleSimpleAttribute<RenderScriptKernelAttr>(S, D, AL);
|
||||
break;
|
||||
|
||||
// XRay attributes.
|
||||
case ParsedAttr::AT_XRayInstrument:
|
||||
handleSimpleAttribute<XRayInstrumentAttr>(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_XRayLogArgs:
|
||||
handleXRayLogArgsAttr(S, D, AL);
|
||||
break;
|
||||
|
@ -7466,11 +7309,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
handlePatchableFunctionEntryAttr(S, D, AL);
|
||||
break;
|
||||
|
||||
// Move semantics attribute.
|
||||
case ParsedAttr::AT_Reinitializes:
|
||||
handleSimpleAttribute<ReinitializesAttr>(S, D, AL);
|
||||
break;
|
||||
|
||||
case ParsedAttr::AT_AlwaysDestroy:
|
||||
case ParsedAttr::AT_NoDestroy:
|
||||
handleDestroyAttr(S, D, AL);
|
||||
|
|
|
@ -3661,6 +3661,20 @@ static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
|
|||
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) {
|
||||
// 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.
|
||||
|
@ -3742,6 +3756,7 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
|
|||
GenerateTargetRequirements(Attr, Dupes, OS);
|
||||
GenerateSpellingIndexToSemanticSpelling(Attr, OS);
|
||||
PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
|
||||
GenerateHandleDeclAttribute(Attr, OS);
|
||||
OS << "static const ParsedAttrInfo" << I->first << " Instance;\n";
|
||||
OS << "};\n";
|
||||
OS << "const ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first
|
||||
|
|
Loading…
Reference in New Issue