r198055 - Teach the diagnostics engine about the Attr type to make reporting on semantic attributes easier (and not require hard-coded strings). This requires a getSpelling() function on the Attr class, which is table-driven. Updates a handful of cases where a hard-coded string was being used to test the functionality out. Updating associated test cases for the improved quoting.

Aaron Ballman aaron at aaronballman.com
Thu Dec 26 10:30:58 PST 2013


Author: aaronballman
Date: Thu Dec 26 12:30:57 2013
New Revision: 198055

URL: http://llvm.org/viewvc/llvm-project?rev=198055&view=rev
Log:
Teach the diagnostics engine about the Attr type to make reporting on semantic attributes easier (and not require hard-coded strings). This requires a getSpelling() function on the Attr class, which is table-driven. Updates a handful of cases where a hard-coded string was being used to test the functionality out. Updating associated test cases for the improved quoting.

Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Rewriter/missing-dllimport.c
    cfe/trunk/test/Sema/dllimport-dllexport.c
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
    cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Thu Dec 26 12:30:57 2013
@@ -85,6 +85,7 @@ public:
   }
   
   unsigned getSpellingListIndex() const { return SpellingListIndex; }
+  virtual const char *getSpelling() const = 0;
 
   SourceLocation getLocation() const { return Range.getBegin(); }
   SourceRange getRange() const { return Range; }
@@ -138,6 +139,19 @@ public:
 
 #include "clang/AST/Attrs.inc"
 
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const Attr *At) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+                  DiagnosticsEngine::ak_attr);
+  return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           const Attr *At) {
+  PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+                  DiagnosticsEngine::ak_attr);
+  return PD;
+}
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Thu Dec 26 12:30:57 2013
@@ -166,7 +166,8 @@ public:
     ak_nameddecl,       ///< NamedDecl *
     ak_nestednamespec,  ///< NestedNameSpecifier *
     ak_declcontext,     ///< DeclContext *
-    ak_qualtype_pair    ///< pair<QualType, QualType>
+    ak_qualtype_pair,   ///< pair<QualType, QualType>
+    ak_attr             ///< Attr *
   };
 
   /// \brief Represents on argument value, which is a union discriminated

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 26 12:30:57 2013
@@ -6722,7 +6722,7 @@ def err_opencl_global_invalid_addr_space
   "global variables must have a constant address space qualifier">;
 def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">;
 def err_opencl_kernel_attr :
-  Error<"attribute '%0' can only be applied to a kernel function">;
+  Error<"attribute %0 can only be applied to a kernel function">;
 } // end of sema category
 
 let CategoryName = "OpenMP Issue" in {

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Thu Dec 26 12:30:57 2013
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
@@ -359,6 +360,14 @@ void clang::FormatASTNodeDiagnosticArgum
       NeedQuotes = false;
       break;
     }
+    case DiagnosticsEngine::ak_attr: {
+      const Attr *At = reinterpret_cast<Attr *>(Val);
+      assert(At && "Received null Attr object!");
+      OS << '\'' << At->getSpelling() << '\'';
+      NeedQuotes = false;
+      break;
+    }
+
   }
 
   OS.flush();

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Thu Dec 26 12:30:57 2013
@@ -861,6 +861,7 @@ FormatDiagnostic(const char *DiagStr, co
     case DiagnosticsEngine::ak_nameddecl:
     case DiagnosticsEngine::ak_nestednamespec:
     case DiagnosticsEngine::ak_declcontext:
+    case DiagnosticsEngine::ak_attr:
       getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
                                      Modifier, ModifierLen,
                                      Argument, ArgumentLen,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec 26 12:30:57 2013
@@ -8934,7 +8934,7 @@ Sema::FinalizeDeclaration(Decl *ThisDecl
 
   if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
     if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
-      Diag(Attr->getLocation(), diag::warn_attribute_ignored) << "'used'";
+      Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
       VD->dropAttr<UsedAttr>();
     }
   }
@@ -9674,7 +9674,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop
         !(LangOpts.MicrosoftExt && FD->getLexicalDeclContext()->isRecord())) {
       Diag(FD->getLocation(),
            diag::err_attribute_can_be_applied_only_to_symbol_declaration)
-        << "dllimport";
+        << DA;
       FD->setInvalidDecl();
       return D;
     }
