diff --git a/src/AST/Function.cs b/src/AST/Function.cs index 35563fde..0a1fe3c7 100644 --- a/src/AST/Function.cs +++ b/src/AST/Function.cs @@ -39,6 +39,7 @@ namespace CppSharp.AST public Type Type { get { return QualifiedType.Type; } } public QualifiedType QualifiedType { get; set; } + public bool IsIndirect { get; set; } public ParameterKind Kind { get; set; } public ParameterUsage Usage { get; set; } @@ -70,6 +71,8 @@ namespace CppSharp.AST } public QualifiedType ReturnType { get; set; } + public bool IsReturnIndirect { get; set; } + public List Parameters { get; set; } public bool IsVariadic { get; set; } public bool IsInline { get; set; } diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 6b515555..ade79b4b 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -23,6 +26,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -1491,6 +1498,19 @@ static CppSharp::AST::CallingConvention ConvertCallConv(clang::CallingConv CC) return CppSharp::AST::CallingConvention::Default; } +static const clang::CodeGen::CGFunctionInfo& GetCodeGenFuntionInfo( + clang::CodeGen::CodeGenTypes* CodeGenTypes, clang::FunctionDecl* FD) +{ + using namespace clang; + if (auto CD = dyn_cast(FD)) { + return CodeGenTypes->arrangeCXXConstructorDeclaration(CD, Ctor_Base); + } else if (auto DD = dyn_cast(FD)) { + return CodeGenTypes->arrangeCXXDestructor(DD, Dtor_Base); + } + + return CodeGenTypes->arrangeFunctionDeclaration(FD); +} + void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F, bool IsDependent) { @@ -1583,6 +1603,21 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F, ParamStartLoc = VD->getLocEnd(); } + + if (FD->isThisDeclarationADefinition() && !FD->isDependentContext()) + { + auto& CGInfo = GetCodeGenFuntionInfo(CodeGenTypes, FD); + F->IsReturnIndirect = CGInfo.getReturnInfo().isIndirect(); + + auto Index = 0; + for (auto I = CGInfo.arg_begin(), E = CGInfo.arg_end(); I != E; I++) + { + // Skip the first argument as it's the return type. + if (I == CGInfo.arg_begin()) + continue; + F->Parameters[Index++]->IsIndirect = I->info.isIndirect(); + } + } } CppSharp::AST::Function^ Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent, @@ -2181,6 +2216,26 @@ ParserResult^ Parser::ParseHeader(const std::string& File) } 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(); + WalkAST(); res->Kind = ParserResultKind::Success; diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index a0824c85..101e530e 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -25,6 +25,13 @@ #include #include "CXXABI.h" +namespace clang { + class TargetCodeGenInfo; + namespace CodeGen { + class CodeGenTypes; + } +} + #include #include @@ -185,6 +192,8 @@ protected: llvm::OwningPtr C; clang::ASTContext* AST; clang::TargetCXXABI::Kind TargetABI; + clang::TargetCodeGenInfo* CodeGenInfo; + clang::CodeGen::CodeGenTypes* CodeGenTypes; }; //-----------------------------------// diff --git a/src/Parser/Parser.lua b/src/Parser/Parser.lua index 8e76aa93..e2bda679 100644 --- a/src/Parser/Parser.lua +++ b/src/Parser/Parser.lua @@ -47,6 +47,7 @@ project "CppSharp.Parser" "../../deps/LLVM/include", "../../deps/LLVM/build/include", "../../deps/LLVM/tools/clang/include", + "../../deps/LLVM/tools/clang/lib", "../../deps/LLVM/build/tools/clang/include" } @@ -63,6 +64,7 @@ project "CppSharp.Parser" "clangAnalysis", "clangAST", "clangBasic", + "clangCodeGen", "clangDriver", "clangEdit", "clangFrontend", @@ -70,14 +72,28 @@ project "CppSharp.Parser" "clangParse", "clangSema", "clangSerialization", + "LLVMAnalysis", "LLVMAsmParser", "LLVMBitReader", "LLVMBitWriter", + "LLVMCodeGen", + "LLVMCore", + "LLVMipa", + "LLVMipo", + "LLVMInstCombine", + "LLVMInstrumentation", + "LLVMIRReader", + "LLVMLinker", "LLVMMC", "LLVMMCParser", + "LLVMObjCARCOpts", "LLVMObject", "LLVMOption", + "LLVMScalarOpts", "LLVMSupport", + "LLVMTarget", + "LLVMTransformUtils", + "LLVMVectorize", "LLVMX86AsmParser", "LLVMX86AsmPrinter", "LLVMX86Desc",