Skip to content

Commit

Permalink
Make sure that cached .ast files are stored in temporary directory.
Browse files Browse the repository at this point in the history
Otherwise they clutter the source tree.
  • Loading branch information
Matthias Peschke committed Feb 28, 2024
1 parent 10f6623 commit 2318b4f
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 41 deletions.
50 changes: 28 additions & 22 deletions Instantiator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <iostream>
#include <ranges>
#include <sstream>
#include <system_error>
#include <unordered_set>

#include "termcolor/termcolor.hpp"
Expand Down Expand Up @@ -78,15 +79,23 @@ int main(int argc, const char** argv)

// clang::ast_matchers::functionDecl(clang::ast_matchers::isDefinition(), clang::ast_matchers::unless(nameMatcher)).bind("func_definition");

std::vector<std::string> main_and_injection_files = OptionsParser.getCompilations().getAllFiles();
std::error_code tmp_create_error;
auto tmpdir = std::filesystem::temp_directory_path(tmp_create_error);
if(tmp_create_error) {
std::cerr << "Error (" << tmp_create_error.value() << ") while getting temporary directory:\n" << tmp_create_error.message() << std::endl;
return 1;
}

std::vector<std::filesystem::path> main_and_injection_files;
for(const auto& file : OptionsParser.getCompilations().getAllFiles()) { main_and_injection_files.push_back(std::filesystem::path(file)); }

// std::cout << "source file from command line: " << OptionsParser.getSourcePathList()[0] << std::endl;
for(auto it = main_and_injection_files.begin(); it != main_and_injection_files.end(); it++) {
if(it->find(OptionsParser.getSourcePathList()[0]) != std::string::npos) { std::iter_swap(main_and_injection_files.begin(), it); }
}
// for(auto it = main_and_injection_files.begin(); it != main_and_injection_files.end(); it++) {
// if(it->find(OptionsParser.getSourcePathList()[0]) != std::string::npos) { std::iter_swap(main_and_injection_files.begin(), it); }
// }
// std::cout << "source files from json" << std::endl;
// for(const auto& source : main_and_injection_files) { std::cout << '\t' << "-- " << source << std::endl; }
llvm::ArrayRef<std::string> sources(main_and_injection_files.data(), main_and_injection_files.size());
llvm::ArrayRef<std::filesystem::path> sources(main_and_injection_files.data(), main_and_injection_files.size());

