[cfe-dev] Parsing gnu c++ headers/code

Pascal Ognibene pognibene at gmail.com
Mon May 13 08:33:28 PDT 2013


Hi all,

I want to parse C++ and C headers coming from a GCC/G++ installation, with
clang 3.2 and a recursive visitor pattern. I have difficulties to parse
some headers with messages like:

stdlib.h:863:20: error: unknown type name 'wchar_t'
extern int mbtowc (wchar_t *__restrict __pwc,

This is while parsing gcc 4.2.4 headers. I do have the wchar.h header in
the include path.

I configure my CompilerInstance the following way:

...

    CompilerInstance ci;
    if ( useCpp )
    {
        ci.getLangOpts().CPlusPlus = 1;
        ci.getLangOpts().Bool = 1;
        ci.getLangOpts().CXXExceptions = 1;
        ci.getLangOpts().RTTI = 1;
        //ci.getLangOpts().GNUMode = 1;
    }

    ci.createDiagnostics ( 0, NULL );

    TargetOptions to;
    to.Triple = llvm::sys::getDefaultTargetTriple();
    TargetInfo *pti = TargetInfo::CreateTargetInfo ( ci.getDiagnostics(),
to );
    ci.setTarget ( pti );

    ci.createFileManager();
    ci.createSourceManager ( ci.getFileManager() );
    ci.createPreprocessor();

//try to get the gcc built ins
//seems to work!
//need now the C headers in addition of C++ headers
//for gcc 4.2
    clang::Preprocessor &PP = ci.getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());
    HeaderSearchOptions headerSearchOptions;
    for ( std::vector<std::string>::iterator it = includeList.begin(); it
!= includeList.end(); ++it )
    {
        headerSearchOptions.AddPath ( *it,
                                      clang::frontend::Angled,
                                      false,
                                      false,
                                      false );
    }

    clang::PreprocessorOptions &ppOptions = ci.getPreprocessorOpts();
    for ( std::vector<std::string>::iterator it = macroList.begin(); it !=
macroList.end(); ++it )
    {
        ppOptions.addMacroDef ( *it );
    }

    clang::InitializePreprocessor ( ci.getPreprocessor(),
                                    ci.getPreprocessorOpts(),
                                    headerSearchOptions,
                                    ci.getFrontendOpts() );
    ci.createASTContext();

    MyASTConsumer *astConsumer = NULL;
    MyASTConsumerCpp *astConsumerCpp = NULL;

    if ( useCpp )
    {
        astConsumerCpp = new MyASTConsumerCpp ( &ci.getASTContext() );
        ci.setASTConsumer ( astConsumerCpp );
    }
    else
    {
        astConsumer = new MyASTConsumer ( &ci.getASTContext() );
        ci.setASTConsumer ( astConsumer );
    }

    const FileEntry *pFile = ci.getFileManager().getFile ( inputFile );
    ci.getSourceManager().createMainFileID ( pFile );
    ci.getDiagnosticClient().BeginSourceFile ( ci.getLangOpts(),
            &ci.getPreprocessor() );

    if ( useCpp )
    {
        clang::ParseAST ( ci.getPreprocessor(), astConsumerCpp,
ci.getASTContext() );
    }
    else
    {
        clang::ParseAST ( ci.getPreprocessor(), astConsumer,
ci.getASTContext() );
    }
    ci.getDiagnosticClient().EndSourceFile();

...

I was hoping that this was enough to make clang 3.2 "gcc 4.2 compatible"
but it looks like it's not the case. Any idea of the required
options/initialization sequence for clang to understand glibc and gnu
libC++ specificities and parse properly GNU headers?

Thank you for your help!

Pascal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130513/a743dd85/attachment.html>


More information about the cfe-dev mailing list