Clean up CGObjCMac's APIs for deriving class references. NFC.
authorJohn McCall <rjmccall@apple.com>
Wed, 30 Nov 2016 23:54:50 +0000 (23:54 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 30 Nov 2016 23:54:50 +0000 (23:54 +0000)
llvm-svn: 288295

clang/lib/CodeGen/CGObjCGNU.cpp
clang/lib/CodeGen/CGObjCMac.cpp
clang/lib/CodeGen/CGObjCRuntime.h

index 3fd8dab..fa2b3d8 100644 (file)
@@ -560,11 +560,6 @@ public:
   llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, QualType T) override {
     return NULLPtr;
   }
-
-  llvm::GlobalVariable *GetClassGlobal(StringRef Name,
-                                       bool Weak = false) override {
-    return nullptr;
-  }
 };
 
 /// Class representing the legacy GCC Objective-C ABI.  This is the default when
index 593067c..7219592 100644 (file)
@@ -1360,13 +1360,6 @@ public:
   llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
                               const ObjCInterfaceDecl *Interface,
                               const ObjCIvarDecl *Ivar) override;
-
-  /// GetClassGlobal - Return the global variable for the Objective-C
-  /// class of the given name.
-  llvm::GlobalVariable *GetClassGlobal(StringRef Name,
-                                       bool Weak = false) override {
-    llvm_unreachable("CGObjCMac::GetClassGlobal");
-  }
 };
 
 class CGObjCNonFragileABIMac : public CGObjCCommonMac {
@@ -1409,12 +1402,12 @@ private:
                                               unsigned InstanceStart,
                                               unsigned InstanceSize,
                                               const ObjCImplementationDecl *ID);
-  llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
-                                            llvm::Constant *IsAGV,
-                                            llvm::Constant *SuperClassGV,
-                                            llvm::Constant *ClassRoGV,
-                                            bool HiddenVisibility,
-                                            bool Weak);
+  llvm::GlobalVariable *BuildClassObject(const ObjCInterfaceDecl *CI,
+                                         bool isMetaclass,
+                                         llvm::Constant *IsAGV,
+                                         llvm::Constant *SuperClassGV,
+                                         llvm::Constant *ClassRoGV,
+                                         bool HiddenVisibility);
 
   void emitMethodConstant(ConstantArrayBuilder &builder,
                             const ObjCMethodDecl *MD,
@@ -1465,8 +1458,12 @@ private:
   
   /// GetClassGlobal - Return the global variable for the Objective-C
   /// class of the given name.
-  llvm::GlobalVariable *GetClassGlobal(StringRef Name,
-                                       bool Weak = false) override;
+  llvm::Constant *GetClassGlobal(StringRef Name,
+                                 ForDefinition_t IsForDefinition,
+                                 bool Weak = false, bool DLLImport = false);
+  llvm::Constant *GetClassGlobal(const ObjCInterfaceDecl *ID,
+                                 bool isMetaclass,
+                                 ForDefinition_t isForDefinition);
 
   /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
   /// for the given class reference.
@@ -1474,7 +1471,7 @@ private:
                             const ObjCInterfaceDecl *ID);
   
   llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
-                                  IdentifierInfo *II, bool Weak,
+                                  IdentifierInfo *II,
                                   const ObjCInterfaceDecl *ID);
 
   llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
@@ -1504,7 +1501,7 @@ private:
   /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
   /// interface. The return value has type EHTypePtrTy.
   llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
-                                  bool ForDefinition);
+                                     ForDefinition_t IsForDefinition);
 
   StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; }
 
@@ -1902,7 +1899,7 @@ llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
   std::string str = 
     StringClass.empty() ? "OBJC_CLASS_$_NSConstantString" 
                         : "OBJC_CLASS_$_" + StringClass;
-  auto GV = GetClassGlobal(str);
+  auto GV = GetClassGlobal(str, NotForDefinition);
 
   // Make sure the result is of the correct type.
   auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
