// clang-format off // REQUIRES: lld // Test various interesting cases for AST reconstruction. // RUN: clang-cl /Z7 /GS- /GR- /c /Fo%t.obj -- %s // RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb -- %t.obj // RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb -f %t.exe -s \ // RUN: %p/Inputs/ast-reconstruction.lldbinit 2>&1 | FileCheck %s // Test trivial versions of each tag type. class TrivialC {}; struct TrivialS {}; union TrivialU {}; enum TrivialE {TE_A}; // Test reconstruction of DeclContext hierarchies. namespace A { namespace B { template struct C { T ABCMember; }; // Let's try a template specialization with a different implementation template<> struct C { void *ABCSpecializationMember; }; } // Let's make sure we can distinguish classes and namespaces. Also let's try // a non-type template parameter. template struct C { class D { int ACDMember = 0; C *CPtr = nullptr; }; }; struct D { // Let's make a nested class with the same name as another nested class // elsewhere, and confirm that they appear in the right DeclContexts in // the AST. struct E { int ADDMember; }; }; } // Let's try an anonymous namespace. namespace { template struct Anonymous { int AnonymousMember; // And a nested class within an anonymous namespace struct D { int AnonymousDMember; }; }; } TrivialC TC; TrivialS TS; TrivialU TU; TrivialE TE; A::B::C ABCInt; A::B::C ABCFloat; A::B::C ABCVoid; A::C<0> AC0; A::C<-1> ACNeg1; A::C<0>::D AC0D; A::C<-1>::D ACNeg1D; A::D AD; A::D::E ADE; // FIXME: Anonymous namespaces aren't working correctly. Anonymous AnonInt; Anonymous> AnonABCVoid; Anonymous>::D AnonABCVoidD; // FIXME: Enum size isn't being correctly determined. // FIXME: Can't read memory for variable values. // CHECK: (TrivialC) TC = {} // CHECK: (TrivialS) TS = {} // CHECK: (TrivialU) TU = {} // CHECK: (TrivialE) TE = // CHECK: (A::B::C) ABCInt = (ABCMember = ) // CHECK: (A::B::C) ABCFloat = (ABCMember = ) // CHECK: (A::B::C) ABCVoid = (ABCSpecializationMember = ) // CHECK: (A::C<0>) AC0 = {} // CHECK: (A::C<-1>) ACNeg1 = {} // CHECK: (A::C<0>::D) AC0D = (ACDMember = , CPtr = ) // CHECK: (A::C<-1>::D) ACNeg1D = (ACDMember = , CPtr = ) // CHECK: (A::D) AD = {} // CHECK: (A::D::E) ADE = (ADDMember = ) // CHECK: Dumping clang ast for 1 modules. // CHECK: TranslationUnitDecl {{.*}} // CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition // CHECK: |-CXXRecordDecl {{.*}} struct TrivialS definition // CHECK: |-CXXRecordDecl {{.*}} union TrivialU definition // CHECK: |-EnumDecl {{.*}} TrivialE // CHECK: |-NamespaceDecl {{.*}} A // CHECK: | |-NamespaceDecl {{.*}} B // CHECK: | | |-CXXRecordDecl {{.*}} struct C definition // CHECK: | | | `-FieldDecl {{.*}} ABCMember 'int' // CHECK: | | |-CXXRecordDecl {{.*}} struct C definition // CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float' // CHECK: | | `-CXXRecordDecl {{.*}} struct C definition // CHECK: | | `-FieldDecl {{.*}} ABCSpecializationMember 'void *' // CHECK: | |-CXXRecordDecl {{.*}} struct C<0> definition // CHECK: | | `-CXXRecordDecl {{.*}} class D definition // CHECK: | | |-FieldDecl {{.*}} ACDMember 'int' // CHECK: | | `-FieldDecl {{.*}} CPtr 'A::C<-1> *' // CHECK: | |-CXXRecordDecl {{.*}} struct C<-1> definition // CHECK: | | `-CXXRecordDecl {{.*}} class D definition // CHECK: | | |-FieldDecl {{.*}} ACDMember 'int' // CHECK: | | `-FieldDecl {{.*}} CPtr 'A::C<-2> *' // CHECK: | |-CXXRecordDecl {{.*}} struct C<-2> // CHECK: | `-CXXRecordDecl {{.*}} struct D definition // CHECK: | `-CXXRecordDecl {{.*}} struct E definition // CHECK: | `-FieldDecl {{.*}} ADDMember 'int' int main(int argc, char **argv) { return 0; }