Using llvm-style rtti gives us stronger guarantees around casting
LanguageRuntimes.
As discussed in D62755
Paths
| Differential D62934
[LanguageRuntime] Introdce LLVM-style casts ClosedPublic Authored by xiaobai on Jun 5 2019, 3:05 PM.
Details Summary Using llvm-style rtti gives us stronger guarantees around casting As discussed in D62755
Diff Detail
Event TimelineComment Actions Implementing classof via an enum is the simplest and most common solution, but it is not the only thing possible. The central enum thingy is fine when all the subclasses are also defined centrally, but for a more distributed scenario like this one, it begins to smell, as now the LanguageRuntime class suddenly needs to be aware of all of its subclasses. A way to implement that without the all-encompassing enum would be via something like: struct Runtime: { virtual bool isA(const void *ClassID) const { return ClassID == &ID; } static char ID; }; ... struct DerivedRuntime: ParentRuntime { bool isA(const void *ClassID) const override { return ClassID == &ID || ParentRuntime::isA(ClassID); } static bool classof(const Runtime *R) { return R->isA(&ID); } static char ID; }; It takes a while to wrap your head around this, but what it basically does is use pointer equality instead of enum comparisons. Then, if you have a multi level hierarchy (like we have here), it uses the virtual isA function to check for subclasses instead of doing a range comparison: The desired target class type is captured in the classof call. Then the || Parent::isA chain builds up a list of actual classes that this object is an instance of. If the captured type is found in this list, then the cast can proceed. You can see this in action in llvm/Support/Error.h (though the ErrorInfo class does not implement the classof method, because it wants to do casting differently.) This is a bit more complex set up, but I think the overall result is worth it. Comment Actions lgtm
This revision is now accepted and ready to land.Jun 7 2019, 9:30 AM Closed by commit rL362884: [LanguageRuntime] Introduce LLVM-style casts (authored by xiaobai). · Explain WhyJun 8 2019, 11:41 AM This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 203260 include/lldb/Target/CPPLanguageRuntime.h
include/lldb/Target/LanguageRuntime.h
include/lldb/Target/ObjCLanguageRuntime.h
source/Plugins/Language/ObjC/CF.cpp
source/Plugins/Language/ObjC/Cocoa.cpp
source/Plugins/Language/ObjC/NSArray.cpp
source/Plugins/Language/ObjC/NSDictionary.cpp
source/Plugins/Language/ObjC/NSError.cpp
source/Plugins/Language/ObjC/NSException.cpp
source/Plugins/Language/ObjC/NSIndexPath.cpp
source/Plugins/Language/ObjC/NSSet.cpp
source/Plugins/Language/ObjC/NSString.cpp
source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
source/Target/CPPLanguageRuntime.cpp
source/Target/LanguageRuntime.cpp
source/Target/ObjCLanguageRuntime.cpp
source/Target/Process.cpp
|
nit: the code (in this whole file) is clearly assuming the pointer is non-null, so you don't need the _or_null part. :)