diff --git a/src/Core/Parser/Parser.cs b/src/Core/Parser/Parser.cs index 2bb1946b..897cfb38 100644 --- a/src/Core/Parser/Parser.cs +++ b/src/Core/Parser/Parser.cs @@ -38,6 +38,18 @@ namespace CppSharp ASTContext = context; } + /// + /// Get info about that target + /// + /// + /// + public ParserTargetInfo GetTargetInfo(ParserOptions options) + { + options.ASTContext = ASTContext; + + return Parser.ClangParser.GetTargetInfo(options); + } + /// /// Parses a C++ source file to a translation unit. /// diff --git a/src/CppParser/CppParser.cpp b/src/CppParser/CppParser.cpp index 66a13298..fe0e7aa9 100644 --- a/src/CppParser/CppParser.cpp +++ b/src/CppParser/CppParser.cpp @@ -27,6 +27,7 @@ DEF_VECTOR_STRING(ParserOptions, SystemIncludeDirs) DEF_VECTOR_STRING(ParserOptions, Defines) DEF_VECTOR_STRING(ParserOptions, LibraryDirs) DEF_STRING(ParserOptions, TargetTriple) +DEF_STRING(ParserTargetInfo, ABI) ParserResult::ParserResult() : ASTContext(0) diff --git a/src/CppParser/CppParser.h b/src/CppParser/CppParser.h index 42f61425..1aa70723 100644 --- a/src/CppParser/CppParser.h +++ b/src/CppParser/CppParser.h @@ -9,6 +9,7 @@ #include "AST.h" #include "Helpers.h" +#include "Target.h" namespace CppSharp { namespace CppParser { diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 32bc3ded..a23e94b4 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -1210,6 +1210,37 @@ static CallingConvention ConvertCallConv(clang::CallingConv CC) return CallingConvention::Default; } +static ParserIntType ConvertIntType(clang::TargetInfo::IntType IT) +{ + switch (IT) + { + case clang::TargetInfo::IntType::NoInt: + return ParserIntType::NoInt; + case clang::TargetInfo::IntType::SignedChar: + return ParserIntType::SignedChar; + case clang::TargetInfo::IntType::UnsignedChar: + return ParserIntType::UnsignedChar; + case clang::TargetInfo::IntType::SignedShort: + return ParserIntType::SignedShort; + case clang::TargetInfo::IntType::UnsignedShort: + return ParserIntType::UnsignedShort; + case clang::TargetInfo::IntType::SignedInt: + return ParserIntType::SignedInt; + case clang::TargetInfo::IntType::UnsignedInt: + return ParserIntType::UnsignedInt; + case clang::TargetInfo::IntType::SignedLong: + return ParserIntType::SignedLong; + case clang::TargetInfo::IntType::UnsignedLong: + return ParserIntType::UnsignedLong; + case clang::TargetInfo::IntType::SignedLongLong: + return ParserIntType::SignedLongLong; + case clang::TargetInfo::IntType::UnsignedLongLong: + return ParserIntType::UnsignedLongLong; + } + + llvm_unreachable("Unknown parser integer type"); +} + Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL, bool DesugarType) { @@ -2688,3 +2719,89 @@ ParserResult* ClangParser::ParseLibrary(ParserOptions* Opts) Parser parser(Opts); return parser.ParseLibrary(Opts->FileName); } + +ParserTargetInfo* Parser::GetTargetInfo() +{ + assert(Opts->ASTContext && "Expected a valid ASTContext"); + + auto res = new ParserResult(); + res->ASTContext = Lib; + + SetupHeader(); + + auto SC = new clang::SemaConsumer(); + C->setASTConsumer(SC); + + C->createSema(clang::TU_Complete, 0); + SC->InitializeSema(C->getSema()); + + auto DiagClient = new DiagnosticConsumer(); + C->getDiagnostics().setClient(DiagClient); + + AST = &C->getASTContext(); + + // Initialize enough Clang codegen machinery so we can get at ABI details. + llvm::LLVMContext Ctx; + llvm::OwningPtr M(new llvm::Module("", Ctx)); + + M->setTargetTriple(AST->getTargetInfo().getTriple().getTriple()); + M->setDataLayout(AST->getTargetInfo().getTargetDescription()); + llvm::OwningPtr TD(new llvm::DataLayout(AST->getTargetInfo() + .getTargetDescription())); + + llvm::OwningPtr CGM( + new clang::CodeGen::CodeGenModule(C->getASTContext(), C->getCodeGenOpts(), + *M, *TD, C->getDiagnostics())); + + llvm::OwningPtr CGT( + new clang::CodeGen::CodeGenTypes(*CGM.get())); + + CodeGenInfo = (clang::TargetCodeGenInfo*) &CGM->getTargetCodeGenInfo(); + CodeGenTypes = CGT.get(); + + auto parserTargetInfo = new ParserTargetInfo(); + + parserTargetInfo->ABI = AST->getTargetInfo().getABI(); + + parserTargetInfo->Char16Type = ConvertIntType(AST->getTargetInfo().getChar16Type()); + parserTargetInfo->Char32Type = ConvertIntType(AST->getTargetInfo().getChar32Type()); + parserTargetInfo->Int64Type = ConvertIntType(AST->getTargetInfo().getInt64Type()); + parserTargetInfo->IntMaxType = ConvertIntType(AST->getTargetInfo().getIntMaxType()); + parserTargetInfo->IntPtrType = ConvertIntType(AST->getTargetInfo().getIntPtrType()); + parserTargetInfo->SizeType = ConvertIntType(AST->getTargetInfo().getSizeType()); + parserTargetInfo->UIntMaxType = ConvertIntType(AST->getTargetInfo().getUIntMaxType()); + parserTargetInfo->WCharType = ConvertIntType(AST->getTargetInfo().getWCharType()); + parserTargetInfo->WIntType = ConvertIntType(AST->getTargetInfo().getWIntType()); + + parserTargetInfo->BoolAlign = AST->getTargetInfo().getBoolAlign(); + parserTargetInfo->BoolWidth = AST->getTargetInfo().getBoolWidth(); + parserTargetInfo->CharAlign = AST->getTargetInfo().getCharAlign(); + parserTargetInfo->CharWidth = AST->getTargetInfo().getCharWidth(); + parserTargetInfo->Char16Align = AST->getTargetInfo().getChar16Align(); + parserTargetInfo->Char16Width = AST->getTargetInfo().getChar16Width(); + parserTargetInfo->Char32Align = AST->getTargetInfo().getChar32Align(); + parserTargetInfo->Char32Width = AST->getTargetInfo().getChar32Width(); + parserTargetInfo->HalfAlign = AST->getTargetInfo().getHalfAlign(); + parserTargetInfo->HalfWidth = AST->getTargetInfo().getHalfWidth(); + parserTargetInfo->FloatAlign = AST->getTargetInfo().getFloatAlign(); + parserTargetInfo->FloatWidth = AST->getTargetInfo().getFloatWidth(); + parserTargetInfo->DoubleAlign = AST->getTargetInfo().getDoubleAlign(); + parserTargetInfo->DoubleWidth = AST->getTargetInfo().getDoubleWidth(); + parserTargetInfo->ShortAlign = AST->getTargetInfo().getShortAlign(); + parserTargetInfo->ShortWidth = AST->getTargetInfo().getShortWidth(); + parserTargetInfo->IntAlign = AST->getTargetInfo().getIntAlign(); + parserTargetInfo->IntWidth = AST->getTargetInfo().getIntWidth(); + parserTargetInfo->IntMaxTWidth = AST->getTargetInfo().getIntMaxTWidth(); + parserTargetInfo->LongAlign = AST->getTargetInfo().getLongAlign(); + parserTargetInfo->LongWidth = AST->getTargetInfo().getLongWidth(); + parserTargetInfo->LongDoubleAlign = AST->getTargetInfo().getLongDoubleAlign(); + parserTargetInfo->LongDoubleWidth = AST->getTargetInfo().getLongDoubleWidth(); + parserTargetInfo->LongLongAlign = AST->getTargetInfo().getLongLongAlign(); + parserTargetInfo->LongLongWidth = AST->getTargetInfo().getLongLongWidth(); + parserTargetInfo->PointerAlign = AST->getTargetInfo().getPointerAlign(0); + parserTargetInfo->PointerWidth = AST->getTargetInfo().getPointerWidth(0); + parserTargetInfo->WCharAlign = AST->getTargetInfo().getWCharAlign(); + parserTargetInfo->WCharWidth = AST->getTargetInfo().getWCharWidth(); + + return parserTargetInfo; +} diff --git a/src/CppParser/Parser.h b/src/CppParser/Parser.h index ddb4f23a..a753475f 100644 --- a/src/CppParser/Parser.h +++ b/src/CppParser/Parser.h @@ -56,6 +56,7 @@ struct Parser ParserResultKind ParseSharedLib(llvm::StringRef File, llvm::MemoryBuffer *Buffer, CppSharp::CppParser::NativeLibrary*& NativeLib); + ParserTargetInfo* GetTargetInfo(); protected: diff --git a/src/CppParser/Target.h b/src/CppParser/Target.h new file mode 100644 index 00000000..6fdda70c --- /dev/null +++ b/src/CppParser/Target.h @@ -0,0 +1,77 @@ +/************************************************************************ +* +* CppSharp +* Licensed under the simplified BSD license. All rights reserved. +* +************************************************************************/ + +#pragma once + +#include "AST.h" +#include "Helpers.h" + +namespace CppSharp { namespace CppParser { + +using namespace CppSharp::CppParser::AST; + +enum struct ParserIntType +{ + NoInt = 0, + SignedChar, + UnsignedChar, + SignedShort, + UnsignedShort, + SignedInt, + UnsignedInt, + SignedLong, + UnsignedLong, + SignedLongLong, + UnsignedLongLong +}; + +struct CS_API ParserTargetInfo +{ + STRING(ABI); + + ParserIntType Char16Type; + ParserIntType Char32Type; + ParserIntType Int64Type; + ParserIntType IntMaxType; + ParserIntType IntPtrType; + ParserIntType SizeType; + ParserIntType UIntMaxType; + ParserIntType WCharType; + ParserIntType WIntType; + + unsigned int BoolAlign; + unsigned int BoolWidth; + unsigned int CharAlign; + unsigned int CharWidth; + unsigned int Char16Align; + unsigned int Char16Width; + unsigned int Char32Align; + unsigned int Char32Width; + unsigned int HalfAlign; + unsigned int HalfWidth; + unsigned int FloatAlign; + unsigned int FloatWidth; + unsigned int DoubleAlign; + unsigned int DoubleWidth; + unsigned int ShortAlign; + unsigned int ShortWidth; + unsigned int IntAlign; + unsigned int IntWidth; + unsigned int IntMaxTWidth; + unsigned int LongAlign; + unsigned int LongWidth; + unsigned int LongDoubleAlign; + unsigned int LongDoubleWidth; + unsigned int LongLongAlign; + unsigned int LongLongWidth; + unsigned int PointerAlign; + unsigned int PointerWidth; + unsigned int WCharAlign; + unsigned int WCharWidth; +}; + +} } \ No newline at end of file diff --git a/src/Parser/Main.cpp b/src/Parser/Main.cpp index df2b7215..031114c3 100644 --- a/src/Parser/Main.cpp +++ b/src/Parser/Main.cpp @@ -14,6 +14,12 @@ public ref class ClangParser { public: + static ParserTargetInfo^ GetTargetInfo(ParserOptions^ Opts) + { + ::Parser parser(Opts); + return parser.GetTargetInfo(); + } + static ParserResult^ ParseHeader(ParserOptions^ Opts) { if (!Opts->FileName) return nullptr; diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 70ad98f6..21d34eaf 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -1233,6 +1233,37 @@ static CppSharp::AST::CallingConvention ConvertCallConv(clang::CallingConv CC) return CppSharp::AST::CallingConvention::Default; } +static ParserIntType ConvertIntType(clang::TargetInfo::IntType IT) +{ + switch (IT) + { + case clang::TargetInfo::IntType::NoInt: + return ParserIntType::NoInt; + case clang::TargetInfo::IntType::SignedChar: + return ParserIntType::SignedChar; + case clang::TargetInfo::IntType::UnsignedChar: + return ParserIntType::UnsignedChar; + case clang::TargetInfo::IntType::SignedShort: + return ParserIntType::SignedShort; + case clang::TargetInfo::IntType::UnsignedShort: + return ParserIntType::UnsignedShort; + case clang::TargetInfo::IntType::SignedInt: + return ParserIntType::SignedInt; + case clang::TargetInfo::IntType::UnsignedInt: + return ParserIntType::UnsignedInt; + case clang::TargetInfo::IntType::SignedLong: + return ParserIntType::SignedLong; + case clang::TargetInfo::IntType::UnsignedLong: + return ParserIntType::UnsignedLong; + case clang::TargetInfo::IntType::SignedLongLong: + return ParserIntType::SignedLongLong; + case clang::TargetInfo::IntType::UnsignedLongLong: + return ParserIntType::UnsignedLongLong; + } + + llvm_unreachable("Unknown parser integer type"); +} + CppSharp::AST::QualifiedType^ Parser::WalkQualifiedType(clang::TypeSourceInfo* TSI) { auto TL = TSI->getTypeLoc(); @@ -2684,4 +2715,90 @@ ParserResult^ Parser::ParseLibrary(const std::string& File) return res; return res; -} \ No newline at end of file +} + +ParserTargetInfo^ Parser::GetTargetInfo() +{ + assert(Opts->ASTContext && "Expected a valid ASTContext"); + + auto res = gcnew ParserResult(); + res->ASTContext = Lib; + + SetupHeader(); + + auto SC = new clang::SemaConsumer(); + C->setASTConsumer(SC); + + C->createSema(clang::TU_Complete, 0); + SC->InitializeSema(C->getSema()); + + auto DiagClient = new DiagnosticConsumer(); + C->getDiagnostics().setClient(DiagClient); + + AST = &C->getASTContext(); + + // Initialize enough Clang codegen machinery so we can get at ABI details. + llvm::LLVMContext Ctx; + llvm::OwningPtr M(new llvm::Module("", Ctx)); + + M->setTargetTriple(AST->getTargetInfo().getTriple().getTriple()); + M->setDataLayout(AST->getTargetInfo().getTargetDescription()); + llvm::OwningPtr TD(new llvm::DataLayout(AST->getTargetInfo() + .getTargetDescription())); + + llvm::OwningPtr CGM( + new clang::CodeGen::CodeGenModule(C->getASTContext(), C->getCodeGenOpts(), + *M, *TD, C->getDiagnostics())); + + llvm::OwningPtr CGT( + new clang::CodeGen::CodeGenTypes(*CGM.get())); + + CodeGenInfo = (clang::TargetCodeGenInfo*) &CGM->getTargetCodeGenInfo(); + CodeGenTypes = CGT.get(); + + auto parserTargetInfo = gcnew ParserTargetInfo(); + + parserTargetInfo->ABI = clix::marshalString(AST->getTargetInfo().getABI()); + + parserTargetInfo->Char16Type = ConvertIntType(AST->getTargetInfo().getChar16Type()); + parserTargetInfo->Char32Type = ConvertIntType(AST->getTargetInfo().getChar32Type()); + parserTargetInfo->Int64Type = ConvertIntType(AST->getTargetInfo().getInt64Type()); + parserTargetInfo->IntMaxType = ConvertIntType(AST->getTargetInfo().getIntMaxType()); + parserTargetInfo->IntPtrType = ConvertIntType(AST->getTargetInfo().getIntPtrType()); + parserTargetInfo->SizeType = ConvertIntType(AST->getTargetInfo().getSizeType()); + parserTargetInfo->UIntMaxType = ConvertIntType(AST->getTargetInfo().getUIntMaxType()); + parserTargetInfo->WCharType = ConvertIntType(AST->getTargetInfo().getWCharType()); + parserTargetInfo->WIntType = ConvertIntType(AST->getTargetInfo().getWIntType()); + + parserTargetInfo->BoolAlign = AST->getTargetInfo().getBoolAlign(); + parserTargetInfo->BoolWidth = AST->getTargetInfo().getBoolWidth(); + parserTargetInfo->CharAlign = AST->getTargetInfo().getCharAlign(); + parserTargetInfo->CharWidth = AST->getTargetInfo().getCharWidth(); + parserTargetInfo->Char16Align = AST->getTargetInfo().getChar16Align(); + parserTargetInfo->Char16Width = AST->getTargetInfo().getChar16Width(); + parserTargetInfo->Char32Align = AST->getTargetInfo().getChar32Align(); + parserTargetInfo->Char32Width = AST->getTargetInfo().getChar32Width(); + parserTargetInfo->HalfAlign = AST->getTargetInfo().getHalfAlign(); + parserTargetInfo->HalfWidth = AST->getTargetInfo().getHalfWidth(); + parserTargetInfo->FloatAlign = AST->getTargetInfo().getFloatAlign(); + parserTargetInfo->FloatWidth = AST->getTargetInfo().getFloatWidth(); + parserTargetInfo->DoubleAlign = AST->getTargetInfo().getDoubleAlign(); + parserTargetInfo->DoubleWidth = AST->getTargetInfo().getDoubleWidth(); + parserTargetInfo->ShortAlign = AST->getTargetInfo().getShortAlign(); + parserTargetInfo->ShortWidth = AST->getTargetInfo().getShortWidth(); + parserTargetInfo->IntAlign = AST->getTargetInfo().getIntAlign(); + parserTargetInfo->IntWidth = AST->getTargetInfo().getIntWidth(); + parserTargetInfo->IntMaxTWidth = AST->getTargetInfo().getIntMaxTWidth(); + parserTargetInfo->LongAlign = AST->getTargetInfo().getLongAlign(); + parserTargetInfo->LongWidth = AST->getTargetInfo().getLongWidth(); + parserTargetInfo->LongDoubleAlign = AST->getTargetInfo().getLongDoubleAlign(); + parserTargetInfo->LongDoubleWidth = AST->getTargetInfo().getLongDoubleWidth(); + parserTargetInfo->LongLongAlign = AST->getTargetInfo().getLongLongAlign(); + parserTargetInfo->LongLongWidth = AST->getTargetInfo().getLongLongWidth(); + parserTargetInfo->PointerAlign = AST->getTargetInfo().getPointerAlign(0); + parserTargetInfo->PointerWidth = AST->getTargetInfo().getPointerWidth(0); + parserTargetInfo->WCharAlign = AST->getTargetInfo().getWCharAlign(); + parserTargetInfo->WCharWidth = AST->getTargetInfo().getWCharWidth(); + + return parserTargetInfo; +} diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 4846bf3a..6cf7d9cf 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -27,6 +27,7 @@ #include #include "CXXABI.h" #include "Options.h" +#include "Target.h" #include #include @@ -54,6 +55,7 @@ struct Parser ParserResultKind ParseSharedLib(llvm::StringRef File, llvm::MemoryBuffer *Buffer, CppSharp::AST::NativeLibrary^ NativeLib); + ParserTargetInfo^ GetTargetInfo(); protected: diff --git a/src/Parser/Target.h b/src/Parser/Target.h new file mode 100644 index 00000000..2eff5da1 --- /dev/null +++ b/src/Parser/Target.h @@ -0,0 +1,69 @@ +/************************************************************************ +* +* CppSharp +* Licensed under the simplified BSD license. All rights reserved. +* +************************************************************************/ + +#using +using namespace System::Collections::Generic; + +public enum ParserIntType +{ + NoInt = 0, + SignedChar, + UnsignedChar, + SignedShort, + UnsignedShort, + SignedInt, + UnsignedInt, + SignedLong, + UnsignedLong, + SignedLongLong, + UnsignedLongLong +}; + +public ref struct ParserTargetInfo +{ + System::String^ ABI; + + ParserIntType Char16Type; + ParserIntType Char32Type; + ParserIntType Int64Type; + ParserIntType IntMaxType; + ParserIntType IntPtrType; + ParserIntType SizeType; + ParserIntType UIntMaxType; + ParserIntType WCharType; + ParserIntType WIntType; + + unsigned int BoolAlign; + unsigned int BoolWidth; + unsigned int CharAlign; + unsigned int CharWidth; + unsigned int Char16Align; + unsigned int Char16Width; + unsigned int Char32Align; + unsigned int Char32Width; + unsigned int HalfAlign; + unsigned int HalfWidth; + unsigned int FloatAlign; + unsigned int FloatWidth; + unsigned int DoubleAlign; + unsigned int DoubleWidth; + unsigned int ShortAlign; + unsigned int ShortWidth; + unsigned int IntAlign; + unsigned int IntWidth; + unsigned int IntMaxTWidth; + unsigned int LongAlign; + unsigned int LongWidth; + unsigned int LongDoubleAlign; + unsigned int LongDoubleWidth; + unsigned int LongLongAlign; + unsigned int LongLongWidth; + unsigned int PointerAlign; + unsigned int PointerWidth; + unsigned int WCharAlign; + unsigned int WCharWidth; +};