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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits