exception.cc (232950) | exception.cc (233235) |
---|---|
1/* 2 * Copyright 2010-2011 PathScale, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 833 unchanged lines hidden (view full) --- 842 * Checks the type signature found in a handler against the type of the thrown 843 * object. If ex is 0 then it is assumed to be a foreign exception and only 844 * matches cleanups. 845 */ 846static bool check_type_signature(__cxa_exception *ex, 847 const std::type_info *type, 848 void *&adjustedPtr) 849{ | 1/* 2 * Copyright 2010-2011 PathScale, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 833 unchanged lines hidden (view full) --- 842 * Checks the type signature found in a handler against the type of the thrown 843 * object. If ex is 0 then it is assumed to be a foreign exception and only 844 * matches cleanups. 845 */ 846static bool check_type_signature(__cxa_exception *ex, 847 const std::type_info *type, 848 void *&adjustedPtr) 849{ |
850 // TODO: For compatibility with the GNU implementation, we should move this 851 // out into a __do_catch() virtual function in std::type_info | |
852 void *exception_ptr = (void*)(ex+1); | 850 void *exception_ptr = (void*)(ex+1); |
853 const std::type_info *ex_type = ex->exceptionType; | 851 const std::type_info *ex_type = ex->exceptionType; |
854 | 852 |
855 const __pointer_type_info *ptr_type = 856 dynamic_cast<const __pointer_type_info*>(ex_type); 857 if (0 != ptr_type) | 853 bool is_ptr = ex_type->__is_pointer_p(); 854 if (is_ptr) |
858 { 859 exception_ptr = *(void**)exception_ptr; 860 } 861 // Always match a catchall, even with a foreign exception 862 // 863 // Note: A 0 here is a catchall, not a cleanup, so we return true to 864 // indicate that we found a catch. | 855 { 856 exception_ptr = *(void**)exception_ptr; 857 } 858 // Always match a catchall, even with a foreign exception 859 // 860 // Note: A 0 here is a catchall, not a cleanup, so we return true to 861 // indicate that we found a catch. |
865 // 866 // TODO: Provide a class for matching against foreign exceptions. This is 867 // already done in libobjc2, allowing C++ exceptions to be boxed as 868 // Objective-C objects. We should do something similar, allowing foreign 869 // exceptions to be wrapped in a C++ exception and delivered. | |
870 if (0 == type) 871 { 872 if (ex) 873 { 874 adjustedPtr = exception_ptr; 875 } 876 return true; 877 } 878 879 if (0 == ex) { return false; } 880 | 862 if (0 == type) 863 { 864 if (ex) 865 { 866 adjustedPtr = exception_ptr; 867 } 868 return true; 869 } 870 871 if (0 == ex) { return false; } 872 |
881 const __pointer_type_info *target_ptr_type = 882 dynamic_cast<const __pointer_type_info*>(type); 883 884 if (0 != ptr_type && 0 != target_ptr_type) 885 { 886 if (ptr_type->__flags & ~target_ptr_type->__flags) 887 { 888 // Handler pointer is less qualified 889 return false; 890 } 891 892 // Special case for void* handler. 893 if(*target_ptr_type->__pointee == typeid(void)) 894 { 895 adjustedPtr = exception_ptr; 896 return true; 897 } 898 899 ex_type = ptr_type->__pointee; 900 type = target_ptr_type->__pointee; 901 } 902 | |
903 // If the types are the same, no casting is needed. 904 if (*type == *ex_type) 905 { 906 adjustedPtr = exception_ptr; 907 return true; 908 } 909 | 873 // If the types are the same, no casting is needed. 874 if (*type == *ex_type) 875 { 876 adjustedPtr = exception_ptr; 877 return true; 878 } 879 |
910 const __class_type_info *cls_type = 911 dynamic_cast<const __class_type_info*>(ex_type); 912 const __class_type_info *target_cls_type = 913 dynamic_cast<const __class_type_info*>(type); | |
914 | 880 |
915 if (0 != cls_type && 916 0 != target_cls_type && 917 cls_type->can_cast_to(target_cls_type)) | 881 if (type->__do_catch(ex_type, &exception_ptr, 1)) |
918 { | 882 { |
919 adjustedPtr = cls_type->cast_to(exception_ptr, target_cls_type); | 883 adjustedPtr = exception_ptr; |
920 return true; 921 } | 884 return true; 885 } |
886 |
|
922 return false; 923} 924/** 925 * Checks whether the exception matches the type specifiers in this action 926 * record. If the exception only matches cleanups, then this returns false. 927 * If it matches a catch (including a catchall) then it returns true. 928 * 929 * The selector argument is used to return the selector that is passed in the --- 548 unchanged lines hidden --- | 887 return false; 888} 889/** 890 * Checks whether the exception matches the type specifiers in this action 891 * record. If the exception only matches cleanups, then this returns false. 892 * If it matches a catch (including a catchall) then it returns true. 893 * 894 * The selector argument is used to return the selector that is passed in the --- 548 unchanged lines hidden --- |