@@ -6161,8 +6158,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
   return CLASS_RO_GV;
 }
 
-/// BuildClassMetaData - This routine defines that to-level meta-data
-/// for the given ClassName for:
+/// Build the metaclass object for a class.
+///
 /// struct _class_t {
 ///   struct _class_t *isa;
 ///   struct _class_t * const superclass;
@@ -6171,9 +6168,13 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
 ///   struct class_ro_t *ro;
 /// }
 ///
-llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
-    const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
-    llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
+llvm::GlobalVariable *
+CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
+                                         bool isMetaclass,
+                                         llvm::Constant *IsAGV,
+                                         llvm::Constant *SuperClassGV,
+                                         llvm::Constant *ClassRoGV,
+                                         bool HiddenVisibility) {
   ConstantInitBuilder builder(CGM);
   auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
   values.add(IsAGV);
@@ -6186,7 +6187,8 @@ llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
   values.add(ObjCEmptyVtableVar);
   values.add(ClassRoGV);
 
-  llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
+  llvm::GlobalVariable *GV =
+    cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
   values.finishAndSetAsInitializer(GV);
 
   if (CGM.getTriple().isOSBinFormatMachO())
@@ -6267,9 +6269,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
   uint32_t InstanceSize = InstanceStart;
   uint32_t flags = NonFragileABI_Class_Meta;
 
-  llvm::GlobalVariable *SuperClassGV, *IsAGV;
+  llvm::Constant *SuperClassGV, *IsAGV;
 
-  StringRef ClassName = ID->getObjCRuntimeNameAsString();
   const auto *CI = ID->getClassInterface();
   assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
 
@@ -6292,17 +6293,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
     // class is root
     flags |= NonFragileABI_Class_Root;
 
-    SuperClassGV = GetClassGlobal((getClassSymbolPrefix() + ClassName).str(),
-                                  CI->isWeakImported());
-    if (CGM.getTriple().isOSBinFormatCOFF())
-      if (CI->hasAttr<DLLImportAttr>())
-        SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
-
-    IsAGV = GetClassGlobal((getMetaclassSymbolPrefix() + ClassName).str(),
-                           CI->isWeakImported());
-    if (CGM.getTriple().isOSBinFormatCOFF())
-      if (CI->hasAttr<DLLImportAttr>())
-        IsAGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
+    IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
   } else {
     // Has a root. Current class is not a root.
     const ObjCInterfaceDecl *Root = ID->getClassInterface();
@@ -6310,31 +6302,16 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
       Root = Super;
 
     const auto *Super = CI->getSuperClass();
-    StringRef RootClassName = Root->getObjCRuntimeNameAsString();
-    StringRef SuperClassName = Super->getObjCRuntimeNameAsString();
-
-    IsAGV = GetClassGlobal((getMetaclassSymbolPrefix() + RootClassName).str(),
-                           Root->isWeakImported());
-    if (CGM.getTriple().isOSBinFormatCOFF())
-      if (Root->hasAttr<DLLImportAttr>())
-        IsAGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
-
-    // work on super class metadata symbol.
-    SuperClassGV =
-        GetClassGlobal((getMetaclassSymbolPrefix() + SuperClassName).str(),
-                       Super->isWeakImported());
-    if (CGM.getTriple().isOSBinFormatCOFF())
-      if (Super->hasAttr<DLLImportAttr>())
-        SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
+    SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
   }
 
   llvm::GlobalVariable *CLASS_RO_GV =
       BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
 
   llvm::GlobalVariable *MetaTClass =
