Change self/_cmd to be instances of ImplicitParamDecl instead of ParmVarDecl.

Patch by David Chisnall!

llvm-svn: 52422
This commit is contained in:
Chris Lattner 2008-06-17 18:05:57 +00:00
parent 5e4188f1ac
commit 5696e7badf
19 changed files with 230 additions and 188 deletions

View File

@ -1975,9 +1975,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
llvm::SmallVector<Expr*, 4> InitExprs;
// set the receiver to self, the first argument to all methods.
InitExprs.push_back(new DeclRefExpr(CurMethodDecl->getSelfDecl(),
Context->getObjCIdType(),
SourceLocation()));
InitExprs.push_back(new DeclRefExpr(
CurMethodDecl->getSelfDecl(),
Context->getObjCIdType(),
SourceLocation()));
llvm::SmallVector<Expr*, 8> ClsExprs;
QualType argType = Context->getPointerType(Context->CharTy);
ClsExprs.push_back(new StringLiteral(SuperDecl->getIdentifier()->getName(),

View File

@ -308,6 +308,20 @@ protected:
static VarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
};
class ImplicitParamDecl : public VarDecl {
protected:
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
: VarDecl(DK, DC, L, Id, T, VarDecl::None, PrevDecl) {}
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, ScopedDecl *PrevDecl);
// Implement isa/cast/dyncast/etc.
static bool classof(const ImplicitParamDecl *D) { return true; }
static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; }
};
/// ParmVarDecl - Represent a parameter to a function.
class ParmVarDecl : public VarDecl {
// NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum

View File

@ -69,6 +69,7 @@ public:
Function, // [DeclContext]
CXXMethod,
Var,
ImplicitParam,
CXXClassVar,
ParmVar,
ObjCInterface, // [DeclContext]
@ -172,6 +173,7 @@ public:
IdentifierNamespace getIdentifierNamespace() const {
switch (DeclKind) {
default: assert(0 && "Unknown decl kind!");
case ImplicitParam:
case Typedef:
case Function:
case Var:

View File

@ -91,7 +91,9 @@ private:
// The following are only used for method definitions, null otherwise.
// FIXME: space savings opportunity, consider a sub-class.
Stmt *Body;
ParmVarDecl *SelfDecl;
// Decls for implicit parameters
ImplicitParamDecl *SelfDecl;
ImplicitParamDecl *CmdDecl;
ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
Selector SelInfo, QualType T,
@ -107,8 +109,8 @@ private:
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
MethodContext(static_cast<NamedDecl*>(contextDecl)),
SelName(SelInfo), MethodDeclType(T),
ParamInfo(0), NumMethodParams(0),
MethodAttrs(M), EndLoc(endLoc), Body(0), SelfDecl(0) {}
ParamInfo(0), NumMethodParams(0), MethodAttrs(M),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
virtual ~ObjCMethodDecl();
@ -164,6 +166,11 @@ public:
ParamInfo[i] = pDecl;
}
void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
void setSelfDecl(ImplicitParamDecl *decl) { SelfDecl = decl; }
ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
void setCmdDecl(ImplicitParamDecl *decl) { CmdDecl = decl; }
AttributeList *getMethodAttrs() const {return MethodAttrs;}
bool isInstance() const { return IsInstance; }
@ -182,10 +189,6 @@ public:
const Stmt *getBody() const { return Body; }
void setBody(Stmt *B) { Body = B; }
const ParmVarDecl *getSelfDecl() const { return SelfDecl; }
ParmVarDecl *getSelfDecl() { return SelfDecl; }
void setSelfDecl(ParmVarDecl *PVD) { SelfDecl = PVD; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
static bool classof(const ObjCMethodDecl *D) { return true; }

View File

@ -56,6 +56,7 @@ public:
DISPATCH_CASE(Function,FunctionDecl)
DISPATCH_CASE(Var,VarDecl)
DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same)
DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
DISPATCH_CASE(EnumConstant,EnumConstantDecl)
DISPATCH_CASE(Typedef,TypedefDecl)
DISPATCH_CASE(Struct,RecordDecl) // FIXME: Refine. VisitStructDecl?
@ -70,6 +71,7 @@ public:
DEFAULT_DISPATCH(VarDecl)
DEFAULT_DISPATCH(FunctionDecl)
DEFAULT_DISPATCH_VARDECL(ParmVarDecl)
DEFAULT_DISPATCH(ImplicitParamDecl)
DEFAULT_DISPATCH(EnumConstantDecl)
DEFAULT_DISPATCH(TypedefDecl)
DEFAULT_DISPATCH(RecordDecl)

View File

@ -40,6 +40,12 @@ void NamespaceDecl::Destroy(ASTContext& C) {
}
ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<ImplicitParamDecl>();
return new (Mem) ImplicitParamDecl(ImplicitParam, DC, L, Id, T, PrevDecl);
}
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id, QualType T,

View File

@ -206,6 +206,7 @@ void Decl::addDeclKind(Kind k) {
case ObjCPropertyImpl: nObjCPropertyImplDecl++; break;
case LinkageSpec: nLinkageSpecDecl++; break;
case FileScopeAsm: nFileScopeAsmDecl++; break;
case ImplicitParam:
case TranslationUnit: break;
// FIXME: Statistics for C++ decls.

View File

@ -389,10 +389,12 @@ Expr::isLvalueResult Expr::isLvalue() const {
if (cast<ArraySubscriptExpr>(this)->getBase()->getType()->isVectorType())
return cast<ArraySubscriptExpr>(this)->getBase()->isLvalue();
return LV_Valid;
case DeclRefExprClass: // C99 6.5.1p2
if (isa<VarDecl>(cast<DeclRefExpr>(this)->getDecl()))
case DeclRefExprClass: { // C99 6.5.1p2
const Decl *RefdDecl = cast<DeclRefExpr>(this)->getDecl();
if (isa<VarDecl>(RefdDecl) || isa<ImplicitParamDecl>(RefdDecl))
return LV_Valid;
break;
}
case MemberExprClass: { // C99 6.5.2.3p4
const MemberExpr *m = cast<MemberExpr>(this);
return m->isArrow() ? LV_Valid : m->getBase()->isLvalue();

View File

@ -144,12 +144,18 @@ ValueState* GRExprEngine::getInitialState() {
for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
VarDecl* VD = cast<VarDecl>(const_cast<ScopedDecl*>(I->first));
if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
RVal X = RVal::GetSymbolValue(SymMgr, VD);
StateMgr.BindVar(StateImpl, VD, X);
ScopedDecl *SD = const_cast<ScopedDecl*>(I->first);
if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
RVal X = RVal::GetSymbolValue(SymMgr, VD);
StateMgr.BindVar(StateImpl, VD, X);
}
} else if (ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(SD)) {
RVal X = RVal::GetSymbolValue(SymMgr, IPD);
StateMgr.BindVar(StateImpl, IPD, X);
}
}
return StateMgr.getPersistentState(StateImpl);

View File

@ -60,6 +60,11 @@ public:
AD.AlwaysLive(*I, AD) = Alive;
}
void VisitImplicitParamDecl(ImplicitParamDecl* IPD) {
// Register the VarDecl for tracking.
AD.Register(IPD);
}
void VisitVarDecl(VarDecl* VD) {
// Register the VarDecl for tracking.
AD.Register(VD);

View File

@ -370,7 +370,8 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD))) {
if (VD && (VD->isBlockVarDecl() || isa<ParmVarDecl>(VD) ||
isa<ImplicitParamDecl>(VD))) {
if (VD->getStorageClass() == VarDecl::Extern)
return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false),
E->getType().getCVRQualifiers());
@ -386,6 +387,12 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false),
E->getType().getCVRQualifiers());
}
else if (const ImplicitParamDecl *IPD =
dyn_cast<ImplicitParamDecl>(E->getDecl())) {
llvm::Value *V = LocalDeclMap[IPD];
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
return LValue::MakeAddr(V, E->getType().getCVRQualifiers());
}
assert(0 && "Unimp declref");
//an invalid LValue, but the assert will
//ensure that this point is never reached.

View File

@ -16,6 +16,8 @@
#include "CodeGenModule.h"
#include "clang/AST/ExprObjC.h"
#include "llvm/Constant.h"
#include "llvm/Function.h"
using namespace clang;
using namespace CodeGen;
@ -24,4 +26,91 @@ llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
return CGM.GetAddrOfConstantCFString(S);
}
/// Generate an Objective-C method. An Objective-C method is a C function with
/// its pointer, name, and types registered in the class struture.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
for (unsigned i=0 ; i<OMD->param_size() ; i++) {
const llvm::Type *Ty = ConvertType(OMD->getParamDecl(i)->getType());
if (Ty->isFirstClassType())
ParamTypes.push_back(Ty);
else
ParamTypes.push_back(llvm::PointerType::getUnqual(Ty));
}
std::string CategoryName = "";
if (ObjCCategoryImplDecl *OCD =
dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
CategoryName = OCD->getName();
}
const llvm::Type *ReturnTy = CGM.getTypes().ConvertReturnType(OMD->getResultType());
CurFn = CGM.getObjCRuntime()->MethodPreamble(
OMD->getClassInterface()->getName(),
CategoryName,
OMD->getSelector().getName(),
ReturnTy,
llvm::PointerType::getUnqual(
llvm::Type::Int32Ty),
ParamTypes.begin(),
OMD->param_size(),
!OMD->isInstance(),
OMD->isVariadic());
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
// Create a marker to make it easy to insert allocas into the entryblock
// later. Don't create this with the builder, because we don't want it
// folded.
llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
EntryBB);
FnRetTy = OMD->getResultType();
CurFuncDecl = OMD;
Builder.SetInsertPoint(EntryBB);
// Emit allocs for param decls. Give the LLVM Argument nodes names.
llvm::Function::arg_iterator AI = CurFn->arg_begin();
if (hasAggregateLLVMType(OMD->getResultType())) {
++AI;
}
// Add implicit parameters to the decl map.
// TODO: Add something to AST to let the runtime specify the names and types
// of these.
llvm::Value *&SelfEntry = LocalDeclMap[OMD->getSelfDecl()];
const llvm::Type *IPTy = AI->getType();
llvm::Value *DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
".addr", AllocaInsertPt);
// Store the initial value into the alloca.
Builder.CreateStore(AI, DeclPtr);
SelfEntry = DeclPtr;
++AI;
llvm::Value *&CmdEntry = LocalDeclMap[OMD->getCmdDecl()];
IPTy = AI->getType();
DeclPtr = new llvm::AllocaInst(IPTy, 0, AI->getName() +
".addr", AllocaInsertPt);
// Store the initial value into the alloca.
Builder.CreateStore(AI, DeclPtr);
CmdEntry = DeclPtr;
for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
assert(AI != CurFn->arg_end() && "Argument mismatch!");
EmitParmDecl(*OMD->getParamDecl(i), AI);
}
GenerateFunction(OMD->getBody());
}
llvm::Value *CodeGenFunction::LoadObjCSelf(void)
{
if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
ValueDecl *Decl = OMD->getSelfDecl();
llvm::Value *SelfPtr = LocalDeclMap[&(*(Decl))];
return Builder.CreateLoad(SelfPtr, "self");
}
return NULL;
}
CGObjCRuntime::~CGObjCRuntime() {}

