forked from OSchip/llvm-project
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:
parent
4bd5596d08
commit
c00c35a857
|
@ -82,7 +82,7 @@ RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
|
||||||
LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
||||||
switch (E->getStmtClass()) {
|
switch (E->getStmtClass()) {
|
||||||
default: {
|
default: {
|
||||||
printf("Statement class: %d\n", E->getStmtClass());
|
printf("Statement class: %d\n", E->getStmtClass());
|
||||||
WarnUnsupported(E, "l-value expression");
|
WarnUnsupported(E, "l-value expression");
|
||||||
llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
|
llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
|
||||||
return LValue::MakeAddr(llvm::UndefValue::get(Ty));
|
return LValue::MakeAddr(llvm::UndefValue::get(Ty));
|
||||||
|
@ -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);
|
|
||||||
}
|
// Return a pointer to the right element.
|
||||||
// Get the correct element
|
return LValue::MakeAddr(Builder.CreateStructGEP(Object, Index,
|
||||||
llvm::Value * Element = Builder.CreateStructGEP(Object,
|
Decl->getName()));
|
||||||
Index,
|
|
||||||
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,
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -51,7 +50,6 @@ public:
|
||||||
Builder(CGF.Builder),
|
Builder(CGF.Builder),
|
||||||
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) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ using namespace CodeGen;
|
||||||
|
|
||||||
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
|
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
|
||||||
: CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
|
: CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
|
||||||
CaseRangeBlock(NULL) {}
|
CaseRangeBlock(NULL) {}
|
||||||
|
|
||||||
ASTContext &CodeGenFunction::getContext() const {
|
ASTContext &CodeGenFunction::getContext() const {
|
||||||
return CGM.getContext();
|
return CGM.getContext();
|
||||||
|
@ -64,11 +64,11 @@ 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(),
|
||||||
OMD->isVariadic());
|
OMD->isVariadic());
|
||||||
llvm::BasicBlock *EntryBB = new llvm::BasicBlock("entry", CurFn);
|
llvm::BasicBlock *EntryBB = new llvm::BasicBlock("entry", CurFn);
|
||||||
|
|
||||||
// Create a marker to make it easy to insert allocas into the entryblock
|
// Create a marker to make it easy to insert allocas into the entryblock
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -148,16 +148,14 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
|
||||||
/// Objective-C object, in the order that they appear. Used to create LLVM
|
/// Objective-C object, in the order that they appear. Used to create LLVM
|
||||||
/// structures corresponding to Objective-C objects.
|
/// structures corresponding to Objective-C objects.
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue