如何在 CLANG 中创建用于代码完成的虚拟文件
how to create a virtual file in clang for codecompletion
我试图在 clang 中创建用于代码完成的虚拟文件。不幸的是,我的应用程序段错误。我有以下设置:
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 Line,
int Column
) {
auto fid = createVirtualFile(ci, Filename, Code);
auto File = setupCodeComplete(ci, Filename, 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
不接受这样的输入,它会导致断言失败。正如我在之前的回答中所说,您可能想在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();
}
}
输出包含 COMPLETION: 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
以利用这些完成提示。
相关文章:
- C++无法定义虚拟函数 OUTER 类和头文件
- main.cpp从 .h 文件调用公共虚拟方法
- 如何在 VSCODE 中构建、运行和删除可执行文件和虚拟文件
- Pimpl习惯用法、单独的接口/实现文件和多个虚拟继承.如何
- cpp文件中的纯虚拟接口实现
- 在技术上是否可以创建 Java 虚拟机的映像文件并使用它来更快地启动 Java 应用程序
- Windows本身是否有虚拟或临时文件系统
- 当包含具有虚拟方法的标头时,不确定如何在.cpp文件中设置方法
- 如何在 CLANG 中创建用于代码完成的虚拟文件
- 覆盖虚拟函数不起作用,头文件和C ++文件
- 用于动态链接的虚拟文件
- 一次从虚拟文件中读取 4 个字节
- 如何创建文件路径可以像磁盘一样访问的虚拟文件系统
- 虚拟文件系统列表
- 如何使用QFileDialog打开虚拟文件夹
- 在虚拟文件系统中运行进程
- 如何在Windows通用文件对话框中显示API填充的虚拟文件夹
- C++访问由 Bash 进程替换创建的"虚拟文件"
- 如何使用C++在Windows中添加虚拟文件夹
- 如何将“std::string”放入 Clang 虚拟文件中