This adds a script called build.py as well as a lit substitution called %build that we can use to invoke it. The idea is that this allows a lit test to build test inferiors without having to worry about architecture / platform specific differences, command line syntax, finding / configurationg a proper toolchain, and other issues. They can simply write something like: %build --arch=32 -o %t.exe %p/Inputs/foo.cpp and it will just work. This paves the way for being able to run lit tests with multiple configurations, platforms, and compilers with a single test. Differential Revision: https://reviews.llvm.org/D54914 llvm-svn: 348058
132 lines
3.8 KiB
C++
132 lines
3.8 KiB
C++
// clang-format off
|
|
// REQUIRES: lld
|
|
|
|
// Test various interesting cases for AST reconstruction.
|
|
// RUN: %build --compiler=clang-cl --nodefaultlib -o %t.exe -- %s
|
|
// 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<typename T>
|
|
struct C {
|
|
T ABCMember;
|
|
};
|
|
|
|
// Let's try a template specialization with a different implementation
|
|
template<>
|
|
struct C<void> {
|
|
void *ABCSpecializationMember;
|
|
};
|
|
}
|
|
|
|
// Let's make sure we can distinguish classes and namespaces. Also let's try
|
|
// a non-type template parameter.
|
|
template<int N>
|
|
struct C {
|
|
class D {
|
|
int ACDMember = 0;
|
|
C<N - 1> *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<typename T>
|
|
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<int> ABCInt;
|
|
A::B::C<float> ABCFloat;
|
|
A::B::C<void> 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<int> AnonInt;
|
|
Anonymous<A::B::C<void>> AnonABCVoid;
|
|
Anonymous<A::B::C<int>>::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 = TE_A
|
|
// CHECK: (A::B::C<int>) ABCInt = (ABCMember = 0)
|
|
// CHECK: (A::B::C<float>) ABCFloat = (ABCMember = 0)
|
|
// CHECK: (A::B::C<void>) ABCVoid = (ABCSpecializationMember = 0x{{0+}})
|
|
// CHECK: (A::C<0>) AC0 = {}
|
|
// CHECK: (A::C<-1>) ACNeg1 = {}
|
|
// 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: 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<int> definition
|
|
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'int'
|
|
// CHECK: | | |-CXXRecordDecl {{.*}} struct C<float> definition
|
|
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float'
|
|
// CHECK: | | `-CXXRecordDecl {{.*}} struct C<void> 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;
|
|
}
|