modern objective-c translator: section info.
and metadata for "non-lazy" class and categories.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152751 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index 4fe5359..580d396 100644
--- a/lib/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Rewrite/RewriteModernObjC.cpp
@@ -110,6 +110,12 @@
     llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
     llvm::SmallPtrSet<TagDecl*, 8> TagsDefinedInIvarDecls;
     SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
+    /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
+    SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
+    
+    /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
+    llvm::SmallVector<ObjCCategoryDecl*, 8> DefinedNonLazyCategories;
+    
     SmallVector<Stmt *, 32> Stmts;
     SmallVector<int, 8> ObjCBcLabelNo;
     // Remember all the @protocol(<expr>) expressions.
@@ -517,6 +523,12 @@
       return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
                                     SourceLocation(), SourceLocation());
     }
+    
+    bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
+      IdentifierInfo* II = &Context->Idents.get("load");
+      Selector LoadSel = Context->Selectors.getSelector(0, &II);
+      return OD->getClassMethod(LoadSel) != 0;
+    }
   };
   
 }
@@ -5032,14 +5044,14 @@
     Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
     Preamble += "#pragma section(\".objc_protolist$B\", long, read, write)\n";
     Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
     
     // These need be generated. But they are not,using API calls instead.
     Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
     Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
     Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n";
     
-    Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
     Preamble += "#pragma section(\".objc_protorefs$B\", long, read, write)\n";
     
     
@@ -5641,14 +5653,20 @@
 static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
                              std::string &Result,
                              StringRef CatName,
-                             StringRef ClassName,
+                             ObjCInterfaceDecl *ClassDecl,
                              ArrayRef<ObjCMethodDecl *> InstanceMethods,
                              ArrayRef<ObjCMethodDecl *> ClassMethods,
                              ArrayRef<ObjCProtocolDecl *> RefedProtocols,
                              ArrayRef<ObjCPropertyDecl *> ClassProperties) {
+  
+  StringRef ClassName = ClassDecl->getNameAsString();
   // must declare an extern class object in case this class is not implemented 
   // in this TU.
-  Result += "\nextern struct _class_t ";
+  Result += "\n";
+  if (ClassDecl->getImplementation())
+    Result += "__declspec(dllexport) ";
+  
+  Result += "extern struct _class_t ";
   Result += "OBJC_CLASS_$_"; Result += ClassName;
   Result += ";\n";
   
@@ -6213,6 +6231,9 @@
   Write_class_t(Context, Result,
                 "OBJC_CLASS_$_",
                 CDecl, /*metaclass*/false);
+  
+  if (ImplementationIsNonLazy(IDecl))
+    DefinedNonLazyClasses.push_back(CDecl);
                 
 }
 
@@ -6242,6 +6263,17 @@
       Result += ",\n";
     }
     Result += "};\n";
+    
+    if (!DefinedNonLazyClasses.empty()) {
+      if (LangOpts.MicrosoftExt)
+        Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
+      Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
+      for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
+        Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
+        Result += ",\n";
+      }
+      Result += "};\n";
+    }
   }
   
   if (CatDefCount > 0) {
@@ -6262,6 +6294,21 @@
     }
     Result += "};\n";
   }
+  
+  if (!DefinedNonLazyCategories.empty()) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
+    Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
+    for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
+      Result += "\t&_OBJC_$_CATEGORY_";
+      Result += 
+        DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 
+      Result += "_$_";
+      Result += DefinedNonLazyCategories[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+  }
 }
 
 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
@@ -6270,7 +6317,7 @@
   
   Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
   // version 0, ObjCABI is 2
-  Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
+  Result += "L_OBJC_IMAGE_INFO = { 0, 2 };\n";
 }
 
 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
@@ -6356,12 +6403,16 @@
   
   Write_category_t(*this, Context, Result,
                    CDecl->getNameAsString(),
-                   ClassDecl->getNameAsString(),
+                   ClassDecl,
                    InstanceMethods,
                    ClassMethods,
                    RefedProtocols,
                    ClassProperties);
   
+  // Determine if this category is also "non-lazy".
+  if (ImplementationIsNonLazy(IDecl))
+    DefinedNonLazyCategories.push_back(CDecl);
+  
 }
 
 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or