1594c85e9SZachary Turner #include "PdbAstBuilder.h"
2594c85e9SZachary Turner
3594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
4594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
544f19514SZachary Turner #include "llvm/DebugInfo/CodeView/RecordName.h"
6594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
7594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
8594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
9594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
10594c85e9SZachary Turner #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
1122566330SZachary Turner #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1222566330SZachary Turner #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
1322566330SZachary Turner #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
14594c85e9SZachary Turner #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
15594c85e9SZachary Turner #include "llvm/Demangle/MicrosoftDemangle.h"
16594c85e9SZachary Turner
178be30215SAlex Langford #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
188be30215SAlex Langford #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
1944f19514SZachary Turner #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
208be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
21594c85e9SZachary Turner #include "lldb/Core/Module.h"
22594c85e9SZachary Turner #include "lldb/Symbol/ObjectFile.h"
23594c85e9SZachary Turner #include "lldb/Utility/LLDBAssert.h"
24594c85e9SZachary Turner
25594c85e9SZachary Turner #include "PdbUtil.h"
26594c85e9SZachary Turner #include "UdtRecordCompleter.h"
27594c85e9SZachary Turner
28594c85e9SZachary Turner using namespace lldb_private;
29594c85e9SZachary Turner using namespace lldb_private::npdb;
30594c85e9SZachary Turner using namespace llvm::codeview;
31594c85e9SZachary Turner using namespace llvm::pdb;
32594c85e9SZachary Turner
33a3a8ed33SZequan Wu namespace {
34a3a8ed33SZequan Wu struct CreateMethodDecl : public TypeVisitorCallbacks {
CreateMethodDecl__anonc2e7a6240111::CreateMethodDecl35a3a8ed33SZequan Wu CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang,
36a3a8ed33SZequan Wu TypeIndex func_type_index,
37a3a8ed33SZequan Wu clang::FunctionDecl *&function_decl,
38a3a8ed33SZequan Wu lldb::opaque_compiler_type_t parent_ty,
39a3a8ed33SZequan Wu llvm::StringRef proc_name, CompilerType func_ct)
40a3a8ed33SZequan Wu : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index),
41a3a8ed33SZequan Wu function_decl(function_decl), parent_ty(parent_ty),
42a3a8ed33SZequan Wu proc_name(proc_name), func_ct(func_ct) {}
43a3a8ed33SZequan Wu PdbIndex &m_index;
44a3a8ed33SZequan Wu TypeSystemClang &m_clang;
45a3a8ed33SZequan Wu TypeIndex func_type_index;
46a3a8ed33SZequan Wu clang::FunctionDecl *&function_decl;
47a3a8ed33SZequan Wu lldb::opaque_compiler_type_t parent_ty;
48a3a8ed33SZequan Wu llvm::StringRef proc_name;
49a3a8ed33SZequan Wu CompilerType func_ct;
50a3a8ed33SZequan Wu
visitKnownMember__anonc2e7a6240111::CreateMethodDecl51a3a8ed33SZequan Wu llvm::Error visitKnownMember(CVMemberRecord &cvr,
52a3a8ed33SZequan Wu OverloadedMethodRecord &overloaded) override {
53a3a8ed33SZequan Wu TypeIndex method_list_idx = overloaded.MethodList;
54a3a8ed33SZequan Wu
55a3a8ed33SZequan Wu CVType method_list_type = m_index.tpi().getType(method_list_idx);
56a3a8ed33SZequan Wu assert(method_list_type.kind() == LF_METHODLIST);
57a3a8ed33SZequan Wu
58a3a8ed33SZequan Wu MethodOverloadListRecord method_list;
59a3a8ed33SZequan Wu llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>(
60a3a8ed33SZequan Wu method_list_type, method_list));
61a3a8ed33SZequan Wu
62a3a8ed33SZequan Wu for (const OneMethodRecord &method : method_list.Methods) {
63a3a8ed33SZequan Wu if (method.getType().getIndex() == func_type_index.getIndex())
64a3a8ed33SZequan Wu AddMethod(overloaded.Name, method.getAccess(), method.getOptions(),
65a3a8ed33SZequan Wu method.Attrs);
66a3a8ed33SZequan Wu }
67a3a8ed33SZequan Wu
68a3a8ed33SZequan Wu return llvm::Error::success();
69a3a8ed33SZequan Wu }
70a3a8ed33SZequan Wu
visitKnownMember__anonc2e7a6240111::CreateMethodDecl71a3a8ed33SZequan Wu llvm::Error visitKnownMember(CVMemberRecord &cvr,
72a3a8ed33SZequan Wu OneMethodRecord &record) override {
73a3a8ed33SZequan Wu AddMethod(record.getName(), record.getAccess(), record.getOptions(),
74a3a8ed33SZequan Wu record.Attrs);
75a3a8ed33SZequan Wu return llvm::Error::success();
76a3a8ed33SZequan Wu }
77a3a8ed33SZequan Wu
AddMethod__anonc2e7a6240111::CreateMethodDecl78a3a8ed33SZequan Wu void AddMethod(llvm::StringRef name, MemberAccess access,
79a3a8ed33SZequan Wu MethodOptions options, MemberAttributes attrs) {
80a3a8ed33SZequan Wu if (name != proc_name || function_decl)
81a3a8ed33SZequan Wu return;
82a3a8ed33SZequan Wu lldb::AccessType access_type = TranslateMemberAccess(access);
83a3a8ed33SZequan Wu bool is_virtual = attrs.isVirtual();
84a3a8ed33SZequan Wu bool is_static = attrs.isStatic();
85a3a8ed33SZequan Wu bool is_artificial = (options & MethodOptions::CompilerGenerated) ==
86a3a8ed33SZequan Wu MethodOptions::CompilerGenerated;
87a3a8ed33SZequan Wu function_decl = m_clang.AddMethodToCXXRecordType(
88a3a8ed33SZequan Wu parent_ty, proc_name,
89a3a8ed33SZequan Wu /*mangled_name=*/nullptr, func_ct, /*access=*/access_type,
90a3a8ed33SZequan Wu /*is_virtual=*/is_virtual, /*is_static=*/is_static,
91a3a8ed33SZequan Wu /*is_inline=*/false, /*is_explicit=*/false,
92a3a8ed33SZequan Wu /*is_attr_used=*/false, /*is_artificial=*/is_artificial);
93a3a8ed33SZequan Wu }
94a3a8ed33SZequan Wu };
95a3a8ed33SZequan Wu } // namespace
96a3a8ed33SZequan Wu
FindSymbolScope(PdbIndex & index,PdbCompilandSymId id)97594c85e9SZachary Turner static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index,
98594c85e9SZachary Turner PdbCompilandSymId id) {
99594c85e9SZachary Turner CVSymbol sym = index.ReadSymbolRecord(id);
100594c85e9SZachary Turner if (symbolOpensScope(sym.kind())) {
101594c85e9SZachary Turner // If this exact symbol opens a scope, we can just directly access its
102594c85e9SZachary Turner // parent.
103594c85e9SZachary Turner id.offset = getScopeParentOffset(sym);
104594c85e9SZachary Turner // Global symbols have parent offset of 0. Return llvm::None to indicate
105594c85e9SZachary Turner // this.
106594c85e9SZachary Turner if (id.offset == 0)
107594c85e9SZachary Turner return llvm::None;
108594c85e9SZachary Turner return id;
109594c85e9SZachary Turner }
110594c85e9SZachary Turner
111594c85e9SZachary Turner // Otherwise we need to start at the beginning and iterate forward until we
112594c85e9SZachary Turner // reach (or pass) this particular symbol
113594c85e9SZachary Turner CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(id.modi);
114594c85e9SZachary Turner const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
115594c85e9SZachary Turner
116594c85e9SZachary Turner auto begin = syms.begin();
117594c85e9SZachary Turner auto end = syms.at(id.offset);
118594c85e9SZachary Turner std::vector<PdbCompilandSymId> scope_stack;
119594c85e9SZachary Turner
120594c85e9SZachary Turner while (begin != end) {
121594c85e9SZachary Turner if (begin.offset() > id.offset) {
122594c85e9SZachary Turner // We passed it. We couldn't even find this symbol record.
123594c85e9SZachary Turner lldbassert(false && "Invalid compiland symbol id!");
124594c85e9SZachary Turner return llvm::None;
125594c85e9SZachary Turner }
126594c85e9SZachary Turner
127594c85e9SZachary Turner // We haven't found the symbol yet. Check if we need to open or close the
128594c85e9SZachary Turner // scope stack.
129594c85e9SZachary Turner if (symbolOpensScope(begin->kind())) {
130594c85e9SZachary Turner // We can use the end offset of the scope to determine whether or not
131594c85e9SZachary Turner // we can just outright skip this entire scope.
132594c85e9SZachary Turner uint32_t scope_end = getScopeEndOffset(*begin);
13348d88907SZequan Wu if (scope_end < id.offset) {
134594c85e9SZachary Turner begin = syms.at(scope_end);
135594c85e9SZachary Turner } else {
136594c85e9SZachary Turner // The symbol we're looking for is somewhere in this scope.
137594c85e9SZachary Turner scope_stack.emplace_back(id.modi, begin.offset());
138594c85e9SZachary Turner }
139594c85e9SZachary Turner } else if (symbolEndsScope(begin->kind())) {
140594c85e9SZachary Turner scope_stack.pop_back();
141594c85e9SZachary Turner }
142594c85e9SZachary Turner ++begin;
143594c85e9SZachary Turner }
14448d88907SZequan Wu if (scope_stack.empty())
145594c85e9SZachary Turner return llvm::None;
14648d88907SZequan Wu // We have a match! Return the top of the stack
14748d88907SZequan Wu return scope_stack.back();
148594c85e9SZachary Turner }
149594c85e9SZachary Turner
TranslateUdtKind(const TagRecord & cr)150594c85e9SZachary Turner static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {
151594c85e9SZachary Turner switch (cr.Kind) {
152594c85e9SZachary Turner case TypeRecordKind::Class:
153594c85e9SZachary Turner return clang::TTK_Class;
154594c85e9SZachary Turner case TypeRecordKind::Struct:
155594c85e9SZachary Turner return clang::TTK_Struct;
156594c85e9SZachary Turner case TypeRecordKind::Union:
157594c85e9SZachary Turner return clang::TTK_Union;
158594c85e9SZachary Turner case TypeRecordKind::Interface:
159594c85e9SZachary Turner return clang::TTK_Interface;
160594c85e9SZachary Turner case TypeRecordKind::Enum:
161594c85e9SZachary Turner return clang::TTK_Enum;
162594c85e9SZachary Turner default:
163594c85e9SZachary Turner lldbassert(false && "Invalid tag record kind!");
164594c85e9SZachary Turner return clang::TTK_Struct;
165594c85e9SZachary Turner }
166594c85e9SZachary Turner }
167594c85e9SZachary Turner
IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args)168594c85e9SZachary Turner static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) {
169594c85e9SZachary Turner if (args.empty())
170594c85e9SZachary Turner return false;
171594c85e9SZachary Turner return args.back() == TypeIndex::None();
172594c85e9SZachary Turner }
173594c85e9SZachary Turner
174594c85e9SZachary Turner static bool
AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node * > scopes)175594c85e9SZachary Turner AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {
176594c85e9SZachary Turner for (llvm::ms_demangle::Node *n : scopes) {
177594c85e9SZachary Turner auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n);
178594c85e9SZachary Turner if (idn->TemplateParams)
179594c85e9SZachary Turner return true;
180594c85e9SZachary Turner }
181594c85e9SZachary Turner return false;
182594c85e9SZachary Turner }
183594c85e9SZachary Turner
184594c85e9SZachary Turner static llvm::Optional<clang::CallingConv>
TranslateCallingConvention(llvm::codeview::CallingConvention conv)185594c85e9SZachary Turner TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
186594c85e9SZachary Turner using CC = llvm::codeview::CallingConvention;
187594c85e9SZachary Turner switch (conv) {
188594c85e9SZachary Turner
189594c85e9SZachary Turner case CC::NearC:
190594c85e9SZachary Turner case CC::FarC:
191594c85e9SZachary Turner return clang::CallingConv::CC_C;
192594c85e9SZachary Turner case CC::NearPascal:
193594c85e9SZachary Turner case CC::FarPascal:
194594c85e9SZachary Turner return clang::CallingConv::CC_X86Pascal;
195594c85e9SZachary Turner case CC::NearFast:
196594c85e9SZachary Turner case CC::FarFast:
197594c85e9SZachary Turner return clang::CallingConv::CC_X86FastCall;
198594c85e9SZachary Turner case CC::NearStdCall:
199594c85e9SZachary Turner case CC::FarStdCall:
200594c85e9SZachary Turner return clang::CallingConv::CC_X86StdCall;
201594c85e9SZachary Turner case CC::ThisCall:
202594c85e9SZachary Turner return clang::CallingConv::CC_X86ThisCall;
203594c85e9SZachary Turner case CC::NearVector:
204594c85e9SZachary Turner return clang::CallingConv::CC_X86VectorCall;
205594c85e9SZachary Turner default:
206594c85e9SZachary Turner return llvm::None;
207594c85e9SZachary Turner }
208594c85e9SZachary Turner }
209594c85e9SZachary Turner
210594c85e9SZachary Turner static llvm::Optional<CVTagRecord>
GetNestedTagDefinition(const NestedTypeRecord & Record,const CVTagRecord & parent,TpiStream & tpi)21122566330SZachary Turner GetNestedTagDefinition(const NestedTypeRecord &Record,
21222566330SZachary Turner const CVTagRecord &parent, TpiStream &tpi) {
213594c85e9SZachary Turner // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
214594c85e9SZachary Turner // is also used to indicate the primary definition of a nested class. That is
215594c85e9SZachary Turner // to say, if you have:
216594c85e9SZachary Turner // struct A {
217594c85e9SZachary Turner // struct B {};
218594c85e9SZachary Turner // using C = B;
219594c85e9SZachary Turner // };
220594c85e9SZachary Turner // Then in the debug info, this will appear as:
221594c85e9SZachary Turner // LF_STRUCTURE `A::B` [type index = N]
222594c85e9SZachary Turner // LF_STRUCTURE `A`
223594c85e9SZachary Turner // LF_NESTTYPE [name = `B`, index = N]
224594c85e9SZachary Turner // LF_NESTTYPE [name = `C`, index = N]
225594c85e9SZachary Turner // In order to accurately reconstruct the decl context hierarchy, we need to
226594c85e9SZachary Turner // know which ones are actual definitions and which ones are just aliases.
227594c85e9SZachary Turner
228594c85e9SZachary Turner // If it's a simple type, then this is something like `using foo = int`.
229594c85e9SZachary Turner if (Record.Type.isSimple())
230594c85e9SZachary Turner return llvm::None;
231594c85e9SZachary Turner
232594c85e9SZachary Turner CVType cvt = tpi.getType(Record.Type);
233594c85e9SZachary Turner
234594c85e9SZachary Turner if (!IsTagRecord(cvt))
235594c85e9SZachary Turner return llvm::None;
236594c85e9SZachary Turner
237594c85e9SZachary Turner // If it's an inner definition, then treat whatever name we have here as a
238594c85e9SZachary Turner // single component of a mangled name. So we can inject it into the parent's
239594c85e9SZachary Turner // mangled name to see if it matches.
240594c85e9SZachary Turner CVTagRecord child = CVTagRecord::create(cvt);
241adcd0268SBenjamin Kramer std::string qname = std::string(parent.asTag().getUniqueName());
242594c85e9SZachary Turner if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
243594c85e9SZachary Turner return llvm::None;
244594c85e9SZachary Turner
245594c85e9SZachary Turner // qname[3] is the tag type identifier (struct, class, union, etc). Since the
246594c85e9SZachary Turner // inner tag type is not necessarily the same as the outer tag type, re-write
247594c85e9SZachary Turner // it to match the inner tag type.
248594c85e9SZachary Turner qname[3] = child.asTag().getUniqueName()[3];
249cb67fad4SZachary Turner std::string piece;
250cb67fad4SZachary Turner if (qname[3] == 'W')
251cb67fad4SZachary Turner piece = "4";
252cb67fad4SZachary Turner piece += Record.Name;
253594c85e9SZachary Turner piece.push_back('@');
254594c85e9SZachary Turner qname.insert(4, std::move(piece));
255594c85e9SZachary Turner if (qname != child.asTag().UniqueName)
256594c85e9SZachary Turner return llvm::None;
257594c85e9SZachary Turner
258594c85e9SZachary Turner return std::move(child);
259594c85e9SZachary Turner }
260594c85e9SZachary Turner
IsAnonymousNamespaceName(llvm::StringRef name)261ee12a75eSAleksandr Urakov static bool IsAnonymousNamespaceName(llvm::StringRef name) {
262ee12a75eSAleksandr Urakov return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
263ee12a75eSAleksandr Urakov }
264ee12a75eSAleksandr Urakov
PdbAstBuilder(ObjectFile & obj,PdbIndex & index,TypeSystemClang & clang)2656e3b0cc2SRaphael Isemann PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index, TypeSystemClang &clang)
2660e252e38SAlex Langford : m_index(index), m_clang(clang) {
267594c85e9SZachary Turner BuildParentMap();
268594c85e9SZachary Turner }
269594c85e9SZachary Turner
GetTranslationUnitDecl()27006bf5d85SNathan Lanza lldb_private::CompilerDeclContext PdbAstBuilder::GetTranslationUnitDecl() {
27106bf5d85SNathan Lanza return ToCompilerDeclContext(*m_clang.GetTranslationUnitDecl());
272594c85e9SZachary Turner }
273594c85e9SZachary Turner
274594c85e9SZachary Turner std::pair<clang::DeclContext *, std::string>
CreateDeclInfoForType(const TagRecord & record,TypeIndex ti)275594c85e9SZachary Turner PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
276594c85e9SZachary Turner // FIXME: Move this to GetDeclContextContainingUID.
27744f19514SZachary Turner if (!record.hasUniqueName())
27844f19514SZachary Turner return CreateDeclInfoForUndecoratedName(record.Name);
279594c85e9SZachary Turner
280594c85e9SZachary Turner llvm::ms_demangle::Demangler demangler;
281594c85e9SZachary Turner StringView sv(record.UniqueName.begin(), record.UniqueName.size());
282594c85e9SZachary Turner llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
28344f19514SZachary Turner if (demangler.Error)
284adcd0268SBenjamin Kramer return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)};
28544f19514SZachary Turner
286594c85e9SZachary Turner llvm::ms_demangle::IdentifierNode *idn =
287594c85e9SZachary Turner ttn->QualifiedName->getUnqualifiedIdentifier();
28822566330SZachary Turner std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier);
289594c85e9SZachary Turner
290594c85e9SZachary Turner llvm::ms_demangle::NodeArrayNode *name_components =
291594c85e9SZachary Turner ttn->QualifiedName->Components;
292594c85e9SZachary Turner llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes,
293594c85e9SZachary Turner name_components->Count - 1);
294594c85e9SZachary Turner
295594c85e9SZachary Turner clang::DeclContext *context = m_clang.GetTranslationUnitDecl();
296594c85e9SZachary Turner
297594c85e9SZachary Turner // If this type doesn't have a parent type in the debug info, then the best we
298594c85e9SZachary Turner // can do is to say that it's either a series of namespaces (if the scope is
299594c85e9SZachary Turner // non-empty), or the translation unit (if the scope is empty).
300594c85e9SZachary Turner auto parent_iter = m_parent_types.find(ti);
301594c85e9SZachary Turner if (parent_iter == m_parent_types.end()) {
302594c85e9SZachary Turner if (scopes.empty())
303594c85e9SZachary Turner return {context, uname};
304594c85e9SZachary Turner
305594c85e9SZachary Turner // If there is no parent in the debug info, but some of the scopes have
306594c85e9SZachary Turner // template params, then this is a case of bad debug info. See, for
307594c85e9SZachary Turner // example, llvm.org/pr39607. We don't want to create an ambiguity between
308594c85e9SZachary Turner // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at
309594c85e9SZachary Turner // global scope with the fully qualified name.
310594c85e9SZachary Turner if (AnyScopesHaveTemplateParams(scopes))
311adcd0268SBenjamin Kramer return {context, std::string(record.Name)};
312594c85e9SZachary Turner
313594c85e9SZachary Turner for (llvm::ms_demangle::Node *scope : scopes) {
314594c85e9SZachary Turner auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
315594c85e9SZachary Turner std::string str = nii->toString();
316ee12a75eSAleksandr Urakov context = GetOrCreateNamespaceDecl(str.c_str(), *context);
317594c85e9SZachary Turner }
318594c85e9SZachary Turner return {context, uname};
319594c85e9SZachary Turner }
320594c85e9SZachary Turner
321594c85e9SZachary Turner // Otherwise, all we need to do is get the parent type of this type and
322594c85e9SZachary Turner // recurse into our lazy type creation / AST reconstruction logic to get an
323594c85e9SZachary Turner // LLDB TypeSP for the parent. This will cause the AST to automatically get
324594c85e9SZachary Turner // the right DeclContext created for any parent.
325594c85e9SZachary Turner clang::QualType parent_qt = GetOrCreateType(parent_iter->second);
3265c9f3ec4SZequan Wu if (parent_qt.isNull())
3275c9f3ec4SZequan Wu return {nullptr, ""};
328594c85e9SZachary Turner
329594c85e9SZachary Turner context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl());
330594c85e9SZachary Turner return {context, uname};
331594c85e9SZachary Turner }
332594c85e9SZachary Turner
BuildParentMap()333594c85e9SZachary Turner void PdbAstBuilder::BuildParentMap() {
334594c85e9SZachary Turner LazyRandomTypeCollection &types = m_index.tpi().typeCollection();
335594c85e9SZachary Turner
33622566330SZachary Turner llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
33722566330SZachary Turner llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
33822566330SZachary Turner
33922566330SZachary Turner struct RecordIndices {
34022566330SZachary Turner TypeIndex forward;
34122566330SZachary Turner TypeIndex full;
34222566330SZachary Turner };
34322566330SZachary Turner
34422566330SZachary Turner llvm::StringMap<RecordIndices> record_indices;
34522566330SZachary Turner
346594c85e9SZachary Turner for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
347594c85e9SZachary Turner CVType type = types.getType(*ti);
348594c85e9SZachary Turner if (!IsTagRecord(type))
349594c85e9SZachary Turner continue;
350594c85e9SZachary Turner
351594c85e9SZachary Turner CVTagRecord tag = CVTagRecord::create(type);
35222566330SZachary Turner
35322566330SZachary Turner RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
35422566330SZachary Turner if (tag.asTag().isForwardRef())
35522566330SZachary Turner indices.forward = *ti;
35622566330SZachary Turner else
35722566330SZachary Turner indices.full = *ti;
35822566330SZachary Turner
35922566330SZachary Turner if (indices.full != TypeIndex::None() &&
36022566330SZachary Turner indices.forward != TypeIndex::None()) {
36122566330SZachary Turner forward_to_full[indices.forward] = indices.full;
36222566330SZachary Turner full_to_forward[indices.full] = indices.forward;
36322566330SZachary Turner }
36422566330SZachary Turner
365594c85e9SZachary Turner // We're looking for LF_NESTTYPE records in the field list, so ignore
366594c85e9SZachary Turner // forward references (no field list), and anything without a nested class
367594c85e9SZachary Turner // (since there won't be any LF_NESTTYPE records).
368594c85e9SZachary Turner if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
369594c85e9SZachary Turner continue;
370594c85e9SZachary Turner
371594c85e9SZachary Turner struct ProcessTpiStream : public TypeVisitorCallbacks {
372594c85e9SZachary Turner ProcessTpiStream(PdbIndex &index, TypeIndex parent,
373594c85e9SZachary Turner const CVTagRecord &parent_cvt,
374594c85e9SZachary Turner llvm::DenseMap<TypeIndex, TypeIndex> &parents)
375594c85e9SZachary Turner : index(index), parents(parents), parent(parent),
376594c85e9SZachary Turner parent_cvt(parent_cvt) {}
377594c85e9SZachary Turner
378594c85e9SZachary Turner PdbIndex &index;
379594c85e9SZachary Turner llvm::DenseMap<TypeIndex, TypeIndex> &parents;
38022566330SZachary Turner
38122566330SZachary Turner unsigned unnamed_type_index = 1;
382594c85e9SZachary Turner TypeIndex parent;
383594c85e9SZachary Turner const CVTagRecord &parent_cvt;
384594c85e9SZachary Turner
385594c85e9SZachary Turner llvm::Error visitKnownMember(CVMemberRecord &CVR,
386594c85e9SZachary Turner NestedTypeRecord &Record) override {
38722566330SZachary Turner std::string unnamed_type_name;
38822566330SZachary Turner if (Record.Name.empty()) {
38922566330SZachary Turner unnamed_type_name =
39022566330SZachary Turner llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
39122566330SZachary Turner Record.Name = unnamed_type_name;
39222566330SZachary Turner ++unnamed_type_index;
39322566330SZachary Turner }
394594c85e9SZachary Turner llvm::Optional<CVTagRecord> tag =
39522566330SZachary Turner GetNestedTagDefinition(Record, parent_cvt, index.tpi());
396594c85e9SZachary Turner if (!tag)
397594c85e9SZachary Turner return llvm::ErrorSuccess();
398594c85e9SZachary Turner
399594c85e9SZachary Turner parents[Record.Type] = parent;
400594c85e9SZachary Turner return llvm::ErrorSuccess();
401594c85e9SZachary Turner }
402594c85e9SZachary Turner };
403594c85e9SZachary Turner
404bd2044c1SZequan Wu CVType field_list_cvt = m_index.tpi().getType(tag.asTag().FieldList);
405594c85e9SZachary Turner ProcessTpiStream process(m_index, *ti, tag, m_parent_types);
406bd2044c1SZequan Wu FieldListRecord field_list;
407bd2044c1SZequan Wu if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
408bd2044c1SZequan Wu field_list_cvt, field_list))
409bd2044c1SZequan Wu llvm::consumeError(std::move(error));
410bd2044c1SZequan Wu if (llvm::Error error = visitMemberRecordStream(field_list.Data, process))
411594c85e9SZachary Turner llvm::consumeError(std::move(error));
412594c85e9SZachary Turner }
41322566330SZachary Turner
41422566330SZachary Turner // Now that we know the forward -> full mapping of all type indices, we can
41522566330SZachary Turner // re-write all the indices. At the end of this process, we want a mapping
41622566330SZachary Turner // consisting of fwd -> full and full -> full for all child -> parent indices.
41722566330SZachary Turner // We can re-write the values in place, but for the keys, we must save them
41822566330SZachary Turner // off so that we don't modify the map in place while also iterating it.
41922566330SZachary Turner std::vector<TypeIndex> full_keys;
42022566330SZachary Turner std::vector<TypeIndex> fwd_keys;
42122566330SZachary Turner for (auto &entry : m_parent_types) {
422489cfbd9SZachary Turner TypeIndex key = entry.first;
423489cfbd9SZachary Turner TypeIndex value = entry.second;
42422566330SZachary Turner
42522566330SZachary Turner auto iter = forward_to_full.find(value);
42622566330SZachary Turner if (iter != forward_to_full.end())
42722566330SZachary Turner entry.second = iter->second;
42822566330SZachary Turner
42922566330SZachary Turner iter = forward_to_full.find(key);
43022566330SZachary Turner if (iter != forward_to_full.end())
43122566330SZachary Turner fwd_keys.push_back(key);
43222566330SZachary Turner else
43322566330SZachary Turner full_keys.push_back(key);
43422566330SZachary Turner }
43522566330SZachary Turner for (TypeIndex fwd : fwd_keys) {
43622566330SZachary Turner TypeIndex full = forward_to_full[fwd];
43722566330SZachary Turner m_parent_types[full] = m_parent_types[fwd];
43822566330SZachary Turner }
43922566330SZachary Turner for (TypeIndex full : full_keys) {
44022566330SZachary Turner TypeIndex fwd = full_to_forward[full];
44122566330SZachary Turner m_parent_types[fwd] = m_parent_types[full];
44222566330SZachary Turner }
44322566330SZachary Turner
44422566330SZachary Turner // Now that
44522566330SZachary Turner }
44622566330SZachary Turner
isLocalVariableType(SymbolKind K)44722566330SZachary Turner static bool isLocalVariableType(SymbolKind K) {
44822566330SZachary Turner switch (K) {
44922566330SZachary Turner case S_REGISTER:
45022566330SZachary Turner case S_REGREL32:
45122566330SZachary Turner case S_LOCAL:
45222566330SZachary Turner return true;
45322566330SZachary Turner default:
45422566330SZachary Turner break;
45522566330SZachary Turner }
45622566330SZachary Turner return false;
45722566330SZachary Turner }
45822566330SZachary Turner
45922566330SZachary Turner static std::string
RenderScopeList(llvm::ArrayRef<llvm::ms_demangle::Node * > nodes)46022566330SZachary Turner RenderScopeList(llvm::ArrayRef<llvm::ms_demangle::Node *> nodes) {
46122566330SZachary Turner lldbassert(!nodes.empty());
46222566330SZachary Turner
46322566330SZachary Turner std::string result = nodes.front()->toString();
46422566330SZachary Turner nodes = nodes.drop_front();
46522566330SZachary Turner while (!nodes.empty()) {
46622566330SZachary Turner result += "::";
46722566330SZachary Turner result += nodes.front()->toString(llvm::ms_demangle::OF_NoTagSpecifier);
46822566330SZachary Turner nodes = nodes.drop_front();
46922566330SZachary Turner }
47022566330SZachary Turner return result;
47122566330SZachary Turner }
47222566330SZachary Turner
FindPublicSym(const SegmentOffset & addr,SymbolStream & syms,PublicsStream & publics)47322566330SZachary Turner static llvm::Optional<PublicSym32> FindPublicSym(const SegmentOffset &addr,
47422566330SZachary Turner SymbolStream &syms,
47522566330SZachary Turner PublicsStream &publics) {
47622566330SZachary Turner llvm::FixedStreamArray<ulittle32_t> addr_map = publics.getAddressMap();
47722566330SZachary Turner auto iter = std::lower_bound(
47822566330SZachary Turner addr_map.begin(), addr_map.end(), addr,
47922566330SZachary Turner [&](const ulittle32_t &x, const SegmentOffset &y) {
48022566330SZachary Turner CVSymbol s1 = syms.readRecord(x);
48122566330SZachary Turner lldbassert(s1.kind() == S_PUB32);
48222566330SZachary Turner PublicSym32 p1;
48322566330SZachary Turner llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(s1, p1));
48422566330SZachary Turner if (p1.Segment < y.segment)
48522566330SZachary Turner return true;
48622566330SZachary Turner return p1.Offset < y.offset;
48722566330SZachary Turner });
48822566330SZachary Turner if (iter == addr_map.end())
48922566330SZachary Turner return llvm::None;
49022566330SZachary Turner CVSymbol sym = syms.readRecord(*iter);
49122566330SZachary Turner lldbassert(sym.kind() == S_PUB32);
49222566330SZachary Turner PublicSym32 p;
49322566330SZachary Turner llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym, p));
49422566330SZachary Turner if (p.Segment == addr.segment && p.Offset == addr.offset)
49522566330SZachary Turner return p;
49622566330SZachary Turner return llvm::None;
497594c85e9SZachary Turner }
498594c85e9SZachary Turner
GetOrCreateSymbolForId(PdbCompilandSymId id)499594c85e9SZachary Turner clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
500594c85e9SZachary Turner CVSymbol cvs = m_index.ReadSymbolRecord(id);
501594c85e9SZachary Turner
50222566330SZachary Turner if (isLocalVariableType(cvs.kind())) {
50322566330SZachary Turner clang::DeclContext *scope = GetParentDeclContext(id);
50422566330SZachary Turner clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope);
5055e9c9b32SZequan Wu PdbCompilandSymId scope_id =
5065e9c9b32SZequan Wu PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym();
50722566330SZachary Turner return GetOrCreateVariableDecl(scope_id, id);
50822566330SZachary Turner }
50922566330SZachary Turner
510594c85e9SZachary Turner switch (cvs.kind()) {
511594c85e9SZachary Turner case S_GPROC32:
512594c85e9SZachary Turner case S_LPROC32:
513594c85e9SZachary Turner return GetOrCreateFunctionDecl(id);
514594c85e9SZachary Turner case S_GDATA32:
515594c85e9SZachary Turner case S_LDATA32:
516594c85e9SZachary Turner case S_GTHREAD32:
517594c85e9SZachary Turner case S_CONSTANT:
518594c85e9SZachary Turner // global variable
519594c85e9SZachary Turner return nullptr;
520594c85e9SZachary Turner case S_BLOCK32:
521594c85e9SZachary Turner return GetOrCreateBlockDecl(id);
522c45975cbSZequan Wu case S_INLINESITE:
523c45975cbSZequan Wu return GetOrCreateInlinedFunctionDecl(id);
524594c85e9SZachary Turner default:
525594c85e9SZachary Turner return nullptr;
526594c85e9SZachary Turner }
527594c85e9SZachary Turner }
528594c85e9SZachary Turner
GetOrCreateDeclForUid(PdbSymUid uid)529fe1b8a09SNathan Lanza llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
530594c85e9SZachary Turner if (clang::Decl *result = TryGetDecl(uid))
531fe1b8a09SNathan Lanza return ToCompilerDecl(*result);
532594c85e9SZachary Turner
533594c85e9SZachary Turner clang::Decl *result = nullptr;
534594c85e9SZachary Turner switch (uid.kind()) {
535594c85e9SZachary Turner case PdbSymUidKind::CompilandSym:
536594c85e9SZachary Turner result = GetOrCreateSymbolForId(uid.asCompilandSym());
537594c85e9SZachary Turner break;
538594c85e9SZachary Turner case PdbSymUidKind::Type: {
539594c85e9SZachary Turner clang::QualType qt = GetOrCreateType(uid.asTypeSym());
5405c9f3ec4SZequan Wu if (qt.isNull())
5415c9f3ec4SZequan Wu return llvm::None;
542594c85e9SZachary Turner if (auto *tag = qt->getAsTagDecl()) {
543594c85e9SZachary Turner result = tag;
544594c85e9SZachary Turner break;
545594c85e9SZachary Turner }
546fe1b8a09SNathan Lanza return llvm::None;
547594c85e9SZachary Turner }
548594c85e9SZachary Turner default:
549fe1b8a09SNathan Lanza return llvm::None;
550594c85e9SZachary Turner }
551c45975cbSZequan Wu
552c45975cbSZequan Wu if (!result)
553c45975cbSZequan Wu return llvm::None;
554594c85e9SZachary Turner m_uid_to_decl[toOpaqueUid(uid)] = result;
555fe1b8a09SNathan Lanza return ToCompilerDecl(*result);
556594c85e9SZachary Turner }
557594c85e9SZachary Turner
GetOrCreateDeclContextForUid(PdbSymUid uid)558594c85e9SZachary Turner clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
55922566330SZachary Turner if (uid.kind() == PdbSymUidKind::CompilandSym) {
56022566330SZachary Turner if (uid.asCompilandSym().offset == 0)
56106bf5d85SNathan Lanza return FromCompilerDeclContext(GetTranslationUnitDecl());
56222566330SZachary Turner }
563fe1b8a09SNathan Lanza auto option = GetOrCreateDeclForUid(uid);
564fe1b8a09SNathan Lanza if (!option)
565fe1b8a09SNathan Lanza return nullptr;
566ed8fceaaSKazu Hirata clang::Decl *decl = FromCompilerDecl(*option);
567594c85e9SZachary Turner if (!decl)
568594c85e9SZachary Turner return nullptr;
569594c85e9SZachary Turner
570594c85e9SZachary Turner return clang::Decl::castToDeclContext(decl);
571594c85e9SZachary Turner }
572594c85e9SZachary Turner
57344f19514SZachary Turner std::pair<clang::DeclContext *, std::string>
CreateDeclInfoForUndecoratedName(llvm::StringRef name)57444f19514SZachary Turner PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
57544f19514SZachary Turner MSVCUndecoratedNameParser parser(name);
57644f19514SZachary Turner llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
57722566330SZachary Turner
57806bf5d85SNathan Lanza auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
57944f19514SZachary Turner
58044f19514SZachary Turner llvm::StringRef uname = specs.back().GetBaseName();
58144f19514SZachary Turner specs = specs.drop_back();
58244f19514SZachary Turner if (specs.empty())
583adcd0268SBenjamin Kramer return {context, std::string(name)};
58444f19514SZachary Turner
58544f19514SZachary Turner llvm::StringRef scope_name = specs.back().GetFullName();
58644f19514SZachary Turner
58744f19514SZachary Turner // It might be a class name, try that first.
58844f19514SZachary Turner std::vector<TypeIndex> types = m_index.tpi().findRecordsByName(scope_name);
58944f19514SZachary Turner while (!types.empty()) {
59044f19514SZachary Turner clang::QualType qt = GetOrCreateType(types.back());
5915c9f3ec4SZequan Wu if (qt.isNull())
5925c9f3ec4SZequan Wu continue;
59344f19514SZachary Turner clang::TagDecl *tag = qt->getAsTagDecl();
59444f19514SZachary Turner if (tag)
595adcd0268SBenjamin Kramer return {clang::TagDecl::castToDeclContext(tag), std::string(uname)};
59644f19514SZachary Turner types.pop_back();
59744f19514SZachary Turner }
59844f19514SZachary Turner
59944f19514SZachary Turner // If that fails, treat it as a series of namespaces.
60044f19514SZachary Turner for (const MSVCUndecoratedNameSpecifier &spec : specs) {
60144f19514SZachary Turner std::string ns_name = spec.GetBaseName().str();
602ee12a75eSAleksandr Urakov context = GetOrCreateNamespaceDecl(ns_name.c_str(), *context);
60344f19514SZachary Turner }
604adcd0268SBenjamin Kramer return {context, std::string(uname)};
60544f19514SZachary Turner }
60644f19514SZachary Turner
60744f19514SZachary Turner clang::DeclContext *
GetParentDeclContextForSymbol(const CVSymbol & sym)60844f19514SZachary Turner PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) {
60922566330SZachary Turner if (!SymbolHasAddress(sym))
61044f19514SZachary Turner return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
61122566330SZachary Turner SegmentOffset addr = GetSegmentAndOffset(sym);
61222566330SZachary Turner llvm::Optional<PublicSym32> pub =
61322566330SZachary Turner FindPublicSym(addr, m_index.symrecords(), m_index.publics());
61422566330SZachary Turner if (!pub)
61544f19514SZachary Turner return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
61622566330SZachary Turner
61722566330SZachary Turner llvm::ms_demangle::Demangler demangler;
61822566330SZachary Turner StringView name{pub->Name.begin(), pub->Name.size()};
61922566330SZachary Turner llvm::ms_demangle::SymbolNode *node = demangler.parse(name);
62022566330SZachary Turner if (!node)
62106bf5d85SNathan Lanza return FromCompilerDeclContext(GetTranslationUnitDecl());
62222566330SZachary Turner llvm::ArrayRef<llvm::ms_demangle::Node *> name_components{
62322566330SZachary Turner node->Name->Components->Nodes, node->Name->Components->Count - 1};
62422566330SZachary Turner
62522566330SZachary Turner if (!name_components.empty()) {
62622566330SZachary Turner // Render the current list of scope nodes as a fully qualified name, and
62722566330SZachary Turner // look it up in the debug info as a type name. If we find something,
62822566330SZachary Turner // this is a type (which may itself be prefixed by a namespace). If we
62922566330SZachary Turner // don't, this is a list of namespaces.
63022566330SZachary Turner std::string qname = RenderScopeList(name_components);
63122566330SZachary Turner std::vector<TypeIndex> matches = m_index.tpi().findRecordsByName(qname);
63222566330SZachary Turner while (!matches.empty()) {
63322566330SZachary Turner clang::QualType qt = GetOrCreateType(matches.back());
6345c9f3ec4SZequan Wu if (qt.isNull())
6355c9f3ec4SZequan Wu continue;
63622566330SZachary Turner clang::TagDecl *tag = qt->getAsTagDecl();
63722566330SZachary Turner if (tag)
63822566330SZachary Turner return clang::TagDecl::castToDeclContext(tag);
63922566330SZachary Turner matches.pop_back();
640594c85e9SZachary Turner }
64122566330SZachary Turner }
64222566330SZachary Turner
64322566330SZachary Turner // It's not a type. It must be a series of namespaces.
64406bf5d85SNathan Lanza auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
64522566330SZachary Turner while (!name_components.empty()) {
64622566330SZachary Turner std::string ns = name_components.front()->toString();
647ee12a75eSAleksandr Urakov context = GetOrCreateNamespaceDecl(ns.c_str(), *context);
64822566330SZachary Turner name_components = name_components.drop_front();
64922566330SZachary Turner }
65022566330SZachary Turner return context;
65122566330SZachary Turner }
65244f19514SZachary Turner
GetParentDeclContext(PdbSymUid uid)65344f19514SZachary Turner clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
65444f19514SZachary Turner // We must do this *without* calling GetOrCreate on the current uid, as
65544f19514SZachary Turner // that would be an infinite recursion.
65644f19514SZachary Turner switch (uid.kind()) {
65744f19514SZachary Turner case PdbSymUidKind::CompilandSym: {
65844f19514SZachary Turner llvm::Optional<PdbCompilandSymId> scope =
65944f19514SZachary Turner FindSymbolScope(m_index, uid.asCompilandSym());
66044f19514SZachary Turner if (scope)
66144f19514SZachary Turner return GetOrCreateDeclContextForUid(*scope);
66244f19514SZachary Turner
66344f19514SZachary Turner CVSymbol sym = m_index.ReadSymbolRecord(uid.asCompilandSym());
66444f19514SZachary Turner return GetParentDeclContextForSymbol(sym);
66544f19514SZachary Turner }
66622566330SZachary Turner case PdbSymUidKind::Type: {
667594c85e9SZachary Turner // It could be a namespace, class, or global. We don't support nested
668594c85e9SZachary Turner // functions yet. Anyway, we just need to consult the parent type map.
66922566330SZachary Turner PdbTypeSymId type_id = uid.asTypeSym();
67022566330SZachary Turner auto iter = m_parent_types.find(type_id.index);
67122566330SZachary Turner if (iter == m_parent_types.end())
67206bf5d85SNathan Lanza return FromCompilerDeclContext(GetTranslationUnitDecl());
67322566330SZachary Turner return GetOrCreateDeclContextForUid(PdbTypeSymId(iter->second));
67422566330SZachary Turner }
675594c85e9SZachary Turner case PdbSymUidKind::FieldListMember:
676594c85e9SZachary Turner // In this case the parent DeclContext is the one for the class that this
677594c85e9SZachary Turner // member is inside of.
678594c85e9SZachary Turner break;
67944f19514SZachary Turner case PdbSymUidKind::GlobalSym: {
68044f19514SZachary Turner // If this refers to a compiland symbol, just recurse in with that symbol.
68144f19514SZachary Turner // The only other possibilities are S_CONSTANT and S_UDT, in which case we
68244f19514SZachary Turner // need to parse the undecorated name to figure out the scope, then look
68344f19514SZachary Turner // that up in the TPI stream. If it's found, it's a type, othewrise it's
68444f19514SZachary Turner // a series of namespaces.
68544f19514SZachary Turner // FIXME: do this.
68644f19514SZachary Turner CVSymbol global = m_index.ReadSymbolRecord(uid.asGlobalSym());
68744f19514SZachary Turner switch (global.kind()) {
68844f19514SZachary Turner case SymbolKind::S_GDATA32:
68944f19514SZachary Turner case SymbolKind::S_LDATA32:
69044f19514SZachary Turner return GetParentDeclContextForSymbol(global);
69144f19514SZachary Turner case SymbolKind::S_PROCREF:
69244f19514SZachary Turner case SymbolKind::S_LPROCREF: {
69344f19514SZachary Turner ProcRefSym ref{global.kind()};
69444f19514SZachary Turner llvm::cantFail(
69544f19514SZachary Turner SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref));
69644f19514SZachary Turner PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset};
69744f19514SZachary Turner return GetParentDeclContext(cu_sym_id);
69844f19514SZachary Turner }
69944f19514SZachary Turner case SymbolKind::S_CONSTANT:
70044f19514SZachary Turner case SymbolKind::S_UDT:
70144f19514SZachary Turner return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;
70244f19514SZachary Turner default:
70344f19514SZachary Turner break;
70444f19514SZachary Turner }
70544f19514SZachary Turner break;
70644f19514SZachary Turner }
707594c85e9SZachary Turner default:
708594c85e9SZachary Turner break;
709594c85e9SZachary Turner }
71006bf5d85SNathan Lanza return FromCompilerDeclContext(GetTranslationUnitDecl());
711594c85e9SZachary Turner }
712594c85e9SZachary Turner
CompleteType(clang::QualType qt)713594c85e9SZachary Turner bool PdbAstBuilder::CompleteType(clang::QualType qt) {
7145c9f3ec4SZequan Wu if (qt.isNull())
7155c9f3ec4SZequan Wu return false;
716594c85e9SZachary Turner clang::TagDecl *tag = qt->getAsTagDecl();
717d6710023SZequan Wu if (qt->isArrayType()) {
718d6710023SZequan Wu const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual();
719d6710023SZequan Wu tag = element_type->getAsTagDecl();
720d6710023SZequan Wu }
721594c85e9SZachary Turner if (!tag)
722594c85e9SZachary Turner return false;
723594c85e9SZachary Turner
724594c85e9SZachary Turner return CompleteTagDecl(*tag);
725594c85e9SZachary Turner }
726594c85e9SZachary Turner
CompleteTagDecl(clang::TagDecl & tag)727594c85e9SZachary Turner bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
728594c85e9SZachary Turner // If this is not in our map, it's an error.
729594c85e9SZachary Turner auto status_iter = m_decl_to_status.find(&tag);
730594c85e9SZachary Turner lldbassert(status_iter != m_decl_to_status.end());
731594c85e9SZachary Turner
732594c85e9SZachary Turner // If it's already complete, just return.
733594c85e9SZachary Turner DeclStatus &status = status_iter->second;
734594c85e9SZachary Turner if (status.resolved)
735594c85e9SZachary Turner return true;
736594c85e9SZachary Turner
737594c85e9SZachary Turner PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym();
738594c85e9SZachary Turner
739594c85e9SZachary Turner lldbassert(IsTagRecord(type_id, m_index.tpi()));
740594c85e9SZachary Turner
741f9f49d35SRaphael Isemann clang::QualType tag_qt = m_clang.getASTContext().getTypeDeclType(&tag);
7426e3b0cc2SRaphael Isemann TypeSystemClang::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);
743594c85e9SZachary Turner
744594c85e9SZachary Turner TypeIndex tag_ti = type_id.index;
745594c85e9SZachary Turner CVType cvt = m_index.tpi().getType(tag_ti);
746594c85e9SZachary Turner if (cvt.kind() == LF_MODIFIER)
747594c85e9SZachary Turner tag_ti = LookThroughModifierRecord(cvt);
748594c85e9SZachary Turner
749594c85e9SZachary Turner PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, m_index.tpi());
750594c85e9SZachary Turner cvt = m_index.tpi().getType(best_ti.index);
751594c85e9SZachary Turner lldbassert(IsTagRecord(cvt));
752594c85e9SZachary Turner
753594c85e9SZachary Turner if (IsForwardRefUdt(cvt)) {
754594c85e9SZachary Turner // If we can't find a full decl for this forward ref anywhere in the debug
755594c85e9SZachary Turner // info, then we have no way to complete it.
756594c85e9SZachary Turner return false;
757594c85e9SZachary Turner }
758594c85e9SZachary Turner
759594c85e9SZachary Turner TypeIndex field_list_ti = GetFieldListIndex(cvt);
760594c85e9SZachary Turner CVType field_list_cvt = m_index.tpi().getType(field_list_ti);
761594c85e9SZachary Turner if (field_list_cvt.kind() != LF_FIELDLIST)
762594c85e9SZachary Turner return false;
763bd2044c1SZequan Wu FieldListRecord field_list;
764bd2044c1SZequan Wu if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
765bd2044c1SZequan Wu field_list_cvt, field_list))
766bd2044c1SZequan Wu llvm::consumeError(std::move(error));
767594c85e9SZachary Turner
768594c85e9SZachary Turner // Visit all members of this class, then perform any finalization necessary
769594c85e9SZachary Turner // to complete the class.
770594c85e9SZachary Turner CompilerType ct = ToCompilerType(tag_qt);
771a3a8ed33SZequan Wu UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index,
772a3a8ed33SZequan Wu m_cxx_record_map);
773bd2044c1SZequan Wu llvm::Error error =
774bd2044c1SZequan Wu llvm::codeview::visitMemberRecordStream(field_list.Data, completer);
775594c85e9SZachary Turner completer.complete();
776594c85e9SZachary Turner
777594c85e9SZachary Turner status.resolved = true;
778bd2044c1SZequan Wu if (error) {
779594c85e9SZachary Turner llvm::consumeError(std::move(error));
780594c85e9SZachary Turner return false;
781594c85e9SZachary Turner }
782bd2044c1SZequan Wu return true;
783bd2044c1SZequan Wu }
784594c85e9SZachary Turner
CreateSimpleType(TypeIndex ti)785594c85e9SZachary Turner clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) {
786594c85e9SZachary Turner if (ti == TypeIndex::NullptrT())
787594c85e9SZachary Turner return GetBasicType(lldb::eBasicTypeNullPtr);
788594c85e9SZachary Turner
789594c85e9SZachary Turner if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
790594c85e9SZachary Turner clang::QualType direct_type = GetOrCreateType(ti.makeDirect());
7915c9f3ec4SZequan Wu if (direct_type.isNull())
7925c9f3ec4SZequan Wu return {};
793f9f49d35SRaphael Isemann return m_clang.getASTContext().getPointerType(direct_type);
794594c85e9SZachary Turner }
795594c85e9SZachary Turner
796594c85e9SZachary Turner if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
797594c85e9SZachary Turner return {};
798594c85e9SZachary Turner
799594c85e9SZachary Turner lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind());
800594c85e9SZachary Turner if (bt == lldb::eBasicTypeInvalid)
801594c85e9SZachary Turner return {};
802594c85e9SZachary Turner
803594c85e9SZachary Turner return GetBasicType(bt);
804594c85e9SZachary Turner }
805594c85e9SZachary Turner
CreatePointerType(const PointerRecord & pointer)806594c85e9SZachary Turner clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) {
807594c85e9SZachary Turner clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType);
808594c85e9SZachary Turner
80944f19514SZachary Turner // This can happen for pointers to LF_VTSHAPE records, which we shouldn't
81044f19514SZachary Turner // create in the AST.
81144f19514SZachary Turner if (pointee_type.isNull())
81244f19514SZachary Turner return {};
81344f19514SZachary Turner
814594c85e9SZachary Turner if (pointer.isPointerToMember()) {
815594c85e9SZachary Turner MemberPointerInfo mpi = pointer.getMemberInfo();
816594c85e9SZachary Turner clang::QualType class_type = GetOrCreateType(mpi.ContainingType);
8175c9f3ec4SZequan Wu if (class_type.isNull())
8185c9f3ec4SZequan Wu return {};
819*b8cf916bSZequan Wu if (clang::TagDecl *tag = class_type->getAsTagDecl()) {
820*b8cf916bSZequan Wu clang::MSInheritanceAttr::Spelling spelling;
821*b8cf916bSZequan Wu switch (mpi.Representation) {
822*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::SingleInheritanceData:
823*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::
824*b8cf916bSZequan Wu SingleInheritanceFunction:
825*b8cf916bSZequan Wu spelling =
826*b8cf916bSZequan Wu clang::MSInheritanceAttr::Spelling::Keyword_single_inheritance;
827*b8cf916bSZequan Wu break;
828*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::
829*b8cf916bSZequan Wu MultipleInheritanceData:
830*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::
831*b8cf916bSZequan Wu MultipleInheritanceFunction:
832*b8cf916bSZequan Wu spelling =
833*b8cf916bSZequan Wu clang::MSInheritanceAttr::Spelling::Keyword_multiple_inheritance;
834*b8cf916bSZequan Wu break;
835*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::
836*b8cf916bSZequan Wu VirtualInheritanceData:
837*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::
838*b8cf916bSZequan Wu VirtualInheritanceFunction:
839*b8cf916bSZequan Wu spelling =
840*b8cf916bSZequan Wu clang::MSInheritanceAttr::Spelling::Keyword_virtual_inheritance;
841*b8cf916bSZequan Wu break;
842*b8cf916bSZequan Wu case llvm::codeview::PointerToMemberRepresentation::Unknown:
843*b8cf916bSZequan Wu spelling =
844*b8cf916bSZequan Wu clang::MSInheritanceAttr::Spelling::Keyword_unspecified_inheritance;
845*b8cf916bSZequan Wu break;
846*b8cf916bSZequan Wu default:
847*b8cf916bSZequan Wu spelling = clang::MSInheritanceAttr::Spelling::SpellingNotCalculated;
848*b8cf916bSZequan Wu break;
849*b8cf916bSZequan Wu }
850*b8cf916bSZequan Wu tag->addAttr(clang::MSInheritanceAttr::CreateImplicit(
851*b8cf916bSZequan Wu m_clang.getASTContext(), spelling));
852*b8cf916bSZequan Wu }
853f9f49d35SRaphael Isemann return m_clang.getASTContext().getMemberPointerType(
854594c85e9SZachary Turner pointee_type, class_type.getTypePtr());
855594c85e9SZachary Turner }
856594c85e9SZachary Turner
857594c85e9SZachary Turner clang::QualType pointer_type;
858594c85e9SZachary Turner if (pointer.getMode() == PointerMode::LValueReference)
859f9f49d35SRaphael Isemann pointer_type = m_clang.getASTContext().getLValueReferenceType(pointee_type);
860594c85e9SZachary Turner else if (pointer.getMode() == PointerMode::RValueReference)
861f9f49d35SRaphael Isemann pointer_type = m_clang.getASTContext().getRValueReferenceType(pointee_type);
862594c85e9SZachary Turner else
863f9f49d35SRaphael Isemann pointer_type = m_clang.getASTContext().getPointerType(pointee_type);
864594c85e9SZachary Turner
865594c85e9SZachary Turner if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None)
866594c85e9SZachary Turner pointer_type.addConst();
867594c85e9SZachary Turner
868594c85e9SZachary Turner if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None)
869594c85e9SZachary Turner pointer_type.addVolatile();
870594c85e9SZachary Turner
871594c85e9SZachary Turner if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None)
872594c85e9SZachary Turner pointer_type.addRestrict();
873594c85e9SZachary Turner
874594c85e9SZachary Turner return pointer_type;
875594c85e9SZachary Turner }
876594c85e9SZachary Turner
877594c85e9SZachary Turner clang::QualType
CreateModifierType(const ModifierRecord & modifier)878594c85e9SZachary Turner PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) {
879594c85e9SZachary Turner clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType);
88044f19514SZachary Turner if (unmodified_type.isNull())
88144f19514SZachary Turner return {};
882594c85e9SZachary Turner
883594c85e9SZachary Turner if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
884594c85e9SZachary Turner unmodified_type.addConst();
885594c85e9SZachary Turner if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
886594c85e9SZachary Turner unmodified_type.addVolatile();
887594c85e9SZachary Turner
888594c85e9SZachary Turner return unmodified_type;
889594c85e9SZachary Turner }
890594c85e9SZachary Turner
CreateRecordType(PdbTypeSymId id,const TagRecord & record)891594c85e9SZachary Turner clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
892594c85e9SZachary Turner const TagRecord &record) {
89322566330SZachary Turner clang::DeclContext *context = nullptr;
894594c85e9SZachary Turner std::string uname;
89522566330SZachary Turner std::tie(context, uname) = CreateDeclInfoForType(record, id.index);
8965c9f3ec4SZequan Wu if (!context)
8975c9f3ec4SZequan Wu return {};
8985c9f3ec4SZequan Wu
899594c85e9SZachary Turner clang::TagTypeKind ttk = TranslateUdtKind(record);
900594c85e9SZachary Turner lldb::AccessType access =
901594c85e9SZachary Turner (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic;
902594c85e9SZachary Turner
903594c85e9SZachary Turner ClangASTMetadata metadata;
904594c85e9SZachary Turner metadata.SetUserID(toOpaqueUid(id));
905594c85e9SZachary Turner metadata.SetIsDynamicCXXType(false);
906594c85e9SZachary Turner
907143d507cSAdrian Prantl CompilerType ct =
908143d507cSAdrian Prantl m_clang.CreateRecordType(context, OptionalClangModuleID(), access, uname,
909143d507cSAdrian Prantl ttk, lldb::eLanguageTypeC_plus_plus, &metadata);
910594c85e9SZachary Turner
911594c85e9SZachary Turner lldbassert(ct.IsValid());
912594c85e9SZachary Turner
9136e3b0cc2SRaphael Isemann TypeSystemClang::StartTagDeclarationDefinition(ct);
914594c85e9SZachary Turner
915594c85e9SZachary Turner // Even if it's possible, don't complete it at this point. Just mark it
916594c85e9SZachary Turner // forward resolved, and if/when LLDB needs the full definition, it can
917594c85e9SZachary Turner // ask us.
918594c85e9SZachary Turner clang::QualType result =
919594c85e9SZachary Turner clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
920594c85e9SZachary Turner
9216e3b0cc2SRaphael Isemann TypeSystemClang::SetHasExternalStorage(result.getAsOpaquePtr(), true);
922594c85e9SZachary Turner return result;
923594c85e9SZachary Turner }
924594c85e9SZachary Turner
TryGetDecl(PdbSymUid uid) const925594c85e9SZachary Turner clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
926594c85e9SZachary Turner auto iter = m_uid_to_decl.find(toOpaqueUid(uid));
927594c85e9SZachary Turner if (iter != m_uid_to_decl.end())
928594c85e9SZachary Turner return iter->second;
929594c85e9SZachary Turner return nullptr;
930594c85e9SZachary Turner }
931594c85e9SZachary Turner
932594c85e9SZachary Turner clang::NamespaceDecl *
GetOrCreateNamespaceDecl(const char * name,clang::DeclContext & context)933ee12a75eSAleksandr Urakov PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
934594c85e9SZachary Turner clang::DeclContext &context) {
935ee12a75eSAleksandr Urakov return m_clang.GetUniqueNamespaceDeclaration(
936143d507cSAdrian Prantl IsAnonymousNamespaceName(name) ? nullptr : name, &context,
937143d507cSAdrian Prantl OptionalClangModuleID());
938594c85e9SZachary Turner }
939594c85e9SZachary Turner
940594c85e9SZachary Turner clang::BlockDecl *
GetOrCreateBlockDecl(PdbCompilandSymId block_id)941594c85e9SZachary Turner PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {
942594c85e9SZachary Turner if (clang::Decl *decl = TryGetDecl(block_id))
943594c85e9SZachary Turner return llvm::dyn_cast<clang::BlockDecl>(decl);
944594c85e9SZachary Turner
945594c85e9SZachary Turner clang::DeclContext *scope = GetParentDeclContext(block_id);
946594c85e9SZachary Turner
947143d507cSAdrian Prantl clang::BlockDecl *block_decl =
948143d507cSAdrian Prantl m_clang.CreateBlockDeclaration(scope, OptionalClangModuleID());
949594c85e9SZachary Turner m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
95022566330SZachary Turner
95122566330SZachary Turner DeclStatus status;
95222566330SZachary Turner status.resolved = true;
95322566330SZachary Turner status.uid = toOpaqueUid(block_id);
95422566330SZachary Turner m_decl_to_status.insert({block_decl, status});
95522566330SZachary Turner
956594c85e9SZachary Turner return block_decl;
957594c85e9SZachary Turner }
958594c85e9SZachary Turner
CreateVariableDecl(PdbSymUid uid,CVSymbol sym,clang::DeclContext & scope)9593790029dSZachary Turner clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,
9603790029dSZachary Turner clang::DeclContext &scope) {
9613790029dSZachary Turner VariableInfo var_info = GetVariableNameInfo(sym);
9623790029dSZachary Turner clang::QualType qt = GetOrCreateType(var_info.type);
9635c9f3ec4SZequan Wu if (qt.isNull())
9645c9f3ec4SZequan Wu return nullptr;
9653790029dSZachary Turner
9663790029dSZachary Turner clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
967143d507cSAdrian Prantl &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt);
9683790029dSZachary Turner
9693790029dSZachary Turner m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
97022566330SZachary Turner DeclStatus status;
97122566330SZachary Turner status.resolved = true;
97222566330SZachary Turner status.uid = toOpaqueUid(uid);
97322566330SZachary Turner m_decl_to_status.insert({var_decl, status});
9743790029dSZachary Turner return var_decl;
9753790029dSZachary Turner }
9763790029dSZachary Turner
977594c85e9SZachary Turner clang::VarDecl *
GetOrCreateVariableDecl(PdbCompilandSymId scope_id,PdbCompilandSymId var_id)97822566330SZachary Turner PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
979594c85e9SZachary Turner PdbCompilandSymId var_id) {
980594c85e9SZachary Turner if (clang::Decl *decl = TryGetDecl(var_id))
981594c85e9SZachary Turner return llvm::dyn_cast<clang::VarDecl>(decl);
982594c85e9SZachary Turner
983594c85e9SZachary Turner clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id);
984c45975cbSZequan Wu if (!scope)
985c45975cbSZequan Wu return nullptr;
986594c85e9SZachary Turner
9873790029dSZachary Turner CVSymbol sym = m_index.ReadSymbolRecord(var_id);
9883790029dSZachary Turner return CreateVariableDecl(PdbSymUid(var_id), sym, *scope);
9893790029dSZachary Turner }
990594c85e9SZachary Turner
GetOrCreateVariableDecl(PdbGlobalSymId var_id)99122566330SZachary Turner clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) {
9923790029dSZachary Turner if (clang::Decl *decl = TryGetDecl(var_id))
9933790029dSZachary Turner return llvm::dyn_cast<clang::VarDecl>(decl);
994594c85e9SZachary Turner
9953790029dSZachary Turner CVSymbol sym = m_index.ReadSymbolRecord(var_id);
99606bf5d85SNathan Lanza auto context = FromCompilerDeclContext(GetTranslationUnitDecl());
99706bf5d85SNathan Lanza return CreateVariableDecl(PdbSymUid(var_id), sym, *context);
998594c85e9SZachary Turner }
999594c85e9SZachary Turner
100044f19514SZachary Turner clang::TypedefNameDecl *
GetOrCreateTypedefDecl(PdbGlobalSymId id)100144f19514SZachary Turner PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
100244f19514SZachary Turner if (clang::Decl *decl = TryGetDecl(id))
100344f19514SZachary Turner return llvm::dyn_cast<clang::TypedefNameDecl>(decl);
100444f19514SZachary Turner
100544f19514SZachary Turner CVSymbol sym = m_index.ReadSymbolRecord(id);
100644f19514SZachary Turner lldbassert(sym.kind() == S_UDT);
100744f19514SZachary Turner UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
100844f19514SZachary Turner
100944f19514SZachary Turner clang::DeclContext *scope = GetParentDeclContext(id);
101044f19514SZachary Turner
101144f19514SZachary Turner PdbTypeSymId real_type_id{udt.Type, false};
101244f19514SZachary Turner clang::QualType qt = GetOrCreateType(real_type_id);
10135c9f3ec4SZequan Wu if (qt.isNull())
10145c9f3ec4SZequan Wu return nullptr;
101544f19514SZachary Turner
1016adcd0268SBenjamin Kramer std::string uname = std::string(DropNameScope(udt.Name));
101744f19514SZachary Turner
1018722247c8SRaphael Isemann CompilerType ct = ToCompilerType(qt).CreateTypedef(
1019722247c8SRaphael Isemann uname.c_str(), ToCompilerDeclContext(*scope), 0);
102044f19514SZachary Turner clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
102144f19514SZachary Turner DeclStatus status;
102244f19514SZachary Turner status.resolved = true;
102344f19514SZachary Turner status.uid = toOpaqueUid(id);
102444f19514SZachary Turner m_decl_to_status.insert({tnd, status});
102544f19514SZachary Turner return tnd;
102644f19514SZachary Turner }
102744f19514SZachary Turner
GetBasicType(lldb::BasicType type)1028594c85e9SZachary Turner clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) {
1029594c85e9SZachary Turner CompilerType ct = m_clang.GetBasicType(type);
1030594c85e9SZachary Turner return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
1031594c85e9SZachary Turner }
1032594c85e9SZachary Turner
CreateType(PdbTypeSymId type)1033594c85e9SZachary Turner clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {
1034594c85e9SZachary Turner if (type.index.isSimple())
1035594c85e9SZachary Turner return CreateSimpleType(type.index);
1036594c85e9SZachary Turner
1037594c85e9SZachary Turner CVType cvt = m_index.tpi().getType(type.index);
1038594c85e9SZachary Turner
1039594c85e9SZachary Turner if (cvt.kind() == LF_MODIFIER) {
1040594c85e9SZachary Turner ModifierRecord modifier;
1041594c85e9SZachary Turner llvm::cantFail(
1042594c85e9SZachary Turner TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
1043594c85e9SZachary Turner return CreateModifierType(modifier);
1044594c85e9SZachary Turner }
1045594c85e9SZachary Turner
1046594c85e9SZachary Turner if (cvt.kind() == LF_POINTER) {
1047594c85e9SZachary Turner PointerRecord pointer;
1048594c85e9SZachary Turner llvm::cantFail(
1049594c85e9SZachary Turner TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
1050594c85e9SZachary Turner return CreatePointerType(pointer);
1051594c85e9SZachary Turner }
1052594c85e9SZachary Turner
1053594c85e9SZachary Turner if (IsTagRecord(cvt)) {
1054594c85e9SZachary Turner CVTagRecord tag = CVTagRecord::create(cvt);
1055594c85e9SZachary Turner if (tag.kind() == CVTagRecord::Union)
1056594c85e9SZachary Turner return CreateRecordType(type.index, tag.asUnion());
1057594c85e9SZachary Turner if (tag.kind() == CVTagRecord::Enum)
1058594c85e9SZachary Turner return CreateEnumType(type.index, tag.asEnum());
1059594c85e9SZachary Turner return CreateRecordType(type.index, tag.asClass());
1060594c85e9SZachary Turner }
1061594c85e9SZachary Turner
1062594c85e9SZachary Turner if (cvt.kind() == LF_ARRAY) {
1063594c85e9SZachary Turner ArrayRecord ar;
1064594c85e9SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
1065594c85e9SZachary Turner return CreateArrayType(ar);
1066594c85e9SZachary Turner }
1067594c85e9SZachary Turner
1068594c85e9SZachary Turner if (cvt.kind() == LF_PROCEDURE) {
1069594c85e9SZachary Turner ProcedureRecord pr;
1070594c85e9SZachary Turner llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
1071ee7c61f1SAleksandr Urakov return CreateFunctionType(pr.ArgumentList, pr.ReturnType, pr.CallConv);
1072ee7c61f1SAleksandr Urakov }
1073ee7c61f1SAleksandr Urakov
1074ee7c61f1SAleksandr Urakov if (cvt.kind() == LF_MFUNCTION) {
1075ee7c61f1SAleksandr Urakov MemberFunctionRecord mfr;
1076ee7c61f1SAleksandr Urakov llvm::cantFail(
1077ee7c61f1SAleksandr Urakov TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr));
1078ee7c61f1SAleksandr Urakov return CreateFunctionType(mfr.ArgumentList, mfr.ReturnType, mfr.CallConv);
1079594c85e9SZachary Turner }
1080594c85e9SZachary Turner
1081594c85e9SZachary Turner return {};
1082594c85e9SZachary Turner }
1083594c85e9SZachary Turner
GetOrCreateType(PdbTypeSymId type)1084594c85e9SZachary Turner clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) {
10855c9f3ec4SZequan Wu if (type.index.isNoneType())
10865c9f3ec4SZequan Wu return {};
10875c9f3ec4SZequan Wu
1088594c85e9SZachary Turner lldb::user_id_t uid = toOpaqueUid(type);
1089594c85e9SZachary Turner auto iter = m_uid_to_type.find(uid);
1090594c85e9SZachary Turner if (iter != m_uid_to_type.end())
1091594c85e9SZachary Turner return iter->second;
1092594c85e9SZachary Turner
1093594c85e9SZachary Turner PdbTypeSymId best_type = GetBestPossibleDecl(type, m_index.tpi());
1094594c85e9SZachary Turner
1095594c85e9SZachary Turner clang::QualType qt;
1096594c85e9SZachary Turner if (best_type.index != type.index) {
1097594c85e9SZachary Turner // This is a forward decl. Call GetOrCreate on the full decl, then map the
1098594c85e9SZachary Turner // forward decl id to the full decl QualType.
1099594c85e9SZachary Turner clang::QualType qt = GetOrCreateType(best_type);
11005c9f3ec4SZequan Wu if (qt.isNull())
11015c9f3ec4SZequan Wu return {};
1102594c85e9SZachary Turner m_uid_to_type[toOpaqueUid(type)] = qt;
1103594c85e9SZachary Turner return qt;
1104594c85e9SZachary Turner }
1105594c85e9SZachary Turner
1106594c85e9SZachary Turner // This is either a full decl, or a forward decl with no matching full decl
1107594c85e9SZachary Turner // in the debug info.
1108594c85e9SZachary Turner qt = CreateType(type);
11095c9f3ec4SZequan Wu if (qt.isNull())
11105c9f3ec4SZequan Wu return {};
11115c9f3ec4SZequan Wu
1112594c85e9SZachary Turner m_uid_to_type[toOpaqueUid(type)] = qt;
1113594c85e9SZachary Turner if (IsTagRecord(type, m_index.tpi())) {
1114594c85e9SZachary Turner clang::TagDecl *tag = qt->getAsTagDecl();
1115594c85e9SZachary Turner lldbassert(m_decl_to_status.count(tag) == 0);
1116594c85e9SZachary Turner
1117594c85e9SZachary Turner DeclStatus &status = m_decl_to_status[tag];
1118594c85e9SZachary Turner status.uid = uid;
1119594c85e9SZachary Turner status.resolved = false;
1120594c85e9SZachary Turner }
1121594c85e9SZachary Turner return qt;
1122594c85e9SZachary Turner }
1123594c85e9SZachary Turner
1124594c85e9SZachary Turner clang::FunctionDecl *
CreateFunctionDecl(PdbCompilandSymId func_id,llvm::StringRef func_name,TypeIndex func_ti,CompilerType func_ct,uint32_t param_count,clang::StorageClass func_storage,bool is_inline,clang::DeclContext * parent)1125c45975cbSZequan Wu PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id,
1126c45975cbSZequan Wu llvm::StringRef func_name, TypeIndex func_ti,
1127c45975cbSZequan Wu CompilerType func_ct, uint32_t param_count,
1128c45975cbSZequan Wu clang::StorageClass func_storage,
1129c45975cbSZequan Wu bool is_inline, clang::DeclContext *parent) {
1130c45975cbSZequan Wu clang::FunctionDecl *function_decl = nullptr;
1131c45975cbSZequan Wu if (parent->isRecord()) {
1132c45975cbSZequan Wu clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent)
1133c45975cbSZequan Wu ->getTypeForDecl()
1134c45975cbSZequan Wu ->getCanonicalTypeInternal();
1135c45975cbSZequan Wu lldb::opaque_compiler_type_t parent_opaque_ty =
1136c45975cbSZequan Wu ToCompilerType(parent_qt).GetOpaqueQualType();
1137d6710023SZequan Wu // FIXME: Remove this workaround.
1138c45975cbSZequan Wu auto iter = m_cxx_record_map.find(parent_opaque_ty);
1139c45975cbSZequan Wu if (iter != m_cxx_record_map.end()) {
1140c45975cbSZequan Wu if (iter->getSecond().contains({func_name, func_ct})) {
1141c45975cbSZequan Wu return nullptr;
1142c45975cbSZequan Wu }
1143c45975cbSZequan Wu }
1144c45975cbSZequan Wu
1145c45975cbSZequan Wu CVType cvt = m_index.tpi().getType(func_ti);
1146c45975cbSZequan Wu MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind()));
1147c45975cbSZequan Wu llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(
1148c45975cbSZequan Wu cvt, func_record));
1149c45975cbSZequan Wu TypeIndex class_index = func_record.getClassType();
1150c45975cbSZequan Wu
1151c45975cbSZequan Wu CVType parent_cvt = m_index.tpi().getType(class_index);
1152d6710023SZequan Wu TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag();
1153c45975cbSZequan Wu // If it's a forward reference, try to get the real TypeIndex.
1154d6710023SZequan Wu if (tag_record.isForwardRef()) {
1155c45975cbSZequan Wu llvm::Expected<TypeIndex> eti =
1156c45975cbSZequan Wu m_index.tpi().findFullDeclForForwardRef(class_index);
1157c45975cbSZequan Wu if (eti) {
1158d6710023SZequan Wu tag_record = CVTagRecord::create(m_index.tpi().getType(*eti)).asTag();
1159c45975cbSZequan Wu }
1160c45975cbSZequan Wu }
1161d6710023SZequan Wu if (!tag_record.FieldList.isSimple()) {
1162bd2044c1SZequan Wu CVType field_list_cvt = m_index.tpi().getType(tag_record.FieldList);
1163bd2044c1SZequan Wu FieldListRecord field_list;
1164bd2044c1SZequan Wu if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>(
1165bd2044c1SZequan Wu field_list_cvt, field_list))
1166bd2044c1SZequan Wu llvm::consumeError(std::move(error));
1167c45975cbSZequan Wu CreateMethodDecl process(m_index, m_clang, func_ti, function_decl,
1168c45975cbSZequan Wu parent_opaque_ty, func_name, func_ct);
1169bd2044c1SZequan Wu if (llvm::Error err = visitMemberRecordStream(field_list.Data, process))
1170c45975cbSZequan Wu llvm::consumeError(std::move(err));
1171c45975cbSZequan Wu }
1172c45975cbSZequan Wu
1173c45975cbSZequan Wu if (!function_decl) {
1174c45975cbSZequan Wu function_decl = m_clang.AddMethodToCXXRecordType(
1175c45975cbSZequan Wu parent_opaque_ty, func_name,
1176c45975cbSZequan Wu /*mangled_name=*/nullptr, func_ct,
1177c45975cbSZequan Wu /*access=*/lldb::AccessType::eAccessPublic,
1178c45975cbSZequan Wu /*is_virtual=*/false, /*is_static=*/false,
1179c45975cbSZequan Wu /*is_inline=*/false, /*is_explicit=*/false,
1180c45975cbSZequan Wu /*is_attr_used=*/false, /*is_artificial=*/false);
1181c45975cbSZequan Wu }
1182c45975cbSZequan Wu m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct});
1183c45975cbSZequan Wu } else {
1184c45975cbSZequan Wu function_decl = m_clang.CreateFunctionDeclaration(
1185c45975cbSZequan Wu parent, OptionalClangModuleID(), func_name, func_ct, func_storage,
1186c45975cbSZequan Wu is_inline);
1187c45975cbSZequan Wu CreateFunctionParameters(func_id, *function_decl, param_count);
1188c45975cbSZequan Wu }
1189c45975cbSZequan Wu return function_decl;
1190c45975cbSZequan Wu }
1191c45975cbSZequan Wu
1192c45975cbSZequan Wu clang::FunctionDecl *
GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id)1193c45975cbSZequan Wu PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) {
1194c45975cbSZequan Wu CompilandIndexItem *cii =
1195c45975cbSZequan Wu m_index.compilands().GetCompiland(inlinesite_id.modi);
1196c45975cbSZequan Wu CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset);
1197c45975cbSZequan Wu InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind()));
1198c45975cbSZequan Wu cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site));
1199c45975cbSZequan Wu
1200c45975cbSZequan Wu // Inlinee is the id index to the function id record that is inlined.
1201c45975cbSZequan Wu PdbTypeSymId func_id(inline_site.Inlinee, true);
1202c45975cbSZequan Wu // Look up the function decl by the id index to see if we have created a
1203c45975cbSZequan Wu // function decl for a different inlinesite that refers the same function.
1204c45975cbSZequan Wu if (clang::Decl *decl = TryGetDecl(func_id))
1205c45975cbSZequan Wu return llvm::dyn_cast<clang::FunctionDecl>(decl);
1206c45975cbSZequan Wu clang::FunctionDecl *function_decl =
1207c45975cbSZequan Wu CreateFunctionDeclFromId(func_id, inlinesite_id);
1208d6710023SZequan Wu if (function_decl == nullptr)
1209d6710023SZequan Wu return nullptr;
1210c45975cbSZequan Wu
1211c45975cbSZequan Wu // Use inline site id in m_decl_to_status because it's expected to be a
1212c45975cbSZequan Wu // PdbCompilandSymId so that we can parse local variables info after it.
1213c45975cbSZequan Wu uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id);
1214c45975cbSZequan Wu DeclStatus status;
1215c45975cbSZequan Wu status.resolved = true;
1216c45975cbSZequan Wu status.uid = inlinesite_uid;
1217c45975cbSZequan Wu m_decl_to_status.insert({function_decl, status});
1218c45975cbSZequan Wu // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI
1219c45975cbSZequan Wu // stream are unique and there could be multiple inline sites (different ids)
1220c45975cbSZequan Wu // referring the same inline function. This avoid creating multiple same
1221c45975cbSZequan Wu // inline function delcs.
1222c45975cbSZequan Wu uint64_t func_uid = toOpaqueUid(func_id);
1223c45975cbSZequan Wu lldbassert(m_uid_to_decl.count(func_uid) == 0);
1224c45975cbSZequan Wu m_uid_to_decl[func_uid] = function_decl;
1225c45975cbSZequan Wu return function_decl;
1226c45975cbSZequan Wu }
1227c45975cbSZequan Wu
1228c45975cbSZequan Wu clang::FunctionDecl *
CreateFunctionDeclFromId(PdbTypeSymId func_tid,PdbCompilandSymId func_sid)1229c45975cbSZequan Wu PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid,
1230c45975cbSZequan Wu PdbCompilandSymId func_sid) {
1231c45975cbSZequan Wu lldbassert(func_tid.is_ipi);
1232c45975cbSZequan Wu CVType func_cvt = m_index.ipi().getType(func_tid.index);
1233c45975cbSZequan Wu llvm::StringRef func_name;
1234c45975cbSZequan Wu TypeIndex func_ti;
1235c45975cbSZequan Wu clang::DeclContext *parent = nullptr;
1236c45975cbSZequan Wu switch (func_cvt.kind()) {
1237c45975cbSZequan Wu case LF_MFUNC_ID: {
1238c45975cbSZequan Wu MemberFuncIdRecord mfr;
1239c45975cbSZequan Wu cantFail(
1240c45975cbSZequan Wu TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr));
1241c45975cbSZequan Wu func_name = mfr.getName();
1242c45975cbSZequan Wu func_ti = mfr.getFunctionType();
1243c45975cbSZequan Wu PdbTypeSymId class_type_id(mfr.ClassType, false);
1244c45975cbSZequan Wu parent = GetOrCreateDeclContextForUid(class_type_id);
1245c45975cbSZequan Wu break;
1246c45975cbSZequan Wu }
1247c45975cbSZequan Wu case LF_FUNC_ID: {
1248c45975cbSZequan Wu FuncIdRecord fir;
1249c45975cbSZequan Wu cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir));
1250c45975cbSZequan Wu func_name = fir.getName();
1251c45975cbSZequan Wu func_ti = fir.getFunctionType();
1252c45975cbSZequan Wu parent = FromCompilerDeclContext(GetTranslationUnitDecl());
1253c45975cbSZequan Wu if (!fir.ParentScope.isNoneType()) {
1254c45975cbSZequan Wu CVType parent_cvt = m_index.ipi().getType(fir.ParentScope);
1255c45975cbSZequan Wu if (parent_cvt.kind() == LF_STRING_ID) {
1256c45975cbSZequan Wu StringIdRecord sir;
1257c45975cbSZequan Wu cantFail(
1258c45975cbSZequan Wu TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir));
1259c45975cbSZequan Wu parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent);
1260c45975cbSZequan Wu }
1261c45975cbSZequan Wu }
1262c45975cbSZequan Wu break;
1263c45975cbSZequan Wu }
1264c45975cbSZequan Wu default:
1265c45975cbSZequan Wu lldbassert(false && "Invalid function id type!");
1266c45975cbSZequan Wu }
1267c45975cbSZequan Wu clang::QualType func_qt = GetOrCreateType(func_ti);
1268c45975cbSZequan Wu if (func_qt.isNull())
1269c45975cbSZequan Wu return nullptr;
1270c45975cbSZequan Wu CompilerType func_ct = ToCompilerType(func_qt);
1271c45975cbSZequan Wu uint32_t param_count =
1272c45975cbSZequan Wu llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams();
1273c45975cbSZequan Wu return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count,
1274c45975cbSZequan Wu clang::SC_None, true, parent);
1275c45975cbSZequan Wu }
1276c45975cbSZequan Wu
1277c45975cbSZequan Wu clang::FunctionDecl *
GetOrCreateFunctionDecl(PdbCompilandSymId func_id)1278594c85e9SZachary Turner PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
1279594c85e9SZachary Turner if (clang::Decl *decl = TryGetDecl(func_id))
1280594c85e9SZachary Turner return llvm::dyn_cast<clang::FunctionDecl>(decl);
1281594c85e9SZachary Turner
1282594c85e9SZachary Turner clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));
128322566330SZachary Turner std::string context_name;
128422566330SZachary Turner if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) {
128522566330SZachary Turner context_name = ns->getQualifiedNameAsString();
128622566330SZachary Turner } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) {
128722566330SZachary Turner context_name = tag->getQualifiedNameAsString();
128822566330SZachary Turner }
1289594c85e9SZachary Turner
1290594c85e9SZachary Turner CVSymbol cvs = m_index.ReadSymbolRecord(func_id);
1291594c85e9SZachary Turner ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind()));
1292594c85e9SZachary Turner llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc));
1293594c85e9SZachary Turner
1294594c85e9SZachary Turner PdbTypeSymId type_id(proc.FunctionType);
1295594c85e9SZachary Turner clang::QualType qt = GetOrCreateType(type_id);
129622566330SZachary Turner if (qt.isNull())
129722566330SZachary Turner return nullptr;
1298594c85e9SZachary Turner
1299594c85e9SZachary Turner clang::StorageClass storage = clang::SC_None;
1300594c85e9SZachary Turner if (proc.Kind == SymbolRecordKind::ProcSym)
1301594c85e9SZachary Turner storage = clang::SC_Static;
1302594c85e9SZachary Turner
1303594c85e9SZachary Turner const clang::FunctionProtoType *func_type =
1304594c85e9SZachary Turner llvm::dyn_cast<clang::FunctionProtoType>(qt);
1305594c85e9SZachary Turner
1306594c85e9SZachary Turner CompilerType func_ct = ToCompilerType(qt);
1307594c85e9SZachary Turner
130822566330SZachary Turner llvm::StringRef proc_name = proc.Name;
130922566330SZachary Turner proc_name.consume_front(context_name);
131022566330SZachary Turner proc_name.consume_front("::");
131122566330SZachary Turner
1312c45975cbSZequan Wu clang::FunctionDecl *function_decl =
1313c45975cbSZequan Wu CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct,
1314c45975cbSZequan Wu func_type->getNumParams(), storage, false, parent);
1315d6710023SZequan Wu if (function_decl == nullptr)
1316d6710023SZequan Wu return nullptr;
1317594c85e9SZachary Turner
1318594c85e9SZachary Turner lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
1319594c85e9SZachary Turner m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
132022566330SZachary Turner DeclStatus status;
132122566330SZachary Turner status.resolved = true;
132222566330SZachary Turner status.uid = toOpaqueUid(func_id);
132322566330SZachary Turner m_decl_to_status.insert({function_decl, status});
1324594c85e9SZachary Turner
1325594c85e9SZachary Turner return function_decl;
1326594c85e9SZachary Turner }
1327594c85e9SZachary Turner
CreateFunctionParameters(PdbCompilandSymId func_id,clang::FunctionDecl & function_decl,uint32_t param_count)1328594c85e9SZachary Turner void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
1329594c85e9SZachary Turner clang::FunctionDecl &function_decl,
1330594c85e9SZachary Turner uint32_t param_count) {
1331594c85e9SZachary Turner CompilandIndexItem *cii = m_index.compilands().GetCompiland(func_id.modi);
1332594c85e9SZachary Turner CVSymbolArray scope =
1333594c85e9SZachary Turner cii->m_debug_stream.getSymbolArrayForScope(func_id.offset);
1334594c85e9SZachary Turner
1335dc100ebfSZequan Wu scope.drop_front();
1336594c85e9SZachary Turner auto begin = scope.begin();
1337594c85e9SZachary Turner auto end = scope.end();
1338594c85e9SZachary Turner std::vector<clang::ParmVarDecl *> params;
13391921b195SZequan Wu for (uint32_t i = 0; i < param_count && begin != end;) {
1340594c85e9SZachary Turner uint32_t record_offset = begin.offset();
1341594c85e9SZachary Turner CVSymbol sym = *begin++;
1342594c85e9SZachary Turner
1343594c85e9SZachary Turner TypeIndex param_type;
1344594c85e9SZachary Turner llvm::StringRef param_name;
1345594c85e9SZachary Turner switch (sym.kind()) {
1346594c85e9SZachary Turner case S_REGREL32: {
1347594c85e9SZachary Turner RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
1348594c85e9SZachary Turner cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
1349594c85e9SZachary Turner param_type = reg.Type;
1350594c85e9SZachary Turner param_name = reg.Name;
1351594c85e9SZachary Turner break;
1352594c85e9SZachary Turner }
1353594c85e9SZachary Turner case S_REGISTER: {
1354594c85e9SZachary Turner RegisterSym reg(SymbolRecordKind::RegisterSym);
1355594c85e9SZachary Turner cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
1356594c85e9SZachary Turner param_type = reg.Index;
1357594c85e9SZachary Turner param_name = reg.Name;
1358594c85e9SZachary Turner break;
1359594c85e9SZachary Turner }
1360594c85e9SZachary Turner case S_LOCAL: {
1361594c85e9SZachary Turner LocalSym local(SymbolRecordKind::LocalSym);
1362594c85e9SZachary Turner cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
1363594c85e9SZachary Turner if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None)
1364594c85e9SZachary Turner continue;
1365594c85e9SZachary Turner param_type = local.Type;
1366594c85e9SZachary Turner param_name = local.Name;
1367594c85e9SZachary Turner break;
1368594c85e9SZachary Turner }
1369594c85e9SZachary Turner case S_BLOCK32:
1370c50817d1SZequan Wu case S_INLINESITE:
1371c50817d1SZequan Wu case S_INLINESITE2:
1372c50817d1SZequan Wu // All parameters should come before the first block/inlinesite. If that
1373c50817d1SZequan Wu // isn't the case, then perhaps this is bad debug info that doesn't
1374c50817d1SZequan Wu // contain information about all parameters.
1375594c85e9SZachary Turner return;
1376594c85e9SZachary Turner default:
1377594c85e9SZachary Turner continue;
1378594c85e9SZachary Turner }
1379594c85e9SZachary Turner
1380594c85e9SZachary Turner PdbCompilandSymId param_uid(func_id.modi, record_offset);
1381594c85e9SZachary Turner clang::QualType qt = GetOrCreateType(param_type);
13825c9f3ec4SZequan Wu if (qt.isNull())
13835c9f3ec4SZequan Wu return;
1384594c85e9SZachary Turner
1385fe8e25a4SRaphael Isemann CompilerType param_type_ct = m_clang.GetType(qt);
1386594c85e9SZachary Turner clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
1387143d507cSAdrian Prantl &function_decl, OptionalClangModuleID(), param_name.str().c_str(),
1388143d507cSAdrian Prantl param_type_ct, clang::SC_None, true);
1389594c85e9SZachary Turner lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
1390594c85e9SZachary Turner
1391594c85e9SZachary Turner m_uid_to_decl[toOpaqueUid(param_uid)] = param;
1392594c85e9SZachary Turner params.push_back(param);
13931921b195SZequan Wu ++i;
1394594c85e9SZachary Turner }
1395594c85e9SZachary Turner
13961921b195SZequan Wu if (!params.empty() && params.size() == param_count)
13977177c595SRaphael Isemann m_clang.SetFunctionParameters(&function_decl, params);
1398594c85e9SZachary Turner }
1399594c85e9SZachary Turner
CreateEnumType(PdbTypeSymId id,const EnumRecord & er)1400594c85e9SZachary Turner clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
1401594c85e9SZachary Turner const EnumRecord &er) {
1402594c85e9SZachary Turner clang::DeclContext *decl_context = nullptr;
1403594c85e9SZachary Turner std::string uname;
1404594c85e9SZachary Turner std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index);
14055c9f3ec4SZequan Wu if (!decl_context)
14065c9f3ec4SZequan Wu return {};
14075c9f3ec4SZequan Wu
1408594c85e9SZachary Turner clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType);
14095c9f3ec4SZequan Wu if (underlying_type.isNull())
14105c9f3ec4SZequan Wu return {};
1411594c85e9SZachary Turner
1412594c85e9SZachary Turner Declaration declaration;
1413594c85e9SZachary Turner CompilerType enum_ct = m_clang.CreateEnumerationType(
1414b738a69aSRaphael Isemann uname, decl_context, OptionalClangModuleID(), declaration,
1415143d507cSAdrian Prantl ToCompilerType(underlying_type), er.isScoped());
1416594c85e9SZachary Turner
14176e3b0cc2SRaphael Isemann TypeSystemClang::StartTagDeclarationDefinition(enum_ct);
14186e3b0cc2SRaphael Isemann TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
1419594c85e9SZachary Turner
1420594c85e9SZachary Turner return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType());
1421594c85e9SZachary Turner }
1422594c85e9SZachary Turner
CreateArrayType(const ArrayRecord & ar)1423594c85e9SZachary Turner clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
1424594c85e9SZachary Turner clang::QualType element_type = GetOrCreateType(ar.ElementType);
1425594c85e9SZachary Turner
1426583223cdSZequan Wu uint64_t element_size = GetSizeOfType({ar.ElementType}, m_index.tpi());
14275c9f3ec4SZequan Wu if (element_type.isNull() || element_size == 0)
1428583223cdSZequan Wu return {};
1429583223cdSZequan Wu uint64_t element_count = ar.Size / element_size;
1430594c85e9SZachary Turner
1431594c85e9SZachary Turner CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type),
1432594c85e9SZachary Turner element_count, false);
1433594c85e9SZachary Turner return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());
1434594c85e9SZachary Turner }
1435594c85e9SZachary Turner
CreateFunctionType(TypeIndex args_type_idx,TypeIndex return_type_idx,llvm::codeview::CallingConvention calling_convention)1436ee7c61f1SAleksandr Urakov clang::QualType PdbAstBuilder::CreateFunctionType(
1437ee7c61f1SAleksandr Urakov TypeIndex args_type_idx, TypeIndex return_type_idx,
1438ee7c61f1SAleksandr Urakov llvm::codeview::CallingConvention calling_convention) {
1439594c85e9SZachary Turner TpiStream &stream = m_index.tpi();
1440ee7c61f1SAleksandr Urakov CVType args_cvt = stream.getType(args_type_idx);
1441594c85e9SZachary Turner ArgListRecord args;
1442594c85e9SZachary Turner llvm::cantFail(
1443594c85e9SZachary Turner TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));
1444594c85e9SZachary Turner
1445594c85e9SZachary Turner llvm::ArrayRef<TypeIndex> arg_indices = llvm::makeArrayRef(args.ArgIndices);
1446594c85e9SZachary Turner bool is_variadic = IsCVarArgsFunction(arg_indices);
1447594c85e9SZachary Turner if (is_variadic)
1448594c85e9SZachary Turner arg_indices = arg_indices.drop_back();
1449594c85e9SZachary Turner
1450594c85e9SZachary Turner std::vector<CompilerType> arg_types;
1451594c85e9SZachary Turner arg_types.reserve(arg_indices.size());
1452594c85e9SZachary Turner
1453594c85e9SZachary Turner for (TypeIndex arg_index : arg_indices) {
1454594c85e9SZachary Turner clang::QualType arg_type = GetOrCreateType(arg_index);
14555c9f3ec4SZequan Wu if (arg_type.isNull())
14565c9f3ec4SZequan Wu continue;
1457594c85e9SZachary Turner arg_types.push_back(ToCompilerType(arg_type));
1458594c85e9SZachary Turner }
1459594c85e9SZachary Turner
1460ee7c61f1SAleksandr Urakov clang::QualType return_type = GetOrCreateType(return_type_idx);
14615c9f3ec4SZequan Wu if (return_type.isNull())
14625c9f3ec4SZequan Wu return {};
1463594c85e9SZachary Turner
1464594c85e9SZachary Turner llvm::Optional<clang::CallingConv> cc =
1465ee7c61f1SAleksandr Urakov TranslateCallingConvention(calling_convention);
1466594c85e9SZachary Turner if (!cc)
1467594c85e9SZachary Turner return {};
1468594c85e9SZachary Turner
1469594c85e9SZachary Turner CompilerType return_ct = ToCompilerType(return_type);
1470594c85e9SZachary Turner CompilerType func_sig_ast_type = m_clang.CreateFunctionType(
1471594c85e9SZachary Turner return_ct, arg_types.data(), arg_types.size(), is_variadic, 0, *cc);
1472594c85e9SZachary Turner
1473594c85e9SZachary Turner return clang::QualType::getFromOpaquePtr(
1474594c85e9SZachary Turner func_sig_ast_type.GetOpaqueQualType());
1475594c85e9SZachary Turner }
1476594c85e9SZachary Turner
isTagDecl(clang::DeclContext & context)147722566330SZachary Turner static bool isTagDecl(clang::DeclContext &context) {
147862e48ed1SKazu Hirata return llvm::isa<clang::TagDecl>(&context);
147922566330SZachary Turner }
148022566330SZachary Turner
isFunctionDecl(clang::DeclContext & context)148122566330SZachary Turner static bool isFunctionDecl(clang::DeclContext &context) {
148262e48ed1SKazu Hirata return llvm::isa<clang::FunctionDecl>(&context);
148322566330SZachary Turner }
148422566330SZachary Turner
isBlockDecl(clang::DeclContext & context)148522566330SZachary Turner static bool isBlockDecl(clang::DeclContext &context) {
148662e48ed1SKazu Hirata return llvm::isa<clang::BlockDecl>(&context);
148722566330SZachary Turner }
148822566330SZachary Turner
ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent)148922566330SZachary Turner void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
149022566330SZachary Turner llvm::Optional<llvm::StringRef> parent) {
149122566330SZachary Turner TypeIndex ti{m_index.tpi().TypeIndexBegin()};
149222566330SZachary Turner for (const CVType &cvt : m_index.tpi().typeArray()) {
149322566330SZachary Turner PdbTypeSymId tid{ti};
149422566330SZachary Turner ++ti;
149522566330SZachary Turner
149622566330SZachary Turner if (!IsTagRecord(cvt))
149722566330SZachary Turner continue;
149822566330SZachary Turner
149922566330SZachary Turner CVTagRecord tag = CVTagRecord::create(cvt);
150022566330SZachary Turner
15015413bf1bSKazu Hirata if (!parent) {
150222566330SZachary Turner clang::QualType qt = GetOrCreateType(tid);
150322566330SZachary Turner CompleteType(qt);
150422566330SZachary Turner continue;
150522566330SZachary Turner }
150622566330SZachary Turner
150722566330SZachary Turner // Call CreateDeclInfoForType unconditionally so that the namespace info
150822566330SZachary Turner // gets created. But only call CreateRecordType if the namespace name
150922566330SZachary Turner // matches.
151022566330SZachary Turner clang::DeclContext *context = nullptr;
151122566330SZachary Turner std::string uname;
151222566330SZachary Turner std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index);
15135c9f3ec4SZequan Wu if (!context || !context->isNamespace())
151422566330SZachary Turner continue;
151522566330SZachary Turner
1516d7aa402bSSimon Pilgrim clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context);
151722566330SZachary Turner std::string actual_ns = ns->getQualifiedNameAsString();
151822566330SZachary Turner if (llvm::StringRef(actual_ns).startswith(*parent)) {
151922566330SZachary Turner clang::QualType qt = GetOrCreateType(tid);
152022566330SZachary Turner CompleteType(qt);
152122566330SZachary Turner continue;
152222566330SZachary Turner }
152322566330SZachary Turner }
152422566330SZachary Turner
152522566330SZachary Turner uint32_t module_count = m_index.dbi().modules().getModuleCount();
152622566330SZachary Turner for (uint16_t modi = 0; modi < module_count; ++modi) {
152722566330SZachary Turner CompilandIndexItem &cii = m_index.compilands().GetOrCreateCompiland(modi);
152822566330SZachary Turner const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
152922566330SZachary Turner auto iter = symbols.begin();
153022566330SZachary Turner while (iter != symbols.end()) {
153122566330SZachary Turner PdbCompilandSymId sym_id{modi, iter.offset()};
153222566330SZachary Turner
153322566330SZachary Turner switch (iter->kind()) {
153422566330SZachary Turner case S_GPROC32:
153522566330SZachary Turner case S_LPROC32:
153622566330SZachary Turner GetOrCreateFunctionDecl(sym_id);
153722566330SZachary Turner iter = symbols.at(getScopeEndOffset(*iter));
153822566330SZachary Turner break;
153922566330SZachary Turner case S_GDATA32:
154022566330SZachary Turner case S_GTHREAD32:
154122566330SZachary Turner case S_LDATA32:
154222566330SZachary Turner case S_LTHREAD32:
154322566330SZachary Turner GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
154422566330SZachary Turner ++iter;
154522566330SZachary Turner break;
154622566330SZachary Turner default:
154722566330SZachary Turner ++iter;
154822566330SZachary Turner continue;
154922566330SZachary Turner }
155022566330SZachary Turner }
155122566330SZachary Turner }
155222566330SZachary Turner }
155322566330SZachary Turner
skipFunctionParameters(clang::Decl & decl,const CVSymbolArray & symbols)155422566330SZachary Turner static CVSymbolArray skipFunctionParameters(clang::Decl &decl,
155522566330SZachary Turner const CVSymbolArray &symbols) {
155622566330SZachary Turner clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>(&decl);
155722566330SZachary Turner if (!func_decl)
155822566330SZachary Turner return symbols;
155922566330SZachary Turner unsigned int params = func_decl->getNumParams();
156022566330SZachary Turner if (params == 0)
156122566330SZachary Turner return symbols;
156222566330SZachary Turner
156322566330SZachary Turner CVSymbolArray result = symbols;
156422566330SZachary Turner
156522566330SZachary Turner while (!result.empty()) {
156622566330SZachary Turner if (params == 0)
156722566330SZachary Turner return result;
156822566330SZachary Turner
156922566330SZachary Turner CVSymbol sym = *result.begin();
157022566330SZachary Turner result.drop_front();
157122566330SZachary Turner
157222566330SZachary Turner if (!isLocalVariableType(sym.kind()))
157322566330SZachary Turner continue;
157422566330SZachary Turner
157522566330SZachary Turner --params;
157622566330SZachary Turner }
157722566330SZachary Turner return result;
157822566330SZachary Turner }
157922566330SZachary Turner
ParseBlockChildren(PdbCompilandSymId block_id)158022566330SZachary Turner void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) {
158122566330SZachary Turner CVSymbol sym = m_index.ReadSymbolRecord(block_id);
158222566330SZachary Turner lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 ||
1583c45975cbSZequan Wu sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE);
158422566330SZachary Turner CompilandIndexItem &cii =
158522566330SZachary Turner m_index.compilands().GetOrCreateCompiland(block_id.modi);
158622566330SZachary Turner CVSymbolArray symbols =
158722566330SZachary Turner cii.m_debug_stream.getSymbolArrayForScope(block_id.offset);
158822566330SZachary Turner
158922566330SZachary Turner // Function parameters should already have been created when the function was
159022566330SZachary Turner // parsed.
159122566330SZachary Turner if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32)
159222566330SZachary Turner symbols =
159322566330SZachary Turner skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols);
159422566330SZachary Turner
1595c45975cbSZequan Wu symbols.drop_front();
159622566330SZachary Turner auto begin = symbols.begin();
159722566330SZachary Turner while (begin != symbols.end()) {
159822566330SZachary Turner PdbCompilandSymId child_sym_id(block_id.modi, begin.offset());
159922566330SZachary Turner GetOrCreateSymbolForId(child_sym_id);
1600c45975cbSZequan Wu if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) {
160122566330SZachary Turner ParseBlockChildren(child_sym_id);
160222566330SZachary Turner begin = symbols.at(getScopeEndOffset(*begin));
160322566330SZachary Turner }
160422566330SZachary Turner ++begin;
160522566330SZachary Turner }
160622566330SZachary Turner }
160722566330SZachary Turner
ParseDeclsForSimpleContext(clang::DeclContext & context)160822566330SZachary Turner void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) {
160922566330SZachary Turner
161022566330SZachary Turner clang::Decl *decl = clang::Decl::castFromDeclContext(&context);
161122566330SZachary Turner lldbassert(decl);
161222566330SZachary Turner
161322566330SZachary Turner auto iter = m_decl_to_status.find(decl);
161422566330SZachary Turner lldbassert(iter != m_decl_to_status.end());
161522566330SZachary Turner
161622566330SZachary Turner if (auto *tag = llvm::dyn_cast<clang::TagDecl>(&context)) {
161722566330SZachary Turner CompleteTagDecl(*tag);
161822566330SZachary Turner return;
161922566330SZachary Turner }
162022566330SZachary Turner
162122566330SZachary Turner if (isFunctionDecl(context) || isBlockDecl(context)) {
162222566330SZachary Turner PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym();
162322566330SZachary Turner ParseBlockChildren(block_id);
162422566330SZachary Turner }
162522566330SZachary Turner }
162622566330SZachary Turner
ParseDeclsForContext(clang::DeclContext & context)162722566330SZachary Turner void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {
162822566330SZachary Turner // Namespaces aren't explicitly represented in the debug info, and the only
162922566330SZachary Turner // way to parse them is to parse all type info, demangling every single type
163022566330SZachary Turner // and trying to reconstruct the DeclContext hierarchy this way. Since this
163122566330SZachary Turner // is an expensive operation, we have to special case it so that we do other
163222566330SZachary Turner // work (such as parsing the items that appear within the namespaces) at the
163322566330SZachary Turner // same time.
163422566330SZachary Turner if (context.isTranslationUnit()) {
163522566330SZachary Turner ParseAllNamespacesPlusChildrenOf(llvm::None);
163622566330SZachary Turner return;
163722566330SZachary Turner }
163822566330SZachary Turner
163922566330SZachary Turner if (context.isNamespace()) {
164022566330SZachary Turner clang::NamespaceDecl &ns = *llvm::dyn_cast<clang::NamespaceDecl>(&context);
164122566330SZachary Turner std::string qname = ns.getQualifiedNameAsString();
164222566330SZachary Turner ParseAllNamespacesPlusChildrenOf(llvm::StringRef{qname});
164322566330SZachary Turner return;
164422566330SZachary Turner }
164522566330SZachary Turner
164622566330SZachary Turner if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) {
164722566330SZachary Turner ParseDeclsForSimpleContext(context);
164822566330SZachary Turner return;
164922566330SZachary Turner }
165022566330SZachary Turner }
165122566330SZachary Turner
ToCompilerDecl(clang::Decl & decl)1652594c85e9SZachary Turner CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {
165346ca55f2SRaphael Isemann return m_clang.GetCompilerDecl(&decl);
1654594c85e9SZachary Turner }
1655594c85e9SZachary Turner
ToCompilerType(clang::QualType qt)1656594c85e9SZachary Turner CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {
1657594c85e9SZachary Turner return {&m_clang, qt.getAsOpaquePtr()};
1658594c85e9SZachary Turner }
1659594c85e9SZachary Turner
1660594c85e9SZachary Turner CompilerDeclContext
ToCompilerDeclContext(clang::DeclContext & context)1661594c85e9SZachary Turner PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {
166242ec584aSRaphael Isemann return m_clang.CreateDeclContext(&context);
1663594c85e9SZachary Turner }
1664594c85e9SZachary Turner
FromCompilerDecl(CompilerDecl decl)16653b96ebeeSNathan Lanza clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) {
166609217b60SRaphael Isemann return ClangUtil::GetDecl(decl);
16673b96ebeeSNathan Lanza }
16683b96ebeeSNathan Lanza
166922566330SZachary Turner clang::DeclContext *
FromCompilerDeclContext(CompilerDeclContext context)167022566330SZachary Turner PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
167122566330SZachary Turner return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());
167222566330SZachary Turner }
167322566330SZachary Turner
Dump(Stream & stream)16749a57d1e5SRaphael Isemann void PdbAstBuilder::Dump(Stream &stream) {
16759a57d1e5SRaphael Isemann m_clang.Dump(stream.AsRawOstream());
16769a57d1e5SRaphael Isemann }
1677