Browse Source

Determine the attribute subject for diagnostics based on declarative information in DeclNodes.td. This greatly reduces the number of enumerated values used for more complex diagnostics; these are now only required when the "attribute only applies to" diagnostic needs to be generated manually as part of semantic processing.

This also clarifies some terminology used by the diagnostic (methods -> Objective-C methods, fields -> non-static data members, etc).

Many of the tests needed to be updated in multiple places for the diagnostic wording tweaks. The first instance of the diagnostic for that attribute is fully specified and subsequent instances cut off the complete list (to make it easier if additional subjects are added in the future for the attribute).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@319002 91177308-0d34-0410-b5e6-96231b3b80d8
Aaron Ballman 7 years ago
parent
commit
f3dc130210
53 changed files with 312 additions and 460 deletions
  1. 69 94
      include/clang/Basic/Attr.td
  2. 31 28
      include/clang/Basic/DeclNodes.td
  3. 5 34
      include/clang/Basic/DiagnosticSemaKinds.td
  4. 0 33
      include/clang/Sema/AttributeList.h
  5. 3 3
      test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
  6. 1 1
      test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
  7. 3 3
      test/CodeGenObjC/objc-asm-attribute-neg-test.m
  8. 2 2
      test/Misc/pragma-attribute-supported-attributes-list.test
  9. 2 2
      test/Parser/MicrosoftExtensions.cpp
  10. 1 1
      test/Parser/cxx0x-attributes.cpp
  11. 1 1
      test/Parser/ms-square-bracket-attributes.mm
  12. 2 2
      test/Sema/attr-capabilities.c
  13. 1 1
      test/Sema/attr-disable-tail-calls.c
  14. 1 1
      test/Sema/attr-minsize.c
  15. 2 2
      test/Sema/attr-mode.c
  16. 1 1
      test/Sema/attr-nodebug.c
  17. 2 2
      test/Sema/attr-section.c
  18. 2 2
      test/Sema/attr-weak.c
  19. 1 1
      test/Sema/builtin-assume-aligned.c
  20. 1 1
      test/Sema/c2x-nodiscard.c
  21. 6 6
      test/Sema/dllexport.c
  22. 6 6
      test/Sema/dllimport.c
  23. 1 1
      test/Sema/internal_linkage.c
  24. 1 1
      test/Sema/nonnull.c
  25. 2 2
      test/Sema/pragma-ms_struct.c
  26. 1 1
      test/Sema/types.c
  27. 1 1
      test/Sema/unused-expr.c
  28. 1 1
      test/Sema/warn-thread-safety-analysis.c
  29. 1 1
      test/Sema/xray-always-instrument-attr.c
  30. 1 1
      test/Sema/xray-always-instrument-attr.cpp
  31. 1 1
      test/Sema/xray-log-args-oob.c
  32. 1 1
      test/Sema/xray-log-args-oob.cpp
  33. 1 1
      test/SemaCUDA/launch_bounds.cu
  34. 5 5
      test/SemaCXX/attr-lto-visibility-public.cpp
  35. 1 1
      test/SemaCXX/attr-mode-tmpl.cpp
  36. 4 4
      test/SemaCXX/attr-require-constant-initialization.cpp
  37. 1 1
      test/SemaCXX/attr-weak.cpp
  38. 1 1
      test/SemaCXX/builtin-assume-aligned-tmpl.cpp
  39. 8 8
      test/SemaCXX/dllexport.cpp
  40. 8 8
      test/SemaCXX/dllimport.cpp
  41. 4 4
      test/SemaCXX/internal_linkage.cpp
  42. 6 6
      test/SemaCXX/warn-consumed-parsing.cpp
  43. 4 4
      test/SemaCXX/warn-thread-safety-analysis.cpp
  44. 36 36
      test/SemaCXX/warn-thread-safety-parsing.cpp
  45. 1 1
      test/SemaCXX/warn-unused-attribute.cpp
  46. 1 1
      test/SemaObjC/arc-property-lifetime.m
  47. 6 6
      test/SemaObjC/dllexport.m
  48. 6 6
      test/SemaObjC/dllimport.m
  49. 3 3
      test/SemaObjC/format-arg-attribute.m
  50. 3 3
      test/SemaObjC/objc-asm-attribute-neg-test.m
  51. 1 1
      test/SemaObjC/objcbridge-attribute-arc.m
  52. 1 1
      test/SemaObjC/objcbridge-attribute.m
  53. 57 121
      utils/TableGen/ClangAttrEmitter.cpp

+ 69 - 94
include/clang/Basic/Attr.td

@@ -69,10 +69,12 @@ include "clang/Basic/StmtNodes.td"
 //
 //
 // The code fragment is a boolean expression that will confirm that the subject
 // 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
 // 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 base, code check> : 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 base, code check, string diag> : AttrSubject {
   AttrSubject Base = base;
   AttrSubject Base = base;
   code CheckCode = check;
   code CheckCode = check;
+  string DiagSpelling = diag;
 }
 }
 
 
 // This is the type of a variable which C++11 allows alignas(...) to appertain
 // This is the type of a variable which C++11 allows alignas(...) to appertain
@@ -81,32 +83,38 @@ def NormalVar : SubsetSubject<Var,
                               [{S->getStorageClass() != VarDecl::Register &&
                               [{S->getStorageClass() != VarDecl::Register &&
                                 S->getKind() != Decl::ImplicitParam &&
                                 S->getKind() != Decl::ImplicitParam &&
                                 S->getKind() != Decl::ParmVar &&
                                 S->getKind() != Decl::ParmVar &&
-                                S->getKind() != Decl::NonTypeTemplateParm}]>;
+                                S->getKind() != Decl::NonTypeTemplateParm}],
+                              "local variables">;
 def NonParmVar : SubsetSubject<Var,
 def NonParmVar : SubsetSubject<Var,
-                               [{S->getKind() != Decl::ParmVar}]>;
+                               [{S->getKind() != Decl::ParmVar}],
+                               "variables and functions">;
 def NonBitField : SubsetSubject<Field,
 def NonBitField : SubsetSubject<Field,
-                                [{!S->isBitField()}]>;
+                                [{!S->isBitField()}],
+                                "non-bit-field non-static data members">;
 
 
 def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
 def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
