xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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