微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 如何在clang中为代码完成创建虚拟文件

我试图在clang中为codecompletion创建虚拟文件.不幸的是,我的应用程序是segfaults.
我有以下设置:
auto createVirtualFile = [](
  clang::CompilerInstance& ci,std::string name,llvm::StringRef input
) {
  std::unique_ptr<llvm::MemoryBuffer>
    MB(llvm::MemoryBuffer::getMemBuffer(input,name));
  return std::move(MB);
};

创建文件后,我设置了CodeCompletConsumer:

auto setupCodeComplete = [](
  clang::CompilerInstance& ci,std::string File,int Line,int Column
) {
  auto& F = ci.getFrontendOpts();
  F.CodeCompletionAt.FileName = File;
  F.CodeCompletionAt.Line = Line;
  F.CodeCompletionAt.Column = Column;
  clang::FrontendInputFile FrontFile(File,clang::IK_CXX);
  //F.Inputs.push_back(FrontFile);
  ci.createCodeCompletionConsumer();
  return FrontFile;
};

我按照以下方式调用这两个函数并执行仅语法操作:

auto runcodeCompleteAt = [] (
  clang::CompilerInstance& ci,std::string Filename,std::string Code,int Column
) {
  auto fid = createVirtualFile(ci,Filename,Code);
  auto File = setupCodeComplete(ci,Line,Column);
  clang::SyntaxOnlyAction Act;
  if (Act.BeginSourceFile(ci,File )) {
    Act.Execute(); // segfault
    Act.EndSourceFile();
  }
};

auto runExample = [](auto& ci){
  runcodeCompleterat(ci,"test.cpp","std::cou",1,7);
}

我很欣赏任何提示.

解决方法

问题是虽然你可以将llvm :: MemoryBuffer添加到clang :: FrontendInputFile中,但是clang :: SyntaxOnlyAction不接受这样的输入,它会导致断言失败.正如我在 previous answer中所说,您可能希望在lib / Frontend / ASTUnit.cpp中查看ASTUnit :: CodeComplete.

实际上,您可以使用remappedFiles将文件链接到缓冲区:

int main()
{
    unsigned Line = 2;
    unsigned Column = 13;
    clang::CompilerInstance ci;
    llvm::StringRef codeStr("void MyFoo() {}\nint main() {My return 0}");

    // Just a dummy filename,the file even doesnt' exist.
    std::string Filename("virtualFile.cpp");
    std::unique_ptr<llvm::MemoryBuffer> MB(llvm::MemoryBuffer::getMemBuffer(codeStr,Filename));

    // Create diagnostics and target
    ci.createDiagnostics();
    std::shared_ptr<clang::Targetoptions> to = std::make_shared<clang::Targetoptions>();
    // clang -v
    //to->Triple = "x86_64-pc-win32";
    //to->Triple = "x86_64-apple-darwin";
    to->Triple = "x86_64-apple-darwin15";
    ci.setTarget(clang::TargetInfo::CreateTargetInfo(ci.getDiagnostics(),to));

    // Create language options
    clang::LangOptions &lo = ci.getLangOpts();
    lo.CPlusPlus = true;
    lo.CPlusPlus11 = true;

    // Create code complete options
    clang::CodeCompleteOptions cco;
    cco.IncludeMacros = 0;
    cco.IncludeCodePatterns = 1;
    cco.IncludeGlobals = 1;
    cco.IncludeBriefComments = 1;

    // Set up the callback,I will go back to this callback class later
    auto pCustomCodeCompleteConsumer = new CustomCodeCompleteConsumer(cco);
    ci.setCodeCompletionConsumer(pCustomCodeCompleteConsumer);

    // Set up code complete postions & file
    // Until Now I didn't find a way to pass in a string rather than a file name
    clang::FrontendOptions& frontendOpts = ci.getFrontendOpts();
    frontendOpts.CodeCompletionAt.FileName = Filename;
    frontendOpts.CodeCompletionAt.Line = Line;
    frontendOpts.CodeCompletionAt.Column = Column;
    frontendOpts.Inputs.push_back(clang::FrontendInputFile(Filename,clang::InputKind::IK_CXX));

    clang::PreprocessorOptions& preprocessorOpts = ci.getPreprocessorOpts();
    preprocessorOpts.clearRemappedFiles();
    preprocessorOpts.addRemappedFile(Filename,MB.release());

    // Execute
    clang::SyntaxOnlyAction Act;
    if (Act.BeginSourceFile(ci,ci.getFrontendOpts().Inputs[0])) {
        Act.Execute();
        Act.EndSourceFile();
    }
}

输出包含COMLELE:50 Decl:MyFoo:[#void#] MyFoo().

我从代码段得到了这个答案

PreprocessorOpts.clearRemappedFiles();
  PreprocessorOpts.RetainRemappedfilebuffers = true;
  for (const auto &RemappedFile : RemappedFiles) {
    PreprocessorOpts.addRemappedFile(RemappedFile.first,RemappedFile.second);
    OwnedBuffers.push_back(RemappedFile.second);
  }

在ASTUnit :: CodeComplete中.

我相信您可能希望阅读AugmentedCodeCompleteConsumer以使用这些完成提示.

原文地址:https://www.jb51.cc/c/118586.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