1

我正在使用 clang API(版本 3.1 - trunk 153913)编译一些非常简单的代码,如下所示:

class MyClass
{
   ~MyClass() ;

};

MyClass::~MyClass()
{

}

int main()
{
   return 0;
}

我的问题是我收到错误消息:test.cpp:20:10: error: destructor cannot have a return type MyClass::~MyClass()

如果有人能指出我正确的方向,那就太好了。如果析构函数是内联定义的,它编译得很好。

请注意,我也可以使用 clang++ 进行编译:-bash-4.1$ clang++ test.cpp

因此,在我的 clang API 使用中必须有一个我缺少的设置。谁能指出那可能是什么。我一直在寻找缺少的选项/配置。

这是我的 clang API 用法:

// Include appropriate headers. 
int main()
{
    clang::DiagnosticOptions diagnosticOptions;
    diagnosticOptions.ShowColors=1;
    diagnosticOptions.ShowOptionNames=1;
    clang::TextDiagnosticPrinter *pTextDiagnosticPrinter =
       new clang::TextDiagnosticPrinter(
           llvm::outs(),
           diagnosticOptions);
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs;
    clang::DiagnosticsEngine *pDiagnosticsEngine =
       new clang::DiagnosticsEngine(pDiagIDs, pTextDiagnosticPrinter);

    clang::LangOptions languageOptions;
    languageOptions.GNUMode = 1;
    languageOptions.CXXExceptions = 1;
    languageOptions.RTTI = 1;
    languageOptions.Bool = 1;
    languageOptions.CPlusPlus = 1;
    clang::FileSystemOptions fileSystemOptions;
    clang::FileManager fileManager(fileSystemOptions);

    clang::SourceManager sourceManager(
      *pDiagnosticsEngine,
      fileManager);


    clang::TargetOptions targetOptions;
     targetOptions.Triple = "x86_64-unknown-linux-gnu";
    targetOptions.CPU = "x86-64";

    clang::TargetInfo *pTargetInfo =
    clang::TargetInfo::CreateTargetInfo(
        *pDiagnosticsEngine,
        targetOptions);

    clang::HeaderSearch headerSearch(fileManager,
                                 *pDiagnosticsEngine,
                                 languageOptions,
                                 pTargetInfo);
    clang::CompilerInstance compInst;
    compInst.getTargetOpts() = targetOptions;
    compInst.getLangOpts().CPlusPlus = 1;
    compInst.getLangOpts().Bool = 1;

    clang::HeaderSearchOptions &headerSearchOpts = compInst.getHeaderSearchOpts();
    headerSearchOpts = headerSearchOptions;

    clang::CompilerInvocation &compInvocation = compInst.getInvocation();

    clang::FrontendOptions & frontendOpts = compInvocation.getFrontendOpts();
    frontendOpts.ProgramAction = clang::frontend::EmitObj;

    clang::CodeGenOptions & codeGenOpts = compInvocation.getCodeGenOpts ();

    codeGenOpts.RelaxAll = 1;
    codeGenOpts.DebugInfo = 1;
    codeGenOpts.RelocationModel = "static";
    codeGenOpts.DisableFPElim = 1;
    codeGenOpts.AsmVerbose = 1;
    codeGenOpts.CXXCtorDtorAliases= 1;
    codeGenOpts.UnwindTables = 1;
    codeGenOpts.OmitLeafFramePointer = 1;
    codeGenOpts.StackRealignment = 1;

    std::vector<std::string> res;
    compInvocation.toArgs (res);

    std::vector<std::string>::iterator it;

   std::cout << "Arguments: " << std::endl;
   for (it = res.begin(); it != res.end(); it++)
   {
      std::string arg = *it;
      std::cout << "Arg: " << arg << std::endl;
   }

   clang::Preprocessor preprocessor(
    *pDiagnosticsEngine,
    languageOptions,
    pTargetInfo,
    sourceManager,
    headerSearch,
    compInst);

   preprocessor.getBuiltinInfo().InitializeBuiltins
    (preprocessor.getIdentifierTable(),
     languageOptions);

   clang::PreprocessorOptions preprocessorOptions;

   clang::FrontendOptions frontendOptions;
   frontendOptions.DisableFree=1;
   clang::InitializePreprocessor(
    preprocessor,
    preprocessorOptions,
    headerSearchOptions,
    frontendOptions);

   const clang::FileEntry *pFile = fileManager.getFile(
    "test.cpp");
   sourceManager.createMainFileID(pFile);
   const clang::TargetInfo &targetInfo = *pTargetInfo;

   clang::IdentifierTable identifierTable(languageOptions);
   clang::SelectorTable selectorTable;

   clang::Builtin::Context builtinContext;
   builtinContext.InitializeTarget(targetInfo);
   builtinContext.InitializeBuiltins(identifierTable, languageOptions);

   clang::ASTContext astContext(
    languageOptions,
    sourceManager,
    pTargetInfo,
    identifierTable,
    selectorTable,
    builtinContext,
    0 /* size_reserve*/);
    MyASTConsumer astConsumer;

    clang::Sema sema(
    preprocessor,
    astContext,
    astConsumer);

    pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor);
    clang::ParseAST (preprocessor, &astConsumer, astContext);
    pTextDiagnosticPrinter->EndSourceFile();

    return 0;
}
4

2 回答 2

7

你不见了

languageOptions.ImplicitInt = 0;

如果没有此配置,任何没有显式返回类型的函数都将设置为 int 返回类型,并在检查析构函数返回类型时引发错误,从而引发错误。使用上述配置,Sema 阶段不会引发错误,因为析构函数返回类型将保持未定义。

于 2012-11-20T07:49:10.750 回答
1

几乎可以肯定,您的原始代码(在您减少它之前)缺少分号。

class MyClass
{
   ~MyClass() ;

}  // right here

MyClass::~MyClass()
{

}

int main()
{
   return 0;
}

这导致类类型定义被视为随后的函数定义的返回类型。

于 2012-10-05T00:22:06.040 回答