I am experiencing an issue with CLang's libastmatchers
while working with Postgres sources: it can't find include file. This error is reproduced only when CLangTool is created from two files. If it is created for a separate file, there is no error and function is successfully matched.
Full error:
/home/myuser/postgres/src/conditional.c:1:10: fatal error: 'pg_config_ext.h' file not found
#include "pg_config_ext.h"
^~~~~~~~~~~~~~~~~
1 error generated.
Error while processing /home/myuser/postgres/src/conditional.c.
Directory structure:
postgres/
|-- compile_commands.json
|-- pg_config_ext.h
`-- src
|-- backend
| `-- nodeHash.c
`-- conditional.c
File contents:
- nodeHash.c is empty;
- conditional.c:
#include "pg_config_ext.h"
- pg_config_ext.h:
int f();
- compile_commands.json:
[ {
"arguments": [
"clang",
"-c",
"-I..",
"/home/myuser/postgres/src/conditional.c"
],
"directory": "/home/myuser/postgres/src",
"file": "/home/myuser/postgres/src/conditional.c"
},
{
"arguments": [
"clang",
"-c",
"-I../..",
"/home/myuser/postgres/src/backend/nodeHash.c"
],
"directory": "/home/myuser/postgres/src/backend",
"file": "/home/myuser/postgres/src/backend/nodeHash.c"
}
]
- CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(untitled)
set(CMAKE_CXX_STANDARD 17)
find_package(Clang REQUIRED)
include_directories(${CLANG_INCLUDE_DIRS})
add_definitions(${CLANG_DEFINITIONS})
add_executable(clang_error main.cpp)
target_link_libraries(clang_error PUBLIC clangTooling clangBasic clangASTMatchers)
- main.cpp:
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/Tooling.h>
#include <string>
#include <vector>
#include <memory>
#include <iostream>
using namespace clang::ast_matchers;
using namespace clang;
using namespace clang::tooling;
using namespace std;
string prefix = "/home/myuser/";
string ccPath = prefix + "postgres/";
vector<string> files = {
prefix + "postgres/src/backend/nodeHash.c", // if you comment out this line, there will be no error
prefix + "postgres/src/conditional.c"
};
class Fetcher : public MatchFinder::MatchCallback {
public:
void run(const MatchFinder::MatchResult &Result) override {
if (const auto *FS = Result.Nodes.getNodeAs<FunctionDecl>("function")) {
std::cout << "Matched"; // Matches only if one file, not two
}
}
};
int main() {
unique_ptr<clang::tooling::ClangTool> clangTool;
unique_ptr<Fetcher> fetcherInstance;
MatchFinder finder;
static const DeclarationMatcher functionMatcher = functionDecl().bind("function");
string errMsg;
shared_ptr<clang::tooling::CompilationDatabase> cDb = clang::tooling::CompilationDatabase::autoDetectFromDirectory(ccPath, errMsg);
std::cout << errMsg; // No output
clangTool = std::make_unique<ClangTool>(*cDb, files);
fetcherInstance = std::make_unique<Fetcher>();
finder.addMatcher(functionMatcher, fetcherInstance.get());
clangTool->run(newFrontendActionFactory(&finder).get());
}
I am using CLang version 10.0.0
Perhaps, this is the same issue, but there is no answer.