2012-12-22 4 views
10

Ich suche einen Bezeichner in einer C++ - Quelldatei, die von Clang analysiert wurde. Es ist eine Funktion, die fünf Argumente benötigt, die direkt in der Quelldatei deklariert sind (keine Kopfzeile). Wenn ich versuche, es mit einem Argument aufzurufen, gibt Clang einen entsprechenden Fehler - sogar den vollständigen Text der Deklaration der Funktion. Aber wenn ich versuche, es mit der API nachzuschlagen, besteht Clang darauf, dass es nicht existiert.Kann den Bezeichner nicht über die Clang-API finden, aber Clang kann ihn finden, wenn er verwendet wird

Hier ist der entsprechende Code:

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); 

ich vergewissert haben, dass identinfo nicht NULL ist, und dass sloc ist auch nicht Null.

Warum kann Clang meinen Namen nicht finden?

Edit: Ich habe erfolgreich durchgeführt qualifizierte Namenssuche in den globalen Geltungsbereich. Leider ist dies nicht das Gleiche wie das Durchführen eines nicht qualifizierten Namensabgleichs - beispielsweise keine ADL. Clang besteht immer noch darauf, dass ein nicht qualifizierter Funktionsname nicht existiert.

Edit: Der qualifizierte Code ist ähnlich, aber refactored um Abhängigkeiten von der Frontend-Bibliothek zu vermeiden, da es extrem fragwürdige Besitz Semantik hat und die Aktion nicht tut, was ich sowieso brauche.

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()); 
+0

Können Sie Code mit qualifizierter Suche posten? – osgx

+0

@osgx: Fertig wie gewünscht. – Puppy

+0

Was ist die in Ihrem Code verwendete Version von LLVM + Clang? – osgx

Antwort

5

Offenbar ist dies gerade bekannt, jetzt gebrochen zu werden. Ich habe die LookupName-Implementierung durchgesehen, und es ist nicht möglich, diesen Fall zu bearbeiten.

Ich werde für jetzt mit qualifizierten Lookup leben müssen.

+0

Können Sie ein bisschen mehr illustrieren? Welcher Fall wird nicht behandelt? – osgx

+0

Dasjenige, in dem das Scope übergeben wurde, ist TUScope. – Puppy

Verwandte Themen