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