-                                       [{S->isInstanceMethod()}]>;
+                                       [{S->isInstanceMethod()}],
+                                       "Objective-C instance methods">;
 
 
 def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
 def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
                                [{S->getMethodFamily() == OMF_init &&
                                [{S->getMethodFamily() == OMF_init &&
                                  (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
                                  (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
                                   (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
                                   (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
-            cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}]>;
+            cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}],
+            "init methods of interface or class extension declarations">;
 
 
 def Struct : SubsetSubject<Record,
 def Struct : SubsetSubject<Record,
-                           [{!S->isUnion()}]>;
+                           [{!S->isUnion()}], "structs">;
 
 
 def TLSVar : SubsetSubject<Var,
 def TLSVar : SubsetSubject<Var,
-                           [{S->getTLSKind() != 0}]>;
+                           [{S->getTLSKind() != 0}], "thread-local variables">;
 
 
 def SharedVar : SubsetSubject<Var,
 def SharedVar : SubsetSubject<Var,
-                              [{S->hasGlobalStorage() && !S->getTLSKind()}]>;
+                              [{S->hasGlobalStorage() && !S->getTLSKind()}],
+                              "global variables">;
 
 
 def GlobalVar : SubsetSubject<Var,
 def GlobalVar : SubsetSubject<Var,
-                             [{S->hasGlobalStorage()}]>;
+                             [{S->hasGlobalStorage()}], "global variables">;
 
 
 // FIXME: this hack is needed because DeclNodes.td defines the base Decl node
 // 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
 // type to be a class, not a definition. This makes it impossible to create an
@@ -115,11 +123,12 @@ def GlobalVar : SubsetSubject<Var,
 // the case of a SubsetSubject, there's no way to express it without this hack.
 // the case of a SubsetSubject, there's no way to express it without this hack.
 def DeclBase : AttrSubject;
 def DeclBase : AttrSubject;
 def FunctionLike : SubsetSubject<DeclBase,
 def FunctionLike : SubsetSubject<DeclBase,
-                                  [{S->getFunctionType(false) != nullptr}]>;
+                                 [{S->getFunctionType(false) != nullptr}],
+                                 "functions, function pointers">;
 
 
-def OpenCLKernelFunction : SubsetSubject<Function, [{
-  S->hasAttr<OpenCLKernelAttr>()
-}]>;
+def OpenCLKernelFunction
+    : SubsetSubject<Function, [{S->hasAttr<OpenCLKernelAttr>()}],
+                    "kernel functions">;
 
 
 // HasFunctionProto is a more strict version of FunctionLike, so it should
 // HasFunctionProto is a more strict version of FunctionLike, so it should
 // never be specified in a Subjects list along with FunctionLike (due to the
 // never be specified in a Subjects list along with FunctionLike (due to the
@@ -128,7 +137,8 @@ def HasFunctionProto : SubsetSubject<DeclBase,
                                      [{(S->getFunctionType(true) != nullptr &&
                                      [{(S->getFunctionType(true) != nullptr &&
                               isa<FunctionProtoType>(S->getFunctionType())) ||
                               isa<FunctionProtoType>(S->getFunctionType())) ||
                                        isa<ObjCMethodDecl>(S) ||
                                        isa<ObjCMethodDecl>(S) ||
-                                       isa<BlockDecl>(S)}]>;
+                                       isa<BlockDecl>(S)}],
+                                     "non-K&R-style functions">;
 
 
 // A single argument to an attribute
 // A single argument to an attribute
 class Argument<string name, bit optional, bit fake = 0> {
 class Argument<string name, bit optional, bit fake = 0> {
@@ -502,8 +512,7 @@ class IgnoredAttr : Attr {
 def AbiTag : Attr {
 def AbiTag : Attr {
   let Spellings = [GCC<"abi_tag">];
   let Spellings = [GCC<"abi_tag">];
   let Args = [VariadicStringArgument<"Tags">];
   let Args = [VariadicStringArgument<"Tags">];
-  let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
-      "ExpectedStructClassVariableFunctionOrInlineNamespace">;
+  let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>;
   let MeaningfulToClassTemplateDefinition = 1;
   let MeaningfulToClassTemplateDefinition = 1;
   let Documentation = [AbiTagsDocs];
   let Documentation = [AbiTagsDocs];
 }
 }
@@ -517,8 +526,7 @@ def AddressSpace : TypeAttr {
 def Alias : Attr {
 def Alias : Attr {
   let Spellings = [GCC<"alias">];
   let Spellings = [GCC<"alias">];
   let Args = [StringArgument<"Aliasee">];
   let Args = [StringArgument<"Aliasee">];
-  let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
-                             "ExpectedFunctionOrGlobalVar">;
+  let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -548,8 +556,7 @@ def AlignValue : Attr {
     // , Declspec<"align_value">
     // , Declspec<"align_value">
   ];
   ];
   let Args = [ExprArgument<"Alignment">];
   let Args = [ExprArgument<"Alignment">];
-  let Subjects = SubjectList<[Var, TypedefName], WarnDiag,
-                             "ExpectedVariableOrTypedef">;
+  let Subjects = SubjectList<[Var, TypedefName]>;
   let Documentation = [AlignValueDocs];
   let Documentation = [AlignValueDocs];
 }
 }
 
 
@@ -569,8 +576,7 @@ def AlwaysInline : InheritableAttr {
 def XRayInstrument : InheritableAttr {
 def XRayInstrument : InheritableAttr {
   let Spellings = [Clang<"xray_always_instrument">,
   let Spellings = [Clang<"xray_always_instrument">,
                    Clang<"xray_never_instrument">];
                    Clang<"xray_never_instrument">];
-  let Subjects = SubjectList<[CXXMethod, ObjCMethod, Function], WarnDiag,
-                              "ExpectedFunctionOrMethod">;
+  let Subjects = SubjectList<[Function, ObjCMethod]>;
   let Accessors = [Accessor<"alwaysXRayInstrument",
   let Accessors = [Accessor<"alwaysXRayInstrument",
                      [Clang<"xray_always_instrument">]>,
                      [Clang<"xray_always_instrument">]>,
                    Accessor<"neverXRayInstrument",
                    Accessor<"neverXRayInstrument",
@@ -580,16 +586,14 @@ def XRayInstrument : InheritableAttr {
 
 
 def XRayLogArgs : InheritableAttr {
 def XRayLogArgs : InheritableAttr {
   let Spellings = [Clang<"xray_log_args">];
   let Spellings = [Clang<"xray_log_args">];
-  let Subjects = SubjectList<
-      [CXXMethod, ObjCMethod, Function], WarnDiag, "ExpectedFunctionOrMethod"
-  >;
+  let Subjects = SubjectList<[Function, ObjCMethod]>;
   let Args = [UnsignedArgument<"ArgumentCount">];
   let Args = [UnsignedArgument<"ArgumentCount">];
   let Documentation = [XRayDocs];
   let Documentation = [XRayDocs];
 }
 }
 
 
 def TLSModel : InheritableAttr {
 def TLSModel : InheritableAttr {
   let Spellings = [GCC<"tls_model">];
   let Spellings = [GCC<"tls_model">];
-  let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
+  let Subjects = SubjectList<[TLSVar], ErrorDiag>;
   let Args = [StringArgument<"Model">];
   let Args = [StringArgument<"Model">];
   let Documentation = [TLSModelDocs];
   let Documentation = [TLSModelDocs];
 }
 }
@@ -855,8 +859,7 @@ def CUDALaunchBounds : InheritableAttr {
   let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">];
   let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">];
   let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
   let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
   let LangOpts = [CUDA];
   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
   // 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
   // of the compiler. However, this node needs to exist in the AST because
   // non-LLVM backends may be relying on the attribute's presence.
   // non-LLVM backends may be relying on the attribute's presence.
@@ -908,8 +911,7 @@ def OpenCLAccess : Attr {
   let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
   let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
                    Keyword<"__write_only">, Keyword<"write_only">,
                    Keyword<"__write_only">, Keyword<"write_only">,
                    Keyword<"__read_write">, Keyword<"read_write">];
                    Keyword<"__read_write">, Keyword<"read_write">];
-  let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag,
-                             "ExpectedParameterOrTypedef">;
+  let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>;
   let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
   let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
                                            Keyword<"read_only">]>,
                                            Keyword<"read_only">]>,
                    Accessor<"isReadWrite", [Keyword<"__read_write">,
                    Accessor<"isReadWrite", [Keyword<"__read_write">,
@@ -1063,16 +1065,14 @@ def Format : InheritableAttr {
   let Spellings = [GCC<"format">];
   let Spellings = [GCC<"format">];
   let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
   let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
               IntArgument<"FirstArg">];
               IntArgument<"FirstArg">];
-  let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag,
-                             "ExpectedFunctionWithProtoType">;
+  let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto]>;
   let Documentation = [FormatDocs];
   let Documentation = [FormatDocs];
 }
 }
 
 
 def FormatArg : InheritableAttr {
 def FormatArg : InheritableAttr {
   let Spellings = [GCC<"format_arg">];
   let Spellings = [GCC<"format_arg">];
   let Args = [IntArgument<"FormatIdx">];
   let Args = [IntArgument<"FormatIdx">];
-  let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
-                             "ExpectedFunctionWithProtoType">;
+  let Subjects = SubjectList<[ObjCMethod, HasFunctionProto]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1092,8 +1092,7 @@ def Hot : InheritableAttr {
 
 
 def IBAction : InheritableAttr {
 def IBAction : InheritableAttr {
   let Spellings = [GNU<"ibaction">];
   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
   // 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
   // of the compiler. However, this node needs to exist in the AST because
   // external tools rely on it.
   // external tools rely on it.
@@ -1205,8 +1204,7 @@ def MipsShortCall : InheritableAttr, TargetSpecificAttr<TargetAnyMips> {
 
 
 def Mode : Attr {
 def Mode : Attr {
   let Spellings = [GCC<"mode">];
   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 Args = [IdentifierArgument<"Mode">];
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
@@ -1255,8 +1253,7 @@ def NoCommon : InheritableAttr {
 
 
 def NoDebug : InheritableAttr {
 def NoDebug : InheritableAttr {
   let Spellings = [GCC<"nodebug">];
   let Spellings = [GCC<"nodebug">];
-  let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar], WarnDiag,
-                              "ExpectedVariableOrFunction">;
+  let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar]>;
   let Documentation = [NoDebugDocs];
   let Documentation = [NoDebugDocs];
 }
 }
 
 
@@ -1311,28 +1308,28 @@ def AMDGPUFlatWorkGroupSize : InheritableAttr {
   let Spellings = [GNU<"amdgpu_flat_work_group_size">];
   let Spellings = [GNU<"amdgpu_flat_work_group_size">];
   let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
   let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
   let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
   let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
-  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+  let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 }
 
 
 def AMDGPUWavesPerEU : InheritableAttr {
 def AMDGPUWavesPerEU : InheritableAttr {
   let Spellings = [GNU<"amdgpu_waves_per_eu">];
   let Spellings = [GNU<"amdgpu_waves_per_eu">];
   let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
   let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
   let Documentation = [AMDGPUWavesPerEUDocs];
   let Documentation = [AMDGPUWavesPerEUDocs];
-  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+  let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 }
 
 
 def AMDGPUNumSGPR : InheritableAttr {
 def AMDGPUNumSGPR : InheritableAttr {
   let Spellings = [GNU<"amdgpu_num_sgpr">];
   let Spellings = [GNU<"amdgpu_num_sgpr">];
   let Args = [UnsignedArgument<"NumSGPR">];
   let Args = [UnsignedArgument<"NumSGPR">];
   let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
   let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
-  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+  let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 }
 
 
 def AMDGPUNumVGPR : InheritableAttr {
 def AMDGPUNumVGPR : InheritableAttr {
   let Spellings = [GNU<"amdgpu_num_vgpr">];
   let Spellings = [GNU<"amdgpu_num_vgpr">];
   let Args = [UnsignedArgument<"NumVGPR">];
   let Args = [UnsignedArgument<"NumVGPR">];
   let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
   let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
-  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+  let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 }
 
 
 def NoSplitStack : InheritableAttr {
 def NoSplitStack : InheritableAttr {
@@ -1344,7 +1341,7 @@ def NoSplitStack : InheritableAttr {
 def NonNull : InheritableParamAttr {
 def NonNull : InheritableParamAttr {
   let Spellings = [GCC<"nonnull">];
   let Spellings = [GCC<"nonnull">];
   let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
   let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
-                             "ExpectedFunctionMethodOrParameter">;
+                             "functions, methods, and parameters">;
   let Args = [VariadicUnsignedArgument<"Args">];
   let Args = [VariadicUnsignedArgument<"Args">];
   let AdditionalMembers =
   let AdditionalMembers =
 [{bool isNonNull(unsigned idx) const {
 [{bool isNonNull(unsigned idx) const {
@@ -1362,8 +1359,7 @@ def NonNull : InheritableParamAttr {
 
 
 def ReturnsNonNull : InheritableAttr {
 def ReturnsNonNull : InheritableAttr {
   let Spellings = [GCC<"returns_nonnull">];
   let Spellings = [GCC<"returns_nonnull">];
-  let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag,
-                             "ExpectedFunctionOrMethod">;
+  let Subjects = SubjectList<[ObjCMethod, Function]>;
   let Documentation = [ReturnsNonNullDocs];
   let Documentation = [ReturnsNonNullDocs];
 }
 }
 
 
@@ -1412,8 +1408,7 @@ def AssumeAligned : InheritableAttr {
 
 
 def AllocAlign : InheritableAttr {
 def AllocAlign : InheritableAttr {
   let Spellings = [GCC<"alloc_align">];
   let Spellings = [GCC<"alloc_align">];
-  let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
-                             "ExpectedFunctionWithProtoType">;
+  let Subjects = SubjectList<[HasFunctionProto]>;
   let Args = [IntArgument<"ParamIndex">];
   let Args = [IntArgument<"ParamIndex">];
   let Documentation = [AllocAlignDocs];
   let Documentation = [AllocAlignDocs];
 }
 }
@@ -1451,8 +1446,7 @@ def NvWeak : IgnoredAttr {
 
 
 def ObjCBridge : InheritableAttr {
 def ObjCBridge : InheritableAttr {
   let Spellings = [GNU<"objc_bridge">];
   let Spellings = [GNU<"objc_bridge">];
-  let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
-                             "ExpectedStructOrUnionOrTypedef">;
+  let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>;
   let Args = [IdentifierArgument<"BridgedType">];
   let Args = [IdentifierArgument<"BridgedType">];
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
@@ -1568,8 +1562,7 @@ def ObjCExplicitProtocolImpl : InheritableAttr {
 
 
 def ObjCDesignatedInitializer : Attr {
 def ObjCDesignatedInitializer : Attr {
   let Spellings = [GNU<"objc_designated_initializer">];
   let Spellings = [GNU<"objc_designated_initializer">];
-  let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag,
-                             "ExpectedObjCInterfaceDeclInitMethod">;
+  let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1588,7 +1581,7 @@ def ObjCRuntimeVisible : Attr {
 
 
 def ObjCBoxable : Attr {
 def ObjCBoxable : Attr {
   let Spellings = [GNU<"objc_boxable">];
   let Spellings = [GNU<"objc_boxable">];
-  let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">;
+  let Subjects = SubjectList<[Record], ErrorDiag>;
   let Documentation = [ObjCBoxableDocs];
   let Documentation = [ObjCBoxableDocs];
 }
 }
 
 
@@ -1625,8 +1618,7 @@ def Ownership : InheritableAttr {
     }
     }
   }];
   }];
   let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
   let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
-  let Subjects = SubjectList<[HasFunctionProto], WarnDiag,
-                             "ExpectedFunctionWithProtoType">;
+  let Subjects = SubjectList<[HasFunctionProto]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1672,8 +1664,7 @@ def ReqdWorkGroupSize : InheritableAttr {
 
 
 def RequireConstantInit : InheritableAttr {
 def RequireConstantInit : InheritableAttr {
   let Spellings = [Clang<"require_constant_initialization">];
   let Spellings = [Clang<"require_constant_initialization">];
-  let Subjects = SubjectList<[GlobalVar], ErrorDiag,
-                              "ExpectedStaticOrTLSVar">;
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
   let Documentation = [RequireConstantInitDocs];
   let Documentation = [RequireConstantInitDocs];
   let LangOpts = [CPlusPlus];
   let LangOpts = [CPlusPlus];
 }
 }
@@ -1697,9 +1688,8 @@ def InitPriority : InheritableAttr {
 def Section : InheritableAttr {
 def Section : InheritableAttr {
   let Spellings = [GCC<"section">, Declspec<"allocate">];
   let Spellings = [GCC<"section">, Declspec<"allocate">];
   let Args = [StringArgument<"Name">];
   let Args = [StringArgument<"Name">];
-  let Subjects = SubjectList<[Function, GlobalVar,
-                              ObjCMethod, ObjCProperty], ErrorDiag,
-                             "ExpectedFunctionGlobalVarMethodOrProperty">;
+  let Subjects =
+      SubjectList<[ Function, GlobalVar, ObjCMethod, ObjCProperty ], ErrorDiag>;
   let Documentation = [SectionDocs];
   let Documentation = [SectionDocs];
 }
 }
 
 
@@ -1707,8 +1697,7 @@ def PragmaClangBSSSection : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let Spellings = [];
   let Args = [StringArgument<"Name">];
   let Args = [StringArgument<"Name">];
-  let Subjects = SubjectList<[GlobalVar], ErrorDiag,
-                             "ExpectedFunctionMethodOrGlobalVar">;
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1716,8 +1705,7 @@ def PragmaClangDataSection : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let Spellings = [];
   let Args = [StringArgument<"Name">];
   let Args = [StringArgument<"Name">];
-  let Subjects = SubjectList<[GlobalVar], ErrorDiag,
-                             "ExpectedFunctionMethodOrGlobalVar">;
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1725,8 +1713,7 @@ def PragmaClangRodataSection : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let Spellings = [];
   let Args = [StringArgument<"Name">];
   let Args = [StringArgument<"Name">];
-  let Subjects = SubjectList<[GlobalVar], ErrorDiag,
-                             "ExpectedFunctionMethodOrGlobalVar">;
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1734,8 +1721,7 @@ def PragmaClangTextSection : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let Spellings = [];
   let Args = [StringArgument<"Name">];
   let Args = [StringArgument<"Name">];
-  let Subjects = SubjectList<[Function], ErrorDiag,
-                             "ExpectedFunctionMethodOrGlobalVar">;
+  let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -1935,8 +1921,7 @@ def Unused : InheritableAttr {
   let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
   let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
                    C2x<"", "maybe_unused">];
                    C2x<"", "maybe_unused">];
   let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
   let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
-                              Field, ObjCMethod, FunctionLike], WarnDiag,
-                             "ExpectedForMaybeUnused">;
+                              Field, ObjCMethod, FunctionLike]>;
   let Documentation = [WarnMaybeUnusedDocs];
   let Documentation = [WarnMaybeUnusedDocs];
 }
 }
 
 
@@ -1948,7 +1933,7 @@ def Used : InheritableAttr {
 def Uuid : InheritableAttr {
 def Uuid : InheritableAttr {
   let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
   let Spellings = [Declspec<"uuid">, Microsoft<"uuid">];
   let Args = [StringArgument<"Guid">];
   let Args = [StringArgument<"Guid">];
-  let Subjects = SubjectList<[Record, Enum], WarnDiag, "ExpectedEnumOrClass">;
+  let Subjects = SubjectList<[Record, Enum]>;
   // FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
   // FIXME: Allow expressing logical AND for LangOpts. Our condition should be:
   // CPlusPlus && (MicrosoftExt || Borland)
   // CPlusPlus && (MicrosoftExt || Borland)
   let LangOpts = [MicrosoftExt, Borland];
   let LangOpts = [MicrosoftExt, Borland];
@@ -2004,8 +1989,7 @@ def WarnUnusedResult : InheritableAttr {
   let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">,
   let Spellings = [CXX11<"", "nodiscard", 201603>, C2x<"", "nodiscard">,
                    CXX11<"clang", "warn_unused_result">,
                    CXX11<"clang", "warn_unused_result">,
                    GCC<"warn_unused_result">];
                    GCC<"warn_unused_result">];
-  let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike],
-                             WarnDiag, "ExpectedFunctionMethodEnumOrClass">;
+  let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;
   let Documentation = [WarnUnusedResultsDocs];
   let Documentation = [WarnUnusedResultsDocs];
 }
 }
 
 
@@ -2061,8 +2045,7 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetAnyX86>
 def NoSanitize : InheritableAttr {
 def NoSanitize : InheritableAttr {
   let Spellings = [Clang<"no_sanitize">];
   let Spellings = [Clang<"no_sanitize">];
   let Args = [VariadicStringArgument<"Sanitizers">];
   let Args = [VariadicStringArgument<"Sanitizers">];
-  let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag,
-    "ExpectedFunctionMethodOrGlobalVar">;
+  let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag>;
   let Documentation = [NoSanitizeDocs];
   let Documentation = [NoSanitizeDocs];
   let AdditionalMembers = [{
   let AdditionalMembers = [{
     SanitizerMask getMask() const {
     SanitizerMask getMask() const {
@@ -2084,8 +2067,7 @@ def NoSanitizeSpecific : InheritableAttr {
                    GCC<"no_sanitize_address">,
                    GCC<"no_sanitize_address">,
                    GCC<"no_sanitize_thread">,
                    GCC<"no_sanitize_thread">,
                    GNU<"no_sanitize_memory">];
                    GNU<"no_sanitize_memory">];
-  let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag,
-        "ExpectedFunctionOrGlobalVar">;
+  let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>;
   let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
   let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
                        NoSanitizeMemoryDocs];
                        NoSanitizeMemoryDocs];
   let ASTNode = 0;
   let ASTNode = 0;
@@ -2095,15 +2077,13 @@ def NoSanitizeSpecific : InheritableAttr {
 
 
 def GuardedVar : InheritableAttr {
 def GuardedVar : InheritableAttr {
   let Spellings = [GNU<"guarded_var">];
   let Spellings = [GNU<"guarded_var">];
-  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
-                             "ExpectedFieldOrGlobalVar">;
+  let Subjects = SubjectList<[Field, SharedVar]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
 def PtGuardedVar : InheritableAttr {
 def PtGuardedVar : InheritableAttr {
   let Spellings = [GNU<"pt_guarded_var">];
   let Spellings = [GNU<"pt_guarded_var">];
-  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
-                             "ExpectedFieldOrGlobalVar">;
+  let Subjects = SubjectList<[Field, SharedVar]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -2122,8 +2102,7 @@ def ScopedLockable : InheritableAttr {
 
 
 def Capability : InheritableAttr {
 def Capability : InheritableAttr {
   let Spellings = [Clang<"capability">, Clang<"shared_capability">];
   let Spellings = [Clang<"capability">, Clang<"shared_capability">];
-  let Subjects = SubjectList<[Record, TypedefName], ErrorDiag,
-                             "ExpectedStructOrUnionOrTypedef">;
+  let Subjects = SubjectList<[Record, TypedefName], ErrorDiag>;
   let Args = [StringArgument<"Name">];
   let Args = [StringArgument<"Name">];
   let Accessors = [Accessor<"isShared",
   let Accessors = [Accessor<"isShared",
                     [Clang<"shared_capability">]>];
                     [Clang<"shared_capability">]>];
@@ -2228,8 +2207,7 @@ def GuardedBy : InheritableAttr {
   let TemplateDependent = 1;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let DuplicatesAllowedWhileMerging = 1;
   let DuplicatesAllowedWhileMerging = 1;
-  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
-                             "ExpectedFieldOrGlobalVar">;
+  let Subjects = SubjectList<[Field, SharedVar]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -2240,8 +2218,7 @@ def PtGuardedBy : InheritableAttr {
   let TemplateDependent = 1;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let DuplicatesAllowedWhileMerging = 1;
   let DuplicatesAllowedWhileMerging = 1;
-  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
-                             "ExpectedFieldOrGlobalVar">;
+  let Subjects = SubjectList<[Field, SharedVar]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -2252,8 +2229,7 @@ def AcquiredAfter : InheritableAttr {
   let TemplateDependent = 1;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let DuplicatesAllowedWhileMerging = 1;
   let DuplicatesAllowedWhileMerging = 1;
-  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
-                             "ExpectedFieldOrGlobalVar">;
+  let Subjects = SubjectList<[Field, SharedVar]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 
@@ -2264,8 +2240,7 @@ def AcquiredBefore : InheritableAttr {
   let TemplateDependent = 1;
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let DuplicatesAllowedWhileMerging = 1;
   let DuplicatesAllowedWhileMerging = 1;
-  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
-                             "ExpectedFieldOrGlobalVar">;
+  let Subjects = SubjectList<[Field, SharedVar]>;
   let Documentation = [Undocumented];
   let Documentation = [Undocumented];
 }
 }
 
 

+ 31 - 28
include/clang/Basic/DeclNodes.td

@@ -1,66 +1,68 @@
 class AttrSubject;
 class AttrSubject;
 
 
-class Decl<bit abstract = 0> : AttrSubject {
+class Decl<string diagSpelling = "", bit abstract = 0> : AttrSubject {
   bit Abstract = abstract;
   bit Abstract = abstract;
+  string DiagSpelling = diagSpelling;
 }
 }
 
 
-class DDecl<Decl base, bit abstract = 0> : Decl<abstract> {
+class DDecl<Decl base, string diagSpelling = "", bit abstract = 0>
+    : Decl<diagSpelling, abstract> {
   Decl Base = base;
   Decl Base = base;
 }
 }
 
 
-class DeclContext { }
+class DeclContext {}
 
 
 def TranslationUnit : Decl, DeclContext;
 def TranslationUnit : Decl, DeclContext;
 def PragmaComment : Decl;
 def PragmaComment : Decl;
 def PragmaDetectMismatch : Decl;
 def PragmaDetectMismatch : Decl;
 def ExternCContext : Decl, DeclContext;
 def ExternCContext : Decl, DeclContext;
-def Named : Decl<1>;
-  def Namespace : DDecl<Named>, DeclContext;
+def Named : Decl<"named declarations", 1>;
+  def Namespace : DDecl<Named, "namespaces">, DeclContext;
   def UsingDirective : DDecl<Named>;
   def UsingDirective : DDecl<Named>;
   def NamespaceAlias : DDecl<Named>;
   def NamespaceAlias : DDecl<Named>;
-  def Label : DDecl<Named>;
-  def Type : DDecl<Named, 1>;
-    def TypedefName : DDecl<Type, 1>;
+  def Label : DDecl<Named, "labels">;
+  def Type : DDecl<Named, "types", 1>;
+    def TypedefName : DDecl<Type, "typedefs", 1>;
       def Typedef : DDecl<TypedefName>;
       def Typedef : DDecl<TypedefName>;
       def TypeAlias : DDecl<TypedefName>;
       def TypeAlias : DDecl<TypedefName>;
       def ObjCTypeParam : DDecl<TypedefName>;
       def ObjCTypeParam : DDecl<TypedefName>;
     def UnresolvedUsingTypename : DDecl<Type>;
     def UnresolvedUsingTypename : DDecl<Type>;
-    def Tag : DDecl<Type, 1>, DeclContext;
-      def Enum : DDecl<Tag>;
-      def Record : DDecl<Tag>;
-        def CXXRecord : DDecl<Record>;
+    def Tag : DDecl<Type, "tag types", 1>, DeclContext;
+      def Enum : DDecl<Tag, "enums">;
+      def Record : DDecl<Tag, "structs, unions, classes">;
+        def CXXRecord : DDecl<Record, "classes">;
           def ClassTemplateSpecialization : DDecl<CXXRecord>;
           def ClassTemplateSpecialization : DDecl<CXXRecord>;
             def ClassTemplatePartialSpecialization
             def ClassTemplatePartialSpecialization
               : DDecl<ClassTemplateSpecialization>;
               : DDecl<ClassTemplateSpecialization>;
     def TemplateTypeParm : DDecl<Type>;
     def TemplateTypeParm : DDecl<Type>;
-  def Value : DDecl<Named, 1>;
-    def EnumConstant : DDecl<Value>;
+  def Value : DDecl<Named, "value declarations", 1>;
+    def EnumConstant : DDecl<Value, "enumerators">;
     def UnresolvedUsingValue : DDecl<Value>;
     def UnresolvedUsingValue : DDecl<Value>;
     def IndirectField : DDecl<Value>;
     def IndirectField : DDecl<Value>;
     def Binding : DDecl<Value>;
     def Binding : DDecl<Value>;
     def OMPDeclareReduction : DDecl<Value>, DeclContext;
     def OMPDeclareReduction : DDecl<Value>, DeclContext;
-    def Declarator : DDecl<Value, 1>;
-      def Field : DDecl<Declarator>;
+    def Declarator : DDecl<Value, "declarators", 1>;
+      def Field : DDecl<Declarator, "non-static data members">;
         def ObjCIvar : DDecl<Field>;
         def ObjCIvar : DDecl<Field>;
         def ObjCAtDefsField : DDecl<Field>;
         def ObjCAtDefsField : DDecl<Field>;
       def MSProperty : DDecl<Declarator>;
       def MSProperty : DDecl<Declarator>;
-      def Function : DDecl<Declarator>, DeclContext;
+      def Function : DDecl<Declarator, "functions">, DeclContext;
         def CXXDeductionGuide : DDecl<Function>;
         def CXXDeductionGuide : DDecl<Function>;
         def CXXMethod : DDecl<Function>;
         def CXXMethod : DDecl<Function>;
           def CXXConstructor : DDecl<CXXMethod>;
           def CXXConstructor : DDecl<CXXMethod>;
           def CXXDestructor : DDecl<CXXMethod>;
           def CXXDestructor : DDecl<CXXMethod>;
           def CXXConversion : DDecl<CXXMethod>;
           def CXXConversion : DDecl<CXXMethod>;
-      def Var : DDecl<Declarator>;
+      def Var : DDecl<Declarator, "variables">;
         def VarTemplateSpecialization : DDecl<Var>;
         def VarTemplateSpecialization : DDecl<Var>;
           def VarTemplatePartialSpecialization
           def VarTemplatePartialSpecialization
             : DDecl<VarTemplateSpecialization>;
             : DDecl<VarTemplateSpecialization>;
         def ImplicitParam : DDecl<Var>;
         def ImplicitParam : DDecl<Var>;
-        def ParmVar : DDecl<Var>;
+        def ParmVar : DDecl<Var, "parameters">;
         def Decomposition : DDecl<Var>;
         def Decomposition : DDecl<Var>;
         def OMPCapturedExpr : DDecl<Var>;
         def OMPCapturedExpr : DDecl<Var>;
       def NonTypeTemplateParm : DDecl<Declarator>;
       def NonTypeTemplateParm : DDecl<Declarator>;
-  def Template : DDecl<Named, 1>;
-    def RedeclarableTemplate : DDecl<Template, 1>;
+  def Template : DDecl<Named, "templates", 1>;
+    def RedeclarableTemplate : DDecl<Template, "redeclarable templates", 1>;
       def FunctionTemplate : DDecl<RedeclarableTemplate>;
       def FunctionTemplate : DDecl<RedeclarableTemplate>;
       def ClassTemplate : DDecl<RedeclarableTemplate>;
       def ClassTemplate : DDecl<RedeclarableTemplate>;
       def VarTemplate : DDecl<RedeclarableTemplate>;
       def VarTemplate : DDecl<RedeclarableTemplate>;
@@ -71,15 +73,16 @@ def Named : Decl<1>;
   def UsingPack : DDecl<Named>;
   def UsingPack : DDecl<Named>;
   def UsingShadow : DDecl<Named>;
   def UsingShadow : DDecl<Named>;
     def ConstructorUsingShadow : DDecl<UsingShadow>;
     def ConstructorUsingShadow : DDecl<UsingShadow>;
-  def ObjCMethod : DDecl<Named>, DeclContext;
-  def ObjCContainer : DDecl<Named, 1>, DeclContext;
+  def ObjCMethod : DDecl<Named, "Objective-C methods">, DeclContext;
+  def ObjCContainer : DDecl<Named, "Objective-C containers", 1>, DeclContext;
     def ObjCCategory : DDecl<ObjCContainer>;
     def ObjCCategory : DDecl<ObjCContainer>;
-    def ObjCProtocol : DDecl<ObjCContainer>;
-    def ObjCInterface : DDecl<ObjCContainer>;
-    def ObjCImpl : DDecl<ObjCContainer, 1>;
+    def ObjCProtocol : DDecl<ObjCContainer, "Objective-C protocols">;
+    def ObjCInterface : DDecl<ObjCContainer, "Objective-C interfaces">;
+    def ObjCImpl
+        : DDecl<ObjCContainer, "Objective-C implementation declarations", 1>;
       def ObjCCategoryImpl : DDecl<ObjCImpl>;
       def ObjCCategoryImpl : DDecl<ObjCImpl>;
       def ObjCImplementation : DDecl<ObjCImpl>;
       def ObjCImplementation : DDecl<ObjCImpl>;
-  def ObjCProperty : DDecl<Named>;
+  def ObjCProperty : DDecl<Named, "Objective-C properties">;
   def ObjCCompatibleAlias : DDecl<Named>;
   def ObjCCompatibleAlias : DDecl<Named>;
 def LinkageSpec : Decl, DeclContext;
 def LinkageSpec : Decl, DeclContext;
 def Export : Decl, DeclContext;
 def Export : Decl, DeclContext;
@@ -89,7 +92,7 @@ def AccessSpec : Decl;
 def Friend : Decl;
 def Friend : Decl;
 def FriendTemplate : Decl;
 def FriendTemplate : Decl;
 def StaticAssert : Decl;
 def StaticAssert : Decl;
-def Block : Decl, DeclContext;
+def Block : Decl<"blocks">, DeclContext;
 def Captured : Decl, DeclContext;
 def Captured : Decl, DeclContext;
 def ClassScopeFunctionSpecialization : Decl;
 def ClassScopeFunctionSpecialization : Decl;
 def Import : Decl;
 def Import : Decl;

+ 5 - 34
include/clang/Basic/DiagnosticSemaKinds.td

@@ -2799,55 +2799,26 @@ def err_ifunc_resolver_return : Error<
   "ifunc resolver function must return a pointer">;
   "ifunc resolver function must return a pointer">;
 def err_ifunc_resolver_params : Error<
 def err_ifunc_resolver_params : Error<
   "ifunc resolver function must have no parameters">;
   "ifunc resolver function must have no parameters">;
+def warn_attribute_wrong_decl_type_str : Warning<
+  "%0 attribute only applies to %1">, InGroup<IgnoredAttributes>;
+def err_attribute_wrong_decl_type_str : Error<
+  warn_attribute_wrong_decl_type_str.Text>;
 def warn_attribute_wrong_decl_type : Warning<
 def warn_attribute_wrong_decl_type : Warning<
   "%0 attribute only applies to %select{"
   "%0 attribute only applies to %select{"
   "functions"
   "functions"
   "|unions"
   "|unions"
   "|variables and functions"
   "|variables and functions"
-  "|functions and global variables"
-  "|functions, variables, and Objective-C interfaces"
   "|functions and methods"
   "|functions and methods"
-  "|parameters"
   "|functions, methods and blocks"
   "|functions, methods and blocks"
-  "|functions, methods, and classes"
   "|functions, methods, and parameters"
   "|functions, methods, and parameters"
-  "|functions, methods, and global variables"
-  "|classes"
-  "|enums"
   "|variables"
   "|variables"
-  "|methods"
-  "|fields and global variables"
-  "|structs"
-  "|parameters and typedefs"
-  "|variables and typedefs"
-  "|thread-local variables"
   "|variables and fields"
   "|variables and fields"
   "|variables, data members and tag types"
   "|variables, data members and tag types"
   "|types and namespaces"
   "|types and namespaces"
-  "|Objective-C interfaces"
-  "|methods and properties"
-  "|functions, methods, and properties"
-  "|struct or union"
-  "|struct, union or class"
-  "|types"
-  "|Objective-C instance methods"
-  "|init methods of interface or class extension declarations"
   "|variables, functions and classes"
   "|variables, functions and classes"
-  "|functions, variables, classes, and Objective-C interfaces"
-  "|Objective-C protocols"
-  "|variables with static or thread storage duration"
-  "|functions, methods, properties, and global variables"
-  "|structs, unions, and typedefs"
-  "|structs and typedefs"
-  "|interface or protocol declarations"
   "|kernel functions"
   "|kernel functions"
   "|non-K&R-style functions"
   "|non-K&R-style functions"
-  "|variables, enums, fields and typedefs"
-  "|functions, methods, enums, and classes"
-  "|structs, classes, variables, functions, and inline namespaces"
-  "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
-  "|classes and enumerations"
-  "|named declarations}1">,
+  "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">,
   InGroup<IgnoredAttributes>;
   InGroup<IgnoredAttributes>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<
 def warn_type_attribute_wrong_type : Warning<

+ 0 - 33
include/clang/Sema/AttributeList.h

@@ -900,50 +900,17 @@ enum AttributeDeclKind {
   ExpectedFunction,
   ExpectedFunction,
   ExpectedUnion,
   ExpectedUnion,
   ExpectedVariableOrFunction,
   ExpectedVariableOrFunction,
-  ExpectedFunctionOrGlobalVar,
-  ExpectedFunctionVariableOrObjCInterface,
   ExpectedFunctionOrMethod,
   ExpectedFunctionOrMethod,
-  ExpectedParameter,
   ExpectedFunctionMethodOrBlock,
   ExpectedFunctionMethodOrBlock,
-  ExpectedFunctionMethodOrClass,
   ExpectedFunctionMethodOrParameter,
   ExpectedFunctionMethodOrParameter,
-  ExpectedFunctionMethodOrGlobalVar,
-  ExpectedClass,
-  ExpectedEnum,
   ExpectedVariable,
   ExpectedVariable,
-  ExpectedMethod,
-  ExpectedFieldOrGlobalVar,
-  ExpectedStruct,
-  ExpectedParameterOrTypedef,
-  ExpectedVariableOrTypedef,
-  ExpectedTLSVar,
   ExpectedVariableOrField,
   ExpectedVariableOrField,
   ExpectedVariableFieldOrTag,
   ExpectedVariableFieldOrTag,
   ExpectedTypeOrNamespace,
   ExpectedTypeOrNamespace,
-  ExpectedObjectiveCInterface,
-  ExpectedMethodOrProperty,
-  ExpectedFunctionOrMethodOrProperty,
-  ExpectedStructOrUnion,
-  ExpectedStructOrUnionOrClass,
-  ExpectedType,
-  ExpectedObjCInstanceMethod,
-  ExpectedObjCInterfaceDeclInitMethod,
   ExpectedFunctionVariableOrClass,
   ExpectedFunctionVariableOrClass,
-  ExpectedFunctionVariableClassOrObjCInterface,
-  ExpectedObjectiveCProtocol,
-  ExpectedStaticOrTLSVar,
-  ExpectedFunctionGlobalVarMethodOrProperty,
-  ExpectedStructOrUnionOrTypedef,
-  ExpectedStructOrTypedef,
-  ExpectedObjectiveCInterfaceOrProtocol,
   ExpectedKernelFunction,
   ExpectedKernelFunction,
   ExpectedFunctionWithProtoType,
   ExpectedFunctionWithProtoType,
-  ExpectedVariableEnumFieldOrTypedef,
-  ExpectedFunctionMethodEnumOrClass,
-  ExpectedStructClassVariableFunctionOrInlineNamespace,
   ExpectedForMaybeUnused,
   ExpectedForMaybeUnused,
-  ExpectedEnumOrClass,
-  ExpectedNamedDecl,
 };
 };
 
 
 }  // end namespace clang
 }  // end namespace clang

+ 3 - 3
test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp

@@ -7,8 +7,8 @@
 [[carries_dependency]] void f1(); // FIXME: warn here
 [[carries_dependency]] void f1(); // FIXME: warn here
 [[carries_dependency]] int f2(); // ok
 [[carries_dependency]] int f2(); // ok
 int f3(int param [[carries_dependency]]); // ok
 int f3(int param [[carries_dependency]]); // ok
-[[carries_dependency]] int (*f4)(); // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
-int (*f5 [[carries_dependency]])(); // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+[[carries_dependency]] int (*f4)(); // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
+int (*f5 [[carries_dependency]])(); // expected-error {{'carries_dependency' attribute only applies to}}
 int (*f6)() [[carries_dependency]]; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
 int (*f6)() [[carries_dependency]]; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
 int (*f7)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
 int (*f7)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
 int (((f8)))(int n [[carries_dependency]]); // ok
 int (((f8)))(int n [[carries_dependency]]); // ok
@@ -21,7 +21,7 @@ struct S {
 };
 };
 void f() {
 void f() {
   [[carries_dependency]] int f(int n [[carries_dependency]]); // ok
   [[carries_dependency]] int f(int n [[carries_dependency]]); // ok
-  [[carries_dependency]] // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+  [[carries_dependency]] // expected-error {{'carries_dependency' attribute only applies to}}
       int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
       int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
 }
 }
 
 

+ 1 - 1
test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp

@@ -7,4 +7,4 @@ struct [[nodiscard("Wrong")]] S3 {}; // expected-error {{'nodiscard' cannot have
 [[nodiscard]] int f();
 [[nodiscard]] int f();
 enum [[nodiscard]] E {};
 enum [[nodiscard]] E {};
 
 
-namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to functions, methods, enums, and classes}}
+namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}

+ 3 - 3
test/CodeGenObjC/objc-asm-attribute-neg-test.m

@@ -7,15 +7,15 @@ __attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
 
 
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 @interface Message <Protocol> { 
 @interface Message <Protocol> { 
-__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
   id MyIVAR;
   id MyIVAR;
 }
 }
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 @property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
 @property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
 
 
-- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
 
 
-- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
 
 
 @end
 @end
 
 

+ 2 - 2
test/Misc/pragma-attribute-supported-attributes-list.test

@@ -67,5 +67,5 @@
 // CHECK-NEXT: Target (SubjectMatchRule_function)
 // CHECK-NEXT: Target (SubjectMatchRule_function)
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
 // CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
-// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function_is_member, SubjectMatchRule_objc_method, SubjectMatchRule_function)
-// CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function_is_member, SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method)
+// CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method)

+ 2 - 2
test/Parser/MicrosoftExtensions.cpp

@@ -51,7 +51,7 @@ struct __declspec(uuid("0000000-0000-0000-Z234-000000000047")) uuid_attr_bad4 {
 struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
 struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
 [uuid("000000000000-0000-1234-000000000047")] struct uuid_attr_bad6 { };// expected-error {{uuid attribute contains a malformed GUID}}
 [uuid("000000000000-0000-1234-000000000047")] struct uuid_attr_bad6 { };// expected-error {{uuid attribute contains a malformed GUID}}
 
 
-__declspec(uuid("000000A0-0000-0000-C000-000000000046")) int i; // expected-warning {{'uuid' attribute only applies to classes}}
+__declspec(uuid("000000A0-0000-0000-C000-000000000046")) int i; // expected-warning {{'uuid' attribute only applies to structs, unions, classes, and enums}}
 
 
 struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
 struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
 struct_with_uuid { };
 struct_with_uuid { };
@@ -69,7 +69,7 @@ enum __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
 enum_with_uuid { };
 enum_with_uuid { };
 enum enum_without_uuid { };
 enum enum_without_uuid { };
 
 
-int __declspec(uuid("000000A0-0000-0000-C000-000000000046")) inappropriate_uuid; // expected-warning {{'uuid' attribute only applies to classes and enumerations}}
+int __declspec(uuid("000000A0-0000-0000-C000-000000000046")) inappropriate_uuid; // expected-warning {{'uuid' attribute only applies to}}
 
 
 int uuid_sema_test()
 int uuid_sema_test()
 {
 {

+ 1 - 1
test/Parser/cxx0x-attributes.cpp

@@ -307,7 +307,7 @@ int v5()[[gnu::unused]]; // expected-warning {{attribute 'unused' ignored}}
 
 
 [[attribute_declaration]]; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
 [[attribute_declaration]]; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}}
 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}}
-[[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
+[[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
 
 
 class A {
 class A {
   A([[gnu::unused]] int a);
   A([[gnu::unused]] int a);

+ 1 - 1
test/Parser/ms-square-bracket-attributes.mm

@@ -133,7 +133,7 @@ void use_it() {
   (void)__uuidof(OuterClass::sic);
   (void)__uuidof(OuterClass::sic);
 }
 }
 
 
-// expected-warning@+1 {{'uuid' attribute only applies to classes}}
+// expected-warning@+1 {{'uuid' attribute only applies to structs, unions, classes, and enums}}
 [uuid("000000A0-0000-0000-C000-000000000049")] void f();
 [uuid("000000A0-0000-0000-C000-000000000049")] void f();
 }
 }
 
 

+ 2 - 2
test/Sema/attr-capabilities.c

@@ -11,8 +11,8 @@ typedef union { int a; char* b; } __attribute__((capability("mutex"))) MutexUnio
 // Test an invalid capability name
 // Test an invalid capability name
 struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}
 struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}
 
 
-int Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs, unions, and typedefs}}
-int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, and typedefs}}
+int Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs, unions, classes, and typedefs}}
+int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, classes, and typedefs}}
 int Test3 __attribute__((acquire_capability("test3")));  // expected-warning {{'acquire_capability' attribute only applies to functions}}
 int Test3 __attribute__((acquire_capability("test3")));  // expected-warning {{'acquire_capability' attribute only applies to functions}}
 int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}}
 int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}}
 int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}
 int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}

+ 1 - 1
test/Sema/attr-disable-tail-calls.c

@@ -8,6 +8,6 @@ void __attribute__((naked,disable_tail_calls)) foo2(int a) { // expected-error {
   __asm__("");
   __asm__("");
 }
 }
 
 
-int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and methods}}
+int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and Objective-C methods}}
 
 
 int foo3(int a) __attribute__((disable_tail_calls("abc"))); // expected-error {{'disable_tail_calls' attribute takes no arguments}}
 int foo3(int a) __attribute__((disable_tail_calls("abc"))); // expected-error {{'disable_tail_calls' attribute takes no arguments}}

+ 1 - 1
test/Sema/attr-minsize.c

@@ -2,4 +2,4 @@
 
 
 int foo() __attribute__((__minsize__));
 int foo() __attribute__((__minsize__));
 
 
-int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and methods}}
+int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and Objective-C methods}}

+ 2 - 2
test/Sema/attr-mode.c

@@ -26,8 +26,8 @@ typedef unsigned unwind_word __attribute((mode(unwind_word)));
 
 
 int **__attribute((mode(QI)))* i32;  // expected-error{{mode attribute}}
 int **__attribute((mode(QI)))* i32;  // expected-error{{mode attribute}}
 
 
-__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}}
-enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}}
+__attribute__((mode(QI))) int invalid_func() { return 1; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}}
+enum invalid_enum { A1 __attribute__((mode(QI))) }; // expected-error{{'mode' attribute only applies to}}
 
 
 typedef _Complex double c32 __attribute((mode(SC)));
 typedef _Complex double c32 __attribute((mode(SC)));
 int c32_test[sizeof(c32) == 8 ? 1 : -1];
 int c32_test[sizeof(c32) == 8 ? 1 : -1];

+ 1 - 1
test/Sema/attr-nodebug.c

@@ -2,7 +2,7 @@
 
 
 int a __attribute__((nodebug));
 int a __attribute__((nodebug));
 
 
-void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to variables and functions}}
+void b(int p __attribute__((nodebug))) { // expected-warning {{'nodebug' attribute only applies to functions, function pointers, Objective-C methods, and variables and functions}}
   int b __attribute__((nodebug));
   int b __attribute__((nodebug));
 }
 }
 
 

+ 2 - 2
test/Sema/attr-section.c

@@ -10,7 +10,7 @@ int y __attribute__((section(
 
 
 // PR6007
 // PR6007
 void test() {
 void test() {
-  __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}}
+  __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions, global variables, Objective-C methods, and Objective-C properties}}
   __attribute__((section("NEAR,x"))) static int n2; // ok.
   __attribute__((section("NEAR,x"))) static int n2; // ok.
 }
 }
 
 
@@ -18,7 +18,7 @@ void test() {
 void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}}
 void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}}
 void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}}
 void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}}
 
 
-enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to functions, methods, properties, and global variables}}
+enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to}}
 
 
 extern int a; // expected-note {{previous declaration is here}}
 extern int a; // expected-note {{previous declaration is here}}
 int *b = &a;
 int *b = &a;

+ 2 - 2
test/Sema/attr-weak.c

@@ -5,10 +5,10 @@ extern int g1 __attribute__((weak_import));
 int g2 __attribute__((weak));
 int g2 __attribute__((weak));
 int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}}
 int g3 __attribute__((weak_import)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}}
 int __attribute__((weak_import)) g4(void);
 int __attribute__((weak_import)) g4(void);
-void __attribute__((weak_import)) g5(void) { 
+void __attribute__((weak_import)) g5(void) {
 }
 }
 
 
-struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables and functions}}
+struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables, functions, and classes}}
 struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variables and functions}}
 struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variables and functions}}
 
 
 static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}

+ 1 - 1
test/Sema/builtin-assume-aligned.c

@@ -47,7 +47,7 @@ void test_void_assume_aligned(void) __attribute__((assume_aligned(32))); // expe
 int test_int_assume_aligned(void) __attribute__((assume_aligned(16))); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers}}
 int test_int_assume_aligned(void) __attribute__((assume_aligned(16))); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers}}
 void *test_ptr_assume_aligned(void) __attribute__((assume_aligned(64))); // no-warning
 void *test_ptr_assume_aligned(void) __attribute__((assume_aligned(64))); // no-warning
 
 
