2

clang::CompilerInstanceインクルードを含むソース ファイルを解析しようとしていますが、インクルードされたヘッダーを実際に見つける方法がわかりません。これが私のセットアップです:

std::unique_ptr<clang::CompilerInstance> ci(new clang::CompilerInstance());
ci->createDiagnostics();

LLVMInitializeARMTarget();
LLVMInitializeARMTargetMC();
LLVMInitializeARMAsmPrinter();
LLVMInitializeARMAsmParser();


std::shared_ptr<clang::TargetOptions> options(new clang::TargetOptions);
options->Triple = "arm-v7m-unknown-none-eabi";
options->CPU = "cortex-m3";

clang::TargetInfo *targetInfo = clang::TargetInfo::CreateTargetInfo(ci->getDiagnostics(), options);

ci->setTarget(targetInfo);

ci->createFileManager();
ci->createSourceManager(ci->getFileManager());

NSURL *sysrootURL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"Compiler/basalt"];
NSURL *includeURL = [sysrootURL URLByAppendingPathComponent:@"include"];

ci->createPreprocessor(clang::TranslationUnitKind::TU_Complete);
ci->getPreprocessorOpts().UsePredefines = false;


// Header searcher
llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> hso(new clang::HeaderSearchOptions());
hso->UseBuiltinIncludes = false;
hso->UseStandardSystemIncludes = false;
hso->UseStandardCXXIncludes = false;
hso->Sysroot = [[includeURL path] UTF8String];

clang::HeaderSearch headerSearch(hso, ci->getSourceManager(), ci->getDiagnostics(), ci->getLangOpts(), targetInfo);

headerSearch.AddSearchPath(clang::DirectoryLookup(ci->getFileManager().getDirectory([[includeURL path] UTF8String]), clang::SrcMgr::C_System, false), true);

clang::InitializePreprocessor(ci->getPreprocessor(), ci->getPreprocessorOpts(), ci->getFrontendOpts());


// Main file
const clang::FileEntry *file = ci->getFileManager().getFile([[[_url URLByAppendingPathComponent:@"src/main.c"] path] UTF8String]);

ci->getSourceManager().setMainFileID(ci->getSourceManager().createFileID(file, clang::SourceLocation(), clang::SrcMgr::C_User));

ci->getPreprocessor().EnterMainSourceFile();
ci->getDiagnosticClient().BeginSourceFile(ci->getLangOpts(), &ci->getPreprocessor());
clang::Token tok;
do {
    ci->getPreprocessor().Lex(tok);
    if(ci->getDiagnostics().hasErrorOccurred())
        break;
    ci->getPreprocessor().DumpToken(tok);
    std::cerr << std::endl;
} while(tok.isNot(clang::tok::eof));

ci->getDiagnosticClient().EndSourceFile();

パスは間違いなく 100% 正しく、何度も何度もチェックしました。私がスローしたソースコードに のようなものが含まれるまで、すべてが機能し#include <foobar.h>ますerror 'foobar.h' file not found。ここで本当に明白な何かが欠けているように感じます。正しい方向への指針はありますか?

4

1 に答える 1

5

まず、CompilerInstance の使用をやめます。所有権のセマンティクスが非常に悪く、実際には使用できません (3.6 で を使用して修正しない限りunique_ptr)。コンポーネントを自分で作成する方が簡単です。

第二に、はい、自分でやらなければなりません。以下は、Clang を使用する私自身のプロジェクトからの抜粋です。

clang::HeaderSearch hs(/*params*/);
// WHY AM I DOING THIS MYSELF CLANG
// CAN'T YOU READ YOUR OWN CONSTRUCTOR PARAMETERS AND OPTIONS STRUCTS?
std::vector<clang::DirectoryLookup> lookups;
for (auto entry : opts.HeaderSearchOptions->UserEntries) {
    auto lookup = clang::DirectoryLookup(FileManager.getDirectory(entry.Path), clang::SrcMgr::CharacteristicKind::C_System, false);
    if (!lookup.getDir())
        throw SpecificError<ClangCouldNotInterpretPath>(a, where, "Clang could not interpret path " + entry.Path);
    lookups.push_back(lookup);
}
hs.SetSearchPaths(lookups, 0, 0, true);
于 2015-06-07T22:05:48.100 に答える