[cfe-commits] [libcxxabi] r148666 - in /libcxxabi/trunk/src: cxa_personality.cpp private_typeinfo.cpp private_typeinfo.h
Howard Hinnant
hhinnant at apple.com
Sun Jan 22 13:47:40 PST 2012
Author: hhinnant
Date: Sun Jan 22 15:47:40 2012
New Revision: 148666
URL: http://llvm.org/viewvc/llvm-project?rev=148666&view=rev
Log:
Getting started on matching a thrown exception to a catch clause, and setting the adjusted pointer to the caught object appearing in the catch clause.
Modified:
libcxxabi/trunk/src/cxa_personality.cpp
libcxxabi/trunk/src/private_typeinfo.cpp
libcxxabi/trunk/src/private_typeinfo.h
Modified: libcxxabi/trunk/src/cxa_personality.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_personality.cpp?rev=148666&r1=148665&r2=148666&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_personality.cpp (original)
+++ libcxxabi/trunk/src/cxa_personality.cpp Sun Jan 22 15:47:40 2012
@@ -14,6 +14,7 @@
#include "unwind.h"
#include "cxa_exception.hpp"
+#include "private_typeinfo.h"
#include <typeinfo>
#include <stdlib.h>
#include <assert.h>
@@ -219,6 +220,8 @@
return classInfo - typeOffset;
}
+static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
+
/// Deals with Dwarf actions matching our type infos
/// (OurExceptionType_t instances). Returns whether or not a dwarf emitted
/// action matches the supplied exception type. If such a match succeeds,
@@ -240,7 +243,12 @@
_Unwind_Exception* unwind_exception, uint8_t ttypeEncoding)
{
__cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
- const std::type_info* excpType = exception_header->exceptionType;
+ void* thrown_object =
+ unwind_exception->exception_class == kOurDependentExceptionClass ?
+ ((__cxa_dependent_exception*)exception_header)->primaryException :
+ exception_header + 1;
+ const __shim_type_info* excpType =
+ static_cast<const __shim_type_info*>(exception_header->exceptionType);
const uint8_t* actionPos = (uint8_t*)actionEntry;
while (true)
{
@@ -255,14 +263,17 @@
{
const uint8_t* TTypeEntry = getTTypeEntry(typeOffset, classInfo,
ttypeEncoding);
- const std::type_info* catchType =
- (const std::type_info*)readEncodedPointer(&TTypeEntry,
+ const __shim_type_info* catchType =
+ (const __shim_type_info*)readEncodedPointer(&TTypeEntry,
ttypeEncoding);
+ void* adjustedPtr = thrown_object;
// catchType == 0 -> catch (...)
- if (catchType == 0 || excpType == catchType)
+ if (catchType == 0 || catchType->can_catch(excpType, adjustedPtr))
{
exception_header->handlerSwitchValue = typeOffset;
- exception_header->actionRecord = SactionPos;
+ exception_header->actionRecord = SactionPos; // unnecessary?
+ // used by __cxa_get_exception_ptr and __cxa_begin_catch
+ exception_header->adjustedPtr = adjustedPtr;
return true;
}
}
@@ -289,9 +300,6 @@
__cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
exception_header->languageSpecificData = lsda;
- // set adjustedPtr! __cxa_get_exception_ptr and __cxa_begin_catch use it.
- // TODO: Put it where it is supposed to be and adjust it properly
- exception_header->adjustedPtr = unwind_exception+1;
if (lsda)
{
// Get the current instruction pointer and offset it before next
Modified: libcxxabi/trunk/src/private_typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=148666&r1=148665&r2=148666&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.cpp (original)
+++ libcxxabi/trunk/src/private_typeinfo.cpp Sun Jan 22 15:47:40 2012
@@ -198,6 +198,42 @@
__pointee->display();
}
+// can_catch
+
+// A handler is a match for an exception object of type E if
+// * The handler is of type cv T or cv T& and E and T are the same type
+// (ignoring the top-level cv-qualifiers), or
+// * the handler is of type cv T or cv T& and T is an unambiguous public
+// base class of E, or
+// * the handler is of type cv1 T* cv2 and E is a pointer type that can be
+// converted to the type of the handler by either or both of
+// * a standard pointer conversion (4.10) not involving conversions to
+// pointers to private or protected or ambiguous classes
+// * a qualification conversion
+// * the handler is a pointer or pointer to member type and E is std::nullptr_t.
+
+// adjustedPtr:
+//
+// catch (A& a) : adjustedPtr == &a
+// catch (A* a) : adjustedPtr == a
+// catch (A** a) : adjustedPtr == a
+//
+// catch (D2& d2) : adjustedPtr == &d2 (d2 is base class of thrown object)
+// catch (D2* d2) : adjustedPtr == d2
+// catch (D2*& d2) : adjustedPtr == d2
+//
+// catch (...) : adjustedPtr == & of the exception
+
+// TODO: can_catch looks similar to search_above_dst. Reuse?
+
+bool
+__shim_type_info::can_catch(const __shim_type_info* thrown_type,
+ void*&) const
+{
+ return this == thrown_type;
+}
+
+
#pragma GCC visibility pop
#pragma GCC visibility push(default)
Modified: libcxxabi/trunk/src/private_typeinfo.h
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.h?rev=148666&r1=148665&r2=148666&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.h (original)
+++ libcxxabi/trunk/src/private_typeinfo.h Sun Jan 22 15:47:40 2012
@@ -24,6 +24,7 @@
public:
virtual ~__shim_type_info();
+ virtual bool can_catch(const __shim_type_info* thrown_type, void*& adjustedPtr) const;
virtual void display() const = 0;
};
More information about the cfe-commits
mailing list