-      BuildClassMetaData((getMetaclassSymbolPrefix() + ClassName).str(), IsAGV,
-                         SuperClassGV, CLASS_RO_GV, classIsHidden,
-                         CI->isWeakImported());
+    BuildClassObject(CI, /*metaclass*/ true,
+                     IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
   if (CGM.getTriple().isOSBinFormatCOFF())
     if (CI->hasAttr<DLLExportAttr>())
       MetaTClass->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
@@ -6367,14 +6344,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
   } else {
     // Has a root. Current class is not a root.
     const auto *Super = CI->getSuperClass();
-    StringRef SuperClassName = Super->getObjCRuntimeNameAsString();
-
-    SuperClassGV =
-        GetClassGlobal((getClassSymbolPrefix() + SuperClassName).str(),
-                       Super->isWeakImported());
-    if (CGM.getTriple().isOSBinFormatCOFF())
-      if (Super->hasAttr<DLLImportAttr>())
-        SuperClassGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
   }
 
   GetClassSizeInfo(ID, InstanceStart, InstanceSize);
@@ -6382,9 +6352,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
       BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
 
   llvm::GlobalVariable *ClassMD =
-    BuildClassMetaData((getClassSymbolPrefix() + ClassName).str(), MetaTClass,
-                       SuperClassGV, CLASS_RO_GV, classIsHidden,
-                       CI->isWeakImported());
+    BuildClassObject(CI, /*metaclass*/ false,
+                     MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
   if (CGM.getTriple().isOSBinFormatCOFF())
     if (CI->hasAttr<DLLExportAttr>())
       ClassMD->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
@@ -6397,7 +6366,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
 
   // Force the definition of the EHType if necessary.
   if (flags & NonFragileABI_Class_Exception)
-    GetInterfaceEHType(CI, true);
+    (void) GetInterfaceEHType(CI, ForDefinition);
   // Make sure method definition entries are all clear for next implementation.
   MethodDefinitions.clear();
 }
@@ -6462,17 +6431,11 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
   ExtCatName += "_$_";
   ExtCatName += OCD->getNameAsString();
     
-  llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
-  ExtClassName += Interface->getObjCRuntimeNameAsString();
-
   ConstantInitBuilder builder(CGM);
   auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
   values.add(GetClassName(OCD->getIdentifier()->getName()));
   // meta-class entry symbol
-  llvm::GlobalVariable *ClassGV =
-      GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
-
-  values.add(ClassGV);
+  values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
   std::string listName =
       (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();
 
@@ -7150,33 +7113,59 @@ CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
                       false, CallArgs, Method, Class, ObjCTypes);
 }
 
-llvm::GlobalVariable *
-CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name, bool Weak) {
+llvm::Constant *
+CGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
+                                       bool metaclass,
+                                       ForDefinition_t isForDefinition) {
+  auto prefix =
+    (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
+  return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
+                        isForDefinition,
+                        ID->isWeakImported(),
+                        !isForDefinition
+                          && CGM.getTriple().isOSBinFormatCOFF()
+                          && ID->hasAttr<DLLImportAttr>());
+}
+
+llvm::Constant *
+CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
+                                       ForDefinition_t IsForDefinition,
+                                       bool Weak, bool DLLImport) {
   llvm::GlobalValue::LinkageTypes L =
       Weak ? llvm::GlobalValue::ExternalWeakLinkage
            : llvm::GlobalValue::ExternalLinkage;
 
-  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
 
-  if (!GV)
+
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  if (!GV) {
     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
                                   false, L, nullptr, Name);
 
+    if (DLLImport)
+      GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+  }
+
   assert(GV->getLinkage() == L);
   return GV;
 }
 
-llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
-                                                        IdentifierInfo *II,
-                                                        bool Weak,
-                                                        const ObjCInterfaceDecl *ID) {
+llvm::Value *
+CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
+                                           IdentifierInfo *II,
+                                           const ObjCInterfaceDecl *ID) {
   CharUnits Align = CGF.getPointerAlign();
   llvm::GlobalVariable *&Entry = ClassReferences[II];
   
   if (!Entry) {
-    StringRef Name = ID ? ID->getObjCRuntimeNameAsString() : II->getName();
-    std::string ClassName = (getClassSymbolPrefix() + Name).str();
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
+    llvm::Constant *ClassGV;
+    if (ID) {
+      ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
+    } else {
+      ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
+                               NotForDefinition);
+    }
+
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
                                      false, llvm::GlobalValue::PrivateLinkage,
                                      ClassGV, "OBJC_CLASSLIST_REFERENCES_$_");
