c – 通过Clang API找不到标识符,但是Clang可以在使用时找到它

前端之家收集整理的这篇文章主要介绍了c – 通过Clang API找不到标识符,但是Clang可以在使用时找到它前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在查找Clang解析的C源文件中的标识符.这是一个函数,它需要在源文件中声明的五个参数(不是标题).当我尝试用一​​个参数调用它时,Clang给出了一个适当的错误,甚至是函数声明的全文.但是当我尝试使用API​​查找时,Clang坚持认为它不存在.

以下是相关代码

  1. llvm::LLVMContext c;
  2. clang::CompilerInstance CI;
  3. llvm::Module m("",c);
  4. clang::EmitLLVMOnlyAction emit(&c);
  5. emit.setLinkModule(&m);
  6.  
  7. std::string errors;
  8. llvm::raw_string_ostream error_stream(errors);
  9. clang::DiagnosticOptions diagopts;
  10. clang::TextDiagnosticPrinter printer(error_stream,&diagopts);
  11. llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagids(new clang::DiagnosticIDs);
  12. clang::DiagnosticsEngine engine(diagids,&diagopts,&printer,false);
  13. CI.setDiagnostics(&engine);
  14.  
  15. clang::TargetOptions target;
  16. target.Triple = llvm::sys::getDefaultTargetTriple();
  17. CI.setTarget(clang::TargetInfo::CreateTargetInfo(engine,&target));
  18.  
  19. CI.getLangOpts().CPlusPlus0x = true;
  20. CI.getLangOpts().CPlusPlus = true;
  21.  
  22. clang::FrontendInputFile f("main.cpp",clang::InputKind::IK_CXX,true);
  23. emit.BeginSourceFile(CI,f);
  24.  
  25. emit.Execute();
  26. auto sema = CI.takeSema();
  27. auto ast = &CI.getASTContext();
  28. CI.resetAndLeakASTContext();
  29. emit.EndSourceFile();
  30.  
  31. emit.takeModule();
  32. auto identinfo = CI.getPreprocessor().getIdentifierInfo("WriteConsoleW");
  33.  
  34. auto sloc = CI.getSourceManager().getLocForEndOfFile(CI.getSourceManager().translateFile(CI.getFileManager().getFile("main.cpp")));
  35. clang::LookupResult lr(*sema,clang::DeclarationName(identinfo),sloc,clang::Sema::LookupNameKind::LookupOrdinaryName);
  36. auto result = sema->LookupName(lr,sema->TUScope);

我已经验证了identinfo不为NULL,并且该sloc也不为零.

为什么不能找到我的名字?

编辑:我已经成功地在全局范围内执行限定名称查找.不幸的是,这与执行不合格的名称查找不同 – 例如,没有ADL. Clang仍然坚持认为不存在不合格的函数名称.

编辑:合格的代码是类似但重构的,以避免对Frontend库的依赖,因为它具有非常有问题的所有权语义,并且该操作不会做我所需要的.

  1. clang::CompilerInstance ci;
  2. clang::FileSystemOptions fso;
  3. clang::FileManager fm(fso);
  4.  
  5. std::string errors;
  6. llvm::raw_string_ostream error_stream(errors);
  7. clang::DiagnosticOptions diagopts;
  8.  
  9. llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagids(new clang::DiagnosticIDs);
  10. clang::DiagnosticsEngine engine(diagids,new clang::TextDiagnosticPrinter(error_stream,&diagopts),false);
  11.  
  12. clang::SourceManager sm(engine,fm);
  13.  
  14. clang::LangOptions langopts;
  15. langopts.CPlusPlus = true;
  16. langopts.CPlusPlus0x = true;
  17.  
  18. clang::TargetOptions target;
  19. target.Triple = llvm::sys::getDefaultTargetTriple();
  20. auto targetinfo = clang::TargetInfo::CreateTargetInfo(engine,&target);
  21.  
  22. auto headeropts = llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions>(new clang::HeaderSearchOptions());
  23. clang::HeaderSearch hs(headeropts,fm,engine,langopts,targetinfo);
  24.  
  25. auto x = llvm::IntrusiveRefCntPtr<clang::PreprocessorOptions>(new clang::PreprocessorOptions());
  26. clang::Preprocessor p(x,targetinfo,sm,hs,ci);
  27.  
  28. clang::ASTContext astcon(langopts,p.getIdentifierTable(),p.getSelectorTable(),p.getBuiltinInfo(),1000);
  29. clang::CodeGenOptions codegenopts;
  30. clang::CodeGen::CodeGenModule codegen(astcon,codegenopts,m,llvm::DataLayout(&m),engine);
  31. CodeGenConsumer consumer(&codegen);
  32. clang::Sema sema(p,astcon,consumer,clang::TranslationUnitKind::TU_Prefix);
  33.  
  34. sm.createMainFileID(fm.getFile(filepath));
  35. engine.getClient()->BeginSourceFile(langopts,&p);
  36. clang::ParseAST(sema);
  37. codegen.Release();
  38. engine.getClient()->EndSourceFile();
  39. /*
  40. for (auto it = astcon.getTranslationUnitDecl()->decls_begin(); it != astcon.getTranslationUnitDecl()->decls_end(); ++it) {
  41. if (auto named = llvm::dyn_cast<clang::NamedDecl>(*it)) {
  42. std::cout << named->getNameAsString() << "\n";
  43. }
  44. }*/
  45. clang::LookupResult lr(sema,clang::DeclarationName(p.getIdentifierInfo("f")),sm.getLocForEndOfFile(sm.translateFile(fm.getFile(filepath))),clang::Sema::LookupNameKind::LookupOrdinaryName);
  46. auto result = sema.LookupQualifiedName(lr,astcon.getTranslationUnitDecl());

解决方法

显然,这只是现在被破坏了.我查看了LookupName的实现,并且它没有处理这种情况.

我现在必须要有合格的查找才能生活.

猜你在找的C&C++相关文章