Parsing gnu c++ headers/code

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::vectorstd::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::vectorstd::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

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;

You also need to set WChar. But this method of setting up a CompilerInstance is not recommended, because there’s a whole big pile of things to remember (and the set of things changes frequently). Instead, consider using CompilerInvocation to set up your CompilerInstance.