-int j __attribute__((assume_aligned(8))); // expected-warning {{'assume_aligned' attribute only applies to functions and methods}}
+int j __attribute__((assume_aligned(8))); // expected-warning {{'assume_aligned' attribute only applies to Objective-C methods and functions}}
 void *test_no_fn_proto() __attribute__((assume_aligned(32))); // no-warning
 void *test_no_fn_proto() __attribute__((assume_aligned(32))); // no-warning
 void *test_with_fn_proto(void) __attribute__((assume_aligned(128))); // no-warning
 void *test_with_fn_proto(void) __attribute__((assume_aligned(128))); // no-warning
 
 

+ 1 - 1
test/Sema/c2x-nodiscard.c

@@ -13,7 +13,7 @@ struct [[nodiscard("Wrong")]] S3 { // expected-error {{'nodiscard' cannot have a
 [[nodiscard]] int f1(void);
 [[nodiscard]] int f1(void);
 enum [[nodiscard]] E1 { One };
 enum [[nodiscard]] E1 { One };
 
 
-[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to functions, methods, enums, and classes}}
+[[nodiscard]] int i; // expected-warning {{'nodiscard' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
 
 
 struct [[nodiscard]] S4 {
 struct [[nodiscard]] S4 {
   int i;
   int i;

+ 6 - 6
test/Sema/dllexport.c

@@ -5,17 +5,17 @@
 
 
 // Invalid usage.
 // Invalid usage.
 __declspec(dllexport) typedef int typedef1;
 __declspec(dllexport) typedef int typedef1;
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
 typedef __declspec(dllexport) int typedef2;
 typedef __declspec(dllexport) int typedef2;
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 typedef int __declspec(dllexport) typedef3;
 typedef int __declspec(dllexport) typedef3;
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 typedef __declspec(dllexport) void (*FunTy)();
 typedef __declspec(dllexport) void (*FunTy)();
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 enum __declspec(dllexport) Enum { EnumVal };
 enum __declspec(dllexport) Enum { EnumVal };
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 struct __declspec(dllexport) Record {};
 struct __declspec(dllexport) Record {};
-// expected-warning@-1{{'dllexport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 
 
 
 
 
 

+ 6 - 6
test/Sema/dllimport.c

@@ -6,17 +6,17 @@
 
 
 // Invalid usage.
 // Invalid usage.
 __declspec(dllimport) typedef int typedef1;
 __declspec(dllimport) typedef int typedef1;
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
 typedef __declspec(dllimport) int typedef2;
 typedef __declspec(dllimport) int typedef2;
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 typedef int __declspec(dllimport) typedef3;
 typedef int __declspec(dllimport) typedef3;
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 typedef __declspec(dllimport) void (*FunTy)();
 typedef __declspec(dllimport) void (*FunTy)();
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 enum __declspec(dllimport) Enum { EnumVal };
 enum __declspec(dllimport) Enum { EnumVal };
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 struct __declspec(dllimport) Record {};
 struct __declspec(dllimport) Record {};
-// expected-warning@-1{{'dllimport' attribute only applies to variables and functions}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 
 
 
 
 
 

+ 1 - 1
test/Sema/internal_linkage.c

@@ -15,7 +15,7 @@ int var5 __attribute__((internal_linkage)); // expected-error{{'internal_linkage
 int var5 __attribute__((common)); // expected-note{{conflicting attribute is here}}
 int var5 __attribute__((common)); // expected-note{{conflicting attribute is here}}
 
 
 __attribute__((internal_linkage)) int f() {}
 __attribute__((internal_linkage)) int f() {}
-struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables and functions}}
+struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables, functions, and classes}}
 };
 };
 
 
 __attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}}
 __attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}}

