xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- PDBASTParser.cpp --------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "PDBASTParser.h"
10061da546Spatrick 
11061da546Spatrick #include "SymbolFilePDB.h"
12061da546Spatrick 
13061da546Spatrick #include "clang/AST/CharUnits.h"
14061da546Spatrick #include "clang/AST/Decl.h"
15061da546Spatrick #include "clang/AST/DeclCXX.h"
16061da546Spatrick 
17dda28197Spatrick #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
18dda28197Spatrick #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
19dda28197Spatrick #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
20be691f3bSpatrick #include "lldb/Core/Declaration.h"
21061da546Spatrick #include "lldb/Core/Module.h"
22061da546Spatrick #include "lldb/Symbol/SymbolFile.h"
23061da546Spatrick #include "lldb/Symbol/TypeMap.h"
24061da546Spatrick #include "lldb/Symbol/TypeSystem.h"
25*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
26*f6aab3d8Srobert #include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
27061da546Spatrick #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
28061da546Spatrick #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
29061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbol.h"
30061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
31061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
32061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
33*f6aab3d8Srobert #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
34061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
35061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
36061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
37061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
38061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
39061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
40061da546Spatrick #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
41061da546Spatrick 
42061da546Spatrick #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
43*f6aab3d8Srobert #include <optional>
44061da546Spatrick 
45061da546Spatrick using namespace lldb;
46061da546Spatrick using namespace lldb_private;
47061da546Spatrick using namespace llvm::pdb;
48061da546Spatrick 
TranslateUdtKind(PDB_UdtType pdb_kind)49061da546Spatrick static int TranslateUdtKind(PDB_UdtType pdb_kind) {
50061da546Spatrick   switch (pdb_kind) {
51061da546Spatrick   case PDB_UdtType::Class:
52061da546Spatrick     return clang::TTK_Class;
53061da546Spatrick   case PDB_UdtType::Struct:
54061da546Spatrick     return clang::TTK_Struct;
55061da546Spatrick   case PDB_UdtType::Union:
56061da546Spatrick     return clang::TTK_Union;
57061da546Spatrick   case PDB_UdtType::Interface:
58061da546Spatrick     return clang::TTK_Interface;
59061da546Spatrick   }
60061da546Spatrick   llvm_unreachable("unsuported PDB UDT type");
61061da546Spatrick }
62061da546Spatrick 
TranslateBuiltinEncoding(PDB_BuiltinType type)63061da546Spatrick static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
64061da546Spatrick   switch (type) {
65061da546Spatrick   case PDB_BuiltinType::Float:
66061da546Spatrick     return lldb::eEncodingIEEE754;
67061da546Spatrick   case PDB_BuiltinType::Int:
68061da546Spatrick   case PDB_BuiltinType::Long:
69061da546Spatrick   case PDB_BuiltinType::Char:
70061da546Spatrick     return lldb::eEncodingSint;
71061da546Spatrick   case PDB_BuiltinType::Bool:
72061da546Spatrick   case PDB_BuiltinType::Char16:
73061da546Spatrick   case PDB_BuiltinType::Char32:
74061da546Spatrick   case PDB_BuiltinType::UInt:
75061da546Spatrick   case PDB_BuiltinType::ULong:
76061da546Spatrick   case PDB_BuiltinType::HResult:
77061da546Spatrick   case PDB_BuiltinType::WCharT:
78061da546Spatrick     return lldb::eEncodingUint;
79061da546Spatrick   default:
80061da546Spatrick     return lldb::eEncodingInvalid;
81061da546Spatrick   }
82061da546Spatrick }
83061da546Spatrick 
TranslateEnumEncoding(PDB_VariantType type)84061da546Spatrick static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
85061da546Spatrick   switch (type) {
86061da546Spatrick   case PDB_VariantType::Int8:
87061da546Spatrick   case PDB_VariantType::Int16:
88061da546Spatrick   case PDB_VariantType::Int32:
89061da546Spatrick   case PDB_VariantType::Int64:
90061da546Spatrick     return lldb::eEncodingSint;
91061da546Spatrick 
92061da546Spatrick   case PDB_VariantType::UInt8:
93061da546Spatrick   case PDB_VariantType::UInt16:
94061da546Spatrick   case PDB_VariantType::UInt32:
95061da546Spatrick   case PDB_VariantType::UInt64:
96061da546Spatrick     return lldb::eEncodingUint;
97061da546Spatrick 
98061da546Spatrick   default:
99061da546Spatrick     break;
100061da546Spatrick   }
101061da546Spatrick 
102061da546Spatrick   return lldb::eEncodingSint;
103061da546Spatrick }
104061da546Spatrick 
105061da546Spatrick static CompilerType
GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang & clang_ast,const PDBSymbolTypeBuiltin & pdb_type,Encoding encoding,uint32_t width)106dda28197Spatrick GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast,
107061da546Spatrick                                        const PDBSymbolTypeBuiltin &pdb_type,
108061da546Spatrick                                        Encoding encoding, uint32_t width) {
109061da546Spatrick   clang::ASTContext &ast = clang_ast.getASTContext();
110061da546Spatrick 
111061da546Spatrick   switch (pdb_type.getBuiltinType()) {
112061da546Spatrick   default:
113061da546Spatrick     break;
114061da546Spatrick   case PDB_BuiltinType::None:
115061da546Spatrick     return CompilerType();
116061da546Spatrick   case PDB_BuiltinType::Void:
117061da546Spatrick     return clang_ast.GetBasicType(eBasicTypeVoid);
118061da546Spatrick   case PDB_BuiltinType::Char:
119061da546Spatrick     return clang_ast.GetBasicType(eBasicTypeChar);
120061da546Spatrick   case PDB_BuiltinType::Bool:
121061da546Spatrick     return clang_ast.GetBasicType(eBasicTypeBool);
122061da546Spatrick   case PDB_BuiltinType::Long:
123061da546Spatrick     if (width == ast.getTypeSize(ast.LongTy))
124*f6aab3d8Srobert       return CompilerType(clang_ast.weak_from_this(),
125*f6aab3d8Srobert                           ast.LongTy.getAsOpaquePtr());
126061da546Spatrick     if (width == ast.getTypeSize(ast.LongLongTy))
127*f6aab3d8Srobert       return CompilerType(clang_ast.weak_from_this(),
128*f6aab3d8Srobert                           ast.LongLongTy.getAsOpaquePtr());
129061da546Spatrick     break;
130061da546Spatrick   case PDB_BuiltinType::ULong:
131061da546Spatrick     if (width == ast.getTypeSize(ast.UnsignedLongTy))
132*f6aab3d8Srobert       return CompilerType(clang_ast.weak_from_this(),
133*f6aab3d8Srobert                           ast.UnsignedLongTy.getAsOpaquePtr());
134061da546Spatrick     if (width == ast.getTypeSize(ast.UnsignedLongLongTy))
135*f6aab3d8Srobert       return CompilerType(clang_ast.weak_from_this(),
136*f6aab3d8Srobert                           ast.UnsignedLongLongTy.getAsOpaquePtr());
137061da546Spatrick     break;
138061da546Spatrick   case PDB_BuiltinType::WCharT:
139061da546Spatrick     if (width == ast.getTypeSize(ast.WCharTy))
140*f6aab3d8Srobert       return CompilerType(clang_ast.weak_from_this(),
141*f6aab3d8Srobert                           ast.WCharTy.getAsOpaquePtr());
142061da546Spatrick     break;
143061da546Spatrick   case PDB_BuiltinType::Char16:
144*f6aab3d8Srobert     return CompilerType(clang_ast.weak_from_this(),
145*f6aab3d8Srobert                         ast.Char16Ty.getAsOpaquePtr());
146061da546Spatrick   case PDB_BuiltinType::Char32:
147*f6aab3d8Srobert     return CompilerType(clang_ast.weak_from_this(),
148*f6aab3d8Srobert                         ast.Char32Ty.getAsOpaquePtr());
149061da546Spatrick   case PDB_BuiltinType::Float:
150061da546Spatrick     // Note: types `long double` and `double` have same bit size in MSVC and
151061da546Spatrick     // there is no information in the PDB to distinguish them. So when falling
152061da546Spatrick     // back to default search, the compiler type of `long double` will be
153061da546Spatrick     // represented by the one generated for `double`.
154061da546Spatrick     break;
155061da546Spatrick   }
156061da546Spatrick   // If there is no match on PDB_BuiltinType, fall back to default search by
157061da546Spatrick   // encoding and width only
158061da546Spatrick   return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
159061da546Spatrick }
160061da546Spatrick 
GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin & pdb_type,CompilerType & compiler_type)161061da546Spatrick static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
162061da546Spatrick                                          CompilerType &compiler_type) {
163061da546Spatrick   PDB_BuiltinType kind = pdb_type.getBuiltinType();
164061da546Spatrick   switch (kind) {
165061da546Spatrick   default:
166061da546Spatrick     break;
167061da546Spatrick   case PDB_BuiltinType::Currency:
168061da546Spatrick     return ConstString("CURRENCY");
169061da546Spatrick   case PDB_BuiltinType::Date:
170061da546Spatrick     return ConstString("DATE");
171061da546Spatrick   case PDB_BuiltinType::Variant:
172061da546Spatrick     return ConstString("VARIANT");
173061da546Spatrick   case PDB_BuiltinType::Complex:
174061da546Spatrick     return ConstString("complex");
175061da546Spatrick   case PDB_BuiltinType::Bitfield:
176061da546Spatrick     return ConstString("bitfield");
177061da546Spatrick   case PDB_BuiltinType::BSTR:
178061da546Spatrick     return ConstString("BSTR");
179061da546Spatrick   case PDB_BuiltinType::HResult:
180061da546Spatrick     return ConstString("HRESULT");
181061da546Spatrick   case PDB_BuiltinType::BCD:
182061da546Spatrick     return ConstString("BCD");
183061da546Spatrick   case PDB_BuiltinType::Char16:
184061da546Spatrick     return ConstString("char16_t");
185061da546Spatrick   case PDB_BuiltinType::Char32:
186061da546Spatrick     return ConstString("char32_t");
187061da546Spatrick   case PDB_BuiltinType::None:
188061da546Spatrick     return ConstString("...");
189061da546Spatrick   }
190061da546Spatrick   return compiler_type.GetTypeName();
191061da546Spatrick }
192061da546Spatrick 
GetDeclarationForSymbol(const PDBSymbol & symbol,Declaration & decl)193061da546Spatrick static bool GetDeclarationForSymbol(const PDBSymbol &symbol,
194061da546Spatrick                                     Declaration &decl) {
195061da546Spatrick   auto &raw_sym = symbol.getRawSymbol();
196061da546Spatrick   auto first_line_up = raw_sym.getSrcLineOnTypeDefn();
197061da546Spatrick 
198061da546Spatrick   if (!first_line_up) {
199061da546Spatrick     auto lines_up = symbol.getSession().findLineNumbersByAddress(
200061da546Spatrick         raw_sym.getVirtualAddress(), raw_sym.getLength());
201061da546Spatrick     if (!lines_up)
202061da546Spatrick       return false;
203061da546Spatrick     first_line_up = lines_up->getNext();
204061da546Spatrick     if (!first_line_up)
205061da546Spatrick       return false;
206061da546Spatrick   }
207061da546Spatrick   uint32_t src_file_id = first_line_up->getSourceFileId();
208061da546Spatrick   auto src_file_up = symbol.getSession().getSourceFileById(src_file_id);
209061da546Spatrick   if (!src_file_up)
210061da546Spatrick     return false;
211061da546Spatrick 
212061da546Spatrick   FileSpec spec(src_file_up->getFileName());
213061da546Spatrick   decl.SetFile(spec);
214061da546Spatrick   decl.SetColumn(first_line_up->getColumnNumber());
215061da546Spatrick   decl.SetLine(first_line_up->getLineNumber());
216061da546Spatrick   return true;
217061da546Spatrick }
218061da546Spatrick 
TranslateMemberAccess(PDB_MemberAccess access)219061da546Spatrick static AccessType TranslateMemberAccess(PDB_MemberAccess access) {
220061da546Spatrick   switch (access) {
221061da546Spatrick   case PDB_MemberAccess::Private:
222061da546Spatrick     return eAccessPrivate;
223061da546Spatrick   case PDB_MemberAccess::Protected:
224061da546Spatrick     return eAccessProtected;
225061da546Spatrick   case PDB_MemberAccess::Public:
226061da546Spatrick     return eAccessPublic;
227061da546Spatrick   }
228061da546Spatrick   return eAccessNone;
229061da546Spatrick }
230061da546Spatrick 
GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind)231061da546Spatrick static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) {
232061da546Spatrick   switch (udt_kind) {
233061da546Spatrick   case PDB_UdtType::Struct:
234061da546Spatrick   case PDB_UdtType::Union:
235061da546Spatrick     return eAccessPublic;
236061da546Spatrick   case PDB_UdtType::Class:
237061da546Spatrick   case PDB_UdtType::Interface:
238061da546Spatrick     return eAccessPrivate;
239061da546Spatrick   }
240061da546Spatrick   llvm_unreachable("unsupported PDB UDT type");
241061da546Spatrick }
242061da546Spatrick 
GetAccessibilityForUdt(const PDBSymbolTypeUDT & udt)243061da546Spatrick static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) {
244061da546Spatrick   AccessType access = TranslateMemberAccess(udt.getAccess());
245061da546Spatrick   if (access != lldb::eAccessNone || !udt.isNested())
246061da546Spatrick     return access;
247061da546Spatrick 
248061da546Spatrick   auto parent = udt.getClassParent();
249061da546Spatrick   if (!parent)
250061da546Spatrick     return lldb::eAccessNone;
251061da546Spatrick 
252061da546Spatrick   auto parent_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(parent.get());
253061da546Spatrick   if (!parent_udt)
254061da546Spatrick     return lldb::eAccessNone;
255061da546Spatrick 
256061da546Spatrick   return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind());
257061da546Spatrick }
258061da546Spatrick 
259061da546Spatrick static clang::MSInheritanceAttr::Spelling
GetMSInheritance(const PDBSymbolTypeUDT & udt)260061da546Spatrick GetMSInheritance(const PDBSymbolTypeUDT &udt) {
261061da546Spatrick   int base_count = 0;
262061da546Spatrick   bool has_virtual = false;
263061da546Spatrick 
264061da546Spatrick   auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
265061da546Spatrick   if (bases_enum) {
266061da546Spatrick     while (auto base = bases_enum->getNext()) {
267061da546Spatrick       base_count++;
268061da546Spatrick       has_virtual |= base->isVirtualBaseClass();
269061da546Spatrick     }
270061da546Spatrick   }
271061da546Spatrick 
272061da546Spatrick   if (has_virtual)
273061da546Spatrick     return clang::MSInheritanceAttr::Keyword_virtual_inheritance;
274061da546Spatrick   if (base_count > 1)
275061da546Spatrick     return clang::MSInheritanceAttr::Keyword_multiple_inheritance;
276061da546Spatrick   return clang::MSInheritanceAttr::Keyword_single_inheritance;
277061da546Spatrick }
278061da546Spatrick 
279061da546Spatrick static std::unique_ptr<llvm::pdb::PDBSymbol>
GetClassOrFunctionParent(const llvm::pdb::PDBSymbol & symbol)280061da546Spatrick GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) {
281061da546Spatrick   const IPDBSession &session = symbol.getSession();
282061da546Spatrick   const IPDBRawSymbol &raw = symbol.getRawSymbol();
283061da546Spatrick   auto tag = symbol.getSymTag();
284061da546Spatrick 
285061da546Spatrick   // For items that are nested inside of a class, return the class that it is
286061da546Spatrick   // nested inside of.
287061da546Spatrick   // Note that only certain items can be nested inside of classes.
288061da546Spatrick   switch (tag) {
289061da546Spatrick   case PDB_SymType::Function:
290061da546Spatrick   case PDB_SymType::Data:
291061da546Spatrick   case PDB_SymType::UDT:
292061da546Spatrick   case PDB_SymType::Enum:
293061da546Spatrick   case PDB_SymType::FunctionSig:
294061da546Spatrick   case PDB_SymType::Typedef:
295061da546Spatrick   case PDB_SymType::BaseClass:
296061da546Spatrick   case PDB_SymType::VTable: {
297061da546Spatrick     auto class_parent_id = raw.getClassParentId();
298061da546Spatrick     if (auto class_parent = session.getSymbolById(class_parent_id))
299061da546Spatrick       return class_parent;
300061da546Spatrick     break;
301061da546Spatrick   }
302061da546Spatrick   default:
303061da546Spatrick     break;
304061da546Spatrick   }
305061da546Spatrick 
306061da546Spatrick   // Otherwise, if it is nested inside of a function, return the function.
307061da546Spatrick   // Note that only certain items can be nested inside of functions.
308061da546Spatrick   switch (tag) {
309061da546Spatrick   case PDB_SymType::Block:
310061da546Spatrick   case PDB_SymType::Data: {
311061da546Spatrick     auto lexical_parent_id = raw.getLexicalParentId();
312061da546Spatrick     auto lexical_parent = session.getSymbolById(lexical_parent_id);
313061da546Spatrick     if (!lexical_parent)
314061da546Spatrick       return nullptr;
315061da546Spatrick 
316061da546Spatrick     auto lexical_parent_tag = lexical_parent->getSymTag();
317061da546Spatrick     if (lexical_parent_tag == PDB_SymType::Function)
318061da546Spatrick       return lexical_parent;
319061da546Spatrick     if (lexical_parent_tag == PDB_SymType::Exe)
320061da546Spatrick       return nullptr;
321061da546Spatrick 
322061da546Spatrick     return GetClassOrFunctionParent(*lexical_parent);
323061da546Spatrick   }
324061da546Spatrick   default:
325061da546Spatrick     return nullptr;
326061da546Spatrick   }
327061da546Spatrick }
328061da546Spatrick 
329061da546Spatrick static clang::NamedDecl *
GetDeclFromContextByName(const clang::ASTContext & ast,const clang::DeclContext & decl_context,llvm::StringRef name)330061da546Spatrick GetDeclFromContextByName(const clang::ASTContext &ast,
331061da546Spatrick                          const clang::DeclContext &decl_context,
332061da546Spatrick                          llvm::StringRef name) {
333061da546Spatrick   clang::IdentifierInfo &ident = ast.Idents.get(name);
334061da546Spatrick   clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident);
335061da546Spatrick   clang::DeclContext::lookup_result result = decl_context.lookup(decl_name);
336061da546Spatrick   if (result.empty())
337061da546Spatrick     return nullptr;
338061da546Spatrick 
339be691f3bSpatrick   return *result.begin();
340061da546Spatrick }
341061da546Spatrick 
IsAnonymousNamespaceName(llvm::StringRef name)342061da546Spatrick static bool IsAnonymousNamespaceName(llvm::StringRef name) {
343061da546Spatrick   return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
344061da546Spatrick }
345061da546Spatrick 
TranslateCallingConvention(PDB_CallingConv pdb_cc)346061da546Spatrick static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
347061da546Spatrick   switch (pdb_cc) {
348061da546Spatrick   case llvm::codeview::CallingConvention::NearC:
349061da546Spatrick     return clang::CC_C;
350061da546Spatrick   case llvm::codeview::CallingConvention::NearStdCall:
351061da546Spatrick     return clang::CC_X86StdCall;
352061da546Spatrick   case llvm::codeview::CallingConvention::NearFast:
353061da546Spatrick     return clang::CC_X86FastCall;
354061da546Spatrick   case llvm::codeview::CallingConvention::ThisCall:
355061da546Spatrick     return clang::CC_X86ThisCall;
356061da546Spatrick   case llvm::codeview::CallingConvention::NearVector:
357061da546Spatrick     return clang::CC_X86VectorCall;
358061da546Spatrick   case llvm::codeview::CallingConvention::NearPascal:
359061da546Spatrick     return clang::CC_X86Pascal;
360061da546Spatrick   default:
361061da546Spatrick     assert(false && "Unknown calling convention");
362061da546Spatrick     return clang::CC_C;
363061da546Spatrick   }
364061da546Spatrick }
365061da546Spatrick 
PDBASTParser(lldb_private::TypeSystemClang & ast)366dda28197Spatrick PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}
367061da546Spatrick 
368be691f3bSpatrick PDBASTParser::~PDBASTParser() = default;
369061da546Spatrick 
370061da546Spatrick // DebugInfoASTParser interface
371061da546Spatrick 
CreateLLDBTypeFromPDBType(const PDBSymbol & type)372061da546Spatrick lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
373061da546Spatrick   Declaration decl;
374061da546Spatrick   switch (type.getSymTag()) {
375061da546Spatrick   case PDB_SymType::BaseClass: {
376061da546Spatrick     auto symbol_file = m_ast.GetSymbolFile();
377061da546Spatrick     if (!symbol_file)
378061da546Spatrick       return nullptr;
379061da546Spatrick 
380061da546Spatrick     auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId());
381061da546Spatrick     return ty ? ty->shared_from_this() : nullptr;
382061da546Spatrick   } break;
383061da546Spatrick   case PDB_SymType::UDT: {
384061da546Spatrick     auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);
385061da546Spatrick     assert(udt);
386061da546Spatrick 
387061da546Spatrick     // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol
388061da546Spatrick     // other than a Typedef symbol in PDB. For example,
389061da546Spatrick     //    typedef union { short Row; short Col; } Union;
390061da546Spatrick     // is generated as a named UDT in PDB:
391061da546Spatrick     //    union Union { short Row; short Col; }
392061da546Spatrick     // Such symbols will be handled here.
393061da546Spatrick 
394061da546Spatrick     // Some UDT with trival ctor has zero length. Just ignore.
395061da546Spatrick     if (udt->getLength() == 0)
396061da546Spatrick       return nullptr;
397061da546Spatrick 
398061da546Spatrick     // Ignore unnamed-tag UDTs.
399dda28197Spatrick     std::string name =
400dda28197Spatrick         std::string(MSVCUndecoratedNameParser::DropScope(udt->getName()));
401061da546Spatrick     if (name.empty())
402061da546Spatrick       return nullptr;
403061da546Spatrick 
404061da546Spatrick     auto decl_context = GetDeclContextContainingSymbol(type);
405061da546Spatrick 
406061da546Spatrick     // Check if such an UDT already exists in the current context.
407061da546Spatrick     // This may occur with const or volatile types. There are separate type
408061da546Spatrick     // symbols in PDB for types with const or volatile modifiers, but we need
409061da546Spatrick     // to create only one declaration for them all.
410061da546Spatrick     Type::ResolveState type_resolve_state;
411061da546Spatrick     CompilerType clang_type = m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(
412061da546Spatrick         ConstString(name), decl_context);
413061da546Spatrick     if (!clang_type.IsValid()) {
414061da546Spatrick       auto access = GetAccessibilityForUdt(*udt);
415061da546Spatrick 
416061da546Spatrick       auto tag_type_kind = TranslateUdtKind(udt->getUdtKind());
417061da546Spatrick 
418061da546Spatrick       ClangASTMetadata metadata;
419061da546Spatrick       metadata.SetUserID(type.getSymIndexId());
420061da546Spatrick       metadata.SetIsDynamicCXXType(false);
421061da546Spatrick 
422dda28197Spatrick       clang_type = m_ast.CreateRecordType(
423dda28197Spatrick           decl_context, OptionalClangModuleID(), access, name, tag_type_kind,
424061da546Spatrick           lldb::eLanguageTypeC_plus_plus, &metadata);
425061da546Spatrick       assert(clang_type.IsValid());
426061da546Spatrick 
427061da546Spatrick       auto record_decl =
428061da546Spatrick           m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
429061da546Spatrick       assert(record_decl);
430061da546Spatrick       m_uid_to_decl[type.getSymIndexId()] = record_decl;
431061da546Spatrick 
432061da546Spatrick       auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit(
433061da546Spatrick           m_ast.getASTContext(), GetMSInheritance(*udt));
434061da546Spatrick       record_decl->addAttr(inheritance_attr);
435061da546Spatrick 
436dda28197Spatrick       TypeSystemClang::StartTagDeclarationDefinition(clang_type);
437061da546Spatrick 
438061da546Spatrick       auto children = udt->findAllChildren();
439061da546Spatrick       if (!children || children->getChildCount() == 0) {
440061da546Spatrick         // PDB does not have symbol of forwarder. We assume we get an udt w/o
441061da546Spatrick         // any fields. Just complete it at this point.
442dda28197Spatrick         TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
443061da546Spatrick 
444dda28197Spatrick         TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
445061da546Spatrick                                                false);
446061da546Spatrick 
447061da546Spatrick         type_resolve_state = Type::ResolveState::Full;
448061da546Spatrick       } else {
449061da546Spatrick         // Add the type to the forward declarations. It will help us to avoid
450061da546Spatrick         // an endless recursion in CompleteTypeFromUdt function.
451061da546Spatrick         m_forward_decl_to_uid[record_decl] = type.getSymIndexId();
452061da546Spatrick 
453dda28197Spatrick         TypeSystemClang::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
454061da546Spatrick                                                true);
455061da546Spatrick 
456061da546Spatrick         type_resolve_state = Type::ResolveState::Forward;
457061da546Spatrick       }
458061da546Spatrick     } else
459061da546Spatrick       type_resolve_state = Type::ResolveState::Forward;
460061da546Spatrick 
461061da546Spatrick     if (udt->isConstType())
462061da546Spatrick       clang_type = clang_type.AddConstModifier();
463061da546Spatrick 
464061da546Spatrick     if (udt->isVolatileType())
465061da546Spatrick       clang_type = clang_type.AddVolatileModifier();
466061da546Spatrick 
467061da546Spatrick     GetDeclarationForSymbol(type, decl);
468*f6aab3d8Srobert     return m_ast.GetSymbolFile()->MakeType(
469*f6aab3d8Srobert         type.getSymIndexId(), ConstString(name), udt->getLength(), nullptr,
470*f6aab3d8Srobert         LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type,
471061da546Spatrick         type_resolve_state);
472061da546Spatrick   } break;
473061da546Spatrick   case PDB_SymType::Enum: {
474061da546Spatrick     auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);
475061da546Spatrick     assert(enum_type);
476061da546Spatrick 
477061da546Spatrick     std::string name =
478dda28197Spatrick         std::string(MSVCUndecoratedNameParser::DropScope(enum_type->getName()));
479061da546Spatrick     auto decl_context = GetDeclContextContainingSymbol(type);
480061da546Spatrick     uint64_t bytes = enum_type->getLength();
481061da546Spatrick 
482061da546Spatrick     // Check if such an enum already exists in the current context
483061da546Spatrick     CompilerType ast_enum = m_ast.GetTypeForIdentifier<clang::EnumDecl>(
484061da546Spatrick         ConstString(name), decl_context);
485061da546Spatrick     if (!ast_enum.IsValid()) {
486061da546Spatrick       auto underlying_type_up = enum_type->getUnderlyingType();
487061da546Spatrick       if (!underlying_type_up)
488061da546Spatrick         return nullptr;
489061da546Spatrick 
490061da546Spatrick       lldb::Encoding encoding =
491061da546Spatrick           TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());
492061da546Spatrick       // FIXME: Type of underlying builtin is always `Int`. We correct it with
493061da546Spatrick       // the very first enumerator's encoding if any.
494061da546Spatrick       auto first_child = enum_type->findOneChild<PDBSymbolData>();
495061da546Spatrick       if (first_child)
496061da546Spatrick         encoding = TranslateEnumEncoding(first_child->getValue().Type);
497061da546Spatrick 
498061da546Spatrick       CompilerType builtin_type;
499061da546Spatrick       if (bytes > 0)
500061da546Spatrick         builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(
501061da546Spatrick             m_ast, *underlying_type_up, encoding, bytes * 8);
502061da546Spatrick       else
503061da546Spatrick         builtin_type = m_ast.GetBasicType(eBasicTypeInt);
504061da546Spatrick 
505061da546Spatrick       // FIXME: PDB does not have information about scoped enumeration (Enum
506061da546Spatrick       // Class). Set it false for now.
507061da546Spatrick       bool isScoped = false;
508061da546Spatrick 
509*f6aab3d8Srobert       ast_enum = m_ast.CreateEnumerationType(name, decl_context,
510dda28197Spatrick                                              OptionalClangModuleID(), decl,
511061da546Spatrick                                              builtin_type, isScoped);
512061da546Spatrick 
513dda28197Spatrick       auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum);
514061da546Spatrick       assert(enum_decl);
515061da546Spatrick       m_uid_to_decl[type.getSymIndexId()] = enum_decl;
516061da546Spatrick 
517061da546Spatrick       auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
518061da546Spatrick       if (enum_values) {
519061da546Spatrick         while (auto enum_value = enum_values->getNext()) {
520061da546Spatrick           if (enum_value->getDataKind() != PDB_DataKind::Constant)
521061da546Spatrick             continue;
522061da546Spatrick           AddEnumValue(ast_enum, *enum_value);
523061da546Spatrick         }
524061da546Spatrick       }
525061da546Spatrick 
526dda28197Spatrick       if (TypeSystemClang::StartTagDeclarationDefinition(ast_enum))
527dda28197Spatrick         TypeSystemClang::CompleteTagDeclarationDefinition(ast_enum);
528061da546Spatrick     }
529061da546Spatrick 
530061da546Spatrick     if (enum_type->isConstType())
531061da546Spatrick       ast_enum = ast_enum.AddConstModifier();
532061da546Spatrick 
533061da546Spatrick     if (enum_type->isVolatileType())
534061da546Spatrick       ast_enum = ast_enum.AddVolatileModifier();
535061da546Spatrick 
536061da546Spatrick     GetDeclarationForSymbol(type, decl);
537*f6aab3d8Srobert     return m_ast.GetSymbolFile()->MakeType(
538*f6aab3d8Srobert         type.getSymIndexId(), ConstString(name), bytes, nullptr,
539*f6aab3d8Srobert         LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ast_enum,
540*f6aab3d8Srobert         lldb_private::Type::ResolveState::Full);
541061da546Spatrick   } break;
542061da546Spatrick   case PDB_SymType::Typedef: {
543061da546Spatrick     auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
544061da546Spatrick     assert(type_def);
545061da546Spatrick 
546be691f3bSpatrick     SymbolFile *symbol_file = m_ast.GetSymbolFile();
547be691f3bSpatrick     if (!symbol_file)
548be691f3bSpatrick       return nullptr;
549be691f3bSpatrick 
550061da546Spatrick     lldb_private::Type *target_type =
551be691f3bSpatrick         symbol_file->ResolveTypeUID(type_def->getTypeId());
552061da546Spatrick     if (!target_type)
553061da546Spatrick       return nullptr;
554061da546Spatrick 
555061da546Spatrick     std::string name =
556dda28197Spatrick         std::string(MSVCUndecoratedNameParser::DropScope(type_def->getName()));
557061da546Spatrick     auto decl_ctx = GetDeclContextContainingSymbol(type);
558061da546Spatrick 
559061da546Spatrick     // Check if such a typedef already exists in the current context
560061da546Spatrick     CompilerType ast_typedef =
561061da546Spatrick         m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(ConstString(name),
562061da546Spatrick                                                            decl_ctx);
563061da546Spatrick     if (!ast_typedef.IsValid()) {
564061da546Spatrick       CompilerType target_ast_type = target_type->GetFullCompilerType();
565061da546Spatrick 
566be691f3bSpatrick       ast_typedef = target_ast_type.CreateTypedef(
567be691f3bSpatrick           name.c_str(), m_ast.CreateDeclContext(decl_ctx), 0);
568061da546Spatrick       if (!ast_typedef)
569061da546Spatrick         return nullptr;
570061da546Spatrick 
571dda28197Spatrick       auto typedef_decl = TypeSystemClang::GetAsTypedefDecl(ast_typedef);
572061da546Spatrick       assert(typedef_decl);
573061da546Spatrick       m_uid_to_decl[type.getSymIndexId()] = typedef_decl;
574061da546Spatrick     }
575061da546Spatrick 
576061da546Spatrick     if (type_def->isConstType())
577061da546Spatrick       ast_typedef = ast_typedef.AddConstModifier();
578061da546Spatrick 
579061da546Spatrick     if (type_def->isVolatileType())
580061da546Spatrick       ast_typedef = ast_typedef.AddVolatileModifier();
581061da546Spatrick 
582061da546Spatrick     GetDeclarationForSymbol(type, decl);
583*f6aab3d8Srobert     std::optional<uint64_t> size;
584061da546Spatrick     if (type_def->getLength())
585061da546Spatrick       size = type_def->getLength();
586*f6aab3d8Srobert     return m_ast.GetSymbolFile()->MakeType(
587*f6aab3d8Srobert         type_def->getSymIndexId(), ConstString(name), size, nullptr,
588*f6aab3d8Srobert         target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, decl,
589*f6aab3d8Srobert         ast_typedef, lldb_private::Type::ResolveState::Full);
590061da546Spatrick   } break;
591061da546Spatrick   case PDB_SymType::Function:
592061da546Spatrick   case PDB_SymType::FunctionSig: {
593061da546Spatrick     std::string name;
594061da546Spatrick     PDBSymbolTypeFunctionSig *func_sig = nullptr;
595061da546Spatrick     if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) {
596061da546Spatrick       if (pdb_func->isCompilerGenerated())
597061da546Spatrick         return nullptr;
598061da546Spatrick 
599061da546Spatrick       auto sig = pdb_func->getSignature();
600061da546Spatrick       if (!sig)
601061da546Spatrick         return nullptr;
602061da546Spatrick       func_sig = sig.release();
603061da546Spatrick       // Function type is named.
604dda28197Spatrick       name = std::string(
605dda28197Spatrick           MSVCUndecoratedNameParser::DropScope(pdb_func->getName()));
606061da546Spatrick     } else if (auto pdb_func_sig =
607061da546Spatrick                    llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
608061da546Spatrick       func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);
609061da546Spatrick     } else
610061da546Spatrick       llvm_unreachable("Unexpected PDB symbol!");
611061da546Spatrick 
612061da546Spatrick     auto arg_enum = func_sig->getArguments();
613061da546Spatrick     uint32_t num_args = arg_enum->getChildCount();
614061da546Spatrick     std::vector<CompilerType> arg_list;
615061da546Spatrick 
616061da546Spatrick     bool is_variadic = func_sig->isCVarArgs();
617061da546Spatrick     // Drop last variadic argument.
618061da546Spatrick     if (is_variadic)
619061da546Spatrick       --num_args;
620061da546Spatrick     for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) {
621061da546Spatrick       auto arg = arg_enum->getChildAtIndex(arg_idx);
622061da546Spatrick       if (!arg)
623061da546Spatrick         break;
624be691f3bSpatrick 
625be691f3bSpatrick       SymbolFile *symbol_file = m_ast.GetSymbolFile();
626be691f3bSpatrick       if (!symbol_file)
627be691f3bSpatrick         return nullptr;
628be691f3bSpatrick 
629061da546Spatrick       lldb_private::Type *arg_type =
630be691f3bSpatrick           symbol_file->ResolveTypeUID(arg->getSymIndexId());
631061da546Spatrick       // If there's some error looking up one of the dependent types of this
632061da546Spatrick       // function signature, bail.
633061da546Spatrick       if (!arg_type)
634061da546Spatrick         return nullptr;
635061da546Spatrick       CompilerType arg_ast_type = arg_type->GetFullCompilerType();
636061da546Spatrick       arg_list.push_back(arg_ast_type);
637061da546Spatrick     }
638061da546Spatrick     lldbassert(arg_list.size() <= num_args);
639061da546Spatrick 
640061da546Spatrick     auto pdb_return_type = func_sig->getReturnType();
641be691f3bSpatrick     SymbolFile *symbol_file = m_ast.GetSymbolFile();
642be691f3bSpatrick     if (!symbol_file)
643be691f3bSpatrick       return nullptr;
644be691f3bSpatrick 
645061da546Spatrick     lldb_private::Type *return_type =
646be691f3bSpatrick         symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId());
647061da546Spatrick     // If there's some error looking up one of the dependent types of this
648061da546Spatrick     // function signature, bail.
649061da546Spatrick     if (!return_type)
650061da546Spatrick       return nullptr;
651061da546Spatrick     CompilerType return_ast_type = return_type->GetFullCompilerType();
652061da546Spatrick     uint32_t type_quals = 0;
653061da546Spatrick     if (func_sig->isConstType())
654061da546Spatrick       type_quals |= clang::Qualifiers::Const;
655061da546Spatrick     if (func_sig->isVolatileType())
656061da546Spatrick       type_quals |= clang::Qualifiers::Volatile;
657061da546Spatrick     auto cc = TranslateCallingConvention(func_sig->getCallingConvention());
658061da546Spatrick     CompilerType func_sig_ast_type =
659061da546Spatrick         m_ast.CreateFunctionType(return_ast_type, arg_list.data(),
660061da546Spatrick                                  arg_list.size(), is_variadic, type_quals, cc);
661061da546Spatrick 
662061da546Spatrick     GetDeclarationForSymbol(type, decl);
663*f6aab3d8Srobert     return m_ast.GetSymbolFile()->MakeType(
664*f6aab3d8Srobert         type.getSymIndexId(), ConstString(name), std::nullopt, nullptr,
665*f6aab3d8Srobert         LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
666*f6aab3d8Srobert         func_sig_ast_type, lldb_private::Type::ResolveState::Full);
667061da546Spatrick   } break;
668061da546Spatrick   case PDB_SymType::ArrayType: {
669061da546Spatrick     auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type);
670061da546Spatrick     assert(array_type);
671061da546Spatrick     uint32_t num_elements = array_type->getCount();
672061da546Spatrick     uint32_t element_uid = array_type->getElementTypeId();
673*f6aab3d8Srobert     std::optional<uint64_t> bytes;
674061da546Spatrick     if (uint64_t size = array_type->getLength())
675061da546Spatrick       bytes = size;
676061da546Spatrick 
677be691f3bSpatrick     SymbolFile *symbol_file = m_ast.GetSymbolFile();
678be691f3bSpatrick     if (!symbol_file)
679be691f3bSpatrick       return nullptr;
680be691f3bSpatrick 
681061da546Spatrick     // If array rank > 0, PDB gives the element type at N=0. So element type
682061da546Spatrick     // will parsed in the order N=0, N=1,..., N=rank sequentially.
683be691f3bSpatrick     lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid);
684061da546Spatrick     if (!element_type)
685061da546Spatrick       return nullptr;
686061da546Spatrick 
687061da546Spatrick     CompilerType element_ast_type = element_type->GetForwardCompilerType();
688061da546Spatrick     // If element type is UDT, it needs to be complete.
689dda28197Spatrick     if (TypeSystemClang::IsCXXClassType(element_ast_type) &&
690061da546Spatrick         !element_ast_type.GetCompleteType()) {
691dda28197Spatrick       if (TypeSystemClang::StartTagDeclarationDefinition(element_ast_type)) {
692dda28197Spatrick         TypeSystemClang::CompleteTagDeclarationDefinition(element_ast_type);
693061da546Spatrick       } else {
694*f6aab3d8Srobert         // We are not able to start definition.
695061da546Spatrick         return nullptr;
696061da546Spatrick       }
697061da546Spatrick     }
698061da546Spatrick     CompilerType array_ast_type = m_ast.CreateArrayType(
699061da546Spatrick         element_ast_type, num_elements, /*is_gnu_vector*/ false);
700*f6aab3d8Srobert     TypeSP type_sp = m_ast.GetSymbolFile()->MakeType(
701*f6aab3d8Srobert         array_type->getSymIndexId(), ConstString(), bytes, nullptr,
702*f6aab3d8Srobert         LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
703*f6aab3d8Srobert         array_ast_type, lldb_private::Type::ResolveState::Full);
704061da546Spatrick     type_sp->SetEncodingType(element_type);
705061da546Spatrick     return type_sp;
706061da546Spatrick   } break;
707061da546Spatrick   case PDB_SymType::BuiltinType: {
708061da546Spatrick     auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type);
709061da546Spatrick     assert(builtin_type);
710061da546Spatrick     PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType();
711061da546Spatrick     if (builtin_kind == PDB_BuiltinType::None)
712061da546Spatrick       return nullptr;
713061da546Spatrick 
714*f6aab3d8Srobert     std::optional<uint64_t> bytes;
715061da546Spatrick     if (uint64_t size = builtin_type->getLength())
716061da546Spatrick       bytes = size;
717061da546Spatrick     Encoding encoding = TranslateBuiltinEncoding(builtin_kind);
718061da546Spatrick     CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize(
719*f6aab3d8Srobert         m_ast, *builtin_type, encoding, bytes.value_or(0) * 8);
720061da546Spatrick 
721061da546Spatrick     if (builtin_type->isConstType())
722061da546Spatrick       builtin_ast_type = builtin_ast_type.AddConstModifier();
723061da546Spatrick 
724061da546Spatrick     if (builtin_type->isVolatileType())
725061da546Spatrick       builtin_ast_type = builtin_ast_type.AddVolatileModifier();
726061da546Spatrick 
727061da546Spatrick     auto type_name = GetPDBBuiltinTypeName(*builtin_type, builtin_ast_type);
728061da546Spatrick 
729*f6aab3d8Srobert     return m_ast.GetSymbolFile()->MakeType(
730*f6aab3d8Srobert         builtin_type->getSymIndexId(), type_name, bytes, nullptr,
731*f6aab3d8Srobert         LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
732061da546Spatrick         builtin_ast_type, lldb_private::Type::ResolveState::Full);
733061da546Spatrick   } break;
734061da546Spatrick   case PDB_SymType::PointerType: {
735061da546Spatrick     auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
736061da546Spatrick     assert(pointer_type);
737be691f3bSpatrick 
738be691f3bSpatrick     SymbolFile *symbol_file = m_ast.GetSymbolFile();
739be691f3bSpatrick     if (!symbol_file)
740be691f3bSpatrick       return nullptr;
741be691f3bSpatrick 
742be691f3bSpatrick     Type *pointee_type = symbol_file->ResolveTypeUID(
743061da546Spatrick         pointer_type->getPointeeType()->getSymIndexId());
744061da546Spatrick     if (!pointee_type)
745061da546Spatrick       return nullptr;
746061da546Spatrick 
747061da546Spatrick     if (pointer_type->isPointerToDataMember() ||
748061da546Spatrick         pointer_type->isPointerToMemberFunction()) {
749061da546Spatrick       auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();
750be691f3bSpatrick       auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid);
751061da546Spatrick       assert(class_parent_type);
752061da546Spatrick 
753061da546Spatrick       CompilerType pointer_ast_type;
754dda28197Spatrick       pointer_ast_type = TypeSystemClang::CreateMemberPointerType(
755061da546Spatrick           class_parent_type->GetLayoutCompilerType(),
756061da546Spatrick           pointee_type->GetForwardCompilerType());
757061da546Spatrick       assert(pointer_ast_type);
758061da546Spatrick 
759*f6aab3d8Srobert       return m_ast.GetSymbolFile()->MakeType(
760*f6aab3d8Srobert           pointer_type->getSymIndexId(), ConstString(),
761061da546Spatrick           pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
762061da546Spatrick           lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
763061da546Spatrick           lldb_private::Type::ResolveState::Forward);
764061da546Spatrick     }
765061da546Spatrick 
766061da546Spatrick     CompilerType pointer_ast_type;
767061da546Spatrick     pointer_ast_type = pointee_type->GetFullCompilerType();
768061da546Spatrick     if (pointer_type->isReference())
769061da546Spatrick       pointer_ast_type = pointer_ast_type.GetLValueReferenceType();
770061da546Spatrick     else if (pointer_type->isRValueReference())
771061da546Spatrick       pointer_ast_type = pointer_ast_type.GetRValueReferenceType();
772061da546Spatrick     else
773061da546Spatrick       pointer_ast_type = pointer_ast_type.GetPointerType();
774061da546Spatrick 
775061da546Spatrick     if (pointer_type->isConstType())
776061da546Spatrick       pointer_ast_type = pointer_ast_type.AddConstModifier();
777061da546Spatrick 
778061da546Spatrick     if (pointer_type->isVolatileType())
779061da546Spatrick       pointer_ast_type = pointer_ast_type.AddVolatileModifier();
780061da546Spatrick 
781061da546Spatrick     if (pointer_type->isRestrictedType())
782061da546Spatrick       pointer_ast_type = pointer_ast_type.AddRestrictModifier();
783061da546Spatrick 
784*f6aab3d8Srobert     return m_ast.GetSymbolFile()->MakeType(
785*f6aab3d8Srobert         pointer_type->getSymIndexId(), ConstString(), pointer_type->getLength(),
786*f6aab3d8Srobert         nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
787*f6aab3d8Srobert         pointer_ast_type, lldb_private::Type::ResolveState::Full);
788061da546Spatrick   } break;
789061da546Spatrick   default:
790061da546Spatrick     break;
791061da546Spatrick   }
792061da546Spatrick   return nullptr;
793061da546Spatrick }
794061da546Spatrick 
CompleteTypeFromPDB(lldb_private::CompilerType & compiler_type)795061da546Spatrick bool PDBASTParser::CompleteTypeFromPDB(
796061da546Spatrick     lldb_private::CompilerType &compiler_type) {
797061da546Spatrick   if (GetClangASTImporter().CanImport(compiler_type))
798061da546Spatrick     return GetClangASTImporter().CompleteType(compiler_type);
799061da546Spatrick 
800061da546Spatrick   // Remove the type from the forward declarations to avoid
801061da546Spatrick   // an endless recursion for types like a linked list.
802061da546Spatrick   clang::CXXRecordDecl *record_decl =
803061da546Spatrick       m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
804061da546Spatrick   auto uid_it = m_forward_decl_to_uid.find(record_decl);
805061da546Spatrick   if (uid_it == m_forward_decl_to_uid.end())
806061da546Spatrick     return true;
807061da546Spatrick 
808*f6aab3d8Srobert   auto symbol_file = static_cast<SymbolFilePDB *>(
809*f6aab3d8Srobert       m_ast.GetSymbolFile()->GetBackingSymbolFile());
810061da546Spatrick   if (!symbol_file)
811061da546Spatrick     return false;
812061da546Spatrick 
813061da546Spatrick   std::unique_ptr<PDBSymbol> symbol =
814061da546Spatrick       symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond());
815061da546Spatrick   if (!symbol)
816061da546Spatrick     return false;
817061da546Spatrick 
818061da546Spatrick   m_forward_decl_to_uid.erase(uid_it);
819061da546Spatrick 
820dda28197Spatrick   TypeSystemClang::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
821061da546Spatrick                                          false);
822061da546Spatrick 
823061da546Spatrick   switch (symbol->getSymTag()) {
824061da546Spatrick   case PDB_SymType::UDT: {
825061da546Spatrick     auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get());
826061da546Spatrick     if (!udt)
827061da546Spatrick       return false;
828061da546Spatrick 
829061da546Spatrick     return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt);
830061da546Spatrick   }
831061da546Spatrick   default:
832061da546Spatrick     llvm_unreachable("not a forward clang type decl!");
833061da546Spatrick   }
834061da546Spatrick }
835061da546Spatrick 
836061da546Spatrick clang::Decl *
GetDeclForSymbol(const llvm::pdb::PDBSymbol & symbol)837061da546Spatrick PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
838061da546Spatrick   uint32_t sym_id = symbol.getSymIndexId();
839061da546Spatrick   auto it = m_uid_to_decl.find(sym_id);
840061da546Spatrick   if (it != m_uid_to_decl.end())
841061da546Spatrick     return it->second;
842061da546Spatrick 
843*f6aab3d8Srobert   auto symbol_file = static_cast<SymbolFilePDB *>(
844*f6aab3d8Srobert       m_ast.GetSymbolFile()->GetBackingSymbolFile());
845061da546Spatrick   if (!symbol_file)
846061da546Spatrick     return nullptr;
847061da546Spatrick 
848061da546Spatrick   // First of all, check if the symbol is a member of a class. Resolve the full
849061da546Spatrick   // class type and return the declaration from the cache if so.
850061da546Spatrick   auto tag = symbol.getSymTag();
851061da546Spatrick   if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) {
852061da546Spatrick     const IPDBSession &session = symbol.getSession();
853061da546Spatrick     const IPDBRawSymbol &raw = symbol.getRawSymbol();
854061da546Spatrick 
855061da546Spatrick     auto class_parent_id = raw.getClassParentId();
856061da546Spatrick     if (std::unique_ptr<PDBSymbol> class_parent =
857061da546Spatrick             session.getSymbolById(class_parent_id)) {
858061da546Spatrick       auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id);
859061da546Spatrick       if (!class_parent_type)
860061da546Spatrick         return nullptr;
861061da546Spatrick 
862061da546Spatrick       CompilerType class_parent_ct = class_parent_type->GetFullCompilerType();
863061da546Spatrick 
864061da546Spatrick       // Look a declaration up in the cache after completing the class
865061da546Spatrick       clang::Decl *decl = m_uid_to_decl.lookup(sym_id);
866061da546Spatrick       if (decl)
867061da546Spatrick         return decl;
868061da546Spatrick 
869061da546Spatrick       // A declaration was not found in the cache. It means that the symbol
870061da546Spatrick       // has the class parent, but the class doesn't have the symbol in its
871061da546Spatrick       // children list.
872061da546Spatrick       if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) {
873061da546Spatrick         // Try to find a class child method with the same RVA and use its
874061da546Spatrick         // declaration if found.
875061da546Spatrick         if (uint32_t rva = func->getRelativeVirtualAddress()) {
876061da546Spatrick           if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>>
877061da546Spatrick                   methods_enum =
878061da546Spatrick                       class_parent->findAllChildren<PDBSymbolFunc>()) {
879061da546Spatrick             while (std::unique_ptr<PDBSymbolFunc> method =
880061da546Spatrick                        methods_enum->getNext()) {
881061da546Spatrick               if (method->getRelativeVirtualAddress() == rva) {
882061da546Spatrick                 decl = m_uid_to_decl.lookup(method->getSymIndexId());
883061da546Spatrick                 if (decl)
884061da546Spatrick                   break;
885061da546Spatrick               }
886061da546Spatrick             }
887061da546Spatrick           }
888061da546Spatrick         }
889061da546Spatrick 
890061da546Spatrick         // If no class methods with the same RVA were found, then create a new
891061da546Spatrick         // method. It is possible for template methods.
892061da546Spatrick         if (!decl)
893061da546Spatrick           decl = AddRecordMethod(*symbol_file, class_parent_ct, *func);
894061da546Spatrick       }
895061da546Spatrick 
896061da546Spatrick       if (decl)
897061da546Spatrick         m_uid_to_decl[sym_id] = decl;
898061da546Spatrick 
899061da546Spatrick       return decl;
900061da546Spatrick     }
901061da546Spatrick   }
902061da546Spatrick 
903061da546Spatrick   // If we are here, then the symbol is not belonging to a class and is not
904061da546Spatrick   // contained in the cache. So create a declaration for it.
905061da546Spatrick   switch (symbol.getSymTag()) {
906061da546Spatrick   case PDB_SymType::Data: {
907061da546Spatrick     auto data = llvm::dyn_cast<PDBSymbolData>(&symbol);
908061da546Spatrick     assert(data);
909061da546Spatrick 
910061da546Spatrick     auto decl_context = GetDeclContextContainingSymbol(symbol);
911061da546Spatrick     assert(decl_context);
912061da546Spatrick 
913061da546Spatrick     // May be the current context is a class really, but we haven't found
914061da546Spatrick     // any class parent. This happens e.g. in the case of class static
915061da546Spatrick     // variables - they has two symbols, one is a child of the class when
916061da546Spatrick     // another is a child of the exe. So always complete the parent and use
917061da546Spatrick     // an existing declaration if possible.
918061da546Spatrick     if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context))
919061da546Spatrick       m_ast.GetCompleteDecl(parent_decl);
920061da546Spatrick 
921dda28197Spatrick     std::string name =
922dda28197Spatrick         std::string(MSVCUndecoratedNameParser::DropScope(data->getName()));
923061da546Spatrick 
924061da546Spatrick     // Check if the current context already contains the symbol with the name.
925061da546Spatrick     clang::Decl *decl =
926061da546Spatrick         GetDeclFromContextByName(m_ast.getASTContext(), *decl_context, name);
927061da546Spatrick     if (!decl) {
928061da546Spatrick       auto type = symbol_file->ResolveTypeUID(data->getTypeId());
929061da546Spatrick       if (!type)
930061da546Spatrick         return nullptr;
931061da546Spatrick 
932061da546Spatrick       decl = m_ast.CreateVariableDeclaration(
933dda28197Spatrick           decl_context, OptionalClangModuleID(), name.c_str(),
934061da546Spatrick           ClangUtil::GetQualType(type->GetLayoutCompilerType()));
935061da546Spatrick     }
936061da546Spatrick 
937061da546Spatrick     m_uid_to_decl[sym_id] = decl;
938061da546Spatrick 
939061da546Spatrick     return decl;
940061da546Spatrick   }
941061da546Spatrick   case PDB_SymType::Function: {
942061da546Spatrick     auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol);
943061da546Spatrick     assert(func);
944061da546Spatrick 
945061da546Spatrick     auto decl_context = GetDeclContextContainingSymbol(symbol);
946061da546Spatrick     assert(decl_context);
947061da546Spatrick 
948dda28197Spatrick     std::string name =
949dda28197Spatrick         std::string(MSVCUndecoratedNameParser::DropScope(func->getName()));
950061da546Spatrick 
951061da546Spatrick     Type *type = symbol_file->ResolveTypeUID(sym_id);
952061da546Spatrick     if (!type)
953061da546Spatrick       return nullptr;
954061da546Spatrick 
955061da546Spatrick     auto storage = func->isStatic() ? clang::StorageClass::SC_Static
956061da546Spatrick                                     : clang::StorageClass::SC_None;
957061da546Spatrick 
958061da546Spatrick     auto decl = m_ast.CreateFunctionDeclaration(
959be691f3bSpatrick         decl_context, OptionalClangModuleID(), name,
960dda28197Spatrick         type->GetForwardCompilerType(), storage, func->hasInlineAttribute());
961061da546Spatrick 
962061da546Spatrick     std::vector<clang::ParmVarDecl *> params;
963061da546Spatrick     if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
964061da546Spatrick       if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>>
965061da546Spatrick               arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) {
966061da546Spatrick         while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg =
967061da546Spatrick                    arg_enum->getNext()) {
968061da546Spatrick           Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId());
969061da546Spatrick           if (!arg_type)
970061da546Spatrick             continue;
971061da546Spatrick 
972061da546Spatrick           clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
973dda28197Spatrick               decl, OptionalClangModuleID(), nullptr,
974dda28197Spatrick               arg_type->GetForwardCompilerType(), clang::SC_None, true);
975061da546Spatrick           if (param)
976061da546Spatrick             params.push_back(param);
977061da546Spatrick         }
978061da546Spatrick       }
979061da546Spatrick     }
980061da546Spatrick     if (params.size())
981be691f3bSpatrick       m_ast.SetFunctionParameters(decl, params);
982061da546Spatrick 
983061da546Spatrick     m_uid_to_decl[sym_id] = decl;
984061da546Spatrick 
985061da546Spatrick     return decl;
986061da546Spatrick   }
987061da546Spatrick   default: {
988061da546Spatrick     // It's not a variable and not a function, check if it's a type
989061da546Spatrick     Type *type = symbol_file->ResolveTypeUID(sym_id);
990061da546Spatrick     if (!type)
991061da546Spatrick       return nullptr;
992061da546Spatrick 
993061da546Spatrick     return m_uid_to_decl.lookup(sym_id);
994061da546Spatrick   }
995061da546Spatrick   }
996061da546Spatrick }
997061da546Spatrick 
998061da546Spatrick clang::DeclContext *
GetDeclContextForSymbol(const llvm::pdb::PDBSymbol & symbol)999061da546Spatrick PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) {
1000061da546Spatrick   if (symbol.getSymTag() == PDB_SymType::Function) {
1001061da546Spatrick     clang::DeclContext *result =
1002061da546Spatrick         llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol));
1003061da546Spatrick 
1004061da546Spatrick     if (result)
1005061da546Spatrick       m_decl_context_to_uid[result] = symbol.getSymIndexId();
1006061da546Spatrick 
1007061da546Spatrick     return result;
1008061da546Spatrick   }
1009061da546Spatrick 
1010*f6aab3d8Srobert   auto symbol_file = static_cast<SymbolFilePDB *>(
1011*f6aab3d8Srobert       m_ast.GetSymbolFile()->GetBackingSymbolFile());
1012061da546Spatrick   if (!symbol_file)
1013061da546Spatrick     return nullptr;
1014061da546Spatrick 
1015061da546Spatrick   auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId());
1016061da546Spatrick   if (!type)
1017061da546Spatrick     return nullptr;
1018061da546Spatrick 
1019061da546Spatrick   clang::DeclContext *result =
1020061da546Spatrick       m_ast.GetDeclContextForType(type->GetForwardCompilerType());
1021061da546Spatrick 
1022061da546Spatrick   if (result)
1023061da546Spatrick     m_decl_context_to_uid[result] = symbol.getSymIndexId();
1024061da546Spatrick 
1025061da546Spatrick   return result;
1026061da546Spatrick }
1027061da546Spatrick 
GetDeclContextContainingSymbol(const llvm::pdb::PDBSymbol & symbol)1028061da546Spatrick clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
1029061da546Spatrick     const llvm::pdb::PDBSymbol &symbol) {
1030061da546Spatrick   auto parent = GetClassOrFunctionParent(symbol);
1031061da546Spatrick   while (parent) {
1032061da546Spatrick     if (auto parent_context = GetDeclContextForSymbol(*parent))
1033061da546Spatrick       return parent_context;
1034061da546Spatrick 
1035061da546Spatrick     parent = GetClassOrFunctionParent(*parent);
1036061da546Spatrick   }
1037061da546Spatrick 
1038061da546Spatrick   // We can't find any class or function parent of the symbol. So analyze
1039061da546Spatrick   // the full symbol name. The symbol may be belonging to a namespace
1040061da546Spatrick   // or function (or even to a class if it's e.g. a static variable symbol).
1041061da546Spatrick 
1042061da546Spatrick   // TODO: Make clang to emit full names for variables in namespaces
1043061da546Spatrick   // (as MSVC does)
1044061da546Spatrick 
1045061da546Spatrick   std::string name(symbol.getRawSymbol().getName());
1046061da546Spatrick   MSVCUndecoratedNameParser parser(name);
1047061da546Spatrick   llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
1048061da546Spatrick   if (specs.empty())
1049061da546Spatrick     return m_ast.GetTranslationUnitDecl();
1050061da546Spatrick 
1051*f6aab3d8Srobert   auto symbol_file = static_cast<SymbolFilePDB *>(
1052*f6aab3d8Srobert       m_ast.GetSymbolFile()->GetBackingSymbolFile());
1053061da546Spatrick   if (!symbol_file)
1054061da546Spatrick     return m_ast.GetTranslationUnitDecl();
1055061da546Spatrick 
1056061da546Spatrick   auto global = symbol_file->GetPDBSession().getGlobalScope();
1057061da546Spatrick   if (!global)
1058061da546Spatrick     return m_ast.GetTranslationUnitDecl();
1059061da546Spatrick 
1060061da546Spatrick   bool has_type_or_function_parent = false;
1061061da546Spatrick   clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl();
1062061da546Spatrick   for (std::size_t i = 0; i < specs.size() - 1; i++) {
1063061da546Spatrick     // Check if there is a function or a type with the current context's name.
1064061da546Spatrick     if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren(
1065061da546Spatrick             PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) {
1066061da546Spatrick       while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child =
1067061da546Spatrick                  children_enum->getNext()) {
1068061da546Spatrick         if (clang::DeclContext *child_context =
1069061da546Spatrick                 GetDeclContextForSymbol(*child)) {
1070061da546Spatrick           // Note that `GetDeclContextForSymbol' retrieves
1071061da546Spatrick           // a declaration context for functions and types only,
1072061da546Spatrick           // so if we are here then `child_context' is guaranteed
1073061da546Spatrick           // a function or a type declaration context.
1074061da546Spatrick           has_type_or_function_parent = true;
1075061da546Spatrick           curr_context = child_context;
1076061da546Spatrick         }
1077061da546Spatrick       }
1078061da546Spatrick     }
1079061da546Spatrick 
1080061da546Spatrick     // If there were no functions or types above then retrieve a namespace with
1081061da546Spatrick     // the current context's name. There can be no namespaces inside a function
1082061da546Spatrick     // or a type. We check it to avoid fake namespaces such as `__l2':
1083061da546Spatrick     // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct'
1084061da546Spatrick     if (!has_type_or_function_parent) {
1085dda28197Spatrick       std::string namespace_name = std::string(specs[i].GetBaseName());
1086061da546Spatrick       const char *namespace_name_c_str =
1087061da546Spatrick           IsAnonymousNamespaceName(namespace_name) ? nullptr
1088061da546Spatrick                                                    : namespace_name.data();
1089061da546Spatrick       clang::NamespaceDecl *namespace_decl =
1090dda28197Spatrick           m_ast.GetUniqueNamespaceDeclaration(
1091dda28197Spatrick               namespace_name_c_str, curr_context, OptionalClangModuleID());
1092061da546Spatrick 
1093061da546Spatrick       m_parent_to_namespaces[curr_context].insert(namespace_decl);
1094061da546Spatrick       m_namespaces.insert(namespace_decl);
1095061da546Spatrick 
1096061da546Spatrick       curr_context = namespace_decl;
1097061da546Spatrick     }
1098061da546Spatrick   }
1099061da546Spatrick 
1100061da546Spatrick   return curr_context;
1101061da546Spatrick }
1102061da546Spatrick 
ParseDeclsForDeclContext(const clang::DeclContext * decl_context)1103061da546Spatrick void PDBASTParser::ParseDeclsForDeclContext(
1104061da546Spatrick     const clang::DeclContext *decl_context) {
1105*f6aab3d8Srobert   auto symbol_file = static_cast<SymbolFilePDB *>(
1106*f6aab3d8Srobert       m_ast.GetSymbolFile()->GetBackingSymbolFile());
1107061da546Spatrick   if (!symbol_file)
1108061da546Spatrick     return;
1109061da546Spatrick 
1110061da546Spatrick   IPDBSession &session = symbol_file->GetPDBSession();
1111061da546Spatrick   auto symbol_up =
1112061da546Spatrick       session.getSymbolById(m_decl_context_to_uid.lookup(decl_context));
1113061da546Spatrick   auto global_up = session.getGlobalScope();
1114061da546Spatrick 
1115061da546Spatrick   PDBSymbol *symbol;
1116061da546Spatrick   if (symbol_up)
1117061da546Spatrick     symbol = symbol_up.get();
1118061da546Spatrick   else if (global_up)
1119061da546Spatrick     symbol = global_up.get();
1120061da546Spatrick   else
1121061da546Spatrick     return;
1122061da546Spatrick 
1123061da546Spatrick   if (auto children = symbol->findAllChildren())
1124061da546Spatrick     while (auto child = children->getNext())
1125061da546Spatrick       GetDeclForSymbol(*child);
1126061da546Spatrick }
1127061da546Spatrick 
1128061da546Spatrick clang::NamespaceDecl *
FindNamespaceDecl(const clang::DeclContext * parent,llvm::StringRef name)1129061da546Spatrick PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent,
1130061da546Spatrick                                 llvm::StringRef name) {
1131061da546Spatrick   NamespacesSet *set;
1132061da546Spatrick   if (parent) {
1133061da546Spatrick     auto pit = m_parent_to_namespaces.find(parent);
1134061da546Spatrick     if (pit == m_parent_to_namespaces.end())
1135061da546Spatrick       return nullptr;
1136061da546Spatrick 
1137061da546Spatrick     set = &pit->second;
1138061da546Spatrick   } else {
1139061da546Spatrick     set = &m_namespaces;
1140061da546Spatrick   }
1141061da546Spatrick   assert(set);
1142061da546Spatrick 
1143061da546Spatrick   for (clang::NamespaceDecl *namespace_decl : *set)
1144061da546Spatrick     if (namespace_decl->getName().equals(name))
1145061da546Spatrick       return namespace_decl;
1146061da546Spatrick 
1147061da546Spatrick   for (clang::NamespaceDecl *namespace_decl : *set)
1148061da546Spatrick     if (namespace_decl->isAnonymousNamespace())
1149061da546Spatrick       return FindNamespaceDecl(namespace_decl, name);
1150061da546Spatrick 
1151061da546Spatrick   return nullptr;
1152061da546Spatrick }
1153061da546Spatrick 
AddEnumValue(CompilerType enum_type,const PDBSymbolData & enum_value)1154061da546Spatrick bool PDBASTParser::AddEnumValue(CompilerType enum_type,
1155061da546Spatrick                                 const PDBSymbolData &enum_value) {
1156061da546Spatrick   Declaration decl;
1157061da546Spatrick   Variant v = enum_value.getValue();
1158dda28197Spatrick   std::string name =
1159dda28197Spatrick       std::string(MSVCUndecoratedNameParser::DropScope(enum_value.getName()));
1160061da546Spatrick   int64_t raw_value;
1161061da546Spatrick   switch (v.Type) {
1162061da546Spatrick   case PDB_VariantType::Int8:
1163061da546Spatrick     raw_value = v.Value.Int8;
1164061da546Spatrick     break;
1165061da546Spatrick   case PDB_VariantType::Int16:
1166061da546Spatrick     raw_value = v.Value.Int16;
1167061da546Spatrick     break;
1168061da546Spatrick   case PDB_VariantType::Int32:
1169061da546Spatrick     raw_value = v.Value.Int32;
1170061da546Spatrick     break;
1171061da546Spatrick   case PDB_VariantType::Int64:
1172061da546Spatrick     raw_value = v.Value.Int64;
1173061da546Spatrick     break;
1174061da546Spatrick   case PDB_VariantType::UInt8:
1175061da546Spatrick     raw_value = v.Value.UInt8;
1176061da546Spatrick     break;
1177061da546Spatrick   case PDB_VariantType::UInt16:
1178061da546Spatrick     raw_value = v.Value.UInt16;
1179061da546Spatrick     break;
1180061da546Spatrick   case PDB_VariantType::UInt32:
1181061da546Spatrick     raw_value = v.Value.UInt32;
1182061da546Spatrick     break;
1183061da546Spatrick   case PDB_VariantType::UInt64:
1184061da546Spatrick     raw_value = v.Value.UInt64;
1185061da546Spatrick     break;
1186061da546Spatrick   default:
1187061da546Spatrick     return false;
1188061da546Spatrick   }
1189dda28197Spatrick   CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type);
1190061da546Spatrick   uint32_t byte_size = m_ast.getASTContext().getTypeSize(
1191061da546Spatrick       ClangUtil::GetQualType(underlying_type));
1192061da546Spatrick   auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(
1193061da546Spatrick       enum_type, decl, name.c_str(), raw_value, byte_size * 8);
1194061da546Spatrick   if (!enum_constant_decl)
1195061da546Spatrick     return false;
1196061da546Spatrick 
1197061da546Spatrick   m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl;
1198061da546Spatrick 
1199061da546Spatrick   return true;
1200061da546Spatrick }
1201061da546Spatrick 
CompleteTypeFromUDT(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & compiler_type,llvm::pdb::PDBSymbolTypeUDT & udt)1202061da546Spatrick bool PDBASTParser::CompleteTypeFromUDT(
1203061da546Spatrick     lldb_private::SymbolFile &symbol_file,
1204061da546Spatrick     lldb_private::CompilerType &compiler_type,
1205061da546Spatrick     llvm::pdb::PDBSymbolTypeUDT &udt) {
1206061da546Spatrick   ClangASTImporter::LayoutInfo layout_info;
1207061da546Spatrick   layout_info.bit_size = udt.getLength() * 8;
1208061da546Spatrick 
1209061da546Spatrick   auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>();
1210061da546Spatrick   if (nested_enums)
1211061da546Spatrick     while (auto nested = nested_enums->getNext())
1212061da546Spatrick       symbol_file.ResolveTypeUID(nested->getSymIndexId());
1213061da546Spatrick 
1214061da546Spatrick   auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
1215061da546Spatrick   if (bases_enum)
1216061da546Spatrick     AddRecordBases(symbol_file, compiler_type,
1217061da546Spatrick                    TranslateUdtKind(udt.getUdtKind()), *bases_enum,
1218061da546Spatrick                    layout_info);
1219061da546Spatrick 
1220061da546Spatrick   auto members_enum = udt.findAllChildren<PDBSymbolData>();
1221061da546Spatrick   if (members_enum)
1222061da546Spatrick     AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info);
1223061da546Spatrick 
1224061da546Spatrick   auto methods_enum = udt.findAllChildren<PDBSymbolFunc>();
1225061da546Spatrick   if (methods_enum)
1226061da546Spatrick     AddRecordMethods(symbol_file, compiler_type, *methods_enum);
1227061da546Spatrick 
1228061da546Spatrick   m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType());
1229dda28197Spatrick   TypeSystemClang::BuildIndirectFields(compiler_type);
1230dda28197Spatrick   TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type);
1231061da546Spatrick 
1232061da546Spatrick   clang::CXXRecordDecl *record_decl =
1233061da546Spatrick       m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
1234061da546Spatrick   if (!record_decl)
1235061da546Spatrick     return static_cast<bool>(compiler_type);
1236061da546Spatrick 
1237061da546Spatrick   GetClangASTImporter().SetRecordLayout(record_decl, layout_info);
1238061da546Spatrick 
1239061da546Spatrick   return static_cast<bool>(compiler_type);
1240061da546Spatrick }
1241061da546Spatrick 
AddRecordMembers(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,PDBDataSymbolEnumerator & members_enum,lldb_private::ClangASTImporter::LayoutInfo & layout_info)1242061da546Spatrick void PDBASTParser::AddRecordMembers(
1243061da546Spatrick     lldb_private::SymbolFile &symbol_file,
1244061da546Spatrick     lldb_private::CompilerType &record_type,
1245061da546Spatrick     PDBDataSymbolEnumerator &members_enum,
1246061da546Spatrick     lldb_private::ClangASTImporter::LayoutInfo &layout_info) {
1247061da546Spatrick   while (auto member = members_enum.getNext()) {
1248061da546Spatrick     if (member->isCompilerGenerated())
1249061da546Spatrick       continue;
1250061da546Spatrick 
1251061da546Spatrick     auto member_name = member->getName();
1252061da546Spatrick 
1253061da546Spatrick     auto member_type = symbol_file.ResolveTypeUID(member->getTypeId());
1254061da546Spatrick     if (!member_type)
1255061da546Spatrick       continue;
1256061da546Spatrick 
1257061da546Spatrick     auto member_comp_type = member_type->GetLayoutCompilerType();
1258061da546Spatrick     if (!member_comp_type.GetCompleteType()) {
1259061da546Spatrick       symbol_file.GetObjectFile()->GetModule()->ReportError(
1260*f6aab3d8Srobert           ":: Class '{0}' has a member '{1}' of type '{2}' "
1261061da546Spatrick           "which does not have a complete definition.",
1262061da546Spatrick           record_type.GetTypeName().GetCString(), member_name.c_str(),
1263061da546Spatrick           member_comp_type.GetTypeName().GetCString());
1264dda28197Spatrick       if (TypeSystemClang::StartTagDeclarationDefinition(member_comp_type))
1265dda28197Spatrick         TypeSystemClang::CompleteTagDeclarationDefinition(member_comp_type);
1266061da546Spatrick     }
1267061da546Spatrick 
1268061da546Spatrick     auto access = TranslateMemberAccess(member->getAccess());
1269061da546Spatrick 
1270061da546Spatrick     switch (member->getDataKind()) {
1271061da546Spatrick     case PDB_DataKind::Member: {
1272061da546Spatrick       auto location_type = member->getLocationType();
1273061da546Spatrick 
1274061da546Spatrick       auto bit_size = member->getLength();
1275061da546Spatrick       if (location_type == PDB_LocType::ThisRel)
1276061da546Spatrick         bit_size *= 8;
1277061da546Spatrick 
1278dda28197Spatrick       auto decl = TypeSystemClang::AddFieldToRecordType(
1279061da546Spatrick           record_type, member_name.c_str(), member_comp_type, access, bit_size);
1280061da546Spatrick       if (!decl)
1281061da546Spatrick         continue;
1282061da546Spatrick 
1283061da546Spatrick       m_uid_to_decl[member->getSymIndexId()] = decl;
1284061da546Spatrick 
1285061da546Spatrick       auto offset = member->getOffset() * 8;
1286061da546Spatrick       if (location_type == PDB_LocType::BitField)
1287061da546Spatrick         offset += member->getBitPosition();
1288061da546Spatrick 
1289061da546Spatrick       layout_info.field_offsets.insert(std::make_pair(decl, offset));
1290061da546Spatrick 
1291061da546Spatrick       break;
1292061da546Spatrick     }
1293061da546Spatrick     case PDB_DataKind::StaticMember: {
1294dda28197Spatrick       auto decl = TypeSystemClang::AddVariableToRecordType(
1295061da546Spatrick           record_type, member_name.c_str(), member_comp_type, access);
1296061da546Spatrick       if (!decl)
1297061da546Spatrick         continue;
1298061da546Spatrick 
1299dda28197Spatrick       // Static constant members may be a const[expr] declaration.
1300dda28197Spatrick       // Query the symbol's value as the variable initializer if valid.
1301dda28197Spatrick       if (member_comp_type.IsConst()) {
1302dda28197Spatrick         auto value = member->getValue();
1303dda28197Spatrick         clang::QualType qual_type = decl->getType();
1304dda28197Spatrick         unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type);
1305dda28197Spatrick         unsigned constant_width = value.getBitWidth();
1306dda28197Spatrick 
1307dda28197Spatrick         if (qual_type->isIntegralOrEnumerationType()) {
1308dda28197Spatrick           if (type_width >= constant_width) {
1309dda28197Spatrick             TypeSystemClang::SetIntegerInitializerForVariable(
1310dda28197Spatrick                 decl, value.toAPSInt().extOrTrunc(type_width));
1311dda28197Spatrick           } else {
1312*f6aab3d8Srobert             LLDB_LOG(GetLog(LLDBLog::AST),
1313dda28197Spatrick                      "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) "
1314dda28197Spatrick                      "which resolves to a wider constant value ({4} bits). "
1315dda28197Spatrick                      "Ignoring constant.",
1316dda28197Spatrick                      record_type.GetTypeName(), member_name,
1317dda28197Spatrick                      member_comp_type.GetTypeName(), type_width,
1318dda28197Spatrick                      constant_width);
1319dda28197Spatrick           }
1320dda28197Spatrick         } else {
1321dda28197Spatrick           switch (member_comp_type.GetBasicTypeEnumeration()) {
1322dda28197Spatrick           case lldb::eBasicTypeFloat:
1323dda28197Spatrick           case lldb::eBasicTypeDouble:
1324dda28197Spatrick           case lldb::eBasicTypeLongDouble:
1325dda28197Spatrick             if (type_width == constant_width) {
1326dda28197Spatrick               TypeSystemClang::SetFloatingInitializerForVariable(
1327dda28197Spatrick                   decl, value.toAPFloat());
1328dda28197Spatrick               decl->setConstexpr(true);
1329dda28197Spatrick             } else {
1330*f6aab3d8Srobert               LLDB_LOG(GetLog(LLDBLog::AST),
1331dda28197Spatrick                        "Class '{0}' has a member '{1}' of type '{2}' ({3} "
1332dda28197Spatrick                        "bits) which resolves to a constant value of mismatched "
1333dda28197Spatrick                        "width ({4} bits). Ignoring constant.",
1334dda28197Spatrick                        record_type.GetTypeName(), member_name,
1335dda28197Spatrick                        member_comp_type.GetTypeName(), type_width,
1336dda28197Spatrick                        constant_width);
1337dda28197Spatrick             }
1338dda28197Spatrick             break;
1339dda28197Spatrick           default:
1340dda28197Spatrick             break;
1341dda28197Spatrick           }
1342dda28197Spatrick         }
1343dda28197Spatrick       }
1344dda28197Spatrick 
1345061da546Spatrick       m_uid_to_decl[member->getSymIndexId()] = decl;
1346061da546Spatrick 
1347061da546Spatrick       break;
1348061da546Spatrick     }
1349061da546Spatrick     default:
1350061da546Spatrick       llvm_unreachable("unsupported PDB data kind");
1351061da546Spatrick     }
1352061da546Spatrick   }
1353061da546Spatrick }
1354061da546Spatrick 
AddRecordBases(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,int record_kind,PDBBaseClassSymbolEnumerator & bases_enum,lldb_private::ClangASTImporter::LayoutInfo & layout_info) const1355061da546Spatrick void PDBASTParser::AddRecordBases(
1356061da546Spatrick     lldb_private::SymbolFile &symbol_file,
1357061da546Spatrick     lldb_private::CompilerType &record_type, int record_kind,
1358061da546Spatrick     PDBBaseClassSymbolEnumerator &bases_enum,
1359061da546Spatrick     lldb_private::ClangASTImporter::LayoutInfo &layout_info) const {
1360061da546Spatrick   std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes;
1361061da546Spatrick 
1362061da546Spatrick   while (auto base = bases_enum.getNext()) {
1363061da546Spatrick     auto base_type = symbol_file.ResolveTypeUID(base->getTypeId());
1364061da546Spatrick     if (!base_type)
1365061da546Spatrick       continue;
1366061da546Spatrick 
1367061da546Spatrick     auto base_comp_type = base_type->GetFullCompilerType();
1368061da546Spatrick     if (!base_comp_type.GetCompleteType()) {
1369061da546Spatrick       symbol_file.GetObjectFile()->GetModule()->ReportError(
1370*f6aab3d8Srobert           ":: Class '{0}' has a base class '{1}' "
1371061da546Spatrick           "which does not have a complete definition.",
1372061da546Spatrick           record_type.GetTypeName().GetCString(),
1373061da546Spatrick           base_comp_type.GetTypeName().GetCString());
1374dda28197Spatrick       if (TypeSystemClang::StartTagDeclarationDefinition(base_comp_type))
1375dda28197Spatrick         TypeSystemClang::CompleteTagDeclarationDefinition(base_comp_type);
1376061da546Spatrick     }
1377061da546Spatrick 
1378061da546Spatrick     auto access = TranslateMemberAccess(base->getAccess());
1379061da546Spatrick 
1380061da546Spatrick     auto is_virtual = base->isVirtualBaseClass();
1381061da546Spatrick 
1382061da546Spatrick     std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
1383061da546Spatrick         m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(),
1384061da546Spatrick                                        access, is_virtual,
1385061da546Spatrick                                        record_kind == clang::TTK_Class);
1386061da546Spatrick     lldbassert(base_spec);
1387061da546Spatrick 
1388061da546Spatrick     base_classes.push_back(std::move(base_spec));
1389061da546Spatrick 
1390061da546Spatrick     if (is_virtual)
1391061da546Spatrick       continue;
1392061da546Spatrick 
1393061da546Spatrick     auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType());
1394061da546Spatrick     if (!decl)
1395061da546Spatrick       continue;
1396061da546Spatrick 
1397061da546Spatrick     auto offset = clang::CharUnits::fromQuantity(base->getOffset());
1398061da546Spatrick     layout_info.base_offsets.insert(std::make_pair(decl, offset));
1399061da546Spatrick   }
1400061da546Spatrick 
1401061da546Spatrick   m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(),
1402061da546Spatrick                             std::move(base_classes));
1403061da546Spatrick }
1404061da546Spatrick 
AddRecordMethods(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,PDBFuncSymbolEnumerator & methods_enum)1405061da546Spatrick void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file,
1406061da546Spatrick                                     lldb_private::CompilerType &record_type,
1407061da546Spatrick                                     PDBFuncSymbolEnumerator &methods_enum) {
1408061da546Spatrick   while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext())
1409061da546Spatrick     if (clang::CXXMethodDecl *decl =
1410061da546Spatrick             AddRecordMethod(symbol_file, record_type, *method))
1411061da546Spatrick       m_uid_to_decl[method->getSymIndexId()] = decl;
1412061da546Spatrick }
1413061da546Spatrick 
1414061da546Spatrick clang::CXXMethodDecl *
AddRecordMethod(lldb_private::SymbolFile & symbol_file,lldb_private::CompilerType & record_type,const llvm::pdb::PDBSymbolFunc & method) const1415061da546Spatrick PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
1416061da546Spatrick                               lldb_private::CompilerType &record_type,
1417061da546Spatrick                               const llvm::pdb::PDBSymbolFunc &method) const {
1418dda28197Spatrick   std::string name =
1419dda28197Spatrick       std::string(MSVCUndecoratedNameParser::DropScope(method.getName()));
1420061da546Spatrick 
1421061da546Spatrick   Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId());
1422061da546Spatrick   // MSVC specific __vecDelDtor.
1423061da546Spatrick   if (!method_type)
1424061da546Spatrick     return nullptr;
1425061da546Spatrick 
1426061da546Spatrick   CompilerType method_comp_type = method_type->GetFullCompilerType();
1427061da546Spatrick   if (!method_comp_type.GetCompleteType()) {
1428061da546Spatrick     symbol_file.GetObjectFile()->GetModule()->ReportError(
1429*f6aab3d8Srobert         ":: Class '{0}' has a method '{1}' whose type cannot be completed.",
1430061da546Spatrick         record_type.GetTypeName().GetCString(),
1431061da546Spatrick         method_comp_type.GetTypeName().GetCString());
1432dda28197Spatrick     if (TypeSystemClang::StartTagDeclarationDefinition(method_comp_type))
1433dda28197Spatrick       TypeSystemClang::CompleteTagDeclarationDefinition(method_comp_type);
1434061da546Spatrick   }
1435061da546Spatrick 
1436061da546Spatrick   AccessType access = TranslateMemberAccess(method.getAccess());
1437061da546Spatrick   if (access == eAccessNone)
1438061da546Spatrick     access = eAccessPublic;
1439061da546Spatrick 
1440061da546Spatrick   // TODO: get mangled name for the method.
1441061da546Spatrick   return m_ast.AddMethodToCXXRecordType(
1442061da546Spatrick       record_type.GetOpaqueQualType(), name.c_str(),
1443061da546Spatrick       /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(),
1444061da546Spatrick       method.isStatic(), method.hasInlineAttribute(),
1445061da546Spatrick       /*is_explicit*/ false, // FIXME: Need this field in CodeView.
1446061da546Spatrick       /*is_attr_used*/ false,
1447061da546Spatrick       /*is_artificial*/ method.isCompilerGenerated());
1448061da546Spatrick }
1449