]> granicus.if.org Git - clang/commitdiff
Handle use side of __objc_exception__ attribute; when using an
authorDaniel Dunbar <daniel@zuster.org>
Tue, 7 Apr 2009 06:43:45 +0000 (06:43 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 7 Apr 2009 06:43:45 +0000 (06:43 +0000)
exception with this attribute we don't need to emit a weak definition
for the exception type information.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68513 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjCMac.cpp
test/CodeGenObjC/metadata_symbols.m
utils/SummarizeErrors

index cf2d8da022ea36ad79b7911f0911b12a1a2f6f46..f410e213cb138ac6b510e5b93058d75c78964211 100644 (file)
@@ -5547,6 +5547,14 @@ void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
   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();
@@ -5554,6 +5562,17 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceType *IT) {
   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());
+
   std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
   std::string VTableName = "objc_ehtype_vtable";
   llvm::GlobalVariable *VTableGV = 
index 99372b829f42e61d213d7f8efdaca11e37a63160..7141813df45d68d699147ba3c1c468890af2ea35 100644 (file)
@@ -2,7 +2,8 @@
 
 // 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_$_EH" = weak global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH2" = external global' %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 &&
@@ -13,7 +14,7 @@
 // RUN: grep '@"OBJC_METACLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t && 
 // FIXME: This is wrong, should be hidden
 // RUN: grep '@"OBJC_CLASS_$_A" = global .*section "__DATA, __objc_data", align 8' %t &&
-// RUN: grep '@"OBJC_EHTYPE_$_EH" = weak hidden global .*section "__DATA,__datacoal_nt,coalesced"' %t &&
+// RUN: grep '@"OBJC_EHTYPE_$_EH1" = weak hidden global .*section "__DATA,__datacoal_nt,coalesced"' %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 &&
 }
 @end
 
-@interface EH
+@interface EH1
+@end
+
+__attribute__((__objc_exception__))
+@interface EH2
 @end
 
 void f1();
@@ -41,6 +46,7 @@ void f1();
 void f0(id x) {
   @try {
     f1();
-  } @catch (EH *x) {
+  } @catch (EH1 *x) {
+  } @catch (EH2 *x) {
   }
 }
index ca3086d9b7fd6ffb59ae61d456f8eedf9bb448df..64d78240dd2fa0f284aa29d17e939b9d9277464a 100755 (executable)
@@ -24,14 +24,17 @@ class multidict:
     def __len__(self):
         return len(self.data)
 
-kGCCErrorRE = re.compile('(.*):([0-9]+): error: (.*)')
-kGCCWarningRE = re.compile('(.*):([0-9]+): warning: (.*)')
-kClangErrorRE = re.compile('(.*):([0-9]+):([0-9]+): error: (.*)')
-kClangWarningRE = re.compile('(.*):([0-9]+):([0-9]+): warning: (.*)')
+kDiagnosticRE = re.compile(': (error|warning): (.*)')
 kAssertionRE = re.compile('Assertion failed: (.*, function .*, file .*, line [0-9]+\\.)')
-kStackDumpLineRE = re.compile('^[0-9]+ +([^ ]+) +0x[0-9a-fA-F]+ +([^ ]+)')
 
 def readInfo(path, opts):
+    lastProgress = [-100,0]
+    def progress(pos):
+        pct = (100. * pos) / (size * 2)
+        if (pct - lastProgress[0]) >= 10:
+            lastProgress[0] = pct
+            print '%d/%d = %.2f%%' % (pos, size*2, pct)
+
     f = open(path)
     data = f.read()
     f.close()
@@ -39,30 +42,45 @@ def readInfo(path, opts):
     if opts.truncate != -1:
         data = data[:opts.truncate]
 
-    gccwarnings = multidict([(m.group(3),m) for m in kGCCWarningRE.finditer(data)]).items()
-    gccerrors = multidict([(m.group(3),m) for m in kGCCErrorRE.finditer(data)]).items()
-    assertions = multidict([(m.group(1),m) for m in kAssertionRE.finditer(data)]).items()
+    size = len(data)
+    warnings = multidict()
+    errors = multidict()
+    for m in kDiagnosticRE.finditer(data):
+        progress(m.end())
+        if m.group(1) == 'error':
+            d = errors
+        else:
+            d = warnings
+        d[m.group(2)] = m
+    warnings = warnings.items()
+    errors = errors.items()
+    assertions = multidict()
+    for m in kAssertionRE.finditer(data):
+        print '%d/%d = %.2f%%' % (size + m.end(), size, (float(m.end()) / (size*2)) * 100.)
+        assertions[m.group(1)] = m
+    assertions = assertions.items()
 
     # Manual scan for stack traces
     aborts = multidict()
-    prevLine = None
-    lnIter = iter(data.split('\n'))
-    for ln in lnIter:
-        m = kStackDumpLineRE.match(ln)
-        if m:
-            stack = [m.group(2)]
-            for ln in lnIter:
-                m = kStackDumpLineRE.match(ln)
-                if not m:
-                    break
-                stack.append(m.group(2))
-            if prevLine is None or not kAssertionRE.match(prevLine):
-                aborts[tuple(stack)] = stack
-        prevLine = ln
+    if 0:
+        prevLine = None
+        lnIter = iter(data.split('\n'))
+        for ln in lnIter:
+            m = kStackDumpLineRE.match(ln)
+            if m:
+                stack = [m.group(2)]
+                for ln in lnIter:
+                    m = kStackDumpLineRE.match(ln)
+                    if not m:
+                        break
+                    stack.append(m.group(2))
+                if prevLine is None or not kAssertionRE.match(prevLine):
+                    aborts[tuple(stack)] = stack
+            prevLine = ln
 
     sections = [
-        (gccwarnings, 'Warnings'),
-        (gccerrors, 'Errors'),
+        (warnings, 'Warnings'),
+        (errors, 'Errors'),
         (assertions, 'Assertions'),
         (aborts.items(), 'Aborts'),
         ]