Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
llvm-epi-0.8
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
Roger Ferrer
llvm-epi-0.8
Commits
53418916
Commit
53418916
authored
13 years ago
by
Howard Hinnant
Browse files
Options
Downloads
Patches
Plain Diff
I'm beginning to be able to throw/catch a wide variety of objects.
llvm-svn: 148713
parent
880bc164
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
libcxxabi/src/private_typeinfo.cpp
+212
-10
212 additions, 10 deletions
libcxxabi/src/private_typeinfo.cpp
libcxxabi/src/private_typeinfo.h
+12
-0
12 additions, 0 deletions
libcxxabi/src/private_typeinfo.h
with
224 additions
and
10 deletions
libcxxabi/src/private_typeinfo.cpp
+
212
−
10
View file @
53418916
...
...
@@ -201,16 +201,17 @@ __pointer_to_member_type_info::display() const
// 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.
// 1. 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
// 2. the handler is of type cv T or cv T& and T is an unambiguous public
// base class of E, or
// 3. 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. a standard pointer conversion (4.10) not involving conversions to
// pointers to private or protected or ambiguous classes
// B. a qualification conversion
// 4. the handler is a pointer or pointer to member type and E is
// std::nullptr_t.
// adjustedPtr:
//
...
...
@@ -233,6 +234,207 @@ __shim_type_info::can_catch(const __shim_type_info* thrown_type,
return
this
==
thrown_type
;
}
// Handles bullet 1
// TODO: Let __shim_type_info handle it?
bool
__fundamental_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
)
const
{
return
this
==
thrown_type
;
}
bool
__array_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
)
const
{
// TODO: Can this be called?
return
false
;
}
bool
__function_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
)
const
{
// TODO: Can this be called?
return
false
;
}
// Handles bullet 1
// TODO: Let __shim_type_info handle it?
bool
__enum_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
)
const
{
return
this
==
thrown_type
;
}
// Handles bullets 1 and 2
bool
__class_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
adjustedPtr
)
const
{
// bullet 1
if
(
this
==
thrown_type
)
return
true
;
const
__class_type_info
*
thrown_class_type
=
dynamic_cast
<
const
__class_type_info
*>
(
thrown_type
);
if
(
thrown_class_type
==
0
)
return
false
;
// bullet 2
__dynamic_cast_info
info
=
{
thrown_class_type
,
0
,
this
,
-
1
,
0
};
info
.
number_of_dst_type
=
1
;
thrown_class_type
->
has_unambiguous_public_base
(
&
info
,
adjustedPtr
,
public_path
);
if
(
info
.
path_dst_ptr_to_static_ptr
==
public_path
)
{
adjustedPtr
=
const_cast
<
void
*>
(
info
.
dst_ptr_leading_to_static_ptr
);
return
true
;
}
return
false
;
}
void
__class_type_info
::
process_found_base_class
(
__dynamic_cast_info
*
info
,
void
*
adjustedPtr
,
int
path_below
)
const
{
if
(
info
->
dst_ptr_leading_to_static_ptr
==
0
)
{
// First time here
info
->
dst_ptr_leading_to_static_ptr
=
adjustedPtr
;
info
->
path_dst_ptr_to_static_ptr
=
path_below
;
info
->
number_to_static_ptr
=
1
;
}
else
if
(
info
->
dst_ptr_leading_to_static_ptr
==
adjustedPtr
)
{
// We've been here before. Update path to "most public"
if
(
info
->
path_dst_ptr_to_static_ptr
==
not_public_path
)
info
->
path_dst_ptr_to_static_ptr
=
path_below
;
}
else
{
// We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
// to a static_type
info
->
number_to_static_ptr
+=
1
;
info
->
path_dst_ptr_to_static_ptr
=
not_public_path
;
info
->
search_done
=
true
;
}
}
void
__class_type_info
::
has_unambiguous_public_base
(
__dynamic_cast_info
*
info
,
void
*
adjustedPtr
,
int
path_below
)
const
{
if
(
this
==
info
->
static_type
)
process_found_base_class
(
info
,
adjustedPtr
,
path_below
);
}
void
__si_class_type_info
::
has_unambiguous_public_base
(
__dynamic_cast_info
*
info
,
void
*
adjustedPtr
,
int
path_below
)
const
{
if
(
this
==
info
->
static_type
)
process_found_base_class
(
info
,
adjustedPtr
,
path_below
);
else
__base_type
->
has_unambiguous_public_base
(
info
,
adjustedPtr
,
path_below
);
}
void
__base_class_type_info
::
has_unambiguous_public_base
(
__dynamic_cast_info
*
info
,
void
*
adjustedPtr
,
int
path_below
)
const
{
ptrdiff_t
offset_to_base
=
__offset_flags
>>
__offset_shift
;
if
(
__offset_flags
&
__virtual_mask
)
{
const
char
*
vtable
=
*
static_cast
<
const
char
*
const
*>
(
adjustedPtr
);
offset_to_base
=
*
reinterpret_cast
<
const
ptrdiff_t
*>
(
vtable
+
offset_to_base
);
}
__base_type
->
has_unambiguous_public_base
(
info
,
static_cast
<
char
*>
(
adjustedPtr
)
+
offset_to_base
,
(
__offset_flags
&
__public_mask
)
?
path_below
:
not_public_path
);
}
void
__vmi_class_type_info
::
has_unambiguous_public_base
(
__dynamic_cast_info
*
info
,
void
*
adjustedPtr
,
int
path_below
)
const
{
if
(
this
==
info
->
static_type
)
process_found_base_class
(
info
,
adjustedPtr
,
path_below
);
else
{
typedef
const
__base_class_type_info
*
Iter
;
const
Iter
e
=
__base_info
+
__base_count
;
Iter
p
=
__base_info
;
p
->
has_unambiguous_public_base
(
info
,
adjustedPtr
,
path_below
);
if
(
++
p
<
e
)
{
do
{
p
->
has_unambiguous_public_base
(
info
,
adjustedPtr
,
path_below
);
if
(
info
->
search_done
)
break
;
}
while
(
++
p
<
e
);
}
}
}
// Handles bullets 1 and 4
// TODO: Are we good to go here for __pointer_to_member_type_info?
bool
__pbase_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
)
const
{
if
(
this
==
thrown_type
)
return
true
;
return
thrown_type
==
&
typeid
(
std
::
nullptr_t
);
}
// Handles bullets 1, 3 and 4
bool
__pointer_type_info
::
can_catch
(
const
__shim_type_info
*
thrown_type
,
void
*&
adjustedPtr
)
const
{
// Do the dereference adjustment
adjustedPtr
=
*
static_cast
<
void
**>
(
adjustedPtr
);
// bullets 1 and 4
if
(
__pbase_type_info
::
can_catch
(
thrown_type
,
adjustedPtr
))
return
true
;
// bullet 3
const
__pointer_type_info
*
thrown_pointer_type
=
dynamic_cast
<
const
__pointer_type_info
*>
(
thrown_type
);
if
(
thrown_pointer_type
==
0
)
return
false
;
// bullet 3B
if
(
thrown_pointer_type
->
__flags
&
~
__flags
)
return
false
;
if
(
__pointee
==
thrown_pointer_type
->
__pointee
)
return
true
;
// bullet 3A
if
(
__pointee
==
&
typeid
(
void
))
return
true
;
const
__class_type_info
*
catch_class_type
=
dynamic_cast
<
const
__class_type_info
*>
(
__pointee
);
if
(
catch_class_type
==
0
)
return
false
;
const
__class_type_info
*
thrown_class_type
=
dynamic_cast
<
const
__class_type_info
*>
(
thrown_pointer_type
->
__pointee
);
if
(
thrown_class_type
==
0
)
return
false
;
__dynamic_cast_info
info
=
{
thrown_class_type
,
0
,
catch_class_type
,
-
1
,
0
};
info
.
number_of_dst_type
=
1
;
thrown_class_type
->
has_unambiguous_public_base
(
&
info
,
adjustedPtr
,
public_path
);
if
(
info
.
path_dst_ptr_to_static_ptr
==
public_path
)
{
adjustedPtr
=
const_cast
<
void
*>
(
info
.
dst_ptr_leading_to_static_ptr
);
return
true
;
}
return
false
;
}
#pragma GCC visibility pop
#pragma GCC visibility push(default)
...
...
This diff is collapsed.
Click to expand it.
libcxxabi/src/private_typeinfo.h
+
12
−
0
View file @
53418916
...
...
@@ -33,6 +33,7 @@ class __fundamental_type_info
{
public:
virtual
~
__fundamental_type_info
();
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -41,6 +42,7 @@ class __array_type_info
{
public:
virtual
~
__array_type_info
();
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -49,6 +51,7 @@ class __function_type_info
{
public:
virtual
~
__function_type_info
();
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -57,6 +60,7 @@ class __enum_type_info
{
public:
virtual
~
__enum_type_info
();
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -127,8 +131,11 @@ public:
void
process_static_type_above_dst
(
__dynamic_cast_info
*
,
const
void
*
,
const
void
*
,
int
)
const
;
void
process_static_type_below_dst
(
__dynamic_cast_info
*
,
const
void
*
,
int
)
const
;
void
process_found_base_class
(
__dynamic_cast_info
*
,
void
*
,
int
)
const
;
virtual
void
search_above_dst
(
__dynamic_cast_info
*
,
const
void
*
,
const
void
*
,
int
)
const
;
virtual
void
search_below_dst
(
__dynamic_cast_info
*
,
const
void
*
,
int
)
const
;
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
virtual
void
has_unambiguous_public_base
(
__dynamic_cast_info
*
,
void
*
,
int
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -143,6 +150,7 @@ public:
virtual
void
search_above_dst
(
__dynamic_cast_info
*
,
const
void
*
,
const
void
*
,
int
)
const
;
virtual
void
search_below_dst
(
__dynamic_cast_info
*
,
const
void
*
,
int
)
const
;
virtual
void
has_unambiguous_public_base
(
__dynamic_cast_info
*
,
void
*
,
int
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -161,6 +169,7 @@ public:
void
search_above_dst
(
__dynamic_cast_info
*
,
const
void
*
,
const
void
*
,
int
)
const
;
void
search_below_dst
(
__dynamic_cast_info
*
,
const
void
*
,
int
)
const
;
void
has_unambiguous_public_base
(
__dynamic_cast_info
*
,
void
*
,
int
)
const
;
void
display
()
const
;
};
...
...
@@ -185,6 +194,7 @@ public:
virtual
void
search_above_dst
(
__dynamic_cast_info
*
,
const
void
*
,
const
void
*
,
int
)
const
;
virtual
void
search_below_dst
(
__dynamic_cast_info
*
,
const
void
*
,
int
)
const
;
virtual
void
has_unambiguous_public_base
(
__dynamic_cast_info
*
,
void
*
,
int
)
const
;
virtual
void
display
()
const
;
};
...
...
@@ -205,6 +215,7 @@ public:
};
virtual
~
__pbase_type_info
();
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
};
class
__pointer_type_info
...
...
@@ -212,6 +223,7 @@ class __pointer_type_info
{
public:
virtual
~
__pointer_type_info
();
virtual
bool
can_catch
(
const
__shim_type_info
*
,
void
*&
)
const
;
virtual
void
display
()
const
;
};
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment