objective-c translator. more modern abi stuff, focusing on ivar related
meta-data.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150310 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index 939f81d..a981ffd 100644
--- a/lib/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Rewrite/RewriteModernObjC.cpp
@@ -626,9 +626,6 @@
       ConstantStringClassReference = FVD;
       return;
     }
-  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    if (ID->isThisDeclarationADefinition())
-      RewriteInterfaceDecl(ID);
   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
     RewriteCategoryDecl(CD);
   } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
@@ -1183,6 +1180,15 @@
 }
 
 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(ClassDecl))
+    return;
+  // Make sure super class's are written before current class is written.
+  ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
+  while (SuperClass) {
+    RewriteInterfaceDecl(SuperClass);
+    SuperClass = SuperClass->getSuperClass();
+  }
   std::string ResultStr;
   if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
     // we haven't seen a forward decl - generate a typedef.
@@ -1215,6 +1221,9 @@
   // Lastly, comment out the @end.
   ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
               "/* @end */");
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(ClassDecl))
+    llvm_unreachable("struct already synthesize- RewriteInterfaceDecl");
 }
 
 Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
@@ -3128,9 +3137,6 @@
   assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
   assert(CDecl->getName() != "" &&
          "Name missing in SynthesizeObjCInternalStruct");
-  // Do not synthesize more than once.
-  if (ObjCSynthesizedStructs.count(CDecl))
-    return;
   ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
   SmallVector<ObjCIvarDecl *, 8> IVars;
   for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
@@ -3171,15 +3177,14 @@
     std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
     Result += "\t";
     Result += TypeString; Result += " "; Result += IvarDecl->getNameAsString();
+    if (IvarDecl->isBitField()) {
+      Result += " : "; Result += utostr(IvarDecl->getBitWidthValue(*Context));
+    }
     Result += ";\n";
   }
   Result += "};\n";
   endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
   ReplaceText(LocStart, endBuf-startBuf, Result);
-
-  // Mark this struct as having been generated.
-  if (!ObjCSynthesizedStructs.insert(CDecl))
-    llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct");
 }
 
 //===----------------------------------------------------------------------===//
@@ -3195,8 +3200,19 @@
   int CatDefCount = CategoryImplementation.size();
 
   // Rewrite implemented methods
-  for (int i = 0; i < ClsDefCount; i++)
-    RewriteImplementationDecl(ClassImplementation[i]);
+  for (int i = 0; i < ClsDefCount; i++) {
+    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);
+    RewriteImplementationDecl(OIMP);
+  }
 
   for (int i = 0; i < CatDefCount; i++)
     RewriteImplementationDecl(CategoryImplementation[i]);
@@ -5458,8 +5474,10 @@
       RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
       Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
       
-      // FIXME: what should the alignment be?
-      unsigned Align = 0;  
+      // FIXME. this alignment represents the host alignment and need be changed to
+      // represent the target alignment.
+      unsigned Align = Context->getTypeAlign(IvarDecl->getType())/8;
+      Align = llvm::Log2_32(Align);
       Result += llvm::utostr(Align); Result += ", ";
       CharUnits Size = Context->getTypeSizeInChars(IvarDecl->getType());
       Result += llvm::utostr(Size.getQuantity());
@@ -5678,6 +5696,7 @@
   if (CDecl->isImplicitInterfaceDecl())
     assert(false && 
            "Legacy implicit interface rewriting not supported in moder abi");
+  
   WriteModernMetadataDeclarations(Result);
   SmallVector<ObjCIvarDecl *, 8> IVars;
   
@@ -5692,238 +5711,6 @@
   Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
                                  "_OBJC_INSTANCE_VARIABLES_",
                                  CDecl->getNameAsString());
