我正在查找Clang解析的C源文件中的标识符.这是一个函数,它需要在源文件中声明的五个参数(不是标题).当我尝试用一个参数调用它时,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,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,targetinfo,sm,hs,ci); clang::ASTContext astcon(langopts,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());
解决方法
显然,这只是现在被破坏了.我查看了LookupName的实现,并且它没有处理这种情况.
我现在必须要有合格的查找才能生活.