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