From cf4c60feae11b2f6a135d7cd8ecf97a5040951c3 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 17 Feb 2012 22:20:12 +0000 Subject: [PATCH] modern objc translator: postpone writing of class definitions until the end when all their ivars are known then. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150844 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Rewrite/RewriteModernObjC.cpp | 37 ++++++++++++++++++------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp index 1c9bf6b056..627368cd3d 100644 --- a/lib/Rewrite/RewriteModernObjC.cpp +++ b/lib/Rewrite/RewriteModernObjC.cpp @@ -107,7 +107,8 @@ namespace { SmallVector CategoryImplementation; llvm::SmallPtrSet ObjCSynthesizedStructs; llvm::SmallPtrSet ObjCSynthesizedProtocols; - llvm::SmallPtrSet ObjCForwardDecls; + llvm::SmallPtrSet ObjCWrittenInterfaces; + SmallVector ObjCInterfacesSeen; SmallVector Stmts; SmallVector ObjCBcLabelNo; // Remember all the @protocol() expressions. @@ -168,6 +169,10 @@ namespace { if (!Class->isThisDeclarationADefinition()) { RewriteForwardClassDecl(D); break; + } else { + // Keep track of all interface declarations seen. + ObjCInterfacesSeen.push_back(Class->getCanonicalDecl()); + break; } } @@ -1191,7 +1196,7 @@ void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { SuperClass = SuperClass->getSuperClass(); } std::string ResultStr; - if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) { + if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) { // we haven't seen a forward decl - generate a typedef. ResultStr = "#ifndef _REWRITER_typedef_"; ResultStr += ClassDecl->getNameAsString(); @@ -1203,8 +1208,8 @@ void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { ResultStr += ClassDecl->getNameAsString(); ResultStr += ";\n#endif\n"; RewriteObjCInternalStruct(ClassDecl, ResultStr); - // Mark this typedef as having been generated. - ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl()); + // Mark this typedef as having been written into its c++ equivalent. + ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl()); for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(), E = ClassDecl->prop_end(); I != E; ++I) @@ -3201,6 +3206,16 @@ void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, /// and emits meta-data. void RewriteModernObjC::RewriteImplementations() { + + for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) { + ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i]; + // Write struct declaration for the class matching its ivar declarations. + // Note that for modern abi, this is postponed until the end of TU + // because class extensions and the implementation might declare their own + // private ivars. + RewriteInterfaceDecl(CDecl); + } + int ClsDefCount = ClassImplementation.size(); int CatDefCount = CategoryImplementation.size(); @@ -3209,13 +3224,8 @@ void RewriteModernObjC::RewriteImplementations() { ObjCImplementationDecl *OIMP = ClassImplementation[i]; ObjCInterfaceDecl *CDecl = OIMP->getClassInterface(); if (CDecl->isImplicitInterfaceDecl()) - assert(false && - "Legacy implicit interface rewriting not supported in moder abi"); - // Write struct declaration for the class matching its ivar declarations. - // Note that for modern abi, this is postponed until implementation decl. - // because class extensions and the implementation might declare their own - // private ivars. - RewriteInterfaceDecl(CDecl); + assert(false && + "Legacy implicit interface rewriting not supported in moder abi"); RewriteImplementationDecl(OIMP); } @@ -3225,11 +3235,6 @@ void RewriteModernObjC::RewriteImplementations() { if (CDecl->isImplicitInterfaceDecl()) assert(false && "Legacy implicit interface rewriting not supported in moder abi"); - // Write struct declaration for the class matching its ivar declarations. - // Note that for modern abi, this is postponed until implementation decl. - // because class extensions and the implementation might declare their own - // private ivars. - RewriteInterfaceDecl(CDecl); RewriteImplementationDecl(CIMP); } } -- 2.50.1