psionic12 created this revision.
psionic12 added reviewers: john.brawn, aaron.ballman, Tyker.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
psionic12 requested review of this revision.
Make the example compiled and the test case passed.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D92006
Files:
clang/examples/Attribute/Attribute.cpp
clang/test/Frontend/plugin-attribute.cpp
Index: clang/test/Frontend/plugin-attribute.cpp
===================================================================
--- clang/test/Frontend/plugin-attribute.cpp
+++ clang/test/Frontend/plugin-attribute.cpp
@@ -1,25 +1,23 @@
-// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -emit-llvm -S %s -o - 2>&1 | FileCheck %s --check-prefix=ATTRIBUTE
-// RUN: not %clang -fplugin=%llvmshlibdir/Attribute%pluginext -emit-llvm -DBAD_ATTRIBUTE -S %s -o - 2>&1 | FileCheck %s --check-prefix=BADATTRIBUTE
+// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -DGOOD_ATTR -fsyntax-only -Xclang -verify=goodattr %s
+// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -DBAD_ATTR -fsyntax-only -Xclang -verify=badattr %s
// REQUIRES: plugins, examples
-
+#ifdef GOOD_ATTR
+// goodattr-no-diagnostics
void fn1a() __attribute__((example)) { }
[[example]] void fn1b() { }
[[plugin::example]] void fn1c() { }
void fn2() __attribute__((example("somestring"))) { }
-// ATTRIBUTE: warning: 'example' attribute only applies to functions
-int var1 __attribute__((example("otherstring"))) = 1;
-
-// ATTRIBUTE: [[STR1_VAR:@.+]] = private unnamed_addr constant [10 x i8] c"example()\00"
-// ATTRIBUTE: [[STR2_VAR:@.+]] = private unnamed_addr constant [20 x i8] c"example(somestring)\00"
-// ATTRIBUTE: @llvm.global.annotations = {{.*}}@{{.*}}fn1a{{.*}}[[STR1_VAR]]{{.*}}@{{.*}}fn1b{{.*}}[[STR1_VAR]]{{.*}}@{{.*}}fn1c{{.*}}[[STR1_VAR]]{{.*}}@{{.*}}fn2{{.*}}[[STR2_VAR]]
+#endif
-#ifdef BAD_ATTRIBUTE
+#ifdef BAD_ATTR
+// badattr-warning@14 {{'example' attribute only applies to functions}}
+int var1 __attribute__((example("otherstring"))) = 1;
class Example {
- // BADATTRIBUTE: error: 'example' attribute only allowed at file scope
+ // badattr-error@17 {{'example' attribute only allowed at file scope}}
void __attribute__((example)) fn3();
};
-// BADATTRIBUTE: error: 'example' attribute requires a string
+// badattr-error@20 {{'example's first argument should be a string literal}}
void fn4() __attribute__((example(123))) { }
-// BADATTRIBUTE: error: 'example' attribute takes no more than 1 argument
-void fn5() __attribute__((example("a","b"))) { }
+// badattr-error@22 {{'example' attribute only allowed at most three arguments}}
+void fn5() __attribute__((example("a","b", 3, 4.0))) { }
#endif
Index: clang/examples/Attribute/Attribute.cpp
===================================================================
--- clang/examples/Attribute/Attribute.cpp
+++ clang/examples/Attribute/Attribute.cpp
@@ -23,9 +23,8 @@
struct ExampleAttrInfo : public ParsedAttrInfo {
ExampleAttrInfo() {
- // Can take an optional string argument (the check that the argument
- // actually is a string happens in handleDeclAttribute).
- OptArgs = 1;
+ // Can take variadic arguments.
+ OptArgs = 15;
// GNU-style __attribute__(("example")) and C++-style [[example]] and
// [[plugin::example]] supported.
static constexpr Spelling S[] = {{ParsedAttr::AS_GNU, "example"},
@@ -39,7 +38,7 @@
// This attribute appertains to functions only.
if (!isa<FunctionDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str)
- << Attr << "functions";
+ << Attr << "functions";
return false;
}
return true;
@@ -55,23 +54,31 @@
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}
- // Check if we have an optional string argument.
- StringRef Str = "";
+ // Make sure there are at most three arguments exists
+ if (Attr.getNumArgs() > 3) {
+ unsigned ID = S.getDiagnostics().getCustomDiagID(
+ DiagnosticsEngine::Error,
+ "'example' attribute only allowed at most three arguments");
+ S.Diag(Attr.getLoc(), ID);
+ return AttributeNotApplied;
+ }
+ // If has arguments, the first argument should be a string literal
+ Expr *Arg0 = nullptr;
if (Attr.getNumArgs() > 0) {
- Expr *ArgExpr = Attr.getArgAsExpr(0);
+ Arg0 = Attr.getArgAsExpr(0);
StringLiteral *Literal =
- dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
- if (Literal) {
- Str = Literal->getString();
- } else {
- S.Diag(ArgExpr->getExprLoc(), diag::err_attribute_argument_type)
- << Attr.getAttrName() << AANT_ArgumentString;
+ dyn_cast<StringLiteral>(Arg0->IgnoreParenCasts());
+ if (!Literal) {
+ unsigned ID = S.getDiagnostics().getCustomDiagID(
+ DiagnosticsEngine::Error,
+ "'example's first argument should be a string literal");
+ S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}
}
// Attach an annotate attribute to the Decl.
- D->addAttr(AnnotateAttr::Create(S.Context, "example(" + Str.str() + ")",
- Attr.getRange()));
+ D->addAttr(AnnotateAttr::Create(S.Context, "example", &Arg0,
+ Attr.getNumArgs(), Attr.getRange()));
return AttributeApplied;
}
};
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits