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