180814287SRaphael Isemann //===-- PDBASTParser.cpp --------------------------------------------------===//
242dff790SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
642dff790SZachary Turner //
742dff790SZachary Turner //===----------------------------------------------------------------------===//
842dff790SZachary Turner 
942dff790SZachary Turner #include "PDBASTParser.h"
1042dff790SZachary Turner 
117d2a74fcSAleksandr Urakov #include "SymbolFilePDB.h"
127d2a74fcSAleksandr Urakov 
1342dff790SZachary Turner #include "clang/AST/CharUnits.h"
1442dff790SZachary Turner #include "clang/AST/Decl.h"
1542dff790SZachary Turner #include "clang/AST/DeclCXX.h"
1642dff790SZachary Turner 
178be30215SAlex Langford #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
188be30215SAlex Langford #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
198be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
201435f6b0SMed Ismail Bennani #include "lldb/Core/Declaration.h"
217d2a74fcSAleksandr Urakov #include "lldb/Core/Module.h"
2242dff790SZachary Turner #include "lldb/Symbol/SymbolFile.h"
23709426b3SAleksandr Urakov #include "lldb/Symbol/TypeMap.h"
2442dff790SZachary Turner #include "lldb/Symbol/TypeSystem.h"
25c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
26eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
277ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
287ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
2942dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbol.h"
3042dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
317ac1c780SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
3242dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
33eb4c8608Sserge-sans-paille #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
3442dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
3542dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
3642dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
3742dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
38ec40f818SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
3942dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
4042dff790SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
4142dff790SZachary Turner 
42c1e530eeSAleksandr Urakov #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
43c1e530eeSAleksandr Urakov 
4442dff790SZachary Turner using namespace lldb;
4542dff790SZachary Turner using namespace lldb_private;
4654fd7ff6SZachary Turner using namespace llvm::pdb;
4742dff790SZachary Turner 
TranslateUdtKind(PDB_UdtType pdb_kind)48d9a58f5aSPavel Labath static int TranslateUdtKind(PDB_UdtType pdb_kind) {
49b9c1b51eSKate Stone   switch (pdb_kind) {
5042dff790SZachary Turner   case PDB_UdtType::Class:
5142dff790SZachary Turner     return clang::TTK_Class;
5242dff790SZachary Turner   case PDB_UdtType::Struct:
5342dff790SZachary Turner     return clang::TTK_Struct;
5442dff790SZachary Turner   case PDB_UdtType::Union:
5542dff790SZachary Turner     return clang::TTK_Union;
5642dff790SZachary Turner   case PDB_UdtType::Interface:
5742dff790SZachary Turner     return clang::TTK_Interface;
5842dff790SZachary Turner   }
5953459482SAleksandr Urakov   llvm_unreachable("unsuported PDB UDT type");
6042dff790SZachary Turner }
6142dff790SZachary Turner 
TranslateBuiltinEncoding(PDB_BuiltinType type)62d9a58f5aSPavel Labath static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
63b9c1b51eSKate Stone   switch (type) {
6442dff790SZachary Turner   case PDB_BuiltinType::Float:
6542dff790SZachary Turner     return lldb::eEncodingIEEE754;
6642dff790SZachary Turner   case PDB_BuiltinType::Int:
6742dff790SZachary Turner   case PDB_BuiltinType::Long:
6842dff790SZachary Turner   case PDB_BuiltinType::Char:
6942dff790SZachary Turner     return lldb::eEncodingSint;
7042dff790SZachary Turner   case PDB_BuiltinType::Bool:
719b5c3db0SAaron Smith   case PDB_BuiltinType::Char16:
729b5c3db0SAaron Smith   case PDB_BuiltinType::Char32:
7342dff790SZachary Turner   case PDB_BuiltinType::UInt:
7442dff790SZachary Turner   case PDB_BuiltinType::ULong:
7542dff790SZachary Turner   case PDB_BuiltinType::HResult:
766de0ca42SAaron Smith   case PDB_BuiltinType::WCharT:
7742dff790SZachary Turner     return lldb::eEncodingUint;
7842dff790SZachary Turner   default:
7942dff790SZachary Turner     return lldb::eEncodingInvalid;
8042dff790SZachary Turner   }
8142dff790SZachary Turner }
82ec40f818SAaron Smith 
TranslateEnumEncoding(PDB_VariantType type)83d9a58f5aSPavel Labath static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
84ec40f818SAaron Smith   switch (type) {
85ec40f818SAaron Smith   case PDB_VariantType::Int8:
86ec40f818SAaron Smith   case PDB_VariantType::Int16:
87ec40f818SAaron Smith   case PDB_VariantType::Int32:
88ec40f818SAaron Smith   case PDB_VariantType::Int64:
89ec40f818SAaron Smith     return lldb::eEncodingSint;
90ec40f818SAaron Smith 
91ec40f818SAaron Smith   case PDB_VariantType::UInt8:
92ec40f818SAaron Smith   case PDB_VariantType::UInt16:
93ec40f818SAaron Smith   case PDB_VariantType::UInt32:
94ec40f818SAaron Smith   case PDB_VariantType::UInt64:
95ec40f818SAaron Smith     return lldb::eEncodingUint;
96ec40f818SAaron Smith 
97ec40f818SAaron Smith   default:
98ec40f818SAaron Smith     break;
99ec40f818SAaron Smith   }
100ec40f818SAaron Smith 
101ec40f818SAaron Smith   return lldb::eEncodingSint;
102ec40f818SAaron Smith }
103ec40f818SAaron Smith 
104d9a58f5aSPavel Labath static CompilerType
GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang & clang_ast,const PDBSymbolTypeBuiltin & pdb_type,Encoding encoding,uint32_t width)1056e3b0cc2SRaphael Isemann GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast,
106c8316ed2SAaron Smith                                        const PDBSymbolTypeBuiltin &pdb_type,
107ec40f818SAaron Smith                                        Encoding encoding, uint32_t width) {
108f9f49d35SRaphael Isemann   clang::ASTContext &ast = clang_ast.getASTContext();
109ec40f818SAaron Smith 
110e664b5dcSAaron Smith   switch (pdb_type.getBuiltinType()) {
111c8316ed2SAaron Smith   default:
112c8316ed2SAaron Smith     break;
113ec40f818SAaron Smith   case PDB_BuiltinType::None:
114ec40f818SAaron Smith     return CompilerType();
115ec40f818SAaron Smith   case PDB_BuiltinType::Void:
116e664b5dcSAaron Smith     return clang_ast.GetBasicType(eBasicTypeVoid);
117ec97b523SAleksandr Urakov   case PDB_BuiltinType::Char:
118ec97b523SAleksandr Urakov     return clang_ast.GetBasicType(eBasicTypeChar);
119ec40f818SAaron Smith   case PDB_BuiltinType::Bool:
120e664b5dcSAaron Smith     return clang_ast.GetBasicType(eBasicTypeBool);
121ec40f818SAaron Smith   case PDB_BuiltinType::Long:
122f9f49d35SRaphael Isemann     if (width == ast.getTypeSize(ast.LongTy))
123b036f557SRaphael Isemann       return CompilerType(&clang_ast, ast.LongTy.getAsOpaquePtr());
124f9f49d35SRaphael Isemann     if (width == ast.getTypeSize(ast.LongLongTy))
125b036f557SRaphael Isemann       return CompilerType(&clang_ast, ast.LongLongTy.getAsOpaquePtr());
126ec40f818SAaron Smith     break;
127ec40f818SAaron Smith   case PDB_BuiltinType::ULong:
128f9f49d35SRaphael Isemann     if (width == ast.getTypeSize(ast.UnsignedLongTy))
129b036f557SRaphael Isemann       return CompilerType(&clang_ast, ast.UnsignedLongTy.getAsOpaquePtr());
130f9f49d35SRaphael Isemann     if (width == ast.getTypeSize(ast.UnsignedLongLongTy))
131b036f557SRaphael Isemann       return CompilerType(&clang_ast, ast.UnsignedLongLongTy.getAsOpaquePtr());
132ec40f818SAaron Smith     break;
133ec40f818SAaron Smith   case PDB_BuiltinType::WCharT:
134f9f49d35SRaphael Isemann     if (width == ast.getTypeSize(ast.WCharTy))
135b036f557SRaphael Isemann       return CompilerType(&clang_ast, ast.WCharTy.getAsOpaquePtr());
136ec40f818SAaron Smith     break;
1372a989f36SAaron Smith   case PDB_BuiltinType::Char16:
138b036f557SRaphael Isemann     return CompilerType(&clang_ast, ast.Char16Ty.getAsOpaquePtr());
1392a989f36SAaron Smith   case PDB_BuiltinType::Char32:
140b036f557SRaphael Isemann     return CompilerType(&clang_ast, ast.Char32Ty.getAsOpaquePtr());
141ec40f818SAaron Smith   case PDB_BuiltinType::Float:
142c8316ed2SAaron Smith     // Note: types `long double` and `double` have same bit size in MSVC and
143c8316ed2SAaron Smith     // there is no information in the PDB to distinguish them. So when falling
144c8316ed2SAaron Smith     // back to default search, the compiler type of `long double` will be
145c8316ed2SAaron Smith     // represented by the one generated for `double`.
146ec40f818SAaron Smith     break;
147ec40f818SAaron Smith   }
14805097246SAdrian Prantl   // If there is no match on PDB_BuiltinType, fall back to default search by
14905097246SAdrian Prantl   // encoding and width only
150e664b5dcSAaron Smith   return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
151ec40f818SAaron Smith }
152ec40f818SAaron Smith 
GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin & pdb_type,CompilerType & compiler_type)153d9a58f5aSPavel Labath static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
154ec40f818SAaron Smith                                          CompilerType &compiler_type) {
155e664b5dcSAaron Smith   PDB_BuiltinType kind = pdb_type.getBuiltinType();
156ec40f818SAaron Smith   switch (kind) {
157c8316ed2SAaron Smith   default:
158c8316ed2SAaron Smith     break;
159ec40f818SAaron Smith   case PDB_BuiltinType::Currency:
160ec40f818SAaron Smith     return ConstString("CURRENCY");
161ec40f818SAaron Smith   case PDB_BuiltinType::Date:
162ec40f818SAaron Smith     return ConstString("DATE");
163ec40f818SAaron Smith   case PDB_BuiltinType::Variant:
164ec40f818SAaron Smith     return ConstString("VARIANT");
165ec40f818SAaron Smith   case PDB_BuiltinType::Complex:
166ec40f818SAaron Smith     return ConstString("complex");
167ec40f818SAaron Smith   case PDB_BuiltinType::Bitfield:
168ec40f818SAaron Smith     return ConstString("bitfield");
169ec40f818SAaron Smith   case PDB_BuiltinType::BSTR:
170ec40f818SAaron Smith     return ConstString("BSTR");
171ec40f818SAaron Smith   case PDB_BuiltinType::HResult:
172ec40f818SAaron Smith     return ConstString("HRESULT");
173ec40f818SAaron Smith   case PDB_BuiltinType::BCD:
174ec40f818SAaron Smith     return ConstString("BCD");
1752a989f36SAaron Smith   case PDB_BuiltinType::Char16:
1762a989f36SAaron Smith     return ConstString("char16_t");
1772a989f36SAaron Smith   case PDB_BuiltinType::Char32:
1782a989f36SAaron Smith     return ConstString("char32_t");
179ec40f818SAaron Smith   case PDB_BuiltinType::None:
180ec40f818SAaron Smith     return ConstString("...");
181ec40f818SAaron Smith   }
182ec40f818SAaron Smith   return compiler_type.GetTypeName();
183ec40f818SAaron Smith }
1847ac1c780SAaron Smith 
GetDeclarationForSymbol(const PDBSymbol & symbol,Declaration & decl)185d9a58f5aSPavel Labath static bool GetDeclarationForSymbol(const PDBSymbol &symbol,
186d9a58f5aSPavel Labath                                     Declaration &decl) {
1877ac1c780SAaron Smith   auto &raw_sym = symbol.getRawSymbol();
1887abdf2d2SAaron Smith   auto first_line_up = raw_sym.getSrcLineOnTypeDefn();
1897abdf2d2SAaron Smith 
1907abdf2d2SAaron Smith   if (!first_line_up) {
1917ac1c780SAaron Smith     auto lines_up = symbol.getSession().findLineNumbersByAddress(
1927ac1c780SAaron Smith         raw_sym.getVirtualAddress(), raw_sym.getLength());
1937ac1c780SAaron Smith     if (!lines_up)
1947ac1c780SAaron Smith       return false;
1957abdf2d2SAaron Smith     first_line_up = lines_up->getNext();
1967ac1c780SAaron Smith     if (!first_line_up)
1977ac1c780SAaron Smith       return false;
1987abdf2d2SAaron Smith   }
1997ac1c780SAaron Smith   uint32_t src_file_id = first_line_up->getSourceFileId();
2007ac1c780SAaron Smith   auto src_file_up = symbol.getSession().getSourceFileById(src_file_id);
2017ac1c780SAaron Smith   if (!src_file_up)
2027ac1c780SAaron Smith     return false;
2037ac1c780SAaron Smith 
2048f3be7a3SJonas Devlieghere   FileSpec spec(src_file_up->getFileName());
2057ac1c780SAaron Smith   decl.SetFile(spec);
2067ac1c780SAaron Smith   decl.SetColumn(first_line_up->getColumnNumber());
2077ac1c780SAaron Smith   decl.SetLine(first_line_up->getLineNumber());
2087ac1c780SAaron Smith   return true;
2097ac1c780SAaron Smith }
2107d2a74fcSAleksandr Urakov 
TranslateMemberAccess(PDB_MemberAccess access)211d9a58f5aSPavel Labath static AccessType TranslateMemberAccess(PDB_MemberAccess access) {
2127d2a74fcSAleksandr Urakov   switch (access) {
2137d2a74fcSAleksandr Urakov   case PDB_MemberAccess::Private:
2147d2a74fcSAleksandr Urakov     return eAccessPrivate;
2157d2a74fcSAleksandr Urakov   case PDB_MemberAccess::Protected:
2167d2a74fcSAleksandr Urakov     return eAccessProtected;
2177d2a74fcSAleksandr Urakov   case PDB_MemberAccess::Public:
2187d2a74fcSAleksandr Urakov     return eAccessPublic;
2197d2a74fcSAleksandr Urakov   }
22053459482SAleksandr Urakov   return eAccessNone;
2217d2a74fcSAleksandr Urakov }
2227d2a74fcSAleksandr Urakov 
GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind)223d9a58f5aSPavel Labath static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) {
2247d2a74fcSAleksandr Urakov   switch (udt_kind) {
2257d2a74fcSAleksandr Urakov   case PDB_UdtType::Struct:
2267d2a74fcSAleksandr Urakov   case PDB_UdtType::Union:
2277d2a74fcSAleksandr Urakov     return eAccessPublic;
2287d2a74fcSAleksandr Urakov   case PDB_UdtType::Class:
2297d2a74fcSAleksandr Urakov   case PDB_UdtType::Interface:
2307d2a74fcSAleksandr Urakov     return eAccessPrivate;
2317d2a74fcSAleksandr Urakov   }
23253459482SAleksandr Urakov   llvm_unreachable("unsupported PDB UDT type");
2337d2a74fcSAleksandr Urakov }
2347d2a74fcSAleksandr Urakov 
GetAccessibilityForUdt(const PDBSymbolTypeUDT & udt)235d9a58f5aSPavel Labath static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) {
2367d2a74fcSAleksandr Urakov   AccessType access = TranslateMemberAccess(udt.getAccess());
2377d2a74fcSAleksandr Urakov   if (access != lldb::eAccessNone || !udt.isNested())
2387d2a74fcSAleksandr Urakov     return access;
2397d2a74fcSAleksandr Urakov 
2407d2a74fcSAleksandr Urakov   auto parent = udt.getClassParent();
2417d2a74fcSAleksandr Urakov   if (!parent)
2427d2a74fcSAleksandr Urakov     return lldb::eAccessNone;
2437d2a74fcSAleksandr Urakov 
2447d2a74fcSAleksandr Urakov   auto parent_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(parent.get());
2457d2a74fcSAleksandr Urakov   if (!parent_udt)
2467d2a74fcSAleksandr Urakov     return lldb::eAccessNone;
2477d2a74fcSAleksandr Urakov 
2487d2a74fcSAleksandr Urakov   return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind());
2497d2a74fcSAleksandr Urakov }
2507d2a74fcSAleksandr Urakov 
251d9a58f5aSPavel Labath static clang::MSInheritanceAttr::Spelling
GetMSInheritance(const PDBSymbolTypeUDT & udt)252709426b3SAleksandr Urakov GetMSInheritance(const PDBSymbolTypeUDT &udt) {
2537d2a74fcSAleksandr Urakov   int base_count = 0;
2547d2a74fcSAleksandr Urakov   bool has_virtual = false;
2557d2a74fcSAleksandr Urakov 
2567d2a74fcSAleksandr Urakov   auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
2577d2a74fcSAleksandr Urakov   if (bases_enum) {
2587d2a74fcSAleksandr Urakov     while (auto base = bases_enum->getNext()) {
2597d2a74fcSAleksandr Urakov       base_count++;
2607d2a74fcSAleksandr Urakov       has_virtual |= base->isVirtualBaseClass();
2617d2a74fcSAleksandr Urakov     }
2627d2a74fcSAleksandr Urakov   }
2637d2a74fcSAleksandr Urakov 
2647d2a74fcSAleksandr Urakov   if (has_virtual)
2657d2a74fcSAleksandr Urakov     return clang::MSInheritanceAttr::Keyword_virtual_inheritance;
2667d2a74fcSAleksandr Urakov   if (base_count > 1)
2677d2a74fcSAleksandr Urakov     return clang::MSInheritanceAttr::Keyword_multiple_inheritance;
2687d2a74fcSAleksandr Urakov   return clang::MSInheritanceAttr::Keyword_single_inheritance;
2697d2a74fcSAleksandr Urakov }
270709426b3SAleksandr Urakov 
271d9a58f5aSPavel Labath static std::unique_ptr<llvm::pdb::PDBSymbol>
GetClassOrFunctionParent(const llvm::pdb::PDBSymbol & symbol)272709426b3SAleksandr Urakov GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) {
273709426b3SAleksandr Urakov   const IPDBSession &session = symbol.getSession();
274709426b3SAleksandr Urakov   const IPDBRawSymbol &raw = symbol.getRawSymbol();
2752fa5c283SAleksandr Urakov   auto tag = symbol.getSymTag();
276709426b3SAleksandr Urakov 
2772fa5c283SAleksandr Urakov   // For items that are nested inside of a class, return the class that it is
2782fa5c283SAleksandr Urakov   // nested inside of.
2792fa5c283SAleksandr Urakov   // Note that only certain items can be nested inside of classes.
2802fa5c283SAleksandr Urakov   switch (tag) {
2812fa5c283SAleksandr Urakov   case PDB_SymType::Function:
2822fa5c283SAleksandr Urakov   case PDB_SymType::Data:
2832fa5c283SAleksandr Urakov   case PDB_SymType::UDT:
2842fa5c283SAleksandr Urakov   case PDB_SymType::Enum:
2852fa5c283SAleksandr Urakov   case PDB_SymType::FunctionSig:
2862fa5c283SAleksandr Urakov   case PDB_SymType::Typedef:
2872fa5c283SAleksandr Urakov   case PDB_SymType::BaseClass:
2882fa5c283SAleksandr Urakov   case PDB_SymType::VTable: {
289709426b3SAleksandr Urakov     auto class_parent_id = raw.getClassParentId();
290709426b3SAleksandr Urakov     if (auto class_parent = session.getSymbolById(class_parent_id))
291709426b3SAleksandr Urakov       return class_parent;
2924dc0b1acSReid Kleckner     break;
2932fa5c283SAleksandr Urakov   }
2942fa5c283SAleksandr Urakov   default:
2952fa5c283SAleksandr Urakov     break;
2962fa5c283SAleksandr Urakov   }
297709426b3SAleksandr Urakov 
2982fa5c283SAleksandr Urakov   // Otherwise, if it is nested inside of a function, return the function.
2992fa5c283SAleksandr Urakov   // Note that only certain items can be nested inside of functions.
3002fa5c283SAleksandr Urakov   switch (tag) {
3012fa5c283SAleksandr Urakov   case PDB_SymType::Block:
3022fa5c283SAleksandr Urakov   case PDB_SymType::Data: {
303709426b3SAleksandr Urakov     auto lexical_parent_id = raw.getLexicalParentId();
304709426b3SAleksandr Urakov     auto lexical_parent = session.getSymbolById(lexical_parent_id);
305709426b3SAleksandr Urakov     if (!lexical_parent)
306709426b3SAleksandr Urakov       return nullptr;
307709426b3SAleksandr Urakov 
308709426b3SAleksandr Urakov     auto lexical_parent_tag = lexical_parent->getSymTag();
309709426b3SAleksandr Urakov     if (lexical_parent_tag == PDB_SymType::Function)
310709426b3SAleksandr Urakov       return lexical_parent;
311709426b3SAleksandr Urakov     if (lexical_parent_tag == PDB_SymType::Exe)
312709426b3SAleksandr Urakov       return nullptr;
313709426b3SAleksandr Urakov 
314709426b3SAleksandr Urakov     return GetClassOrFunctionParent(*lexical_parent);
315709426b3SAleksandr Urakov   }
3162fa5c283SAleksandr Urakov   default:
3172fa5c283SAleksandr Urakov     return nullptr;
3182fa5c283SAleksandr Urakov   }
3192fa5c283SAleksandr Urakov }
320709426b3SAleksandr Urakov 
321d9a58f5aSPavel Labath static clang::NamedDecl *
GetDeclFromContextByName(const clang::ASTContext & ast,const clang::DeclContext & decl_context,llvm::StringRef name)322709426b3SAleksandr Urakov GetDeclFromContextByName(const clang::ASTContext &ast,
323709426b3SAleksandr Urakov                          const clang::DeclContext &decl_context,
324709426b3SAleksandr Urakov                          llvm::StringRef name) {
325709426b3SAleksandr Urakov   clang::IdentifierInfo &ident = ast.Idents.get(name);
326709426b3SAleksandr Urakov   clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident);
327709426b3SAleksandr Urakov   clang::DeclContext::lookup_result result = decl_context.lookup(decl_name);
328709426b3SAleksandr Urakov   if (result.empty())
329709426b3SAleksandr Urakov     return nullptr;
330709426b3SAleksandr Urakov 
3310cb7e7caSVassil Vassilev   return *result.begin();
332709426b3SAleksandr Urakov }
333709426b3SAleksandr Urakov 
IsAnonymousNamespaceName(llvm::StringRef name)334c1e530eeSAleksandr Urakov static bool IsAnonymousNamespaceName(llvm::StringRef name) {
335d9a58f5aSPavel Labath   return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
336709426b3SAleksandr Urakov }
33742dff790SZachary Turner 
TranslateCallingConvention(PDB_CallingConv pdb_cc)338bc4707ccSAleksandr Urakov static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
339bc4707ccSAleksandr Urakov   switch (pdb_cc) {
340bc4707ccSAleksandr Urakov   case llvm::codeview::CallingConvention::NearC:
341bc4707ccSAleksandr Urakov     return clang::CC_C;
342bc4707ccSAleksandr Urakov   case llvm::codeview::CallingConvention::NearStdCall:
343bc4707ccSAleksandr Urakov     return clang::CC_X86StdCall;
344bc4707ccSAleksandr Urakov   case llvm::codeview::CallingConvention::NearFast:
345bc4707ccSAleksandr Urakov     return clang::CC_X86FastCall;
346bc4707ccSAleksandr Urakov   case llvm::codeview::CallingConvention::ThisCall:
347bc4707ccSAleksandr Urakov     return clang::CC_X86ThisCall;
348bc4707ccSAleksandr Urakov   case llvm::codeview::CallingConvention::NearVector:
349bc4707ccSAleksandr Urakov     return clang::CC_X86VectorCall;
350bc4707ccSAleksandr Urakov   case llvm::codeview::CallingConvention::NearPascal:
351bc4707ccSAleksandr Urakov     return clang::CC_X86Pascal;
352bc4707ccSAleksandr Urakov   default:
353bc4707ccSAleksandr Urakov     assert(false && "Unknown calling convention");
354bc4707ccSAleksandr Urakov     return clang::CC_C;
355bc4707ccSAleksandr Urakov   }
356bc4707ccSAleksandr Urakov }
357bc4707ccSAleksandr Urakov 
PDBASTParser(lldb_private::TypeSystemClang & ast)3586e3b0cc2SRaphael Isemann PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}
35942dff790SZachary Turner 
360fd2433e1SJonas Devlieghere PDBASTParser::~PDBASTParser() = default;
36142dff790SZachary Turner 
36242dff790SZachary Turner // DebugInfoASTParser interface
36342dff790SZachary Turner 
CreateLLDBTypeFromPDBType(const PDBSymbol & type)364b9c1b51eSKate Stone lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
36542dff790SZachary Turner   Declaration decl;
3667ac1c780SAaron Smith   switch (type.getSymTag()) {
3677d2a74fcSAleksandr Urakov   case PDB_SymType::BaseClass: {
3687d2a74fcSAleksandr Urakov     auto symbol_file = m_ast.GetSymbolFile();
3697d2a74fcSAleksandr Urakov     if (!symbol_file)
3707d2a74fcSAleksandr Urakov       return nullptr;
3717d2a74fcSAleksandr Urakov 
3727d2a74fcSAleksandr Urakov     auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId());
3737d2a74fcSAleksandr Urakov     return ty ? ty->shared_from_this() : nullptr;
3747d2a74fcSAleksandr Urakov   } break;
3757ac1c780SAaron Smith   case PDB_SymType::UDT: {
3767ac1c780SAaron Smith     auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);
3777ac1c780SAaron Smith     assert(udt);
3787d2a74fcSAleksandr Urakov 
3797d2a74fcSAleksandr Urakov     // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol
3807d2a74fcSAleksandr Urakov     // other than a Typedef symbol in PDB. For example,
3817d2a74fcSAleksandr Urakov     //    typedef union { short Row; short Col; } Union;
3827d2a74fcSAleksandr Urakov     // is generated as a named UDT in PDB:
3837d2a74fcSAleksandr Urakov     //    union Union { short Row; short Col; }
3847d2a74fcSAleksandr Urakov     // Such symbols will be handled here.
3857d2a74fcSAleksandr Urakov 
3867d2a74fcSAleksandr Urakov     // Some UDT with trival ctor has zero length. Just ignore.
3877d2a74fcSAleksandr Urakov     if (udt->getLength() == 0)
388ec40f818SAaron Smith       return nullptr;
38942dff790SZachary Turner 
3907d2a74fcSAleksandr Urakov     // Ignore unnamed-tag UDTs.
391adcd0268SBenjamin Kramer     std::string name =
392adcd0268SBenjamin Kramer         std::string(MSVCUndecoratedNameParser::DropScope(udt->getName()));
393709426b3SAleksandr Urakov     if (name.empty())
3947d2a74fcSAleksandr Urakov       return nullptr;
3957d2a74fcSAleksandr Urakov 
396709426b3SAleksandr Urakov     auto decl_context = GetDeclContextContainingSymbol(type);
397709426b3SAleksandr Urakov 
398709426b3SAleksandr Urakov     // Check if such an UDT already exists in the current context.
399709426b3SAleksandr Urakov     // This may occur with const or volatile types. There are separate type
400709426b3SAleksandr Urakov     // symbols in PDB for types with const or volatile modifiers, but we need
401709426b3SAleksandr Urakov     // to create only one declaration for them all.
402d4f18f11SAdrian Prantl     Type::ResolveState type_resolve_state;
403709426b3SAleksandr Urakov     CompilerType clang_type = m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(
404709426b3SAleksandr Urakov         ConstString(name), decl_context);
405709426b3SAleksandr Urakov     if (!clang_type.IsValid()) {
4067d2a74fcSAleksandr Urakov       auto access = GetAccessibilityForUdt(*udt);
4077d2a74fcSAleksandr Urakov 
4087d2a74fcSAleksandr Urakov       auto tag_type_kind = TranslateUdtKind(udt->getUdtKind());
4097d2a74fcSAleksandr Urakov 
4107d2a74fcSAleksandr Urakov       ClangASTMetadata metadata;
4117d2a74fcSAleksandr Urakov       metadata.SetUserID(type.getSymIndexId());
4127d2a74fcSAleksandr Urakov       metadata.SetIsDynamicCXXType(false);
41342dff790SZachary Turner 
414143d507cSAdrian Prantl       clang_type = m_ast.CreateRecordType(
415143d507cSAdrian Prantl           decl_context, OptionalClangModuleID(), access, name, tag_type_kind,
4167d2a74fcSAleksandr Urakov           lldb::eLanguageTypeC_plus_plus, &metadata);
4177d2a74fcSAleksandr Urakov       assert(clang_type.IsValid());
4187d2a74fcSAleksandr Urakov 
419709426b3SAleksandr Urakov       auto record_decl =
420709426b3SAleksandr Urakov           m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
421709426b3SAleksandr Urakov       assert(record_decl);
422709426b3SAleksandr Urakov       m_uid_to_decl[type.getSymIndexId()] = record_decl;
423709426b3SAleksandr Urakov 
424709426b3SAleksandr Urakov       auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit(
425f9f49d35SRaphael Isemann           m_ast.getASTContext(), GetMSInheritance(*udt));
426709426b3SAleksandr Urakov       record_decl->addAttr(inheritance_attr);
427709426b3SAleksandr Urakov 
4286e3b0cc2SRaphael Isemann       TypeSystemClang::StartTagDeclarationDefinition(clang_type);
429709426b3SAleksandr Urakov 
430709426b3SAleksandr Urakov       auto children = udt->findAllChildren();
431709426b3SAleksandr Urakov       if (!children || children->getChildCount() == 0) {
432709426b3SAleksandr Urakov         // PDB does not have symbol of forwarder. We assume we get an udt w/o
433709426b3SAleksandr Urakov         // any fields. Just complete it at this point.
4346e3b0cc2SRaphael Isemann         TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
435709426b3SAleksandr Urakov 
4366e3b0cc2SRaphael Isemann         TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
437709426b3SAleksandr Urakov                                                false);
438709426b3SAleksandr Urakov 
439d4f18f11SAdrian Prantl         type_resolve_state = Type::ResolveState::Full;
440709426b3SAleksandr Urakov       } else {
441709426b3SAleksandr Urakov         // Add the type to the forward declarations. It will help us to avoid
442709426b3SAleksandr Urakov         // an endless recursion in CompleteTypeFromUdt function.
443709426b3SAleksandr Urakov         m_forward_decl_to_uid[record_decl] = type.getSymIndexId();
444709426b3SAleksandr Urakov 
4456e3b0cc2SRaphael Isemann         TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
446709426b3SAleksandr Urakov                                                true);
447709426b3SAleksandr Urakov 
448d4f18f11SAdrian Prantl         type_resolve_state = Type::ResolveState::Forward;
449709426b3SAleksandr Urakov       }
450709426b3SAleksandr Urakov     } else
451d4f18f11SAdrian Prantl       type_resolve_state = Type::ResolveState::Forward;
452709426b3SAleksandr Urakov 
4537d2a74fcSAleksandr Urakov     if (udt->isConstType())
4547d2a74fcSAleksandr Urakov       clang_type = clang_type.AddConstModifier();
4557d2a74fcSAleksandr Urakov 
4567d2a74fcSAleksandr Urakov     if (udt->isVolatileType())
4577d2a74fcSAleksandr Urakov       clang_type = clang_type.AddVolatileModifier();
4587d2a74fcSAleksandr Urakov 
4597d2a74fcSAleksandr Urakov     GetDeclarationForSymbol(type, decl);
4606c13510cSSaleem Abdulrasool     return std::make_shared<lldb_private::Type>(
461709426b3SAleksandr Urakov         type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
462709426b3SAleksandr Urakov         udt->getLength(), nullptr, LLDB_INVALID_UID,
463709426b3SAleksandr Urakov         lldb_private::Type::eEncodingIsUID, decl, clang_type,
464d4f18f11SAdrian Prantl         type_resolve_state);
4657ac1c780SAaron Smith   } break;
4667ac1c780SAaron Smith   case PDB_SymType::Enum: {
4677ac1c780SAaron Smith     auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);
4687ac1c780SAaron Smith     assert(enum_type);
469709426b3SAleksandr Urakov 
470c1e530eeSAleksandr Urakov     std::string name =
471adcd0268SBenjamin Kramer         std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName()));
472709426b3SAleksandr Urakov     auto decl_context = GetDeclContextContainingSymbol(type);
473709426b3SAleksandr Urakov     uint64_t bytes = enum_type->getLength();
474709426b3SAleksandr Urakov 
475709426b3SAleksandr Urakov     // Check if such an enum already exists in the current context
476709426b3SAleksandr Urakov     CompilerType ast_enum = m_ast.GetTypeForIdentifier<clang::EnumDecl>(
477709426b3SAleksandr Urakov         ConstString(name), decl_context);
478709426b3SAleksandr Urakov     if (!ast_enum.IsValid()) {
479ec40f818SAaron Smith       auto underlying_type_up = enum_type->getUnderlyingType();
480ec40f818SAaron Smith       if (!underlying_type_up)
481ec40f818SAaron Smith         return nullptr;
482709426b3SAleksandr Urakov 
48311d0b294SPavel Labath       lldb::Encoding encoding =
484ec40f818SAaron Smith           TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());
485ec40f818SAaron Smith       // FIXME: Type of underlying builtin is always `Int`. We correct it with
486ec40f818SAaron Smith       // the very first enumerator's encoding if any.
487ec40f818SAaron Smith       auto first_child = enum_type->findOneChild<PDBSymbolData>();
488709426b3SAleksandr Urakov       if (first_child)
489ec40f818SAaron Smith         encoding = TranslateEnumEncoding(first_child->getValue().Type);
490709426b3SAleksandr Urakov 
491ec40f818SAaron Smith       CompilerType builtin_type;
492ec40f818SAaron Smith       if (bytes > 0)
493ec40f818SAaron Smith         builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(
494e664b5dcSAaron Smith             m_ast, *underlying_type_up, encoding, bytes * 8);
495ec40f818SAaron Smith       else
496ec40f818SAaron Smith         builtin_type = m_ast.GetBasicType(eBasicTypeInt);
497709426b3SAleksandr Urakov 
498c8316ed2SAaron Smith       // FIXME: PDB does not have information about scoped enumeration (Enum
499c8316ed2SAaron Smith       // Class). Set it false for now.
500ec40f818SAaron Smith       bool isScoped = false;
50142dff790SZachary Turner 
502b738a69aSRaphael Isemann       ast_enum = m_ast.CreateEnumerationType(name, decl_context,
503143d507cSAdrian Prantl                                              OptionalClangModuleID(), decl,
50432672b87SAdrian Prantl                                              builtin_type, isScoped);
505709426b3SAleksandr Urakov 
5066e3b0cc2SRaphael Isemann       auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
507709426b3SAleksandr Urakov       assert(enum_decl);
508709426b3SAleksandr Urakov       m_uid_to_decl[type.getSymIndexId()] = enum_decl;
509709426b3SAleksandr Urakov 
51042dff790SZachary Turner       auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
511ec40f818SAaron Smith       if (enum_values) {
512b9c1b51eSKate Stone         while (auto enum_value = enum_values->getNext()) {
51342dff790SZachary Turner           if (enum_value->getDataKind() != PDB_DataKind::Constant)
51442dff790SZachary Turner             continue;
51542dff790SZachary Turner           AddEnumValue(ast_enum, *enum_value);
51642dff790SZachary Turner         }
517ec40f818SAaron Smith       }
518709426b3SAleksandr Urakov 
5196e3b0cc2SRaphael Isemann       if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum))
5206e3b0cc2SRaphael Isemann         TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum);
521709426b3SAleksandr Urakov     }
522709426b3SAleksandr Urakov 
523709426b3SAleksandr Urakov     if (enum_type->isConstType())
524709426b3SAleksandr Urakov       ast_enum = ast_enum.AddConstModifier();
525709426b3SAleksandr Urakov 
526709426b3SAleksandr Urakov     if (enum_type->isVolatileType())
527709426b3SAleksandr Urakov       ast_enum = ast_enum.AddVolatileModifier();
52842dff790SZachary Turner 
5297abdf2d2SAaron Smith     GetDeclarationForSymbol(type, decl);
5306c13510cSSaleem Abdulrasool     return std::make_shared<lldb_private::Type>(
5316c13510cSSaleem Abdulrasool         type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes,
5326c13510cSSaleem Abdulrasool         nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
533d4f18f11SAdrian Prantl         ast_enum, lldb_private::Type::ResolveState::Full);
5347ac1c780SAaron Smith   } break;
5357ac1c780SAaron Smith   case PDB_SymType::Typedef: {
5367ac1c780SAaron Smith     auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
5377ac1c780SAaron Smith     assert(type_def);
538709426b3SAleksandr Urakov 
539ec28e43eSAugusto Noronha     SymbolFile *symbol_file = m_ast.GetSymbolFile();
540ec28e43eSAugusto Noronha     if (!symbol_file)
541ec28e43eSAugusto Noronha       return nullptr;
542ec28e43eSAugusto Noronha 
5436c13510cSSaleem Abdulrasool     lldb_private::Type *target_type =
544ec28e43eSAugusto Noronha         symbol_file->ResolveTypeUID(type_def->getTypeId());
54586e9434dSAaron Smith     if (!target_type)
54686e9434dSAaron Smith       return nullptr;
547709426b3SAleksandr Urakov 
548c1e530eeSAleksandr Urakov     std::string name =
549adcd0268SBenjamin Kramer         std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName()));
550709426b3SAleksandr Urakov     auto decl_ctx = GetDeclContextContainingSymbol(type);
551709426b3SAleksandr Urakov 
552709426b3SAleksandr Urakov     // Check if such a typedef already exists in the current context
553b9c1b51eSKate Stone     CompilerType ast_typedef =
554709426b3SAleksandr Urakov         m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(ConstString(name),
555709426b3SAleksandr Urakov                                                            decl_ctx);
556709426b3SAleksandr Urakov     if (!ast_typedef.IsValid()) {
557709426b3SAleksandr Urakov       CompilerType target_ast_type = target_type->GetFullCompilerType();
558709426b3SAleksandr Urakov 
559722247c8SRaphael Isemann       ast_typedef = target_ast_type.CreateTypedef(
560722247c8SRaphael Isemann           name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
561a0db2eb0SAaron Smith       if (!ast_typedef)
562a0db2eb0SAaron Smith         return nullptr;
563a0db2eb0SAaron Smith 
5646e3b0cc2SRaphael Isemann       auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef);
565709426b3SAleksandr Urakov       assert(typedef_decl);
566709426b3SAleksandr Urakov       m_uid_to_decl[type.getSymIndexId()] = typedef_decl;
567709426b3SAleksandr Urakov     }
568709426b3SAleksandr Urakov 
569709426b3SAleksandr Urakov     if (type_def->isConstType())
570709426b3SAleksandr Urakov       ast_typedef = ast_typedef.AddConstModifier();
571709426b3SAleksandr Urakov 
572709426b3SAleksandr Urakov     if (type_def->isVolatileType())
573709426b3SAleksandr Urakov       ast_typedef = ast_typedef.AddVolatileModifier();
574709426b3SAleksandr Urakov 
575709426b3SAleksandr Urakov     GetDeclarationForSymbol(type, decl);
576d13777aaSAdrian Prantl     llvm::Optional<uint64_t> size;
577d13777aaSAdrian Prantl     if (type_def->getLength())
578d13777aaSAdrian Prantl       size = type_def->getLength();
5796c13510cSSaleem Abdulrasool     return std::make_shared<lldb_private::Type>(
580b9c1b51eSKate Stone         type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
581d13777aaSAdrian Prantl         size, nullptr, target_type->GetID(),
5826c13510cSSaleem Abdulrasool         lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef,
583d4f18f11SAdrian Prantl         lldb_private::Type::ResolveState::Full);
5847ac1c780SAaron Smith   } break;
5857ac1c780SAaron Smith   case PDB_SymType::Function:
5867ac1c780SAaron Smith   case PDB_SymType::FunctionSig: {
5877ac1c780SAaron Smith     std::string name;
5887ac1c780SAaron Smith     PDBSymbolTypeFunctionSig *func_sig = nullptr;
5897ac1c780SAaron Smith     if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) {
590d5a925f4SAaron Smith       if (pdb_func->isCompilerGenerated())
591d5a925f4SAaron Smith         return nullptr;
592d5a925f4SAaron Smith 
5937ac1c780SAaron Smith       auto sig = pdb_func->getSignature();
5947ac1c780SAaron Smith       if (!sig)
5957ac1c780SAaron Smith         return nullptr;
5967ac1c780SAaron Smith       func_sig = sig.release();
5977ac1c780SAaron Smith       // Function type is named.
598adcd0268SBenjamin Kramer       name = std::string(
599adcd0268SBenjamin Kramer           MSVCUndecoratedNameParser::DropScope(pdb_func->getName()));
6007ac1c780SAaron Smith     } else if (auto pdb_func_sig =
6017ac1c780SAaron Smith                    llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
6027ac1c780SAaron Smith       func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);
6037ac1c780SAaron Smith     } else
6047ac1c780SAaron Smith       llvm_unreachable("Unexpected PDB symbol!");
6057ac1c780SAaron Smith 
60642dff790SZachary Turner     auto arg_enum = func_sig->getArguments();
60742dff790SZachary Turner     uint32_t num_args = arg_enum->getChildCount();
608ec40f818SAaron Smith     std::vector<CompilerType> arg_list;
609ec40f818SAaron Smith 
610ec40f818SAaron Smith     bool is_variadic = func_sig->isCVarArgs();
611ec40f818SAaron Smith     // Drop last variadic argument.
612ec40f818SAaron Smith     if (is_variadic)
613ec40f818SAaron Smith       --num_args;
614de6fad69SKirill Bobyrev     for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) {
615ec40f818SAaron Smith       auto arg = arg_enum->getChildAtIndex(arg_idx);
616ec40f818SAaron Smith       if (!arg)
617ec40f818SAaron Smith         break;
618ec28e43eSAugusto Noronha 
619ec28e43eSAugusto Noronha       SymbolFile *symbol_file = m_ast.GetSymbolFile();
620ec28e43eSAugusto Noronha       if (!symbol_file)
621ec28e43eSAugusto Noronha         return nullptr;
622ec28e43eSAugusto Noronha 
6236c13510cSSaleem Abdulrasool       lldb_private::Type *arg_type =
624ec28e43eSAugusto Noronha           symbol_file->ResolveTypeUID(arg->getSymIndexId());
625b9c1b51eSKate Stone       // If there's some error looking up one of the dependent types of this
626b9c1b51eSKate Stone       // function signature, bail.
62742dff790SZachary Turner       if (!arg_type)
62842dff790SZachary Turner         return nullptr;
62942dff790SZachary Turner       CompilerType arg_ast_type = arg_type->GetFullCompilerType();
63042dff790SZachary Turner       arg_list.push_back(arg_ast_type);
63142dff790SZachary Turner     }
632ec40f818SAaron Smith     lldbassert(arg_list.size() <= num_args);
633ec40f818SAaron Smith 
63442dff790SZachary Turner     auto pdb_return_type = func_sig->getReturnType();
635ec28e43eSAugusto Noronha     SymbolFile *symbol_file = m_ast.GetSymbolFile();
636ec28e43eSAugusto Noronha     if (!symbol_file)
637ec28e43eSAugusto Noronha       return nullptr;
638ec28e43eSAugusto Noronha 
6396c13510cSSaleem Abdulrasool     lldb_private::Type *return_type =
640ec28e43eSAugusto Noronha         symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId());
641b9c1b51eSKate Stone     // If there's some error looking up one of the dependent types of this
642b9c1b51eSKate Stone     // function signature, bail.
64342dff790SZachary Turner     if (!return_type)
64442dff790SZachary Turner       return nullptr;
64542dff790SZachary Turner     CompilerType return_ast_type = return_type->GetFullCompilerType();
64642dff790SZachary Turner     uint32_t type_quals = 0;
64742dff790SZachary Turner     if (func_sig->isConstType())
64842dff790SZachary Turner       type_quals |= clang::Qualifiers::Const;
64942dff790SZachary Turner     if (func_sig->isVolatileType())
65042dff790SZachary Turner       type_quals |= clang::Qualifiers::Volatile;
651bc4707ccSAleksandr Urakov     auto cc = TranslateCallingConvention(func_sig->getCallingConvention());
652c8316ed2SAaron Smith     CompilerType func_sig_ast_type =
653c8316ed2SAaron Smith         m_ast.CreateFunctionType(return_ast_type, arg_list.data(),
654bc4707ccSAleksandr Urakov                                  arg_list.size(), is_variadic, type_quals, cc);
65542dff790SZachary Turner 
6567ac1c780SAaron Smith     GetDeclarationForSymbol(type, decl);
6576c13510cSSaleem Abdulrasool     return std::make_shared<lldb_private::Type>(
658d13777aaSAdrian Prantl         type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
659d13777aaSAdrian Prantl         llvm::None, nullptr, LLDB_INVALID_UID,
660d13777aaSAdrian Prantl         lldb_private::Type::eEncodingIsUID, decl, func_sig_ast_type,
661d4f18f11SAdrian Prantl         lldb_private::Type::ResolveState::Full);
6627ac1c780SAaron Smith   } break;
6637ac1c780SAaron Smith   case PDB_SymType::ArrayType: {
6647ac1c780SAaron Smith     auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
6657ac1c780SAaron Smith     assert(array_type);
66642dff790SZachary Turner     uint32_t num_elements = array_type->getCount();
667a0db2eb0SAaron Smith     uint32_t element_uid = array_type->getElementTypeId();
668d55102a1SAdrian Prantl     llvm::Optional<uint64_t> bytes;
669d55102a1SAdrian Prantl     if (uint64_t size = array_type->getLength())
670d55102a1SAdrian Prantl       bytes = size;
67142dff790SZachary Turner 
672ec28e43eSAugusto Noronha     SymbolFile *symbol_file = m_ast.GetSymbolFile();
673ec28e43eSAugusto Noronha     if (!symbol_file)
674ec28e43eSAugusto Noronha       return nullptr;
675ec28e43eSAugusto Noronha 
676a0db2eb0SAaron Smith     // If array rank > 0, PDB gives the element type at N=0. So element type
677a0db2eb0SAaron Smith     // will parsed in the order N=0, N=1,..., N=rank sequentially.
678ec28e43eSAugusto Noronha     lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid);
67986e9434dSAaron Smith     if (!element_type)
68086e9434dSAaron Smith       return nullptr;
681a0db2eb0SAaron Smith 
682a0db2eb0SAaron Smith     CompilerType element_ast_type = element_type->GetForwardCompilerType();
683a0db2eb0SAaron Smith     // If element type is UDT, it needs to be complete.
6846e3b0cc2SRaphael Isemann     if (TypeSystemClang::IsCXXClassType(element_ast_type) &&
685a6682a41SJonas Devlieghere         !element_ast_type.GetCompleteType()) {
6866e3b0cc2SRaphael Isemann       if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) {
6876e3b0cc2SRaphael Isemann         TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type);
688a0db2eb0SAaron Smith       } else {
689a0db2eb0SAaron Smith         // We are not able to start defintion.
690a0db2eb0SAaron Smith         return nullptr;
691a0db2eb0SAaron Smith       }
692a0db2eb0SAaron Smith     }
693c8316ed2SAaron Smith     CompilerType array_ast_type = m_ast.CreateArrayType(
694c8316ed2SAaron Smith         element_ast_type, num_elements, /*is_gnu_vector*/ false);
695a0db2eb0SAaron Smith     TypeSP type_sp = std::make_shared<lldb_private::Type>(
696b9c1b51eSKate Stone         array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
6976c13510cSSaleem Abdulrasool         bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
698d4f18f11SAdrian Prantl         decl, array_ast_type, lldb_private::Type::ResolveState::Full);
699a0db2eb0SAaron Smith     type_sp->SetEncodingType(element_type);
700a0db2eb0SAaron Smith     return type_sp;
7017ac1c780SAaron Smith   } break;
7027ac1c780SAaron Smith   case PDB_SymType::BuiltinType: {
7037ac1c780SAaron Smith     auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);
7047ac1c780SAaron Smith     assert(builtin_type);
705ec40f818SAaron Smith     PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType();
706ec40f818SAaron Smith     if (builtin_kind == PDB_BuiltinType::None)
707ec40f818SAaron Smith       return nullptr;
708ec40f818SAaron Smith 
709d55102a1SAdrian Prantl     llvm::Optional<uint64_t> bytes;
710d55102a1SAdrian Prantl     if (uint64_t size = builtin_type->getLength())
711d55102a1SAdrian Prantl       bytes = size;
712ec40f818SAaron Smith     Encoding encoding = TranslateBuiltinEncoding(builtin_kind);
713ec40f818SAaron Smith     CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(
714*aa88161bSKazu Hirata         m_ast, *builtin_type, encoding, bytes.value_or(0) * 8);
715ec40f818SAaron Smith 
716a0db2eb0SAaron Smith     if (builtin_type->isConstType())
717ec40f818SAaron Smith       builtin_ast_type = builtin_ast_type.AddConstModifier();
718a0db2eb0SAaron Smith 
719a0db2eb0SAaron Smith     if (builtin_type->isVolatileType())
720ec40f818SAaron Smith       builtin_ast_type = builtin_ast_type.AddVolatileModifier();
721a0db2eb0SAaron Smith 
722e664b5dcSAaron Smith     auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type);
723ec40f818SAaron Smith 
724ec40f818SAaron Smith     return std::make_shared<lldb_private::Type>(
725c8316ed2SAaron Smith         builtin_type->getSymIndexId(), m_ast.GetSymbolFile(), type_name, bytes,
726c8316ed2SAaron Smith         nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
727d4f18f11SAdrian Prantl         builtin_ast_type, lldb_private::Type::ResolveState::Full);
7287ac1c780SAaron Smith   } break;
7297ac1c780SAaron Smith   case PDB_SymType::PointerType: {
7307ac1c780SAaron Smith     auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
7317ac1c780SAaron Smith     assert(pointer_type);
732ec28e43eSAugusto Noronha 
733ec28e43eSAugusto Noronha     SymbolFile *symbol_file = m_ast.GetSymbolFile();
734ec28e43eSAugusto Noronha     if (!symbol_file)
735ec28e43eSAugusto Noronha       return nullptr;
736ec28e43eSAugusto Noronha 
737ec28e43eSAugusto Noronha     Type *pointee_type = symbol_file->ResolveTypeUID(
738ec40f818SAaron Smith         pointer_type->getPointeeType()->getSymIndexId());
739ec40f818SAaron Smith     if (!pointee_type)
740ec40f818SAaron Smith       return nullptr;
741ec40f818SAaron Smith 
7427d2a74fcSAleksandr Urakov     if (pointer_type->isPointerToDataMember() ||
7437d2a74fcSAleksandr Urakov         pointer_type->isPointerToMemberFunction()) {
7447d2a74fcSAleksandr Urakov       auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();
745ec28e43eSAugusto Noronha       auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid);
7467d2a74fcSAleksandr Urakov       assert(class_parent_type);
7477d2a74fcSAleksandr Urakov 
7487d2a74fcSAleksandr Urakov       CompilerType pointer_ast_type;
7496e3b0cc2SRaphael Isemann       pointer_ast_type = TypeSystemClang::CreateMemberPointerType(
7507d2a74fcSAleksandr Urakov           class_parent_type->GetLayoutCompilerType(),
7517d2a74fcSAleksandr Urakov           pointee_type->GetForwardCompilerType());
7527d2a74fcSAleksandr Urakov       assert(pointer_ast_type);
7537d2a74fcSAleksandr Urakov 
7547d2a74fcSAleksandr Urakov       return std::make_shared<lldb_private::Type>(
7557d2a74fcSAleksandr Urakov           pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
7567d2a74fcSAleksandr Urakov           pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
7577d2a74fcSAleksandr Urakov           lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
758d4f18f11SAdrian Prantl           lldb_private::Type::ResolveState::Forward);
7597d2a74fcSAleksandr Urakov     }
7607d2a74fcSAleksandr Urakov 
761ec40f818SAaron Smith     CompilerType pointer_ast_type;
762a0db2eb0SAaron Smith     pointer_ast_type = pointee_type->GetFullCompilerType();
763a0db2eb0SAaron Smith     if (pointer_type->isReference())
764a0db2eb0SAaron Smith       pointer_ast_type = pointer_ast_type.GetLValueReferenceType();
765a3a8cc80SAaron Smith     else if (pointer_type->isRValueReference())
766a0db2eb0SAaron Smith       pointer_ast_type = pointer_ast_type.GetRValueReferenceType();
767a0db2eb0SAaron Smith     else
768a0db2eb0SAaron Smith       pointer_ast_type = pointer_ast_type.GetPointerType();
769a0db2eb0SAaron Smith 
770a0db2eb0SAaron Smith     if (pointer_type->isConstType())
771a0db2eb0SAaron Smith       pointer_ast_type = pointer_ast_type.AddConstModifier();
772a0db2eb0SAaron Smith 
773a0db2eb0SAaron Smith     if (pointer_type->isVolatileType())
774a0db2eb0SAaron Smith       pointer_ast_type = pointer_ast_type.AddVolatileModifier();
775a0db2eb0SAaron Smith 
776a3a8cc80SAaron Smith     if (pointer_type->isRestrictedType())
777a0db2eb0SAaron Smith       pointer_ast_type = pointer_ast_type.AddRestrictModifier();
778ec40f818SAaron Smith 
779ec40f818SAaron Smith     return std::make_shared<lldb_private::Type>(
780ec40f818SAaron Smith         pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
781ec40f818SAaron Smith         pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
782a0db2eb0SAaron Smith         lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
783d4f18f11SAdrian Prantl         lldb_private::Type::ResolveState::Full);
7847ac1c780SAaron Smith   } break;
785c8316ed2SAaron Smith   default:
786c8316ed2SAaron Smith     break;
78742dff790SZachary Turner   }
78842dff790SZachary Turner   return nullptr;
78942dff790SZachary Turner }
79042dff790SZachary Turner 
CompleteTypeFromPDB(lldb_private::CompilerType & compiler_type)7917d2a74fcSAleksandr Urakov bool PDBASTParser::CompleteTypeFromPDB(
7927d2a74fcSAleksandr Urakov     lldb_private::CompilerType &compiler_type) {
7937d2a74fcSAleksandr Urakov   if (GetClangASTImporter().CanImport(compiler_type))
7947d2a74fcSAleksandr Urakov     return GetClangASTImporter().CompleteType(compiler_type);
7957d2a74fcSAleksandr Urakov 
7967d2a74fcSAleksandr Urakov   // Remove the type from the forward declarations to avoid
7977d2a74fcSAleksandr Urakov   // an endless recursion for types like a linked list.
798709426b3SAleksandr Urakov   clang::CXXRecordDecl *record_decl =
799709426b3SAleksandr Urakov       m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
800709426b3SAleksandr Urakov   auto uid_it = m_forward_decl_to_uid.find(record_decl);
801709426b3SAleksandr Urakov   if (uid_it == m_forward_decl_to_uid.end())
8027d2a74fcSAleksandr Urakov     return true;
8037d2a74fcSAleksandr Urakov 
8047b81192dSJeffrey Tan   auto symbol_file = static_cast<SymbolFilePDB *>(
8057b81192dSJeffrey Tan       m_ast.GetSymbolFile()->GetBackingSymbolFile());
8067d2a74fcSAleksandr Urakov   if (!symbol_file)
8077d2a74fcSAleksandr Urakov     return false;
8087d2a74fcSAleksandr Urakov 
8097d2a74fcSAleksandr Urakov   std::unique_ptr<PDBSymbol> symbol =
8107d2a74fcSAleksandr Urakov       symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond());
8117d2a74fcSAleksandr Urakov   if (!symbol)
8127d2a74fcSAleksandr Urakov     return false;
8137d2a74fcSAleksandr Urakov 
814709426b3SAleksandr Urakov   m_forward_decl_to_uid.erase(uid_it);
8157d2a74fcSAleksandr Urakov 
8166e3b0cc2SRaphael Isemann   TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
8177d2a74fcSAleksandr Urakov                                          false);
8187d2a74fcSAleksandr Urakov 
8197d2a74fcSAleksandr Urakov   switch (symbol->getSymTag()) {
8207d2a74fcSAleksandr Urakov   case PDB_SymType::UDT: {
8217d2a74fcSAleksandr Urakov     auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get());
8227d2a74fcSAleksandr Urakov     if (!udt)
8237d2a74fcSAleksandr Urakov       return false;
8247d2a74fcSAleksandr Urakov 
8257d2a74fcSAleksandr Urakov     return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt);
8267d2a74fcSAleksandr Urakov   }
8277d2a74fcSAleksandr Urakov   default:
8287d2a74fcSAleksandr Urakov     llvm_unreachable("not a forward clang type decl!");
8297d2a74fcSAleksandr Urakov   }
8307d2a74fcSAleksandr Urakov }
8317d2a74fcSAleksandr Urakov 
832709426b3SAleksandr Urakov clang::Decl *
GetDeclForSymbol(const llvm::pdb::PDBSymbol & symbol)833709426b3SAleksandr Urakov PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
834c1e530eeSAleksandr Urakov   uint32_t sym_id = symbol.getSymIndexId();
835c1e530eeSAleksandr Urakov   auto it = m_uid_to_decl.find(sym_id);
836709426b3SAleksandr Urakov   if (it != m_uid_to_decl.end())
837709426b3SAleksandr Urakov     return it->second;
838709426b3SAleksandr Urakov 
8397b81192dSJeffrey Tan   auto symbol_file = static_cast<SymbolFilePDB *>(
8407b81192dSJeffrey Tan       m_ast.GetSymbolFile()->GetBackingSymbolFile());
841709426b3SAleksandr Urakov   if (!symbol_file)
842709426b3SAleksandr Urakov     return nullptr;
843709426b3SAleksandr Urakov 
844709426b3SAleksandr Urakov   // First of all, check if the symbol is a member of a class. Resolve the full
845709426b3SAleksandr Urakov   // class type and return the declaration from the cache if so.
846709426b3SAleksandr Urakov   auto tag = symbol.getSymTag();
847709426b3SAleksandr Urakov   if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) {
848709426b3SAleksandr Urakov     const IPDBSession &session = symbol.getSession();
849709426b3SAleksandr Urakov     const IPDBRawSymbol &raw = symbol.getRawSymbol();
850709426b3SAleksandr Urakov 
851709426b3SAleksandr Urakov     auto class_parent_id = raw.getClassParentId();
852c1e530eeSAleksandr Urakov     if (std::unique_ptr<PDBSymbol> class_parent =
853c1e530eeSAleksandr Urakov             session.getSymbolById(class_parent_id)) {
854709426b3SAleksandr Urakov       auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id);
855709426b3SAleksandr Urakov       if (!class_parent_type)
856709426b3SAleksandr Urakov         return nullptr;
857709426b3SAleksandr Urakov 
858c1e530eeSAleksandr Urakov       CompilerType class_parent_ct = class_parent_type->GetFullCompilerType();
859709426b3SAleksandr Urakov 
860c1e530eeSAleksandr Urakov       // Look a declaration up in the cache after completing the class
861c1e530eeSAleksandr Urakov       clang::Decl *decl = m_uid_to_decl.lookup(sym_id);
862c1e530eeSAleksandr Urakov       if (decl)
863c1e530eeSAleksandr Urakov         return decl;
864c1e530eeSAleksandr Urakov 
865c1e530eeSAleksandr Urakov       // A declaration was not found in the cache. It means that the symbol
866c1e530eeSAleksandr Urakov       // has the class parent, but the class doesn't have the symbol in its
867c1e530eeSAleksandr Urakov       // children list.
868c1e530eeSAleksandr Urakov       if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) {
869c1e530eeSAleksandr Urakov         // Try to find a class child method with the same RVA and use its
870c1e530eeSAleksandr Urakov         // declaration if found.
871c1e530eeSAleksandr Urakov         if (uint32_t rva = func->getRelativeVirtualAddress()) {
872c1e530eeSAleksandr Urakov           if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>>
873c1e530eeSAleksandr Urakov                   methods_enum =
874c1e530eeSAleksandr Urakov                       class_parent->findAllChildren<PDBSymbolFunc>()) {
875c1e530eeSAleksandr Urakov             while (std::unique_ptr<PDBSymbolFunc> method =
876c1e530eeSAleksandr Urakov                        methods_enum->getNext()) {
877c1e530eeSAleksandr Urakov               if (method->getRelativeVirtualAddress() == rva) {
878c1e530eeSAleksandr Urakov                 decl = m_uid_to_decl.lookup(method->getSymIndexId());
879c1e530eeSAleksandr Urakov                 if (decl)
880c1e530eeSAleksandr Urakov                   break;
881c1e530eeSAleksandr Urakov               }
882c1e530eeSAleksandr Urakov             }
883c1e530eeSAleksandr Urakov           }
884c1e530eeSAleksandr Urakov         }
885c1e530eeSAleksandr Urakov 
886c1e530eeSAleksandr Urakov         // If no class methods with the same RVA were found, then create a new
887c1e530eeSAleksandr Urakov         // method. It is possible for template methods.
888c1e530eeSAleksandr Urakov         if (!decl)
889c1e530eeSAleksandr Urakov           decl = AddRecordMethod(*symbol_file, class_parent_ct, *func);
890c1e530eeSAleksandr Urakov       }
891c1e530eeSAleksandr Urakov 
892c1e530eeSAleksandr Urakov       if (decl)
893c1e530eeSAleksandr Urakov         m_uid_to_decl[sym_id] = decl;
894c1e530eeSAleksandr Urakov 
895c1e530eeSAleksandr Urakov       return decl;
896709426b3SAleksandr Urakov     }
897709426b3SAleksandr Urakov   }
898709426b3SAleksandr Urakov 
899709426b3SAleksandr Urakov   // If we are here, then the symbol is not belonging to a class and is not
900709426b3SAleksandr Urakov   // contained in the cache. So create a declaration for it.
901709426b3SAleksandr Urakov   switch (symbol.getSymTag()) {
902709426b3SAleksandr Urakov   case PDB_SymType::Data: {
903709426b3SAleksandr Urakov     auto data = llvm::dyn_cast<PDBSymbolData>(&symbol);
904709426b3SAleksandr Urakov     assert(data);
905709426b3SAleksandr Urakov 
906709426b3SAleksandr Urakov     auto decl_context = GetDeclContextContainingSymbol(symbol);
907709426b3SAleksandr Urakov     assert(decl_context);
908709426b3SAleksandr Urakov 
909709426b3SAleksandr Urakov     // May be the current context is a class really, but we haven't found
910709426b3SAleksandr Urakov     // any class parent. This happens e.g. in the case of class static
911709426b3SAleksandr Urakov     // variables - they has two symbols, one is a child of the class when
912709426b3SAleksandr Urakov     // another is a child of the exe. So always complete the parent and use
913709426b3SAleksandr Urakov     // an existing declaration if possible.
914709426b3SAleksandr Urakov     if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context))
915709426b3SAleksandr Urakov       m_ast.GetCompleteDecl(parent_decl);
916709426b3SAleksandr Urakov 
917adcd0268SBenjamin Kramer     std::string name =
918adcd0268SBenjamin Kramer         std::string(MSVCUndecoratedNameParser::DropScope(data->getName()));
919709426b3SAleksandr Urakov 
920709426b3SAleksandr Urakov     // Check if the current context already contains the symbol with the name.
921709426b3SAleksandr Urakov     clang::Decl *decl =
922f9f49d35SRaphael Isemann         GetDeclFromContextByName(m_ast.getASTContext(), *decl_context, name);
923709426b3SAleksandr Urakov     if (!decl) {
924709426b3SAleksandr Urakov       auto type = symbol_file->ResolveTypeUID(data->getTypeId());
925709426b3SAleksandr Urakov       if (!type)
926709426b3SAleksandr Urakov         return nullptr;
927709426b3SAleksandr Urakov 
928709426b3SAleksandr Urakov       decl = m_ast.CreateVariableDeclaration(
929143d507cSAdrian Prantl           decl_context, OptionalClangModuleID(), name.c_str(),
930709426b3SAleksandr Urakov           ClangUtil::GetQualType(type->GetLayoutCompilerType()));
931709426b3SAleksandr Urakov     }
932709426b3SAleksandr Urakov 
933c1e530eeSAleksandr Urakov     m_uid_to_decl[sym_id] = decl;
934709426b3SAleksandr Urakov 
935709426b3SAleksandr Urakov     return decl;
936709426b3SAleksandr Urakov   }
937709426b3SAleksandr Urakov   case PDB_SymType::Function: {
938709426b3SAleksandr Urakov     auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol);
939709426b3SAleksandr Urakov     assert(func);
940709426b3SAleksandr Urakov 
941709426b3SAleksandr Urakov     auto decl_context = GetDeclContextContainingSymbol(symbol);
942709426b3SAleksandr Urakov     assert(decl_context);
943709426b3SAleksandr Urakov 
944adcd0268SBenjamin Kramer     std::string name =
945adcd0268SBenjamin Kramer         std::string(MSVCUndecoratedNameParser::DropScope(func->getName()));
946709426b3SAleksandr Urakov 
947c1e530eeSAleksandr Urakov     Type *type = symbol_file->ResolveTypeUID(sym_id);
948709426b3SAleksandr Urakov     if (!type)
949709426b3SAleksandr Urakov       return nullptr;
950709426b3SAleksandr Urakov 
951709426b3SAleksandr Urakov     auto storage = func->isStatic() ? clang::StorageClass::SC_Static
952709426b3SAleksandr Urakov                                     : clang::StorageClass::SC_None;
953709426b3SAleksandr Urakov 
954709426b3SAleksandr Urakov     auto decl = m_ast.CreateFunctionDeclaration(
955cfb773c6SRaphael Isemann         decl_context, OptionalClangModuleID(), name,
956143d507cSAdrian Prantl         type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
957709426b3SAleksandr Urakov 
958a5235af9SAleksandr Urakov     std::vector<clang::ParmVarDecl *> params;
959a5235af9SAleksandr Urakov     if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
960a5235af9SAleksandr Urakov       if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>>
961a5235af9SAleksandr Urakov               arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) {
962a5235af9SAleksandr Urakov         while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg =
963a5235af9SAleksandr Urakov                    arg_enum->getNext()) {
964a5235af9SAleksandr Urakov           Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId());
965a5235af9SAleksandr Urakov           if (!arg_type)
966a5235af9SAleksandr Urakov             continue;
967a5235af9SAleksandr Urakov 
968a5235af9SAleksandr Urakov           clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
969143d507cSAdrian Prantl               decl, OptionalClangModuleID(), nullptr,
970143d507cSAdrian Prantl               arg_type->GetForwardCompilerType(), clang::SC_None, true);
971a5235af9SAleksandr Urakov           if (param)
972a5235af9SAleksandr Urakov             params.push_back(param);
973a5235af9SAleksandr Urakov         }
974a5235af9SAleksandr Urakov       }
975a5235af9SAleksandr Urakov     }
976a5235af9SAleksandr Urakov     if (params.size())
9777177c595SRaphael Isemann       m_ast.SetFunctionParameters(decl, params);
978a5235af9SAleksandr Urakov 
979c1e530eeSAleksandr Urakov     m_uid_to_decl[sym_id] = decl;
980709426b3SAleksandr Urakov 
981709426b3SAleksandr Urakov     return decl;
982709426b3SAleksandr Urakov   }
983709426b3SAleksandr Urakov   default: {
984709426b3SAleksandr Urakov     // It's not a variable and not a function, check if it's a type
985c1e530eeSAleksandr Urakov     Type *type = symbol_file->ResolveTypeUID(sym_id);
986709426b3SAleksandr Urakov     if (!type)
987709426b3SAleksandr Urakov       return nullptr;
988709426b3SAleksandr Urakov 
989c1e530eeSAleksandr Urakov     return m_uid_to_decl.lookup(sym_id);
990709426b3SAleksandr Urakov   }
991709426b3SAleksandr Urakov   }
992709426b3SAleksandr Urakov }
993709426b3SAleksandr Urakov 
994709426b3SAleksandr Urakov clang::DeclContext *
GetDeclContextForSymbol(const llvm::pdb::PDBSymbol & symbol)995709426b3SAleksandr Urakov PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) {
996709426b3SAleksandr Urakov   if (symbol.getSymTag() == PDB_SymType::Function) {
997709426b3SAleksandr Urakov     clang::DeclContext *result =
998709426b3SAleksandr Urakov         llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol));
999709426b3SAleksandr Urakov 
1000709426b3SAleksandr Urakov     if (result)
1001709426b3SAleksandr Urakov       m_decl_context_to_uid[result] = symbol.getSymIndexId();
1002709426b3SAleksandr Urakov 
1003709426b3SAleksandr Urakov     return result;
1004709426b3SAleksandr Urakov   }
1005709426b3SAleksandr Urakov 
10067b81192dSJeffrey Tan   auto symbol_file = static_cast<SymbolFilePDB *>(
10077b81192dSJeffrey Tan       m_ast.GetSymbolFile()->GetBackingSymbolFile());
1008709426b3SAleksandr Urakov   if (!symbol_file)
1009709426b3SAleksandr Urakov     return nullptr;
1010709426b3SAleksandr Urakov 
1011709426b3SAleksandr Urakov   auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId());
1012709426b3SAleksandr Urakov   if (!type)
1013709426b3SAleksandr Urakov     return nullptr;
1014709426b3SAleksandr Urakov 
1015709426b3SAleksandr Urakov   clang::DeclContext *result =
1016709426b3SAleksandr Urakov       m_ast.GetDeclContextForType(type->GetForwardCompilerType());
1017709426b3SAleksandr Urakov 
1018709426b3SAleksandr Urakov   if (result)
1019709426b3SAleksandr Urakov     m_decl_context_to_uid[result] = symbol.getSymIndexId();
1020709426b3SAleksandr Urakov 
1021709426b3SAleksandr Urakov   return result;
1022709426b3SAleksandr Urakov }
1023709426b3SAleksandr Urakov 
GetDeclContextContainingSymbol(const llvm::pdb::PDBSymbol & symbol)1024709426b3SAleksandr Urakov clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
1025709426b3SAleksandr Urakov     const llvm::pdb::PDBSymbol &symbol) {
1026709426b3SAleksandr Urakov   auto parent = GetClassOrFunctionParent(symbol);
1027709426b3SAleksandr Urakov   while (parent) {
1028709426b3SAleksandr Urakov     if (auto parent_context = GetDeclContextForSymbol(*parent))
1029709426b3SAleksandr Urakov       return parent_context;
1030709426b3SAleksandr Urakov 
1031709426b3SAleksandr Urakov     parent = GetClassOrFunctionParent(*parent);
1032709426b3SAleksandr Urakov   }
1033709426b3SAleksandr Urakov 
1034709426b3SAleksandr Urakov   // We can't find any class or function parent of the symbol. So analyze
1035709426b3SAleksandr Urakov   // the full symbol name. The symbol may be belonging to a namespace
1036709426b3SAleksandr Urakov   // or function (or even to a class if it's e.g. a static variable symbol).
1037709426b3SAleksandr Urakov 
1038709426b3SAleksandr Urakov   // TODO: Make clang to emit full names for variables in namespaces
1039709426b3SAleksandr Urakov   // (as MSVC does)
1040709426b3SAleksandr Urakov 
1041c1e530eeSAleksandr Urakov   std::string name(symbol.getRawSymbol().getName());
1042c1e530eeSAleksandr Urakov   MSVCUndecoratedNameParser parser(name);
1043c1e530eeSAleksandr Urakov   llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
1044c1e530eeSAleksandr Urakov   if (specs.empty())
1045c1e530eeSAleksandr Urakov     return m_ast.GetTranslationUnitDecl();
1046709426b3SAleksandr Urakov 
10477b81192dSJeffrey Tan   auto symbol_file = static_cast<SymbolFilePDB *>(
10487b81192dSJeffrey Tan       m_ast.GetSymbolFile()->GetBackingSymbolFile());
1049709426b3SAleksandr Urakov   if (!symbol_file)
1050709426b3SAleksandr Urakov     return m_ast.GetTranslationUnitDecl();
1051709426b3SAleksandr Urakov 
1052709426b3SAleksandr Urakov   auto global = symbol_file->GetPDBSession().getGlobalScope();
1053709426b3SAleksandr Urakov   if (!global)
1054709426b3SAleksandr Urakov     return m_ast.GetTranslationUnitDecl();
1055709426b3SAleksandr Urakov 
1056c1e530eeSAleksandr Urakov   bool has_type_or_function_parent = false;
10574911023fSZachary Turner   clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl();
1058c1e530eeSAleksandr Urakov   for (std::size_t i = 0; i < specs.size() - 1; i++) {
1059c1e530eeSAleksandr Urakov     // Check if there is a function or a type with the current context's name.
1060c1e530eeSAleksandr Urakov     if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren(
1061c1e530eeSAleksandr Urakov             PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) {
1062c1e530eeSAleksandr Urakov       while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child =
1063c1e530eeSAleksandr Urakov                  children_enum->getNext()) {
1064c1e530eeSAleksandr Urakov         if (clang::DeclContext *child_context =
1065c1e530eeSAleksandr Urakov                 GetDeclContextForSymbol(*child)) {
1066c1e530eeSAleksandr Urakov           // Note that `GetDeclContextForSymbol' retrieves
1067c1e530eeSAleksandr Urakov           // a declaration context for functions and types only,
1068c1e530eeSAleksandr Urakov           // so if we are here then `child_context' is guaranteed
1069c1e530eeSAleksandr Urakov           // a function or a type declaration context.
1070c1e530eeSAleksandr Urakov           has_type_or_function_parent = true;
1071c1e530eeSAleksandr Urakov           curr_context = child_context;
1072c1e530eeSAleksandr Urakov         }
1073c1e530eeSAleksandr Urakov       }
1074c1e530eeSAleksandr Urakov     }
1075709426b3SAleksandr Urakov 
1076c1e530eeSAleksandr Urakov     // If there were no functions or types above then retrieve a namespace with
1077c1e530eeSAleksandr Urakov     // the current context's name. There can be no namespaces inside a function
1078c1e530eeSAleksandr Urakov     // or a type. We check it to avoid fake namespaces such as `__l2':
1079c1e530eeSAleksandr Urakov     // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct'
1080c1e530eeSAleksandr Urakov     if (!has_type_or_function_parent) {
1081adcd0268SBenjamin Kramer       std::string namespace_name = std::string(specs[i].GetBaseName());
1082c1e530eeSAleksandr Urakov       const char *namespace_name_c_str =
1083c1e530eeSAleksandr Urakov           IsAnonymousNamespaceName(namespace_name) ? nullptr
1084c1e530eeSAleksandr Urakov                                                    : namespace_name.data();
1085c1e530eeSAleksandr Urakov       clang::NamespaceDecl *namespace_decl =
1086143d507cSAdrian Prantl           m_ast.GetUniqueNamespaceDeclaration(
1087143d507cSAdrian Prantl               namespace_name_c_str, curr_context, OptionalClangModuleID());
1088709426b3SAleksandr Urakov 
1089709426b3SAleksandr Urakov       m_parent_to_namespaces[curr_context].insert(namespace_decl);
1090a5235af9SAleksandr Urakov       m_namespaces.insert(namespace_decl);
1091709426b3SAleksandr Urakov 
1092709426b3SAleksandr Urakov       curr_context = namespace_decl;
1093c1e530eeSAleksandr Urakov     }
1094709426b3SAleksandr Urakov   }
1095709426b3SAleksandr Urakov 
1096709426b3SAleksandr Urakov   return curr_context;
1097709426b3SAleksandr Urakov }
1098709426b3SAleksandr Urakov 
ParseDeclsForDeclContext(const clang::DeclContext * decl_context)1099709426b3SAleksandr Urakov void PDBASTParser::ParseDeclsForDeclContext(
1100709426b3SAleksandr Urakov     const clang::DeclContext *decl_context) {
11017b81192dSJeffrey Tan   auto symbol_file = static_cast<SymbolFilePDB *>(
11027b81192dSJeffrey Tan       m_ast.GetSymbolFile()->GetBackingSymbolFile());
1103709426b3SAleksandr Urakov   if (!symbol_file)
1104709426b3SAleksandr Urakov     return;
1105709426b3SAleksandr Urakov 
1106709426b3SAleksandr Urakov   IPDBSession &session = symbol_file->GetPDBSession();
1107709426b3SAleksandr Urakov   auto symbol_up =
1108709426b3SAleksandr Urakov       session.getSymbolById(m_decl_context_to_uid.lookup(decl_context));
1109709426b3SAleksandr Urakov   auto global_up = session.getGlobalScope();
1110709426b3SAleksandr Urakov 
1111709426b3SAleksandr Urakov   PDBSymbol *symbol;
1112709426b3SAleksandr Urakov   if (symbol_up)
1113709426b3SAleksandr Urakov     symbol = symbol_up.get();
1114709426b3SAleksandr Urakov   else if (global_up)
1115709426b3SAleksandr Urakov     symbol = global_up.get();
1116709426b3SAleksandr Urakov   else
1117709426b3SAleksandr Urakov     return;
1118709426b3SAleksandr Urakov 
1119709426b3SAleksandr Urakov   if (auto children = symbol->findAllChildren())
1120709426b3SAleksandr Urakov     while (auto child = children->getNext())
1121709426b3SAleksandr Urakov       GetDeclForSymbol(*child);
1122709426b3SAleksandr Urakov }
1123709426b3SAleksandr Urakov 
1124709426b3SAleksandr Urakov clang::NamespaceDecl *
FindNamespaceDecl(const clang::DeclContext * parent,llvm::StringRef name)1125709426b3SAleksandr Urakov PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent,
1126709426b3SAleksandr Urakov                                 llvm::StringRef name) {
1127a5235af9SAleksandr Urakov   NamespacesSet *set;
1128a5235af9SAleksandr Urakov   if (parent) {
1129a5235af9SAleksandr Urakov     auto pit = m_parent_to_namespaces.find(parent);
1130a5235af9SAleksandr Urakov     if (pit == m_parent_to_namespaces.end())
1131709426b3SAleksandr Urakov       return nullptr;
1132709426b3SAleksandr Urakov 
1133a5235af9SAleksandr Urakov     set = &pit->second;
1134a5235af9SAleksandr Urakov   } else {
1135a5235af9SAleksandr Urakov     set = &m_namespaces;
1136a5235af9SAleksandr Urakov   }
1137a5235af9SAleksandr Urakov   assert(set);
1138a5235af9SAleksandr Urakov 
1139a5235af9SAleksandr Urakov   for (clang::NamespaceDecl *namespace_decl : *set)
1140709426b3SAleksandr Urakov     if (namespace_decl->getName().equals(name))
1141709426b3SAleksandr Urakov       return namespace_decl;
1142709426b3SAleksandr Urakov 
1143a5235af9SAleksandr Urakov   for (clang::NamespaceDecl *namespace_decl : *set)
1144709426b3SAleksandr Urakov     if (namespace_decl->isAnonymousNamespace())
1145709426b3SAleksandr Urakov       return FindNamespaceDecl(namespace_decl, name);
1146709426b3SAleksandr Urakov 
1147709426b3SAleksandr Urakov   return nullptr;
1148709426b3SAleksandr Urakov }
1149709426b3SAleksandr Urakov 
AddEnumValue(CompilerType enum_type,const PDBSymbolData & enum_value)1150b9c1b51eSKate Stone bool PDBASTParser::AddEnumValue(CompilerType enum_type,
1151709426b3SAleksandr Urakov                                 const PDBSymbolData &enum_value) {
115242dff790SZachary Turner   Declaration decl;
115342dff790SZachary Turner   Variant v = enum_value.getValue();
1154adcd0268SBenjamin Kramer   std::string name =
1155adcd0268SBenjamin Kramer       std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName()));
115642dff790SZachary Turner   int64_t raw_value;
1157b9c1b51eSKate Stone   switch (v.Type) {
115842dff790SZachary Turner   case PDB_VariantType::Int8:
115942dff790SZachary Turner     raw_value = v.Value.Int8;
116042dff790SZachary Turner     break;
116142dff790SZachary Turner   case PDB_VariantType::Int16:
116242dff790SZachary Turner     raw_value = v.Value.Int16;
116342dff790SZachary Turner     break;
116442dff790SZachary Turner   case PDB_VariantType::Int32:
116542dff790SZachary Turner     raw_value = v.Value.Int32;
116642dff790SZachary Turner     break;
116742dff790SZachary Turner   case PDB_VariantType::Int64:
116842dff790SZachary Turner     raw_value = v.Value.Int64;
116942dff790SZachary Turner     break;
117042dff790SZachary Turner   case PDB_VariantType::UInt8:
117142dff790SZachary Turner     raw_value = v.Value.UInt8;
117242dff790SZachary Turner     break;
117342dff790SZachary Turner   case PDB_VariantType::UInt16:
117442dff790SZachary Turner     raw_value = v.Value.UInt16;
117542dff790SZachary Turner     break;
117642dff790SZachary Turner   case PDB_VariantType::UInt32:
117742dff790SZachary Turner     raw_value = v.Value.UInt32;
117842dff790SZachary Turner     break;
117942dff790SZachary Turner   case PDB_VariantType::UInt64:
118042dff790SZachary Turner     raw_value = v.Value.UInt64;
118142dff790SZachary Turner     break;
118242dff790SZachary Turner   default:
118342dff790SZachary Turner     return false;
118442dff790SZachary Turner   }
11858ffea27aSRaphael Isemann   CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type);
1186f9f49d35SRaphael Isemann   uint32_t byte_size = m_ast.getASTContext().getTypeSize(
1187b9c1b51eSKate Stone       ClangUtil::GetQualType(underlying_type));
1188709426b3SAleksandr Urakov   auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(
11898c5ec1ffSShafik Yaghmour       enum_type, decl, name.c_str(), raw_value, byte_size * 8);
1190709426b3SAleksandr Urakov   if (!enum_constant_decl)
1191709426b3SAleksandr Urakov     return false;
1192709426b3SAleksandr Urakov 
1193709426b3SAleksandr Urakov   m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl;
1194709426b3SAleksandr Urakov 
1195709426b3SAleksandr Urakov   return true;
119642dff790SZachary Turner }
11977d2a74fcSAleksandr Urakov 
CompleteTypeFromUDT(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & compiler_type,llvm::pdb::PDBSymbolTypeUDT & udt)11987d2a74fcSAleksandr Urakov bool PDBASTParser::CompleteTypeFromUDT(
11997d2a74fcSAleksandr Urakov     lldb_private::SymbolFile &symbol_file,
12007d2a74fcSAleksandr Urakov     lldb_private::CompilerType &compiler_type,
12017d2a74fcSAleksandr Urakov     llvm::pdb::PDBSymbolTypeUDT &udt) {
12027d2a74fcSAleksandr Urakov   ClangASTImporter::LayoutInfo layout_info;
12037d2a74fcSAleksandr Urakov   layout_info.bit_size = udt.getLength() * 8;
12047d2a74fcSAleksandr Urakov 
12057d2a74fcSAleksandr Urakov   auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>();
12067d2a74fcSAleksandr Urakov   if (nested_enums)
12077d2a74fcSAleksandr Urakov     while (auto nested = nested_enums->getNext())
12087d2a74fcSAleksandr Urakov       symbol_file.ResolveTypeUID(nested->getSymIndexId());
12097d2a74fcSAleksandr Urakov 
12107d2a74fcSAleksandr Urakov   auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
12117d2a74fcSAleksandr Urakov   if (bases_enum)
12127d2a74fcSAleksandr Urakov     AddRecordBases(symbol_file, compiler_type,
12137d2a74fcSAleksandr Urakov                    TranslateUdtKind(udt.getUdtKind()), *bases_enum,
12147d2a74fcSAleksandr Urakov                    layout_info);
12157d2a74fcSAleksandr Urakov 
12167d2a74fcSAleksandr Urakov   auto members_enum = udt.findAllChildren<PDBSymbolData>();
12177d2a74fcSAleksandr Urakov   if (members_enum)
12187d2a74fcSAleksandr Urakov     AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info);
12197d2a74fcSAleksandr Urakov 
12207d2a74fcSAleksandr Urakov   auto methods_enum = udt.findAllChildren<PDBSymbolFunc>();
12217d2a74fcSAleksandr Urakov   if (methods_enum)
12227d2a74fcSAleksandr Urakov     AddRecordMethods(symbol_file, compiler_type, *methods_enum);
12237d2a74fcSAleksandr Urakov 
12247d2a74fcSAleksandr Urakov   m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType());
12256e3b0cc2SRaphael Isemann   TypeSystemClang::BuildIndirectFields(compiler_type);
12266e3b0cc2SRaphael Isemann   TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);
12277d2a74fcSAleksandr Urakov 
12287d2a74fcSAleksandr Urakov   clang::CXXRecordDecl *record_decl =
12297d2a74fcSAleksandr Urakov       m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
12307d2a74fcSAleksandr Urakov   if (!record_decl)
12317d2a74fcSAleksandr Urakov     return static_cast<bool>(compiler_type);
12327d2a74fcSAleksandr Urakov 
1233b852b3c9SRaphael Isemann   GetClangASTImporter().SetRecordLayout(record_decl, layout_info);
12347d2a74fcSAleksandr Urakov 
12357d2a74fcSAleksandr Urakov   return static_cast<bool>(compiler_type);
12367d2a74fcSAleksandr Urakov }
12377d2a74fcSAleksandr Urakov 
AddRecordMembers(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,PDBDataSymbolEnumerator & members_enum,lldb_private::ClangASTImporter::LayoutInfo & layout_info)12387d2a74fcSAleksandr Urakov void PDBASTParser::AddRecordMembers(
12397d2a74fcSAleksandr Urakov     lldb_private::SymbolFile &symbol_file,
12407d2a74fcSAleksandr Urakov     lldb_private::CompilerType &record_type,
12417d2a74fcSAleksandr Urakov     PDBDataSymbolEnumerator &members_enum,
1242709426b3SAleksandr Urakov     lldb_private::ClangASTImporter::LayoutInfo &layout_info) {
12437d2a74fcSAleksandr Urakov   while (auto member = members_enum.getNext()) {
12447d2a74fcSAleksandr Urakov     if (member->isCompilerGenerated())
12457d2a74fcSAleksandr Urakov       continue;
12467d2a74fcSAleksandr Urakov 
12477d2a74fcSAleksandr Urakov     auto member_name = member->getName();
12487d2a74fcSAleksandr Urakov 
12497d2a74fcSAleksandr Urakov     auto member_type = symbol_file.ResolveTypeUID(member->getTypeId());
12507d2a74fcSAleksandr Urakov     if (!member_type)
12517d2a74fcSAleksandr Urakov       continue;
12527d2a74fcSAleksandr Urakov 
12537d2a74fcSAleksandr Urakov     auto member_comp_type = member_type->GetLayoutCompilerType();
12547d2a74fcSAleksandr Urakov     if (!member_comp_type.GetCompleteType()) {
12557d2a74fcSAleksandr Urakov       symbol_file.GetObjectFile()->GetModule()->ReportError(
12567d2a74fcSAleksandr Urakov           ":: Class '%s' has a member '%s' of type '%s' "
12577d2a74fcSAleksandr Urakov           "which does not have a complete definition.",
12587d2a74fcSAleksandr Urakov           record_type.GetTypeName().GetCString(), member_name.c_str(),
12597d2a74fcSAleksandr Urakov           member_comp_type.GetTypeName().GetCString());
12606e3b0cc2SRaphael Isemann       if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type))
12616e3b0cc2SRaphael Isemann         TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type);
12627d2a74fcSAleksandr Urakov     }
12637d2a74fcSAleksandr Urakov 
12647d2a74fcSAleksandr Urakov     auto access = TranslateMemberAccess(member->getAccess());
12657d2a74fcSAleksandr Urakov 
12667d2a74fcSAleksandr Urakov     switch (member->getDataKind()) {
12677d2a74fcSAleksandr Urakov     case PDB_DataKind::Member: {
12687d2a74fcSAleksandr Urakov       auto location_type = member->getLocationType();
12697d2a74fcSAleksandr Urakov 
12707d2a74fcSAleksandr Urakov       auto bit_size = member->getLength();
12717d2a74fcSAleksandr Urakov       if (location_type == PDB_LocType::ThisRel)
12727d2a74fcSAleksandr Urakov         bit_size *= 8;
12737d2a74fcSAleksandr Urakov 
12746e3b0cc2SRaphael Isemann       auto decl = TypeSystemClang::AddFieldToRecordType(
12757d2a74fcSAleksandr Urakov           record_type, member_name.c_str(), member_comp_type, access, bit_size);
12767d2a74fcSAleksandr Urakov       if (!decl)
12777d2a74fcSAleksandr Urakov         continue;
12787d2a74fcSAleksandr Urakov 
1279709426b3SAleksandr Urakov       m_uid_to_decl[member->getSymIndexId()] = decl;
1280709426b3SAleksandr Urakov 
12817d2a74fcSAleksandr Urakov       auto offset = member->getOffset() * 8;
12827d2a74fcSAleksandr Urakov       if (location_type == PDB_LocType::BitField)
12837d2a74fcSAleksandr Urakov         offset += member->getBitPosition();
12847d2a74fcSAleksandr Urakov 
12857d2a74fcSAleksandr Urakov       layout_info.field_offsets.insert(std::make_pair(decl, offset));
12867d2a74fcSAleksandr Urakov 
12877d2a74fcSAleksandr Urakov       break;
12887d2a74fcSAleksandr Urakov     }
1289709426b3SAleksandr Urakov     case PDB_DataKind::StaticMember: {
12906e3b0cc2SRaphael Isemann       auto decl = TypeSystemClang::AddVariableToRecordType(
1291709426b3SAleksandr Urakov           record_type, member_name.c_str(), member_comp_type, access);
1292709426b3SAleksandr Urakov       if (!decl)
1293709426b3SAleksandr Urakov         continue;
1294709426b3SAleksandr Urakov 
1295895529cfSAleksandr Urakov       // Static constant members may be a const[expr] declaration.
1296895529cfSAleksandr Urakov       // Query the symbol's value as the variable initializer if valid.
1297895529cfSAleksandr Urakov       if (member_comp_type.IsConst()) {
1298895529cfSAleksandr Urakov         auto value = member->getValue();
1299895529cfSAleksandr Urakov         clang::QualType qual_type = decl->getType();
1300895529cfSAleksandr Urakov         unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type);
1301895529cfSAleksandr Urakov         unsigned constant_width = value.getBitWidth();
1302895529cfSAleksandr Urakov 
1303895529cfSAleksandr Urakov         if (qual_type->isIntegralOrEnumerationType()) {
1304895529cfSAleksandr Urakov           if (type_width >= constant_width) {
1305895529cfSAleksandr Urakov             TypeSystemClang::SetIntegerInitializerForVariable(
1306895529cfSAleksandr Urakov                 decl, value.toAPSInt().extOrTrunc(type_width));
1307895529cfSAleksandr Urakov           } else {
1308a007a6d8SPavel Labath             LLDB_LOG(GetLog(LLDBLog::AST),
1309895529cfSAleksandr Urakov                      "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
1310895529cfSAleksandr Urakov                      "which resolves to a wider constant value ({4} bits). "
1311895529cfSAleksandr Urakov                      "Ignoring constant.",
1312895529cfSAleksandr Urakov                      record_type.GetTypeName(), member_name,
1313895529cfSAleksandr Urakov                      member_comp_type.GetTypeName(), type_width,
1314895529cfSAleksandr Urakov                      constant_width);
1315895529cfSAleksandr Urakov           }
1316895529cfSAleksandr Urakov         } else {
1317895529cfSAleksandr Urakov           switch (member_comp_type.GetBasicTypeEnumeration()) {
1318895529cfSAleksandr Urakov           case lldb::eBasicTypeFloat:
1319895529cfSAleksandr Urakov           case lldb::eBasicTypeDouble:
1320895529cfSAleksandr Urakov           case lldb::eBasicTypeLongDouble:
1321895529cfSAleksandr Urakov             if (type_width == constant_width) {
1322895529cfSAleksandr Urakov               TypeSystemClang::SetFloatingInitializerForVariable(
1323895529cfSAleksandr Urakov                   decl, value.toAPFloat());
1324895529cfSAleksandr Urakov               decl->setConstexpr(true);
1325895529cfSAleksandr Urakov             } else {
1326a007a6d8SPavel Labath               LLDB_LOG(GetLog(LLDBLog::AST),
1327895529cfSAleksandr Urakov                        "Class '{0}' has a member '{1}' of type '{2}' ({3} "
1328895529cfSAleksandr Urakov                        "bits) which resolves to a constant value of mismatched "
1329895529cfSAleksandr Urakov                        "width ({4} bits). Ignoring constant.",
1330895529cfSAleksandr Urakov                        record_type.GetTypeName(), member_name,
1331895529cfSAleksandr Urakov                        member_comp_type.GetTypeName(), type_width,
1332895529cfSAleksandr Urakov                        constant_width);
1333895529cfSAleksandr Urakov             }
1334895529cfSAleksandr Urakov             break;
1335895529cfSAleksandr Urakov           default:
1336895529cfSAleksandr Urakov             break;
1337895529cfSAleksandr Urakov           }
1338895529cfSAleksandr Urakov         }
1339895529cfSAleksandr Urakov       }
1340895529cfSAleksandr Urakov 
1341709426b3SAleksandr Urakov       m_uid_to_decl[member->getSymIndexId()] = decl;
1342709426b3SAleksandr Urakov 
13437d2a74fcSAleksandr Urakov       break;
1344709426b3SAleksandr Urakov     }
13457d2a74fcSAleksandr Urakov     default:
13467d2a74fcSAleksandr Urakov       llvm_unreachable("unsupported PDB data kind");
13477d2a74fcSAleksandr Urakov     }
13487d2a74fcSAleksandr Urakov   }
13497d2a74fcSAleksandr Urakov }
13507d2a74fcSAleksandr Urakov 
AddRecordBases(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,int record_kind,PDBBaseClassSymbolEnumerator & bases_enum,lldb_private::ClangASTImporter::LayoutInfo & layout_info) const13517d2a74fcSAleksandr Urakov void PDBASTParser::AddRecordBases(
13527d2a74fcSAleksandr Urakov     lldb_private::SymbolFile &symbol_file,
13537d2a74fcSAleksandr Urakov     lldb_private::CompilerType &record_type, int record_kind,
13547d2a74fcSAleksandr Urakov     PDBBaseClassSymbolEnumerator &bases_enum,
13557d2a74fcSAleksandr Urakov     lldb_private::ClangASTImporter::LayoutInfo &layout_info) const {
1356970f38eaSZachary Turner   std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes;
1357970f38eaSZachary Turner 
13587d2a74fcSAleksandr Urakov   while (auto base = bases_enum.getNext()) {
13597d2a74fcSAleksandr Urakov     auto base_type = symbol_file.ResolveTypeUID(base->getTypeId());
13607d2a74fcSAleksandr Urakov     if (!base_type)
13617d2a74fcSAleksandr Urakov       continue;
13627d2a74fcSAleksandr Urakov 
13637d2a74fcSAleksandr Urakov     auto base_comp_type = base_type->GetFullCompilerType();
13647d2a74fcSAleksandr Urakov     if (!base_comp_type.GetCompleteType()) {
13657d2a74fcSAleksandr Urakov       symbol_file.GetObjectFile()->GetModule()->ReportError(
13667d2a74fcSAleksandr Urakov           ":: Class '%s' has a base class '%s' "
13677d2a74fcSAleksandr Urakov           "which does not have a complete definition.",
13687d2a74fcSAleksandr Urakov           record_type.GetTypeName().GetCString(),
13697d2a74fcSAleksandr Urakov           base_comp_type.GetTypeName().GetCString());
13706e3b0cc2SRaphael Isemann       if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type))
13716e3b0cc2SRaphael Isemann         TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type);
13727d2a74fcSAleksandr Urakov     }
13737d2a74fcSAleksandr Urakov 
13747d2a74fcSAleksandr Urakov     auto access = TranslateMemberAccess(base->getAccess());
13757d2a74fcSAleksandr Urakov 
13767d2a74fcSAleksandr Urakov     auto is_virtual = base->isVirtualBaseClass();
13777d2a74fcSAleksandr Urakov 
1378970f38eaSZachary Turner     std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
1379970f38eaSZachary Turner         m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(),
1380970f38eaSZachary Turner                                        access, is_virtual,
13817d2a74fcSAleksandr Urakov                                        record_kind == clang::TTK_Class);
1382970f38eaSZachary Turner     lldbassert(base_spec);
13837d2a74fcSAleksandr Urakov 
1384970f38eaSZachary Turner     base_classes.push_back(std::move(base_spec));
13857d2a74fcSAleksandr Urakov 
13867d2a74fcSAleksandr Urakov     if (is_virtual)
13877d2a74fcSAleksandr Urakov       continue;
13887d2a74fcSAleksandr Urakov 
13897d2a74fcSAleksandr Urakov     auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType());
13907d2a74fcSAleksandr Urakov     if (!decl)
13917d2a74fcSAleksandr Urakov       continue;
13927d2a74fcSAleksandr Urakov 
13937d2a74fcSAleksandr Urakov     auto offset = clang::CharUnits::fromQuantity(base->getOffset());
13947d2a74fcSAleksandr Urakov     layout_info.base_offsets.insert(std::make_pair(decl, offset));
13957d2a74fcSAleksandr Urakov   }
1396970f38eaSZachary Turner 
1397970f38eaSZachary Turner   m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(),
1398970f38eaSZachary Turner                             std::move(base_classes));
13997d2a74fcSAleksandr Urakov }
14007d2a74fcSAleksandr Urakov 
AddRecordMethods(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,PDBFuncSymbolEnumerator & methods_enum)1401709426b3SAleksandr Urakov void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file,
14027d2a74fcSAleksandr Urakov                                     lldb_private::CompilerType &record_type,
1403709426b3SAleksandr Urakov                                     PDBFuncSymbolEnumerator &methods_enum) {
1404c1e530eeSAleksandr Urakov   while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext())
1405c1e530eeSAleksandr Urakov     if (clang::CXXMethodDecl *decl =
1406c1e530eeSAleksandr Urakov             AddRecordMethod(symbol_file, record_type, *method))
1407c1e530eeSAleksandr Urakov       m_uid_to_decl[method->getSymIndexId()] = decl;
1408c1e530eeSAleksandr Urakov }
1409709426b3SAleksandr Urakov 
1410c1e530eeSAleksandr Urakov clang::CXXMethodDecl *
AddRecordMethod(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,const llvm::pdb::PDBSymbolFunc & method) const1411c1e530eeSAleksandr Urakov PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
1412c1e530eeSAleksandr Urakov                               lldb_private::CompilerType &record_type,
1413c1e530eeSAleksandr Urakov                               const llvm::pdb::PDBSymbolFunc &method) const {
1414adcd0268SBenjamin Kramer   std::string name =
1415adcd0268SBenjamin Kramer       std::string(MSVCUndecoratedNameParser::DropScope(method.getName()));
1416c1e530eeSAleksandr Urakov 
1417c1e530eeSAleksandr Urakov   Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId());
14187d2a74fcSAleksandr Urakov   // MSVC specific __vecDelDtor.
14197d2a74fcSAleksandr Urakov   if (!method_type)
1420c1e530eeSAleksandr Urakov     return nullptr;
14217d2a74fcSAleksandr Urakov 
1422c1e530eeSAleksandr Urakov   CompilerType method_comp_type = method_type->GetFullCompilerType();
14237d2a74fcSAleksandr Urakov   if (!method_comp_type.GetCompleteType()) {
14247d2a74fcSAleksandr Urakov     symbol_file.GetObjectFile()->GetModule()->ReportError(
14257d2a74fcSAleksandr Urakov         ":: Class '%s' has a method '%s' whose type cannot be completed.",
14267d2a74fcSAleksandr Urakov         record_type.GetTypeName().GetCString(),
14277d2a74fcSAleksandr Urakov         method_comp_type.GetTypeName().GetCString());
14286e3b0cc2SRaphael Isemann     if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type))
14296e3b0cc2SRaphael Isemann       TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type);
14307d2a74fcSAleksandr Urakov   }
14317d2a74fcSAleksandr Urakov 
1432c1e530eeSAleksandr Urakov   AccessType access = TranslateMemberAccess(method.getAccess());
1433c1e530eeSAleksandr Urakov   if (access == eAccessNone)
1434c1e530eeSAleksandr Urakov     access = eAccessPublic;
1435c1e530eeSAleksandr Urakov 
14367d2a74fcSAleksandr Urakov   // TODO: get mangled name for the method.
1437c1e530eeSAleksandr Urakov   return m_ast.AddMethodToCXXRecordType(
1438709426b3SAleksandr Urakov       record_type.GetOpaqueQualType(), name.c_str(),
1439c1e530eeSAleksandr Urakov       /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(),
1440c1e530eeSAleksandr Urakov       method.isStatic(), method.hasInlineAttribute(),
14417d2a74fcSAleksandr Urakov       /*is_explicit*/ false, // FIXME: Need this field in CodeView.
14427d2a74fcSAleksandr Urakov       /*is_attr_used*/ false,
1443c1e530eeSAleksandr Urakov       /*is_artificial*/ method.isCompilerGenerated());
14447d2a74fcSAleksandr Urakov }
1445