From: Daniel Dunbar Date: Tue, 7 Apr 2009 06:43:45 +0000 (+0000) Subject: Handle use side of __objc_exception__ attribute; when using an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e075cb62c06e0b0023fd12875c95da9c5ddefb7;p=clang Handle use side of __objc_exception__ attribute; when using an 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 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index cf2d8da022..f410e213cb 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -5547,6 +5547,14 @@ void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, CGF.Builder.ClearInsertionPoint(); } +static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *OID) { + if (OID->getAttr()) + 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 = diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m index 99372b829f..7141813df4 100644 --- a/test/CodeGenObjC/metadata_symbols.m +++ b/test/CodeGenObjC/metadata_symbols.m @@ -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 && @@ -33,7 +34,11 @@ } @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) { } } diff --git a/utils/SummarizeErrors b/utils/SummarizeErrors index ca3086d9b7..64d78240dd 100755 --- a/utils/SummarizeErrors +++ b/utils/SummarizeErrors @@ -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'), ]