}
unsigned getSpellingListIndex() const { return SpellingListIndex; }
+ virtual const char *getSpelling() const = 0;
SourceLocation getLocation() const { return Range.getBegin(); }
SourceRange getRange() const { return Range; }
#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
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
"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 {
//===----------------------------------------------------------------------===//
#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"
NeedQuotes = false;
break;
}
+ case DiagnosticsEngine::ak_attr: {\r
+ const Attr *At = reinterpret_cast<Attr *>(Val);\r
+ assert(At && "Received null Attr object!");\r
+ OS << '\'' << At->getSpelling() << '\'';\r
+ NeedQuotes = false;\r
+ break;\r
+ }\r
+
}
OS.flush();
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,
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>();
}
}
!(LangOpts.MicrosoftExt && FD->getLexicalDeclContext()->isRecord())) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
- << "dllimport";
+ << DA;
FD->setInvalidDecl();
return D;
}
// 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
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;
}
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();
}
}
// 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
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}}
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}}
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();
// 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;
{
int c2;
} d2;
-
+
union C2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
{
int e2;
// __stdcall handling
struct M {
int __stdcall addP();
- float __stdcall subtractP();
+ float __stdcall subtractP();
};
// __unaligned handling
void m1() {
h1<int>(&M::addP);
h1(&M::subtractP);
-}
+}
void f(long long);
void f(int);
-
+
int main()
{
// This is an ambiguous call in standard C++.
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}}
}
namespace rdar14250378 {
class Bar {};
-
+
namespace NyNamespace {
class Foo {
public:
Bar* EnsureBar();
};
-
+
class Baz : public Foo {
public:
friend class Bar;
};
-
+
Bar* Foo::EnsureBar() {
return 0;
}
<< " 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");
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);
OS << ", getSpellingListIndex());\n}\n\n";
writePrettyPrintFunction(R, Args, OS);
+ writeGetSpellingFunction(R, OS);
}
}