if(Clean) {
indicators::ProgressBar deletion_bar{indicators::option::BarWidth{50},
Expand All @@ -102,9 +111,9 @@ int main(int argc, const char** argv)
indicators::option::FontStyles{std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}};
indicators::show_console_cursor(false);
for(std::size_t i = 0; i < sources.size(); i++) {
deletion_bar.set_option(indicators::option::PostfixText{"Processing: " + sources[i]});
deletion_bar.set_option(indicators::option::PostfixText{"Processing: " + sources[i].string()});
std::unique_ptr<clang::ASTUnit> AST;
int success = parseOrLoadAST(AST, OptionsParser.getCompilations(), sources[i]);
int success = parseOrLoadAST(AST, OptionsParser.getCompilations(), sources[i], tmpdir);
clang::Rewriter rewriter(AST->getSourceManager(), AST->getLangOpts());
DeleteInstantiations Deleter;
Deleter.rewriter = &rewriter;
Expand All @@ -129,26 +138,23 @@ int main(int argc, const char** argv)
std::unordered_set<std::string> workList;
// workList.insert(main_and_injection_files[0]);
workList.insert(OptionsParser.getSourcePathList()[0]);
indicators::IndeterminateProgressBar outer_bar{
indicators::option::BarWidth{40},
indicators::option::Start{"["},
indicators::option::Fill{"·"},
indicators::option::Lead{"<==>"},
indicators::option::End{"]"},
indicators::option::PrefixText{"Main loop"},
indicators::option::ForegroundColor{indicators::Color::yellow},
indicators::option::FontStyles{
std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}
};
indicators::IndeterminateProgressBar outer_bar{indicators::option::BarWidth{40},
indicators::option::Start{"["},
indicators::option::Fill{"·"},
indicators::option::Lead{"<==>"},
indicators::option::End{"]"},
indicators::option::PrefixText{"Main loop"},
indicators::option::ForegroundColor{indicators::Color::yellow},
indicators::option::FontStyles{std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}};

while(workList.size() > 0) {
auto copyOf_workList = workList;
for(const auto& item : copyOf_workList) {
// std::cout << "Processing file " << item << std::endl;
outer_bar.set_option(indicators::option::PostfixText{"Scanning: "+item});
outer_bar.set_option(indicators::option::PostfixText{"Scanning: " + item});
workList.erase(item);
std::unique_ptr<clang::ASTUnit> source_AST;
int success = parseOrLoadAST(source_AST, OptionsParser.getCompilations(), item);
int success = parseOrLoadAST(source_AST, OptionsParser.getCompilations(), item, tmpdir);
// std::cout << "Got AST" << std::endl;
Finder.matchAST(source_AST->getASTContext());
// std::cout << termcolor::bold << "Run on file " << item << " produced " << toDoList.size() << " ToDos" << termcolor::reset << std::endl;
Expand Down Expand Up @@ -177,8 +183,8 @@ int main(int argc, const char** argv)
break;
}
std::unique_ptr<clang::ASTUnit> target_AST;
int success = parseOrLoadAST(target_AST, OptionsParser.getCompilations(), file_for_search);
inner_bar.set_option(indicators::option::PostfixText{"Processing: " + file_for_search});
int success = parseOrLoadAST(target_AST, OptionsParser.getCompilations(), file_for_search, tmpdir);
inner_bar.set_option(indicators::option::PostfixText{"Processing: " + file_for_search.string()});
// std::cout << termcolor::green << "Search in AST of file " << file_for_search << termcolor::reset << std::endl;
clang::Rewriter rewriter(target_AST->getSourceManager(), target_AST->getLangOpts());
clang::ast_matchers::MatchFinder FuncFinder;
Expand Down
8 changes: 6 additions & 2 deletions include/ASTCreation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
#define AST_CREATION_H_

#include "clang/Tooling/Tooling.h"
#include <filesystem>

int parseOrLoadAST(std::unique_ptr<clang::ASTUnit>& AST, const clang::tooling::CompilationDatabase& db, const std::string filename);
int parseOrLoadAST(std::unique_ptr<clang::ASTUnit>& AST,
const clang::tooling::CompilationDatabase& db,
const std::filesystem::path& filename,
const std::filesystem::path& tmpdir);

namespace internal {
/**
Expand All @@ -14,7 +18,7 @@ namespace internal {
* invoke the compiler for getting the dependencies.
* \param filename : Name of the source file
*/
bool is_cached(const clang::tooling::CompilationDatabase& db, std::string filename);
bool is_cached(const clang::tooling::CompilationDatabase& db, const std::filesystem::path& filename, const std::filesystem::path& tmpdir);
} // namespace internal

#endif
12 changes: 9 additions & 3 deletions include/Actions/ASTBuilderAction.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef ASTBUILDER_ACTION_HPP_
#define ASTBUILDER_ACTION_HPP_
#include <filesystem>
#include <iostream>
#include <memory>
#include <vector>
Expand Down Expand Up @@ -27,13 +28,18 @@ class ASTBuilderAction : public clang::tooling::ToolAction
{
std::unique_ptr<clang::ASTUnit>& AST;
const clang::tooling::CompilationDatabase& db;
std::string filename;
std::filesystem::path file;
std::filesystem::path tmpdir;

public:
ASTBuilderAction(std::unique_ptr<clang::ASTUnit>& AST, const clang::tooling::CompilationDatabase& db, const std::string filename)
ASTBuilderAction(std::unique_ptr<clang::ASTUnit>& AST,
const clang::tooling::CompilationDatabase& db,
const std::filesystem::path& filename,
const std::filesystem::path& tmpdir)
: AST(AST)
, db(db)
, filename(filename)
, file(filename)
, tmpdir(tmpdir)
{}

bool runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
Expand Down
1 change: 0 additions & 1 deletion include/Callbacks/InjectInstantiation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class InjectInstantiation : public clang::ast_matchers::MatchFinder::MatchCallba
public:
/**
* A pointer to an external vector of Injection which is filled during GetNeededInstantiations.
* \todo Can this be a `std::list`?
*/
std::vector<Injection>* toDoList;
/**Pointer to an external [clang::Rewriter]((https://clang.llvm.org/doxygen/classclang_1_1Rewriter.html)) object.*/
Expand Down
19 changes: 10 additions & 9 deletions src/ASTCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
#include "Actions/ASTBuilderAction.hpp"
#include "Actions/DependencyAction.hpp"

int parseOrLoadAST(std::unique_ptr<clang::ASTUnit>& AST, const clang::tooling::CompilationDatabase& db, const std::string filename)
int parseOrLoadAST(std::unique_ptr<clang::ASTUnit>& AST,
const clang::tooling::CompilationDatabase& db,
const std::filesystem::path& filename,
const std::filesystem::path& tmpdir)
{
clang::tooling::ClangTool Tool(db, filename);
ASTBuilderAction ast_build_action(AST, db, filename);
clang::tooling::ClangTool Tool(db, filename.string());
ASTBuilderAction ast_build_action(AST, db, filename, tmpdir);
return Tool.run(&ast_build_action);
}

namespace internal {

bool is_cached(const clang::tooling::CompilationDatabase& db, std::string filename)
bool is_cached(const clang::tooling::CompilationDatabase& db, const std::filesystem::path& file, const std::filesystem::path& tmpdir)
{
auto to_time_t = [](auto tp) -> std::time_t {
auto sctp =
Expand All @@ -30,9 +33,7 @@ bool is_cached(const clang::tooling::CompilationDatabase& db, std::string filena
std::cout << text << ": " << ftime.time_since_epoch().count() << std::endl;
};

std::filesystem::path p(filename);

clang::tooling::ClangTool Tool(db, filename);
clang::tooling::ClangTool Tool(db, file.string());
std::vector<std::string> deps;
class SingleFrontendActionFactory : public clang::tooling::FrontendActionFactory
{
Expand All @@ -54,8 +55,8 @@ bool is_cached(const clang::tooling::CompilationDatabase& db, std::string filena
auto wrapper = std::make_unique<SingleFrontendActionFactory>(&deps);
[[maybe_unused]] int result = Tool.run(wrapper.get());

if(not std::filesystem::exists(p.replace_extension("ast"))) { return false; }
auto time_point_ast = std::filesystem::last_write_time(p.replace_extension(std::filesystem::path("ast")));
if(not std::filesystem::exists(tmpdir / file.filename().replace_extension("ast"))) { return false; }
auto time_point_ast = std::filesystem::last_write_time(tmpdir / file.filename().replace_extension("ast"));
for(const auto& dep : deps) {
std::filesystem::path p_dep(dep);
auto time_point_cpp = std::filesystem::last_write_time(p_dep);
Expand Down
7 changes: 3 additions & 4 deletions src/Actions/ASTBuilderAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ bool ASTBuilderAction::runInvocation(std::shared_ptr<clang::CompilerInvocation>
std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps,
clang::DiagnosticConsumer* DiagConsumer)
{
bool is_cached_on_disk = internal::is_cached(db, filename);
bool is_cached_on_disk = internal::is_cached(db, file, tmpdir);
// std::cout << "Processing " << filename << std::endl;
// std::cout << std::boolalpha << "cached=" << is_cached_on_disk << std::endl;
std::filesystem::path p(filename);
if(is_cached_on_disk) {
clang::CompilerInstance CI;
CI.setInvocation(Invocation);
CI.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
clang::DiagnosticsEngine* DiagEngine = &CI.getDiagnostics();
AST = clang::ASTUnit::LoadFromASTFile(p.replace_extension("ast").string(),
AST = clang::ASTUnit::LoadFromASTFile((tmpdir / file.filename().replace_extension("ast")).string(),
CI.getPCHContainerReader(),
clang::ASTUnit::WhatToLoad::LoadEverything,
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine>(DiagEngine),
Expand All @@ -33,7 +32,7 @@ bool ASTBuilderAction::runInvocation(std::shared_ptr<clang::CompilerInvocation>
DiagConsumer,
/*ShouldOwnClient=*/false),
Files);
AST->Save(p.replace_extension("ast").string());
AST->Save((tmpdir / file.filename().replace_extension("ast")).string());
}
if(!AST or AST->getDiagnostics().hasUncompilableErrorOccurred()) return false;
return true;
Expand Down

0 comments on commit 2318b4f

Please sign in to comment.