Index: clang/docs/ClangPlugins.rst =================================================================== --- clang/docs/ClangPlugins.rst +++ clang/docs/ClangPlugins.rst @@ -63,6 +63,28 @@ 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() { + AttrKind = ParsedAttr::NoSemaHandlerAttribute; + Spellings.push_back({ParsedAttr::AS_GNU,"example"}); + } + virtual bool handleDeclAttribute(Sema &S, Decl *D, + const ParsedAttr &Attr) const { + // Handle the attribute + } + }; + + static ParsedAttrInfoRegistry::Add Z("example_attr","example attribute description"); + Putting it all together ======================= Index: clang/docs/InternalsManual.rst =================================================================== --- clang/docs/InternalsManual.rst +++ clang/docs/InternalsManual.rst @@ -2449,6 +2449,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 @@ -2475,12 +2478,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 Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -489,6 +489,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 @@ -657,6 +659,7 @@ let Spellings = [GCC<"artificial">]; let Subjects = SubjectList<[InlineFunction], WarnDiag>; let Documentation = [ArtificialDocs]; + let SimpleHandler = 1; } def XRayInstrument : InheritableAttr { @@ -668,6 +671,7 @@ Accessor<"neverXRayInstrument", [Clang<"xray_never_instrument">]>]; let Documentation = [XRayDocs]; + let SimpleHandler = 1; } def XRayLogArgs : InheritableAttr { @@ -924,6 +928,7 @@ let Spellings = [Clang<"os_consumes_this">]; let Subjects = SubjectList<[NonStaticCXXMethod]>; let Documentation = [RetainBehaviorDocs]; + let SimpleHandler = 1; } def Cleanup : InheritableAttr { @@ -948,6 +953,7 @@ def Const : InheritableAttr { let Spellings = [GCC<"const">, GCC<"__const">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ConstInit : InheritableAttr { @@ -959,6 +965,7 @@ let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>]; let Documentation = [ConstInitDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def Constructor : InheritableAttr { @@ -1089,6 +1096,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 @@ -1097,6 +1105,7 @@ let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def OpenCLUnrollHint : InheritableAttr { @@ -1166,6 +1175,7 @@ let Subjects = SubjectList<[Function]>; let Documentation = [RenderScriptKernelAttributeDocs]; let LangOpts = [RenderScript]; + let SimpleHandler = 1; } def Deprecated : InheritableAttr { @@ -1190,6 +1200,7 @@ let Spellings = [Declspec<"empty_bases">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [EmptyBasesDocs]; + let SimpleHandler = 1; } def AllocSize : InheritableAttr { @@ -1261,6 +1272,7 @@ let Spellings = [Clang<"flag_enum">]; let Subjects = SubjectList<[Enum]>; let Documentation = [FlagEnumDocs]; + let SimpleHandler = 1; } def EnumExtensibility : InheritableAttr { @@ -1275,6 +1287,7 @@ let Spellings = [GCC<"flatten">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [FlattenDocs]; + let SimpleHandler = 1; } def Format : InheritableAttr { @@ -1320,6 +1333,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 { @@ -1360,6 +1374,7 @@ let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>; let Documentation = [LifetimeBoundDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def TrivialABI : InheritableAttr { @@ -1369,6 +1384,7 @@ let Subjects = SubjectList<[CXXRecord]>; let Documentation = [TrivialABIDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def MaxFieldAlignment : InheritableAttr { @@ -1383,6 +1399,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 { @@ -1488,12 +1505,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 { @@ -1506,12 +1525,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 { @@ -1524,30 +1545,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 { @@ -1642,6 +1668,7 @@ let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSplitStackDocs]; + let SimpleHandler = 1; } def NonNull : InheritableParamAttr { @@ -1739,6 +1766,7 @@ let Spellings = [GCC<"no_instrument_function">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NotTailCalled : InheritableAttr { @@ -1751,6 +1779,7 @@ let Spellings = [Clang<"no_stack_protector">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoStackProtectorDocs]; + let SimpleHandler = 1; } def NoThrow : InheritableAttr { @@ -1813,6 +1842,7 @@ let Spellings = [Clang<"ns_consumes_self">]; let Subjects = SubjectList<[ObjCMethod]>; let Documentation = [RetainBehaviorDocs]; + let SimpleHandler = 1; } def NSConsumed : InheritableParamAttr { @@ -1825,6 +1855,7 @@ let Spellings = [Clang<"objc_exception">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCMethodFamily : InheritableAttr { @@ -1869,6 +1900,7 @@ let Spellings = [Clang<"objc_root_class">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCNonLazyClass : Attr { @@ -1876,12 +1908,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 { @@ -1921,6 +1955,7 @@ let Spellings = [Clang<"objc_runtime_visible">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCRuntimeVisibleDocs]; + let SimpleHandler = 1; } def ObjCClassStub : Attr { @@ -1928,6 +1963,7 @@ let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCClassStubDocs]; let LangOpts = [ObjCNonFragileRuntime]; + let SimpleHandler = 1; } def ObjCBoxable : Attr { @@ -1946,6 +1982,7 @@ let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [OverloadableDocs]; + let SimpleHandler = 1; } def Override : InheritableAttr { @@ -2003,6 +2040,7 @@ def Pure : InheritableAttr { let Spellings = [GCC<"pure">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Regparm : TypeAttr { @@ -2326,6 +2364,7 @@ let Spellings = [Clang<"objc_arc_weak_reference_unavailable">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCGC : TypeAttr { @@ -2344,6 +2383,7 @@ let Spellings = [Clang<"objc_requires_property_definitions">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Unused : InheritableAttr { @@ -2358,6 +2398,7 @@ let Spellings = [GCC<"used">]; let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Uuid : InheritableAttr { @@ -2419,6 +2460,7 @@ let Spellings = [GCC<"warn_unused">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def WarnUnusedResult : InheritableAttr { @@ -2441,6 +2483,7 @@ let Spellings = [GCC<"weak">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def WeakImport : InheritableAttr { @@ -2460,6 +2503,7 @@ let Spellings = [Clang<"lto_visibility_public">]; let Subjects = SubjectList<[Record]>; let Documentation = [LTOVisibilityDocs]; + let SimpleHandler = 1; } def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr { @@ -2476,6 +2520,7 @@ TargetSpecificAttr { let Spellings = [GCC<"no_caller_saved_registers">]; let Documentation = [AnyX86NoCallerSavedRegistersDocs]; + let SimpleHandler = 1; } def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr{ @@ -2527,6 +2572,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) @@ -2539,6 +2585,7 @@ let Spellings = [Clang<"guarded_var", 0>]; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def PtGuardedVar : InheritableAttr { @@ -2558,6 +2605,7 @@ let Spellings = [Clang<"scoped_lockable", 0>]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Capability : InheritableAttr { @@ -2658,6 +2706,7 @@ let Spellings = [Clang<"no_thread_safety_analysis">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def GuardedBy : InheritableAttr { @@ -2794,6 +2843,7 @@ let Spellings = [Clang<"consumable_auto_cast_state", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ConsumableSetOnRead : InheritableAttr { @@ -2803,6 +2853,7 @@ let Spellings = [Clang<"consumable_set_state_on_read", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def CallableWhen : InheritableAttr { @@ -2909,6 +2960,7 @@ let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [MSNoVTableDocs]; + let SimpleHandler = 1; } def : IgnoredAttr { @@ -2934,6 +2986,7 @@ let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def DLLExport : InheritableAttr, TargetSpecificAttr { @@ -2982,6 +3035,7 @@ def SelectAny : InheritableAttr { let Spellings = [Declspec<"selectany">, GCC<"selectany">]; let Documentation = [SelectAnyDocs]; + let SimpleHandler = 1; } def Thread : Attr { @@ -3443,12 +3497,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 { Index: clang/include/clang/Sema/ParsedAttr.h =================================================================== --- clang/include/clang/Sema/ParsedAttr.h +++ clang/include/clang/Sema/ParsedAttr.h @@ -98,6 +98,12 @@ llvm::SmallVectorImpl> &Rules, const LangOptions &LangOpts) const { } + /// If this ParsedAttrInfo knows how to apply an attribute to a decl then do + /// so and return true. If not return false. + virtual bool handleDeclAttribute(Sema &S, Decl *D, + const ParsedAttr &Attr) const { + return false; + } static std::unique_ptr get(AttributeCommonInfo::Kind); static std::unique_ptr Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -6698,6 +6698,9 @@ if (handleCommonAttributeFeatures(S, D, AL)) return; + if (AL.getInfo().handleDeclAttribute(S, D, AL)) + return; + switch (AL.getKind()) { default: if (!AL.isStmtAttr()) { @@ -6722,15 +6725,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); @@ -6766,9 +6763,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; @@ -6793,9 +6787,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; @@ -6827,9 +6818,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; @@ -6857,15 +6845,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; @@ -6901,27 +6883,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); @@ -6940,9 +6904,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; @@ -6998,9 +6959,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; @@ -7018,12 +6976,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), @@ -7057,9 +7009,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; @@ -7090,12 +7039,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; @@ -7103,27 +7046,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); @@ -7132,24 +7060,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; @@ -7159,9 +7078,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; @@ -7177,37 +7093,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: @@ -7232,9 +7123,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; @@ -7253,38 +7141,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; @@ -7303,24 +7170,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; @@ -7372,12 +7230,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; @@ -7401,16 +7253,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; @@ -7419,11 +7263,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); Index: clang/utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangAttrEmitter.cpp +++ clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3576,6 +3576,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 bool 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 true;\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. @@ -3657,6 +3671,7 @@ GenerateTargetRequirements(Attr, Dupes, SS); GenerateSpellingIndexToSemanticSpelling(Attr, SS); PragmaAttributeSupport.generateStrictConformsTo(*I->second, SS); + GenerateHandleDeclAttribute(Attr, SS); SS << "};\n"; SS << "static ParsedAttrInfoRegistry::Add<" << AttrInfoName << "> "; SS << AttrInfoName << "Instance(\"" << AttrName << "\",\"\");\n";