10b57cec5SDimitry Andric #include "PdbAstBuilder.h"
20b57cec5SDimitry Andric
30b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
40b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
50b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordName.h"
60b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
70b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
80b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
90b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
100b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
110b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
120b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
130b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
140b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
150b57cec5SDimitry Andric #include "llvm/Demangle/MicrosoftDemangle.h"
160b57cec5SDimitry Andric
1706c3fb27SDimitry Andric #include "PdbUtil.h"
185ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
195ffd83dbSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
200b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
215ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
2206c3fb27SDimitry Andric #include "SymbolFileNativePDB.h"
2306c3fb27SDimitry Andric #include "UdtRecordCompleter.h"
240b57cec5SDimitry Andric #include "lldb/Core/Module.h"
250b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
260b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
27bdd1243dSDimitry Andric #include <optional>
2806c3fb27SDimitry Andric #include <string_view>
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric using namespace lldb_private;
310b57cec5SDimitry Andric using namespace lldb_private::npdb;
320b57cec5SDimitry Andric using namespace llvm::codeview;
330b57cec5SDimitry Andric using namespace llvm::pdb;
340b57cec5SDimitry Andric
350eae32dcSDimitry Andric namespace {
360eae32dcSDimitry Andric struct CreateMethodDecl : public TypeVisitorCallbacks {
CreateMethodDecl__anon3a236c060111::CreateMethodDecl370eae32dcSDimitry Andric CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang,
380eae32dcSDimitry Andric TypeIndex func_type_index,
390eae32dcSDimitry Andric clang::FunctionDecl *&function_decl,
400eae32dcSDimitry Andric lldb::opaque_compiler_type_t parent_ty,
410eae32dcSDimitry Andric llvm::StringRef proc_name, CompilerType func_ct)
420eae32dcSDimitry Andric : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),
430eae32dcSDimitry Andric function_decl(function_decl), parent_ty(parent_ty),
440eae32dcSDimitry Andric proc_name(proc_name), func_ct(func_ct) {}
450eae32dcSDimitry Andric PdbIndex &m_index;
460eae32dcSDimitry Andric TypeSystemClang &m_clang;
470eae32dcSDimitry Andric TypeIndex func_type_index;
480eae32dcSDimitry Andric clang::FunctionDecl *&function_decl;
490eae32dcSDimitry Andric lldb::opaque_compiler_type_t parent_ty;
500eae32dcSDimitry Andric llvm::StringRef proc_name;
510eae32dcSDimitry Andric CompilerType func_ct;
520eae32dcSDimitry Andric
visitKnownMember__anon3a236c060111::CreateMethodDecl530eae32dcSDimitry Andric llvm::Error visitKnownMember(CVMemberRecord &cvr,
540eae32dcSDimitry Andric OverloadedMethodRecord &overloaded) override {
550eae32dcSDimitry Andric TypeIndex method_list_idx = overloaded.MethodList;
560eae32dcSDimitry Andric
570eae32dcSDimitry Andric CVType method_list_type = m_index.tpi().getType(method_list_idx);
580eae32dcSDimitry Andric assert(method_list_type.kind() == LF_METHODLIST);
590eae32dcSDimitry Andric
600eae32dcSDimitry Andric MethodOverloadListRecord method_list;
610eae32dcSDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
620eae32dcSDimitry Andric method_list_type, method_list));
630eae32dcSDimitry Andric
640eae32dcSDimitry Andric for (const OneMethodRecord &method : method_list.Methods) {
650eae32dcSDimitry Andric if (method.getType().getIndex() == func_type_index.getIndex())
660eae32dcSDimitry Andric AddMethod(overloaded.Name, method.getAccess(), method.getOptions(),
670eae32dcSDimitry Andric method.Attrs);
680eae32dcSDimitry Andric }
690eae32dcSDimitry Andric
700eae32dcSDimitry Andric return llvm::Error::success();
710eae32dcSDimitry Andric }
720eae32dcSDimitry Andric
visitKnownMember__anon3a236c060111::CreateMethodDecl730eae32dcSDimitry Andric llvm::Error visitKnownMember(CVMemberRecord &cvr,
740eae32dcSDimitry Andric OneMethodRecord &record) override {
750eae32dcSDimitry Andric AddMethod(record.getName(), record.getAccess(), record.getOptions(),
760eae32dcSDimitry Andric record.Attrs);
770eae32dcSDimitry Andric return llvm::Error::success();
780eae32dcSDimitry Andric }
790eae32dcSDimitry Andric
AddMethod__anon3a236c060111::CreateMethodDecl800eae32dcSDimitry Andric void AddMethod(llvm::StringRef name, MemberAccess access,
810eae32dcSDimitry Andric MethodOptions options, MemberAttributes attrs) {
820eae32dcSDimitry Andric if (name != proc_name || function_decl)
830eae32dcSDimitry Andric return;
840eae32dcSDimitry Andric lldb::AccessType access_type = TranslateMemberAccess(access);
850eae32dcSDimitry Andric bool is_virtual = attrs.isVirtual();
860eae32dcSDimitry Andric bool is_static = attrs.isStatic();
870eae32dcSDimitry Andric bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
880eae32dcSDimitry Andric MethodOptions::CompilerGenerated;
890eae32dcSDimitry Andric function_decl = m_clang.AddMethodToCXXRecordType(
900eae32dcSDimitry Andric parent_ty, proc_name,
910eae32dcSDimitry Andric /*mangled_name=*/nullptr, func_ct, /*access=*/access_type,
920eae32dcSDimitry Andric /*is_virtual=*/is_virtual, /*is_static=*/is_static,
930eae32dcSDimitry Andric /*is_inline=*/false, /*is_explicit=*/false,
940eae32dcSDimitry Andric /*is_attr_used=*/false, /*is_artificial=*/is_artificial);
950eae32dcSDimitry Andric }
960eae32dcSDimitry Andric };
970eae32dcSDimitry Andric } // namespace
980eae32dcSDimitry Andric
TranslateUdtKind(const TagRecord & cr)990b57cec5SDimitry Andric static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {
1000b57cec5SDimitry Andric switch (cr.Kind) {
1010b57cec5SDimitry Andric case TypeRecordKind::Class:
102*5f757f3fSDimitry Andric return clang::TagTypeKind::Class;
1030b57cec5SDimitry Andric case TypeRecordKind::Struct:
104*5f757f3fSDimitry Andric return clang::TagTypeKind::Struct;
1050b57cec5SDimitry Andric case TypeRecordKind::Union:
106*5f757f3fSDimitry Andric return clang::TagTypeKind::Union;
1070b57cec5SDimitry Andric case TypeRecordKind::Interface:
108*5f757f3fSDimitry Andric return clang::TagTypeKind::Interface;
1090b57cec5SDimitry Andric case TypeRecordKind::Enum:
110*5f757f3fSDimitry Andric return clang::TagTypeKind::Enum;
1110b57cec5SDimitry Andric default:
1120b57cec5SDimitry Andric lldbassert(false && "Invalid tag record kind!");
113*5f757f3fSDimitry Andric return clang::TagTypeKind::Struct;
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric
IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args)1170b57cec5SDimitry Andric static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) {
1180b57cec5SDimitry Andric if (args.empty())
1190b57cec5SDimitry Andric return false;
1200b57cec5SDimitry Andric return args.back() == TypeIndex::None();
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric
1230b57cec5SDimitry Andric static bool
AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node * > scopes)1240b57cec5SDimitry Andric AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {
1250b57cec5SDimitry Andric for (llvm::ms_demangle::Node *n : scopes) {
1260b57cec5SDimitry Andric auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n);
1270b57cec5SDimitry Andric if (idn->TemplateParams)
1280b57cec5SDimitry Andric return true;
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric return false;
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric
133bdd1243dSDimitry Andric static std::optional<clang::CallingConv>
TranslateCallingConvention(llvm::codeview::CallingConvention conv)1340b57cec5SDimitry Andric TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
1350b57cec5SDimitry Andric using CC = llvm::codeview::CallingConvention;
1360b57cec5SDimitry Andric switch (conv) {
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric case CC::NearC:
1390b57cec5SDimitry Andric case CC::FarC:
1400b57cec5SDimitry Andric return clang::CallingConv::CC_C;
1410b57cec5SDimitry Andric case CC::NearPascal:
1420b57cec5SDimitry Andric case CC::FarPascal:
1430b57cec5SDimitry Andric return clang::CallingConv::CC_X86Pascal;
1440b57cec5SDimitry Andric case CC::NearFast:
1450b57cec5SDimitry Andric case CC::FarFast:
1460b57cec5SDimitry Andric return clang::CallingConv::CC_X86FastCall;
1470b57cec5SDimitry Andric case CC::NearStdCall:
1480b57cec5SDimitry Andric case CC::FarStdCall:
1490b57cec5SDimitry Andric return clang::CallingConv::CC_X86StdCall;
1500b57cec5SDimitry Andric case CC::ThisCall:
1510b57cec5SDimitry Andric return clang::CallingConv::CC_X86ThisCall;
1520b57cec5SDimitry Andric case CC::NearVector:
1530b57cec5SDimitry Andric return clang::CallingConv::CC_X86VectorCall;
1540b57cec5SDimitry Andric default:
155bdd1243dSDimitry Andric return std::nullopt;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric
IsAnonymousNamespaceName(llvm::StringRef name)1590b57cec5SDimitry Andric static bool IsAnonymousNamespaceName(llvm::StringRef name) {
1600b57cec5SDimitry Andric return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric
PdbAstBuilder(TypeSystemClang & clang)163bdd1243dSDimitry Andric PdbAstBuilder::PdbAstBuilder(TypeSystemClang &clang) : m_clang(clang) {}
1640b57cec5SDimitry Andric
GetTranslationUnitDecl()1650b57cec5SDimitry Andric lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() {
1660b57cec5SDimitry Andric return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl());
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric std::pair<clang::DeclContext *, std::string>
CreateDeclInfoForType(const TagRecord & record,TypeIndex ti)1700b57cec5SDimitry Andric PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
171bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
172bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1730b57cec5SDimitry Andric // FIXME: Move this to GetDeclContextContainingUID.
1740b57cec5SDimitry Andric if (!record.hasUniqueName())
1750b57cec5SDimitry Andric return CreateDeclInfoForUndecoratedName(record.Name);
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric llvm::ms_demangle::Demangler demangler;
17806c3fb27SDimitry Andric std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());
1790b57cec5SDimitry Andric llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
1800b57cec5SDimitry Andric if (demangler.Error)
1815ffd83dbSDimitry Andric return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)};
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andric llvm::ms_demangle::IdentifierNode *idn =
1840b57cec5SDimitry Andric ttn->QualifiedName->getUnqualifiedIdentifier();
1850b57cec5SDimitry Andric std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier);
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric llvm::ms_demangle::NodeArrayNode *name_components =
1880b57cec5SDimitry Andric ttn->QualifiedName->Components;
1890b57cec5SDimitry Andric llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes,
1900b57cec5SDimitry Andric name_components->Count - 1);
1910b57cec5SDimitry Andric
1920b57cec5SDimitry Andric clang::DeclContext *context = m_clang.GetTranslationUnitDecl();
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric // If this type doesn't have a parent type in the debug info, then the best we
1950b57cec5SDimitry Andric // can do is to say that it's either a series of namespaces (if the scope is
1960b57cec5SDimitry Andric // non-empty), or the translation unit (if the scope is empty).
197bdd1243dSDimitry Andric std::optional<TypeIndex> parent_index = pdb->GetParentType(ti);
198bdd1243dSDimitry Andric if (!parent_index) {
1990b57cec5SDimitry Andric if (scopes.empty())
2000b57cec5SDimitry Andric return {context, uname};
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric // If there is no parent in the debug info, but some of the scopes have
2030b57cec5SDimitry Andric // template params, then this is a case of bad debug info. See, for
2040b57cec5SDimitry Andric // example, llvm.org/pr39607. We don't want to create an ambiguity between
2050b57cec5SDimitry Andric // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at
2060b57cec5SDimitry Andric // global scope with the fully qualified name.
2070b57cec5SDimitry Andric if (AnyScopesHaveTemplateParams(scopes))
2085ffd83dbSDimitry Andric return {context, std::string(record.Name)};
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric for (llvm::ms_demangle::Node *scope : scopes) {
2110b57cec5SDimitry Andric auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
2120b57cec5SDimitry Andric std::string str = nii->toString();
2130b57cec5SDimitry Andric context = GetOrCreateNamespaceDecl(str.c_str(), *context);
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric return {context, uname};
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric // Otherwise, all we need to do is get the parent type of this type and
2190b57cec5SDimitry Andric // recurse into our lazy type creation / AST reconstruction logic to get an
2200b57cec5SDimitry Andric // LLDB TypeSP for the parent. This will cause the AST to automatically get
2210b57cec5SDimitry Andric // the right DeclContext created for any parent.
222bdd1243dSDimitry Andric clang::QualType parent_qt = GetOrCreateType(*parent_index);
22381ad6265SDimitry Andric if (parent_qt.isNull())
22481ad6265SDimitry Andric return {nullptr, ""};
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl());
2270b57cec5SDimitry Andric return {context, uname};
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
isLocalVariableType(SymbolKind K)2300b57cec5SDimitry Andric static bool isLocalVariableType(SymbolKind K) {
2310b57cec5SDimitry Andric switch (K) {
2320b57cec5SDimitry Andric case S_REGISTER:
2330b57cec5SDimitry Andric case S_REGREL32:
2340b57cec5SDimitry Andric case S_LOCAL:
2350b57cec5SDimitry Andric return true;
2360b57cec5SDimitry Andric default:
2370b57cec5SDimitry Andric break;
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric return false;
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric
GetOrCreateSymbolForId(PdbCompilandSymId id)2420b57cec5SDimitry Andric clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
243bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
244bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
245bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
246bdd1243dSDimitry Andric CVSymbol cvs = index.ReadSymbolRecord(id);
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric if (isLocalVariableType(cvs.kind())) {
2490b57cec5SDimitry Andric clang::DeclContext *scope = GetParentDeclContext(id);
250bdd1243dSDimitry Andric if (!scope)
251bdd1243dSDimitry Andric return nullptr;
2520b57cec5SDimitry Andric clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope);
25381ad6265SDimitry Andric PdbCompilandSymId scope_id =
25481ad6265SDimitry Andric PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym();
2550b57cec5SDimitry Andric return GetOrCreateVariableDecl(scope_id, id);
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric switch (cvs.kind()) {
2590b57cec5SDimitry Andric case S_GPROC32:
2600b57cec5SDimitry Andric case S_LPROC32:
2610b57cec5SDimitry Andric return GetOrCreateFunctionDecl(id);
2620b57cec5SDimitry Andric case S_GDATA32:
2630b57cec5SDimitry Andric case S_LDATA32:
2640b57cec5SDimitry Andric case S_GTHREAD32:
2650b57cec5SDimitry Andric case S_CONSTANT:
2660b57cec5SDimitry Andric // global variable
2670b57cec5SDimitry Andric return nullptr;
2680b57cec5SDimitry Andric case S_BLOCK32:
2690b57cec5SDimitry Andric return GetOrCreateBlockDecl(id);
27081ad6265SDimitry Andric case S_INLINESITE:
27181ad6265SDimitry Andric return GetOrCreateInlinedFunctionDecl(id);
2720b57cec5SDimitry Andric default:
2730b57cec5SDimitry Andric return nullptr;
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric
277bdd1243dSDimitry Andric std::optional<CompilerDecl>
GetOrCreateDeclForUid(PdbSymUid uid)278bdd1243dSDimitry Andric PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
2790b57cec5SDimitry Andric if (clang::Decl *result = TryGetDecl(uid))
2809dba64beSDimitry Andric return ToCompilerDecl(*result);
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric clang::Decl *result = nullptr;
2830b57cec5SDimitry Andric switch (uid.kind()) {
2840b57cec5SDimitry Andric case PdbSymUidKind::CompilandSym:
2850b57cec5SDimitry Andric result = GetOrCreateSymbolForId(uid.asCompilandSym());
2860b57cec5SDimitry Andric break;
2870b57cec5SDimitry Andric case PdbSymUidKind::Type: {
2880b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(uid.asTypeSym());
28981ad6265SDimitry Andric if (qt.isNull())
290bdd1243dSDimitry Andric return std::nullopt;
2910b57cec5SDimitry Andric if (auto *tag = qt->getAsTagDecl()) {
2920b57cec5SDimitry Andric result = tag;
2930b57cec5SDimitry Andric break;
2940b57cec5SDimitry Andric }
295bdd1243dSDimitry Andric return std::nullopt;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric default:
298bdd1243dSDimitry Andric return std::nullopt;
2990b57cec5SDimitry Andric }
30081ad6265SDimitry Andric
30181ad6265SDimitry Andric if (!result)
302bdd1243dSDimitry Andric return std::nullopt;
3030b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(uid)] = result;
3049dba64beSDimitry Andric return ToCompilerDecl(*result);
3050b57cec5SDimitry Andric }
3060b57cec5SDimitry Andric
GetOrCreateDeclContextForUid(PdbSymUid uid)3070b57cec5SDimitry Andric clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
3080b57cec5SDimitry Andric if (uid.kind() == PdbSymUidKind::CompilandSym) {
3090b57cec5SDimitry Andric if (uid.asCompilandSym().offset == 0)
3100b57cec5SDimitry Andric return FromCompilerDeclContext(GetTranslationUnitDecl());
3110b57cec5SDimitry Andric }
3129dba64beSDimitry Andric auto option = GetOrCreateDeclForUid(uid);
3139dba64beSDimitry Andric if (!option)
3149dba64beSDimitry Andric return nullptr;
31581ad6265SDimitry Andric clang::Decl *decl = FromCompilerDecl(*option);
3160b57cec5SDimitry Andric if (!decl)
3170b57cec5SDimitry Andric return nullptr;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric return clang::Decl::castToDeclContext(decl);
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric std::pair<clang::DeclContext *, std::string>
CreateDeclInfoForUndecoratedName(llvm::StringRef name)3230b57cec5SDimitry Andric PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
324bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
325bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
326bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
3270b57cec5SDimitry Andric MSVCUndecoratedNameParser parser(name);
3280b57cec5SDimitry Andric llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
3290b57cec5SDimitry Andric
330bdd1243dSDimitry Andric auto *context = FromCompilerDeclContext(GetTranslationUnitDecl());
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric llvm::StringRef uname = specs.back().GetBaseName();
3330b57cec5SDimitry Andric specs = specs.drop_back();
3340b57cec5SDimitry Andric if (specs.empty())
3355ffd83dbSDimitry Andric return {context, std::string(name)};
3360b57cec5SDimitry Andric
3370b57cec5SDimitry Andric llvm::StringRef scope_name = specs.back().GetFullName();
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric // It might be a class name, try that first.
340bdd1243dSDimitry Andric std::vector<TypeIndex> types = index.tpi().findRecordsByName(scope_name);
3410b57cec5SDimitry Andric while (!types.empty()) {
3420b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(types.back());
34381ad6265SDimitry Andric if (qt.isNull())
34481ad6265SDimitry Andric continue;
3450b57cec5SDimitry Andric clang::TagDecl *tag = qt->getAsTagDecl();
3460b57cec5SDimitry Andric if (tag)
3475ffd83dbSDimitry Andric return {clang::TagDecl::castToDeclContext(tag), std::string(uname)};
3480b57cec5SDimitry Andric types.pop_back();
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric
3510b57cec5SDimitry Andric // If that fails, treat it as a series of namespaces.
3520b57cec5SDimitry Andric for (const MSVCUndecoratedNameSpecifier &spec : specs) {
3530b57cec5SDimitry Andric std::string ns_name = spec.GetBaseName().str();
3540b57cec5SDimitry Andric context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);
3550b57cec5SDimitry Andric }
3565ffd83dbSDimitry Andric return {context, std::string(uname)};
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric
GetParentDeclContext(PdbSymUid uid)3590b57cec5SDimitry Andric clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
3600b57cec5SDimitry Andric // We must do this *without* calling GetOrCreate on the current uid, as
3610b57cec5SDimitry Andric // that would be an infinite recursion.
362bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
363bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
364bdd1243dSDimitry Andric PdbIndex& index = pdb->GetIndex();
3650b57cec5SDimitry Andric switch (uid.kind()) {
3660b57cec5SDimitry Andric case PdbSymUidKind::CompilandSym: {
367bdd1243dSDimitry Andric std::optional<PdbCompilandSymId> scope =
368bdd1243dSDimitry Andric pdb->FindSymbolScope(uid.asCompilandSym());
3690b57cec5SDimitry Andric if (scope)
3700b57cec5SDimitry Andric return GetOrCreateDeclContextForUid(*scope);
3710b57cec5SDimitry Andric
372bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(uid.asCompilandSym());
373bdd1243dSDimitry Andric return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric case PdbSymUidKind::Type: {
3760b57cec5SDimitry Andric // It could be a namespace, class, or global. We don't support nested
3770b57cec5SDimitry Andric // functions yet. Anyway, we just need to consult the parent type map.
3780b57cec5SDimitry Andric PdbTypeSymId type_id = uid.asTypeSym();
379bdd1243dSDimitry Andric std::optional<TypeIndex> parent_index = pdb->GetParentType(type_id.index);
380bdd1243dSDimitry Andric if (!parent_index)
3810b57cec5SDimitry Andric return FromCompilerDeclContext(GetTranslationUnitDecl());
382bdd1243dSDimitry Andric return GetOrCreateDeclContextForUid(PdbTypeSymId(*parent_index));
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric case PdbSymUidKind::FieldListMember:
3850b57cec5SDimitry Andric // In this case the parent DeclContext is the one for the class that this
3860b57cec5SDimitry Andric // member is inside of.
3870b57cec5SDimitry Andric break;
3880b57cec5SDimitry Andric case PdbSymUidKind::GlobalSym: {
3890b57cec5SDimitry Andric // If this refers to a compiland symbol, just recurse in with that symbol.
3900b57cec5SDimitry Andric // The only other possibilities are S_CONSTANT and S_UDT, in which case we
3910b57cec5SDimitry Andric // need to parse the undecorated name to figure out the scope, then look
3920b57cec5SDimitry Andric // that up in the TPI stream. If it's found, it's a type, othewrise it's
3930b57cec5SDimitry Andric // a series of namespaces.
3940b57cec5SDimitry Andric // FIXME: do this.
395bdd1243dSDimitry Andric CVSymbol global = index.ReadSymbolRecord(uid.asGlobalSym());
3960b57cec5SDimitry Andric switch (global.kind()) {
3970b57cec5SDimitry Andric case SymbolKind::S_GDATA32:
3980b57cec5SDimitry Andric case SymbolKind::S_LDATA32:
399bdd1243dSDimitry Andric return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;;
4000b57cec5SDimitry Andric case SymbolKind::S_PROCREF:
4010b57cec5SDimitry Andric case SymbolKind::S_LPROCREF: {
4020b57cec5SDimitry Andric ProcRefSym ref{global.kind()};
4030b57cec5SDimitry Andric llvm::cantFail(
4040b57cec5SDimitry Andric SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref));
4050b57cec5SDimitry Andric PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset};
4060b57cec5SDimitry Andric return GetParentDeclContext(cu_sym_id);
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric case SymbolKind::S_CONSTANT:
4090b57cec5SDimitry Andric case SymbolKind::S_UDT:
4100b57cec5SDimitry Andric return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;
4110b57cec5SDimitry Andric default:
4120b57cec5SDimitry Andric break;
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric break;
4150b57cec5SDimitry Andric }
4160b57cec5SDimitry Andric default:
4170b57cec5SDimitry Andric break;
4180b57cec5SDimitry Andric }
4190b57cec5SDimitry Andric return FromCompilerDeclContext(GetTranslationUnitDecl());
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric
CompleteType(clang::QualType qt)4220b57cec5SDimitry Andric bool PdbAstBuilder::CompleteType(clang::QualType qt) {
42381ad6265SDimitry Andric if (qt.isNull())
42481ad6265SDimitry Andric return false;
4250b57cec5SDimitry Andric clang::TagDecl *tag = qt->getAsTagDecl();
42681ad6265SDimitry Andric if (qt->isArrayType()) {
42781ad6265SDimitry Andric const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual();
42881ad6265SDimitry Andric tag = element_type->getAsTagDecl();
42981ad6265SDimitry Andric }
4300b57cec5SDimitry Andric if (!tag)
4310b57cec5SDimitry Andric return false;
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric return CompleteTagDecl(*tag);
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric
CompleteTagDecl(clang::TagDecl & tag)4360b57cec5SDimitry Andric bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
4370b57cec5SDimitry Andric // If this is not in our map, it's an error.
4380b57cec5SDimitry Andric auto status_iter = m_decl_to_status.find(&tag);
4390b57cec5SDimitry Andric lldbassert(status_iter != m_decl_to_status.end());
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric // If it's already complete, just return.
4420b57cec5SDimitry Andric DeclStatus &status = status_iter->second;
4430b57cec5SDimitry Andric if (status.resolved)
4440b57cec5SDimitry Andric return true;
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym();
447bdd1243dSDimitry Andric PdbIndex &index = static_cast<SymbolFileNativePDB *>(
448bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile())
449bdd1243dSDimitry Andric ->GetIndex();
450bdd1243dSDimitry Andric lldbassert(IsTagRecord(type_id, index.tpi()));
4510b57cec5SDimitry Andric
452480093f4SDimitry Andric clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag);
4535ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andric TypeIndex tag_ti = type_id.index;
456bdd1243dSDimitry Andric CVType cvt = index.tpi().getType(tag_ti);
4570b57cec5SDimitry Andric if (cvt.kind() == LF_MODIFIER)
4580b57cec5SDimitry Andric tag_ti = LookThroughModifierRecord(cvt);
4590b57cec5SDimitry Andric
460bdd1243dSDimitry Andric PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, index.tpi());
461bdd1243dSDimitry Andric cvt = index.tpi().getType(best_ti.index);
4620b57cec5SDimitry Andric lldbassert(IsTagRecord(cvt));
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andric if (IsForwardRefUdt(cvt)) {
4650b57cec5SDimitry Andric // If we can't find a full decl for this forward ref anywhere in the debug
4660b57cec5SDimitry Andric // info, then we have no way to complete it.
4670b57cec5SDimitry Andric return false;
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric
4700b57cec5SDimitry Andric TypeIndex field_list_ti = GetFieldListIndex(cvt);
471bdd1243dSDimitry Andric CVType field_list_cvt = index.tpi().getType(field_list_ti);
4720b57cec5SDimitry Andric if (field_list_cvt.kind() != LF_FIELDLIST)
4730b57cec5SDimitry Andric return false;
47481ad6265SDimitry Andric FieldListRecord field_list;
47581ad6265SDimitry Andric if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
47681ad6265SDimitry Andric field_list_cvt, field_list))
47781ad6265SDimitry Andric llvm::consumeError(std::move(error));
4780b57cec5SDimitry Andric
4790b57cec5SDimitry Andric // Visit all members of this class, then perform any finalization necessary
4800b57cec5SDimitry Andric // to complete the class.
4810b57cec5SDimitry Andric CompilerType ct = ToCompilerType(tag_qt);
482bdd1243dSDimitry Andric UdtRecordCompleter completer(best_ti, ct, tag, *this, index, m_decl_to_status,
4830eae32dcSDimitry Andric m_cxx_record_map);
48481ad6265SDimitry Andric llvm::Error error =
48581ad6265SDimitry Andric llvm::codeview::visitMemberRecordStream(field_list.Data, completer);
4860b57cec5SDimitry Andric completer.complete();
4870b57cec5SDimitry Andric
488bdd1243dSDimitry Andric m_decl_to_status[&tag].resolved = true;
48981ad6265SDimitry Andric if (error) {
4900b57cec5SDimitry Andric llvm::consumeError(std::move(error));
4910b57cec5SDimitry Andric return false;
4920b57cec5SDimitry Andric }
49381ad6265SDimitry Andric return true;
49481ad6265SDimitry Andric }
4950b57cec5SDimitry Andric
CreateSimpleType(TypeIndex ti)4960b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) {
4970b57cec5SDimitry Andric if (ti == TypeIndex::NullptrT())
4980b57cec5SDimitry Andric return GetBasicType(lldb::eBasicTypeNullPtr);
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
5010b57cec5SDimitry Andric clang::QualType direct_type = GetOrCreateType(ti.makeDirect());
50281ad6265SDimitry Andric if (direct_type.isNull())
50381ad6265SDimitry Andric return {};
504480093f4SDimitry Andric return m_clang.getASTContext().getPointerType(direct_type);
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andric if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
5080b57cec5SDimitry Andric return {};
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind());
5110b57cec5SDimitry Andric if (bt == lldb::eBasicTypeInvalid)
5120b57cec5SDimitry Andric return {};
5130b57cec5SDimitry Andric
5140b57cec5SDimitry Andric return GetBasicType(bt);
5150b57cec5SDimitry Andric }
5160b57cec5SDimitry Andric
CreatePointerType(const PointerRecord & pointer)5170b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) {
5180b57cec5SDimitry Andric clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType);
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andric // This can happen for pointers to LF_VTSHAPE records, which we shouldn't
5210b57cec5SDimitry Andric // create in the AST.
5220b57cec5SDimitry Andric if (pointee_type.isNull())
5230b57cec5SDimitry Andric return {};
5240b57cec5SDimitry Andric
5250b57cec5SDimitry Andric if (pointer.isPointerToMember()) {
5260b57cec5SDimitry Andric MemberPointerInfo mpi = pointer.getMemberInfo();
5270b57cec5SDimitry Andric clang::QualType class_type = GetOrCreateType(mpi.ContainingType);
52881ad6265SDimitry Andric if (class_type.isNull())
52981ad6265SDimitry Andric return {};
530fcaf7f86SDimitry Andric if (clang::TagDecl *tag = class_type->getAsTagDecl()) {
531fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling spelling;
532fcaf7f86SDimitry Andric switch (mpi.Representation) {
533fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData:
534fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::
535fcaf7f86SDimitry Andric SingleInheritanceFunction:
536fcaf7f86SDimitry Andric spelling =
537fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance;
538fcaf7f86SDimitry Andric break;
539fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::
540fcaf7f86SDimitry Andric MultipleInheritanceData:
541fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::
542fcaf7f86SDimitry Andric MultipleInheritanceFunction:
543fcaf7f86SDimitry Andric spelling =
544fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_multiple_inheritance;
545fcaf7f86SDimitry Andric break;
546fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::
547fcaf7f86SDimitry Andric VirtualInheritanceData:
548fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::
549fcaf7f86SDimitry Andric VirtualInheritanceFunction:
550fcaf7f86SDimitry Andric spelling =
551fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance;
552fcaf7f86SDimitry Andric break;
553fcaf7f86SDimitry Andric case llvm::codeview::PointerToMemberRepresentation::Unknown:
554fcaf7f86SDimitry Andric spelling =
555fcaf7f86SDimitry Andric clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance;
556fcaf7f86SDimitry Andric break;
557fcaf7f86SDimitry Andric default:
558fcaf7f86SDimitry Andric spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated;
559fcaf7f86SDimitry Andric break;
560fcaf7f86SDimitry Andric }
561fcaf7f86SDimitry Andric tag->addAttr(clang::MSInheritanceAttr::CreateImplicit(
562fcaf7f86SDimitry Andric m_clang.getASTContext(), spelling));
563fcaf7f86SDimitry Andric }
564480093f4SDimitry Andric return m_clang.getASTContext().getMemberPointerType(
5650b57cec5SDimitry Andric pointee_type, class_type.getTypePtr());
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric
5680b57cec5SDimitry Andric clang::QualType pointer_type;
5690b57cec5SDimitry Andric if (pointer.getMode() == PointerMode::LValueReference)
570480093f4SDimitry Andric pointer_type = m_clang.getASTContext().getLValueReferenceType(pointee_type);
5710b57cec5SDimitry Andric else if (pointer.getMode() == PointerMode::RValueReference)
572480093f4SDimitry Andric pointer_type = m_clang.getASTContext().getRValueReferenceType(pointee_type);
5730b57cec5SDimitry Andric else
574480093f4SDimitry Andric pointer_type = m_clang.getASTContext().getPointerType(pointee_type);
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None)
5770b57cec5SDimitry Andric pointer_type.addConst();
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andric if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None)
5800b57cec5SDimitry Andric pointer_type.addVolatile();
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None)
5830b57cec5SDimitry Andric pointer_type.addRestrict();
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric return pointer_type;
5860b57cec5SDimitry Andric }
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andric clang::QualType
CreateModifierType(const ModifierRecord & modifier)5890b57cec5SDimitry Andric PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) {
5900b57cec5SDimitry Andric clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType);
5910b57cec5SDimitry Andric if (unmodified_type.isNull())
5920b57cec5SDimitry Andric return {};
5930b57cec5SDimitry Andric
5940b57cec5SDimitry Andric if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
5950b57cec5SDimitry Andric unmodified_type.addConst();
5960b57cec5SDimitry Andric if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
5970b57cec5SDimitry Andric unmodified_type.addVolatile();
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andric return unmodified_type;
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric
CreateRecordType(PdbTypeSymId id,const TagRecord & record)6020b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
6030b57cec5SDimitry Andric const TagRecord &record) {
6040b57cec5SDimitry Andric clang::DeclContext *context = nullptr;
6050b57cec5SDimitry Andric std::string uname;
6060b57cec5SDimitry Andric std::tie(context, uname) = CreateDeclInfoForType(record, id.index);
60781ad6265SDimitry Andric if (!context)
60881ad6265SDimitry Andric return {};
60981ad6265SDimitry Andric
6100b57cec5SDimitry Andric clang::TagTypeKind ttk = TranslateUdtKind(record);
611*5f757f3fSDimitry Andric lldb::AccessType access = (ttk == clang::TagTypeKind::Class)
612*5f757f3fSDimitry Andric ? lldb::eAccessPrivate
613*5f757f3fSDimitry Andric : lldb::eAccessPublic;
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andric ClangASTMetadata metadata;
6160b57cec5SDimitry Andric metadata.SetUserID(toOpaqueUid(id));
6170b57cec5SDimitry Andric metadata.SetIsDynamicCXXType(false);
6180b57cec5SDimitry Andric
619*5f757f3fSDimitry Andric CompilerType ct = m_clang.CreateRecordType(
620*5f757f3fSDimitry Andric context, OptionalClangModuleID(), access, uname, llvm::to_underlying(ttk),
621*5f757f3fSDimitry Andric lldb::eLanguageTypeC_plus_plus, &metadata);
6220b57cec5SDimitry Andric
6230b57cec5SDimitry Andric lldbassert(ct.IsValid());
6240b57cec5SDimitry Andric
6255ffd83dbSDimitry Andric TypeSystemClang::StartTagDeclarationDefinition(ct);
6260b57cec5SDimitry Andric
6270b57cec5SDimitry Andric // Even if it's possible, don't complete it at this point. Just mark it
6280b57cec5SDimitry Andric // forward resolved, and if/when LLDB needs the full definition, it can
6290b57cec5SDimitry Andric // ask us.
6300b57cec5SDimitry Andric clang::QualType result =
6310b57cec5SDimitry Andric clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
6320b57cec5SDimitry Andric
6335ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true);
6340b57cec5SDimitry Andric return result;
6350b57cec5SDimitry Andric }
6360b57cec5SDimitry Andric
TryGetDecl(PdbSymUid uid) const6370b57cec5SDimitry Andric clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
6380b57cec5SDimitry Andric auto iter = m_uid_to_decl.find(toOpaqueUid(uid));
6390b57cec5SDimitry Andric if (iter != m_uid_to_decl.end())
6400b57cec5SDimitry Andric return iter->second;
6410b57cec5SDimitry Andric return nullptr;
6420b57cec5SDimitry Andric }
6430b57cec5SDimitry Andric
6440b57cec5SDimitry Andric clang::NamespaceDecl *
GetOrCreateNamespaceDecl(const char * name,clang::DeclContext & context)6450b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
6460b57cec5SDimitry Andric clang::DeclContext &context) {
6470b57cec5SDimitry Andric return m_clang.GetUniqueNamespaceDeclaration(
6485ffd83dbSDimitry Andric IsAnonymousNamespaceName(name) ? nullptr : name, &context,
6495ffd83dbSDimitry Andric OptionalClangModuleID());
6500b57cec5SDimitry Andric }
6510b57cec5SDimitry Andric
6520b57cec5SDimitry Andric clang::BlockDecl *
GetOrCreateBlockDecl(PdbCompilandSymId block_id)6530b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {
6540b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(block_id))
6550b57cec5SDimitry Andric return llvm::dyn_cast<clang::BlockDecl>(decl);
6560b57cec5SDimitry Andric
6570b57cec5SDimitry Andric clang::DeclContext *scope = GetParentDeclContext(block_id);
6580b57cec5SDimitry Andric
6595ffd83dbSDimitry Andric clang::BlockDecl *block_decl =
6605ffd83dbSDimitry Andric m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());
6610b57cec5SDimitry Andric m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andric DeclStatus status;
6640b57cec5SDimitry Andric status.resolved = true;
6650b57cec5SDimitry Andric status.uid = toOpaqueUid(block_id);
6660b57cec5SDimitry Andric m_decl_to_status.insert({block_decl, status});
6670b57cec5SDimitry Andric
6680b57cec5SDimitry Andric return block_decl;
6690b57cec5SDimitry Andric }
6700b57cec5SDimitry Andric
CreateVariableDecl(PdbSymUid uid,CVSymbol sym,clang::DeclContext & scope)6710b57cec5SDimitry Andric clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,
6720b57cec5SDimitry Andric clang::DeclContext &scope) {
6730b57cec5SDimitry Andric VariableInfo var_info = GetVariableNameInfo(sym);
6740b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(var_info.type);
67581ad6265SDimitry Andric if (qt.isNull())
67681ad6265SDimitry Andric return nullptr;
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andric clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
6795ffd83dbSDimitry Andric &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
6820b57cec5SDimitry Andric DeclStatus status;
6830b57cec5SDimitry Andric status.resolved = true;
6840b57cec5SDimitry Andric status.uid = toOpaqueUid(uid);
6850b57cec5SDimitry Andric m_decl_to_status.insert({var_decl, status});
6860b57cec5SDimitry Andric return var_decl;
6870b57cec5SDimitry Andric }
6880b57cec5SDimitry Andric
6890b57cec5SDimitry Andric clang::VarDecl *
GetOrCreateVariableDecl(PdbCompilandSymId scope_id,PdbCompilandSymId var_id)6900b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
6910b57cec5SDimitry Andric PdbCompilandSymId var_id) {
6920b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(var_id))
6930b57cec5SDimitry Andric return llvm::dyn_cast<clang::VarDecl>(decl);
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andric clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id);
69681ad6265SDimitry Andric if (!scope)
69781ad6265SDimitry Andric return nullptr;
6980b57cec5SDimitry Andric
699bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
700bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
701bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
702bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(var_id);
7030b57cec5SDimitry Andric return CreateVariableDecl(PdbSymUid(var_id), sym, *scope);
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric
GetOrCreateVariableDecl(PdbGlobalSymId var_id)7060b57cec5SDimitry Andric clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) {
7070b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(var_id))
7080b57cec5SDimitry Andric return llvm::dyn_cast<clang::VarDecl>(decl);
7090b57cec5SDimitry Andric
710bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
711bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
712bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
713bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(var_id);
7140b57cec5SDimitry Andric auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
7150b57cec5SDimitry Andric return CreateVariableDecl(PdbSymUid(var_id), sym, *context);
7160b57cec5SDimitry Andric }
7170b57cec5SDimitry Andric
7180b57cec5SDimitry Andric clang::TypedefNameDecl *
GetOrCreateTypedefDecl(PdbGlobalSymId id)7190b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
7200b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(id))
7210b57cec5SDimitry Andric return llvm::dyn_cast<clang::TypedefNameDecl>(decl);
7220b57cec5SDimitry Andric
723bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
724bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
725bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
726bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(id);
7270b57cec5SDimitry Andric lldbassert(sym.kind() == S_UDT);
7280b57cec5SDimitry Andric UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
7290b57cec5SDimitry Andric
7300b57cec5SDimitry Andric clang::DeclContext *scope = GetParentDeclContext(id);
7310b57cec5SDimitry Andric
7320b57cec5SDimitry Andric PdbTypeSymId real_type_id{udt.Type, false};
7330b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(real_type_id);
734bdd1243dSDimitry Andric if (qt.isNull() || !scope)
73581ad6265SDimitry Andric return nullptr;
7360b57cec5SDimitry Andric
7375ffd83dbSDimitry Andric std::string uname = std::string(DropNameScope(udt.Name));
7380b57cec5SDimitry Andric
739e8d8bef9SDimitry Andric CompilerType ct = ToCompilerType(qt).CreateTypedef(
740e8d8bef9SDimitry Andric uname.c_str(), ToCompilerDeclContext(*scope), 0);
7410b57cec5SDimitry Andric clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
7420b57cec5SDimitry Andric DeclStatus status;
7430b57cec5SDimitry Andric status.resolved = true;
7440b57cec5SDimitry Andric status.uid = toOpaqueUid(id);
7450b57cec5SDimitry Andric m_decl_to_status.insert({tnd, status});
7460b57cec5SDimitry Andric return tnd;
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric
GetBasicType(lldb::BasicType type)7490b57cec5SDimitry Andric clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) {
7500b57cec5SDimitry Andric CompilerType ct = m_clang.GetBasicType(type);
7510b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
7520b57cec5SDimitry Andric }
7530b57cec5SDimitry Andric
CreateType(PdbTypeSymId type)7540b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {
7550b57cec5SDimitry Andric if (type.index.isSimple())
7560b57cec5SDimitry Andric return CreateSimpleType(type.index);
7570b57cec5SDimitry Andric
758bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
759bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
760bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
761bdd1243dSDimitry Andric CVType cvt = index.tpi().getType(type.index);
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andric if (cvt.kind() == LF_MODIFIER) {
7640b57cec5SDimitry Andric ModifierRecord modifier;
7650b57cec5SDimitry Andric llvm::cantFail(
7660b57cec5SDimitry Andric TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
7670b57cec5SDimitry Andric return CreateModifierType(modifier);
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric
7700b57cec5SDimitry Andric if (cvt.kind() == LF_POINTER) {
7710b57cec5SDimitry Andric PointerRecord pointer;
7720b57cec5SDimitry Andric llvm::cantFail(
7730b57cec5SDimitry Andric TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
7740b57cec5SDimitry Andric return CreatePointerType(pointer);
7750b57cec5SDimitry Andric }
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andric if (IsTagRecord(cvt)) {
7780b57cec5SDimitry Andric CVTagRecord tag = CVTagRecord::create(cvt);
7790b57cec5SDimitry Andric if (tag.kind() == CVTagRecord::Union)
7800b57cec5SDimitry Andric return CreateRecordType(type.index, tag.asUnion());
7810b57cec5SDimitry Andric if (tag.kind() == CVTagRecord::Enum)
7820b57cec5SDimitry Andric return CreateEnumType(type.index, tag.asEnum());
7830b57cec5SDimitry Andric return CreateRecordType(type.index, tag.asClass());
7840b57cec5SDimitry Andric }
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andric if (cvt.kind() == LF_ARRAY) {
7870b57cec5SDimitry Andric ArrayRecord ar;
7880b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
7890b57cec5SDimitry Andric return CreateArrayType(ar);
7900b57cec5SDimitry Andric }
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andric if (cvt.kind() == LF_PROCEDURE) {
7930b57cec5SDimitry Andric ProcedureRecord pr;
7940b57cec5SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
7950b57cec5SDimitry Andric return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv);
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric if (cvt.kind() == LF_MFUNCTION) {
7990b57cec5SDimitry Andric MemberFunctionRecord mfr;
8000b57cec5SDimitry Andric llvm::cantFail(
8010b57cec5SDimitry Andric TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
8020b57cec5SDimitry Andric return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);
8030b57cec5SDimitry Andric }
8040b57cec5SDimitry Andric
8050b57cec5SDimitry Andric return {};
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric
GetOrCreateType(PdbTypeSymId type)8080b57cec5SDimitry Andric clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) {
80981ad6265SDimitry Andric if (type.index.isNoneType())
81081ad6265SDimitry Andric return {};
81181ad6265SDimitry Andric
8120b57cec5SDimitry Andric lldb::user_id_t uid = toOpaqueUid(type);
8130b57cec5SDimitry Andric auto iter = m_uid_to_type.find(uid);
8140b57cec5SDimitry Andric if (iter != m_uid_to_type.end())
8150b57cec5SDimitry Andric return iter->second;
8160b57cec5SDimitry Andric
817bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
818bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
819bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
820bdd1243dSDimitry Andric PdbTypeSymId best_type = GetBestPossibleDecl(type, index.tpi());
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric clang::QualType qt;
8230b57cec5SDimitry Andric if (best_type.index != type.index) {
8240b57cec5SDimitry Andric // This is a forward decl. Call GetOrCreate on the full decl, then map the
8250b57cec5SDimitry Andric // forward decl id to the full decl QualType.
8260b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(best_type);
82781ad6265SDimitry Andric if (qt.isNull())
82881ad6265SDimitry Andric return {};
8290b57cec5SDimitry Andric m_uid_to_type[toOpaqueUid(type)] = qt;
8300b57cec5SDimitry Andric return qt;
8310b57cec5SDimitry Andric }
8320b57cec5SDimitry Andric
8330b57cec5SDimitry Andric // This is either a full decl, or a forward decl with no matching full decl
8340b57cec5SDimitry Andric // in the debug info.
8350b57cec5SDimitry Andric qt = CreateType(type);
83681ad6265SDimitry Andric if (qt.isNull())
83781ad6265SDimitry Andric return {};
83881ad6265SDimitry Andric
8390b57cec5SDimitry Andric m_uid_to_type[toOpaqueUid(type)] = qt;
840bdd1243dSDimitry Andric if (IsTagRecord(type, index.tpi())) {
8410b57cec5SDimitry Andric clang::TagDecl *tag = qt->getAsTagDecl();
8420b57cec5SDimitry Andric lldbassert(m_decl_to_status.count(tag) == 0);
8430b57cec5SDimitry Andric
8440b57cec5SDimitry Andric DeclStatus &status = m_decl_to_status[tag];
8450b57cec5SDimitry Andric status.uid = uid;
8460b57cec5SDimitry Andric status.resolved = false;
8470b57cec5SDimitry Andric }
8480b57cec5SDimitry Andric return qt;
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric
8510b57cec5SDimitry Andric clang::FunctionDecl *
CreateFunctionDecl(PdbCompilandSymId func_id,llvm::StringRef func_name,TypeIndex func_ti,CompilerType func_ct,uint32_t param_count,clang::StorageClass func_storage,bool is_inline,clang::DeclContext * parent)85281ad6265SDimitry Andric PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
85381ad6265SDimitry Andric llvm::StringRef func_name, TypeIndex func_ti,
85481ad6265SDimitry Andric CompilerType func_ct, uint32_t param_count,
85581ad6265SDimitry Andric clang::StorageClass func_storage,
85681ad6265SDimitry Andric bool is_inline, clang::DeclContext *parent) {
85781ad6265SDimitry Andric clang::FunctionDecl *function_decl = nullptr;
85881ad6265SDimitry Andric if (parent->isRecord()) {
859bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
860bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
861bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
86281ad6265SDimitry Andric clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent)
86381ad6265SDimitry Andric ->getTypeForDecl()
86481ad6265SDimitry Andric ->getCanonicalTypeInternal();
86581ad6265SDimitry Andric lldb::opaque_compiler_type_t parent_opaque_ty =
86681ad6265SDimitry Andric ToCompilerType(parent_qt).GetOpaqueQualType();
86781ad6265SDimitry Andric // FIXME: Remove this workaround.
86881ad6265SDimitry Andric auto iter = m_cxx_record_map.find(parent_opaque_ty);
86981ad6265SDimitry Andric if (iter != m_cxx_record_map.end()) {
87081ad6265SDimitry Andric if (iter->getSecond().contains({func_name, func_ct})) {
87181ad6265SDimitry Andric return nullptr;
87281ad6265SDimitry Andric }
87381ad6265SDimitry Andric }
87481ad6265SDimitry Andric
875bdd1243dSDimitry Andric CVType cvt = index.tpi().getType(func_ti);
87681ad6265SDimitry Andric MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));
87781ad6265SDimitry Andric llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(
87881ad6265SDimitry Andric cvt, func_record));
87981ad6265SDimitry Andric TypeIndex class_index = func_record.getClassType();
88081ad6265SDimitry Andric
881bdd1243dSDimitry Andric CVType parent_cvt = index.tpi().getType(class_index);
88281ad6265SDimitry Andric TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag();
88381ad6265SDimitry Andric // If it's a forward reference, try to get the real TypeIndex.
88481ad6265SDimitry Andric if (tag_record.isForwardRef()) {
88581ad6265SDimitry Andric llvm::Expected<TypeIndex> eti =
886bdd1243dSDimitry Andric index.tpi().findFullDeclForForwardRef(class_index);
88781ad6265SDimitry Andric if (eti) {
888bdd1243dSDimitry Andric tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag();
88981ad6265SDimitry Andric }
89081ad6265SDimitry Andric }
89181ad6265SDimitry Andric if (!tag_record.FieldList.isSimple()) {
892bdd1243dSDimitry Andric CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);
89381ad6265SDimitry Andric FieldListRecord field_list;
89481ad6265SDimitry Andric if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
89581ad6265SDimitry Andric field_list_cvt, field_list))
89681ad6265SDimitry Andric llvm::consumeError(std::move(error));
897bdd1243dSDimitry Andric CreateMethodDecl process(index, m_clang, func_ti, function_decl,
89881ad6265SDimitry Andric parent_opaque_ty, func_name, func_ct);
89981ad6265SDimitry Andric if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))
90081ad6265SDimitry Andric llvm::consumeError(std::move(err));
90181ad6265SDimitry Andric }
90281ad6265SDimitry Andric
90381ad6265SDimitry Andric if (!function_decl) {
90481ad6265SDimitry Andric function_decl = m_clang.AddMethodToCXXRecordType(
90581ad6265SDimitry Andric parent_opaque_ty, func_name,
90681ad6265SDimitry Andric /*mangled_name=*/nullptr, func_ct,
90781ad6265SDimitry Andric /*access=*/lldb::AccessType::eAccessPublic,
90881ad6265SDimitry Andric /*is_virtual=*/false, /*is_static=*/false,
90981ad6265SDimitry Andric /*is_inline=*/false, /*is_explicit=*/false,
91081ad6265SDimitry Andric /*is_attr_used=*/false, /*is_artificial=*/false);
91181ad6265SDimitry Andric }
91281ad6265SDimitry Andric m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct});
91381ad6265SDimitry Andric } else {
91481ad6265SDimitry Andric function_decl = m_clang.CreateFunctionDeclaration(
91581ad6265SDimitry Andric parent, OptionalClangModuleID(), func_name, func_ct, func_storage,
91681ad6265SDimitry Andric is_inline);
91781ad6265SDimitry Andric CreateFunctionParameters(func_id, *function_decl, param_count);
91881ad6265SDimitry Andric }
91981ad6265SDimitry Andric return function_decl;
92081ad6265SDimitry Andric }
92181ad6265SDimitry Andric
92281ad6265SDimitry Andric clang::FunctionDecl *
GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id)92381ad6265SDimitry Andric PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) {
924bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
925bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
926bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
92781ad6265SDimitry Andric CompilandIndexItem *cii =
928bdd1243dSDimitry Andric index.compilands().GetCompiland(inlinesite_id.modi);
92981ad6265SDimitry Andric CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset);
93081ad6265SDimitry Andric InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
93181ad6265SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
93281ad6265SDimitry Andric
93381ad6265SDimitry Andric // Inlinee is the id index to the function id record that is inlined.
93481ad6265SDimitry Andric PdbTypeSymId func_id(inline_site.Inlinee, true);
93581ad6265SDimitry Andric // Look up the function decl by the id index to see if we have created a
93681ad6265SDimitry Andric // function decl for a different inlinesite that refers the same function.
93781ad6265SDimitry Andric if (clang::Decl *decl = TryGetDecl(func_id))
93881ad6265SDimitry Andric return llvm::dyn_cast<clang::FunctionDecl>(decl);
93981ad6265SDimitry Andric clang::FunctionDecl *function_decl =
94081ad6265SDimitry Andric CreateFunctionDeclFromId(func_id, inlinesite_id);
94181ad6265SDimitry Andric if (function_decl == nullptr)
94281ad6265SDimitry Andric return nullptr;
94381ad6265SDimitry Andric
94481ad6265SDimitry Andric // Use inline site id in m_decl_to_status because it's expected to be a
94581ad6265SDimitry Andric // PdbCompilandSymId so that we can parse local variables info after it.
94681ad6265SDimitry Andric uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id);
94781ad6265SDimitry Andric DeclStatus status;
94881ad6265SDimitry Andric status.resolved = true;
94981ad6265SDimitry Andric status.uid = inlinesite_uid;
95081ad6265SDimitry Andric m_decl_to_status.insert({function_decl, status});
95181ad6265SDimitry Andric // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI
95281ad6265SDimitry Andric // stream are unique and there could be multiple inline sites (different ids)
95381ad6265SDimitry Andric // referring the same inline function. This avoid creating multiple same
95481ad6265SDimitry Andric // inline function delcs.
95581ad6265SDimitry Andric uint64_t func_uid = toOpaqueUid(func_id);
95681ad6265SDimitry Andric lldbassert(m_uid_to_decl.count(func_uid) == 0);
95781ad6265SDimitry Andric m_uid_to_decl[func_uid] = function_decl;
95881ad6265SDimitry Andric return function_decl;
95981ad6265SDimitry Andric }
96081ad6265SDimitry Andric
96181ad6265SDimitry Andric clang::FunctionDecl *
CreateFunctionDeclFromId(PdbTypeSymId func_tid,PdbCompilandSymId func_sid)96281ad6265SDimitry Andric PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid,
96381ad6265SDimitry Andric PdbCompilandSymId func_sid) {
96481ad6265SDimitry Andric lldbassert(func_tid.is_ipi);
965bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
966bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
967bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
968bdd1243dSDimitry Andric CVType func_cvt = index.ipi().getType(func_tid.index);
96981ad6265SDimitry Andric llvm::StringRef func_name;
97081ad6265SDimitry Andric TypeIndex func_ti;
97181ad6265SDimitry Andric clang::DeclContext *parent = nullptr;
97281ad6265SDimitry Andric switch (func_cvt.kind()) {
97381ad6265SDimitry Andric case LF_MFUNC_ID: {
97481ad6265SDimitry Andric MemberFuncIdRecord mfr;
97581ad6265SDimitry Andric cantFail(
97681ad6265SDimitry Andric TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr));
97781ad6265SDimitry Andric func_name = mfr.getName();
97881ad6265SDimitry Andric func_ti = mfr.getFunctionType();
97981ad6265SDimitry Andric PdbTypeSymId class_type_id(mfr.ClassType, false);
98081ad6265SDimitry Andric parent = GetOrCreateDeclContextForUid(class_type_id);
98181ad6265SDimitry Andric break;
98281ad6265SDimitry Andric }
98381ad6265SDimitry Andric case LF_FUNC_ID: {
98481ad6265SDimitry Andric FuncIdRecord fir;
98581ad6265SDimitry Andric cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir));
98681ad6265SDimitry Andric func_name = fir.getName();
98781ad6265SDimitry Andric func_ti = fir.getFunctionType();
98881ad6265SDimitry Andric parent = FromCompilerDeclContext(GetTranslationUnitDecl());
98981ad6265SDimitry Andric if (!fir.ParentScope.isNoneType()) {
990bdd1243dSDimitry Andric CVType parent_cvt = index.ipi().getType(fir.ParentScope);
99181ad6265SDimitry Andric if (parent_cvt.kind() == LF_STRING_ID) {
99281ad6265SDimitry Andric StringIdRecord sir;
99381ad6265SDimitry Andric cantFail(
99481ad6265SDimitry Andric TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir));
99581ad6265SDimitry Andric parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent);
99681ad6265SDimitry Andric }
99781ad6265SDimitry Andric }
99881ad6265SDimitry Andric break;
99981ad6265SDimitry Andric }
100081ad6265SDimitry Andric default:
100181ad6265SDimitry Andric lldbassert(false && "Invalid function id type!");
100281ad6265SDimitry Andric }
100381ad6265SDimitry Andric clang::QualType func_qt = GetOrCreateType(func_ti);
1004bdd1243dSDimitry Andric if (func_qt.isNull() || !parent)
100581ad6265SDimitry Andric return nullptr;
100681ad6265SDimitry Andric CompilerType func_ct = ToCompilerType(func_qt);
100781ad6265SDimitry Andric uint32_t param_count =
100881ad6265SDimitry Andric llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams();
100981ad6265SDimitry Andric return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count,
101081ad6265SDimitry Andric clang::SC_None, true, parent);
101181ad6265SDimitry Andric }
101281ad6265SDimitry Andric
101381ad6265SDimitry Andric clang::FunctionDecl *
GetOrCreateFunctionDecl(PdbCompilandSymId func_id)10140b57cec5SDimitry Andric PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
10150b57cec5SDimitry Andric if (clang::Decl *decl = TryGetDecl(func_id))
10160b57cec5SDimitry Andric return llvm::dyn_cast<clang::FunctionDecl>(decl);
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andric clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));
1019bdd1243dSDimitry Andric if (!parent)
1020bdd1243dSDimitry Andric return nullptr;
10210b57cec5SDimitry Andric std::string context_name;
10220b57cec5SDimitry Andric if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) {
10230b57cec5SDimitry Andric context_name = ns->getQualifiedNameAsString();
10240b57cec5SDimitry Andric } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) {
10250b57cec5SDimitry Andric context_name = tag->getQualifiedNameAsString();
10260b57cec5SDimitry Andric }
10270b57cec5SDimitry Andric
1028bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1029bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1030bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1031bdd1243dSDimitry Andric CVSymbol cvs = index.ReadSymbolRecord(func_id);
10320b57cec5SDimitry Andric ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind()));
10330b57cec5SDimitry Andric llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc));
10340b57cec5SDimitry Andric
10350b57cec5SDimitry Andric PdbTypeSymId type_id(proc.FunctionType);
10360b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(type_id);
10370b57cec5SDimitry Andric if (qt.isNull())
10380b57cec5SDimitry Andric return nullptr;
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andric clang::StorageClass storage = clang::SC_None;
10410b57cec5SDimitry Andric if (proc.Kind == SymbolRecordKind::ProcSym)
10420b57cec5SDimitry Andric storage = clang::SC_Static;
10430b57cec5SDimitry Andric
10440b57cec5SDimitry Andric const clang::FunctionProtoType *func_type =
10450b57cec5SDimitry Andric llvm::dyn_cast<clang::FunctionProtoType>(qt);
10460b57cec5SDimitry Andric
10470b57cec5SDimitry Andric CompilerType func_ct = ToCompilerType(qt);
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andric llvm::StringRef proc_name = proc.Name;
10500b57cec5SDimitry Andric proc_name.consume_front(context_name);
10510b57cec5SDimitry Andric proc_name.consume_front("::");
105281ad6265SDimitry Andric clang::FunctionDecl *function_decl =
105381ad6265SDimitry Andric CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct,
105481ad6265SDimitry Andric func_type->getNumParams(), storage, false, parent);
105581ad6265SDimitry Andric if (function_decl == nullptr)
10560eae32dcSDimitry Andric return nullptr;
10570b57cec5SDimitry Andric
10580b57cec5SDimitry Andric lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
10590b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
10600b57cec5SDimitry Andric DeclStatus status;
10610b57cec5SDimitry Andric status.resolved = true;
10620b57cec5SDimitry Andric status.uid = toOpaqueUid(func_id);
10630b57cec5SDimitry Andric m_decl_to_status.insert({function_decl, status});
10640b57cec5SDimitry Andric
10650b57cec5SDimitry Andric return function_decl;
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric
CreateFunctionParameters(PdbCompilandSymId func_id,clang::FunctionDecl & function_decl,uint32_t param_count)10680b57cec5SDimitry Andric void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
10690b57cec5SDimitry Andric clang::FunctionDecl &function_decl,
10700b57cec5SDimitry Andric uint32_t param_count) {
1071bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1072bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1073bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1074bdd1243dSDimitry Andric CompilandIndexItem *cii = index.compilands().GetCompiland(func_id.modi);
10750b57cec5SDimitry Andric CVSymbolArray scope =
10760b57cec5SDimitry Andric cii->m_debug_stream.getSymbolArrayForScope(func_id.offset);
10770b57cec5SDimitry Andric
107881ad6265SDimitry Andric scope.drop_front();
10790b57cec5SDimitry Andric auto begin = scope.begin();
10800b57cec5SDimitry Andric auto end = scope.end();
10810b57cec5SDimitry Andric std::vector<clang::ParmVarDecl *> params;
108281ad6265SDimitry Andric for (uint32_t i = 0; i < param_count && begin != end;) {
10830b57cec5SDimitry Andric uint32_t record_offset = begin.offset();
10840b57cec5SDimitry Andric CVSymbol sym = *begin++;
10850b57cec5SDimitry Andric
10860b57cec5SDimitry Andric TypeIndex param_type;
10870b57cec5SDimitry Andric llvm::StringRef param_name;
10880b57cec5SDimitry Andric switch (sym.kind()) {
10890b57cec5SDimitry Andric case S_REGREL32: {
10900b57cec5SDimitry Andric RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
10910b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
10920b57cec5SDimitry Andric param_type = reg.Type;
10930b57cec5SDimitry Andric param_name = reg.Name;
10940b57cec5SDimitry Andric break;
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric case S_REGISTER: {
10970b57cec5SDimitry Andric RegisterSym reg(SymbolRecordKind::RegisterSym);
10980b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
10990b57cec5SDimitry Andric param_type = reg.Index;
11000b57cec5SDimitry Andric param_name = reg.Name;
11010b57cec5SDimitry Andric break;
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric case S_LOCAL: {
11040b57cec5SDimitry Andric LocalSym local(SymbolRecordKind::LocalSym);
11050b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
11060b57cec5SDimitry Andric if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None)
11070b57cec5SDimitry Andric continue;
11080b57cec5SDimitry Andric param_type = local.Type;
11090b57cec5SDimitry Andric param_name = local.Name;
11100b57cec5SDimitry Andric break;
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric case S_BLOCK32:
111381ad6265SDimitry Andric case S_INLINESITE:
111481ad6265SDimitry Andric case S_INLINESITE2:
111581ad6265SDimitry Andric // All parameters should come before the first block/inlinesite. If that
111681ad6265SDimitry Andric // isn't the case, then perhaps this is bad debug info that doesn't
111781ad6265SDimitry Andric // contain information about all parameters.
11180b57cec5SDimitry Andric return;
11190b57cec5SDimitry Andric default:
11200b57cec5SDimitry Andric continue;
11210b57cec5SDimitry Andric }
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric PdbCompilandSymId param_uid(func_id.modi, record_offset);
11240b57cec5SDimitry Andric clang::QualType qt = GetOrCreateType(param_type);
112581ad6265SDimitry Andric if (qt.isNull())
112681ad6265SDimitry Andric return;
11270b57cec5SDimitry Andric
1128480093f4SDimitry Andric CompilerType param_type_ct = m_clang.GetType(qt);
11290b57cec5SDimitry Andric clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
11305ffd83dbSDimitry Andric &function_decl, OptionalClangModuleID(), param_name.str().c_str(),
11315ffd83dbSDimitry Andric param_type_ct, clang::SC_None, true);
11320b57cec5SDimitry Andric lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
11330b57cec5SDimitry Andric
11340b57cec5SDimitry Andric m_uid_to_decl[toOpaqueUid(param_uid)] = param;
11350b57cec5SDimitry Andric params.push_back(param);
113681ad6265SDimitry Andric ++i;
11370b57cec5SDimitry Andric }
11380b57cec5SDimitry Andric
113981ad6265SDimitry Andric if (!params.empty() && params.size() == param_count)
1140fe6060f1SDimitry Andric m_clang.SetFunctionParameters(&function_decl, params);
11410b57cec5SDimitry Andric }
11420b57cec5SDimitry Andric
CreateEnumType(PdbTypeSymId id,const EnumRecord & er)11430b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
11440b57cec5SDimitry Andric const EnumRecord &er) {
11450b57cec5SDimitry Andric clang::DeclContext *decl_context = nullptr;
11460b57cec5SDimitry Andric std::string uname;
11470b57cec5SDimitry Andric std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index);
114881ad6265SDimitry Andric if (!decl_context)
114981ad6265SDimitry Andric return {};
115081ad6265SDimitry Andric
11510b57cec5SDimitry Andric clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType);
115281ad6265SDimitry Andric if (underlying_type.isNull())
115381ad6265SDimitry Andric return {};
11540b57cec5SDimitry Andric
11550b57cec5SDimitry Andric Declaration declaration;
11560b57cec5SDimitry Andric CompilerType enum_ct = m_clang.CreateEnumerationType(
1157349cc55cSDimitry Andric uname, decl_context, OptionalClangModuleID(), declaration,
11585ffd83dbSDimitry Andric ToCompilerType(underlying_type), er.isScoped());
11590b57cec5SDimitry Andric
11605ffd83dbSDimitry Andric TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
11615ffd83dbSDimitry Andric TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
11620b57cec5SDimitry Andric
11630b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType());
11640b57cec5SDimitry Andric }
11650b57cec5SDimitry Andric
CreateArrayType(const ArrayRecord & ar)11660b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
11670b57cec5SDimitry Andric clang::QualType element_type = GetOrCreateType(ar.ElementType);
11680b57cec5SDimitry Andric
1169bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1170bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1171bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1172bdd1243dSDimitry Andric uint64_t element_size = GetSizeOfType({ar.ElementType}, index.tpi());
117381ad6265SDimitry Andric if (element_type.isNull() || element_size == 0)
117481ad6265SDimitry Andric return {};
117581ad6265SDimitry Andric uint64_t element_count = ar.Size / element_size;
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andric CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type),
11780b57cec5SDimitry Andric element_count, false);
11790b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric
CreateFunctionType(TypeIndex args_type_idx,TypeIndex return_type_idx,llvm::codeview::CallingConvention calling_convention)11820b57cec5SDimitry Andric clang::QualType PdbAstBuilder::CreateFunctionType(
11830b57cec5SDimitry Andric TypeIndex args_type_idx, TypeIndex return_type_idx,
11840b57cec5SDimitry Andric llvm::codeview::CallingConvention calling_convention) {
1185bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1186bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1187bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1188bdd1243dSDimitry Andric TpiStream &stream = index.tpi();
11890b57cec5SDimitry Andric CVType args_cvt = stream.getType(args_type_idx);
11900b57cec5SDimitry Andric ArgListRecord args;
11910b57cec5SDimitry Andric llvm::cantFail(
11920b57cec5SDimitry Andric TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));
11930b57cec5SDimitry Andric
1194bdd1243dSDimitry Andric llvm::ArrayRef<TypeIndex> arg_indices = llvm::ArrayRef(args.ArgIndices);
11950b57cec5SDimitry Andric bool is_variadic = IsCVarArgsFunction(arg_indices);
11960b57cec5SDimitry Andric if (is_variadic)
11970b57cec5SDimitry Andric arg_indices = arg_indices.drop_back();
11980b57cec5SDimitry Andric
11990b57cec5SDimitry Andric std::vector<CompilerType> arg_types;
12000b57cec5SDimitry Andric arg_types.reserve(arg_indices.size());
12010b57cec5SDimitry Andric
12020b57cec5SDimitry Andric for (TypeIndex arg_index : arg_indices) {
12030b57cec5SDimitry Andric clang::QualType arg_type = GetOrCreateType(arg_index);
120481ad6265SDimitry Andric if (arg_type.isNull())
120581ad6265SDimitry Andric continue;
12060b57cec5SDimitry Andric arg_types.push_back(ToCompilerType(arg_type));
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric
12090b57cec5SDimitry Andric clang::QualType return_type = GetOrCreateType(return_type_idx);
121081ad6265SDimitry Andric if (return_type.isNull())
121181ad6265SDimitry Andric return {};
12120b57cec5SDimitry Andric
1213bdd1243dSDimitry Andric std::optional<clang::CallingConv> cc =
12140b57cec5SDimitry Andric TranslateCallingConvention(calling_convention);
12150b57cec5SDimitry Andric if (!cc)
12160b57cec5SDimitry Andric return {};
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andric CompilerType return_ct = ToCompilerType(return_type);
12190b57cec5SDimitry Andric CompilerType func_sig_ast_type = m_clang.CreateFunctionType(
12200b57cec5SDimitry Andric return_ct, arg_types.data(), arg_types.size(), is_variadic, 0, *cc);
12210b57cec5SDimitry Andric
12220b57cec5SDimitry Andric return clang::QualType::getFromOpaquePtr(
12230b57cec5SDimitry Andric func_sig_ast_type.GetOpaqueQualType());
12240b57cec5SDimitry Andric }
12250b57cec5SDimitry Andric
isTagDecl(clang::DeclContext & context)12260b57cec5SDimitry Andric static bool isTagDecl(clang::DeclContext &context) {
12270eae32dcSDimitry Andric return llvm::isa<clang::TagDecl>(&context);
12280b57cec5SDimitry Andric }
12290b57cec5SDimitry Andric
isFunctionDecl(clang::DeclContext & context)12300b57cec5SDimitry Andric static bool isFunctionDecl(clang::DeclContext &context) {
12310eae32dcSDimitry Andric return llvm::isa<clang::FunctionDecl>(&context);
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric
isBlockDecl(clang::DeclContext & context)12340b57cec5SDimitry Andric static bool isBlockDecl(clang::DeclContext &context) {
12350eae32dcSDimitry Andric return llvm::isa<clang::BlockDecl>(&context);
12360b57cec5SDimitry Andric }
12370b57cec5SDimitry Andric
ParseNamespace(clang::DeclContext & context)1238bdd1243dSDimitry Andric void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) {
1239bdd1243dSDimitry Andric clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context);
1240bdd1243dSDimitry Andric if (m_parsed_namespaces.contains(ns))
1241bdd1243dSDimitry Andric return;
1242bdd1243dSDimitry Andric std::string qname = ns->getQualifiedNameAsString();
1243bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1244bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1245bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1246bdd1243dSDimitry Andric TypeIndex ti{index.tpi().TypeIndexBegin()};
1247bdd1243dSDimitry Andric for (const CVType &cvt : index.tpi().typeArray()) {
12480b57cec5SDimitry Andric PdbTypeSymId tid{ti};
12490b57cec5SDimitry Andric ++ti;
12500b57cec5SDimitry Andric
12510b57cec5SDimitry Andric if (!IsTagRecord(cvt))
12520b57cec5SDimitry Andric continue;
12530b57cec5SDimitry Andric
12540b57cec5SDimitry Andric CVTagRecord tag = CVTagRecord::create(cvt);
12550b57cec5SDimitry Andric
12560b57cec5SDimitry Andric // Call CreateDeclInfoForType unconditionally so that the namespace info
12570b57cec5SDimitry Andric // gets created. But only call CreateRecordType if the namespace name
12580b57cec5SDimitry Andric // matches.
12590b57cec5SDimitry Andric clang::DeclContext *context = nullptr;
12600b57cec5SDimitry Andric std::string uname;
12610b57cec5SDimitry Andric std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index);
126281ad6265SDimitry Andric if (!context || !context->isNamespace())
12630b57cec5SDimitry Andric continue;
12640b57cec5SDimitry Andric
126504eeddc0SDimitry Andric clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);
1266bdd1243dSDimitry Andric llvm::StringRef ns_name = ns->getName();
1267*5f757f3fSDimitry Andric if (ns_name.starts_with(qname)) {
1268bdd1243dSDimitry Andric ns_name = ns_name.drop_front(qname.size());
1269*5f757f3fSDimitry Andric if (ns_name.starts_with("::"))
1270bdd1243dSDimitry Andric GetOrCreateType(tid);
12710b57cec5SDimitry Andric }
12720b57cec5SDimitry Andric }
1273bdd1243dSDimitry Andric ParseAllFunctionsAndNonLocalVars();
1274bdd1243dSDimitry Andric m_parsed_namespaces.insert(ns);
1275bdd1243dSDimitry Andric }
12760b57cec5SDimitry Andric
ParseAllTypes()1277bdd1243dSDimitry Andric void PdbAstBuilder::ParseAllTypes() {
1278bdd1243dSDimitry Andric llvm::call_once(m_parse_all_types, [this]() {
1279bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1280bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1281bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1282bdd1243dSDimitry Andric TypeIndex ti{index.tpi().TypeIndexBegin()};
1283bdd1243dSDimitry Andric for (const CVType &cvt : index.tpi().typeArray()) {
1284bdd1243dSDimitry Andric PdbTypeSymId tid{ti};
1285bdd1243dSDimitry Andric ++ti;
1286bdd1243dSDimitry Andric
1287bdd1243dSDimitry Andric if (!IsTagRecord(cvt))
1288bdd1243dSDimitry Andric continue;
1289bdd1243dSDimitry Andric
1290bdd1243dSDimitry Andric GetOrCreateType(tid);
1291bdd1243dSDimitry Andric }
1292bdd1243dSDimitry Andric });
1293bdd1243dSDimitry Andric }
1294bdd1243dSDimitry Andric
ParseAllFunctionsAndNonLocalVars()1295bdd1243dSDimitry Andric void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() {
1296bdd1243dSDimitry Andric llvm::call_once(m_parse_functions_and_non_local_vars, [this]() {
1297bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1298bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1299bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1300bdd1243dSDimitry Andric uint32_t module_count = index.dbi().modules().getModuleCount();
13010b57cec5SDimitry Andric for (uint16_t modi = 0; modi < module_count; ++modi) {
1302bdd1243dSDimitry Andric CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);
13030b57cec5SDimitry Andric const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
13040b57cec5SDimitry Andric auto iter = symbols.begin();
13050b57cec5SDimitry Andric while (iter != symbols.end()) {
13060b57cec5SDimitry Andric PdbCompilandSymId sym_id{modi, iter.offset()};
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andric switch (iter->kind()) {
13090b57cec5SDimitry Andric case S_GPROC32:
13100b57cec5SDimitry Andric case S_LPROC32:
13110b57cec5SDimitry Andric GetOrCreateFunctionDecl(sym_id);
13120b57cec5SDimitry Andric iter = symbols.at(getScopeEndOffset(*iter));
13130b57cec5SDimitry Andric break;
13140b57cec5SDimitry Andric case S_GDATA32:
13150b57cec5SDimitry Andric case S_GTHREAD32:
13160b57cec5SDimitry Andric case S_LDATA32:
13170b57cec5SDimitry Andric case S_LTHREAD32:
13180b57cec5SDimitry Andric GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
13190b57cec5SDimitry Andric ++iter;
13200b57cec5SDimitry Andric break;
13210b57cec5SDimitry Andric default:
13220b57cec5SDimitry Andric ++iter;
13230b57cec5SDimitry Andric continue;
13240b57cec5SDimitry Andric }
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric }
1327bdd1243dSDimitry Andric });
13280b57cec5SDimitry Andric }
13290b57cec5SDimitry Andric
skipFunctionParameters(clang::Decl & decl,const CVSymbolArray & symbols)13300b57cec5SDimitry Andric static CVSymbolArray skipFunctionParameters(clang::Decl &decl,
13310b57cec5SDimitry Andric const CVSymbolArray &symbols) {
13320b57cec5SDimitry Andric clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>(&decl);
13330b57cec5SDimitry Andric if (!func_decl)
13340b57cec5SDimitry Andric return symbols;
13350b57cec5SDimitry Andric unsigned int params = func_decl->getNumParams();
13360b57cec5SDimitry Andric if (params == 0)
13370b57cec5SDimitry Andric return symbols;
13380b57cec5SDimitry Andric
13390b57cec5SDimitry Andric CVSymbolArray result = symbols;
13400b57cec5SDimitry Andric
13410b57cec5SDimitry Andric while (!result.empty()) {
13420b57cec5SDimitry Andric if (params == 0)
13430b57cec5SDimitry Andric return result;
13440b57cec5SDimitry Andric
13450b57cec5SDimitry Andric CVSymbol sym = *result.begin();
13460b57cec5SDimitry Andric result.drop_front();
13470b57cec5SDimitry Andric
13480b57cec5SDimitry Andric if (!isLocalVariableType(sym.kind()))
13490b57cec5SDimitry Andric continue;
13500b57cec5SDimitry Andric
13510b57cec5SDimitry Andric --params;
13520b57cec5SDimitry Andric }
13530b57cec5SDimitry Andric return result;
13540b57cec5SDimitry Andric }
13550b57cec5SDimitry Andric
ParseBlockChildren(PdbCompilandSymId block_id)13560b57cec5SDimitry Andric void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) {
1357bdd1243dSDimitry Andric SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
1358bdd1243dSDimitry Andric m_clang.GetSymbolFile()->GetBackingSymbolFile());
1359bdd1243dSDimitry Andric PdbIndex &index = pdb->GetIndex();
1360bdd1243dSDimitry Andric CVSymbol sym = index.ReadSymbolRecord(block_id);
13610b57cec5SDimitry Andric lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 ||
136281ad6265SDimitry Andric sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE);
13630b57cec5SDimitry Andric CompilandIndexItem &cii =
1364bdd1243dSDimitry Andric index.compilands().GetOrCreateCompiland(block_id.modi);
13650b57cec5SDimitry Andric CVSymbolArray symbols =
13660b57cec5SDimitry Andric cii.m_debug_stream.getSymbolArrayForScope(block_id.offset);
13670b57cec5SDimitry Andric
13680b57cec5SDimitry Andric // Function parameters should already have been created when the function was
13690b57cec5SDimitry Andric // parsed.
13700b57cec5SDimitry Andric if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32)
13710b57cec5SDimitry Andric symbols =
13720b57cec5SDimitry Andric skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols);
13730b57cec5SDimitry Andric
137481ad6265SDimitry Andric symbols.drop_front();
13750b57cec5SDimitry Andric auto begin = symbols.begin();
13760b57cec5SDimitry Andric while (begin != symbols.end()) {
13770b57cec5SDimitry Andric PdbCompilandSymId child_sym_id(block_id.modi, begin.offset());
13780b57cec5SDimitry Andric GetOrCreateSymbolForId(child_sym_id);
137981ad6265SDimitry Andric if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) {
13800b57cec5SDimitry Andric ParseBlockChildren(child_sym_id);
13810b57cec5SDimitry Andric begin = symbols.at(getScopeEndOffset(*begin));
13820b57cec5SDimitry Andric }
13830b57cec5SDimitry Andric ++begin;
13840b57cec5SDimitry Andric }
13850b57cec5SDimitry Andric }
13860b57cec5SDimitry Andric
ParseDeclsForSimpleContext(clang::DeclContext & context)13870b57cec5SDimitry Andric void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) {
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andric clang::Decl *decl = clang::Decl::castFromDeclContext(&context);
13900b57cec5SDimitry Andric lldbassert(decl);
13910b57cec5SDimitry Andric
13920b57cec5SDimitry Andric auto iter = m_decl_to_status.find(decl);
13930b57cec5SDimitry Andric lldbassert(iter != m_decl_to_status.end());
13940b57cec5SDimitry Andric
13950b57cec5SDimitry Andric if (auto *tag = llvm::dyn_cast<clang::TagDecl>(&context)) {
13960b57cec5SDimitry Andric CompleteTagDecl(*tag);
13970b57cec5SDimitry Andric return;
13980b57cec5SDimitry Andric }
13990b57cec5SDimitry Andric
14000b57cec5SDimitry Andric if (isFunctionDecl(context) || isBlockDecl(context)) {
14010b57cec5SDimitry Andric PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym();
14020b57cec5SDimitry Andric ParseBlockChildren(block_id);
14030b57cec5SDimitry Andric }
14040b57cec5SDimitry Andric }
14050b57cec5SDimitry Andric
ParseDeclsForContext(clang::DeclContext & context)14060b57cec5SDimitry Andric void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {
14070b57cec5SDimitry Andric // Namespaces aren't explicitly represented in the debug info, and the only
14080b57cec5SDimitry Andric // way to parse them is to parse all type info, demangling every single type
14090b57cec5SDimitry Andric // and trying to reconstruct the DeclContext hierarchy this way. Since this
14100b57cec5SDimitry Andric // is an expensive operation, we have to special case it so that we do other
14110b57cec5SDimitry Andric // work (such as parsing the items that appear within the namespaces) at the
14120b57cec5SDimitry Andric // same time.
14130b57cec5SDimitry Andric if (context.isTranslationUnit()) {
1414bdd1243dSDimitry Andric ParseAllTypes();
1415bdd1243dSDimitry Andric ParseAllFunctionsAndNonLocalVars();
14160b57cec5SDimitry Andric return;
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric
14190b57cec5SDimitry Andric if (context.isNamespace()) {
1420bdd1243dSDimitry Andric ParseNamespace(context);
14210b57cec5SDimitry Andric return;
14220b57cec5SDimitry Andric }
14230b57cec5SDimitry Andric
14240b57cec5SDimitry Andric if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) {
14250b57cec5SDimitry Andric ParseDeclsForSimpleContext(context);
14260b57cec5SDimitry Andric return;
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric }
14290b57cec5SDimitry Andric
ToCompilerDecl(clang::Decl & decl)14300b57cec5SDimitry Andric CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {
14315ffd83dbSDimitry Andric return m_clang.GetCompilerDecl(&decl);
14320b57cec5SDimitry Andric }
14330b57cec5SDimitry Andric
ToCompilerType(clang::QualType qt)14340b57cec5SDimitry Andric CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {
1435bdd1243dSDimitry Andric return {m_clang.weak_from_this(), qt.getAsOpaquePtr()};
14360b57cec5SDimitry Andric }
14370b57cec5SDimitry Andric
14380b57cec5SDimitry Andric CompilerDeclContext
ToCompilerDeclContext(clang::DeclContext & context)14390b57cec5SDimitry Andric PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {
1440480093f4SDimitry Andric return m_clang.CreateDeclContext(&context);
14410b57cec5SDimitry Andric }
14420b57cec5SDimitry Andric
FromCompilerDecl(CompilerDecl decl)14430b57cec5SDimitry Andric clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {
14445ffd83dbSDimitry Andric return ClangUtil::GetDecl(decl);
14450b57cec5SDimitry Andric }
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andric clang::DeclContext *
FromCompilerDeclContext(CompilerDeclContext context)14480b57cec5SDimitry Andric PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
14490b57cec5SDimitry Andric return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric
Dump(Stream & stream)1452349cc55cSDimitry Andric void PdbAstBuilder::Dump(Stream &stream) {
1453349cc55cSDimitry Andric m_clang.Dump(stream.AsRawOstream());
1454349cc55cSDimitry Andric }
1455