如何把CLANG放进C++模式?

如何把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.

我正在使用叮当声制作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.
  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());
}