зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
7f48c6e0f0
Коммит
7e075cb62c
|
@ -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 =
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,12 +42,27 @@ 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()
|
||||
if 0:
|
||||
prevLine = None
|
||||
lnIter = iter(data.split('\n'))
|
||||
for ln in lnIter:
|
||||
|
@ -61,8 +79,8 @@ def readInfo(path, opts):
|
|||
prevLine = ln
|
||||
|
||||
sections = [
|
||||
(gccwarnings, 'Warnings'),
|
||||
(gccerrors, 'Errors'),
|
||||
(warnings, 'Warnings'),
|
||||
(errors, 'Errors'),
|
||||
(assertions, 'Assertions'),
|
||||
(aborts.items(), 'Aborts'),
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче