[cfe-commits] r68591 - in /cfe/trunk: lib/CodeGen/CGObjCMac.cpp test/CodeGenObjC/metadata_symbols.m

Daniel Dunbar daniel at zuster.org
Tue Apr 7 21:21:03 PDT 2009


Author: ddunbar
Date: Tue Apr  7 23:21:03 2009
New Revision: 68591

URL: http://llvm.org/viewvc/llvm-project?rev=68591&view=rev
Log:
Implementation definition of interfaces with __objc_exception attribute.
 - Complete <rdar://problem/6635883> Support __objc_exception__
   attribute

Modified:
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/test/CodeGenObjC/metadata_symbols.m

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=68591&r1=68590&r2=68591&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Apr  7 23:21:03 2009
@@ -712,7 +712,7 @@
   /// FinishNonFragileABIModule - Write out global data structures at the end of
   /// processing a translation unit.
   void FinishNonFragileABIModule();
-  
+
   llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 
                                 unsigned InstanceStart,
                                 unsigned InstanceSize,
@@ -795,9 +795,10 @@
   /// for the given selector.
   llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
 
-  /// GetInterfaceEHType - Get the ehtype for the given Objective-C
+  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
   /// interface. The return value has type EHTypePtrTy.
-  llvm::Value *GetInterfaceEHType(const ObjCInterfaceType *IT);
+  llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
+                                  bool ForDefinition);
 
   const char *getMetaclassSymbolPrefix() const { 
     return "OBJC_METACLASS_$_";
@@ -891,6 +892,16 @@
   return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
 }
 
+/// hasObjCExceptionAttribute - Return true if this class or any super
+/// class has the __objc_exception__ attribute.
+static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *OID) {
+  if (OID->getAttr<ObjCExceptionAttr>())
+    return true;
+  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+    return hasObjCExceptionAttribute(Super);
+  return false;
+}
+
 /* *** CGObjCMac Public Interface *** */
  
 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
@@ -4238,6 +4249,10 @@
   flags = CLS;
   if (classIsHidden)
     flags |= OBJC2_CLS_HIDDEN;
+
+  if (hasObjCExceptionAttribute(ID->getClassInterface()))
+    flags |= CLS_EXCEPTION;
+
   if (!ID->getClassInterface()->getSuperClass()) {
     flags |= CLS_ROOT;
     SuperClassGV = 0;
@@ -4287,6 +4302,10 @@
                        classIsHidden);
   UsedGlobals.push_back(ClassMD);
   DefinedClasses.push_back(ClassMD);
+
+  // Force the definition of the EHType if necessary.
+  if (flags & CLS_EXCEPTION)
+    GetInterfaceEHType(ID->getClassInterface(), true);
 }
 
 /// GenerateProtocolRef - This routine is called to generate code for
@@ -5356,7 +5375,7 @@
         const ObjCInterfaceType *IT = 
           PT->getPointeeType()->getAsObjCInterfaceType();
         assert(IT && "Invalid @catch type.");
-        llvm::Value *EHType = GetInterfaceEHType(IT);
+        llvm::Value *EHType = GetInterfaceEHType(IT->getDecl(), false);
         SelectorArgs.push_back(EHType);
       }
     }
@@ -5544,32 +5563,32 @@
   CGF.Builder.ClearInsertionPoint();
 }
 
-static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *OID) {
-  if (OID->getAttr<ObjCExceptionAttr>())
-    return true;
-  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
-    return hasObjCExceptionAttribute(Super);
-  return false;
-}
-
 llvm::Value *
-CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) {
-  const ObjCInterfaceDecl *ID = IT->getDecl();
+CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 
+                                           bool ForDefinition) {
   llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
-  if (Entry)
-    return Entry;
-
-  // If this type (or a super class) has the __objc_exception__
-  // attribute, emit an external reference.
-  if (hasObjCExceptionAttribute(IT->getDecl()))
-    return Entry = 
-      new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
-                               llvm::GlobalValue::ExternalLinkage,
-                               0, 
-                               (std::string("OBJC_EHTYPE_$_") + 
-                                ID->getIdentifier()->getName()),
-                               &CGM.getModule());
 