@@ -9687,7 +9687,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop
       // emitted.
       Diag(FD->getLocation(),
            diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-        << FD->getName() << "dllimport";
+        << FD->getName() << DA;
     }
   }
   // We want to attach documentation to original Decl (which might be

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Dec 26 12:30:57 2013
@@ -1557,8 +1557,8 @@ static void handleVecReturnAttr(Sema &S,
     return result; // This will be returned in a register
   }
 */
-  if (D->hasAttr<VecReturnAttr>()) {
-    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
+  if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << A;
     return;
   }
 
@@ -4127,18 +4127,16 @@ void Sema::ProcessDeclAttributeList(Scop
 
   if (!D->hasAttr<OpenCLKernelAttr>()) {
     // These attributes cannot be applied to a non-kernel function.
-    if (D->hasAttr<ReqdWorkGroupSizeAttr>()) {
-      Diag(D->getLocation(), diag::err_opencl_kernel_attr)
-          << "reqd_work_group_size";
+    if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
+      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
       D->setInvalidDecl();
     }
-    if (D->hasAttr<WorkGroupSizeHintAttr>()) {
-      Diag(D->getLocation(), diag::err_opencl_kernel_attr)
-          << "work_group_size_hint";
+    if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) {
+      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
       D->setInvalidDecl();
     }
-    if (D->hasAttr<VecTypeHintAttr>()) {
-      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << "vec_type_hint";
+    if (Attr *A = D->getAttr<VecTypeHintAttr>()) {
+      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
       D->setInvalidDecl();
     }
   }

Modified: cfe/trunk/test/Rewriter/missing-dllimport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/missing-dllimport.c?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/test/Rewriter/missing-dllimport.c (original)
+++ cfe/trunk/test/Rewriter/missing-dllimport.c Thu Dec 26 12:30:57 2013
@@ -13,7 +13,7 @@ void bar() { return 1; }
 
 // CHECK-NEG: error: void function 'bar' should not return a value
 // CHECK-NEG: 1 error generated
-// CHECK-POS: warning: 'foo' redeclared without dllimport attribute: previous dllimport ignored
+// CHECK-POS: warning: 'foo' redeclared without 'dllimport' attribute: previous 'dllimport' ignored
 // CHECK-POS: error: void function 'bar' should not return a value
 // CHECK-POS: 1 warning and 1 error generated
 

Modified: cfe/trunk/test/Sema/dllimport-dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport-dllexport.c?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/test/Sema/dllimport-dllexport.c (original)
+++ cfe/trunk/test/Sema/dllimport-dllexport.c Thu Dec 26 12:30:57 2013
@@ -4,7 +4,7 @@
 inline void __attribute__((dllexport)) foo1(){} // expected-warning{{'dllexport' attribute ignored}}
 inline void __attribute__((dllimport)) foo2(){} // expected-warning{{'dllimport' attribute ignored}}
 
-void __attribute__((dllimport)) foo3(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
+void __attribute__((dllimport)) foo3(){} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
 
 void __attribute__((dllimport, dllexport)) foo4(); // expected-warning{{dllimport attribute ignored}}
 
@@ -16,13 +16,13 @@ typedef int __attribute__((dllexport)) t
 typedef int __attribute__((dllimport)) type7; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
 
 void __attribute__((dllimport)) foo6();
-void foo6(){} // expected-warning {{'foo6' redeclared without dllimport attribute: previous dllimport ignored}}
+void foo6(){} // expected-warning {{'foo6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
 
 // PR6269
 inline void __declspec(dllexport) foo7(){} // expected-warning{{'dllexport' attribute ignored}}
 inline void __declspec(dllimport) foo8(){} // expected-warning{{'dllimport' attribute ignored}}
 
-void __declspec(dllimport) foo9(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
+void __declspec(dllimport) foo9(){} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
 
 void __declspec(dllimport) __declspec(dllexport) foo10(); // expected-warning{{dllimport attribute ignored}}
 
@@ -34,7 +34,7 @@ typedef int __declspec(dllexport) type1;
 typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
 
 void __declspec(dllimport) foo12();
-void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}}
+void foo12(){} // expected-warning {{'foo12' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
 
 void __attribute__((dllimport)) foo13(); // expected-warning{{dllimport attribute ignored}}
 void __attribute__((dllexport)) foo13();

Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Thu Dec 26 12:30:57 2013
@@ -37,11 +37,11 @@ class B : public A {
 // MSVC allows type definition in anonymous union and struct
 struct A
 {
-  union 
+  union
   {
     int a;
     struct B  // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
-    { 
+    {
       int c;
     } d;
 
@@ -63,7 +63,7 @@ struct A
     {
       int c2;
     } d2;
-    
+
 	union C2  // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
     {
       int e2;
@@ -78,7 +78,7 @@ struct A
 // __stdcall handling
 struct M {
     int __stdcall addP();
-    float __stdcall subtractP(); 
+    float __stdcall subtractP();
 };
 
 // __unaligned handling
@@ -90,7 +90,7 @@ template<typename T> void h1(T (__stdcal
 void m1() {
   h1<int>(&M::addP);
   h1(&M::subtractP);
-} 
+}
 
 
 
@@ -98,7 +98,7 @@ void m1() {
 
 void f(long long);
 void f(int);
- 
+
 int main()
 {
   // This is an ambiguous call in standard C++.
@@ -126,7 +126,7 @@ __declspec(dllimport) void f(void) { }
 void f2(void);
 };
 
-__declspec(dllimport) void AAA::f2(void) { // expected-error {{dllimport attribute can be applied only to symbol}}
+__declspec(dllimport) void AAA::f2(void) { // expected-error {{'dllimport' attribute can be applied only to symbol}}
 
 }
 
@@ -368,18 +368,18 @@ struct StructWithUnnamedMember {
 
 namespace rdar14250378 {
   class Bar {};
-  
+
   namespace NyNamespace {
     class Foo {
     public:
       Bar* EnsureBar();
     };
-    
+
     class Baz : public Foo {
     public:
       friend class Bar;
     };
-    
+
     Bar* Foo::EnsureBar() {
       return 0;
     }

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=198055&r1=198054&r2=198055&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Thu Dec 26 12:30:57 2013
@@ -954,6 +954,29 @@ static void writeAvailabilityValue(raw_o
      << "  OS << \"";
 }
 
+static void writeGetSpellingFunction(Record &R, raw_ostream &OS) {
+  std::vector<Record *> Spellings = R.getValueAsListOfDefs("Spellings");
+
+  OS << "const char *" << R.getName() << "Attr::getSpelling() const {\n";
+  if (Spellings.empty()) {
+    OS << "  return \"(No spelling)\";\n}\n\n";
+    return;
+  }
+
+  OS << "  switch (SpellingListIndex) {\n"
+        "  default:\n"
+        "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
+        "    return \"(No spelling)\";\n";
+
+  for (unsigned I = 0; I < Spellings.size(); ++I)
+    OS << "  case " << I << ":\n"
+          "    return \"" << Spellings[I]->getValueAsString("Name") << "\";\n";
+  // End of the switch statement.
+  OS << "  }\n";
+  // End of the getSpelling function.
+  OS << "}\n\n";
+}
+
 static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
                                      raw_ostream &OS) {
   std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
@@ -1197,6 +1220,7 @@ void EmitClangAttrClass(RecordKeeper &Re
     OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
     OS << "  virtual void printPretty(raw_ostream &OS,\n"
        << "                           const PrintingPolicy &Policy) const;\n";
+    OS << "  virtual const char *getSpelling() const;\n";
 
     writeAttrAccessorDefinition(R, OS);
 
@@ -1328,6 +1352,7 @@ void EmitClangAttrImpl(RecordKeeper &Rec
     OS << ", getSpellingListIndex());\n}\n\n";
 
     writePrettyPrintFunction(R, Args, OS);
+    writeGetSpellingFunction(R, OS);
   }
 }
 





More information about the cfe-commits mailing list