+ 1 - 1
test/Sema/nonnull.c

@@ -37,7 +37,7 @@ int test_int_returns_nonnull(void) __attribute__((returns_nonnull)); // expected
 void *test_ptr_returns_nonnull(void) __attribute__((returns_nonnull)); // no-warning
 void *test_ptr_returns_nonnull(void) __attribute__((returns_nonnull)); // no-warning
 
 
 int i __attribute__((nonnull)); // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}}
 int i __attribute__((nonnull)); // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}}
-int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to functions and methods}}
+int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to Objective-C methods and functions}}
 void *test_no_fn_proto() __attribute__((returns_nonnull)); // no-warning
 void *test_no_fn_proto() __attribute__((returns_nonnull)); // no-warning
 void *test_with_fn_proto(void) __attribute__((returns_nonnull)); // no-warning
 void *test_with_fn_proto(void) __attribute__((returns_nonnull)); // no-warning
 
 

+ 2 - 2
test/Sema/pragma-ms_struct.c

@@ -25,7 +25,7 @@ struct {
 } __attribute__((__ms_struct__)) t1;
 } __attribute__((__ms_struct__)) t1;
 
 
 struct S {
 struct S {
-		   double __attribute__((ms_struct)) d;	// expected-warning {{'ms_struct' attribute only applies to struct or union}}
+		   double __attribute__((ms_struct)) d;	// expected-warning {{'ms_struct' attribute only applies to structs, unions, and classes}}
                    unsigned long bf_1 : 12;
                    unsigned long bf_1 : 12;
                    unsigned long : 0;
                    unsigned long : 0;
                    unsigned long bf_2 : 12;
                    unsigned long bf_2 : 12;
@@ -36,7 +36,7 @@ enum
   A = 0,
   A = 0,
   B,
   B,
   C
   C
-} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to struct or union}}
+} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to}}
 
 
 // rdar://10513599
 // rdar://10513599
 #pragma ms_struct on
 #pragma ms_struct on

+ 1 - 1
test/Sema/types.c

@@ -75,7 +75,7 @@ typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vect
 // no support for vector enum type
 // no support for vector enum type
 enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}}
 enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}}
 
 
-int x4 __attribute__((ext_vector_type(64)));  // expected-error {{'ext_vector_type' attribute only applies to types}}
+int x4 __attribute__((ext_vector_type(64)));  // expected-error {{'ext_vector_type' attribute only applies to typedefs}}
 
 
 // rdar://16492792
 // rdar://16492792
 typedef __attribute__ ((ext_vector_type(32),__aligned__(32))) unsigned char uchar32;
 typedef __attribute__ ((ext_vector_type(32),__aligned__(32))) unsigned char uchar32;

+ 1 - 1
test/Sema/unused-expr.c

@@ -96,7 +96,7 @@ int t6() {
   return 0;
   return 0;
 }
 }
 
 
-int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to functions}}
+int t7 __attribute__ ((warn_unused_result)); // expected-warning {{'warn_unused_result' attribute only applies to Objective-C methods, enums, structs, unions, classes, functions, and function pointers}}
 
 
 // PR4010
 // PR4010
 int (*fn4)(void) __attribute__ ((warn_unused_result));
 int (*fn4)(void) __attribute__ ((warn_unused_result));

+ 1 - 1
test/Sema/warn-thread-safety-analysis.c

@@ -130,4 +130,4 @@ int main() {
 
 
 // We had a problem where we'd skip all attributes that follow a late-parsed
 // We had a problem where we'd skip all attributes that follow a late-parsed
 // attribute in a single __attribute__.
 // attribute in a single __attribute__.
-void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to fields and global variables}}
+void run() __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to non-static data members and global variables}}

+ 1 - 1
test/Sema/xray-always-instrument-attr.c

@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
 void foo() __attribute__((xray_always_instrument));
 void foo() __attribute__((xray_always_instrument));
 
 
-struct __attribute__((xray_always_instrument)) a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and methods}}
+struct __attribute__((xray_always_instrument)) a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and Objective-C methods}}
 
 
 void bar() __attribute__((xray_always_instrument("not-supported"))); // expected-error {{'xray_always_instrument' attribute takes no arguments}}
 void bar() __attribute__((xray_always_instrument("not-supported"))); // expected-error {{'xray_always_instrument' attribute takes no arguments}}

+ 1 - 1
test/Sema/xray-always-instrument-attr.cpp

@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
 void foo [[clang::xray_always_instrument]] ();
 void foo [[clang::xray_always_instrument]] ();
 
 
-struct [[clang::xray_always_instrument]] a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and methods}}
+struct [[clang::xray_always_instrument]] a { int x; }; // expected-warning {{'xray_always_instrument' attribute only applies to functions and Objective-C methods}}
 
 
 class b {
 class b {
  void c [[clang::xray_always_instrument]] ();
  void c [[clang::xray_always_instrument]] ();

+ 1 - 1
test/Sema/xray-log-args-oob.c

@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11
 void foo(int) __attribute__((xray_log_args(1)));
 void foo(int) __attribute__((xray_log_args(1)));
-struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
+struct __attribute__((xray_log_args(1))) a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and Objective-C methods}}
 
 
 void fop() __attribute__((xray_log_args(1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
 void fop() __attribute__((xray_log_args(1))); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
 
 

+ 1 - 1
test/Sema/xray-log-args-oob.cpp

@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
 // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++
 void foo [[clang::xray_log_args(1)]] (int);
 void foo [[clang::xray_log_args(1)]] (int);
-struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and methods}}
+struct [[clang::xray_log_args(1)]] a { int x; }; // expected-warning {{'xray_log_args' attribute only applies to functions and Objective-C methods}}
 
 
 void fop [[clang::xray_log_args(1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
 void fop [[clang::xray_log_args(1)]] (); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}}
 
 

+ 1 - 1
test/SemaCUDA/launch_bounds.cu

@@ -15,7 +15,7 @@ __launch_bounds__(128, -7) void TestNegArg2(void); // expected-warning {{'launch
 __launch_bounds__(1, 2, 3) void Test3Args(void); // expected-error {{'launch_bounds' attribute takes no more than 2 arguments}}
 __launch_bounds__(1, 2, 3) void Test3Args(void); // expected-error {{'launch_bounds' attribute takes no more than 2 arguments}}
 __launch_bounds__() void TestNoArgs(void); // expected-error {{'launch_bounds' attribute takes at least 1 argument}}
 __launch_bounds__() void TestNoArgs(void); // expected-error {{'launch_bounds' attribute takes at least 1 argument}}
 
 
-int TestNoFunction __launch_bounds__(128, 7); // expected-warning {{'launch_bounds' attribute only applies to functions and methods}}
+int TestNoFunction __launch_bounds__(128, 7); // expected-warning {{'launch_bounds' attribute only applies to Objective-C methods, functions, and function pointers}}
 
 
 __launch_bounds__(true) void TestBool(void);
 __launch_bounds__(true) void TestBool(void);
 __launch_bounds__(128.0) void TestFP(void); // expected-error {{'launch_bounds' attribute requires parameter 0 to be an integer constant}}
 __launch_bounds__(128.0) void TestFP(void); // expected-error {{'launch_bounds' attribute requires parameter 0 to be an integer constant}}

+ 5 - 5
test/SemaCXX/attr-lto-visibility-public.cpp

@@ -1,13 +1,13 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
 
-int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
-typedef int t [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
-[[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
+int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to structs, unions, and classes}}
+typedef int t [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to}}
+[[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to}}
 void f() [[clang::lto_visibility_public]]; // expected-error {{'lto_visibility_public' attribute cannot be applied to types}}
 void f() [[clang::lto_visibility_public]]; // expected-error {{'lto_visibility_public' attribute cannot be applied to types}}
 
 
 struct [[clang::lto_visibility_public]] s1 {
 struct [[clang::lto_visibility_public]] s1 {
-  int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
-  [[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to struct, union or class}}
+  int i [[clang::lto_visibility_public]]; // expected-warning {{'lto_visibility_public' attribute only applies to}}
+  [[clang::lto_visibility_public]] void f(); // expected-warning {{'lto_visibility_public' attribute only applies to}}
 };
 };
 
 
 struct [[clang::lto_visibility_public(1)]] s2 { // expected-error {{'lto_visibility_public' attribute takes no arguments}}
 struct [[clang::lto_visibility_public(1)]] s2 { // expected-error {{'lto_visibility_public' attribute takes no arguments}}

+ 1 - 1
test/SemaCXX/attr-mode-tmpl.cpp

@@ -72,7 +72,7 @@ struct TemplatedStruct {
                                               // expected-warning@-1{{deprecated}}
                                               // expected-warning@-1{{deprecated}}
 
 
   // Check attribute on methods - it is invalid.
   // Check attribute on methods - it is invalid.
-  __attribute__((mode(QI))) T g1() { return 0; } // expected-error{{'mode' attribute only applies to variables, enums, fields and typedefs}}
+  __attribute__((mode(QI))) T g1() { return 0; } // expected-error{{'mode' attribute only applies to variables, enums, typedefs, and non-static data members}}
 };
 };
 
 
 
 

+ 4 - 4
test/SemaCXX/attr-require-constant-initialization.cpp

@@ -56,12 +56,12 @@ struct StoresNonLit {
 #if defined(TEST_ONE) // Test semantics of attribute
 #if defined(TEST_ONE) // Test semantics of attribute
 
 
 // Test diagnostics when attribute is applied to non-static declarations.
 // Test diagnostics when attribute is applied to non-static declarations.
-void test_func_local(ATTR int param) { // expected-error {{only applies to variables with static or thread}}
-  ATTR int x = 42;                     // expected-error {{only applies to variables with static or thread}}
+void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}
+  ATTR int x = 42;                     // expected-error {{only applies to}}
   ATTR extern int y;
   ATTR extern int y;
 }
 }
-struct ATTR class_mem { // expected-error {{only applies to variables with static or thread}}
-  ATTR int x;           // expected-error {{only applies to variables with static or thread}}
+struct ATTR class_mem { // expected-error {{only applies to}}
+  ATTR int x;           // expected-error {{only applies to}}
 };
 };
 
 
 // [basic.start.static]p2.1
 // [basic.start.static]p2.1

+ 1 - 1
test/SemaCXX/attr-weak.cpp

@@ -3,7 +3,7 @@
 static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 
 
-namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}}
+namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions, and classes}}
 }
 }
 
 
 namespace {
 namespace {

+ 1 - 1
test/SemaCXX/builtin-assume-aligned-tmpl.cpp

@@ -57,7 +57,7 @@ void test22() {
   atest4<int, 5>();
   atest4<int, 5>();
 }
 }
 
 
-// expected-warning@+1 {{'assume_aligned' attribute only applies to functions and methods}}
+// expected-warning@+1 {{'assume_aligned' attribute only applies to Objective-C methods and functions}}
 class __attribute__((assume_aligned(32))) x {
 class __attribute__((assume_aligned(32))) x {
   int y;
   int y;
 };
 };

+ 8 - 8
test/SemaCXX/dllexport.cpp

@@ -17,18 +17,18 @@ struct External { int v; };
 
 
 // Invalid usage.
 // Invalid usage.
 __declspec(dllexport) typedef int typedef1;
 __declspec(dllexport) typedef int typedef1;
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
 typedef __declspec(dllexport) int typedef2;
 typedef __declspec(dllexport) int typedef2;
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 typedef int __declspec(dllexport) typedef3;
 typedef int __declspec(dllexport) typedef3;
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 typedef __declspec(dllexport) void (*FunTy)();
 typedef __declspec(dllexport) void (*FunTy)();
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 enum __declspec(dllexport) Enum {};
 enum __declspec(dllexport) Enum {};
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 #if __has_feature(cxx_strong_enums)
 #if __has_feature(cxx_strong_enums)
 enum class __declspec(dllexport) EnumClass {};
 enum class __declspec(dllexport) EnumClass {};
-// expected-warning@-1{{'dllexport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 #endif
 #endif
 
 
 
 
@@ -565,7 +565,7 @@ private:
   __declspec(dllexport)                void privateDef();
   __declspec(dllexport)                void privateDef();
 public:
 public:
 
 
-  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to}}
   __declspec(dllexport) static         int  StaticField;
   __declspec(dllexport) static         int  StaticField;
   __declspec(dllexport) static         int  StaticFieldDef;
   __declspec(dllexport) static         int  StaticFieldDef;
   __declspec(dllexport) static  const  int  StaticConstField;
   __declspec(dllexport) static  const  int  StaticConstField;
@@ -977,7 +977,7 @@ private:
   __declspec(dllexport)                void privateDef();
   __declspec(dllexport)                void privateDef();
 public:
 public:
 
 
-  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to}}
   __declspec(dllexport) static         int  StaticField;
   __declspec(dllexport) static         int  StaticField;
   __declspec(dllexport) static         int  StaticFieldDef;
   __declspec(dllexport) static         int  StaticFieldDef;
   __declspec(dllexport) static  const  int  StaticConstField;
   __declspec(dllexport) static  const  int  StaticConstField;

+ 8 - 8
test/SemaCXX/dllimport.cpp

@@ -16,18 +16,18 @@ namespace { struct Internal {}; }
 
 
 // Invalid usage.
 // Invalid usage.
 __declspec(dllimport) typedef int typedef1;
 __declspec(dllimport) typedef int typedef1;
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
 typedef __declspec(dllimport) int typedef2;
 typedef __declspec(dllimport) int typedef2;
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 typedef int __declspec(dllimport) typedef3;
 typedef int __declspec(dllimport) typedef3;
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 typedef __declspec(dllimport) void (*FunTy)();
 typedef __declspec(dllimport) void (*FunTy)();
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 enum __declspec(dllimport) Enum {};
 enum __declspec(dllimport) Enum {};
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 #if __has_feature(cxx_strong_enums)
 #if __has_feature(cxx_strong_enums)
 enum class __declspec(dllimport) EnumClass {};
 enum class __declspec(dllimport) EnumClass {};
-// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 #endif
 #endif
 
 
 
 
@@ -574,7 +574,7 @@ private:
   __declspec(dllimport)                void privateDecl();
   __declspec(dllimport)                void privateDecl();
 public:
 public:
 
 
-  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to}}
   __declspec(dllimport) static         int  StaticField;
   __declspec(dllimport) static         int  StaticField;
   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
   __declspec(dllimport) static  const  int  StaticConstField;
   __declspec(dllimport) static  const  int  StaticConstField;
@@ -1147,7 +1147,7 @@ private:
   __declspec(dllimport)                void privateDecl();
   __declspec(dllimport)                void privateDecl();
 public:
 public:
 
 
-  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to}}
   __declspec(dllimport) static         int  StaticField;
   __declspec(dllimport) static         int  StaticField;
   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
   __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
   __declspec(dllimport) static  const  int  StaticConstField;
   __declspec(dllimport) static  const  int  StaticConstField;

+ 4 - 4
test/SemaCXX/internal_linkage.cpp

@@ -5,7 +5,7 @@ int f() __attribute__((internal_linkage));
 class A;
 class A;
 class __attribute__((internal_linkage)) A {
 class __attribute__((internal_linkage)) A {
 public:
 public:
-  int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+  int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions, and classes}}
   static int y __attribute__((internal_linkage));
   static int y __attribute__((internal_linkage));
   void f1() __attribute__((internal_linkage));
   void f1() __attribute__((internal_linkage));
   void f2() __attribute__((internal_linkage)) {}
   void f2() __attribute__((internal_linkage)) {}
@@ -16,7 +16,7 @@ public:
   ~A() __attribute__((internal_linkage)) {}
   ~A() __attribute__((internal_linkage)) {}
   A& operator=(const A&) __attribute__((internal_linkage)) { return *this; }
   A& operator=(const A&) __attribute__((internal_linkage)) { return *this; }
   struct {
   struct {
-    int z  __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+    int z  __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to}}
   };
   };
 };
 };
 
 
@@ -24,14 +24,14 @@ __attribute__((internal_linkage)) void A::f4() {} // expected-error{{'internal_l
 
 
 __attribute__((internal_linkage)) int A::zz; // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'zz'}}
 __attribute__((internal_linkage)) int A::zz; // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'zz'}}
 
 
-namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to}}
 }
 }
 
 
 __attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}}
 __attribute__((internal_linkage("foo"))) int g() {} // expected-error{{'internal_linkage' attribute takes no arguments}}
 
 
 [[clang::internal_linkage]] int h() {}
 [[clang::internal_linkage]] int h() {}
 
 
-enum struct __attribute__((internal_linkage)) E { // expected-warning{{'internal_linkage' attribute only applies to variables, functions and classes}}
+enum struct __attribute__((internal_linkage)) E { // expected-warning{{'internal_linkage' attribute only applies to}}
   a = 1,
   a = 1,
   b = 2
   b = 2
 };
 };

+ 6 - 6
test/SemaCXX/warn-consumed-parsing.cpp

@@ -22,15 +22,15 @@ class AttrTester0 {
   void callableWhen()   __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
   void callableWhen()   __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
 };
 };
 
 
-int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
-int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}}
-int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}}
+int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to functions}}
+int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}}
+int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}}
 int var3 CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
 int var3 CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
 int var4 RETURN_TYPESTATE(consumed); // expected-warning {{'return_typestate' attribute only applies to functions}}
 int var4 RETURN_TYPESTATE(consumed); // expected-warning {{'return_typestate' attribute only applies to functions}}
 
 
-void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
-void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to methods}}
-void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to methods}}
+void function0() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to}}
+void function1() TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}}
+void function2() CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}}
 void function3() CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
 void function3() CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
 
 
 class CONSUMABLE(unknown) AttrTester1 {
 class CONSUMABLE(unknown) AttrTester1 {

+ 4 - 4
test/SemaCXX/warn-thread-safety-analysis.cpp

@@ -4427,11 +4427,11 @@ namespace pt_guard_attribute_type {
   int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
   int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
 
 
   void test() {
   void test() {
-    int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
-    int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+    int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
+    int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
 
 
-    typedef int PT_GUARDED_BY(sls_mu) bad1;  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
-    typedef int PT_GUARDED_VAR bad2;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+    typedef int PT_GUARDED_BY(sls_mu) bad1;  // expected-warning {{'pt_guarded_by' attribute only applies to}}
+    typedef int PT_GUARDED_VAR bad2;  // expected-warning {{'pt_guarded_var' attribute only applies to}}
   }
   }
 }  // end namespace pt_guard_attribute_type
 }  // end namespace pt_guard_attribute_type
 
 

+ 36 - 36
test/SemaCXX/warn-thread-safety-parsing.cpp

@@ -154,18 +154,18 @@ class GVFoo {
 };
 };
 
 
 class GUARDED_VAR GV { // \
 class GUARDED_VAR GV { // \
-  // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+  // expected-warning {{'guarded_var' attribute only applies to non-static data members and global variables}}
 };
 };
 
 
 void gv_function() GUARDED_VAR; // \
 void gv_function() GUARDED_VAR; // \
-  // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+  // expected-warning {{'guarded_var' attribute only applies to}}
 
 
 void gv_function_params(int gv_lvar GUARDED_VAR); // \
 void gv_function_params(int gv_lvar GUARDED_VAR); // \
-  // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+  // expected-warning {{'guarded_var' attribute only applies to}}
 
 
 int gv_testfn(int y){
 int gv_testfn(int y){
   int x GUARDED_VAR = y; // \
   int x GUARDED_VAR = y; // \
-    // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+    // expected-warning {{'guarded_var' attribute only applies to}}
   return x;
   return x;
 }
 }
 
 
@@ -194,7 +194,7 @@ class PGVFoo {
 };
 };
 
 
 class PT_GUARDED_VAR PGV { // \
 class PT_GUARDED_VAR PGV { // \
-  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+  // expected-warning {{'pt_guarded_var' attribute only applies to non-static data members and global variables}}
 };
 };
 
 
 int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
 int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
@@ -202,14 +202,14 @@ int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
 
 
 
 
 void pgv_function() PT_GUARDED_VAR; // \
 void pgv_function() PT_GUARDED_VAR; // \
-  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+  // expected-warning {{'pt_guarded_var' attribute only applies to}}
 
 
 void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \
 void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \
-  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+  // expected-warning {{'pt_guarded_var' attribute only applies to}}
 
 
 void pgv_testfn(int y){
 void pgv_testfn(int y){
   int *x PT_GUARDED_VAR = new int(0); // \
   int *x PT_GUARDED_VAR = new int(0); // \
-    // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+    // expected-warning {{'pt_guarded_var' attribute only applies to}}
   delete x;
   delete x;
 }
 }
 
 
@@ -231,28 +231,28 @@ class __attribute__((lockable (1))) LTestClass_args { // \
 };
 };
 
 
 void l_test_function() LOCKABLE;  // \
 void l_test_function() LOCKABLE;  // \
-  // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+  // expected-warning {{'lockable' attribute only applies to structs, unions, and classes}}
 
 
 int l_testfn(int y) {
 int l_testfn(int y) {
   int x LOCKABLE = y; // \
   int x LOCKABLE = y; // \
-    // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+    // expected-warning {{'lockable' attribute only applies to}}
   return x;
   return x;
 }
 }
 
 
 int l_test_var LOCKABLE; // \
 int l_test_var LOCKABLE; // \
-  // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+  // expected-warning {{'lockable' attribute only applies to}}
 
 
 class LFoo {
 class LFoo {
  private:
  private:
   int test_field LOCKABLE; // \
   int test_field LOCKABLE; // \
-    // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+    // expected-warning {{'lockable' attribute only applies to}}
   void test_method() LOCKABLE; // \
   void test_method() LOCKABLE; // \
-    // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+    // expected-warning {{'lockable' attribute only applies to}}
 };
 };
 
 
 
 
 void l_function_params(int lvar LOCKABLE); // \
 void l_function_params(int lvar LOCKABLE); // \
-  // expected-warning {{'lockable' attribute only applies to struct, union or class}}
+  // expected-warning {{'lockable' attribute only applies to}}
 
 
 
 
 //-----------------------------------------//
 //-----------------------------------------//
@@ -271,28 +271,28 @@ class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
 };
 };
 
 
 void sl_test_function() SCOPED_LOCKABLE;  // \
 void sl_test_function() SCOPED_LOCKABLE;  // \
-  // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+  // expected-warning {{'scoped_lockable' attribute only applies to structs, unions, and classes}}
 
 
 int sl_testfn(int y) {
 int sl_testfn(int y) {
   int x SCOPED_LOCKABLE = y; // \
   int x SCOPED_LOCKABLE = y; // \
-    // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+    // expected-warning {{'scoped_lockable' attribute only applies to}}
   return x;
   return x;
 }
 }
 
 
 int sl_test_var SCOPED_LOCKABLE; // \
 int sl_test_var SCOPED_LOCKABLE; // \
-  // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+  // expected-warning {{'scoped_lockable' attribute only applies to}}
 
 
 class SLFoo {
 class SLFoo {
  private:
  private:
   int test_field SCOPED_LOCKABLE; // \
   int test_field SCOPED_LOCKABLE; // \
-    // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+    // expected-warning {{'scoped_lockable' attribute only applies to}}
   void test_method() SCOPED_LOCKABLE; // \
   void test_method() SCOPED_LOCKABLE; // \
-    // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+    // expected-warning {{'scoped_lockable' attribute only applies to}}
 };
 };
 
 
 
 
 void sl_function_params(int lvar SCOPED_LOCKABLE); // \
 void sl_function_params(int lvar SCOPED_LOCKABLE); // \
-  // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
+  // expected-warning {{'scoped_lockable' attribute only applies to}}
 
 
 
 
 //-----------------------------------------//
 //-----------------------------------------//
@@ -325,18 +325,18 @@ class GBFoo {
 };
 };
 
 
 class GUARDED_BY(mu1) GB { // \
 class GUARDED_BY(mu1) GB { // \
-  // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+  // expected-warning {{'guarded_by' attribute only applies to non-static data members and global variables}}
 };
 };
 
 
 void gb_function() GUARDED_BY(mu1); // \
 void gb_function() GUARDED_BY(mu1); // \
-  // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+  // expected-warning {{'guarded_by' attribute only applies to}}
 
 
 void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \
 void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \
-  // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+  // expected-warning {{'guarded_by' attribute only applies to}}
 
 
 int gb_testfn(int y){
 int gb_testfn(int y){
   int x GUARDED_BY(mu1) = y; // \
   int x GUARDED_BY(mu1) = y; // \
-    // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+    // expected-warning {{'guarded_by' attribute only applies to}}
   return x;
   return x;
 }
 }
 
 
@@ -396,18 +396,18 @@ class PGBFoo {
 };
 };
 
 
 class PT_GUARDED_BY(mu1) PGB { // \
 class PT_GUARDED_BY(mu1) PGB { // \
-  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+  // expected-warning {{'pt_guarded_by' attribute only applies to non-static data members and global variables}}
 };
 };
 
 
 void pgb_function() PT_GUARDED_BY(mu1); // \
 void pgb_function() PT_GUARDED_BY(mu1); // \
-  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+  // expected-warning {{'pt_guarded_by' attribute only applies to}}
 
 
 void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \
 void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \
-  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+  // expected-warning {{'pt_guarded_by' attribute only applies to}}
 
 
 void pgb_testfn(int y){
 void pgb_testfn(int y){
   int *x PT_GUARDED_BY(mu1) = new int(0); // \
   int *x PT_GUARDED_BY(mu1) = new int(0); // \
-    // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+    // expected-warning {{'pt_guarded_by' attribute only applies to}}
   delete x;
   delete x;
 }
 }
 
 
@@ -458,18 +458,18 @@ class AAFoo {
 };
 };
 
 
 class ACQUIRED_AFTER(mu1) AA { // \
 class ACQUIRED_AFTER(mu1) AA { // \
-  // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+  // expected-warning {{'acquired_after' attribute only applies to non-static data members and global variables}}
 };
 };
 
 
 void aa_function() ACQUIRED_AFTER(mu1); // \
 void aa_function() ACQUIRED_AFTER(mu1); // \
-  // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+  // expected-warning {{'acquired_after' attribute only applies to}}
 
 
 void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \
 void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \
-  // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+  // expected-warning {{'acquired_after' attribute only applies to}}
 
 
 void aa_testfn(int y){
 void aa_testfn(int y){
   Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \
   Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \
-    // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+    // expected-warning {{'acquired_after' attribute only applies to}}
 }
 }
 
 
 //Check argument parsing.
 //Check argument parsing.
@@ -518,18 +518,18 @@ class ABFoo {
 };
 };
 
 
 class ACQUIRED_BEFORE(mu1) AB { // \
 class ACQUIRED_BEFORE(mu1) AB { // \
-  // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+  // expected-warning {{'acquired_before' attribute only applies to non-static data members and global variables}}
 };
 };
 
 
 void ab_function() ACQUIRED_BEFORE(mu1); // \
 void ab_function() ACQUIRED_BEFORE(mu1); // \
-  // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+  // expected-warning {{'acquired_before' attribute only applies to}}
 
 
 void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \
 void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \
-  // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+  // expected-warning {{'acquired_before' attribute only applies to}}
 
 
 void ab_testfn(int y){
 void ab_testfn(int y){
   Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \
   Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \
-    // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+    // expected-warning {{'acquired_before' attribute only applies to}}
 }
 }
 
 
 // Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will
 // Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will

+ 1 - 1
test/SemaCXX/warn-unused-attribute.cpp

@@ -15,6 +15,6 @@ int main(void) {
   TestNormal normal;
   TestNormal normal;
   used.use();
   used.use();
 
 
-  int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to struct, union or class}}
+  int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to structs, unions, and classes}}
   return i;
   return i;
 }
 }

+ 1 - 1
test/SemaObjC/arc-property-lifetime.m

@@ -172,7 +172,7 @@ void foo(Baz *f) {
 // rdar://11253688
 // rdar://11253688
 @interface Boom 
 @interface Boom 
 {
 {
-  const void * innerPointerIvar __attribute__((objc_returns_inner_pointer)); // expected-error {{'objc_returns_inner_pointer' attribute only applies to methods and properties}}
+  const void * innerPointerIvar __attribute__((objc_returns_inner_pointer)); // expected-error {{'objc_returns_inner_pointer' attribute only applies to Objective-C methods and Objective-C properties}}
 }
 }
 @property (readonly) Boom * NotInnerPointer __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to properties that return a non-retainable pointer}}
 @property (readonly) Boom * NotInnerPointer __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to properties that return a non-retainable pointer}}
 - (Boom *) NotInnerPointerMethod __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to methods that return a non-retainable pointer}}
 - (Boom *) NotInnerPointerMethod __attribute__((objc_returns_inner_pointer)); // expected-warning {{'objc_returns_inner_pointer' attribute only applies to methods that return a non-retainable pointer}}

+ 6 - 6
test/SemaObjC/dllexport.m

@@ -1,17 +1,17 @@
 // RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
 
 
 __declspec(dllexport) typedef int typedef1;
 __declspec(dllexport) typedef int typedef1;
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
 typedef __declspec(dllexport) int typedef2;
 typedef __declspec(dllexport) int typedef2;
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 typedef int __declspec(dllexport) typedef3;
 typedef int __declspec(dllexport) typedef3;
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 typedef __declspec(dllexport) void (*FunTy)();
 typedef __declspec(dllexport) void (*FunTy)();
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 enum __declspec(dllexport) E { Val };
 enum __declspec(dllexport) E { Val };
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 struct __declspec(dllexport) Record {};
 struct __declspec(dllexport) Record {};
-// expected-warning@-1{{'dllexport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllexport' attribute only applies to}}
 
 
 __declspec(dllexport)
 __declspec(dllexport)
 __attribute__((__objc_root_class__))
 __attribute__((__objc_root_class__))

+ 6 - 6
test/SemaObjC/dllimport.m

@@ -1,17 +1,17 @@
 // RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple i686-windows -fdeclspec -fsyntax-only -verify %s
 
 
 __declspec(dllimport) typedef int typedef1;
 __declspec(dllimport) typedef int typedef1;
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}
 typedef __declspec(dllimport) int typedef2;
 typedef __declspec(dllimport) int typedef2;
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 typedef int __declspec(dllimport) typedef3;
 typedef int __declspec(dllimport) typedef3;
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 typedef __declspec(dllimport) void (*FunTy)();
 typedef __declspec(dllimport) void (*FunTy)();
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 enum __declspec(dllimport) E { Val };
 enum __declspec(dllimport) E { Val };
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 struct __declspec(dllimport) Record {};
 struct __declspec(dllimport) Record {};
-// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, and Objective-C interfaces}}
+// expected-warning@-1{{'dllimport' attribute only applies to}}
 
 
 __declspec(dllimport)
 __declspec(dllimport)
 __attribute__((__objc_root_class__))
 __attribute__((__objc_root_class__))

+ 3 - 3
test/SemaObjC/format-arg-attribute.m

@@ -9,9 +9,9 @@ extern void fc1 (const NSString *) __attribute__((format_arg));  // expected-err
 extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{'format_arg' attribute takes one argument}}
 extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{'format_arg' attribute takes one argument}}
 extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{'format_arg' attribute takes one argument}}
 extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{'format_arg' attribute takes one argument}}
 
 
-struct s1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to non-K&R-style functions}}
-union u1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to non-K&R-style functions}}
-enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to non-K&R-style functions}}
+struct s1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to Objective-C methods and non-K&R-style functions}}
+union u1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to}}
+enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to}}
 
 
 extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
 extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
 extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}}
 extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}}

+ 3 - 3
test/SemaObjC/objc-asm-attribute-neg-test.m

@@ -15,15 +15,15 @@ __attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
 
 
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 @interface Message <Protocol> { 
 @interface Message <Protocol> { 
-__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
   id MyIVAR;
   id MyIVAR;
 }
 }
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 __attribute__((objc_runtime_name("MySecretNamespace.Message")))
 @property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
 @property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
 
 
-- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
 
 
-- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
 
 
 @end
 @end
 
 

+ 1 - 1
test/SemaObjC/objcbridge-attribute-arc.m

@@ -32,7 +32,7 @@ typedef XXX *CFUColor2Ref;
 
 
 @interface I
 @interface I
 {
 {
-   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}};
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, classes, and typedefs}};
 }
 }
 @end
 @end
 
 

+ 1 - 1
test/SemaObjC/objcbridge-attribute.m

@@ -38,7 +38,7 @@ typedef struct Opaque *OpaqueRef __attribute__((objc_bridge(id))); // expected-e
 
 
 @interface I
 @interface I
 {
 {
-   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}};
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, classes, and typedefs}};
 }
 }
 @end
 @end
 
 

+ 57 - 121
utils/TableGen/ClangAttrEmitter.cpp

@@ -3029,136 +3029,72 @@ static void GenerateDefaultAppertainsTo(raw_ostream &OS) {
   OS << "}\n\n";
   OS << "}\n\n";
 }
 }
 
 
+static std::string GetDiagnosticSpelling(const Record &R) {
+  std::string Ret = R.getValueAsString("DiagSpelling");
+  if (!Ret.empty())
+    return Ret;
+
+  // If we couldn't find the DiagSpelling in this object, we can check to see
+  // if the object is one that has a base, and if it is, loop up to the Base
+  // member recursively.
+  std::string Super = R.getSuperClasses().back().first->getName();
+  if (Super == "DDecl" || Super == "DStmt")
+    return GetDiagnosticSpelling(*R.getValueAsDef("Base"));
+
+  return "";
+}
+
 static std::string CalculateDiagnostic(const Record &S) {
 static std::string CalculateDiagnostic(const Record &S) {
   // If the SubjectList object has a custom diagnostic associated with it,
   // If the SubjectList object has a custom diagnostic associated with it,
   // return that directly.
   // return that directly.
   const StringRef CustomDiag = S.getValueAsString("CustomDiag");
   const StringRef CustomDiag = S.getValueAsString("CustomDiag");
   if (!CustomDiag.empty())
   if (!CustomDiag.empty())
-    return CustomDiag;
-
-  // Given the list of subjects, determine what diagnostic best fits.
-  enum {
-    Func = 1U << 0,
-    Var = 1U << 1,
-    ObjCMethod = 1U << 2,
-    Param = 1U << 3,
-    Class = 1U << 4,
-    GenericRecord = 1U << 5,
-    Type = 1U << 6,
-    ObjCIVar = 1U << 7,
-    ObjCProp = 1U << 8,
-    ObjCInterface = 1U << 9,
-    Block = 1U << 10,
-    Namespace = 1U << 11,
-    Field = 1U << 12,
-    CXXMethod = 1U << 13,
-    ObjCProtocol = 1U << 14,
-    Enum = 1U << 15,
-    Named = 1U << 16,
-  };
-  uint32_t SubMask = 0;
+    return ("\"" + Twine(CustomDiag) + "\"").str();
 
 
+  std::vector<std::string> DiagList;
   std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
   std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
   for (const auto *Subject : Subjects) {
   for (const auto *Subject : Subjects) {
     const Record &R = *Subject;
     const Record &R = *Subject;
-    std::string Name;
+    // Get the diagnostic text from the Decl or Stmt node given.
+    std::string V = GetDiagnosticSpelling(R);
+    if (V.empty()) {
+      PrintError(R.getLoc(),
+                 "Could not determine diagnostic spelling for the node: " +
+                     R.getName() + "; please add one to DeclNodes.td");
+    } else {
+      // The node may contain a list of elements itself, so split the elements
+      // by a comma, and trim any whitespace.
+      SmallVector<StringRef, 2> Frags;
+      llvm::SplitString(V, Frags, ",");
+      for (auto Str : Frags) {
+        DiagList.push_back(Str.trim());
+      }
+    }
+  }
 
 
-    if (R.isSubClassOf("SubsetSubject")) {
-      PrintError(R.getLoc(), "SubsetSubjects should use a custom diagnostic");
-      // As a fallback, look through the SubsetSubject to see what its base
-      // type is, and use that. This needs to be updated if SubsetSubjects
-      // are allowed within other SubsetSubjects.
-      Name = R.getValueAsDef("Base")->getName();
-    } else
-      Name = R.getName();
-
-    uint32_t V = StringSwitch<uint32_t>(Name)
-                   .Case("Function", Func)
-                   .Case("Var", Var)
-                   .Case("ObjCMethod", ObjCMethod)
-                   .Case("ParmVar", Param)
-                   .Case("TypedefName", Type)
-                   .Case("ObjCIvar", ObjCIVar)
-                   .Case("ObjCProperty", ObjCProp)
-                   .Case("Record", GenericRecord)
-                   .Case("ObjCInterface", ObjCInterface)
-                   .Case("ObjCProtocol", ObjCProtocol)
-                   .Case("Block", Block)
-                   .Case("CXXRecord", Class)
-                   .Case("Namespace", Namespace)
-                   .Case("Field", Field)
-                   .Case("CXXMethod", CXXMethod)
-                   .Case("Enum", Enum)
-                   .Case("Named", Named)
-                   .Default(0);
-    if (!V) {
-      // Something wasn't in our mapping, so be helpful and let the developer
-      // know about it.
-      PrintFatalError(R.getLoc(), "Unknown subject type: " + R.getName());
-      return "";
-    }
-
-    SubMask |= V;
-  }
-
-  switch (SubMask) {
-    // For the simple cases where there's only a single entry in the mask, we
-    // don't have to resort to bit fiddling.
-    case Func:  return "ExpectedFunction";
-    case Var:   return "ExpectedVariable";
-    case Param: return "ExpectedParameter";
-    case Class: return "ExpectedClass";
-    case Enum:  return "ExpectedEnum";
-    case CXXMethod:
-      // FIXME: Currently, this maps to ExpectedMethod based on existing code,
-      // but should map to something a bit more accurate at some point.
-    case ObjCMethod:  return "ExpectedMethod";
-    case Type:  return "ExpectedType";
-    case ObjCInterface: return "ExpectedObjectiveCInterface";
-    case ObjCProtocol: return "ExpectedObjectiveCProtocol";
-    
-    // "GenericRecord" means struct, union or class; check the language options
-    // and if not compiling for C++, strip off the class part. Note that this
-    // relies on the fact that the context for this declares "Sema &S".
-    case GenericRecord:
-      return "(S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : "
-                                           "ExpectedStructOrUnion)";
-    case Func | ObjCMethod | Block: return "ExpectedFunctionMethodOrBlock";
-    case Func | ObjCMethod | Class: return "ExpectedFunctionMethodOrClass";
-    case Func | Param:
-    case Func | ObjCMethod | Param: return "ExpectedFunctionMethodOrParameter";
-    case Func | ObjCMethod: return "ExpectedFunctionOrMethod";
-    case Func | Var: return "ExpectedVariableOrFunction";
-
-    // If not compiling for C++, the class portion does not apply.
-    case Func | Var | Class:
-      return "(S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : "
-                                           "ExpectedVariableOrFunction)";
-
-    case Func | Var | Class | ObjCInterface:
-      return "(S.getLangOpts().CPlusPlus"
-             "     ? ((S.getLangOpts().ObjC1 || S.getLangOpts().ObjC2)"
-             "            ? ExpectedFunctionVariableClassOrObjCInterface"
-             "            : ExpectedFunctionVariableOrClass)"
-             "     : ((S.getLangOpts().ObjC1 || S.getLangOpts().ObjC2)"
-             "            ? ExpectedFunctionVariableOrObjCInterface"
-             "            : ExpectedVariableOrFunction))";
-
-    case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
-    case Func | ObjCMethod | ObjCProp:
-      return "ExpectedFunctionOrMethodOrProperty";
-    case ObjCProtocol | ObjCInterface:
-      return "ExpectedObjectiveCInterfaceOrProtocol";
-    case Field | Var: return "ExpectedFieldOrGlobalVar";
-
-    case Named:
-      return "ExpectedNamedDecl";
-  }
-
-  PrintFatalError(S.getLoc(),
-                  "Could not deduce diagnostic argument for Attr subjects");
+  if (DiagList.empty()) {
+    PrintFatalError(S.getLoc(),
+                    "Could not deduce diagnostic argument for Attr subjects");
+    return "";
+  }
 
 
-  return "";
+  // FIXME: this is not particularly good for localization purposes and ideally
+  // should be part of the diagnostics engine itself with some sort of list
+  // specifier.
+
+  // A single member of the list can be returned directly.
+  if (DiagList.size() == 1)
+    return '"' + DiagList.front() + '"';
+
+  if (DiagList.size() == 2)
+    return '"' + DiagList[0] + " and " + DiagList[1] + '"';
+
+  // If there are more than two in the list, we serialize the first N - 1
+  // elements with a comma. This leaves the string in the state: foo, bar,
+  // baz (but misses quux). We can then add ", and " for the last element
+  // manually.
+  std::string Diag = llvm::join(DiagList.begin(), DiagList.end() - 1, ", ");
+  return '"' + Diag + ", and " + *(DiagList.end() - 1) + '"';
 }
 }
 
 
 static std::string GetSubjectWithSuffix(const Record *R) {
 static std::string GetSubjectWithSuffix(const Record *R) {
@@ -3245,8 +3181,8 @@ static std::string GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
   }
   }
   SS << ") {\n";
   SS << ") {\n";
   SS << "    S.Diag(Attr.getLoc(), diag::";
   SS << "    S.Diag(Attr.getLoc(), diag::";
-  SS << (Warn ? "warn_attribute_wrong_decl_type" :
-               "err_attribute_wrong_decl_type");
+  SS << (Warn ? "warn_attribute_wrong_decl_type_str" :
+               "err_attribute_wrong_decl_type_str");
   SS << ")\n";
   SS << ")\n";
   SS << "      << Attr.getName() << ";
   SS << "      << Attr.getName() << ";
   SS << CalculateDiagnostic(*SubjectObj) << ";\n";
   SS << CalculateDiagnostic(*SubjectObj) << ";\n";