forked from OSchip/llvm-project
IRGen for initialization/destruction of
ivar class objects (NeXt runtime). (radar 7900343). llvm-svn: 102533
This commit is contained in:
parent
c892b6dbb0
commit
0dec1e0d56
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue