psionic12 updated this revision to Diff 309813.
psionic12 added a comment.

Add tests to check if attributes are attached to AST


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92006/new/

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,21 @@
-// 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 -cc1 -load %llvmshlibdir/Attribute%pluginext -DGOOD_ATTR -fsyntax-only -ast-dump -verify=goodattr %s | FileCheck %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"))) {}
+// CHECK-COUNT-4: -AnnotateAttr 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} "example"
+// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char [{{[0-9]+}}]' lvalue "somestring"
+#endif
 
-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]]
-
-#ifdef BAD_ATTRIBUTE
+#ifdef BAD_ATTR
+int var1 __attribute__((example("otherstring"))) = 1; // badattr-warning {{'example' attribute only applies to functions}}
 class Example {
-  // BADATTRIBUTE: error: 'example' attribute only allowed at file scope
-  void __attribute__((example)) fn3();
+  void __attribute__((example)) fn3(); // badattr-error {{'example' attribute only allowed at file scope}}
 };
-// BADATTRIBUTE: error: 'example' attribute requires a string
-void fn4() __attribute__((example(123))) { }
-// BADATTRIBUTE: error: 'example' attribute takes no more than 1 argument
-void fn5() __attribute__((example("a","b"))) { }
+void fn4() __attribute__((example(123))) { } // badattr-error {{'example's first argument should be a string literal}}
+void fn5() __attribute__((example("a","b", 3, 4.0))) { } // badattr-error {{'example' attribute only allowed at most three arguments}}
 #endif
Index: clang/examples/Attribute/Attribute.cpp
===================================================================
--- clang/examples/Attribute/Attribute.cpp
+++ clang/examples/Attribute/Attribute.cpp
@@ -23,9 +23,10 @@
 
 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 up to 15 optional arguments, to emulate accepting a variadic
+    // number of arguments. This just illustrates how many arguments a
+    // `ParsedAttrInfo` can hold, we will not use that much in this example.
+    OptArgs = 15;
     // GNU-style __attribute__(("example")) and C++-style [[example]] and
     // [[plugin::example]] supported.
     static constexpr Spelling S[] = {{ParsedAttr::AS_GNU, "example"},
@@ -39,7 +40,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 +56,33 @@
       S.Diag(Attr.getLoc(), ID);
       return AttributeNotApplied;
     }
-    // Check if we have an optional string argument.
-    StringRef Str = "";
+    // We make some rules here:
+    // 1. Only accept at most 3 arguments here.
+    // 2. The first argument must be a string literal if it 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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to