IRGen for initialization/destruction of

ivar class objects (NeXt runtime).
(radar 7900343).

llvm-svn: 102533
This commit is contained in:
Fariborz Jahanian 2010-04-28 21:28:56 +00:00
parent c892b6dbb0
commit 0dec1e0d56
5 changed files with 92 additions and 0 deletions

View File

@ -397,6 +397,55 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
FinishFunction();
}
void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
ObjCMethodDecl *MD,
bool ctor) {
llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> IvarInitializers;
MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
StartObjCMethod(MD, IMP->getClassInterface());
for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
E = IMP->init_end(); B != E; ++B) {
CXXBaseOrMemberInitializer *Member = (*B);
IvarInitializers.push_back(Member);
}
if (ctor) {
for (unsigned I = 0, E = IvarInitializers.size(); I != E; ++I) {
CXXBaseOrMemberInitializer *IvarInit = IvarInitializers[I];
FieldDecl *Field = IvarInit->getMember();
QualType FieldType = Field->getType();
if (CGM.getContext().getAsConstantArrayType(FieldType))
assert(false && "Construction objc arrays NYI");
ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
EmitAggExpr(IvarInit->getInit(), LV.getAddress(),
LV.isVolatileQualified(), false, true);
}
// constructor returns 'self'.
CodeGenTypes &Types = CGM.getTypes();
QualType IdTy(CGM.getContext().getObjCIdType());
llvm::Value *SelfAsId =
Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
}
else {
// dtor
for (size_t i = IvarInitializers.size(); i > 0; --i) {
FieldDecl *Field = IvarInitializers[i - 1]->getMember();
QualType FieldType = Field->getType();
if (CGM.getContext().getAsConstantArrayType(FieldType))
assert(false && "Destructing objc arrays NYI");
ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
LoadObjCSelf(), Ivar, 0);
const RecordType *RT = FieldType->getAs<RecordType>();
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
EmitCXXDestructorCall(FieldClassDecl->getDestructor(CGM.getContext()),
Dtor_Complete, LV.getAddress());
}
}
FinishFunction();
}
bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
it++; it++;

View File

@ -2083,6 +2083,8 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Interface->protocol_begin(),
Interface->protocol_end());
unsigned Flags = eClassFlags_Factory;
if (ID->getNumIvarInitializers())
Flags |= eClassFlags_HasCXXStructors;
unsigned Size =
CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
@ -4497,6 +4499,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden;
if (classIsHidden)
flags |= OBJC2_CLS_HIDDEN;
if (ID->getNumIvarInitializers())
flags |= eClassFlags_ABI2_HasCXXStructors;
if (!ID->getClassInterface()->getSuperClass()) {
// class is root
flags |= CLS_ROOT;
@ -4531,6 +4535,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
flags = CLS;
if (classIsHidden)
flags |= OBJC2_CLS_HIDDEN;
if (ID->getNumIvarInitializers())
flags |= eClassFlags_ABI2_HasCXXStructors;
if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
flags |= CLS_EXCEPTION;

View File

@ -473,6 +473,8 @@ public:
/// GenerateObjCGetter - Synthesize an Objective-C property getter function.
void GenerateObjCGetter(ObjCImplementationDecl *IMP,
const ObjCPropertyImplDecl *PID);
void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
ObjCMethodDecl *MD, bool ctor);
/// GenerateObjCSetter - Synthesize an Objective-C property setter function
/// for the given property.

View File

@ -1820,6 +1820,39 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
}
}
/// EmitObjCIvarInitializations - Emit information for ivar initialization
/// for an implementation.
void CodeGenModule::EmitObjCIvarInitializations(ObjCImplementationDecl *D) {
if (!Features.NeXTRuntime || D->getNumIvarInitializers() == 0)
return;
DeclContext* DC = const_cast<DeclContext*>(dyn_cast<DeclContext>(D));
assert(DC && "EmitObjCIvarInitializations - null DeclContext");
IdentifierInfo *II = &getContext().Idents.get(".cxx_destruct");
Selector cxxSelector = getContext().Selectors.getSelector(0, &II);
ObjCMethodDecl *DTORMethod = ObjCMethodDecl::Create(getContext(),
D->getLocation(),
D->getLocation(), cxxSelector,
getContext().VoidTy, 0,
DC, true, false, true,
ObjCMethodDecl::Required);
D->addInstanceMethod(DTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, DTORMethod, false);
II = &getContext().Idents.get(".cxx_construct");
cxxSelector = getContext().Selectors.getSelector(0, &II);
// The constructor returns 'self'.
ObjCMethodDecl *CTORMethod = ObjCMethodDecl::Create(getContext(),
D->getLocation(),
D->getLocation(), cxxSelector,
getContext().getObjCIdType(), 0,
DC, true, false, true,
ObjCMethodDecl::Required);
D->addInstanceMethod(CTORMethod);
CodeGenFunction(*this).GenerateObjCCtorDtorMethod(D, CTORMethod, true);
}
/// EmitNamespace - Emit all declarations in a namespace.
void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end();
@ -1916,6 +1949,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::ObjCImplementation: {
ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
EmitObjCPropertyImplementations(OMD);
EmitObjCIvarInitializations(OMD);
Runtime->GenerateClass(OMD);
break;
}

View File

@ -482,6 +482,7 @@ private:
void EmitGlobalVarDefinition(const VarDecl *D);
void EmitAliasDefinition(GlobalDecl GD);
void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
// C++ related functions.