[cfe-commits] r109298 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/CodeGen/CGException.cpp lib/CodeGen/CGObjCGNU.cpp lib/CodeGen/CGObjCMac.cpp lib/CodeGen/CGObjCRuntime.h lib/Sema/SemaDeclCXX.cpp test/CodeGenObjCXX/exceptions.mm test/SemaObjCXX/exceptions-fragile.mm
John McCall
rjmccall at apple.com
Fri Jul 23 17:37:23 PDT 2010
Author: rjmccall
Date: Fri Jul 23 19:37:23 2010
New Revision: 109298
URL: http://llvm.org/viewvc/llvm-project?rev=109298&view=rev
Log:
Support catching Objective C pointers in C++ under the non-fragile NeXT runtime.
Diagnose attempts to do this under the GNU or fragile NeXT runtimes.
Added:
cfe/trunk/test/CodeGenObjCXX/exceptions.mm
cfe/trunk/test/SemaObjCXX/exceptions-fragile.mm
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/CodeGen/CGException.cpp
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/CodeGen/CGObjCRuntime.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=109298&r1=109297&r2=109298&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jul 23 19:37:23 2010
@@ -2266,7 +2266,13 @@
"'register' storage specifier on @catch parameter will be ignored">;
def err_qualified_objc_catch_parm : Error<
"@catch parameter declarator cannot be qualified">;
-
+def err_objc_pointer_cxx_catch_gnu : Error<
+ "can't catch Objective C exceptions in C++ in the GNU runtime">;
+def err_objc_pointer_cxx_catch_fragile : Error<
+ "can't catch Objective C exceptions in C++ in the non-unified "
+ "exception model">;
+def err_objc_object_catch : Error<
+ "can't catch an Objective C object by value">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=109298&r1=109297&r2=109298&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Fri Jul 23 19:37:23 2010
@@ -16,6 +16,7 @@
#include "llvm/Intrinsics.h"
#include "llvm/Support/CallSite.h"
+#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
#include "CGException.h"
#include "TargetInfo.h"
@@ -617,7 +618,12 @@
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
QualType CaughtType = C->getCaughtType();
CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();
- llvm::Value *TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, true);
+
+ llvm::Value *TypeInfo = 0;
+ if (CaughtType->isObjCObjectPointerType())
+ TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
+ else
+ TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, true);
CatchScope->setHandler(I, TypeInfo, Handler);
} else {
// No exception decl indicates '...', a catch-all.
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=109298&r1=109297&r2=109298&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Fri Jul 23 19:37:23 2010
@@ -167,6 +167,7 @@
bool lval = false);
virtual llvm::Value *GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl
*Method);
+ virtual llvm::Constant *GetEHType(QualType T);
virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD);
@@ -403,6 +404,11 @@
return Builder.CreateLoad(Sel);
}
+llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
+ llvm_unreachable("asking for catch type for ObjC type in GNU runtime");
+ return 0;
+}
+
llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
const std::string &Name) {
llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str());
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=109298&r1=109297&r2=109298&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Jul 23 19:37:23 2010
@@ -1184,6 +1184,8 @@
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method);
+ virtual llvm::Constant *GetEHType(QualType T);
+
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
@@ -1354,7 +1356,7 @@
/// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
/// interface. The return value has type EHTypePtrTy.
- llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
+ llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
bool ForDefinition);
const char *getMetaclassSymbolPrefix() const {
@@ -1429,6 +1431,8 @@
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
const ObjCProtocolDecl *PD);
+ virtual llvm::Constant *GetEHType(QualType T);
+
virtual llvm::Constant *GetPropertyGetFunction() {
return ObjCTypes.getGetPropertyFn();
}
@@ -1527,6 +1531,11 @@
return EmitSelector(Builder, Method->getSelector());
}
+llvm::Constant *CGObjCMac::GetEHType(QualType T) {
+ llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
+ return 0;
+}
+
/// Generate a constant CFString object.
/*
struct __builtin_CFString {
@@ -5777,6 +5786,31 @@
};
}
+llvm::Constant *
+CGObjCNonFragileABIMac::GetEHType(QualType T) {
+ // There's a particular fixed type info for 'id'.
+ if (T->isObjCIdType() ||
+ T->isObjCQualifiedIdType()) {
+ llvm::Constant *IDEHType =
+ CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
+ if (!IDEHType)
+ IDEHType =
+ new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
+ false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0, "OBJC_EHTYPE_id");
+ return IDEHType;
+ }
+
+ // All other types should be Objective-C interface pointer types.
+ const ObjCObjectPointerType *PT =
+ T->getAs<ObjCObjectPointerType>();
+ assert(PT && "Invalid @catch type.");
+ const ObjCInterfaceType *IT = PT->getInterfaceType();
+ assert(IT && "Invalid @catch type.");
+ return GetInterfaceEHType(IT->getDecl(), false);
+}
+
void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
// Jump destination for falling out of catch bodies.
@@ -5812,27 +5846,7 @@
break;
}
- // There's a particular fixed type info for 'id'.
- if (CatchDecl->getType()->isObjCIdType() ||
- CatchDecl->getType()->isObjCQualifiedIdType()) {
- llvm::Value *IDEHType =
- CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
- if (!IDEHType)
- IDEHType =
- new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
- false,
- llvm::GlobalValue::ExternalLinkage,
- 0, "OBJC_EHTYPE_id");
- Handler.TypeInfo = IDEHType;
- } else {
- // All other types should be Objective-C interface pointer types.
- const ObjCObjectPointerType *PT =
- CatchDecl->getType()->getAs<ObjCObjectPointerType>();
- assert(PT && "Invalid @catch type.");
- const ObjCInterfaceType *IT = PT->getInterfaceType();
- assert(IT && "Invalid @catch type.");
- Handler.TypeInfo = GetInterfaceEHType(IT->getDecl(), false);
- }
+ Handler.TypeInfo = GetEHType(CatchDecl->getType());
}
EHCatchScope *Catch = CGF.EHStack.pushCatch(Handlers.size());
@@ -5931,7 +5945,7 @@
CGF.Builder.ClearInsertionPoint();
}
-llvm::Value *
+llvm::Constant *
CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
bool ForDefinition) {
llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=109298&r1=109297&r2=109298&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Fri Jul 23 19:37:23 2010
@@ -103,6 +103,12 @@
virtual llvm::Value *GetSelector(CGBuilderTy &Builder,
const ObjCMethodDecl *Method) = 0;
+ /// Get the type constant to catch for the given ObjC pointer type.
+ /// This is used externally to implement catching ObjC types in C++.
+ /// Runtimes which don't support this should add the appropriate
+ /// error to Sema.
+ virtual llvm::Constant *GetEHType(QualType T) = 0;
+
/// Generate a constant string object.
virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=109298&r1=109297&r2=109298&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Jul 23 19:37:23 2010
@@ -5983,6 +5983,27 @@
AbstractVariableType))
Invalid = true;
+ // Only the non-fragile NeXT runtime currently supports C++ catches
+ // of ObjC types, and no runtime supports catching ObjC types by value.
+ if (!Invalid && getLangOptions().ObjC1) {
+ QualType T = ExDeclType;
+ if (const ReferenceType *RT = T->getAs<ReferenceType>())
+ T = RT->getPointeeType();
+
+ if (T->isObjCObjectType()) {
+ Diag(Loc, diag::err_objc_object_catch);
+ Invalid = true;
+ } else if (T->isObjCObjectPointerType()) {
+ if (!getLangOptions().NeXTRuntime) {
+ Diag(Loc, diag::err_objc_pointer_cxx_catch_gnu);
+ Invalid = true;
+ } else if (!getLangOptions().ObjCNonFragileABI) {
+ Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
+ Invalid = true;
+ }
+ }
+ }
+
VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
Name, ExDeclType, TInfo, VarDecl::None,
VarDecl::None);
Added: cfe/trunk/test/CodeGenObjCXX/exceptions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/exceptions.mm?rev=109298&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/exceptions.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/exceptions.mm Fri Jul 23 19:37:23 2010
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-nonfragile-abi -fexceptions -o - %s | FileCheck %s
+
+ at interface OCType @end
+void opaque();
+
+namespace test0 {
+
+ // CHECK: define void @_ZN5test03fooEv
+ void foo() {
+ try {
+ // CHECK: invoke void @_Z6opaquev
+ opaque();
+ } catch (OCType *T) {
+ // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} @__objc_personality_v0 {{.*}} @"OBJC_EHTYPE_$_OCType"
+ }
+ }
+}
Added: cfe/trunk/test/SemaObjCXX/exceptions-fragile.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/exceptions-fragile.mm?rev=109298&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjCXX/exceptions-fragile.mm (added)
+++ cfe/trunk/test/SemaObjCXX/exceptions-fragile.mm Fri Jul 23 19:37:23 2010
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+ at interface NSException @end
+void opaque();
+
+namespace test0 {
+ void test() {
+ try {
+ } catch (NSException *e) { // expected-error {{can't catch Objective C exceptions in C++ in the non-unified exception model}}
+ }
+ }
+}
More information about the cfe-commits
mailing list