//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These classes wrap the information about a call or function
// definition used to handle ABI compliancy.
//
//===----------------------------------------------------------------------===//
#include "CGCall.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Frontend/CompileOptions.h"
#include "llvm/Attributes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Target/TargetData.h"
#include "ABIInfo.h"
using namespace clang;
using namespace CodeGen;
/***/
// FIXME: Use iterator and sidestep silly type array creation.
const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
return getFunctionInfo(FTNP->getResultType(),
llvm::SmallVector<QualType, 16>());
}
const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
llvm::SmallVector<QualType, 16> ArgTys;
// FIXME: Kill copy.
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
return getFunctionInfo(FTP->getResultType(), ArgTys);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
llvm::SmallVector<QualType, 16> ArgTys;
// Add the 'this' pointer unless this is a static method.
if (MD->isInstance())
ArgTys.push_back(MD->getThisType(Context));
const FunctionProtoType *FTP = MD->getType()->getAsFunctionProtoType();
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
ArgTys.push_back(FTP->getArgType(i));
return getFunctionInfo(FTP->getResultType(), ArgTys);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
if (MD->isInstance())
return getFunctionInfo(MD);
const FunctionType *FTy = FD->getType()->getAsFunctionType();
if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FTy))
return getFunctionInfo(FTP);
return getFunctionInfo(cast<FunctionNoProtoType>(FTy));
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
llvm::SmallVector<QualType, 16> ArgTys;
ArgTys.push_back(MD->getSelfDecl()->getType());
ArgTys.push_back(Context.getObjCSelType());
// FIXME: Kill copy?
for (ObjCMethodDecl::param_iterator i = MD->param_begin(),
e = MD->param_end(); i != e; ++i)
ArgTys.push_back((*i)->getType());
return getFunctionInfo(MD->getResultType(), ArgTys);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
const CallArgList &Args) {
// FIXME: Kill copy.
llvm::SmallVector<QualType, 16> ArgTys;
for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
ArgTys.push_back(i->second);
return getFunctionInfo(ResTy, ArgTys);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
const FunctionArgList &Args) {
// FIXME: Kill copy.
llvm::SmallVector<QualType, 16> ArgTys;
for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
ArgTys.push_back(i->second);
return getFunctionInfo(ResTy, ArgTys);
}
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
const llvm::SmallVector<QualType, 16> &ArgTys) {
// Lookup or create unique function info.
llvm::FoldingSetNodeID ID;
CGFunctionInfo::Profile(ID, ResTy, ArgTys.begin(), ArgTys.end());
void *InsertPos = 0;
CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos);
if (FI)
return *FI;
// Construct the function info.
FI = new CGFunctionInfo(ResTy, ArgTys);
FunctionInfos.InsertNode(FI, InsertPos);
// Compute ABI information.
getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext());
return *FI;
}
CGFunctionInfo::CGFunctionInfo(QualType ResTy,
const llvm::SmallVector<QualType, 16> &ArgTys) {
NumArgs = ArgTys.size();
Args = new ArgInfo[1 + NumArgs];
Args[0].type = ResTy;
for (unsigned i = 0; i <