Skip to content

Instantly share code, notes, and snippets.

@chichunchen
Last active April 20, 2019 03:09
Show Gist options
  • Save chichunchen/32838bcf7a53b69c5ff8a03a06b54ae4 to your computer and use it in GitHub Desktop.
Save chichunchen/32838bcf7a53b69c5ff8a03a06b54ae4 to your computer and use it in GitHub Desktop.

Revisions

  1. chichunchen revised this gist Apr 20, 2019. 1 changed file with 70 additions and 31 deletions.
    101 changes: 70 additions & 31 deletions ClangTool.cpp
    Original file line number Diff line number Diff line change
    @@ -1,24 +1,65 @@
    // Clang includes
    #include "clang/AST/AST.h"
    #include "clang/AST/ASTConsumer.h"
    #include "clang/AST/ASTContext.h"
    #include "clang/AST/AttrIterator.h"
    #include "clang/AST/Decl.h"
    #include "clang/AST/DeclCXX.h"
    #include "clang/AST/DeclarationName.h"
    #include "clang/AST/RecursiveASTVisitor.h"
    #include "clang/Basic/Diagnostic.h"
    #include "clang/Basic/SourceLocation.h"
    #include "clang/Basic/SourceManager.h"
    #include "clang/Basic/TokenKinds.h"
    #include "clang/Frontend/CompilerInstance.h"
    #include "clang/Frontend/FrontendAction.h"
    #include "clang/Lex/Lexer.h"
    #include "clang/Rewrite/Core/RewriteBuffer.h"
    #include "clang/Rewrite/Core/Rewriter.h"
    #include "clang/Tooling/CommonOptionsParser.h"
    #include "clang/Tooling/Tooling.h"

    // LLVM includes
    #include "llvm//Support/Path.h"
    #include "llvm/ADT/ArrayRef.h"
    #include "llvm/ADT/StringRef.h"
    #include "llvm/ADT/Twine.h"
    #include "llvm/Support/Casting.h"
    #include "llvm/Support/CommandLine.h"
    #include "llvm/Support/raw_ostream.h"

    // Standard includes
    #include <algorithm>
    #include <cassert>
    #include <cstddef>
    #include <functional>
    #include <iterator>
    #include <memory>
    #include <string>
    #include <utility>
    #include <vector>

    namespace UseOverride {
    class Consumer : public clang::ASTConsumer {
    public:
    void HandleTranslationUnit(clang::ASTContext& Context) {
    }
    public:
    void HandleTranslationUnit(clang::ASTContext &Context) {}
    };

    class Action : public clang::ASTFrontendAction {
    public:
    using ASTConsumerPointer = std::unique_ptr<clang::ASTConsumer>;
    public:
    using ASTConsumerPointer = std::unique_ptr<clang::ASTConsumer>;

    explicit Action(bool RewriteOption) : RewriteOption(RewriteOption) {}
    explicit Action(bool RewriteOption) : RewriteOption(RewriteOption) {}

    ASTConsumerPointer
    CreateASTConsumer(clang::CompilerInstance&, llvm::StringRef) override {
    return std::make_unique<Consumer>();
    }
    private:
    bool RewriteOption;
    ASTConsumerPointer CreateASTConsumer(clang::CompilerInstance &,
    llvm::StringRef) override {
    return std::make_unique<Consumer>();
    }

    private:
    bool RewriteOption;
    };
    }
    } // namespace UseOverride

    namespace {
    llvm::cl::OptionCategory UseOverrideCategory("Use override options");
    @@ -36,31 +77,29 @@ declaration 'method()' should be followed by the keyword 'override'.
    )");

    llvm::cl::opt<bool>
    RewriteOption("rewrite",
    llvm::cl::init(false),
    llvm::cl::desc("If set, emits rewritten source code"),
    llvm::cl::cat(UseOverrideCategory));
    RewriteOption("rewrite", llvm::cl::init(false),
    llvm::cl::desc("If set, emits rewritten source code"),
    llvm::cl::cat(UseOverrideCategory));
    llvm::cl::alias
    RewriteShortOption("r",
    llvm::cl::desc("Alias for the --rewrite option"),
    llvm::cl::aliasopt(RewriteOption));
    RewriteShortOption("r", llvm::cl::desc("Alias for the --rewrite option"),
    llvm::cl::aliasopt(RewriteOption));
    llvm::cl::extrahelp
    CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage);
    CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage);

    }
    } // namespace

    struct ToolFactory : public clang::tooling::FrontendActionFactory {
    clang::FrontendAction* create() override {
    return new UseOverride::Action(RewriteOption);
    }
    clang::FrontendAction *create() override {
    return new UseOverride::Action(RewriteOption);
    }
    };

    auto main(int argc, const char* argv[]) -> int {
    using namespace clang::tooling;
    auto main(int argc, const char *argv[]) -> int {
    using namespace clang::tooling;

    CommonOptionsParser OptionsParser(argc, argv, UseOverrideCategory);
    ClangTool Tool(OptionsParser.getCompilations(),
    OptionsParser.getSourcePathList());
    CommonOptionsParser OptionsParser(argc, argv, UseOverrideCategory);
    ClangTool Tool(OptionsParser.getCompilations(),
    OptionsParser.getSourcePathList());

    return Tool.run(new ToolFactory);
    return Tool.run(new ToolFactory);
    }
  2. chichunchen revised this gist Apr 20, 2019. 1 changed file with 48 additions and 8 deletions.
    56 changes: 48 additions & 8 deletions ClangTool.cpp
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,25 @@
    namespace UseOverride {
    class Consumer : public clang::ASTConsumer {
    public:
    void HandleTranslationUnit(clang::ASTContext& Context) {
    }
    };

    class Action : public clang::ASTFrontendAction {
    public:
    using ASTConsumerPointer = std::unique_ptr<clang::ASTConsumer>;

    explicit Action(bool RewriteOption) : RewriteOption(RewriteOption) {}

    ASTConsumerPointer
    CreateASTConsumer(clang::CompilerInstance&, llvm::StringRef) override {
    return std::make_unique<Consumer>();
    }
    private:
    bool RewriteOption;
    };
    }

    namespace {
    llvm::cl::OptionCategory UseOverrideCategory("Use override options");
    llvm::cl::extrahelp UseOverrideCategoryHelp(R"(
    @@ -10,17 +32,35 @@ For example, given this snippet of code:
    void method(int);
    };
    Running this tool over the code will produce a warning message stating that the
    declaration 'method()' should be followed by the keyword 'override'.
    declaration 'method()' should be followed by the keyword 'override'.
    )");

    llvm::cl::opt<bool>
    RewriteOption("rewrite",
    llvm::cl::init(false),
    llvm::cl::desc("If set, emits rewritten source code"),
    llvm::cl::cat(UseOverrideCategory));
    llvm::cl::alias
    RewriteShortOption("r",
    llvm::cl::desc("Alias for the --rewrite option"),
    llvm::cl::aliasopt(RewriteOption));
    llvm::cl::extrahelp
    CommonHelp(clang::tooling::CommonOptionsParser::HelpMessage);

    }

    struct ToolFactory : public clang::tooling::FrontendActionFactory {
    clang::FrontendAction* create() override {
    return new UseOverride::Action(RewriteOption);
    }
    };

    auto main(int argc, const char* argv[]) -> int {
    using namespace clang::tooling;
    using namespace clang::tooling;

    CommonOptionsParser OptionsParser(argc, argv, UseOverrideCategory);
    ClangTool Tool(OptionsParser.getCompilations(),
    OptionsParser.getSourcePathList());
    CommonOptionsParser OptionsParser(argc, argv, UseOverrideCategory);
    ClangTool Tool(OptionsParser.getCompilations(),
    OptionsParser.getSourcePathList());

    auto action = newFrontendActionFactory<UseOverride::Action>();
    return Tool.run(action.get());
    }
    return Tool.run(new ToolFactory);
    }
  3. chichunchen created this gist Apr 20, 2019.
    26 changes: 26 additions & 0 deletions ClangTool.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    namespace {
    llvm::cl::OptionCategory UseOverrideCategory("Use override options");
    llvm::cl::extrahelp UseOverrideCategoryHelp(R"(
    This tool ensures that you use the 'override' keyword appropriately.
    For example, given this snippet of code:
    struct Base {
    virtual void method(int);
    };
    struct Derived : public Base {
    void method(int);
    };
    Running this tool over the code will produce a warning message stating that the
    declaration 'method()' should be followed by the keyword 'override'.
    )");
    }

    auto main(int argc, const char* argv[]) -> int {
    using namespace clang::tooling;

    CommonOptionsParser OptionsParser(argc, argv, UseOverrideCategory);
    ClangTool Tool(OptionsParser.getCompilations(),
    OptionsParser.getSourcePathList());

    auto action = newFrontendActionFactory<UseOverride::Action>();
    return Tool.run(action.get());
    }