@@ -7194,13 +7183,13 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
   if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
     return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
 
-  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
+  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
                                                     CodeGenFunction &CGF) {
   IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
-  return EmitClassRefFromId(CGF, II, false, nullptr);
+  return EmitClassRefFromId(CGF, II, nullptr);
 }
 
 llvm::Value *
@@ -7210,10 +7199,7 @@ CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
   llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
 
   if (!Entry) {
-    llvm::SmallString<64> ClassName(getClassSymbolPrefix());
-    ClassName += ID->getObjCRuntimeNameAsString();
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
-                                                   ID->isWeakImported());
+    auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
                                      false, llvm::GlobalValue::PrivateLinkage,
                                      ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
@@ -7233,10 +7219,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
   CharUnits Align = CGF.getPointerAlign();
   llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
   if (!Entry) {
-    llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
-    MetaClassName += ID->getObjCRuntimeNameAsString();
-    llvm::GlobalVariable *MetaClassGV =
-      GetClassGlobal(MetaClassName.str(), Weak);
+    auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
 
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
                                      false, llvm::GlobalValue::PrivateLinkage,
@@ -7255,11 +7238,10 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
 llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
                                               const ObjCInterfaceDecl *ID) {
   if (ID->isWeakImported()) {
-    llvm::SmallString<64> ClassName(getClassSymbolPrefix());
-    ClassName += ID->getObjCRuntimeNameAsString();
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
+    auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
     (void)ClassGV;
-    assert(ClassGV->hasExternalWeakLinkage());
+    assert(!isa<llvm::GlobalVariable>(ClassGV) ||
+           cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
   }
   
   return EmitClassRef(CGF, ID);
@@ -7492,7 +7474,7 @@ CGObjCNonFragileABIMac::GetEHType(QualType T) {
   const ObjCInterfaceType *IT = PT->getInterfaceType();
   assert(IT && "Invalid @catch type.");
 
-  return GetInterfaceEHType(IT->getDecl(), false);
+  return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
 }
 
 void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
@@ -7524,13 +7506,13 @@ void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
 
 llvm::Constant *
 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
-                                           bool ForDefinition) {
+                                           ForDefinition_t IsForDefinition) {
   llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
   StringRef ClassName = ID->getObjCRuntimeNameAsString();
 
   // If we don't need a definition, return the entry if found or check
   // if we use an external reference.
-  if (!ForDefinition) {
+  if (!IsForDefinition) {
     if (Entry)
       return Entry;
 
@@ -7570,10 +7552,10 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
   auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
   values.add(llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(),
                                                   VTableGV, VTableIdx));
-  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
-  values.add(GetClassGlobal((getClassSymbolPrefix() + ClassName).str()));
+  values.add(GetClassName(ClassName));
+  values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
 
-  llvm::GlobalValue::LinkageTypes L = ForDefinition
+  llvm::GlobalValue::LinkageTypes L = IsForDefinition
                                           ? llvm::GlobalValue::ExternalLinkage
                                           : llvm::GlobalValue::WeakAnyLinkage;
   if (Entry) {
@@ -7595,7 +7577,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
     if (ID->getVisibility() == HiddenVisibility)
       Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
-  if (ForDefinition)
+  if (IsForDefinition)
     if (CGM.getTriple().isOSBinFormatMachO())
       Entry->setSection("__DATA,__objc_const");
 
index 6c33059..a14b44a 100644 (file)
@@ -280,9 +280,6 @@ public:
   virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
                                            QualType T) = 0;
 
-  virtual llvm::GlobalVariable *GetClassGlobal(StringRef Name,
-                                               bool Weak = false) = 0;
-
   struct MessageSendInfo {
     const CGFunctionInfo &CallInfo;
     llvm::PointerType *MessengerType;