From af05bb9073319d8381b71c4325188853fd4b8ed6 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 26 Aug 2008 08:29:31 +0000 Subject: Objective-C @synthesize support. - Only supports simple assignment and atomic semantics are ignored. - Not quite usable yet because the methods do not actually get added to the class metadata. - Added ObjCPropertyDecl::getSetterKind (one of Assign, Copy, Retain). - Rearrange CodeGenFunction so synthesis can reuse function prolog / epilog code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55365 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'lib/CodeGen/CodeGenModule.cpp') diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 51428c07ac..57d5377bc3 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -836,6 +836,32 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str) return GetAddrOfConstantString(str + "\0"); } +/// EmitObjCPropertyImplementations - Emit information for synthesized +/// properties for an implementation. +void CodeGenModule::EmitObjCPropertyImplementations(const + ObjCImplementationDecl *D) { + for (ObjCImplementationDecl::propimpl_iterator i = D->propimpl_begin(), + e = D->propimpl_end(); i != e; ++i) { + ObjCPropertyImplDecl *PID = *i; + + // Dynamic is just for type-checking. + if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { + ObjCPropertyDecl *PD = PID->getPropertyDecl(); + + // Determine which methods need to be implemented, some may have + // been overridden. Note that ::isSynthesized is not the method + // we want, that just indicates if the decl came from a + // property. What we want to know is if the method is defined in + // this implementation. + if (!D->getInstanceMethod(PD->getGetterName())) + CodeGenFunction(*this).GenerateObjCGetter(PID); + if (!PD->isReadOnly() && + !D->getInstanceMethod(PD->getSetterName())) + CodeGenFunction(*this).GenerateObjCSetter(PID); + } + } +} + /// EmitTopLevelDecl - Emit code for a single top level declaration. void CodeGenModule::EmitTopLevelDecl(Decl *D) { // If an error has occurred, stop code generation, but continue @@ -868,13 +894,18 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { break; case Decl::ObjCCategoryImpl: + // Categories have properties but don't support synthesize so we + // can ignore them here. + Runtime->GenerateCategory(cast(D)); break; - case Decl::ObjCImplementation: - Runtime->GenerateClass(cast(D)); + case Decl::ObjCImplementation: { + ObjCImplementationDecl *OMD = cast(D); + EmitObjCPropertyImplementations(OMD); + Runtime->GenerateClass(OMD); break; - + } case Decl::ObjCMethod: { ObjCMethodDecl *OMD = cast(D); // If this is not a prototype, emit the body. @@ -882,9 +913,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { CodeGenFunction(*this).GenerateObjCMethod(OMD); break; } - case Decl::ObjCPropertyImpl: - assert(0 && "FIXME: ObjCPropertyImpl unsupported"); - break; case Decl::ObjCCompatibleAlias: assert(0 && "FIXME: ObjCCompatibleAlias unsupported"); break; -- cgit v1.2.3-18-g5258