john.brawn updated this revision to Diff 239307.
john.brawn added reviewers: erichkeane, aaron.ballman, rjmccall.
john.brawn set the repository for this revision to rG LLVM Github Monorepo.
john.brawn added a subscriber: cfe-commits.
john.brawn added a comment.
Herald added a project: clang.
Resurrecting this old patch. This is the fourth of four patches to make it
possible for clang plugins to define attributes.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D31343/new/
https://reviews.llvm.org/D31343
Files:
clang/examples/Attribute/Attribute.cpp
clang/examples/Attribute/CMakeLists.txt
clang/examples/CMakeLists.txt
clang/test/CMakeLists.txt
clang/test/Frontend/plugin-attribute.cpp
Index: clang/test/Frontend/plugin-attribute.cpp
===================================================================
--- /dev/null
+++ clang/test/Frontend/plugin-attribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang -fplugin=%llvmshlibdir/Attribute%pluginext -emit-llvm -S %s -o - | 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
+// REQUIRES: plugins, examples
+
+// 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: [[STR3_VAR:@.+]] = private unnamed_addr constant [21 x i8] c"example(otherstring)\00"
+// ATTRIBUTE: @llvm.global.annotations = {{.*}}@{{.*}}fn1a{{.*}}[[STR1_VAR]]{{.*}}@{{.*}}fn1b{{.*}}[[STR1_VAR]]{{.*}}@{{.*}}fn2{{.*}}[[STR2_VAR]]{{.*}}@{{.*}}var1{{.*}}[[STR3_VAR]]
+void fn1a() __attribute__((example)) { }
+[[example]] void fn1b() { }
+void fn2() __attribute__((example("somestring"))) { }
+int var1 __attribute__((example("otherstring"))) = 1;
+
+#ifdef BAD_ATTRIBUTE
+void fn3() {
+ // BADATTRIBUTE: error: 'example' attribute only allowed at file scop
+ int var2 __attribute__((example));
+}
+// 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"))) { }
+#endif
Index: clang/test/CMakeLists.txt
===================================================================
--- clang/test/CMakeLists.txt
+++ clang/test/CMakeLists.txt
@@ -72,6 +72,7 @@
if (CLANG_BUILD_EXAMPLES)
list(APPEND CLANG_TEST_DEPS
+ Attribute
AnnotateFunctions
clang-interpreter
PrintFunctionNames
Index: clang/examples/CMakeLists.txt
===================================================================
--- clang/examples/CMakeLists.txt
+++ clang/examples/CMakeLists.txt
@@ -6,3 +6,4 @@
add_subdirectory(clang-interpreter)
add_subdirectory(PrintFunctionNames)
add_subdirectory(AnnotateFunctions)
+add_subdirectory(Attribute)
Index: clang/examples/Attribute/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang/examples/Attribute/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_llvm_library(Attribute MODULE Attribute.cpp PLUGIN_TOOL clang)
+
+if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
+ target_link_libraries(AnnotateFunctions ${cmake_2_8_12_PRIVATE}
+ clangAST
+ clangBasic
+ clangFrontend
+ clangLex
+ LLVMSupport
+ )
+endif()
Index: clang/examples/Attribute/Attribute.cpp
===================================================================
--- /dev/null
+++ clang/examples/Attribute/Attribute.cpp
@@ -0,0 +1,66 @@
+//===- Attribute.cpp ------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Example clang plugin which adds an an annotation to file-scope declarations
+// with the 'example' attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/Sema/ParsedAttr.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/IR/Attributes.h"
+using namespace clang;
+
+namespace {
+
+struct ExampleAttrInfo : public ParsedAttrInfo {
+ ExampleAttrInfo() {
+ // Set the kind to NoSemaHandlerAttribute to make sure clang doesn't assume
+ // anything about what it does.
+ AttrKind = ParsedAttr::NoSemaHandlerAttribute;
+ // Can take an optional string argument.
+ OptArgs = 1;
+ // GNU-style __attribute__(("example")) and C++-style [[example]] supported.
+ Spellings.push_back({ParsedAttr::AS_GNU, "example"});
+ Spellings.push_back({ParsedAttr::AS_CXX11, "::example"});
+ }
+ virtual bool handleDeclAttribute(Sema &S, Decl *D,
+ const ParsedAttr &Attr) const {
+ // Check if the decl is at file scope.
+ if (!D->getDeclContext()->isFileContext()) {
+ unsigned ID = S.getDiagnostics().getCustomDiagID(
+ DiagnosticsEngine::Error,
+ "'example' attribute only allowed at file scope");
+ S.Diag(Attr.getLoc(), ID);
+ }
+ // Check if we have an optional string argument.
+ StringRef Str = "";
+ if (Attr.getNumArgs() > 0) {
+ Expr *ArgExpr = 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;
+ }
+ }
+ // Attach an annotate attribute to the Decl.
+ D->addAttr(AnnotateAttr::Create(S.Context, "example(" + Str.str() + ")",
+ Attr.getRange()));
+ return true;
+ }
+};
+
+} // namespace
+
+static ParsedAttrInfoRegistry::Add<ExampleAttrInfo> X("example", "");
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits