I'm trying to parse an AST of the whole project using a compilation database (compile_commands.json), but it contains pch files and commands related to generate those, resulting in errors during parsing: error: PCH file uses a newer PCH format that cannot be read 1 error generated.
The project has been configured (via CMake) and compiled using a different compiler, and the whole reason to make a tool instead of a plugin is not to be bound to a particular compiler. I might try an ad hoc solution to strip compile_commands.json
from pch-related stuff, but I doubt it will work properly and worth the hustle.
The initialization is basically like this:
auto options_parser =
CommonOptionsParser::create(argc, argv, option_category);
if (!options_parser) {
llvm::errs() << options_parser.takeError();
return -1;
}
ClangTool tool(options_parser->getCompilations(),
options_parser->getCompilations().getAllFiles());
Is possible to configure the tool not to handle pch-related stuff?
I found the exact issue that has been solved for clangd, the corresponding changes can be found here.
It boils down to setting certain fields for clang::CompilerInvocation
- the class that contains all the state that is used to configure a CompilerInstance
.
An instance of CompilerInvocation
is accessible via implementation of virtual bool clang::tooling::ToolAction::runInvocation
. The pch-related options are accessible via CompilerInvocation::getPreprocessorOpts()
. This code additionally disables reporting warnings
struct custom_action : public clang::tooling::ToolAction {
bool
runInvocation(std::shared_ptr<clang::CompilerInvocation> inv,
clang::FileManager *files,
std::shared_ptr<clang::PCHContainerOperations> pch_cont_ops,
clang::DiagnosticConsumer *diag_cons) override {
// createInvocationFromCommandLine sets DisableFree.
inv->getFrontendOpts().DisableFree = false;
inv->getLangOpts()->CommentOpts.ParseAllComments = true;
inv->getLangOpts()->RetainCommentsFromSystemHeaders = true;
[](auto &diag) {
diag.Warnings.clear();
diag.UndefPrefixes.clear();
diag.Remarks.clear();
diag.VerifyPrefixes.clear();
}(inv->getDiagnosticOpts());
[](auto &output) {
// Disable any dependency outputting, we don't want to generate files or
// write to stdout/stderr.
output.ShowIncludesDest = clang::ShowIncludesDestination::None;
output.OutputFile.clear();
output.HeaderIncludeOutputFile.clear();
output.DOTOutputFile.clear();
output.ModuleDependencyOutputDir.clear();
}(inv->getDependencyOutputOpts());
[](auto &preproc) {
// Disable any pch generation/usage operations. Since serialized preamble
// format is unstable, using an incompatible one might result in
// unexpected behaviours, including crashes.
preproc.ImplicitPCHInclude.clear();
preproc.PrecompiledPreambleBytes = {0, false};
preproc.PCHThroughHeader.clear();
preproc.PCHWithHdrStop = false;
preproc.PCHWithHdrStopCreate = false;
}(inv->getPreprocessorOpts());
// your code here
return true;
}
};
One can configure all the needed adaptors and than call ClangTool::run(ToolAction*)
.