如何把CLANG放进C++模式?
我正在使用叮当声制作AST变压器。它应该以文件名作为输入,对该文件中的代码执行一些转换,然后返回转换后的代码。它是基于 代码如下:如何把CLANG放进C++模式?,c++,clang,C++,Clang,我正在使用叮当声制作AST变压器。它应该以文件名作为输入,对该文件中的代码执行一些转换,然后返回转换后的代码。它是基于 代码如下: std::string transform(std::string fileName) { // CompilerInstance will hold the instance of the Clang compiler for us, // managing the various objects needed to run the compiler.
std::string transform(std::string fileName) {
// CompilerInstance will hold the instance of the Clang compiler for us,
// managing the various objects needed to run the compiler.
CompilerInstance compilerInstance;
compilerInstance.createDiagnostics();
auto& langOpts = compilerInstance.getLangOpts();
langOpts.CPlusPlus = true;
// Initialize target info with the default triple for our platform.
auto TO = std::make_shared<TargetOptions>();
TO->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo* targetInfo =
TargetInfo::CreateTargetInfo(compilerInstance.getDiagnostics(), TO);
compilerInstance.setTarget(targetInfo);
compilerInstance.createFileManager();
auto& fileManager = compilerInstance.getFileManager();
compilerInstance.createSourceManager(fileManager);
auto& sourceManager = compilerInstance.getSourceManager();
compilerInstance.createPreprocessor(TU_Module);
compilerInstance.createASTContext();
// A Rewriter helps us manage the code rewriting task.
auto rewriter = clang::Rewriter(sourceManager, compilerInstance.getLangOpts());
// Set the main file handled by the source manager to the input file.
const FileEntry* inputFile = fileManager.getFile(fileName);
sourceManager.setMainFileID(
sourceManager.createFileID(inputFile, SourceLocation(), SrcMgr::C_User));
compilerInstance.getDiagnosticClient().BeginSourceFile(
compilerInstance.getLangOpts(), &compilerInstance.getPreprocessor());
// Create an AST consumer instance which is going to get called by
// ParseAST.
MyASTConsumer consumer(rewriter);
// Parse the file to AST, registering our consumer as the AST consumer.
clang::ParseAST(
compilerInstance.getPreprocessor(),
&consumer,
compilerInstance.getASTContext());
// At this point the rewriter's buffer should be full with the rewritten
// file contents.
const RewriteBuffer* buffer = rewriter.getRewriteBufferFor(sourceManager.getMainFileID());
return std::string(buffer->begin(), buffer->end());
}
当我在此代码上运行transform时,我得到以下错误:
negate.cpp:1:1: error: unknown type name 'bool'
bool negate(bool b) {
^
<>这表明它是在C模式下工作,而不是C++模式。为了确认,我将bool替换为int,true替换为1,false替换为0:
这是有效的,所以我的问题是:
<>如何将CLAN编译程序实例放入C++模式?
更新:
我尝试更改调用,但没有成功:
auto& langOpts = compilerInstance.getLangOpts();
langOpts.CPlusPlus = true;
langOpts.CPlusPlus11 = true;
auto* compilerInvocation = new CompilerInvocation();
compilerInvocation->setLangDefaults(
langOpts,
clang::InputKind::IK_CXX,
LangStandard::lang_gnu11);
在执行编译器之前,必须使用getInvocation/setInvocation方法检查/设置编译器调用结构。此结构定义了语言选项调用约定、垃圾收集、…、语言种类C、CXX、Asm、ObjC、…、目标三元组、预处理器选项和语言标准。它是用setLangDefaults方法设置的 这是保存要解析的语言的InputKind类 如文档中所述,setLangDefaults API 设置一些仅依赖于输入类型的属性 通过检查源代码,您可以看到以下构造函数调用层次结构: 编译立场 编辑职业 编译库 朗格期权 在LangOptions构造函数中,您可以看到没有设置特定/默认语言。因此,需要通过特定的API 你应该这样做:
std::string transform(std::string fileName) {
CompilerInstance compilerInstance;
compilerInstance.createDiagnostics();
CompilerInvocation & invocation = compilerInstance.getInvocation();
// Initialize target info with the default triple for our platform.
auto TO = std::make_shared<TargetOptions>();
TO->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo* targetInfo =
TargetInfo::CreateTargetInfo(compilerInstance.getDiagnostics(), TO);
compilerInstance.setTarget(targetInfo);
compilerInstance.createFileManager();
auto& fileManager = compilerInstance.getFileManager();
compilerInstance.createSourceManager(fileManager);
auto& sourceManager = compilerInstance.getSourceManager();
LangOptions langOpts;
langOpts.GNUMode = 1;
langOpts.CXXExceptions = 1;
langOpts.RTTI = 1;
langOpts.Bool = 1; // <-- Note the Bool option here !
langOpts.CPlusPlus = 1;
PreprocessorOptions &PPOpts = compilerInstance.getPreprocessorOpts();
invocation.setLangDefaults(langOpts,
clang::IK_CXX,
TO->Triple,
PPOpts,
clang::LangStandard::lang_cxx0x);
compilerInstance.createPreprocessor(TU_Module);
compilerInstance.createASTContext();
// A Rewriter helps us manage the code rewriting task.
auto rewriter = clang::Rewriter(sourceManager, compilerInstance.getLangOpts());
// Set the main file handled by the source manager to the input file.
const FileEntry* inputFile = fileManager.getFile(fileName);
sourceManager.setMainFileID(
sourceManager.createFileID(inputFile, SourceLocation(), SrcMgr::C_User));
compilerInstance.getDiagnosticClient().BeginSourceFile(
compilerInstance.getLangOpts(), &compilerInstance.getPreprocessor());
// Create an AST consumer instance which is going to get called by
// ParseAST.
MyASTConsumer consumer(rewriter);
// Parse the file to AST, registering our consumer as the AST consumer.
clang::ParseAST(
compilerInstance.getPreprocessor(),
&consumer,
compilerInstance.getASTContext());
// At this point the rewriter's buffer should be full with the rewritten
// file contents.
const RewriteBuffer* buffer = rewriter.getRewriteBufferFor(sourceManager.getMainFileID());
return std::string(buffer->begin(), buffer->end());
}
参考clang教程中的内容,这似乎也有点过时。我不太确定,因为我只是在尝试clang,但您可以试试:auto&lang_opts=ci.getLangOpts;lang_opts.CPlusPlus14=1;。可能是叮当声++文件名.cpp?或者使用clang++-std=c++11。。。大概或者将您的源文件命名为.cpp,也许?@Galik已经很不幸地尝试过了。目标是什么-std=?是否打开了-ansi?这个方法和使用clang-cc1选项一样吗?看看哪一个似乎是类似的问题。请您对此进行详细说明?@sdgfsdh:您应该指定更改,以便Heyji可以修改他的示例,使其生效unchanged@IraBaxter我已经把它加在他回答的末尾了。等待同行评审。。。
auto& langOpts = compilerInstance.getLangOpts();
langOpts.CPlusPlus = true;
langOpts.CPlusPlus11 = true;
auto* compilerInvocation = new CompilerInvocation();
compilerInvocation->setLangDefaults(
langOpts,
clang::InputKind::IK_CXX,
LangStandard::lang_gnu11);
std::string transform(std::string fileName) {
CompilerInstance compilerInstance;
compilerInstance.createDiagnostics();
CompilerInvocation & invocation = compilerInstance.getInvocation();
// Initialize target info with the default triple for our platform.
auto TO = std::make_shared<TargetOptions>();
TO->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo* targetInfo =
TargetInfo::CreateTargetInfo(compilerInstance.getDiagnostics(), TO);
compilerInstance.setTarget(targetInfo);
compilerInstance.createFileManager();
auto& fileManager = compilerInstance.getFileManager();
compilerInstance.createSourceManager(fileManager);
auto& sourceManager = compilerInstance.getSourceManager();
LangOptions langOpts;
langOpts.GNUMode = 1;
langOpts.CXXExceptions = 1;
langOpts.RTTI = 1;
langOpts.Bool = 1; // <-- Note the Bool option here !
langOpts.CPlusPlus = 1;
PreprocessorOptions &PPOpts = compilerInstance.getPreprocessorOpts();
invocation.setLangDefaults(langOpts,
clang::IK_CXX,
TO->Triple,
PPOpts,
clang::LangStandard::lang_cxx0x);
compilerInstance.createPreprocessor(TU_Module);
compilerInstance.createASTContext();
// A Rewriter helps us manage the code rewriting task.
auto rewriter = clang::Rewriter(sourceManager, compilerInstance.getLangOpts());
// Set the main file handled by the source manager to the input file.
const FileEntry* inputFile = fileManager.getFile(fileName);
sourceManager.setMainFileID(
sourceManager.createFileID(inputFile, SourceLocation(), SrcMgr::C_User));
compilerInstance.getDiagnosticClient().BeginSourceFile(
compilerInstance.getLangOpts(), &compilerInstance.getPreprocessor());
// Create an AST consumer instance which is going to get called by
// ParseAST.
MyASTConsumer consumer(rewriter);
// Parse the file to AST, registering our consumer as the AST consumer.
clang::ParseAST(
compilerInstance.getPreprocessor(),
&consumer,
compilerInstance.getASTContext());
// At this point the rewriter's buffer should be full with the rewritten
// file contents.
const RewriteBuffer* buffer = rewriter.getRewriteBufferFor(sourceManager.getMainFileID());
return std::string(buffer->begin(), buffer->end());
}