some cleanups on top of David's patch. There are still two

remaining open issues I've communicated to him:

1) self can be assigned to, and his patch didn't handle it correctly.
2) CollectObjCIvarTypes is N^2 (because each subclass reprocesses
   all parent class ivars) and flattens classes.  If A derives from B, 
   and both have an int, I'd expect to get { {i32}, i32}, not { i32, i32}.

David, please review.

llvm-svn: 48970
This commit is contained in:
Chris Lattner 2008-03-30 23:25:33 +00:00
parent 4bd5596d08
commit c00c35a857
5 changed files with 46 additions and 64 deletions

View File

@ -566,32 +566,27 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
// a class without recompiling all of the subclasses. If this is the case // a class without recompiling all of the subclasses. If this is the case
// then the CGObjCRuntime subclass must return true to LateBoundIvars and // then the CGObjCRuntime subclass must return true to LateBoundIvars and
// implement the lookup itself. // implement the lookup itself.
if(CGM.getObjCRuntime()->LateBoundIVars()) { if (CGM.getObjCRuntime()->LateBoundIVars()) {
assert(0 && "FIXME: Implement support for late-bound instance variables"); assert(0 && "FIXME: Implement support for late-bound instance variables");
return LValue(); // Not reached. return LValue(); // Not reached.
} }
else {
// Get a structure type for the object // Get a structure type for the object
QualType ExprTy = E->getBase()->getType(); QualType ExprTy = E->getBase()->getType();
const llvm::Type *ObjectType = ConvertType(ExprTy); const llvm::Type *ObjectType = ConvertType(ExprTy);
//TODO: Add a special case for isa (index 0) // TODO: Add a special case for isa (index 0)
// Work out which index the ivar is // Work out which index the ivar is
const ObjCIvarDecl *Decl = E->getDecl(); const ObjCIvarDecl *Decl = E->getDecl();
unsigned Index = CGM.getTypes().getLLVMFieldNo(Decl); unsigned Index = CGM.getTypes().getLLVMFieldNo(Decl);
// Get object pointer // Get object pointer and coerce object pointer to correct type.
llvm::Value * Object = EmitLValue(E->getBase()).getAddress(); llvm::Value *Object = EmitLValue(E->getBase()).getAddress();
// Coerce object pointer to correct type. if (Object->getType() != ObjectType)
if (Object->getType() != ObjectType) {
Object = Builder.CreateBitCast(Object, ObjectType); Object = Builder.CreateBitCast(Object, ObjectType);
}
// Get the correct element // Return a pointer to the right element.
llvm::Value * Element = Builder.CreateStructGEP(Object, return LValue::MakeAddr(Builder.CreateStructGEP(Object, Index,
Index, Decl->getName()));
Decl->getName());
// Element = Builder.CreateLoad(Element);
return LValue::MakeAddr(Element);
}
} }
RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,

View File

@ -19,7 +19,6 @@
#include "llvm/GlobalVariable.h" #include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h" #include "llvm/Intrinsics.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/ValueSymbolTable.h"
#include <cstdarg> #include <cstdarg>
using namespace clang; using namespace clang;
@ -52,7 +51,6 @@ public:
Runtime(CGF.CGM.getObjCRuntime()) { Runtime(CGF.CGM.getObjCRuntime()) {
} }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Utilities // Utilities
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -127,7 +125,7 @@ public:
return EmitLoadOfLValue(E); return EmitLoadOfLValue(E);
} }
Value *VisitObjCMessageExpr(ObjCMessageExpr *E); Value *VisitObjCMessageExpr(ObjCMessageExpr *E);
Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E); Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);}
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E); Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); } Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
Value *VisitOCUVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); } Value *VisitOCUVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
@ -451,22 +449,18 @@ Value *ScalarExprEmitter::VisitExpr(Expr *E) {
return llvm::UndefValue::get(CGF.ConvertType(E->getType())); return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
} }
Value *ScalarExprEmitter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
return Builder.CreateLoad(CGF.EmitObjCIvarRefLValue(E).getAddress());
}
Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) { Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
// Only the lookup mechanism and first two arguments of the method // Only the lookup mechanism and first two arguments of the method
// implementation vary between runtimes. We can get the receiver and // implementation vary between runtimes. We can get the receiver and
// arguments in generic code. // arguments in generic code.
// Find the receiver // Find the receiver
llvm::Value * Receiver = CGF.EmitScalarExpr(E->getReceiver()); llvm::Value *Receiver = CGF.EmitScalarExpr(E->getReceiver());
// Process the arguments // Process the arguments
unsigned int ArgC = E->getNumArgs(); unsigned ArgC = E->getNumArgs();
llvm::SmallVector<llvm::Value*, 16> Args; llvm::SmallVector<llvm::Value*, 16> Args;
for(unsigned i=0 ; i<ArgC ; i++) { for (unsigned i = 0; i != ArgC; ++i) {
Expr *ArgExpr = E->getArg(i); Expr *ArgExpr = E->getArg(i);
QualType ArgTy = ArgExpr->getType(); QualType ArgTy = ArgExpr->getType();
if (!CGF.hasAggregateLLVMType(ArgTy)) { if (!CGF.hasAggregateLLVMType(ArgTy)) {
@ -489,13 +483,11 @@ Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
llvm::Constant *Selector = CGF.CGM.GetAddrOfConstantString(SelStr); llvm::Constant *Selector = CGF.CGM.GetAddrOfConstantString(SelStr);
llvm::Value *SelPtr = Builder.CreateStructGEP(Selector, 0); llvm::Value *SelPtr = Builder.CreateStructGEP(Selector, 0);
return Runtime->generateMessageSend(Builder, return Runtime->generateMessageSend(Builder, ConvertType(E->getType()),
ConvertType(E->getType()), // FIXME: Self can be assigned to!
CGF.CurFn->getValueSymbolTable().lookup("self"), CGF.CurFn->arg_begin(),
Receiver, Receiver, SelPtr,
SelPtr, &Args[0], Args.size());
&Args[0],
Args.size());
} }
Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {

View File

@ -64,7 +64,7 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
for (unsigned i=0 ; i<OMD->param_size() ; i++) { for (unsigned i=0 ; i<OMD->param_size() ; i++) {
ParamTypes.push_back(ConvertType(OMD->getParamDecl(i)->getType())); ParamTypes.push_back(ConvertType(OMD->getParamDecl(i)->getType()));
} }
CurFn = CGM.getObjCRuntime()->MethodPreamble(ConvertType(OMD->getResultType()), CurFn =CGM.getObjCRuntime()->MethodPreamble(ConvertType(OMD->getResultType()),
llvm::PointerType::getUnqual(llvm::Type::Int32Ty), llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
ParamTypes.begin(), ParamTypes.begin(),
OMD->param_size(), OMD->param_size(),

View File

@ -41,9 +41,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
CodeGenModule::~CodeGenModule() { CodeGenModule::~CodeGenModule() {
llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction(); llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction();
if (ObjCInitFunction) { if (ObjCInitFunction)
AddGlobalCtor(ObjCInitFunction); AddGlobalCtor(ObjCInitFunction);
}
EmitGlobalCtors(); EmitGlobalCtors();
delete Runtime; delete Runtime;
} }
@ -80,15 +79,15 @@ void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor) {
/// called on module load, if any have been registered with AddGlobalCtor. /// called on module load, if any have been registered with AddGlobalCtor.
void CodeGenModule::EmitGlobalCtors() { void CodeGenModule::EmitGlobalCtors() {
if (GlobalCtors.empty()) return; if (GlobalCtors.empty()) return;
// Get the type of @llvm.global_ctors // Get the type of @llvm.global_ctors
std::vector<const llvm::Type*> CtorFields; std::vector<const llvm::Type*> CtorFields;
CtorFields.push_back(llvm::IntegerType::get(32)); CtorFields.push_back(llvm::IntegerType::get(32));
// Constructor function type // Constructor function type
std::vector<const llvm::Type*> VoidArgs; std::vector<const llvm::Type*> VoidArgs;
llvm::FunctionType* CtorFuncTy = llvm::FunctionType::get( llvm::FunctionType* CtorFuncTy =
llvm::Type::VoidTy, llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false);
VoidArgs,
false);
// i32, function type pair // i32, function type pair
const llvm::Type *FPType = llvm::PointerType::getUnqual(CtorFuncTy); const llvm::Type *FPType = llvm::PointerType::getUnqual(CtorFuncTy);
llvm::StructType* CtorStructTy = llvm::StructType* CtorStructTy =
@ -120,7 +119,6 @@ void CodeGenModule::EmitGlobalCtors() {
GlobalCtorsVal->setInitializer(llvm::ConstantArray::get(GlobalCtorsTy, GlobalCtorsVal->setInitializer(llvm::ConstantArray::get(GlobalCtorsTy,
CtorValues)); CtorValues));
} }

View File

@ -150,14 +150,12 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass, void CodeGenTypes::CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
std::vector<const llvm::Type*> &IvarTypes) { std::vector<const llvm::Type*> &IvarTypes) {
ObjCInterfaceDecl *SuperClass = ObjCClass->getSuperClass(); ObjCInterfaceDecl *SuperClass = ObjCClass->getSuperClass();
if(SuperClass) { if (SuperClass)
CollectObjCIvarTypes(SuperClass, IvarTypes); CollectObjCIvarTypes(SuperClass, IvarTypes);
} for (ObjCInterfaceDecl::ivar_iterator I = ObjCClass->ivar_begin(),
for(ObjCInterfaceDecl::ivar_iterator ivar=ObjCClass->ivar_begin() ; E = ObjCClass->ivar_end(); I != E; ++I) {
ivar != ObjCClass->ivar_end() ; IvarTypes.push_back(ConvertType((*I)->getType()));
ivar++) { ObjCIvarInfo[*I] = IvarTypes.size() - 1;
IvarTypes.push_back(ConvertType((*ivar)->getType()));
ObjCIvarInfo[*ivar] = IvarTypes.size() - 1;
} }
} }
@ -420,8 +418,7 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
/// getLLVMFieldNo - Return llvm::StructType element number /// getLLVMFieldNo - Return llvm::StructType element number
/// that corresponds to the field FD. /// that corresponds to the field FD.
unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) { unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
llvm::DenseMap<const FieldDecl *, unsigned>::iterator llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD);
I = FieldInfo.find(FD);
assert (I != FieldInfo.end() && "Unable to find field info"); assert (I != FieldInfo.end() && "Unable to find field info");
return I->second; return I->second;
} }
@ -429,7 +426,7 @@ unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
unsigned CodeGenTypes::getLLVMFieldNo(const ObjCIvarDecl *OID) { unsigned CodeGenTypes::getLLVMFieldNo(const ObjCIvarDecl *OID) {
llvm::DenseMap<const ObjCIvarDecl*, unsigned>::iterator llvm::DenseMap<const ObjCIvarDecl*, unsigned>::iterator
I = ObjCIvarInfo.find(OID); I = ObjCIvarInfo.find(OID);
assert (I != ObjCIvarInfo.end() && "Unable to find field info"); assert(I != ObjCIvarInfo.end() && "Unable to find field info");
return I->second; return I->second;
} }