// clang-format off // REQUIRES: lld, x86 // Test various interesting cases for AST reconstruction. // RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -c /Fo%t.obj -- %s // RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb // RUN: %lldb -f %t.exe -s \ // RUN: %p/Inputs/ast-types.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; // FIXME: The type `D` is located now at the level of the translation unit. // FIXME: Should be located in the namespace `A`, in the struct `C<1>`. A::C<1>::D AC1D; A::C<0>::D AC0D; A::C<-1>::D ACNeg1D; A::D AD; A::D::E ADE; Anonymous AnonInt; Anonymous> AnonABCVoid; Anonymous>::D AnonABCVoidD; // The following tests that MSInheritanceAttr are set for record decls. class SI { int si; }; struct SI2 { int si2; }; class MI : SI, SI2 { int mi; }; class MI2 : MI { int mi2; }; class VI : virtual MI { int vi; }; class VI2 : virtual SI, virtual SI2 { int vi; }; class/* __unspecified_inheritance*/ UI; typedef void (SI::*SITYPE)(); typedef void (MI::*MITYPE)(); typedef void (MI2::*MI2TYPE)(); typedef void (VI::*VITYPE)(); typedef void (VI2::*VI2TYPE)(); typedef void (UI::*UITYPE)(); SITYPE mp1 = nullptr; MITYPE mp2 = nullptr; MI2TYPE mp3 = nullptr; VITYPE mp4 = nullptr; VI2TYPE mp5 = nullptr; UITYPE mp6 = nullptr; MITYPE *mp7 = nullptr; VI2TYPE *mp8 = nullptr; int SI::*mp9 = nullptr; // 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 = TE_A // CHECK: (A::B::C) ABCInt = (ABCMember = 0) // CHECK: (A::B::C) ABCFloat = (ABCMember = 0) // CHECK: (A::B::C) ABCVoid = (ABCSpecializationMember = 0x{{0+}}) // CHECK: (A::C<0>) AC0 = {} // CHECK: (A::C<-1>) ACNeg1 = {} // CHECK: (A::C<1>::D) AC1D = (ACDMember = 0, CPtr = 0x{{0+}}) // CHECK: (A::C<0>::D) AC0D = (ACDMember = 0, CPtr = 0x{{0+}}) // CHECK: (A::C<-1>::D) ACNeg1D = (ACDMember = 0, CPtr = 0x{{0+}}) // CHECK: (A::D) AD = {} // CHECK: (A::D::E) ADE = (ADDMember = 0) // CHECK: (Anonymous) AnonInt = (AnonymousMember = 0) // CHECK: (Anonymous>) AnonABCVoid = (AnonymousMember = 0) // CHECK: (Anonymous>::D) AnonABCVoidD = (AnonymousDMember = 0) // CHECK: (void (SI::*)()) mp1 = 0x0000000000000000 // CHECK: (void (MI::*)()) mp2 = 0x0000000000000000 // CHECK: (void (MI2::*)()) mp3 = 0x0000000000000000 // CHECK: (void (VI::*)()) mp4 = 0x0000000000000000 // CHECK: (void (VI2::*)()) mp5 = 0x0000000000000000 // CHECK: (void (UI::*)()) mp6 = 0x0000000000000000 // CHECK: (void (MI::**)()) mp7 = 0x0000000000000000 // CHECK: (void (VI2::**)()) mp8 = 0x0000000000000000 // CHECK: (int SI::*) mp9 = 0xffffffff // 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: | `-EnumConstantDecl {{.*}} TE_A '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 *' // FIXME: | |-CXXRecordDecl {{.*}} struct C<1> definition // FIXME: | | `-CXXRecordDecl {{.*}} class D definition // FIXME: | | |-FieldDecl {{.*}} ACDMember 'int' // FIXME: | | `-FieldDecl {{.*}} CPtr 'A::C<1> *' // 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' // CHECK: |-NamespaceDecl // CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous definition // CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int' // CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous> definition // CHECK: | |-FieldDecl {{.*}} AnonymousMember 'int' // CHECK: | `-CXXRecordDecl {{.*}} struct D definition // CHECK: | `-FieldDecl {{.*}} AnonymousDMember 'int' int main(int argc, char **argv) { AnonInt.AnonymousMember = 1; AnonABCVoid.AnonymousMember = 2; AnonABCVoidD.AnonymousDMember = 3; return 0; }