target variable AC0
target variable ACNeg1
+target variable AC1D
target variable AC0D
target variable ACNeg1D
target variable AD
target variable ADE
+target variable AnonInt
+target variable AnonABCVoid
+target variable AnonABCVoidD
+
target modules dump ast
quit
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;
-// FIXME: Anonymous namespaces aren't working correctly.
Anonymous<int> AnonInt;
Anonymous<A::B::C<void>> AnonABCVoid;
-Anonymous<A::B::C<int>>::D AnonABCVoidD;
+Anonymous<A::B::C<void>>::D AnonABCVoidD;
// FIXME: Enum size isn't being correctly determined.
// FIXME: Can't read memory for variable values.
// CHECK: (A::B::C<void>) 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 namespace)::Anonymous<int>) AnonInt = (AnonymousMember = 0)
+// CHECK: ((anonymous namespace)::Anonymous<A::B::C<void>>) AnonABCVoid = (AnonymousMember = 0)
+// CHECK: ((anonymous namespace)::Anonymous<A::B::C<void>>::D) AnonABCVoidD = (AnonymousDMember = 0)
// CHECK: Dumping clang ast for 1 modules.
// CHECK: TranslationUnitDecl {{.*}}
// CHECK: |-CXXRecordDecl {{.*}} class TrivialC definition
// CHECK: | | | `-FieldDecl {{.*}} ABCMember 'float'
// CHECK: | | `-CXXRecordDecl {{.*}} struct C<void> 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: | `-CXXRecordDecl {{.*}} struct D definition
// CHECK: | `-CXXRecordDecl {{.*}} struct E definition
// CHECK: | `-FieldDecl {{.*}} ADDMember 'int'
+// CHECK: |-NamespaceDecl
+// CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous<int> definition
+// CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int'
+// CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous<A::B::C<void>> 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;
}
}
-// CHECK: namespace `anonymous namespace' {
+// CHECK: namespace {
// CHECK-NEXT: typedef bool AnonNamespaceTypedef;
// CHECK-NEXT: }
// CHECK-NEXT: typedef unsigned long ULongArrayTypedef[10];
REQUIRES: system-windows, msvc
RUN: %build --compiler=msvc --nodefaultlib --output=%t.exe %S/Inputs/AstRestoreTest.cpp
-RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=ENUM %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=GLOBAL %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=BASE %s
RUN: lldb-test symbols -dump-ast %t.exe | FileCheck --check-prefix=CLASS %s
return std::move(child);
}
+static bool IsAnonymousNamespaceName(llvm::StringRef name) {
+ return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
+}
+
PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
: m_index(index), m_clang(GetClangASTContext(obj)) {
BuildParentMap();
for (llvm::ms_demangle::Node *scope : scopes) {
auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
std::string str = nii->toString();
- context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context);
+ context = GetOrCreateNamespaceDecl(str.c_str(), *context);
}
return {context, uname};
}
// If that fails, treat it as a series of namespaces.
for (const MSVCUndecoratedNameSpecifier &spec : specs) {
std::string ns_name = spec.GetBaseName().str();
- context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context);
+ context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);
}
return {context, uname};
}
clang::DeclContext *context = &GetTranslationUnitDecl();
while (!name_components.empty()) {
std::string ns = name_components.front()->toString();
- context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context);
+ context = GetOrCreateNamespaceDecl(ns.c_str(), *context);
name_components = name_components.drop_front();
}
return context;
}
clang::NamespaceDecl *
-PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name,
+PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
clang::DeclContext &context) {
- return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context);
+ return m_clang.GetUniqueNamespaceDeclaration(
+ IsAnonymousNamespaceName(name) ? nullptr : name, &context);
}
clang::BlockDecl *
clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
- clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name,
- clang::DeclContext &context);
clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
clang::DeclContext *
GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
+ clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name,
+ clang::DeclContext &context);
+
void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
void ParseDeclsForSimpleContext(clang::DeclContext &context);
void ParseBlockChildren(PdbCompilandSymId block_id);