@ -44,8 +44,7 @@
@@ -44,8 +44,7 @@
# include <clang/Driver/ToolChain.h>
# include <clang/Driver/Util.h>
# include <clang/Index/USRGeneration.h>
# include <CodeGen/CodeGenModule.h>
# include <CodeGen/CodeGenTypes.h>
# include <CodeGen/TargetInfo.h>
# include <CodeGen/CGCall.h>
# include <CodeGen/CGCXXABI.h>
@ -3278,9 +3277,8 @@ bool Parser::IsValidDeclaration(const clang::SourceLocation& Loc)
@@ -3278,9 +3277,8 @@ bool Parser::IsValidDeclaration(const clang::SourceLocation& Loc)
//-----------------------------------//
void Parser : : WalkAST ( )
void Parser : : WalkAST ( clang : : TranslationUnitDecl * TU )
{
auto TU = c - > getASTContext ( ) . getTranslationUnitDecl ( ) ;
for ( auto D : TU - > decls ( ) )
{
if ( D - > getBeginLoc ( ) . isValid ( ) & &
@ -4049,35 +4047,32 @@ void Parser::HandleDiagnostics(ParserResult* res)
@@ -4049,35 +4047,32 @@ void Parser::HandleDiagnostics(ParserResult* res)
}
}
ParserResult * Parser : : ParseHeader ( const std : : vector < std : : string > & SourceFiles )
void Parser : : SetupLLVMCodegen ( )
{
assert ( opts - > ASTContext & & " Expected a valid ASTContext " ) ;
auto res = new ParserResult ( ) ;
if ( SourceFiles . empty ( ) )
{
res - > kind = ParserResultKind : : FileNotFound ;
return res ;
}
// Initialize enough Clang codegen machinery so we can get at ABI details.
LLVMModule . reset ( new llvm : : Module ( " " , LLVMCtx ) ) ;
Setup ( ) ;
LLVMModule - > setTargetTriple ( c - > getTarget ( ) . getTriple ( ) . getTriple ( ) ) ;
LLVMModule - > setDataLayout ( c - > getTarget ( ) . getDataLayout ( ) ) ;
std : : unique_ptr < clang : : SemaConsumer > SC ( new clang : : SemaConsumer ( ) ) ;
c - > setASTConsumer ( std : : move ( SC ) ) ;
CGM . reset ( new clang : : CodeGen : : CodeGenModule ( c - > getASTContext ( ) ,
c - > getHeaderSearchOpts ( ) , c - > getPreprocessorOpts ( ) ,
c - > getCodeGenOpts ( ) , * LLVMModule , c - > getDiagnostics ( ) ) ) ;
c - > createSema ( clang : : TU_Complete , 0 ) ;
CGT . reset ( new clang : : CodeGen : : CodeGenTypes ( * CGM . get ( ) ) ) ;
auto DiagClient = new DiagnosticConsumer ( ) ;
c - > getDiagnostics ( ) . setClient ( DiagClient ) ;
codeGenTypes = CGT . get ( ) ;
}
bool Parser : : SetupSourceFiles ( const std : : vector < std : : string > & SourceFiles ,
std : : vector < const clang : : FileEntry * > & FileEntries )
{
// Check that the file is reachable.
const clang : : DirectoryLookup * Dir ;
llvm : : SmallVector <
std : : pair < const clang : : FileEntry * , const clang : : DirectoryEntry * > ,
0 > Includers ;
std : : vector < const clang : : FileEntry * > FileEntries ;
for ( const auto & SourceFile : SourceFiles )
{
auto FileEntry = c - > getPreprocessor ( ) . getHeaderSearchInfo ( ) . LookupFile ( SourceFile ,
@ -4085,71 +4080,97 @@ ParserResult* Parser::ParseHeader(const std::vector<std::string>& SourceFiles)
@@ -4085,71 +4080,97 @@ ParserResult* Parser::ParseHeader(const std::vector<std::string>& SourceFiles)
nullptr , Dir , Includers , nullptr , nullptr , nullptr , nullptr , nullptr ) ;
if ( ! FileEntry )
{
res - > kind = ParserResultKind : : FileNotFound ;
return res ;
}
return false ;
FileEntries . push_back ( FileEntry ) ;
}
// Create a virtual file that includes the header. This gets rid of some
// Clang warnings about parsing an header file as the main file.
std : : string str ;
std : : string source ;
for ( const auto & SourceFile : SourceFiles )
{
str + = " #include \" " + SourceFile + " \" " + " \n " ;
source + = " #include \" " + SourceFile + " \" " + " \n " ;
}
str + = " \0 " ;
source + = " \0 " ;
auto buffer = llvm : : MemoryBuffer : : getMemBuffer ( str ) ;
auto buffer = llvm : : MemoryBuffer : : getMemBufferCopy ( source ) ;
auto & SM = c - > getSourceManager ( ) ;
SM . setMainFileID ( SM . createFileID ( std : : move ( buffer ) ) ) ;
clang : : DiagnosticConsumer * client = c - > getDiagnostics ( ) . getClient ( ) ;
client - > BeginSourceFile ( c - > getLangOpts ( ) , & c - > getPreprocessor ( ) ) ;
return true ;
}
ParseAST ( c - > getSema ( ) ) ;
class SemaConsumer : public clang : : SemaConsumer {
CppSharp : : CppParser : : Parser & Parser ;
std : : vector < const clang : : FileEntry * > & FileEntries ;
public :
SemaConsumer ( CppSharp : : CppParser : : Parser & parser ,
std : : vector < const clang : : FileEntry * > & entries )
: Parser ( parser ) , FileEntries ( entries ) { }
virtual void HandleTranslationUnit ( clang : : ASTContext & Ctx ) override ;
} ;
client - > EndSourceFile ( ) ;
void SemaConsumer : : HandleTranslationUnit ( clang : : ASTContext & Ctx )
{
auto FileEntry = FileEntries [ 0 ] ;
auto FileName = FileEntry - > getName ( ) ;
auto Unit = Parser . opts - > ASTContext - > FindOrCreateModule ( FileName ) ;
HandleDiagnostics ( res ) ;
auto TU = Ctx . getTranslationUnitDecl ( ) ;
Parser . HandleDeclaration ( TU , Unit ) ;
if ( client - > getNumErrors ( ) ! = 0 )
if ( Unit - > originalPtr = = nullptr )
Unit - > originalPtr = ( void * ) FileEntry ;
Parser . WalkAST ( TU ) ;
}
ParserResult * Parser : : ParseHeader ( const std : : vector < std : : string > & SourceFiles )
{
assert ( opts - > ASTContext & & " Expected a valid ASTContext " ) ;
auto res = new ParserResult ( ) ;
if ( SourceFiles . empty ( ) )
{
res - > kind = ParserResultKind : : Error ;
res - > kind = ParserResultKind : : FileNotFound ;
return res ;
}
auto & AST = c - > getASTContext ( ) ;
Setup ( ) ;
SetupLLVMCodegen ( ) ;
auto FileEntry = FileEntries [ 0 ] ;
auto FileName = FileEntry - > getName ( ) ;
auto Unit = opts - > ASTContext - > FindOrCreateModule ( FileName ) ;
std : : vector < const clang : : FileEntry * > FileEntries ;
if ( ! SetupSourceFiles ( SourceFiles , FileEntries ) )
{
res - > kind = ParserResultKind : : FileNotFound ;
return res ;
}
auto TU = AST . getTranslationUnitDecl ( ) ;
HandleDeclaration ( TU , Unit ) ;
std : : unique_ptr < SemaConsumer > SC ( new SemaConsumer ( * this , FileEntries ) ) ;
c - > setASTConsumer ( std : : move ( SC ) ) ;
if ( Unit - > originalPtr = = nullptr )
Unit - > originalPtr = ( void * ) FileEntry ;
c - > createSema ( clang : : TU_Complete , 0 ) ;
// Initialize enough Clang codegen machinery so we can get at ABI details.
llvm : : LLVMContext Ctx ;
std : : unique_ptr < llvm : : Module > M ( new llvm : : Module ( " " , Ctx ) ) ;
auto DiagClient = new DiagnosticConsumer ( ) ;
c - > getDiagnostics ( ) . setClient ( DiagClient ) ;
M - > setTargetTriple ( c - > getTarget ( ) . getTriple ( ) . getTriple ( ) ) ;
M - > setDataLayout ( c - > getTarget ( ) . getDataLayout ( ) ) ;
clang : : DiagnosticConsumer * client = c - > getDiagnostics ( ) . getClient ( ) ;
client - > BeginSourceFile ( c - > getLangOpts ( ) , & c - > getPreprocessor ( ) ) ;
std : : unique_ptr < clang : : CodeGen : : CodeGenModule > CGM (
new clang : : CodeGen : : CodeGenModule ( c - > getASTContext ( ) , c - > getHeaderSearchOpts ( ) ,
c - > getPreprocessorOpts ( ) , c - > getCodeGenOpts ( ) , * M , c - > getDiagnostics ( ) ) ) ;
ParseAST ( c - > getSema ( ) ) ;
std : : unique_ptr < clang : : CodeGen : : CodeGenTypes > CGT (
new clang : : CodeGen : : CodeGenTypes ( * CGM . get ( ) ) ) ;
client - > EndSourceFile ( ) ;
codeGenTypes = CGT . get ( ) ;
HandleDiagnostics ( res ) ;
WalkAST ( ) ;
if ( client - > getNumErrors ( ) ! = 0 )
{
res - > kind = ParserResultKind : : Error ;
return res ;
}
res - > targetInfo = GetTargetInfo ( ) ;