Clangによって解析されたC++ソースファイルで識別子を検索しています。これは、ソースファイル(ヘッダーではありません)の中で正しく宣言されている5つの引数をとる関数です。 1つの引数で呼び出そうとすると、Clangは関数の宣言の完全なテキストでさえ、適切なエラーを返します。しかし、私がAPIでそれを調べようとすると、Clangはそれが存在しないと主張します。Clang APIで識別子を見つけることができませんが、Clangは使用時にそれを見つけることができます
はここに関連するコードです:
llvm::LLVMContext c;
clang::CompilerInstance CI;
llvm::Module m("", c);
clang::EmitLLVMOnlyAction emit(&c);
emit.setLinkModule(&m);
std::string errors;
llvm::raw_string_ostream error_stream(errors);
clang::DiagnosticOptions diagopts;
clang::TextDiagnosticPrinter printer(error_stream, &diagopts);
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagids(new clang::DiagnosticIDs);
clang::DiagnosticsEngine engine(diagids, &diagopts, &printer, false);
CI.setDiagnostics(&engine);
clang::TargetOptions target;
target.Triple = llvm::sys::getDefaultTargetTriple();
CI.setTarget(clang::TargetInfo::CreateTargetInfo(engine, &target));
CI.getLangOpts().CPlusPlus0x = true;
CI.getLangOpts().CPlusPlus = true;
clang::FrontendInputFile f("main.cpp", clang::InputKind::IK_CXX, true);
emit.BeginSourceFile(CI, f);
emit.Execute();
auto sema = CI.takeSema();
auto ast = &CI.getASTContext();
CI.resetAndLeakASTContext();
emit.EndSourceFile();
emit.takeModule();
auto identinfo = CI.getPreprocessor().getIdentifierInfo("WriteConsoleW");
auto sloc = CI.getSourceManager().getLocForEndOfFile(CI.getSourceManager().translateFile(CI.getFileManager().getFile("main.cpp")));
clang::LookupResult lr(*sema, clang::DeclarationName(identinfo), sloc, clang::Sema::LookupNameKind::LookupOrdinaryName);
auto result = sema->LookupName(lr, sema->TUScope);
私はidentinfo
がNULLでないことを確認した、とsloc
こともゼロではありません。
なぜ私の名前を見つけることができないのですか?
編集:修飾のグローバルスコープへの名前検索を成功させました。残念ながら、これは、修飾されていない名前の検索(例:ADLなし)を実行することと全く同じではありません。 Clangはまだ未修飾の関数名が存在しないと主張しています。
編集:修飾されたコードは類似していますが、Frontendライブラリへの依存を避けるためにリファクタリングされています。これは所有権の意味合いが非常に疑わしく、私はとにかく必要な操作をしません。
clang::CompilerInstance ci;
clang::FileSystemOptions fso;
clang::FileManager fm(fso);
std::string errors;
llvm::raw_string_ostream error_stream(errors);
clang::DiagnosticOptions diagopts;
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagids(new clang::DiagnosticIDs);
clang::DiagnosticsEngine engine(diagids, &diagopts, new clang::TextDiagnosticPrinter(error_stream, &diagopts), false);
clang::SourceManager sm(engine, fm);
clang::LangOptions langopts;
langopts.CPlusPlus = true;
langopts.CPlusPlus0x = true;
clang::TargetOptions target;
target.Triple = llvm::sys::getDefaultTargetTriple();
auto targetinfo = clang::TargetInfo::CreateTargetInfo(engine, &target);
auto headeropts = llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions>(new clang::HeaderSearchOptions());
clang::HeaderSearch hs(headeropts, fm, engine, langopts, targetinfo);
auto x = llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions>(new clang::PreprocessorOptions());
clang::Preprocessor p(x, engine, langopts, targetinfo, sm, hs, ci);
clang::ASTContext astcon(langopts, sm, targetinfo, p.getIdentifierTable(), p.getSelectorTable(), p.getBuiltinInfo(), 1000);
clang::CodeGenOptions codegenopts;
clang::CodeGen::CodeGenModule codegen(astcon, codegenopts, m, llvm::DataLayout(&m), engine);
CodeGenConsumer consumer(&codegen);
clang::Sema sema(p, astcon, consumer, clang::TranslationUnitKind::TU_Prefix);
sm.createMainFileID(fm.getFile(filepath));
engine.getClient()->BeginSourceFile(langopts, &p);
clang::ParseAST(sema);
codegen.Release();
engine.getClient()->EndSourceFile();
/*
for (auto it = astcon.getTranslationUnitDecl()->decls_begin(); it != astcon.getTranslationUnitDecl()->decls_end(); ++it) {
if (auto named = llvm::dyn_cast<clang::NamedDecl>(*it)) {
std::cout << named->getNameAsString() << "\n";
}
}*/
clang::LookupResult lr(sema, clang::DeclarationName(p.getIdentifierInfo("f")), sm.getLocForEndOfFile(sm.translateFile(fm.getFile(filepath))), clang::Sema::LookupNameKind::LookupOrdinaryName);
auto result = sema.LookupQualifiedName(lr, astcon.getTranslationUnitDecl());
適格な検索でコードを投稿できますか? – osgx
@osgx:リクエストされたとおりに完了しました。 – Puppy
あなたのコードで使用されているLLVM + Clangのバージョンは? – osgx