View File

@ -27,7 +27,10 @@ using namespace CodeGen;
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
: CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
CaseRangeBlock(NULL) {}
CaseRangeBlock(NULL) {
LLVMIntTy = ConvertType(getContext().IntTy);
LLVMPointerWidth = Target.getPointerWidth(0);
}
ASTContext &CodeGenFunction::getContext() const {
return CGM.getContext();
@ -51,170 +54,21 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
return CGM.getTypes().ConvertType(T);
}
bool CodeGenFunction::isObjCPointerType(QualType T) {
// All Objective-C types are pointers.
return T->isObjCInterfaceType() ||
T->isObjCQualifiedInterfaceType() || T->isObjCQualifiedIdType();
}
bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
return !T->isRealType() && !T->isPointerLikeType() &&
!T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
return !isObjCPointerType(T) &&!T->isRealType() && !T->isPointerLikeType() &&
!T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
}
/// Generate an Objective-C method. An Objective-C method is a C function with
/// its pointer, name, and types registered in the class struture.
// FIXME: This method contains a lot of code copied and pasted from
// GenerateCode. This should be factored out.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
llvm::SmallVector<const llvm::Type *, 16> ParamTypes;
for (unsigned i=0 ; i<OMD->param_size() ; i++) {
ParamTypes.push_back(ConvertType(OMD->getParamDecl(i)->getType()));
}
std::string CategoryName = "";
if (ObjCCategoryImplDecl *OCD =
dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
CategoryName = OCD->getName();
}
CurFn =CGM.getObjCRuntime()->MethodPreamble(
OMD->getClassInterface()->getName(),
CategoryName,
OMD->getSelector().getName(),
ConvertType(OMD->getResultType()),
llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
ParamTypes.begin(),
OMD->param_size(),
!OMD->isInstance(),
OMD->isVariadic());
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
// Create a marker to make it easy to insert allocas into the entryblock
// later. Don't create this with the builder, because we don't want it
// folded.
llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
EntryBB);
FnRetTy = OMD->getResultType();
Builder.SetInsertPoint(EntryBB);
// Emit allocs for param decls. Give the LLVM Argument nodes names.
llvm::Function::arg_iterator AI = CurFn->arg_begin();
// Name the struct return argument.
// FIXME: Probably should be in the runtime, or it will trample the other
// hidden arguments.
if (hasAggregateLLVMType(OMD->getResultType())) {
AI->setName("agg.result");
++AI;
}
// Add implicit parameters to the decl map.
// TODO: Add something to AST to let the runtime specify the names and types
// of these.
llvm::Value *&DMEntry = LocalDeclMap[&(*OMD->getSelfDecl())];
const llvm::Type *SelfTy = AI->getType();
llvm::Value *DeclPtr = new llvm::AllocaInst(SelfTy, 0, "self.addr",
AllocaInsertPt);
// Store the initial value into the alloca.
// FIXME: volatility
Builder.CreateStore(AI, DeclPtr);
DMEntry = DeclPtr;
++AI; ++AI;
for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
assert(AI != CurFn->arg_end() && "Argument mismatch!");
EmitParmDecl(*OMD->getParamDecl(i), AI);
}
void CodeGenFunction::GenerateFunction(const Stmt *Body) {
// Emit the function body.
EmitStmt(OMD->getBody());
EmitStmt(Body);
// Emit a return for code that falls off the end. If insert point
// is a dummy block with no predecessors then remove the block itself.
llvm::BasicBlock *BB = Builder.GetInsertBlock();
if (isDummyBlock(BB))
BB->eraseFromParent();
else {
if (CurFn->getReturnType() == llvm::Type::VoidTy)
Builder.CreateRetVoid();
else
Builder.CreateRet(llvm::UndefValue::get(CurFn->getReturnType()));
}
assert(BreakContinueStack.empty() &&
"mismatched push/pop in break/continue stack!");
// Remove the AllocaInsertPt instruction, which is just a convenience for us.
AllocaInsertPt->eraseFromParent();
AllocaInsertPt = 0;
// Verify that the function is well formed.
assert(!verifyFunction(*CurFn) && "Generated method is not well formed.");
}
llvm::Value *CodeGenFunction::LoadObjCSelf(void)
{
if(const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurFuncDecl)) {
llvm::Value *SelfPtr = LocalDeclMap[&(*OMD->getSelfDecl())];
// FIXME: Volatility
return Builder.CreateLoad(SelfPtr, "self");
}
return NULL;
}
void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
LLVMIntTy = ConvertType(getContext().IntTy);
LLVMPointerWidth = static_cast<unsigned>(
getContext().getTypeSize(getContext().getPointerType(getContext().VoidTy)));
CurFuncDecl = FD;
FnRetTy = FD->getType()->getAsFunctionType()->getResultType();
CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
assert(CurFn->isDeclaration() && "Function already has body?");
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
// Create a marker to make it easy to insert allocas into the entryblock
// later. Don't create this with the builder, because we don't want it
// folded.
llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
EntryBB);
Builder.SetInsertPoint(EntryBB);
CGDebugInfo *DI = CGM.getDebugInfo();
if (DI) {
CompoundStmt* body = cast<CompoundStmt>(CurFuncDecl->getBody());
if (body->getLBracLoc().isValid()) {
DI->setLocation(body->getLBracLoc());
}
DI->EmitFunctionStart(FD, CurFn, Builder);
}
// Emit allocs for param decls. Give the LLVM Argument nodes names.
llvm::Function::arg_iterator AI = CurFn->arg_begin();
// Name the struct return argument.
if (hasAggregateLLVMType(FD->getResultType())) {
AI->setName("agg.result");
++AI;
}
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
assert(AI != CurFn->arg_end() && "Argument mismatch!");
EmitParmDecl(*FD->getParamDecl(i), AI);
}
// Emit the function body.
EmitStmt(FD->getBody());
if (DI) {
CompoundStmt* body = cast<CompoundStmt>(CurFuncDecl->getBody());
if (body->getRBracLoc().isValid()) {
DI->setLocation(body->getRBracLoc());
}
DI->EmitRegionEnd(CurFn, Builder);
}
// Emit a return for code that falls off the end. If insert point
// is a dummy block with no predecessors then remove the block itself.
llvm::BasicBlock *BB = Builder.GetInsertBlock();
@ -238,6 +92,39 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
assert(!verifyFunction(*CurFn) && "Generated function is not well formed.");
}
void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
CurFuncDecl = FD;
FnRetTy = FD->getResultType();
CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
assert(CurFn->isDeclaration() && "Function already has body?");
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
// Create a marker to make it easy to insert allocas into the entryblock
// later. Don't create this with the builder, because we don't want it
// folded.
llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
EntryBB);
Builder.SetInsertPoint(EntryBB);
// Emit allocs for param decls. Give the LLVM Argument nodes names.
llvm::Function::arg_iterator AI = CurFn->arg_begin();
// Name the struct return argument.
if (hasAggregateLLVMType(FD->getResultType())) {
AI->setName("agg.result");
++AI;
}
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
assert(AI != CurFn->arg_end() && "Argument mismatch!");
EmitParmDecl(*FD->getParamDecl(i), AI);
}
GenerateFunction(FD->getBody());
}
/// isDummyBlock - Return true if BB is an empty basic block
/// with no predecessors.
bool CodeGenFunction::isDummyBlock(const llvm::BasicBlock *BB) {

View File

@ -232,7 +232,7 @@ public:
llvm::IRBuilder Builder;
// Holds the Decl for the current function or method
const FunctionDecl *CurFuncDecl;
const Decl *CurFuncDecl;
QualType FnRetTy;
llvm::Function *CurFn;
@ -277,11 +277,16 @@ public:
void GenerateObjCMethod(const ObjCMethodDecl *OMD);
void GenerateCode(const FunctionDecl *FD);
void GenerateFunction(const Stmt *Body);
const llvm::Type *ConvertType(QualType T);
llvm::Value *LoadObjCSelf();
/// isObjCPointerType - Return true if the specificed AST type will map onto
/// some Objective-C pointer type.
static bool isObjCPointerType(QualType T);
/// hasAggregateLLVMType - Return true if the specified AST type will map into
/// an aggregate LLVM type or is void.
static bool hasAggregateLLVMType(QualType T);

View File

@ -161,6 +161,13 @@ void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
}
}
const llvm::Type *CodeGenTypes::ConvertReturnType(QualType T) {
if (T->isVoidType())
return llvm::Type::VoidTy; // Result of function uses llvm void.
else
return ConvertType(T);
}
static const llvm::Type* getTypeForFormat(const llvm::fltSemantics * format) {
if (format == &llvm::APFloat::IEEEsingle)
return llvm::Type::FloatTy;

View File

@ -132,6 +132,9 @@ public:
/// ConvertType - Convert type T into a llvm::Type.
const llvm::Type *ConvertType(QualType T);
const llvm::Type *ConvertTypeRecursive(QualType T);
/// ConvertReturnType - Convert T into an llvm::Type assuming that it will be
/// used as a function return type.
const llvm::Type *ConvertReturnType(QualType T);
/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
/// ConvertType in that it is used to convert to the memory representation for
@ -143,6 +146,8 @@ public:
std::vector<const llvm::Type*> &IvarTypes);
const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
/// Returns a StructType representing an Objective-C object
const llvm::Type *ConvertObjCInterfaceToStruct(const ObjCInterfaceDecl *OID);
/// getLLVMFieldNo - Return llvm::StructType element number
/// that corresponds to the field FD.

