| // This class just serves as an indirection between LLDB and Clang. LLDB might |
| // be tempted to check the member type of DependsOnParam2 for whether it's |
| // in some 'currently-loading' state before trying to produce the record layout. |
| // By inheriting from ToLayout this will make LLDB just check if |
| // DependsOnParam1 is currently being loaded (which it's not) but it will |
| template <typename ToLayoutParam> struct DependsOnParam1 : ToLayoutParam {}; |
| // This class forces the memory layout of it's type parameter to be created. |
| template <typename ToLayoutParam> struct DependsOnParam2 { |
| DependsOnParam1<ToLayoutParam> m; |
| }; |
| |
| // This is the class that LLDB has to generate the record layout for. |
| struct ToLayout { |
| // A static member variable which memory layout depends on the surrounding |
| // class. This comes first so that if we accidentially generate the layout |
| // for static member types we end up recursively going back to 'ToLayout' |
| // before 'some_member' has been loaded. |
| static DependsOnParam2<ToLayout> a_static_member; |
| // Some dummy member variable. This is only there so that Clang can detect |
| // that the record layout is inconsistent (i.e., the number of fields in the |
| // layout doesn't fit to the fields in the declaration). |
| int some_member; |
| }; |
| DependsOnParam2<ToLayout> ToLayout::a_static_member; |
| |
| ToLayout test_var; |
| |
| int main() { return test_var.some_member; } |