Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -69,10 +69,12 @@ // // The code fragment is a boolean expression that will confirm that the subject // meets the requirements; the subject will have the name S, and will have the -// type specified by the base. It should be a simple boolean expression. -class SubsetSubject : AttrSubject { +// type specified by the base. It should be a simple boolean expression. The +// diagnostic string should be a comma-separated list of subject names. +class SubsetSubject : AttrSubject { AttrSubject Base = base; code CheckCode = check; + string DiagSpelling = diag; } // This is the type of a variable which C++11 allows alignas(...) to appertain @@ -81,30 +83,34 @@ [{S->getStorageClass() != VarDecl::Register && S->getKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && - S->getKind() != Decl::NonTypeTemplateParm}]>; -def NonBitField : SubsetSubjectisBitField()}]>; + S->getKind() != Decl::NonTypeTemplateParm}], + "local variables">; -def ObjCInstanceMethod : SubsetSubjectisInstanceMethod()}]>; +def NonBitField : SubsetSubjectisBitField()}], + "non-bit-field non-static data members">; +def ObjCInstanceMethod : SubsetSubjectisInstanceMethod()}], + "Objective-C instance methods">; + def ObjCInterfaceDeclInitMethod : SubsetSubjectgetMethodFamily() == OMF_init && (isa(S->getDeclContext()) || (isa(S->getDeclContext()) && - cast(S->getDeclContext())->IsClassExtension()))}]>; + cast(S->getDeclContext())->IsClassExtension()))}], + "init methods of interface or class extension declarations">; def Struct : SubsetSubjectisUnion()}]>; + [{!S->isUnion()}], "structs">; def TLSVar : SubsetSubjectgetTLSKind() != 0}]>; + [{S->getTLSKind() != 0}], "thread-local variables">; def SharedVar : SubsetSubjecthasGlobalStorage() && !S->getTLSKind()}]>; + [{S->hasGlobalStorage() && !S->getTLSKind()}], + "global variables">; -def GlobalVar : SubsetSubjecthasGlobalStorage()}]>; +def GlobalVar : SubsetSubjecthasGlobalStorage()}], + "global variables">; // FIXME: this hack is needed because DeclNodes.td defines the base Decl node // type to be a class, not a definition. This makes it impossible to create an @@ -113,11 +119,12 @@ // the case of a SubsetSubject, there's no way to express it without this hack. def DeclBase : AttrSubject; def FunctionLike : SubsetSubjectgetFunctionType(false) != nullptr}]>; + [{S->getFunctionType(false) != nullptr}], + "functions, function pointers">; -def OpenCLKernelFunction : SubsetSubjecthasAttr() -}]>; +def OpenCLKernelFunction + : SubsetSubjecthasAttr()}], + "kernel functions">; // HasFunctionProto is a more strict version of FunctionLike, so it should // never be specified in a Subjects list along with FunctionLike (due to the @@ -126,7 +133,8 @@ [{(S->getFunctionType(true) != nullptr && isa(S->getFunctionType())) || isa(S) || - isa(S)}]>; + isa(S)}], + "non-K&R-style functions">; // A single argument to an attribute class Argument { @@ -362,8 +370,7 @@ def AbiTag : Attr { let Spellings = [GCC<"abi_tag">]; let Args = [VariadicStringArgument<"Tags">]; - let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag, - "ExpectedStructClassVariableFunctionOrInlineNamespace">; + let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>; let Documentation = [AbiTagsDocs]; } @@ -376,8 +383,7 @@ def Alias : Attr { let Spellings = [GCC<"alias">]; let Args = [StringArgument<"Aliasee">]; - let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag, - "ExpectedFunctionGlobalVarMethodOrProperty">; + let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; let Documentation = [Undocumented]; } @@ -407,8 +413,7 @@ // , Declspec<"align_value"> ]; let Args = [ExprArgument<"Alignment">]; - let Subjects = SubjectList<[Var, TypedefName], WarnDiag, - "ExpectedVariableOrTypedef">; + let Subjects = SubjectList<[Var, TypedefName]>; let Documentation = [AlignValueDocs]; } @@ -427,7 +432,7 @@ def TLSModel : InheritableAttr { let Spellings = [GCC<"tls_model">]; - let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">; + let Subjects = SubjectList<[TLSVar], ErrorDiag>; let Args = [StringArgument<"Model">]; let Documentation = [TLSModelDocs]; } @@ -639,8 +644,7 @@ let Spellings = [GNU<"launch_bounds">]; let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>]; let LangOpts = [CUDA]; - let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag, - "ExpectedFunctionOrMethod">; + let Subjects = SubjectList<[ObjCMethod, FunctionLike]>; // An AST node is created for this attribute, but is not used by other parts // of the compiler. However, this node needs to exist in the AST because // non-LLVM backends may be relying on the attribute's presence. @@ -805,8 +809,7 @@ let Spellings = [GCC<"format">]; let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; - let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag, - "ExpectedFunctionWithProtoType">; + let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto]>; let Documentation = [FormatDocs]; } @@ -813,8 +816,7 @@ def FormatArg : InheritableAttr { let Spellings = [GCC<"format_arg">]; let Args = [IntArgument<"FormatIdx">]; - let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag, - "ExpectedFunctionWithProtoType">; + let Subjects = SubjectList<[ObjCMethod, HasFunctionProto]>; let Documentation = [Undocumented]; } @@ -834,8 +836,7 @@ def IBAction : InheritableAttr { let Spellings = [GNU<"ibaction">]; - let Subjects = SubjectList<[ObjCInstanceMethod], WarnDiag, - "ExpectedObjCInstanceMethod">; + let Subjects = SubjectList<[ObjCInstanceMethod]>; // An AST node is created for this attribute, but is not used by other parts // of the compiler. However, this node needs to exist in the AST because // external tools rely on it. @@ -915,8 +916,7 @@ def Mode : Attr { let Spellings = [GCC<"mode">]; - let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag, - "ExpectedVariableEnumFieldOrTypedef">; + let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>; let Args = [IdentifierArgument<"Mode">]; let Documentation = [Undocumented]; } @@ -1007,8 +1007,7 @@ // FIXME: This should be for OpenCLKernelFunction, but is not to // workaround needing to see kernel attribute before others to know if // this should be rejected on non-kernels. - let Subjects = SubjectList<[Function], ErrorDiag, - "ExpectedKernelFunction">; + let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def AMDGPUNumSGPR : InheritableAttr { @@ -1015,8 +1014,7 @@ let Spellings = [GNU<"amdgpu_num_sgpr">]; let Args = [UnsignedArgument<"NumSGPR">]; let Documentation = [AMDGPUNumSGPRDocs]; - let Subjects = SubjectList<[Function], ErrorDiag, - "ExpectedKernelFunction">; + let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } def NoSplitStack : InheritableAttr { @@ -1028,7 +1026,7 @@ def NonNull : InheritableAttr { let Spellings = [GCC<"nonnull">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag, - "ExpectedFunctionMethodOrParameter">; + "functions, methods, and parameters">; let Args = [VariadicUnsignedArgument<"Args">]; let AdditionalMembers = [{bool isNonNull(unsigned idx) const { @@ -1046,8 +1044,7 @@ def ReturnsNonNull : InheritableAttr { let Spellings = [GCC<"returns_nonnull">]; - let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag, - "ExpectedFunctionOrMethod">; + let Subjects = SubjectList<[ObjCMethod, Function]>; let Documentation = [ReturnsNonNullDocs]; } @@ -1118,8 +1115,7 @@ def ObjCBridge : InheritableAttr { let Spellings = [GNU<"objc_bridge">]; - let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, - "ExpectedStructOrUnionOrTypedef">; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } @@ -1229,8 +1225,7 @@ def ObjCDesignatedInitializer : Attr { let Spellings = [GNU<"objc_designated_initializer">]; - let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag, - "ExpectedObjCInterfaceDeclInitMethod">; + let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>; let Documentation = [Undocumented]; } @@ -1243,7 +1238,7 @@ def ObjCBoxable : Attr { let Spellings = [GNU<"objc_boxable">]; - let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">; + let Subjects = SubjectList<[Record], ErrorDiag>; let Documentation = [ObjCBoxableDocs]; } @@ -1280,8 +1275,7 @@ } }]; let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">]; - let Subjects = SubjectList<[HasFunctionProto], WarnDiag, - "ExpectedFunctionWithProtoType">; + let Subjects = SubjectList<[HasFunctionProto]>; let Documentation = [Undocumented]; } @@ -1344,9 +1338,8 @@ def Section : InheritableAttr { let Spellings = [GCC<"section">, Declspec<"allocate">]; let Args = [StringArgument<"Name">]; - let Subjects = SubjectList<[Function, GlobalVar, - ObjCMethod, ObjCProperty], ErrorDiag, - "ExpectedFunctionGlobalVarMethodOrProperty">; + let Subjects = + SubjectList<[ Function, GlobalVar, ObjCMethod, ObjCProperty ], ErrorDiag>; let Documentation = [SectionDocs]; } @@ -1508,8 +1501,7 @@ def Unused : InheritableAttr { let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">]; let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, - Field, ObjCMethod, FunctionLike], WarnDiag, - "ExpectedForMaybeUnused">; + Field, ObjCMethod, FunctionLike]>; let Documentation = [WarnMaybeUnusedDocs]; } @@ -1574,8 +1566,7 @@ let Spellings = [CXX11<"", "nodiscard", 201603>, CXX11<"clang", "warn_unused_result">, GCC<"warn_unused_result">]; - let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike], - WarnDiag, "ExpectedFunctionMethodEnumOrClass">; + let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike]>; let Documentation = [WarnUnusedResultsDocs]; } @@ -1651,15 +1642,13 @@ def GuardedVar : InheritableAttr { let Spellings = [GNU<"guarded_var">]; - let Subjects = SubjectList<[Field, SharedVar], WarnDiag, - "ExpectedFieldOrGlobalVar">; + let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } def PtGuardedVar : InheritableAttr { let Spellings = [GNU<"pt_guarded_var">]; - let Subjects = SubjectList<[Field, SharedVar], WarnDiag, - "ExpectedFieldOrGlobalVar">; + let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } @@ -1680,8 +1669,7 @@ let Spellings = [GNU<"capability">, CXX11<"clang", "capability">, GNU<"shared_capability">, CXX11<"clang", "shared_capability">]; - let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, - "ExpectedStructOrUnionOrTypedef">; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>; let Args = [StringArgument<"Name">]; let Accessors = [Accessor<"isShared", [GNU<"shared_capability">, @@ -1804,8 +1792,7 @@ let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; - let Subjects = SubjectList<[Field, SharedVar], WarnDiag, - "ExpectedFieldOrGlobalVar">; + let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } @@ -1816,8 +1803,7 @@ let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; - let Subjects = SubjectList<[Field, SharedVar], WarnDiag, - "ExpectedFieldOrGlobalVar">; + let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } @@ -1828,8 +1814,7 @@ let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; - let Subjects = SubjectList<[Field, SharedVar], WarnDiag, - "ExpectedFieldOrGlobalVar">; + let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } @@ -1840,8 +1825,7 @@ let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let DuplicatesAllowedWhileMerging = 1; - let Subjects = SubjectList<[Field, SharedVar], WarnDiag, - "ExpectedFieldOrGlobalVar">; + let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; } Index: include/clang/Basic/DeclNodes.td =================================================================== --- include/clang/Basic/DeclNodes.td +++ include/clang/Basic/DeclNodes.td @@ -1,63 +1,66 @@ class AttrSubject; -class Decl : AttrSubject { +class Decl : AttrSubject { bit Abstract = abstract; + string DiagSpelling = diagSpelling; } -class DDecl : Decl { +class DDecl + : Decl { Decl Base = base; } -class DeclContext { } +class DeclContext {} -def TranslationUnit : Decl, DeclContext; +def TranslationUnit : Decl, + DeclContext; def PragmaComment : Decl; def PragmaDetectMismatch : Decl; def ExternCContext : Decl, DeclContext; -def Named : Decl<1>; - def Namespace : DDecl, DeclContext; +def Named : Decl<"named declarations", 1>; + def Namespace : DDecl, DeclContext; def UsingDirective : DDecl; def NamespaceAlias : DDecl; - def Label : DDecl; - def Type : DDecl; - def TypedefName : DDecl; + def Label : DDecl; + def Type : DDecl; + def TypedefName : DDecl; def Typedef : DDecl; def TypeAlias : DDecl; def ObjCTypeParam : DDecl; def UnresolvedUsingTypename : DDecl; - def Tag : DDecl, DeclContext; - def Enum : DDecl; - def Record : DDecl; - def CXXRecord : DDecl; + def Tag : DDecl, DeclContext; + def Enum : DDecl; + def Record : DDecl; + def CXXRecord : DDecl; def ClassTemplateSpecialization : DDecl; def ClassTemplatePartialSpecialization : DDecl; def TemplateTypeParm : DDecl; - def Value : DDecl; - def EnumConstant : DDecl; + def Value : DDecl; + def EnumConstant : DDecl; def UnresolvedUsingValue : DDecl; def IndirectField : DDecl; def OMPDeclareReduction : DDecl, DeclContext; - def Declarator : DDecl; - def Field : DDecl; + def Declarator : DDecl; + def Field : DDecl; def ObjCIvar : DDecl; def ObjCAtDefsField : DDecl; def MSProperty : DDecl; - def Function : DDecl, DeclContext; + def Function : DDecl, DeclContext; def CXXMethod : DDecl; def CXXConstructor : DDecl; def CXXDestructor : DDecl; def CXXConversion : DDecl; - def Var : DDecl; + def Var : DDecl; def VarTemplateSpecialization : DDecl; def VarTemplatePartialSpecialization : DDecl; def ImplicitParam : DDecl; - def ParmVar : DDecl; + def ParmVar : DDecl; def OMPCapturedExpr : DDecl; def NonTypeTemplateParm : DDecl; - def Template : DDecl; - def RedeclarableTemplate : DDecl; + def Template : DDecl; + def RedeclarableTemplate : DDecl; def FunctionTemplate : DDecl; def ClassTemplate : DDecl; def VarTemplate : DDecl; @@ -66,15 +69,16 @@ def BuiltinTemplate : DDecl