diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -63,6 +63,53 @@ static PragmaHandlerRegistry::Add 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 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 + `_ 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 ======================= diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -2455,6 +2455,9 @@ 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 @@ All semantic processing of declaration attributes happens in `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(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 diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -513,6 +513,8 @@ 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 @@ let Spellings = [GCC<"artificial">]; let Subjects = SubjectList<[InlineFunction]>; let Documentation = [ArtificialDocs]; + let SimpleHandler = 1; } def XRayInstrument : InheritableAttr { @@ -692,6 +695,7 @@ Accessor<"neverXRayInstrument", [Clang<"xray_never_instrument">]>]; let Documentation = [XRayDocs]; + let SimpleHandler = 1; } def XRayLogArgs : InheritableAttr { @@ -948,6 +952,7 @@ let Spellings = [Clang<"os_consumes_this">]; let Subjects = SubjectList<[NonStaticCXXMethod]>; let Documentation = [RetainBehaviorDocs]; + let SimpleHandler = 1; } def Cleanup : InheritableAttr { @@ -972,6 +977,7 @@ def Const : InheritableAttr { let Spellings = [GCC<"const">, GCC<"__const">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ConstInit : InheritableAttr { @@ -983,6 +989,7 @@ let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>]; let Documentation = [ConstInitDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def Constructor : InheritableAttr { @@ -1113,6 +1120,7 @@ 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 @@ let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def OpenCLUnrollHint : InheritableAttr { @@ -1190,6 +1199,7 @@ let Subjects = SubjectList<[Function]>; let Documentation = [RenderScriptKernelAttributeDocs]; let LangOpts = [RenderScript]; + let SimpleHandler = 1; } def Deprecated : InheritableAttr { @@ -1214,6 +1224,7 @@ let Spellings = [Declspec<"empty_bases">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [EmptyBasesDocs]; + let SimpleHandler = 1; } def AllocSize : InheritableAttr { @@ -1285,6 +1296,7 @@ let Spellings = [Clang<"flag_enum">]; let Subjects = SubjectList<[Enum]>; let Documentation = [FlagEnumDocs]; + let SimpleHandler = 1; } def EnumExtensibility : InheritableAttr { @@ -1299,6 +1311,7 @@ let Spellings = [GCC<"flatten">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [FlattenDocs]; + let SimpleHandler = 1; } def Format : InheritableAttr { @@ -1344,6 +1357,7 @@ // 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 @@ let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>; let Documentation = [LifetimeBoundDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def TrivialABI : InheritableAttr { @@ -1393,6 +1408,7 @@ let Subjects = SubjectList<[CXXRecord]>; let Documentation = [TrivialABIDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def MaxFieldAlignment : InheritableAttr { @@ -1407,6 +1423,7 @@ // 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 @@ 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 @@ 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 @@ 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 { let Spellings = [GCC<"nomips16">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NoMicroMips : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"nomicromips">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [MicroMipsDocs]; + let SimpleHandler = 1; } def RISCVInterrupt : InheritableAttr, TargetSpecificAttr { @@ -1666,6 +1692,7 @@ let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSplitStackDocs]; + let SimpleHandler = 1; } def NonNull : InheritableParamAttr { @@ -1763,6 +1790,7 @@ let Spellings = [GCC<"no_instrument_function">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NotTailCalled : InheritableAttr { @@ -1775,6 +1803,7 @@ let Spellings = [Clang<"no_stack_protector">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoStackProtectorDocs]; + let SimpleHandler = 1; } def NoThrow : InheritableAttr { @@ -1837,6 +1866,7 @@ let Spellings = [Clang<"ns_consumes_self">]; let Subjects = SubjectList<[ObjCMethod]>; let Documentation = [RetainBehaviorDocs]; + let SimpleHandler = 1; } def NSConsumed : InheritableParamAttr { @@ -1849,6 +1879,7 @@ let Spellings = [Clang<"objc_exception">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCMethodFamily : InheritableAttr { @@ -1893,6 +1924,7 @@ let Spellings = [Clang<"objc_root_class">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCNonLazyClass : Attr { @@ -1900,12 +1932,14 @@ 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 @@ let Spellings = [Clang<"objc_runtime_visible">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCRuntimeVisibleDocs]; + let SimpleHandler = 1; } def ObjCClassStub : Attr { @@ -1952,6 +1987,7 @@ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCClassStubDocs]; let LangOpts = [ObjCNonFragileRuntime]; + let SimpleHandler = 1; } def ObjCBoxable : Attr { @@ -1970,6 +2006,7 @@ let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [OverloadableDocs]; + let SimpleHandler = 1; } def Override : InheritableAttr { @@ -2027,6 +2064,7 @@ def Pure : InheritableAttr { let Spellings = [GCC<"pure">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Regparm : TypeAttr { @@ -2350,6 +2388,7 @@ 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 @@ 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 @@ let Spellings = [GCC<"used">]; let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Uuid : InheritableAttr { @@ -2443,6 +2484,7 @@ let Spellings = [GCC<"warn_unused">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def WarnUnusedResult : InheritableAttr { @@ -2465,6 +2507,7 @@ let Spellings = [GCC<"weak">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def WeakImport : InheritableAttr { @@ -2484,6 +2527,7 @@ let Spellings = [Clang<"lto_visibility_public">]; let Subjects = SubjectList<[Record]>; let Documentation = [LTOVisibilityDocs]; + let SimpleHandler = 1; } def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr { @@ -2500,6 +2544,7 @@ TargetSpecificAttr { let Spellings = [GCC<"no_caller_saved_registers">]; let Documentation = [AnyX86NoCallerSavedRegistersDocs]; + let SimpleHandler = 1; } def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr{ @@ -2551,6 +2596,7 @@ 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 @@ let Spellings = [Clang<"guarded_var", 0>]; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def PtGuardedVar : InheritableAttr { @@ -2582,6 +2629,7 @@ let Spellings = [Clang<"scoped_lockable", 0>]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Capability : InheritableAttr { @@ -2678,6 +2726,7 @@ let Spellings = [Clang<"no_thread_safety_analysis">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def GuardedBy : InheritableAttr { @@ -2814,6 +2863,7 @@ 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 @@ 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 @@ let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [MSNoVTableDocs]; + let SimpleHandler = 1; } def : IgnoredAttr { @@ -2954,6 +3006,7 @@ let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def DLLExport : InheritableAttr, TargetSpecificAttr { @@ -3002,6 +3055,7 @@ def SelectAny : InheritableAttr { let Spellings = [Declspec<"selectany">, GCC<"selectany">]; let Documentation = [SelectAnyDocs]; + let SimpleHandler = 1; } def Thread : Attr { @@ -3277,12 +3331,14 @@ 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 { diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -68,7 +68,7 @@ std::vector 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 @@ llvm::SmallVectorImpl> &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); }; diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -140,7 +140,8 @@ return *Ptr; // If we failed to find a match then return a default ParsedAttrInfo. - static ParsedAttrInfo DefaultParsedAttrInfo; + static ParsedAttrInfo DefaultParsedAttrInfo( + AttributeCommonInfo::UnknownAttribute); return DefaultParsedAttrInfo; } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6747,6 +6747,8 @@ 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 @@ handleSimpleAttributeWithExclusions(S, D, AL); break; - case ParsedAttr::AT_NoMips16: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_MicroMips: handleSimpleAttributeWithExclusions(S, D, AL); break; - case ParsedAttr::AT_NoMicroMips: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_MipsLongCall: handleSimpleAttributeWithExclusions( S, D, AL); @@ -6813,9 +6809,6 @@ case ParsedAttr::AT_WebAssemblyImportName: handleWebAssemblyImportNameAttr(S, D, AL); break; - case ParsedAttr::AT_IBAction: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_IBOutlet: handleIBOutlet(S, D, AL); break; @@ -6840,9 +6833,6 @@ case ParsedAttr::AT_AlwaysInline: handleAlwaysInlineAttr(S, D, AL); break; - case ParsedAttr::AT_Artificial: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_AnalyzerNoReturn: handleAnalyzerNoReturnAttr(S, D, AL); break; @@ -6874,9 +6864,6 @@ case ParsedAttr::AT_Constructor: handleConstructorAttr(S, D, AL); break; - case ParsedAttr::AT_CXX11NoReturn: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_Deprecated: handleDeprecatedAttr(S, D, AL); break; @@ -6904,15 +6891,9 @@ case ParsedAttr::AT_OptimizeNone: handleOptimizeNoneAttr(S, D, AL); break; - case ParsedAttr::AT_FlagEnum: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break; - case ParsedAttr::AT_Flatten: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_SYCLKernel: handleSYCLKernelAttr(S, D, AL); break; @@ -6948,27 +6929,9 @@ case ParsedAttr::AT_Restrict: handleRestrictAttr(S, D, AL); break; - case ParsedAttr::AT_LifetimeBound: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_MayAlias: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_Mode: handleModeAttr(S, D, AL); break; - case ParsedAttr::AT_NoAlias: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_NoCommon: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_NoSplitStack: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_NoUniqueAddress: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_NonNull: if (auto *PVD = dyn_cast(D)) handleNonNullAttrParameter(S, PVD, AL); @@ -6987,9 +6950,6 @@ case ParsedAttr::AT_AllocAlign: handleAllocAlignAttr(S, D, AL); break; - case ParsedAttr::AT_Overloadable: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_Ownership: handleOwnershipAttr(S, D, AL); break; @@ -7045,9 +7005,6 @@ case ParsedAttr::AT_ObjCRuntimeName: handleObjCRuntimeName(S, D, AL); break; - case ParsedAttr::AT_ObjCRuntimeVisible: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_ObjCBoxable: handleObjCBoxable(S, D, AL); break; @@ -7065,12 +7022,6 @@ S.AddXConsumedAttr(D, AL, parsedAttrToRetainOwnershipKind(AL), /*IsTemplateInstantiation=*/false); break; - case ParsedAttr::AT_NSConsumesSelf: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_OSConsumesThis: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_OSReturnsRetainedOnZero: handleSimpleAttributeOrDiagnose( S, D, AL, isValidOSObjectOutParameter(D), @@ -7104,9 +7055,6 @@ case ParsedAttr::AT_VecTypeHint: handleVecTypeHint(S, D, AL); break; - case ParsedAttr::AT_ConstInit: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_InitPriority: handleInitPriorityAttr(S, D, AL); break; @@ -7137,12 +7085,6 @@ case ParsedAttr::AT_Unavailable: handleAttrWithMessage(S, D, AL); break; - case ParsedAttr::AT_ArcWeakrefUnavailable: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_ObjCRootClass: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_ObjCDirect: handleObjCDirectAttr(S, D, AL); break; @@ -7150,27 +7092,12 @@ handleObjCDirectMembersAttr(S, D, AL); handleSimpleAttribute(S, D, AL); break; - case ParsedAttr::AT_ObjCNonLazyClass: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_ObjCSubclassingRestricted: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_ObjCClassStub: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_ObjCExplicitProtocolImpl: handleObjCSuppresProtocolAttr(S, D, AL); break; - case ParsedAttr::AT_ObjCRequiresPropertyDefs: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_Unused: handleUnusedAttr(S, D, AL); break; - case ParsedAttr::AT_ReturnsTwice: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_NotTailCalled: handleSimpleAttributeWithExclusions( S, D, AL); @@ -7179,24 +7106,15 @@ handleSimpleAttributeWithExclusions(S, D, AL); break; - case ParsedAttr::AT_Used: - handleSimpleAttribute(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(S, D, AL); - break; case ParsedAttr::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, AL); break; - case ParsedAttr::AT_Weak: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_WeakRef: handleWeakRefAttr(S, D, AL); break; @@ -7206,9 +7124,6 @@ case ParsedAttr::AT_TransparentUnion: handleTransparentUnionAttr(S, D, AL); break; - case ParsedAttr::AT_ObjCException: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_ObjCMethodFamily: handleObjCMethodFamilyAttr(S, D, AL); break; @@ -7224,37 +7139,12 @@ case ParsedAttr::AT_Sentinel: handleSentinelAttr(S, D, AL); break; - case ParsedAttr::AT_Const: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_Pure: - handleSimpleAttribute(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(S, D, AL); - break; - case ParsedAttr::AT_Convergent: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_NoInline: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_NoInstrumentFunction: // Interacts with -pg. - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_NoStackProtector: - // Interacts with -fstack-protector options. - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_CFICanonicalJumpTable: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_StdCall: case ParsedAttr::AT_CDecl: case ParsedAttr::AT_FastCall: @@ -7279,9 +7169,6 @@ case ParsedAttr::AT_Pointer: handleLifetimeCategoryAttr(S, D, AL); break; - case ParsedAttr::AT_OpenCLKernel: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_OpenCLAccess: handleOpenCLAccessAttr(S, D, AL); break; @@ -7300,38 +7187,17 @@ case ParsedAttr::AT_InternalLinkage: handleInternalLinkageAttr(S, D, AL); break; - case ParsedAttr::AT_ExcludeFromExplicitInstantiation: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_LTOVisibilityPublic: - handleSimpleAttribute(S, D, AL); - break; // Microsoft attributes: - case ParsedAttr::AT_EmptyBases: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_LayoutVersion: handleLayoutVersion(S, D, AL); break; - case ParsedAttr::AT_TrivialABI: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_MSNoVTable: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_MSStruct: - handleSimpleAttribute(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(S, D, AL); - break; case ParsedAttr::AT_Thread: handleDeclspecThreadAttr(S, D, AL); break; @@ -7350,24 +7216,15 @@ case ParsedAttr::AT_AssertSharedLock: handleAssertSharedLockAttr(S, D, AL); break; - case ParsedAttr::AT_GuardedVar: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_PtGuardedVar: handlePtGuardedVarAttr(S, D, AL); break; - case ParsedAttr::AT_ScopedLockable: - handleSimpleAttribute(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(S, D, AL); - break; case ParsedAttr::AT_GuardedBy: handleGuardedByAttr(S, D, AL); break; @@ -7419,12 +7276,6 @@ case ParsedAttr::AT_Consumable: handleConsumableAttr(S, D, AL); break; - case ParsedAttr::AT_ConsumableAutoCast: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_ConsumableSetOnRead: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_CallableWhen: handleCallableWhenAttr(S, D, AL); break; @@ -7448,16 +7299,8 @@ case ParsedAttr::AT_TypeTagForDatatype: handleTypeTagForDatatypeAttr(S, D, AL); break; - case ParsedAttr::AT_AnyX86NoCallerSavedRegisters: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_RenderScriptKernel: - handleSimpleAttribute(S, D, AL); - break; + // XRay attributes. - case ParsedAttr::AT_XRayInstrument: - handleSimpleAttribute(S, D, AL); - break; case ParsedAttr::AT_XRayLogArgs: handleXRayLogArgsAttr(S, D, AL); break; @@ -7466,11 +7309,6 @@ handlePatchableFunctionEntryAttr(S, D, AL); break; - // Move semantics attribute. - case ParsedAttr::AT_Reinitializes: - handleSimpleAttribute(S, D, AL); - break; - case ParsedAttr::AT_AlwaysDestroy: case ParsedAttr::AT_NoDestroy: handleDestroyAttr(S, D, AL); diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3661,6 +3661,20 @@ 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 @@ 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