brintos

brintos / llvm-project-archived public Read only

0
0
Text · 51.8 KiB · e7fddf0 Raw
1493 lines · cpp
1#include "PdbAstBuilder.h"2 3#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"4#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"5#include "llvm/DebugInfo/CodeView/RecordName.h"6#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"7#include "llvm/DebugInfo/CodeView/SymbolRecord.h"8#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"9#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"10#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"11#include "llvm/DebugInfo/PDB/Native/DbiStream.h"12#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"13#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"14#include "llvm/DebugInfo/PDB/Native/TpiStream.h"15#include "llvm/Demangle/MicrosoftDemangle.h"16 17#include "PdbUtil.h"18#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"19#include "Plugins/ExpressionParser/Clang/ClangUtil.h"20#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"21#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"22#include "SymbolFileNativePDB.h"23#include "UdtRecordCompleter.h"24#include "lldb/Core/Module.h"25#include "lldb/Symbol/ObjectFile.h"26#include "lldb/Utility/LLDBAssert.h"27#include <optional>28#include <string_view>29 30using namespace lldb_private;31using namespace lldb_private::npdb;32using namespace llvm::codeview;33using namespace llvm::pdb;34 35namespace {36struct CreateMethodDecl : public TypeVisitorCallbacks {37  CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang,38                   TypeIndex func_type_index,39                   clang::FunctionDecl *&function_decl,40                   lldb::opaque_compiler_type_t parent_ty,41                   llvm::StringRef proc_name, ConstString mangled_name,42                   CompilerType func_ct)43      : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),44        function_decl(function_decl), parent_ty(parent_ty),45        proc_name(proc_name), mangled_name(mangled_name), func_ct(func_ct) {}46  PdbIndex &m_index;47  TypeSystemClang &m_clang;48  TypeIndex func_type_index;49  clang::FunctionDecl *&function_decl;50  lldb::opaque_compiler_type_t parent_ty;51  llvm::StringRef proc_name;52  ConstString mangled_name;53  CompilerType func_ct;54 55  llvm::Error visitKnownMember(CVMemberRecord &cvr,56                               OverloadedMethodRecord &overloaded) override {57    TypeIndex method_list_idx = overloaded.MethodList;58 59    CVType method_list_type = m_index.tpi().getType(method_list_idx);60    assert(method_list_type.kind() == LF_METHODLIST);61 62    MethodOverloadListRecord method_list;63    llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(64        method_list_type, method_list));65 66    for (const OneMethodRecord &method : method_list.Methods) {67      if (method.getType().getIndex() == func_type_index.getIndex())68        AddMethod(overloaded.Name, method.getAccess(), method.getOptions(),69                  method.Attrs);70    }71 72    return llvm::Error::success();73  }74 75  llvm::Error visitKnownMember(CVMemberRecord &cvr,76                               OneMethodRecord &record) override {77    AddMethod(record.getName(), record.getAccess(), record.getOptions(),78              record.Attrs);79    return llvm::Error::success();80  }81 82  void AddMethod(llvm::StringRef name, MemberAccess access,83                 MethodOptions options, MemberAttributes attrs) {84    if (name != proc_name || function_decl)85      return;86    lldb::AccessType access_type = TranslateMemberAccess(access);87    bool is_virtual = attrs.isVirtual();88    bool is_static = attrs.isStatic();89    bool is_artificial = (options & MethodOptions::CompilerGenerated) ==90                         MethodOptions::CompilerGenerated;91    function_decl = m_clang.AddMethodToCXXRecordType(92        parent_ty, proc_name, mangled_name, func_ct, /*access=*/access_type,93        /*is_virtual=*/is_virtual, /*is_static=*/is_static,94        /*is_inline=*/false, /*is_explicit=*/false,95        /*is_attr_used=*/false, /*is_artificial=*/is_artificial);96  }97};98} // namespace99 100static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {101  switch (cr.Kind) {102  case TypeRecordKind::Class:103    return clang::TagTypeKind::Class;104  case TypeRecordKind::Struct:105    return clang::TagTypeKind::Struct;106  case TypeRecordKind::Union:107    return clang::TagTypeKind::Union;108  case TypeRecordKind::Interface:109    return clang::TagTypeKind::Interface;110  case TypeRecordKind::Enum:111    return clang::TagTypeKind::Enum;112  default:113    lldbassert(false && "Invalid tag record kind!");114    return clang::TagTypeKind::Struct;115  }116}117 118static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) {119  if (args.empty())120    return false;121  return args.back() == TypeIndex::None();122}123 124static bool125AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {126  for (llvm::ms_demangle::Node *n : scopes) {127    auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n);128    if (idn->TemplateParams)129      return true;130  }131  return false;132}133 134static std::optional<clang::CallingConv>135TranslateCallingConvention(llvm::codeview::CallingConvention conv) {136  using CC = llvm::codeview::CallingConvention;137  switch (conv) {138 139  case CC::NearC:140  case CC::FarC:141    return clang::CallingConv::CC_C;142  case CC::NearPascal:143  case CC::FarPascal:144    return clang::CallingConv::CC_X86Pascal;145  case CC::NearFast:146  case CC::FarFast:147    return clang::CallingConv::CC_X86FastCall;148  case CC::NearStdCall:149  case CC::FarStdCall:150    return clang::CallingConv::CC_X86StdCall;151  case CC::ThisCall:152    return clang::CallingConv::CC_X86ThisCall;153  case CC::NearVector:154    return clang::CallingConv::CC_X86VectorCall;155  default:156    return std::nullopt;157  }158}159 160static bool IsAnonymousNamespaceName(llvm::StringRef name) {161  return name == "`anonymous namespace'" || name == "`anonymous-namespace'";162}163 164PdbAstBuilder::PdbAstBuilder(TypeSystemClang &clang) : m_clang(clang) {}165 166lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() {167  return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl());168}169 170std::pair<clang::DeclContext *, std::string>171PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {172  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(173      m_clang.GetSymbolFile()->GetBackingSymbolFile());174  // FIXME: Move this to GetDeclContextContainingUID.175  if (!record.hasUniqueName())176    return CreateDeclInfoForUndecoratedName(record.Name);177 178  llvm::ms_demangle::Demangler demangler;179  std::string_view sv(record.UniqueName.begin(), record.UniqueName.size());180  llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);181  if (demangler.Error)182    return CreateDeclInfoForUndecoratedName(record.Name);183 184  llvm::ms_demangle::IdentifierNode *idn =185      ttn->QualifiedName->getUnqualifiedIdentifier();186  std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier);187 188  llvm::ms_demangle::NodeArrayNode *name_components =189      ttn->QualifiedName->Components;190  llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes,191                                                   name_components->Count - 1);192 193  clang::DeclContext *context = m_clang.GetTranslationUnitDecl();194 195  // If this type doesn't have a parent type in the debug info, then the best we196  // can do is to say that it's either a series of namespaces (if the scope is197  // non-empty), or the translation unit (if the scope is empty).198  std::optional<TypeIndex> parent_index = pdb->GetParentType(ti);199  if (!parent_index) {200    if (scopes.empty())201      return {context, uname};202 203    // If there is no parent in the debug info, but some of the scopes have204    // template params, then this is a case of bad debug info.  See, for205    // example, llvm.org/pr39607.  We don't want to create an ambiguity between206    // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at207    // global scope with the fully qualified name.208    if (AnyScopesHaveTemplateParams(scopes))209      return {context, std::string(record.Name)};210 211    for (llvm::ms_demangle::Node *scope : scopes) {212      auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);213      std::string str = nii->toString();214      context = GetOrCreateNamespaceDecl(str.c_str(), *context);215    }216    return {context, uname};217  }218 219  // Otherwise, all we need to do is get the parent type of this type and220  // recurse into our lazy type creation / AST reconstruction logic to get an221  // LLDB TypeSP for the parent.  This will cause the AST to automatically get222  // the right DeclContext created for any parent.223  clang::QualType parent_qt = GetOrCreateType(*parent_index);224  if (parent_qt.isNull())225    return {nullptr, ""};226 227  context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl());228  return {context, uname};229}230 231static bool isLocalVariableType(SymbolKind K) {232  switch (K) {233  case S_REGISTER:234  case S_REGREL32:235  case S_LOCAL:236    return true;237  default:238    break;239  }240  return false;241}242 243clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {244  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(245      m_clang.GetSymbolFile()->GetBackingSymbolFile());246  PdbIndex &index = pdb->GetIndex();247  CVSymbol cvs = index.ReadSymbolRecord(id);248 249  if (isLocalVariableType(cvs.kind())) {250    clang::DeclContext *scope = GetParentDeclContext(id);251    if (!scope)252      return nullptr;253    clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope);254    PdbCompilandSymId scope_id =255        PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym();256    return GetOrCreateVariableDecl(scope_id, id);257  }258 259  switch (cvs.kind()) {260  case S_GPROC32:261  case S_LPROC32:262    return GetOrCreateFunctionDecl(id);263  case S_GDATA32:264  case S_LDATA32:265  case S_GTHREAD32:266  case S_CONSTANT:267    // global variable268    return nullptr;269  case S_BLOCK32:270    return GetOrCreateBlockDecl(id);271  case S_INLINESITE:272    return GetOrCreateInlinedFunctionDecl(id);273  default:274    return nullptr;275  }276}277 278std::optional<CompilerDecl>279PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {280  if (clang::Decl *result = TryGetDecl(uid))281    return ToCompilerDecl(*result);282 283  clang::Decl *result = nullptr;284  switch (uid.kind()) {285  case PdbSymUidKind::CompilandSym:286    result = GetOrCreateSymbolForId(uid.asCompilandSym());287    break;288  case PdbSymUidKind::Type: {289    clang::QualType qt = GetOrCreateType(uid.asTypeSym());290    if (qt.isNull())291      return std::nullopt;292    if (auto *tag = qt->getAsTagDecl()) {293      result = tag;294      break;295    }296    return std::nullopt;297  }298  default:299    return std::nullopt;300  }301 302  if (!result)303    return std::nullopt;304  m_uid_to_decl[toOpaqueUid(uid)] = result;305  return ToCompilerDecl(*result);306}307 308clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {309  if (uid.kind() == PdbSymUidKind::CompilandSym) {310    if (uid.asCompilandSym().offset == 0)311      return FromCompilerDeclContext(GetTranslationUnitDecl());312  }313  auto option = GetOrCreateDeclForUid(uid);314  if (!option)315    return nullptr;316  clang::Decl *decl = FromCompilerDecl(*option);317  if (!decl)318    return nullptr;319 320  return clang::Decl::castToDeclContext(decl);321}322 323std::pair<clang::DeclContext *, std::string>324PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {325  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(326      m_clang.GetSymbolFile()->GetBackingSymbolFile());327  PdbIndex &index = pdb->GetIndex();328  MSVCUndecoratedNameParser parser(name);329  llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();330 331  auto *context = FromCompilerDeclContext(GetTranslationUnitDecl());332 333  llvm::StringRef uname = specs.back().GetBaseName();334  specs = specs.drop_back();335  if (specs.empty())336    return {context, std::string(name)};337 338  llvm::StringRef scope_name = specs.back().GetFullName();339 340  // It might be a class name, try that first.341  std::vector<TypeIndex> types = index.tpi().findRecordsByName(scope_name);342  while (!types.empty()) {343    clang::QualType qt = GetOrCreateType(types.back());344    if (qt.isNull())345      continue;346    clang::TagDecl *tag = qt->getAsTagDecl();347    if (tag)348      return {clang::TagDecl::castToDeclContext(tag), std::string(uname)};349    types.pop_back();350  }351 352  // If that fails, treat it as a series of namespaces.353  for (const MSVCUndecoratedNameSpecifier &spec : specs) {354    std::string ns_name = spec.GetBaseName().str();355    context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);356  }357  return {context, std::string(uname)};358}359 360clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {361  // We must do this *without* calling GetOrCreate on the current uid, as362  // that would be an infinite recursion.363  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(364      m_clang.GetSymbolFile()->GetBackingSymbolFile());365  PdbIndex& index = pdb->GetIndex();366  switch (uid.kind()) {367  case PdbSymUidKind::CompilandSym: {368    std::optional<PdbCompilandSymId> scope =369        pdb->FindSymbolScope(uid.asCompilandSym());370    if (scope)371      return GetOrCreateDeclContextForUid(*scope);372 373    CVSymbol sym = index.ReadSymbolRecord(uid.asCompilandSym());374    return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;375  }376  case PdbSymUidKind::Type: {377    // It could be a namespace, class, or global.  We don't support nested378    // functions yet.  Anyway, we just need to consult the parent type map.379    PdbTypeSymId type_id = uid.asTypeSym();380    std::optional<TypeIndex> parent_index = pdb->GetParentType(type_id.index);381    if (!parent_index)382      return FromCompilerDeclContext(GetTranslationUnitDecl());383    return GetOrCreateDeclContextForUid(PdbTypeSymId(*parent_index));384  }385  case PdbSymUidKind::FieldListMember:386    // In this case the parent DeclContext is the one for the class that this387    // member is inside of.388    break;389  case PdbSymUidKind::GlobalSym: {390    // If this refers to a compiland symbol, just recurse in with that symbol.391    // The only other possibilities are S_CONSTANT and S_UDT, in which case we392    // need to parse the undecorated name to figure out the scope, then look393    // that up in the TPI stream.  If it's found, it's a type, othewrise it's394    // a series of namespaces.395    // FIXME: do this.396    CVSymbol global = index.ReadSymbolRecord(uid.asGlobalSym());397    switch (global.kind()) {398    case SymbolKind::S_GDATA32:399    case SymbolKind::S_LDATA32:400      return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;;401    case SymbolKind::S_PROCREF:402    case SymbolKind::S_LPROCREF: {403      ProcRefSym ref{global.kind()};404      llvm::cantFail(405          SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref));406      PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset};407      return GetParentDeclContext(cu_sym_id);408    }409    case SymbolKind::S_CONSTANT:410    case SymbolKind::S_UDT:411      return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;412    default:413      break;414    }415    break;416  }417  default:418    break;419  }420  return FromCompilerDeclContext(GetTranslationUnitDecl());421}422 423bool PdbAstBuilder::CompleteType(clang::QualType qt) {424  if (qt.isNull())425    return false;426  clang::TagDecl *tag = qt->getAsTagDecl();427  if (qt->isArrayType()) {428    const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual();429    tag = element_type->getAsTagDecl();430  }431  if (!tag)432    return false;433 434  return CompleteTagDecl(*tag);435}436 437bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {438  // If this is not in our map, it's an error.439  auto status_iter = m_decl_to_status.find(&tag);440  lldbassert(status_iter != m_decl_to_status.end());441 442  // If it's already complete, just return.443  DeclStatus &status = status_iter->second;444  if (status.resolved)445    return true;446 447  PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym();448  PdbIndex &index = static_cast<SymbolFileNativePDB *>(449                        m_clang.GetSymbolFile()->GetBackingSymbolFile())450                        ->GetIndex();451  lldbassert(IsTagRecord(type_id, index.tpi()));452 453  clang::QualType tag_qt = m_clang.getASTContext().getCanonicalTagType(&tag);454  TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);455 456  TypeIndex tag_ti = type_id.index;457  CVType cvt = index.tpi().getType(tag_ti);458  if (cvt.kind() == LF_MODIFIER)459    tag_ti = LookThroughModifierRecord(cvt);460 461  PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, index.tpi());462  cvt = index.tpi().getType(best_ti.index);463  lldbassert(IsTagRecord(cvt));464 465  if (IsForwardRefUdt(cvt)) {466    // If we can't find a full decl for this forward ref anywhere in the debug467    // info, then we have no way to complete it.468    return false;469  }470 471  TypeIndex field_list_ti = GetFieldListIndex(cvt);472  CVType field_list_cvt = index.tpi().getType(field_list_ti);473  if (field_list_cvt.kind() != LF_FIELDLIST)474    return false;475  FieldListRecord field_list;476  if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(477          field_list_cvt, field_list))478    llvm::consumeError(std::move(error));479 480  // Visit all members of this class, then perform any finalization necessary481  // to complete the class.482  CompilerType ct = ToCompilerType(tag_qt);483  UdtRecordCompleter completer(best_ti, ct, tag, *this, index, m_decl_to_status,484                               m_cxx_record_map);485  llvm::Error error =486      llvm::codeview::visitMemberRecordStream(field_list.Data, completer);487  completer.complete();488 489  m_decl_to_status[&tag].resolved = true;490  if (error) {491    llvm::consumeError(std::move(error));492    return false;493  }494  return true;495}496 497clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) {498  if (ti == TypeIndex::NullptrT())499    return GetBasicType(lldb::eBasicTypeNullPtr);500 501  if (ti.getSimpleMode() != SimpleTypeMode::Direct) {502    clang::QualType direct_type = GetOrCreateType(ti.makeDirect());503    if (direct_type.isNull())504      return {};505    return m_clang.getASTContext().getPointerType(direct_type);506  }507 508  if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)509    return {};510 511  lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind());512  if (bt == lldb::eBasicTypeInvalid)513    return {};514 515  return GetBasicType(bt);516}517 518clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) {519  clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType);520 521  // This can happen for pointers to LF_VTSHAPE records, which we shouldn't522  // create in the AST.523  if (pointee_type.isNull())524    return {};525 526  if (pointer.isPointerToMember()) {527    MemberPointerInfo mpi = pointer.getMemberInfo();528    clang::QualType class_type = GetOrCreateType(mpi.ContainingType);529    if (class_type.isNull())530      return {};531    if (clang::TagDecl *tag = class_type->getAsTagDecl()) {532      clang::MSInheritanceAttr::Spelling spelling;533      switch (mpi.Representation) {534      case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData:535      case llvm::codeview::PointerToMemberRepresentation::536          SingleInheritanceFunction:537        spelling =538            clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance;539        break;540      case llvm::codeview::PointerToMemberRepresentation::541          MultipleInheritanceData:542      case llvm::codeview::PointerToMemberRepresentation::543          MultipleInheritanceFunction:544        spelling =545            clang::MSInheritanceAttr::Spelling::Keyword_multiple_inheritance;546        break;547      case llvm::codeview::PointerToMemberRepresentation::548          VirtualInheritanceData:549      case llvm::codeview::PointerToMemberRepresentation::550          VirtualInheritanceFunction:551        spelling =552            clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance;553        break;554      case llvm::codeview::PointerToMemberRepresentation::Unknown:555        spelling =556            clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance;557        break;558      default:559        spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated;560        break;561      }562      tag->addAttr(clang::MSInheritanceAttr::CreateImplicit(563          m_clang.getASTContext(), spelling));564    }565    return m_clang.getASTContext().getMemberPointerType(566        pointee_type, /*Qualifier=*/std::nullopt,567        class_type->getAsCXXRecordDecl());568  }569 570  clang::QualType pointer_type;571  if (pointer.getMode() == PointerMode::LValueReference)572    pointer_type = m_clang.getASTContext().getLValueReferenceType(pointee_type);573  else if (pointer.getMode() == PointerMode::RValueReference)574    pointer_type = m_clang.getASTContext().getRValueReferenceType(pointee_type);575  else576    pointer_type = m_clang.getASTContext().getPointerType(pointee_type);577 578  if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None)579    pointer_type.addConst();580 581  if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None)582    pointer_type.addVolatile();583 584  if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None)585    pointer_type.addRestrict();586 587  return pointer_type;588}589 590clang::QualType591PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) {592  clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType);593  if (unmodified_type.isNull())594    return {};595 596  if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None)597    unmodified_type.addConst();598  if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)599    unmodified_type.addVolatile();600 601  return unmodified_type;602}603 604clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,605                                                const TagRecord &record) {606  clang::DeclContext *context = nullptr;607  std::string uname;608  std::tie(context, uname) = CreateDeclInfoForType(record, id.index);609  if (!context)610    return {};611 612  clang::TagTypeKind ttk = TranslateUdtKind(record);613  lldb::AccessType access = (ttk == clang::TagTypeKind::Class)614                                ? lldb::eAccessPrivate615                                : lldb::eAccessPublic;616 617  ClangASTMetadata metadata;618  metadata.SetUserID(toOpaqueUid(id));619  metadata.SetIsDynamicCXXType(false);620 621  CompilerType ct = m_clang.CreateRecordType(622      context, OptionalClangModuleID(), access, uname, llvm::to_underlying(ttk),623      lldb::eLanguageTypeC_plus_plus, metadata);624 625  lldbassert(ct.IsValid());626 627  TypeSystemClang::StartTagDeclarationDefinition(ct);628 629  // Even if it's possible, don't complete it at this point. Just mark it630  // forward resolved, and if/when LLDB needs the full definition, it can631  // ask us.632  clang::QualType result =633      clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());634 635  TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true);636  return result;637}638 639clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {640  auto iter = m_uid_to_decl.find(toOpaqueUid(uid));641  if (iter != m_uid_to_decl.end())642    return iter->second;643  return nullptr;644}645 646clang::NamespaceDecl *647PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,648                                        clang::DeclContext &context) {649  clang::NamespaceDecl *ns = m_clang.GetUniqueNamespaceDeclaration(650      IsAnonymousNamespaceName(name) ? nullptr : name, &context,651      OptionalClangModuleID());652  m_known_namespaces.insert(ns);653  m_parent_to_namespaces[&context].insert(ns);654  return ns;655}656 657clang::BlockDecl *658PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {659  if (clang::Decl *decl = TryGetDecl(block_id))660    return llvm::dyn_cast<clang::BlockDecl>(decl);661 662  clang::DeclContext *scope = GetParentDeclContext(block_id);663 664  clang::BlockDecl *block_decl =665      m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());666  m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});667 668  DeclStatus status;669  status.resolved = true;670  status.uid = toOpaqueUid(block_id);671  m_decl_to_status.insert({block_decl, status});672 673  return block_decl;674}675 676clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,677                                                  clang::DeclContext &scope) {678  VariableInfo var_info = GetVariableNameInfo(sym);679  clang::QualType qt = GetOrCreateType(var_info.type);680  if (qt.isNull())681    return nullptr;682 683  clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(684      &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);685 686  m_uid_to_decl[toOpaqueUid(uid)] = var_decl;687  DeclStatus status;688  status.resolved = true;689  status.uid = toOpaqueUid(uid);690  m_decl_to_status.insert({var_decl, status});691  return var_decl;692}693 694clang::VarDecl *695PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id,696                                       PdbCompilandSymId var_id) {697  if (clang::Decl *decl = TryGetDecl(var_id))698    return llvm::dyn_cast<clang::VarDecl>(decl);699 700  clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id);701  if (!scope)702    return nullptr;703 704  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(705      m_clang.GetSymbolFile()->GetBackingSymbolFile());706  PdbIndex &index = pdb->GetIndex();707  CVSymbol sym = index.ReadSymbolRecord(var_id);708  return CreateVariableDecl(PdbSymUid(var_id), sym, *scope);709}710 711clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) {712  if (clang::Decl *decl = TryGetDecl(var_id))713    return llvm::dyn_cast<clang::VarDecl>(decl);714 715  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(716      m_clang.GetSymbolFile()->GetBackingSymbolFile());717  PdbIndex &index = pdb->GetIndex();718  CVSymbol sym = index.ReadSymbolRecord(var_id);719  auto context = FromCompilerDeclContext(GetTranslationUnitDecl());720  return CreateVariableDecl(PdbSymUid(var_id), sym, *context);721}722 723clang::TypedefNameDecl *724PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {725  if (clang::Decl *decl = TryGetDecl(id))726    return llvm::dyn_cast<clang::TypedefNameDecl>(decl);727 728  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(729      m_clang.GetSymbolFile()->GetBackingSymbolFile());730  PdbIndex &index = pdb->GetIndex();731  CVSymbol sym = index.ReadSymbolRecord(id);732  lldbassert(sym.kind() == S_UDT);733  UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));734 735  clang::DeclContext *scope = GetParentDeclContext(id);736 737  PdbTypeSymId real_type_id{udt.Type, false};738  clang::QualType qt = GetOrCreateType(real_type_id);739  if (qt.isNull() || !scope)740    return nullptr;741 742  std::string uname = std::string(DropNameScope(udt.Name));743 744  CompilerType ct = ToCompilerType(qt).CreateTypedef(745      uname.c_str(), ToCompilerDeclContext(*scope), 0);746  clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);747  DeclStatus status;748  status.resolved = true;749  status.uid = toOpaqueUid(id);750  m_decl_to_status.insert({tnd, status});751  return tnd;752}753 754clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) {755  CompilerType ct = m_clang.GetBasicType(type);756  return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());757}758 759clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {760  if (type.index.isSimple())761    return CreateSimpleType(type.index);762 763  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(764      m_clang.GetSymbolFile()->GetBackingSymbolFile());765  PdbIndex &index = pdb->GetIndex();766  CVType cvt = index.tpi().getType(type.index);767 768  if (cvt.kind() == LF_MODIFIER) {769    ModifierRecord modifier;770    llvm::cantFail(771        TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));772    return CreateModifierType(modifier);773  }774 775  if (cvt.kind() == LF_POINTER) {776    PointerRecord pointer;777    llvm::cantFail(778        TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));779    return CreatePointerType(pointer);780  }781 782  if (IsTagRecord(cvt)) {783    CVTagRecord tag = CVTagRecord::create(cvt);784    if (tag.kind() == CVTagRecord::Union)785      return CreateRecordType(type.index, tag.asUnion());786    if (tag.kind() == CVTagRecord::Enum)787      return CreateEnumType(type.index, tag.asEnum());788    return CreateRecordType(type.index, tag.asClass());789  }790 791  if (cvt.kind() == LF_ARRAY) {792    ArrayRecord ar;793    llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));794    return CreateArrayType(ar);795  }796 797  if (cvt.kind() == LF_PROCEDURE) {798    ProcedureRecord pr;799    llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));800    return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv);801  }802 803  if (cvt.kind() == LF_MFUNCTION) {804    MemberFunctionRecord mfr;805    llvm::cantFail(806        TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));807    return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);808  }809 810  return {};811}812 813clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) {814  if (type.index.isNoneType())815    return {};816 817  lldb::user_id_t uid = toOpaqueUid(type);818  auto iter = m_uid_to_type.find(uid);819  if (iter != m_uid_to_type.end())820    return iter->second;821 822  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(823      m_clang.GetSymbolFile()->GetBackingSymbolFile());824  PdbIndex &index = pdb->GetIndex();825  PdbTypeSymId best_type = GetBestPossibleDecl(type, index.tpi());826 827  clang::QualType qt;828  if (best_type.index != type.index) {829    // This is a forward decl.  Call GetOrCreate on the full decl, then map the830    // forward decl id to the full decl QualType.831    clang::QualType qt = GetOrCreateType(best_type);832    if (qt.isNull())833      return {};834    m_uid_to_type[toOpaqueUid(type)] = qt;835    return qt;836  }837 838  // This is either a full decl, or a forward decl with no matching full decl839  // in the debug info.840  qt = CreateType(type);841  if (qt.isNull())842    return {};843 844  m_uid_to_type[toOpaqueUid(type)] = qt;845  if (IsTagRecord(type, index.tpi())) {846    clang::TagDecl *tag = qt->getAsTagDecl();847    lldbassert(m_decl_to_status.count(tag) == 0);848 849    DeclStatus &status = m_decl_to_status[tag];850    status.uid = uid;851    status.resolved = false;852  }853  return qt;854}855 856clang::FunctionDecl *857PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,858                                  llvm::StringRef func_name, TypeIndex func_ti,859                                  CompilerType func_ct, uint32_t param_count,860                                  clang::StorageClass func_storage,861                                  bool is_inline, clang::DeclContext *parent) {862  clang::FunctionDecl *function_decl = nullptr;863  if (parent->isRecord()) {864    SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(865        m_clang.GetSymbolFile()->GetBackingSymbolFile());866    PdbIndex &index = pdb->GetIndex();867    clang::CanQualType parent_qt =868        m_clang.getASTContext().getCanonicalTypeDeclType(869            llvm::cast<clang::TypeDecl>(parent));870    lldb::opaque_compiler_type_t parent_opaque_ty =871        ToCompilerType(parent_qt).GetOpaqueQualType();872    // FIXME: Remove this workaround.873    auto iter = m_cxx_record_map.find(parent_opaque_ty);874    if (iter != m_cxx_record_map.end()) {875      if (iter->getSecond().contains({func_name, func_ct})) {876        return nullptr;877      }878    }879 880    CVType cvt = index.tpi().getType(func_ti);881    MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));882    llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(883        cvt, func_record));884    TypeIndex class_index = func_record.getClassType();885 886    CVType parent_cvt = index.tpi().getType(class_index);887    TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag();888    // If it's a forward reference, try to get the real TypeIndex.889    if (tag_record.isForwardRef()) {890      llvm::Expected<TypeIndex> eti =891          index.tpi().findFullDeclForForwardRef(class_index);892      if (eti) {893        tag_record = CVTagRecord::create(index.tpi().getType(*eti)).asTag();894      }895    }896 897    ConstString mangled_name(898        pdb->FindMangledFunctionName(func_id).value_or(llvm::StringRef()));899 900    if (!tag_record.FieldList.isSimple()) {901      CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);902      FieldListRecord field_list;903      if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(904              field_list_cvt, field_list))905        llvm::consumeError(std::move(error));906      CreateMethodDecl process(index, m_clang, func_ti, function_decl,907                               parent_opaque_ty, func_name, mangled_name,908                               func_ct);909      if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))910        llvm::consumeError(std::move(err));911    }912 913    if (!function_decl) {914      function_decl = m_clang.AddMethodToCXXRecordType(915          parent_opaque_ty, func_name, mangled_name, func_ct,916          /*access=*/lldb::AccessType::eAccessPublic,917          /*is_virtual=*/false, /*is_static=*/false,918          /*is_inline=*/false, /*is_explicit=*/false,919          /*is_attr_used=*/false, /*is_artificial=*/false);920    }921    m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct});922  } else {923    function_decl = m_clang.CreateFunctionDeclaration(924        parent, OptionalClangModuleID(), func_name, func_ct, func_storage,925        is_inline, /*asm_label=*/{});926    CreateFunctionParameters(func_id, *function_decl, param_count);927  }928  return function_decl;929}930 931clang::FunctionDecl *932PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) {933  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(934      m_clang.GetSymbolFile()->GetBackingSymbolFile());935  PdbIndex &index = pdb->GetIndex();936  CompilandIndexItem *cii =937      index.compilands().GetCompiland(inlinesite_id.modi);938  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset);939  InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));940  cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));941 942  // Inlinee is the id index to the function id record that is inlined.943  PdbTypeSymId func_id(inline_site.Inlinee, true);944  // Look up the function decl by the id index to see if we have created a945  // function decl for a different inlinesite that refers the same function.946  if (clang::Decl *decl = TryGetDecl(func_id))947    return llvm::dyn_cast<clang::FunctionDecl>(decl);948  clang::FunctionDecl *function_decl =949      CreateFunctionDeclFromId(func_id, inlinesite_id);950  if (function_decl == nullptr)951    return nullptr;952 953  // Use inline site id in m_decl_to_status because it's expected to be a954  // PdbCompilandSymId so that we can parse local variables info after it.955  uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id);956  DeclStatus status;957  status.resolved = true;958  status.uid = inlinesite_uid;959  m_decl_to_status.insert({function_decl, status});960  // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI961  // stream are unique and there could be multiple inline sites (different ids)962  // referring the same inline function. This avoid creating multiple same963  // inline function delcs.964  uint64_t func_uid = toOpaqueUid(func_id);965  lldbassert(m_uid_to_decl.count(func_uid) == 0);966  m_uid_to_decl[func_uid] = function_decl;967  return function_decl;968}969 970clang::FunctionDecl *971PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid,972                                        PdbCompilandSymId func_sid) {973  lldbassert(func_tid.is_ipi);974  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(975      m_clang.GetSymbolFile()->GetBackingSymbolFile());976  PdbIndex &index = pdb->GetIndex();977  CVType func_cvt = index.ipi().getType(func_tid.index);978  llvm::StringRef func_name;979  TypeIndex func_ti;980  clang::DeclContext *parent = nullptr;981  switch (func_cvt.kind()) {982  case LF_MFUNC_ID: {983    MemberFuncIdRecord mfr;984    cantFail(985        TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr));986    func_name = mfr.getName();987    func_ti = mfr.getFunctionType();988    PdbTypeSymId class_type_id(mfr.ClassType, false);989    parent = GetOrCreateDeclContextForUid(class_type_id);990    break;991  }992  case LF_FUNC_ID: {993    FuncIdRecord fir;994    cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir));995    func_name = fir.getName();996    func_ti = fir.getFunctionType();997    parent = FromCompilerDeclContext(GetTranslationUnitDecl());998    if (!fir.ParentScope.isNoneType()) {999      CVType parent_cvt = index.ipi().getType(fir.ParentScope);1000      if (parent_cvt.kind() == LF_STRING_ID) {1001        StringIdRecord sir;1002        cantFail(1003            TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir));1004        parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent);1005      }1006    }1007    break;1008  }1009  default:1010    lldbassert(false && "Invalid function id type!");1011  }1012  clang::QualType func_qt = GetOrCreateType(func_ti);1013  if (func_qt.isNull() || !parent)1014    return nullptr;1015  CompilerType func_ct = ToCompilerType(func_qt);1016  uint32_t param_count =1017      llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams();1018  return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count,1019                            clang::SC_None, true, parent);1020}1021 1022clang::FunctionDecl *1023PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {1024  if (clang::Decl *decl = TryGetDecl(func_id))1025    return llvm::dyn_cast<clang::FunctionDecl>(decl);1026 1027  clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));1028  if (!parent)1029    return nullptr;1030  std::string context_name;1031  if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) {1032    context_name = ns->getQualifiedNameAsString();1033  } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) {1034    context_name = tag->getQualifiedNameAsString();1035  }1036 1037  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1038      m_clang.GetSymbolFile()->GetBackingSymbolFile());1039  PdbIndex &index = pdb->GetIndex();1040  CVSymbol cvs = index.ReadSymbolRecord(func_id);1041  ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind()));1042  llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc));1043 1044  PdbTypeSymId type_id(proc.FunctionType);1045  clang::QualType qt = GetOrCreateType(type_id);1046  if (qt.isNull())1047    return nullptr;1048 1049  clang::StorageClass storage = clang::SC_None;1050  if (proc.Kind == SymbolRecordKind::ProcSym)1051    storage = clang::SC_Static;1052 1053  const clang::FunctionProtoType *func_type =1054      llvm::dyn_cast<clang::FunctionProtoType>(qt);1055 1056  CompilerType func_ct = ToCompilerType(qt);1057 1058  llvm::StringRef proc_name = proc.Name;1059  proc_name.consume_front(context_name);1060  proc_name.consume_front("::");1061  clang::FunctionDecl *function_decl =1062      CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct,1063                         func_type->getNumParams(), storage, false, parent);1064  if (function_decl == nullptr)1065    return nullptr;1066 1067  lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);1068  m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;1069  DeclStatus status;1070  status.resolved = true;1071  status.uid = toOpaqueUid(func_id);1072  m_decl_to_status.insert({function_decl, status});1073 1074  return function_decl;1075}1076 1077void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,1078                                             clang::FunctionDecl &function_decl,1079                                             uint32_t param_count) {1080  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1081      m_clang.GetSymbolFile()->GetBackingSymbolFile());1082  PdbIndex &index = pdb->GetIndex();1083  CompilandIndexItem *cii = index.compilands().GetCompiland(func_id.modi);1084  CVSymbolArray scope =1085      cii->m_debug_stream.getSymbolArrayForScope(func_id.offset);1086 1087  scope.drop_front();1088  auto begin = scope.begin();1089  auto end = scope.end();1090  std::vector<clang::ParmVarDecl *> params;1091  for (uint32_t i = 0; i < param_count && begin != end;) {1092    uint32_t record_offset = begin.offset();1093    CVSymbol sym = *begin++;1094 1095    TypeIndex param_type;1096    llvm::StringRef param_name;1097    switch (sym.kind()) {1098    case S_REGREL32: {1099      RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);1100      cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));1101      param_type = reg.Type;1102      param_name = reg.Name;1103      break;1104    }1105    case S_REGISTER: {1106      RegisterSym reg(SymbolRecordKind::RegisterSym);1107      cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));1108      param_type = reg.Index;1109      param_name = reg.Name;1110      break;1111    }1112    case S_LOCAL: {1113      LocalSym local(SymbolRecordKind::LocalSym);1114      cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));1115      if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None)1116        continue;1117      param_type = local.Type;1118      param_name = local.Name;1119      break;1120    }1121    case S_BLOCK32:1122    case S_INLINESITE:1123    case S_INLINESITE2:1124      // All parameters should come before the first block/inlinesite.  If that1125      // isn't the case, then perhaps this is bad debug info that doesn't1126      // contain information about all parameters.1127      return;1128    default:1129      continue;1130    }1131 1132    PdbCompilandSymId param_uid(func_id.modi, record_offset);1133    clang::QualType qt = GetOrCreateType(param_type);1134    if (qt.isNull())1135      return;1136 1137    CompilerType param_type_ct = m_clang.GetType(qt);1138    clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(1139        &function_decl, OptionalClangModuleID(), param_name.str().c_str(),1140        param_type_ct, clang::SC_None, true);1141    lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);1142 1143    m_uid_to_decl[toOpaqueUid(param_uid)] = param;1144    params.push_back(param);1145    ++i;1146  }1147 1148  if (!params.empty() && params.size() == param_count)1149    function_decl.setParams(params);1150}1151 1152clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,1153                                              const EnumRecord &er) {1154  clang::DeclContext *decl_context = nullptr;1155  std::string uname;1156  std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index);1157  if (!decl_context)1158    return {};1159 1160  clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType);1161  if (underlying_type.isNull())1162    return {};1163 1164  Declaration declaration;1165  CompilerType enum_ct = m_clang.CreateEnumerationType(1166      uname, decl_context, OptionalClangModuleID(), declaration,1167      ToCompilerType(underlying_type), er.isScoped());1168 1169  TypeSystemClang::StartTagDeclarationDefinition(enum_ct);1170  TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);1171 1172  return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType());1173}1174 1175clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {1176  clang::QualType element_type = GetOrCreateType(ar.ElementType);1177  TypeSystemClang::RequireCompleteType(ToCompilerType(element_type));1178 1179  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1180      m_clang.GetSymbolFile()->GetBackingSymbolFile());1181  PdbIndex &index = pdb->GetIndex();1182  uint64_t element_size = GetSizeOfType({ar.ElementType}, index.tpi());1183  if (element_type.isNull() || element_size == 0)1184    return {};1185  uint64_t element_count = ar.Size / element_size;1186 1187  CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type),1188                                                  element_count, false);1189  return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());1190}1191 1192clang::QualType PdbAstBuilder::CreateFunctionType(1193    TypeIndex args_type_idx, TypeIndex return_type_idx,1194    llvm::codeview::CallingConvention calling_convention) {1195  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1196      m_clang.GetSymbolFile()->GetBackingSymbolFile());1197  PdbIndex &index = pdb->GetIndex();1198  TpiStream &stream = index.tpi();1199  CVType args_cvt = stream.getType(args_type_idx);1200  ArgListRecord args;1201  llvm::cantFail(1202      TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));1203 1204  llvm::ArrayRef<TypeIndex> arg_indices = llvm::ArrayRef(args.ArgIndices);1205  bool is_variadic = IsCVarArgsFunction(arg_indices);1206  if (is_variadic)1207    arg_indices = arg_indices.drop_back();1208 1209  std::vector<CompilerType> arg_types;1210  arg_types.reserve(arg_indices.size());1211 1212  for (TypeIndex arg_index : arg_indices) {1213    clang::QualType arg_type = GetOrCreateType(arg_index);1214    if (arg_type.isNull())1215      continue;1216    arg_types.push_back(ToCompilerType(arg_type));1217  }1218 1219  clang::QualType return_type = GetOrCreateType(return_type_idx);1220  if (return_type.isNull())1221    return {};1222 1223  std::optional<clang::CallingConv> cc =1224      TranslateCallingConvention(calling_convention);1225  if (!cc)1226    return {};1227 1228  CompilerType return_ct = ToCompilerType(return_type);1229  CompilerType func_sig_ast_type =1230      m_clang.CreateFunctionType(return_ct, arg_types, is_variadic, 0, *cc);1231 1232  return clang::QualType::getFromOpaquePtr(1233      func_sig_ast_type.GetOpaqueQualType());1234}1235 1236static bool isTagDecl(clang::DeclContext &context) {1237  return llvm::isa<clang::TagDecl>(&context);1238}1239 1240static bool isFunctionDecl(clang::DeclContext &context) {1241  return llvm::isa<clang::FunctionDecl>(&context);1242}1243 1244static bool isBlockDecl(clang::DeclContext &context) {1245  return llvm::isa<clang::BlockDecl>(&context);1246}1247 1248void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) {1249  clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(&context);1250  if (m_parsed_namespaces.contains(ns))1251    return;1252  std::string qname = ns->getQualifiedNameAsString();1253  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1254      m_clang.GetSymbolFile()->GetBackingSymbolFile());1255  PdbIndex &index = pdb->GetIndex();1256  TypeIndex ti{index.tpi().TypeIndexBegin()};1257  for (const CVType &cvt : index.tpi().typeArray()) {1258    PdbTypeSymId tid{ti};1259    ++ti;1260 1261    if (!IsTagRecord(cvt))1262      continue;1263 1264    CVTagRecord tag = CVTagRecord::create(cvt);1265 1266    // Call CreateDeclInfoForType unconditionally so that the namespace info1267    // gets created.  But only call CreateRecordType if the namespace name1268    // matches.1269    clang::DeclContext *context = nullptr;1270    std::string uname;1271    std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index);1272    if (!context || !context->isNamespace())1273      continue;1274 1275    clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);1276    llvm::StringRef ns_name = ns->getName();1277    if (ns_name.starts_with(qname)) {1278      ns_name = ns_name.drop_front(qname.size());1279      if (ns_name.starts_with("::"))1280        GetOrCreateType(tid);1281    }1282  }1283  ParseAllFunctionsAndNonLocalVars();1284  m_parsed_namespaces.insert(ns);1285}1286 1287void PdbAstBuilder::ParseAllTypes() {1288  llvm::call_once(m_parse_all_types, [this]() {1289    SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1290        m_clang.GetSymbolFile()->GetBackingSymbolFile());1291    PdbIndex &index = pdb->GetIndex();1292    TypeIndex ti{index.tpi().TypeIndexBegin()};1293    for (const CVType &cvt : index.tpi().typeArray()) {1294      PdbTypeSymId tid{ti};1295      ++ti;1296 1297      if (!IsTagRecord(cvt))1298        continue;1299 1300      GetOrCreateType(tid);1301    }1302  });1303}1304 1305void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() {1306  llvm::call_once(m_parse_functions_and_non_local_vars, [this]() {1307    SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1308        m_clang.GetSymbolFile()->GetBackingSymbolFile());1309    PdbIndex &index = pdb->GetIndex();1310    uint32_t module_count = index.dbi().modules().getModuleCount();1311    for (uint16_t modi = 0; modi < module_count; ++modi) {1312      CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi);1313      const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();1314      auto iter = symbols.begin();1315      while (iter != symbols.end()) {1316        PdbCompilandSymId sym_id{modi, iter.offset()};1317 1318        switch (iter->kind()) {1319        case S_GPROC32:1320        case S_LPROC32:1321          GetOrCreateFunctionDecl(sym_id);1322          iter = symbols.at(getScopeEndOffset(*iter));1323          break;1324        case S_GDATA32:1325        case S_GTHREAD32:1326        case S_LDATA32:1327        case S_LTHREAD32:1328          GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);1329          ++iter;1330          break;1331        default:1332          ++iter;1333          continue;1334        }1335      }1336    }1337  });1338}1339 1340static CVSymbolArray skipFunctionParameters(clang::Decl &decl,1341                                            const CVSymbolArray &symbols) {1342  clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>(&decl);1343  if (!func_decl)1344    return symbols;1345  unsigned int params = func_decl->getNumParams();1346  if (params == 0)1347    return symbols;1348 1349  CVSymbolArray result = symbols;1350 1351  while (!result.empty()) {1352    if (params == 0)1353      return result;1354 1355    CVSymbol sym = *result.begin();1356    result.drop_front();1357 1358    if (!isLocalVariableType(sym.kind()))1359      continue;1360 1361    --params;1362  }1363  return result;1364}1365 1366void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) {1367  SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(1368      m_clang.GetSymbolFile()->GetBackingSymbolFile());1369  PdbIndex &index = pdb->GetIndex();1370  CVSymbol sym = index.ReadSymbolRecord(block_id);1371  lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 ||1372             sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE);1373  CompilandIndexItem &cii =1374      index.compilands().GetOrCreateCompiland(block_id.modi);1375  CVSymbolArray symbols =1376      cii.m_debug_stream.getSymbolArrayForScope(block_id.offset);1377 1378  // Function parameters should already have been created when the function was1379  // parsed.1380  if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32)1381    symbols =1382        skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols);1383 1384  symbols.drop_front();1385  auto begin = symbols.begin();1386  while (begin != symbols.end()) {1387    PdbCompilandSymId child_sym_id(block_id.modi, begin.offset());1388    GetOrCreateSymbolForId(child_sym_id);1389    if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) {1390      ParseBlockChildren(child_sym_id);1391      begin = symbols.at(getScopeEndOffset(*begin));1392    }1393    ++begin;1394  }1395}1396 1397void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) {1398 1399  clang::Decl *decl = clang::Decl::castFromDeclContext(&context);1400  lldbassert(decl);1401 1402  auto iter = m_decl_to_status.find(decl);1403  lldbassert(iter != m_decl_to_status.end());1404 1405  if (auto *tag = llvm::dyn_cast<clang::TagDecl>(&context)) {1406    CompleteTagDecl(*tag);1407    return;1408  }1409 1410  if (isFunctionDecl(context) || isBlockDecl(context)) {1411    PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym();1412    ParseBlockChildren(block_id);1413  }1414}1415 1416void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {1417  // Namespaces aren't explicitly represented in the debug info, and the only1418  // way to parse them is to parse all type info, demangling every single type1419  // and trying to reconstruct the DeclContext hierarchy this way.  Since this1420  // is an expensive operation, we have to special case it so that we do other1421  // work (such as parsing the items that appear within the namespaces) at the1422  // same time.1423  if (context.isTranslationUnit()) {1424    ParseAllTypes();1425    ParseAllFunctionsAndNonLocalVars();1426    return;1427  }1428 1429  if (context.isNamespace()) {1430    ParseNamespace(context);1431    return;1432  }1433 1434  if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) {1435    ParseDeclsForSimpleContext(context);1436    return;1437  }1438}1439 1440CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {1441  return m_clang.GetCompilerDecl(&decl);1442}1443 1444CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {1445  return {m_clang.weak_from_this(), qt.getAsOpaquePtr()};1446}1447 1448CompilerDeclContext1449PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {1450  return m_clang.CreateDeclContext(&context);1451}1452 1453clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {1454  return ClangUtil::GetDecl(decl);1455}1456 1457clang::DeclContext *1458PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {1459  return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());1460}1461 1462void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter,1463                         bool show_color) {1464  m_clang.Dump(stream.AsRawOstream(), filter, show_color);1465}1466 1467clang::NamespaceDecl *1468PdbAstBuilder::FindNamespaceDecl(const clang::DeclContext *parent,1469                                 llvm::StringRef name) {1470  NamespaceSet *set;1471  if (parent) {1472    auto it = m_parent_to_namespaces.find(parent);1473    if (it == m_parent_to_namespaces.end())1474      return nullptr;1475 1476    set = &it->second;1477  } else {1478    // In this case, search through all known namespaces1479    set = &m_known_namespaces;1480  }1481  assert(set);1482 1483  for (clang::NamespaceDecl *namespace_decl : *set)1484    if (namespace_decl->getName() == name)1485      return namespace_decl;1486 1487  for (clang::NamespaceDecl *namespace_decl : *set)1488    if (namespace_decl->isAnonymousNamespace())1489      return FindNamespaceDecl(namespace_decl, name);1490 1491  return nullptr;1492}1493