citrun

watch C/C++ source code execute
Log | Files | Refs | LICENSE

commit 51b04695cb81670905902cd81b53254714ff10a7
parent 206aa1a24869b9c69c5e79643d395fe84ec30984
Author: kyle <kyle@getaddrinfo.net>
Date:   Sun,  1 Nov 2015 14:47:31 -0700

instrumenter: move MyFrontendAction class

- put MyFrontendAction into instrumenter.cpp
- now it lives with the other semantic analysis-y stuff
- main.cpp is mostly argument fixups, file backups, etc

Diffstat:
Minstrument/instrumenter.cpp | 47+++++++++++++++++++++++++++++++++++++++++++++++
Minstrument/instrumenter.h | 28++++++++++++++++++++++++++++
Minstrument/main.cpp | 63---------------------------------------------------------------
3 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/instrument/instrumenter.cpp b/instrument/instrumenter.cpp @@ -1,9 +1,14 @@ +#include <err.h> +#include <fcntl.h> // open +#include <sys/stat.h> // mode flags + #include <sstream> #include <string> #include <iostream> #include <clang/AST/AST.h> #include <clang/Lex/Lexer.h> +#include <clang/Frontend/CompilerInstance.h> #include "instrumenter.h" @@ -97,3 +102,45 @@ instrumenter::real_loc_end(Stmt *d) SourceLocation _e(d->getLocEnd()); return SourceLocation(Lexer::getLocForEndOfToken(_e, 0, SM, lopt)); } + +// MyFrontendAction --- + +ASTConsumer * +MyFrontendAction::CreateASTConsumer(CompilerInstance &CI, StringRef file) +{ + // llvm::errs() << "** Creating AST consumer for: " << file << "\n"; + SourceManager &sm = CI.getSourceManager(); + TheRewriter.setSourceMgr(sm, CI.getLangOpts()); + + return new MyASTConsumer(TheRewriter); +} + +void +MyFrontendAction::EndSourceFileAction() +{ + SourceManager &sm = TheRewriter.getSourceMgr(); + const FileID main_fid = sm.getMainFileID(); + // llvm::errs() << "** EndSourceFileAction for: " + // << sm.getFileEntryForID(main_fid)->getName() + // << "\n"; + + SourceLocation start = sm.getLocForStartOfFile(main_fid); + std::string file_name = getCurrentFile(); + + std::stringstream ss; + // Add declarations for coverage buffers + int file_bytes = sm.getFileIDSize(main_fid); + ss << "unsigned int lines[" << file_bytes << "];" + << std::endl; + ss << "int size = " << file_bytes << ";" << std::endl; + ss << "char file_name[] = \"" << file_name << "\";" << std::endl; + TheRewriter.InsertTextAfter(start, ss.str()); + + // rewrite the original source file + int fd = open(file_name.c_str(), O_WRONLY | O_CREAT); + if (fd < 0) + err(1, "open"); + llvm::raw_fd_ostream output(fd, /* close */ 1); + TheRewriter.getEditBuffer(main_fid).write(output); + // TheRewriter.getEditBuffer(main_fid).write(llvm::outs()); +} diff --git a/instrument/instrumenter.h b/instrument/instrumenter.h @@ -1,5 +1,6 @@ #include <clang/AST/ASTConsumer.h> #include <clang/AST/RecursiveASTVisitor.h> +#include <clang/Frontend/FrontendActions.h> #include <clang/Rewrite/Core/Rewriter.h> using namespace clang; @@ -44,3 +45,30 @@ public: private: instrumenter Visitor; }; + +// For each source file provided to the tool, a new FrontendAction is created. +class MyFrontendAction : public ASTFrontendAction { +public: + MyFrontendAction() {}; + + void EndSourceFileAction() override; + ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef file); + +private: + Rewriter TheRewriter; +}; + + +#if 0 +class MFAF : public FrontendActionFactory { +public: + MFAF(std::vector<const char *> &i) : inst_files(i) {} + + FrontendAction *create() { + return new MyFrontendAction(); + } + +private: + std::vector<const char *> inst_files; +}; +#endif diff --git a/instrument/main.cpp b/instrument/main.cpp @@ -1,8 +1,6 @@ #include <err.h> // err, errx -#include <fcntl.h> // open #include <stdlib.h> // mktemp #include <unistd.h> -#include <sys/stat.h> // mode flags #include <sys/wait.h> // wait #include <fstream> @@ -10,8 +8,6 @@ #include <sstream> #include <string> -#include <clang/Frontend/FrontendActions.h> -#include <clang/Frontend/CompilerInstance.h> #include <clang/Tooling/CommonOptionsParser.h> #include <clang/Tooling/Tooling.h> #include <clang/Rewrite/Core/Rewriter.h> @@ -20,69 +16,10 @@ #include "instrumenter.h" using namespace clang; -using namespace clang::driver; using namespace clang::tooling; static llvm::cl::OptionCategory ToolingCategory("instrument options"); -// For each source file provided to the tool, a new FrontendAction is created. -class MyFrontendAction : public ASTFrontendAction { -public: - MyFrontendAction() {}; - - void EndSourceFileAction() override { - SourceManager &sm = TheRewriter.getSourceMgr(); - const FileID main_fid = sm.getMainFileID(); - // llvm::errs() << "** EndSourceFileAction for: " - // << sm.getFileEntryForID(main_fid)->getName() - // << "\n"; - - SourceLocation start = sm.getLocForStartOfFile(main_fid); - std::string file_name = getCurrentFile(); - - std::stringstream ss; - // Add declarations for coverage buffers - int file_bytes = sm.getFileIDSize(main_fid); - ss << "unsigned int lines[" << file_bytes << "];" - << std::endl; - ss << "int size = " << file_bytes << ";" << std::endl; - ss << "char file_name[] = \"" << file_name << "\";" << std::endl; - TheRewriter.InsertTextAfter(start, ss.str()); - - // rewrite the original source file - int fd = open(file_name.c_str(), O_WRONLY | O_CREAT); - if (fd < 0) - err(1, "open"); - llvm::raw_fd_ostream output(fd, /* close */ 1); - TheRewriter.getEditBuffer(main_fid).write(output); - // TheRewriter.getEditBuffer(main_fid).write(llvm::outs()); - } - - ASTConsumer *CreateASTConsumer(CompilerInstance &CI, - StringRef file) override { - // llvm::errs() << "** Creating AST consumer for: " << file << "\n"; - SourceManager &sm = CI.getSourceManager(); - TheRewriter.setSourceMgr(sm, CI.getLangOpts()); - - return new MyASTConsumer(TheRewriter); - } - -private: - Rewriter TheRewriter; -}; - -class MFAF : public FrontendActionFactory { -public: - MFAF(std::vector<const char *> &i) : inst_files(i) {} - - FrontendAction *create() { - return new MyFrontendAction(); - } - -private: - std::vector<const char *> inst_files; -}; - void clean_path() {