diff options
author | Edwin Vane <edwin.vane@intel.com> | 2013-05-31 13:20:24 +0000 |
---|---|---|
committer | Edwin Vane <edwin.vane@intel.com> | 2013-05-31 13:20:24 +0000 |
commit | 99f8042e74c0ecbfad3a75cf65b5245839e1fa8d (patch) | |
tree | 8d53f2d061ec43000c3ff33a253e26fc84907557 /clang-tools-extra | |
parent | 5494e0bec303af3557f96fa3e6dff88428b885a8 (diff) | |
download | bcm5719-llvm-99f8042e74c0ecbfad3a75cf65b5245839e1fa8d.tar.gz bcm5719-llvm-99f8042e74c0ecbfad3a75cf65b5245839e1fa8d.zip |
cpp11-migrate: Add option to detect and use macros that expand to 'override'
Added a new option -override-macros which causes the, the add-override
transform to detect macros that expand to 'override' (like LLVM_OVERRIDE) and
use these macros instead of the override keyword directly.
llvm-svn: 183001
Diffstat (limited to 'clang-tools-extra')
5 files changed, 109 insertions, 61 deletions
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp index f431c34c88f..f02548b25ff 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp @@ -16,15 +16,21 @@ #include "AddOverride.h" #include "AddOverrideActions.h" #include "AddOverrideMatchers.h" +#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" +#include "llvm/Support/CommandLine.h" using clang::ast_matchers::MatchFinder; using namespace clang::tooling; using namespace clang; +static llvm::cl::opt<bool> DetectMacros( + "override-macros", + llvm::cl::desc("Detect and use macros that expand to the 'override' keyword.")); + int AddOverrideTransform::apply(const FileContentsByPath &InputStates, RiskLevel MaxRisk, const CompilationDatabase &Database, @@ -41,7 +47,10 @@ int AddOverrideTransform::apply(const FileContentsByPath &InputStates, unsigned AcceptedChanges = 0; MatchFinder Finder; - AddOverrideFixer Fixer(AddOverrideTool.getReplacements(), AcceptedChanges); + AddOverrideFixer Fixer(AddOverrideTool.getReplacements(), AcceptedChanges, + DetectMacros); + // Make Fixer available to handleBeginSource(). + this->Fixer = &Fixer; Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer); @@ -62,3 +71,10 @@ int AddOverrideTransform::apply(const FileContentsByPath &InputStates, return 0; } + +bool AddOverrideTransform::handleBeginSource(clang::CompilerInstance &CI, + llvm::StringRef Filename) { + assert(Fixer != NULL && "Fixer must be set"); + Fixer->setPreprocessor(CI.getPreprocessor()); + return Transform::handleBeginSource(CI, Filename); +} diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h index 1e9de5d5c71..45bd6ee8725 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.h @@ -20,6 +20,8 @@ #include "Core/Transform.h" #include "llvm/Support/Compiler.h" +class AddOverrideFixer; + /// \brief Subclass of Transform that adds the C++11 override keyword to /// member functions overriding base class virtual functions. class AddOverrideTransform : public Transform { @@ -33,6 +35,12 @@ public: const clang::tooling::CompilationDatabase &Database, const std::vector<std::string> &SourcePaths, FileContentsByPath &ResultStates) LLVM_OVERRIDE; + + virtual bool handleBeginSource(clang::CompilerInstance &CI, + llvm::StringRef Filename) LLVM_OVERRIDE; + +private: + AddOverrideFixer *Fixer; }; #endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_ADD_OVERRIDE_H diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp index b93aee927d3..008e947410e 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp @@ -21,6 +21,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; using namespace clang::tooling; @@ -85,6 +86,15 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) { StartLoc = SM.getSpellingLoc(M->getLocEnd()); StartLoc = Lexer::getLocForEndOfToken(StartLoc, 0, SM, LangOptions()); } - Replace.insert(tooling::Replacement(SM, StartLoc, 0, " override")); + + std::string ReplacementText = " override"; + if (DetectMacros) { + assert(PP != 0 && "No access to Preprocessor object for macro detection"); + clang::TokenValue Tokens[] = { PP->getIdentifierInfo("override") }; + llvm::StringRef MacroName = PP->getLastMacroWithSpelling(StartLoc, Tokens); + if (!MacroName.empty()) + ReplacementText = (" " + MacroName).str(); + } + Replace.insert(tooling::Replacement(SM, StartLoc, 0, ReplacementText)); ++AcceptedChanges; } diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h index b2fdcec83cc..831344344a1 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.h @@ -24,15 +24,20 @@ class AddOverrideFixer : public clang::ast_matchers::MatchFinder::MatchCallback { public: AddOverrideFixer(clang::tooling::Replacements &Replace, - unsigned &AcceptedChanges) : - Replace(Replace), AcceptedChanges(AcceptedChanges) {} + unsigned &AcceptedChanges, bool DetectMacros) + : Replace(Replace), AcceptedChanges(AcceptedChanges), + DetectMacros(DetectMacros) {} /// \brief Entry point to the callback called when matches are made. virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result); + void setPreprocessor(clang::Preprocessor &PP) { this->PP = &PP; } + private: + clang::Preprocessor *PP; clang::tooling::Replacements &Replace; unsigned &AcceptedChanges; + bool DetectMacros; }; #endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_ADD_OVERRIDE_ACTIONS_H diff --git a/clang-tools-extra/test/cpp11-migrate/AddOverride/basic.cpp b/clang-tools-extra/test/cpp11-migrate/AddOverride/basic.cpp index 4bc471015df..41a50eb5e31 100644 --- a/clang-tools-extra/test/cpp11-migrate/AddOverride/basic.cpp +++ b/clang-tools-extra/test/cpp11-migrate/AddOverride/basic.cpp @@ -1,9 +1,11 @@ // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp // RUN: cpp11-migrate -add-override %t.cpp -- -I %S -std=c++11 // RUN: FileCheck -input-file=%t.cpp %s +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp +// RUN: cpp11-migrate -add-override -override-macros %t.cpp -- -I %S -std=c++11 +// RUN: FileCheck --check-prefix=MACRO --input-file=%t.cpp %s -class A { -public: +struct A { virtual ~A(); // CHECK: virtual ~A(); void f(); @@ -14,81 +16,76 @@ public: }; // Test that override isn't added to non-virtual functions. -class B : public A { -public: +struct B : public A { void f(); - // CHECK: class B - // CHECK: void f(); + // CHECK: struct B + // CHECK-NEXT: void f(); }; // Test that override is added to functions that override virtual functions. -class C : public A { -public: +struct C : public A { void h() const; - // CHECK: class C - // CHECK: void h() const override; + // CHECK: struct C + // CHECK-NEXT: void h() const override; + // MACRO: struct C + // MACRO-NEXT: void h() const override; }; // Test that override isn't add to functions that overload but not override. -class D : public A { -public: +struct D : public A { void h(); - // CHECK: class D - // CHECK: void h(); + // CHECK: struct D + // CHECK-NEXT: void h(); }; // Test that override isn't added again to functions that already have it. -class E : public A { -public: +struct E : public A { void h() const override; - // CHECK: class E - // CHECK: void h() const override; + // CHECK: struct E + // CHECK-NEXT: void h() const override; + // MACRO: struct E + // MACRO-NEXT: void h() const override; }; // Test that override isn't added to the destructor. -class F : public A { -public: +struct F : public A { virtual ~F(); - // CHECK: class F - // CHECK: virtual ~F(); + // CHECK: struct F + // CHECK-NEXT: virtual ~F(); }; // Test that override is placed before any end of line comments. -class G : public A { -public: +struct G : public A { void h() const; // comment void i() // comment {} - // CHECK: class G - // CHECK: void h() const override; // comment - // CHECK: void i() override // comment + // CHECK: struct G + // CHECK-NEXT: void h() const override; // comment + // CHECK-NEXT: void i() override // comment // CHECK-NEXT: {} }; // Test that override is placed correctly if there is an inline body. -class H : public A { -public: +struct H : public A { void h() const { } - // CHECK: class H - // CHECK: void h() const override { } + // CHECK: struct H + // CHECK-NEXT: void h() const override { } }; // Test that override is placed correctly if there is a body on the next line. -class I : public A { -public: +struct I : public A { void h() const { } - // CHECK: class I - // CHECK: void h() const override - // CHECK: { } + // CHECK: struct I + // CHECK-NEXT: void h() const override + // CHECK-NEXT: { } }; // Test that override is placed correctly if there is a body outside the class. -class J : public A { -public: +struct J : public A { void h() const; - // CHECK: class J - // CHECK: void h() const override; + // CHECK: struct J + // CHECK-NEXT: void h() const override; }; void J::h() const { @@ -96,21 +93,32 @@ void J::h() const { } // Test that override is placed correctly if there is a trailing return type. -class K : public A { -public: +struct K : public A { auto h() const -> void; - // CHECK: class K - // CHECK: auto h() const -> void override; + // CHECK: struct K + // CHECK-NEXT: auto h() const -> void override; }; -// Test that override isn't added if it is already specified via a macro. -class L : public A { -public: #define LLVM_OVERRIDE override + +// Test that override isn't added if it is already specified via a macro. +struct L : public A { void h() const LLVM_OVERRIDE; - // CHECK: class L - // CHECK: void h() const LLVM_OVERRIDE; + // CHECK: struct L + // CHECK-NEXT: void h() const LLVM_OVERRIDE; + // MACRO: struct L + // MACRO-NEXT: void h() const LLVM_OVERRIDE; +}; + +template <typename T> +struct M : public A { + virtual void i(); + // CHECK: struct M + // CHECK-NEXT: virtual void i() override; + // MACRO: struct M + // MACRO-NEXT: virtual void i() LLVM_OVERRIDE; }; +M<int> b; // Test that override isn't added at the wrong place for "pure overrides" struct APure { @@ -137,16 +145,17 @@ struct Base2 {}; template<typename T> struct Derived : T { void f(); // adding 'override' here will break instantiation of Derived<Base2> // CHECK: struct Derived - // CHECK: void f(); + // CHECK-NEXT: void f(); }; Derived<Base1> d1; Derived<Base2> d2; -template <typename T> -class M : public A { -public: - virtual void i(); - // CHECK: class M : public A { - // CHECK: virtual void i() override; +#undef LLVM_OVERRIDE + +struct N : public A { + void h() const; + // CHECK: struct N + // CHECK-NEXT: void h() const override; + // MACRO: struct N + // MACRO-NEXT: void h() const override; }; -M<int> b; |