Browse Source

Added accurate return and argument type ABI information by querying Clang's code gen layer for the correct information. This does add a lot of extra dependencies on LLVM and Clang libraries.

pull/47/merge
triton 12 years ago
parent
commit
5586acdbaf
  1. 3
      src/AST/Function.cs
  2. 55
      src/Parser/Parser.cpp
  3. 9
      src/Parser/Parser.h
  4. 16
      src/Parser/Parser.lua

3
src/AST/Function.cs

@ -39,6 +39,7 @@ namespace CppSharp.AST
public Type Type { get { return QualifiedType.Type; } } public Type Type { get { return QualifiedType.Type; } }
public QualifiedType QualifiedType { get; set; } public QualifiedType QualifiedType { get; set; }
public bool IsIndirect { get; set; }
public ParameterKind Kind { get; set; } public ParameterKind Kind { get; set; }
public ParameterUsage Usage { get; set; } public ParameterUsage Usage { get; set; }
@ -70,6 +71,8 @@ namespace CppSharp.AST
} }
public QualifiedType ReturnType { get; set; } public QualifiedType ReturnType { get; set; }
public bool IsReturnIndirect { get; set; }
public List<Parameter> Parameters { get; set; } public List<Parameter> Parameters { get; set; }
public bool IsVariadic { get; set; } public bool IsVariadic { get; set; }
public bool IsInline { get; set; } public bool IsInline { get; set; }

55
src/Parser/Parser.cpp

@ -11,6 +11,9 @@
#include <llvm/Support/Path.h> #include <llvm/Support/Path.h>
#include <llvm/Object/Archive.h> #include <llvm/Object/Archive.h>
#include <llvm/Object/ObjectFile.h> #include <llvm/Object/ObjectFile.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/DataLayout.h>
#include <clang/Basic/Version.h> #include <clang/Basic/Version.h>
#include <clang/Config/config.h> #include <clang/Config/config.h>
#include <clang/AST/ASTContext.h> #include <clang/AST/ASTContext.h>
@ -23,6 +26,10 @@
#include <clang/Sema/SemaConsumer.h> #include <clang/Sema/SemaConsumer.h>
#include <clang/Frontend/Utils.h> #include <clang/Frontend/Utils.h>
#include <clang/Driver/Util.h> #include <clang/Driver/Util.h>
#include <CodeGen/CodeGenModule.h>
#include <CodeGen/CodeGenTypes.h>
#include <CodeGen/TargetInfo.h>
#include <CodeGen/CGCall.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -1491,6 +1498,19 @@ static CppSharp::AST::CallingConvention ConvertCallConv(clang::CallingConv CC)
return CppSharp::AST::CallingConvention::Default; 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<clang::CXXConstructorDecl>(FD)) {
return CodeGenTypes->arrangeCXXConstructorDeclaration(CD, Ctor_Base);
} else if (auto DD = dyn_cast<clang::CXXDestructorDecl>(FD)) {
return CodeGenTypes->arrangeCXXDestructor(DD, Dtor_Base);
}
return CodeGenTypes->arrangeFunctionDeclaration(FD);
}
void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F, void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F,
bool IsDependent) bool IsDependent)
{ {
@ -1583,6 +1603,21 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, CppSharp::AST::Function^ F,
ParamStartLoc = VD->getLocEnd(); 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, CppSharp::AST::Function^ Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDependent,
@ -2181,6 +2216,26 @@ ParserResult^ Parser::ParseHeader(const std::string& File)
} }
AST = &C->getASTContext(); AST = &C->getASTContext();
// Initialize enough Clang codegen machinery so we can get at ABI details.
llvm::LLVMContext Ctx;
llvm::OwningPtr<llvm::Module> M(new llvm::Module("", Ctx));
M->setTargetTriple(AST->getTargetInfo().getTriple().getTriple());
M->setDataLayout(AST->getTargetInfo().getTargetDescription());
llvm::OwningPtr<llvm::DataLayout> TD(new llvm::DataLayout(AST->getTargetInfo()
.getTargetDescription()));
llvm::OwningPtr<clang::CodeGen::CodeGenModule> CGM(
new clang::CodeGen::CodeGenModule(C->getASTContext(), C->getCodeGenOpts(),
*M, *TD, C->getDiagnostics()));
llvm::OwningPtr<clang::CodeGen::CodeGenTypes> CGT(
new clang::CodeGen::CodeGenTypes(*CGM.get()));
CodeGenInfo = (clang::TargetCodeGenInfo*) &CGM->getTargetCodeGenInfo();
CodeGenTypes = CGT.get();
WalkAST(); WalkAST();
res->Kind = ParserResultKind::Success; res->Kind = ParserResultKind::Success;

9
src/Parser/Parser.h

@ -25,6 +25,13 @@
#include <clang/Sema/Sema.h> #include <clang/Sema/Sema.h>
#include "CXXABI.h" #include "CXXABI.h"
namespace clang {
class TargetCodeGenInfo;
namespace CodeGen {
class CodeGenTypes;
}
}
#include <string> #include <string>
#include <cstdarg> #include <cstdarg>
@ -185,6 +192,8 @@ protected:
llvm::OwningPtr<clang::CompilerInstance> C; llvm::OwningPtr<clang::CompilerInstance> C;
clang::ASTContext* AST; clang::ASTContext* AST;
clang::TargetCXXABI::Kind TargetABI; clang::TargetCXXABI::Kind TargetABI;
clang::TargetCodeGenInfo* CodeGenInfo;
clang::CodeGen::CodeGenTypes* CodeGenTypes;
}; };
//-----------------------------------// //-----------------------------------//

16
src/Parser/Parser.lua

@ -47,6 +47,7 @@ project "CppSharp.Parser"
"../../deps/LLVM/include", "../../deps/LLVM/include",
"../../deps/LLVM/build/include", "../../deps/LLVM/build/include",
"../../deps/LLVM/tools/clang/include", "../../deps/LLVM/tools/clang/include",
"../../deps/LLVM/tools/clang/lib",
"../../deps/LLVM/build/tools/clang/include" "../../deps/LLVM/build/tools/clang/include"
} }
@ -63,6 +64,7 @@ project "CppSharp.Parser"
"clangAnalysis", "clangAnalysis",
"clangAST", "clangAST",
"clangBasic", "clangBasic",
"clangCodeGen",
"clangDriver", "clangDriver",
"clangEdit", "clangEdit",
"clangFrontend", "clangFrontend",
@ -70,14 +72,28 @@ project "CppSharp.Parser"
"clangParse", "clangParse",
"clangSema", "clangSema",
"clangSerialization", "clangSerialization",
"LLVMAnalysis",
"LLVMAsmParser", "LLVMAsmParser",
"LLVMBitReader", "LLVMBitReader",
"LLVMBitWriter", "LLVMBitWriter",
"LLVMCodeGen",
"LLVMCore",
"LLVMipa",
"LLVMipo",
"LLVMInstCombine",
"LLVMInstrumentation",
"LLVMIRReader",
"LLVMLinker",
"LLVMMC", "LLVMMC",
"LLVMMCParser", "LLVMMCParser",
"LLVMObjCARCOpts",
"LLVMObject", "LLVMObject",
"LLVMOption", "LLVMOption",
"LLVMScalarOpts",
"LLVMSupport", "LLVMSupport",
"LLVMTarget",
"LLVMTransformUtils",
"LLVMVectorize",
"LLVMX86AsmParser", "LLVMX86AsmParser",
"LLVMX86AsmPrinter", "LLVMX86AsmPrinter",
"LLVMX86Desc", "LLVMX86Desc",

Loading…
Cancel
Save