4

私はClangC++APIを使用しています。APIはスマートポインターを正しく使用しないため、所有権に苦労しました。私はこれまでに見つけたすべての問題を自分で踏みにじりましたが、これは私を悩ませています。コードを実行すると、アクセス違反が発生します。二重削除だと確信していますが、ドキュメントが存在しないため、どこを見ればよいかわかりません。幸いなことに、再生プログラムはかなり短いです。助言がありますか?

#define _SCL_SECURE_NO_WARNINGS

#pragma warning(push, 0)

#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Sema/Lookup.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/Mangle.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Sema/Sema.h>
#include <clang/Sema/SemaConsumer.h>
#include <clang/Sema/CodeCompleteConsumer.h>
#include <llvm/LLVMContext.h>
#include <llvm/Support/DataTypes.h>
#include <llvm/Module.h>
#include <llvm/Support/Host.h>

#pragma warning(pop)

#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
    llvm::LLVMContext c;
    llvm::Module m("", c);
    clang::EmitLLVMOnlyAction emit(&c);
    emit.setLinkModule(&m);
    clang::CompilerInstance CI;

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

    CI.createFileManager();
    CI.createSourceManager(CI.getFileManager());

    llvm::raw_null_ostream empty;
    clang::PrintingCodeCompleteConsumer print(CodeCompleteOptions(), empty);        

    clang::TargetOptions target;
    target.Triple = llvm::sys::getDefaultTargetTriple();
    CI.setTarget(clang::TargetInfo::CreateTargetInfo(engine, &target));

    CI.createPreprocessor();
    CI.createASTContext();

    clang::SemaConsumer* cons = new clang::SemaConsumer();

    CI.setASTConsumer(cons);    
    CI.createSema(clang::TranslationUnitKind::TU_Complete, &print);
    cons->InitializeSema(CI.getSema());

    clang::FrontendInputFile f("header", clang::InputKind::IK_CXX, true);
    emit.BeginSourceFile(CI, f);
    emit.Execute();
    emit.EndSourceFile();
    emit.takeModule();
    clang::LookupResult lr(CI.getSema(), clang::DeclarationName(CI.getPreprocessor().getIdentifierInfo("function")), clang::SourceLocation(), clang::Sema::LookupNameKind::LookupOrdinaryName);
    auto result = CI.getSema().LookupName(lr, CI.getSema().TUScope);

    std::string temp;
    llvm::raw_string_ostream out(temp);
    CI.getASTContext().createMangleContext()->mangleName(lr.getFoundDecl(), out);
    auto fun = m.getFunction(temp);

    std::cout << fun->getName().str();

    return 0;
}

編集:また、ファイルが実際に存在するように変更すると、たとえそれが些細なプログラムであっても、アクションの実行中に、前のアクションの前であっても、Clangがアクセス違反で失敗することにも言及しましたEndSourceFile。Whyyyyyy。

4

1 に答える 1

1

私は最終的に、フロントエンド全体をスキップすることでこれを解決しました。これは、ほとんどの場合、危険な所有権のすべてが存在する場所であり、必要な関数を自分で呼び出すだけです。

于 2012-12-24T16:33:39.353 に答える