+  // If we don't need a definition, return the entry if found or check
+  // if we use an external reference.
+  if (!ForDefinition) {
+    if (Entry)
+      return Entry;
+
+    // If this type (or a super class) has the __objc_exception__
+    // attribute, emit an external reference.
+    if (hasObjCExceptionAttribute(ID))
+      return Entry = 
+        new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
+                                 llvm::GlobalValue::ExternalLinkage,
+                                 0, 
+                                 (std::string("OBJC_EHTYPE_$_") + 
+                                  ID->getIdentifier()->getName()),
+                                 &CGM.getModule());
+  }
+  
+  // Otherwise we need to either make a new entry or fill in the
+  // initializer.
+  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
   std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
   std::string VTableName = "objc_ehtype_vtable";
   llvm::GlobalVariable *VTableGV = 
@@ -5587,17 +5606,28 @@
   Values[2] = GetClassGlobal(ClassName, false);
   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
 
-  Entry = 
-    new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
-                             llvm::GlobalValue::WeakAnyLinkage,
-                             Init, 
-                             (std::string("OBJC_EHTYPE_$_") + 
-                              ID->getIdentifier()->getName()),
-                             &CGM.getModule());
+  if (Entry) {
+    Entry->setInitializer(Init);
+  } else {
+    Entry = new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false,
+                                     llvm::GlobalValue::WeakAnyLinkage,
+                                     Init, 
+                                     (std::string("OBJC_EHTYPE_$_") + 
+                                      ID->getIdentifier()->getName()),
+                                     &CGM.getModule());
+  }
+
   if (CGM.getLangOptions().getVisibilityMode() ==
       LangOptions::HiddenVisibility)
     Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  Entry->setSection("__DATA,__datacoal_nt,coalesced");
+  Entry->setAlignment(8);
+
+  if (ForDefinition) {
+    Entry->setSection("__DATA,__objc_const");
+    Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
+  } else {
+    Entry->setSection("__DATA,__datacoal_nt,coalesced");
+  }
 
   return Entry;
 }

Modified: cfe/trunk/test/CodeGenObjC/metadata_symbols.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/metadata_symbols.m?rev=68591&r1=68590&r2=68591&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenObjC/metadata_symbols.m (original)
+++ cfe/trunk/test/CodeGenObjC/metadata_symbols.m Tue Apr  7 23:21:03 2009
@@ -2,8 +2,10 @@
 
 // RUN: grep '@"OBJC_METACLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t && 
 // RUN: grep '@"OBJC_CLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t &&
-// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak global .*section "__DATA,__datacoal_nt,coalesced", align 8' %t &&
 // RUN: grep '@"OBJC_EHTYPE_$_EH2" = external global' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH3" = global .*section "__DATA,__objc_const", align 8' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH3"' %t | count 3 &&
 // RUN: grep -F 'define internal void @"\01-[A im0]"' %t &&
 // FIXME: Should include category name.
 // RUN: grep -F 'define internal void @"\01-[A im1]"' %t &&
@@ -13,6 +15,8 @@
 // RUN: grep '@"OBJC_METACLASS_$_A" = hidden global .*section "__DATA, __objc_data", align 8' %t && 
 // RUN: grep '@"OBJC_CLASS_$_A" = hidden global .*section "__DATA, __objc_data", align 8' %t &&
 // RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak hidden global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH2" = external global' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH3" = hidden global .*section "__DATA,__objc_const", align 8' %t &&
 // RUN: grep -F 'define internal void @"\01-[A im0]"' %t &&
 // FIXME: Should include category name.
 // RUN: grep -F 'define internal void @"\01-[A im1]"' %t &&
@@ -39,6 +43,10 @@
 @interface EH2
 @end
 
+__attribute__((__objc_exception__))
+ at interface EH3
+ at end
+
 void f1();
 
 void f0(id x) {
@@ -46,5 +54,9 @@
     f1();
   } @catch (EH1 *x) {
   } @catch (EH2 *x) {
+  } @catch (EH3 *x) {
   }
 }
+
+ at implementation EH3
+ at end





More information about the cfe-commits mailing list