-  
-  // FIXME. Handle modern abi's private ivars declared in @implementation.
-  // Build _objc_ivar_list metadata for classes ivars if needed
-  unsigned NumIvars = CDecl->ivar_size();
-  
-  if (NumIvars > 0) {
-    
-    /* struct {
-     int ivar_count;
-     struct _objc_ivar ivar_list[nIvars];
-     };
-     */
-    Result += "\nstatic struct {\n";
-    Result += "\tint ivar_count;\n";
-    Result += "\tstruct _objc_ivar ivar_list[";
-    Result += utostr(NumIvars);
-    Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
-    Result += IDecl->getNameAsString();
-    Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
-    "{\n\t";
-    Result += utostr(NumIvars);
-    Result += "\n";
-    
-    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
-    SmallVector<ObjCIvarDecl *, 8> IVars;
-    if (!IDecl->ivar_empty()) {
-      for (ObjCInterfaceDecl::ivar_iterator
-           IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
-           IV != IVEnd; ++IV)
-        IVars.push_back(*IV);
-      IVI = IDecl->ivar_begin();
-      IVE = IDecl->ivar_end();
-    } else {
-      IVI = CDecl->ivar_begin();
-      IVE = CDecl->ivar_end();
-    }
-    Result += "\t,{{\"";
-    Result += (*IVI)->getNameAsString();
-    Result += "\", \"";
-    std::string TmpString, StrEncoding;
-    Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
-    QuoteDoublequotes(TmpString, StrEncoding);
-    Result += StrEncoding;
-    Result += "\", ";
-    RewriteIvarOffsetComputation(*IVI, Result);
-    Result += "}\n";
-    for (++IVI; IVI != IVE; ++IVI) {
-      Result += "\t  ,{\"";
-      Result += (*IVI)->getNameAsString();
-      Result += "\", \"";
-      std::string TmpString, StrEncoding;
-      Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI);
-      QuoteDoublequotes(TmpString, StrEncoding);
-      Result += StrEncoding;
-      Result += "\", ";
-      RewriteIvarOffsetComputation((*IVI), Result);
-      Result += "}\n";
-    }
-    
-    Result += "\t }\n};\n";
-  }
-  
-  // Build _objc_method_list for class's instance methods if needed
-  SmallVector<ObjCMethodDecl *, 32>
-  InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
-  
-  // If any of our property implementations have associated getters or
-  // setters, produce metadata for them as well.
-  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
-       PropEnd = IDecl->propimpl_end();
-       Prop != PropEnd; ++Prop) {
-    if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-      continue;
-    if (!(*Prop)->getPropertyIvarDecl())
-      continue;
-    ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
-    if (!PD)
-      continue;
-    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
-      if (!Getter->isDefined())
-        InstanceMethods.push_back(Getter);
-    if (PD->isReadOnly())
-      continue;
-    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
-      if (!Setter->isDefined())
-        InstanceMethods.push_back(Setter);
-  }
-  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
-                             true, "", IDecl->getName(), Result);
-  
-  // Build _objc_method_list for class's class methods if needed
-  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
-                             false, "", IDecl->getName(), Result);
-  
-  // Protocols referenced in class declaration?
-  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
-                                  "CLASS", CDecl->getName(), Result);
-  
-  // Declaration of class/meta-class metadata
-  /* struct _objc_class {
-   struct _objc_class *isa; // or const char *root_class_name when metadata
-   const char *super_class_name;
-   char *name;
-   long version;
-   long info;
-   long instance_size;
-   struct _objc_ivar_list *ivars;
-   struct _objc_method_list *methods;
-   struct objc_cache *cache;
-   struct objc_protocol_list *protocols;
-   const char *ivar_layout;
-   struct _objc_class_ext  *ext;
-   };
-   */
-  static bool objc_class = false;
-  if (!objc_class) {
-    Result += "\nstruct _objc_class {\n";
-    Result += "\tstruct _objc_class *isa;\n";
-    Result += "\tconst char *super_class_name;\n";
-    Result += "\tchar *name;\n";
-    Result += "\tlong version;\n";
-    Result += "\tlong info;\n";
-    Result += "\tlong instance_size;\n";
-    Result += "\tstruct _objc_ivar_list *ivars;\n";
-    Result += "\tstruct _objc_method_list *methods;\n";
-    Result += "\tstruct objc_cache *cache;\n";
-    Result += "\tstruct _objc_protocol_list *protocols;\n";
-    Result += "\tconst char *ivar_layout;\n";
-    Result += "\tstruct _objc_class_ext  *ext;\n";
-    Result += "};\n";
-    objc_class = true;
-  }
-  
-  // Meta-class metadata generation.
-  ObjCInterfaceDecl *RootClass = 0;
-  ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
-  while (SuperClass) {
-    RootClass = SuperClass;
-    SuperClass = SuperClass->getSuperClass();
-  }
-  SuperClass = CDecl->getSuperClass();
-  
-  Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
-  Result += CDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
-  "{\n\t(struct _objc_class *)\"";
-  Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
-  Result += "\"";
-  
-  if (SuperClass) {
-    Result += ", \"";
-    Result += SuperClass->getNameAsString();
-    Result += "\", \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  else {
-    Result += ", 0, \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
-  // 'info' field is initialized to CLS_META(2) for metaclass
-  Result += ", 0,2, sizeof(struct _objc_class), 0";
-  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
-    Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
-    Result += IDecl->getNameAsString();
-    Result += "\n";
-  }
-  else
-    Result += ", 0\n";
-  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
-    Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
-    Result += CDecl->getNameAsString();
-    Result += ",0,0\n";
-  }
-  else
-    Result += "\t,0,0,0,0\n";
-  Result += "};\n";
-  
-  // class metadata generation.
-  Result += "\nstatic struct _objc_class _OBJC_CLASS_";
-  Result += CDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
-  "{\n\t&_OBJC_METACLASS_";
-  Result += CDecl->getNameAsString();
-  if (SuperClass) {
-    Result += ", \"";
-    Result += SuperClass->getNameAsString();
-    Result += "\", \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  else {
-    Result += ", 0, \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  // 'info' field is initialized to CLS_CLASS(1) for class
-  Result += ", 0,1";
-  if (!ObjCSynthesizedStructs.count(CDecl))
-    Result += ",0";
-  else {
-    // class has size. Must synthesize its size.
-    Result += ",sizeof(struct ";
-    Result += CDecl->getNameAsString();
-    if (LangOpts.MicrosoftExt)
-      Result += "_IMPL";
-    Result += ")";
-  }
-  if (NumIvars > 0) {
-    Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
-    Result += CDecl->getNameAsString();
-    Result += "\n\t";
-  }
-  else
-    Result += ",0";
-  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
-    Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
-    Result += CDecl->getNameAsString();
-    Result += ", 0\n\t";
-  }
-  else
-    Result += ",0,0";
-  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
-    Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
-    Result += CDecl->getNameAsString();
-    Result += ", 0,0\n";
-  }
-  else
-    Result += ",0,0,0\n";
-  Result += "};\n";
 }
 
 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {