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