View File

@ -277,7 +277,7 @@ private:
/// Helpers for dealing with function parameters
bool CheckParmsForFunctionDef(FunctionDecl *FD);
ParmVarDecl *CreateImplicitParameter(Scope *S, IdentifierInfo *Id,
ImplicitParamDecl *CreateImplicitParameter(Scope *S, IdentifierInfo *Id,
SourceLocation IdLoc, QualType Type);
void CheckCXXDefaultArguments(FunctionDecl *FD);
void CheckExtraCXXDefaultArguments(Declarator &D);

View File

@ -480,11 +480,11 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
/// in the scope S and with the given type. This routine is used, for
/// example, to create the implicit "self" parameter in an Objective-C
/// method.
ParmVarDecl *
ImplicitParamDecl *
Sema::CreateImplicitParameter(Scope *S, IdentifierInfo *Id,
SourceLocation IdLoc, QualType Type) {
ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, IdLoc, Id, Type,
VarDecl::None, 0, 0);
ImplicitParamDecl *New = ImplicitParamDecl::Create(Context, CurContext,
IdLoc, Id, Type, 0);
if (Id)
PushOnScopeChains(New, S);

View File

@ -53,12 +53,12 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
}
} else // we have a factory method.
selfTy = Context.getObjCClassType();
CurMethodDecl->setSelfDecl(CreateImplicitParameter(FnBodyScope, PI.Ident,
PI.IdentLoc, selfTy));
CurMethodDecl->setSelfDecl(CreateImplicitParameter(FnBodyScope,
PI.Ident, PI.IdentLoc, selfTy));
PI.Ident = &Context.Idents.get("_cmd");
CreateImplicitParameter(FnBodyScope, PI.Ident, PI.IdentLoc,
Context.getObjCSelType());
CurMethodDecl->setCmdDecl(CreateImplicitParameter(FnBodyScope,
PI.Ident, PI.IdentLoc, Context.getObjCSelType()));
// Introduce all of the other parameters into this scope.
for (unsigned i = 0, e = MDecl->getNumParams(); i != e; ++i) {