dev_overflow
dev_overflow

Reputation: 63

Clang API parsing of destructor

I am using the clang API (version 3.1 - trunk 153913) to compile some very simple code as follows:

class MyClass
{
   ~MyClass() ;

};

MyClass::~MyClass()
{

}

int main()
{
   return 0;
}

My problem is that I get the error message: test.cpp:20:10: error: destructor cannot have a return type MyClass::~MyClass()

If someone can point me to the right direction that would be great. It compiles fine if the destructor is defined inline to the class.

Note that I can also compile with clang++ fine: -bash-4.1$ clang++ test.cpp

So there must be a setting I'm missing in my clang API usage. Can anyone indicate what that might be. I've been searching all over for a missing option/configuration.

Here is my clang API usage:

// 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;
}

Upvotes: 1

Views: 904

Answers (2)

user1838017
user1838017

Reputation: 71

You are missing

languageOptions.ImplicitInt = 0;

without this configuration any function not having explicit return type will be set to int return type and raise an error when desctructor return type is checked thus raising the error. With the above configuration the Sema phase will not raise the error as the destructor return type will remain undefined.

Upvotes: 7

Quuxplusone
Quuxplusone

Reputation: 27314

Almost certainly, your original code (before you reduced it) was missing a semicolon.

class MyClass
{
   ~MyClass() ;

}  // right here

MyClass::~MyClass()
{

}

int main()
{
   return 0;
}

This caused the class type definition to be treated as the return type for the function definition which followed.

Upvotes: 1

Related Questions