1//===-- LVCodeViewVisitor.cpp ---------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This implements the LVCodeViewVisitor class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h"
14#include "llvm/BinaryFormat/Magic.h"
15#include "llvm/DebugInfo/CodeView/EnumTables.h"
16#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
17#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
18#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
19#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
20#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
21#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
22#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
23#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h"
24#include "llvm/DebugInfo/PDB/Native/InputFile.h"
25#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
26#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
27#include "llvm/Demangle/Demangle.h"
28#include "llvm/Object/COFF.h"
29#include "llvm/Support/Error.h"
30#include "llvm/Support/FormatAdapters.h"
31#include "llvm/Support/FormatVariadic.h"
32
33using namespace llvm;
34using namespace llvm::codeview;
35using namespace llvm::object;
36using namespace llvm::pdb;
37using namespace llvm::logicalview;
38
39#define DEBUG_TYPE "CodeViewUtilities"
40
41namespace llvm {
42namespace logicalview {
43
44static TypeIndex getTrueType(TypeIndex &TI) {
45 // Dealing with a MSVC generated PDB, we encountered a type index with the
46 // value of: 0x0280xxxx where xxxx=0000.
47 //
48 // There is some documentation about type indices:
49 // https://llvm.org/docs/PDB/TpiStream.html
50 //
51 // A type index is a 32-bit integer that uniquely identifies a type inside
52 // of an object file’s .debug$T section or a PDB file’s TPI or IPI stream.
53 // The value of the type index for the first type record from the TPI stream
54 // is given by the TypeIndexBegin member of the TPI Stream Header although
55 // in practice this value is always equal to 0x1000 (4096).
56 //
57 // Any type index with a high bit set is considered to come from the IPI
58 // stream, although this appears to be more of a hack, and LLVM does not
59 // generate type indices of this nature. They can, however, be observed in
60 // Microsoft PDBs occasionally, so one should be prepared to handle them.
61 // Note that having the high bit set is not a necessary condition to
62 // determine whether a type index comes from the IPI stream, it is only
63 // sufficient.
64 LLVM_DEBUG(
65 { dbgs() << "Index before: " << HexNumber(TI.getIndex()) << "\n"; });
66 TI.setIndex(TI.getIndex() & 0x0000ffff);
67 LLVM_DEBUG(
68 { dbgs() << "Index after: " << HexNumber(TI.getIndex()) << "\n"; });
69 return TI;
70}
71
72// Return the type name pointed by the type index. It uses the kind to query
73// the associated name for the record type.
74static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI) {
75 if (TI.isSimple())
76 return {};
77
78 StringRef RecordName;
79 CVType CVReference = Types.getType(Index: TI);
80 auto GetName = [&](auto Record) {
81 if (Error Err = TypeDeserializer::deserializeAs(
82 const_cast<CVType &>(CVReference), Record))
83 consumeError(Err: std::move(Err));
84 else
85 RecordName = Record.getName();
86 };
87
88 TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());
89 if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
90 GetName(ClassRecord(RK));
91 else if (RK == TypeRecordKind::Union)
92 GetName(UnionRecord(RK));
93 else if (RK == TypeRecordKind::Enum)
94 GetName(EnumRecord(RK));
95
96 return RecordName;
97}
98
99} // namespace logicalview
100} // namespace llvm
101
102#undef DEBUG_TYPE
103#define DEBUG_TYPE "CodeViewDataVisitor"
104
105namespace llvm {
106namespace logicalview {
107
108// Keeps the type indexes with line information.
109using LVLineRecords = std::vector<TypeIndex>;
110
111namespace {
112
113class LVTypeRecords {
114 LVShared *Shared = nullptr;
115
116 // Logical elements associated to their CodeView Type Index.
117 using RecordEntry = std::pair<TypeLeafKind, LVElement *>;
118 using RecordTable = std::map<TypeIndex, RecordEntry>;
119 RecordTable RecordFromTypes;
120 RecordTable RecordFromIds;
121
122 using NameTable = std::map<StringRef, TypeIndex>;
123 NameTable NameFromTypes;
124 NameTable NameFromIds;
125
126public:
127 LVTypeRecords(LVShared *Shared) : Shared(Shared) {}
128
129 void add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,
130 LVElement *Element = nullptr);
131 void add(uint32_t StreamIdx, TypeIndex TI, StringRef Name);
132 LVElement *find(uint32_t StreamIdx, TypeIndex TI, bool Create = true);
133 TypeIndex find(uint32_t StreamIdx, StringRef Name);
134};
135
136class LVForwardReferences {
137 // Forward reference and its definitions (Name as key).
138 using ForwardEntry = std::pair<TypeIndex, TypeIndex>;
139 using ForwardTypeNames = std::map<StringRef, ForwardEntry>;
140 ForwardTypeNames ForwardTypesNames;
141
142 // Forward reference and its definition (TypeIndex as key).
143 using ForwardType = std::map<TypeIndex, TypeIndex>;
144 ForwardType ForwardTypes;
145
146 // Forward types and its references.
147 void add(TypeIndex TIForward, TypeIndex TIReference) {
148 ForwardTypes.emplace(args&: TIForward, args&: TIReference);
149 }
150
151 void add(StringRef Name, TypeIndex TIForward) {
152 auto [It, Inserted] =
153 ForwardTypesNames.try_emplace(k: Name, args&: TIForward, args: TypeIndex::None());
154 if (!Inserted) {
155 // Update a recorded definition with its reference.
156 It->second.first = TIForward;
157 add(TIForward, TIReference: It->second.second);
158 }
159 }
160
161 // Update a previously recorded forward reference with its definition.
162 void update(StringRef Name, TypeIndex TIReference) {
163 auto [It, Inserted] =
164 ForwardTypesNames.try_emplace(k: Name, args: TypeIndex::None(), args&: TIReference);
165 if (!Inserted) {
166 // Update the recorded forward reference with its definition.
167 It->second.second = TIReference;
168 add(TIForward: It->second.first, TIReference);
169 }
170 }
171
172public:
173 LVForwardReferences() = default;
174
175 void record(bool IsForwardRef, StringRef Name, TypeIndex TI) {
176 // We are expecting for the forward references to be first. But that
177 // is not always the case. A name must be recorded regardless of the
178 // order in which the forward reference appears.
179 (IsForwardRef) ? add(Name, TIForward: TI) : update(Name, TIReference: TI);
180 }
181
182 TypeIndex find(TypeIndex TIForward) {
183 auto It = ForwardTypes.find(x: TIForward);
184 return It != ForwardTypes.end() ? It->second : TypeIndex::None();
185 }
186
187 TypeIndex find(StringRef Name) {
188 auto It = ForwardTypesNames.find(x: Name);
189 return It != ForwardTypesNames.end() ? It->second.second
190 : TypeIndex::None();
191 }
192
193 // If the given TI corresponds to a reference, return the reference.
194 // Otherwise return the given TI.
195 TypeIndex remap(TypeIndex TI) {
196 TypeIndex Forward = find(TIForward: TI);
197 return Forward.isNoneType() ? TI : Forward;
198 }
199};
200
201// Namespace deduction.
202class LVNamespaceDeduction {
203 LVShared *Shared = nullptr;
204
205 using Names = std::map<StringRef, LVScope *>;
206 Names NamespaceNames;
207
208 using LookupSet = std::set<StringRef>;
209 LookupSet DeducedScopes;
210 LookupSet UnresolvedScopes;
211 LookupSet IdentifiedNamespaces;
212
213 void add(StringRef Name, LVScope *Namespace) {
214 if (NamespaceNames.find(x: Name) == NamespaceNames.end())
215 NamespaceNames.emplace(args&: Name, args&: Namespace);
216 }
217
218public:
219 LVNamespaceDeduction(LVShared *Shared) : Shared(Shared) {}
220
221 void init();
222 void add(StringRef String);
223 LVScope *get(LVStringRefs Components);
224 LVScope *get(StringRef Name, bool CheckScope = true);
225
226 // Find the logical namespace for the 'Name' component.
227 LVScope *find(StringRef Name) {
228 auto It = NamespaceNames.find(x: Name);
229 LVScope *Namespace = It != NamespaceNames.end() ? It->second : nullptr;
230 return Namespace;
231 }
232
233 // For the given lexical components, return a tuple with the first entry
234 // being the outermost namespace and the second entry being the first
235 // non-namespace.
236 LVLexicalIndex find(LVStringRefs Components) {
237 if (Components.empty())
238 return {};
239
240 LVStringRefs::size_type FirstNamespace = 0;
241 LVStringRefs::size_type FirstNonNamespace;
242 for (LVStringRefs::size_type Index = 0; Index < Components.size();
243 ++Index) {
244 FirstNonNamespace = Index;
245 LookupSet::iterator Iter = IdentifiedNamespaces.find(x: Components[Index]);
246 if (Iter == IdentifiedNamespaces.end())
247 // The component is not a namespace name.
248 break;
249 }
250 return std::make_tuple(args&: FirstNamespace, args&: FirstNonNamespace);
251 }
252};
253
254// Strings.
255class LVStringRecords {
256 using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
257 using StringIds = std::map<TypeIndex, StringEntry>;
258 StringIds Strings;
259
260public:
261 LVStringRecords() = default;
262
263 void add(TypeIndex TI, StringRef String) {
264 static uint32_t Index = 0;
265 auto [It, Inserted] = Strings.try_emplace(k: TI);
266 if (Inserted)
267 It->second = std::make_tuple(args&: ++Index, args: std::string(String), args: nullptr);
268 }
269
270 StringRef find(TypeIndex TI) {
271 StringIds::iterator Iter = Strings.find(x: TI);
272 return Iter != Strings.end() ? std::get<1>(t&: Iter->second) : StringRef{};
273 }
274
275 uint32_t findIndex(TypeIndex TI) {
276 StringIds::iterator Iter = Strings.find(x: TI);
277 return Iter != Strings.end() ? std::get<0>(t&: Iter->second) : 0;
278 }
279
280 // Move strings representing the filenames to the compile unit.
281 void addFilenames();
282 void addFilenames(LVScopeCompileUnit *Scope);
283};
284} // namespace
285
286using LVTypeKinds = std::set<TypeLeafKind>;
287using LVSymbolKinds = std::set<SymbolKind>;
288
289// The following data keeps forward information, type records, names for
290// namespace deduction, strings records, line records.
291// It is shared by the type visitor, symbol visitor and logical visitor and
292// it is independent from the CodeViewReader.
293struct LVShared {
294 LVCodeViewReader *Reader;
295 LVLogicalVisitor *Visitor;
296 LVForwardReferences ForwardReferences;
297 LVLineRecords LineRecords;
298 LVNamespaceDeduction NamespaceDeduction;
299 LVStringRecords StringRecords;
300 LVTypeRecords TypeRecords;
301
302 // In order to determine which types and/or symbols records should be handled
303 // by the reader, we record record kinds seen by the type and symbol visitors.
304 // At the end of the scopes creation, the '--internal=tag' option will allow
305 // to print the unique record ids collected.
306 LVTypeKinds TypeKinds;
307 LVSymbolKinds SymbolKinds;
308
309 LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)
310 : Reader(Reader), Visitor(Visitor), NamespaceDeduction(this),
311 TypeRecords(this) {}
312 ~LVShared() = default;
313};
314} // namespace logicalview
315} // namespace llvm
316
317void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,
318 LVElement *Element) {
319 RecordTable &Target =
320 (StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;
321 Target.emplace(args: std::piecewise_construct, args: std::forward_as_tuple(args&: TI),
322 args: std::forward_as_tuple(args&: Kind, args&: Element));
323}
324
325void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef Name) {
326 NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;
327 Target.emplace(args&: Name, args&: TI);
328}
329
330LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI, bool Create) {
331 RecordTable &Target =
332 (StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;
333
334 LVElement *Element = nullptr;
335 RecordTable::iterator Iter = Target.find(x: TI);
336 if (Iter != Target.end()) {
337 Element = Iter->second.second;
338 if (Element || !Create)
339 return Element;
340
341 // Create the logical element if not found.
342 Element = Shared->Visitor->createElement(Kind: Iter->second.first);
343 if (Element) {
344 Element->setOffset(TI.getIndex());
345 Element->setOffsetFromTypeIndex();
346 Target[TI].second = Element;
347 }
348 }
349 return Element;
350}
351
352TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef Name) {
353 NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;
354 NameTable::iterator Iter = Target.find(x: Name);
355 return Iter != Target.end() ? Iter->second : TypeIndex::None();
356}
357
358void LVStringRecords::addFilenames() {
359 for (StringIds::const_reference Entry : Strings) {
360 StringRef Name = std::get<1>(t: Entry.second);
361 LVScopeCompileUnit *Scope = std::get<2>(t: Entry.second);
362 Scope->addFilename(Name: transformPath(Path: Name));
363 }
364 Strings.clear();
365}
366
367void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {
368 for (StringIds::reference Entry : Strings)
369 if (!std::get<2>(t&: Entry.second))
370 std::get<2>(t&: Entry.second) = Scope;
371}
372
373void LVNamespaceDeduction::add(StringRef String) {
374 StringRef InnerComponent;
375 StringRef OuterComponent;
376 std::tie(args&: OuterComponent, args&: InnerComponent) = getInnerComponent(Name: String);
377 DeducedScopes.insert(x: InnerComponent);
378 if (OuterComponent.size())
379 UnresolvedScopes.insert(x: OuterComponent);
380}
381
382void LVNamespaceDeduction::init() {
383 // We have 2 sets of names:
384 // - deduced scopes (class, structure, union and enum) and
385 // - unresolved scopes, that can represent namespaces or any deduced.
386 // Before creating the namespaces, we have to traverse the unresolved
387 // and remove any references to already deduced scopes.
388 LVStringRefs Components;
389 for (const StringRef &Unresolved : UnresolvedScopes) {
390 Components = getAllLexicalComponents(Name: Unresolved);
391 for (const StringRef &Component : Components) {
392 LookupSet::iterator Iter = DeducedScopes.find(x: Component);
393 if (Iter == DeducedScopes.end())
394 IdentifiedNamespaces.insert(x: Component);
395 }
396 }
397
398 LLVM_DEBUG({
399 auto Print = [&](LookupSet &Container, const char *Title) {
400 auto Header = [&]() {
401 dbgs() << formatv("\n{0}\n", fmt_repeat('=', 72));
402 dbgs() << formatv("{0}\n", Title);
403 dbgs() << formatv("{0}\n", fmt_repeat('=', 72));
404 };
405 Header();
406 for (const StringRef &Item : Container)
407 dbgs() << formatv("'{0}'\n", Item);
408 };
409
410 Print(DeducedScopes, "Deducted Scopes");
411 Print(UnresolvedScopes, "Unresolved Scopes");
412 Print(IdentifiedNamespaces, "Namespaces");
413 });
414}
415
416LVScope *LVNamespaceDeduction::get(LVStringRefs Components) {
417 LLVM_DEBUG({
418 for (const StringRef &Component : Components)
419 dbgs() << formatv("'{0}'\n", Component);
420 });
421
422 if (Components.empty())
423 return nullptr;
424
425 // Update the namespaces relationship.
426 LVScope *Namespace = nullptr;
427 LVScope *Parent = Shared->Reader->getCompileUnit();
428 for (const StringRef &Component : Components) {
429 // Check if we have seen the namespace.
430 Namespace = find(Name: Component);
431 if (!Namespace) {
432 // We have identified namespaces that are generated by MSVC. Mark them
433 // as 'system' so they will be excluded from the logical view.
434 Namespace = Shared->Reader->createScopeNamespace();
435 Namespace->setTag(dwarf::DW_TAG_namespace);
436 Namespace->setName(Component);
437 Parent->addElement(Scope: Namespace);
438 getReader().isSystemEntry(Element: Namespace);
439 add(Name: Component, Namespace);
440 }
441 Parent = Namespace;
442 }
443 return Parent;
444}
445
446LVScope *LVNamespaceDeduction::get(StringRef ScopedName, bool CheckScope) {
447 LVStringRefs Components = getAllLexicalComponents(Name: ScopedName);
448 if (CheckScope)
449 llvm::erase_if(C&: Components, P: [&](StringRef Component) {
450 LookupSet::iterator Iter = IdentifiedNamespaces.find(x: Component);
451 return Iter == IdentifiedNamespaces.end();
452 });
453
454 LLVM_DEBUG({ dbgs() << formatv("ScopedName: '{0}'\n", ScopedName); });
455
456 return get(Components);
457}
458
459#undef DEBUG_TYPE
460#define DEBUG_TYPE "CodeViewTypeVisitor"
461
462//===----------------------------------------------------------------------===//
463// TypeRecord traversal.
464//===----------------------------------------------------------------------===//
465void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
466 uint32_t StreamIdx) const {
467 codeview::printTypeIndex(Printer&: W, FieldName, TI,
468 Types&: StreamIdx == StreamTPI ? Types : Ids);
469}
470
471Error LVTypeVisitor::visitTypeBegin(CVType &Record) {
472 return visitTypeBegin(Record, TI: TypeIndex::fromArrayIndex(Index: Types.size()));
473}
474
475Error LVTypeVisitor::visitTypeBegin(CVType &Record, TypeIndex TI) {
476 LLVM_DEBUG({
477 W.getOStream() << formatTypeLeafKind(Record.kind());
478 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")\n";
479 });
480
481 if (options().getInternalTag())
482 Shared->TypeKinds.insert(x: Record.kind());
483
484 // The collected type records, will be use to create the logical elements
485 // during the symbols traversal when a type is referenced.
486 CurrentTypeIndex = TI;
487 Shared->TypeRecords.add(StreamIdx, TI, Kind: Record.kind());
488 return Error::success();
489}
490
491Error LVTypeVisitor::visitUnknownType(CVType &Record) {
492 LLVM_DEBUG({ W.printNumber("Length", uint32_t(Record.content().size())); });
493 return Error::success();
494}
495
496Error LVTypeVisitor::visitMemberBegin(CVMemberRecord &Record) {
497 LLVM_DEBUG({
498 W.startLine() << formatTypeLeafKind(Record.Kind);
499 W.getOStream() << " {\n";
500 W.indent();
501 });
502 return Error::success();
503}
504
505Error LVTypeVisitor::visitMemberEnd(CVMemberRecord &Record) {
506 LLVM_DEBUG({
507 W.unindent();
508 W.startLine() << "}\n";
509 });
510 return Error::success();
511}
512
513Error LVTypeVisitor::visitUnknownMember(CVMemberRecord &Record) {
514 LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
515 return Error::success();
516}
517
518// LF_BUILDINFO (TPI)/(IPI)
519Error LVTypeVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &Args) {
520 // All the args are references into the TPI/IPI stream.
521 LLVM_DEBUG({
522 W.printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
523 ListScope Arguments(W, "Arguments");
524 for (TypeIndex Arg : Args.getArgs())
525 printTypeIndex("ArgType", Arg, StreamIPI);
526 });
527
528 // Only add the strings that hold information about filenames. They will be
529 // used to complete the line/file information for the logical elements.
530 // There are other strings holding information about namespaces.
531 TypeIndex TI;
532 StringRef String;
533
534 // Absolute CWD path
535 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];
536 String = Ids.getTypeName(Index: TI);
537 if (!String.empty())
538 Shared->StringRecords.add(TI, String);
539
540 // Get the compile unit name.
541 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
542 String = Ids.getTypeName(Index: TI);
543 if (!String.empty())
544 Shared->StringRecords.add(TI, String);
545 LogicalVisitor->setCompileUnitName(std::string(String));
546
547 return Error::success();
548}
549
550// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)
551Error LVTypeVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class) {
552 LLVM_DEBUG({
553 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
554 printTypeIndex("FieldListType", Class.getFieldList(), StreamTPI);
555 W.printString("Name", Class.getName());
556 });
557
558 // Collect class name for scope deduction.
559 Shared->NamespaceDeduction.add(String: Class.getName());
560 Shared->ForwardReferences.record(IsForwardRef: Class.isForwardRef(), Name: Class.getName(),
561 TI: CurrentTypeIndex);
562
563 // Collect class name for contained scopes deduction.
564 Shared->TypeRecords.add(StreamIdx, TI: CurrentTypeIndex, Name: Class.getName());
565 return Error::success();
566}
567
568// LF_ENUM (TPI)
569Error LVTypeVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum) {
570 LLVM_DEBUG({
571 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
572 printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);
573 W.printString("Name", Enum.getName());
574 });
575
576 // Collect enum name for scope deduction.
577 Shared->NamespaceDeduction.add(String: Enum.getName());
578 return Error::success();
579}
580
581// LF_FUNC_ID (TPI)/(IPI)
582Error LVTypeVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func) {
583 LLVM_DEBUG({
584 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
585 printTypeIndex("Type", Func.getFunctionType(), StreamTPI);
586 printTypeIndex("Parent", Func.getParentScope(), StreamTPI);
587 W.printString("Name", Func.getName());
588 });
589
590 // Collect function name for scope deduction.
591 Shared->NamespaceDeduction.add(String: Func.getName());
592 return Error::success();
593}
594
595// LF_PROCEDURE (TPI)
596Error LVTypeVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc) {
597 LLVM_DEBUG({
598 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
599 printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);
600 W.printNumber("NumParameters", Proc.getParameterCount());
601 printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);
602 });
603
604 // Collect procedure information as they can be referenced by typedefs.
605 Shared->TypeRecords.add(StreamIdx: StreamTPI, TI: CurrentTypeIndex, Kind: {});
606 return Error::success();
607}
608
609// LF_STRING_ID (TPI)/(IPI)
610Error LVTypeVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String) {
611 // No additional references are needed.
612 LLVM_DEBUG({
613 printTypeIndex("Id", String.getId(), StreamIPI);
614 W.printString("StringData", String.getString());
615 });
616 return Error::success();
617}
618
619// LF_UDT_SRC_LINE (TPI)/(IPI)
620Error LVTypeVisitor::visitKnownRecord(CVType &Record,
621 UdtSourceLineRecord &Line) {
622 // UDT and SourceFile are references into the TPI/IPI stream.
623 LLVM_DEBUG({
624 printTypeIndex("UDT", Line.getUDT(), StreamIPI);
625 printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);
626 W.printNumber("LineNumber", Line.getLineNumber());
627 });
628
629 Shared->LineRecords.push_back(x: CurrentTypeIndex);
630 return Error::success();
631}
632
633// LF_UNION (TPI)
634Error LVTypeVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union) {
635 LLVM_DEBUG({
636 W.printNumber("MemberCount", Union.getMemberCount());
637 printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);
638 W.printNumber("SizeOf", Union.getSize());
639 W.printString("Name", Union.getName());
640 if (Union.hasUniqueName())
641 W.printString("UniqueName", Union.getUniqueName());
642 });
643
644 // Collect union name for scope deduction.
645 Shared->NamespaceDeduction.add(String: Union.getName());
646 Shared->ForwardReferences.record(IsForwardRef: Union.isForwardRef(), Name: Union.getName(),
647 TI: CurrentTypeIndex);
648
649 // Collect class name for contained scopes deduction.
650 Shared->TypeRecords.add(StreamIdx, TI: CurrentTypeIndex, Name: Union.getName());
651 return Error::success();
652}
653
654#undef DEBUG_TYPE
655#define DEBUG_TYPE "CodeViewSymbolVisitor"
656
657//===----------------------------------------------------------------------===//
658// SymbolRecord traversal.
659//===----------------------------------------------------------------------===//
660void LVSymbolVisitorDelegate::printRelocatedField(StringRef Label,
661 uint32_t RelocOffset,
662 uint32_t Offset,
663 StringRef *RelocSym) {
664 Reader->printRelocatedField(Label, CoffSection, RelocOffset, Offset,
665 RelocSym);
666}
667
668void LVSymbolVisitorDelegate::getLinkageName(uint32_t RelocOffset,
669 uint32_t Offset,
670 StringRef *RelocSym) {
671 Reader->getLinkageName(CoffSection, RelocOffset, Offset, RelocSym);
672}
673
674StringRef
675LVSymbolVisitorDelegate::getFileNameForFileOffset(uint32_t FileOffset) {
676 Expected<StringRef> Name = Reader->getFileNameForFileOffset(FileOffset);
677 if (!Name) {
678 consumeError(Err: Name.takeError());
679 return {};
680 }
681 return *Name;
682}
683
684DebugStringTableSubsectionRef LVSymbolVisitorDelegate::getStringTable() {
685 return Reader->CVStringTable;
686}
687
688void LVSymbolVisitor::printLocalVariableAddrRange(
689 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
690 DictScope S(W, "LocalVariableAddrRange");
691 if (ObjDelegate)
692 ObjDelegate->printRelocatedField(Label: "OffsetStart", RelocOffset: RelocationOffset,
693 Offset: Range.OffsetStart);
694 W.printHex(Label: "ISectStart", Value: Range.ISectStart);
695 W.printHex(Label: "Range", Value: Range.Range);
696}
697
698void LVSymbolVisitor::printLocalVariableAddrGap(
699 ArrayRef<LocalVariableAddrGap> Gaps) {
700 for (const LocalVariableAddrGap &Gap : Gaps) {
701 ListScope S(W, "LocalVariableAddrGap");
702 W.printHex(Label: "GapStartOffset", Value: Gap.GapStartOffset);
703 W.printHex(Label: "Range", Value: Gap.Range);
704 }
705}
706
707void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
708 codeview::printTypeIndex(Printer&: W, FieldName, TI, Types);
709}
710
711Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record) {
712 return visitSymbolBegin(Record, Offset: 0);
713}
714
715Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record, uint32_t Offset) {
716 SymbolKind Kind = Record.kind();
717 LLVM_DEBUG({
718 W.printNumber("Offset", Offset);
719 W.printEnum("Begin Kind", unsigned(Kind), getSymbolTypeNames());
720 });
721
722 if (options().getInternalTag())
723 Shared->SymbolKinds.insert(x: Kind);
724
725 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(Kind);
726 if (!LogicalVisitor->CurrentElement) {
727 LLVM_DEBUG({
728 // We have an unsupported Symbol or Type Record.
729 // W.printEnum("Kind ignored", unsigned(Kind), getSymbolTypeNames());
730 });
731 return Error::success();
732 }
733
734 // Offset carried by the traversal routines when dealing with streams.
735 CurrentOffset = Offset;
736 IsCompileUnit = false;
737 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
738 LogicalVisitor->CurrentElement->setOffset(Offset);
739 if (symbolOpensScope(Kind) || (IsCompileUnit = symbolIsCompileUnit(Kind))) {
740 assert(LogicalVisitor->CurrentScope && "Invalid scope!");
741 LogicalVisitor->addElement(Scope: LogicalVisitor->CurrentScope, IsCompileUnit);
742 } else {
743 if (LogicalVisitor->CurrentSymbol)
744 LogicalVisitor->addElement(Symbol: LogicalVisitor->CurrentSymbol);
745 if (LogicalVisitor->CurrentType)
746 LogicalVisitor->addElement(Type: LogicalVisitor->CurrentType);
747 }
748
749 return Error::success();
750}
751
752Error LVSymbolVisitor::visitSymbolEnd(CVSymbol &Record) {
753 SymbolKind Kind = Record.kind();
754 LLVM_DEBUG(
755 { W.printEnum("End Kind", unsigned(Kind), getSymbolTypeNames()); });
756
757 if (symbolEndsScope(Kind)) {
758 LogicalVisitor->popScope();
759 }
760
761 return Error::success();
762}
763
764Error LVSymbolVisitor::visitUnknownSymbol(CVSymbol &Record) {
765 LLVM_DEBUG({ W.printNumber("Length", Record.length()); });
766 return Error::success();
767}
768
769// S_BLOCK32
770Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, BlockSym &Block) {
771 LLVM_DEBUG({
772 W.printHex("CodeSize", Block.CodeSize);
773 W.printHex("Segment", Block.Segment);
774 W.printString("BlockName", Block.Name);
775 });
776
777 if (LVScope *Scope = LogicalVisitor->CurrentScope) {
778 StringRef LinkageName;
779 if (ObjDelegate)
780 ObjDelegate->getLinkageName(RelocOffset: Block.getRelocationOffset(), Offset: Block.CodeOffset,
781 RelocSym: &LinkageName);
782 Scope->setLinkageName(LinkageName);
783
784 if (options().getGeneralCollectRanges()) {
785 // Record converted segment::offset addressing for this scope.
786 LVAddress Addendum = Reader->getSymbolTableAddress(Name: LinkageName);
787 LVAddress LowPC =
788 Reader->linearAddress(Segment: Block.Segment, Offset: Block.CodeOffset, Addendum);
789 LVAddress HighPC = LowPC + Block.CodeSize - 1;
790 Scope->addObject(LowerAddress: LowPC, UpperAddress: HighPC);
791 }
792 }
793
794 return Error::success();
795}
796
797// S_BPREL32
798Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
799 BPRelativeSym &Local) {
800 LLVM_DEBUG({
801 printTypeIndex("Type", Local.Type);
802 W.printNumber("Offset", Local.Offset);
803 W.printString("VarName", Local.Name);
804 });
805
806 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
807 Symbol->setName(Local.Name);
808 // From the MS_Symbol_Type.pdf documentation (S_BPREL32):
809 // This symbol specifies symbols that are allocated on the stack for a
810 // procedure. For C and C++, these include the actual function parameters
811 // and the local non-static variables of functions.
812 // However, the offset for 'this' comes as a negative value.
813
814 // Symbol was created as 'variable'; determine its real kind.
815 Symbol->resetIsVariable();
816
817 if (Local.Name == "this") {
818 Symbol->setIsParameter();
819 Symbol->setIsArtificial();
820 } else {
821 // Determine symbol kind.
822 bool(Local.Offset > 0) ? Symbol->setIsParameter()
823 : Symbol->setIsVariable();
824 }
825
826 // Update correct debug information tag.
827 if (Symbol->getIsParameter())
828 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
829
830 setLocalVariableType(Symbol, TI: Local.Type);
831 }
832
833 return Error::success();
834}
835
836// S_REGREL32
837Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
838 RegRelativeSym &Local) {
839 LLVM_DEBUG({
840 printTypeIndex("Type", Local.Type);
841 W.printNumber("Offset", Local.Offset);
842 W.printString("VarName", Local.Name);
843 });
844
845 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
846 Symbol->setName(Local.Name);
847
848 // Symbol was created as 'variable'; determine its real kind.
849 Symbol->resetIsVariable();
850
851 // Check for the 'this' symbol.
852 if (Local.Name == "this") {
853 Symbol->setIsArtificial();
854 Symbol->setIsParameter();
855 } else {
856 // Determine symbol kind.
857 determineSymbolKind(Symbol, Register: Local.Register);
858 }
859
860 // Update correct debug information tag.
861 if (Symbol->getIsParameter())
862 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
863
864 setLocalVariableType(Symbol, TI: Local.Type);
865 }
866
867 return Error::success();
868}
869
870// S_REGREL32_INDIR
871Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
872 RegRelativeIndirSym &Local) {
873 LLVM_DEBUG({
874 printTypeIndex("Type", Local.Type);
875 W.printNumber("Offset", Local.Offset);
876 W.printNumber("OffsetInUdt", Local.OffsetInUdt);
877 W.printString("VarName", Local.Name);
878 });
879
880 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
881 Symbol->setName(Local.Name);
882
883 // Symbol was created as 'variable'; determine its real kind.
884 Symbol->resetIsVariable();
885
886 // Check for the 'this' symbol.
887 if (Local.Name == "this") {
888 Symbol->setIsArtificial();
889 Symbol->setIsParameter();
890 } else {
891 // Determine symbol kind.
892 determineSymbolKind(Symbol, Register: Local.Register);
893 }
894
895 // Update correct debug information tag.
896 if (Symbol->getIsParameter())
897 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
898
899 setLocalVariableType(Symbol, TI: Local.Type);
900 }
901
902 return Error::success();
903}
904
905// S_BUILDINFO
906Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
907 BuildInfoSym &BuildInfo) {
908 LLVM_DEBUG({ printTypeIndex("BuildId", BuildInfo.BuildId); });
909
910 CVType CVBuildType = Ids.getType(Index: BuildInfo.BuildId);
911 if (Error Err = LogicalVisitor->finishVisitation(
912 Record&: CVBuildType, TI: BuildInfo.BuildId, Element: Reader->getCompileUnit()))
913 return Err;
914
915 return Error::success();
916}
917
918// S_COMPILE2
919Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
920 Compile2Sym &Compile2) {
921 LLVM_DEBUG({
922 W.printEnum("Language", uint8_t(Compile2.getLanguage()),
923 getSourceLanguageNames());
924 W.printFlags("Flags", uint32_t(Compile2.getFlags()),
925 getCompileSym3FlagNames());
926 W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
927 W.printString("VersionName", Compile2.Version);
928 });
929
930 // MSVC generates the following sequence for a CodeView module:
931 // S_OBJNAME --> Set 'CurrentObjectName'.
932 // S_COMPILE2 --> Set the compile unit name using 'CurrentObjectName'.
933 // ...
934 // S_BUILDINFO --> Extract the source name.
935 //
936 // Clang generates the following sequence for a CodeView module:
937 // S_COMPILE2 --> Set the compile unit name to empty string.
938 // ...
939 // S_BUILDINFO --> Extract the source name.
940 //
941 // For both toolchains, update the compile unit name from S_BUILDINFO.
942 if (LVScope *Scope = LogicalVisitor->CurrentScope) {
943 // The name of the CU, was extracted from the 'BuildInfo' subsection.
944 Reader->setCompileUnitCPUType(Compile2.Machine);
945 Scope->setName(CurrentObjectName);
946 if (options().getAttributeProducer())
947 Scope->setProducer(Compile2.Version);
948 if (options().getAttributeLanguage())
949 Scope->setSourceLanguage(LVSourceLanguage{
950 static_cast<llvm::codeview::SourceLanguage>(Compile2.getLanguage())});
951 getReader().isSystemEntry(Element: Scope, Name: CurrentObjectName);
952
953 // The line records in CodeView are recorded per Module ID. Update
954 // the relationship between the current CU and the Module ID.
955 Reader->addModule(Scope);
956
957 // Updated the collected strings with their associated compile unit.
958 Shared->StringRecords.addFilenames(Scope: Reader->getCompileUnit());
959 }
960
961 // Clear any previous ObjectName.
962 CurrentObjectName = "";
963 return Error::success();
964}
965
966// S_COMPILE3
967Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
968 Compile3Sym &Compile3) {
969 LLVM_DEBUG({
970 W.printEnum("Language", uint8_t(Compile3.getLanguage()),
971 getSourceLanguageNames());
972 W.printFlags("Flags", uint32_t(Compile3.getFlags()),
973 getCompileSym3FlagNames());
974 W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
975 W.printString("VersionName", Compile3.Version);
976 });
977
978 // MSVC generates the following sequence for a CodeView module:
979 // S_OBJNAME --> Set 'CurrentObjectName'.
980 // S_COMPILE3 --> Set the compile unit name using 'CurrentObjectName'.
981 // ...
982 // S_BUILDINFO --> Extract the source name.
983 //
984 // Clang generates the following sequence for a CodeView module:
985 // S_COMPILE3 --> Set the compile unit name to empty string.
986 // ...
987 // S_BUILDINFO --> Extract the source name.
988 //
989 // For both toolchains, update the compile unit name from S_BUILDINFO.
990 if (LVScope *Scope = LogicalVisitor->CurrentScope) {
991 // The name of the CU, was extracted from the 'BuildInfo' subsection.
992 Reader->setCompileUnitCPUType(Compile3.Machine);
993 Scope->setName(CurrentObjectName);
994 if (options().getAttributeProducer())
995 Scope->setProducer(Compile3.Version);
996 if (options().getAttributeLanguage())
997 Scope->setSourceLanguage(LVSourceLanguage{
998 static_cast<llvm::codeview::SourceLanguage>(Compile3.getLanguage())});
999 getReader().isSystemEntry(Element: Scope, Name: CurrentObjectName);
1000
1001 // The line records in CodeView are recorded per Module ID. Update
1002 // the relationship between the current CU and the Module ID.
1003 Reader->addModule(Scope);
1004
1005 // Updated the collected strings with their associated compile unit.
1006 Shared->StringRecords.addFilenames(Scope: Reader->getCompileUnit());
1007 }
1008
1009 // Clear any previous ObjectName.
1010 CurrentObjectName = "";
1011 return Error::success();
1012}
1013
1014// S_CONSTANT, S_MANCONSTANT
1015Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1016 ConstantSym &Constant) {
1017 LLVM_DEBUG({
1018 printTypeIndex("Type", Constant.Type);
1019 W.printNumber("Value", Constant.Value);
1020 W.printString("Name", Constant.Name);
1021 });
1022
1023 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1024 Symbol->setName(Constant.Name);
1025 Symbol->setType(LogicalVisitor->getElement(StreamIdx: StreamTPI, TI: Constant.Type));
1026 Symbol->resetIncludeInPrint();
1027 }
1028
1029 return Error::success();
1030}
1031
1032// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
1033Error LVSymbolVisitor::visitKnownRecord(
1034 CVSymbol &Record,
1035 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
1036 // DefRanges don't have types, just registers and code offsets.
1037 LLVM_DEBUG({
1038 if (LocalSymbol)
1039 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1040
1041 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
1042 });
1043
1044 if (LVSymbol *Symbol = LocalSymbol) {
1045 Symbol->setHasCodeViewLocation();
1046 LocalSymbol = nullptr;
1047
1048 // Add location debug location. Operands: [Offset, 0].
1049 dwarf::Attribute Attr =
1050 dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE);
1051
1052 uint64_t Operand1 = DefRangeFramePointerRelFullScope.Offset;
1053 Symbol->addLocation(Attr, LowPC: 0, HighPC: 0, SectionOffset: 0, LocDescOffset: 0);
1054 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1});
1055 }
1056
1057 return Error::success();
1058}
1059
1060// S_DEFRANGE_FRAMEPOINTER_REL
1061Error LVSymbolVisitor::visitKnownRecord(
1062 CVSymbol &Record, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
1063 // DefRanges don't have types, just registers and code offsets.
1064 LLVM_DEBUG({
1065 if (LocalSymbol)
1066 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1067
1068 W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
1069 printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
1070 DefRangeFramePointerRel.getRelocationOffset());
1071 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
1072 });
1073
1074 // We are expecting the following sequence:
1075 // 128 | S_LOCAL [size = 20] `ParamBar`
1076 // ...
1077 // 148 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16]
1078 if (LVSymbol *Symbol = LocalSymbol) {
1079 Symbol->setHasCodeViewLocation();
1080 LocalSymbol = nullptr;
1081
1082 // Add location debug location. Operands: [Offset, 0].
1083 dwarf::Attribute Attr =
1084 dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL);
1085 uint64_t Operand1 = DefRangeFramePointerRel.Hdr.Offset;
1086
1087 LocalVariableAddrRange Range = DefRangeFramePointerRel.Range;
1088 LVAddress Address =
1089 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1090
1091 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1092 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1});
1093 }
1094
1095 return Error::success();
1096}
1097
1098// S_DEFRANGE_REGISTER_REL
1099Error LVSymbolVisitor::visitKnownRecord(
1100 CVSymbol &Record, DefRangeRegisterRelSym &DefRangeRegisterRel) {
1101 // DefRanges don't have types, just registers and code offsets.
1102 LLVM_DEBUG({
1103 if (LocalSymbol)
1104 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1105
1106 W.printBoolean("HasSpilledUDTMember",
1107 DefRangeRegisterRel.hasSpilledUDTMember());
1108 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
1109 W.printNumber("BasePointerOffset",
1110 DefRangeRegisterRel.Hdr.BasePointerOffset);
1111 printLocalVariableAddrRange(DefRangeRegisterRel.Range,
1112 DefRangeRegisterRel.getRelocationOffset());
1113 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
1114 });
1115
1116 if (LVSymbol *Symbol = LocalSymbol) {
1117 Symbol->setHasCodeViewLocation();
1118 LocalSymbol = nullptr;
1119
1120 // Add location debug location. Operands: [Register, Offset].
1121 dwarf::Attribute Attr =
1122 dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL);
1123 uint64_t Operand1 = DefRangeRegisterRel.Hdr.Register;
1124 uint64_t Operand2 = DefRangeRegisterRel.Hdr.BasePointerOffset;
1125
1126 LocalVariableAddrRange Range = DefRangeRegisterRel.Range;
1127 LVAddress Address =
1128 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1129
1130 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1131 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1, Operand2});
1132 }
1133
1134 return Error::success();
1135}
1136
1137// S_DEFRANGE_REGISTER_REL_INDIR
1138Error LVSymbolVisitor::visitKnownRecord(
1139 CVSymbol &Record, DefRangeRegisterRelIndirSym &DefRangeRegisterRelIndir) {
1140 // DefRanges don't have types, just registers and code offsets.
1141 LLVM_DEBUG({
1142 if (LocalSymbol)
1143 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1144
1145 W.printBoolean("HasSpilledUDTMember",
1146 DefRangeRegisterRelIndir.hasSpilledUDTMember());
1147 W.printNumber("OffsetInParent", DefRangeRegisterRelIndir.offsetInParent());
1148 W.printNumber("BasePointerOffset",
1149 DefRangeRegisterRelIndir.Hdr.BasePointerOffset);
1150 W.printNumber("OffsetInUdt", DefRangeRegisterRelIndir.Hdr.OffsetInUdt);
1151 printLocalVariableAddrRange(DefRangeRegisterRelIndir.Range,
1152 DefRangeRegisterRelIndir.getRelocationOffset());
1153 printLocalVariableAddrGap(DefRangeRegisterRelIndir.Gaps);
1154 });
1155
1156 if (LVSymbol *Symbol = LocalSymbol) {
1157 Symbol->setHasCodeViewLocation();
1158 LocalSymbol = nullptr;
1159
1160 // Add location debug location. Operands: [Register, Offset, OffsetInUdt].
1161 dwarf::Attribute Attr =
1162 dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL_INDIR);
1163 const uint64_t Operand1 = DefRangeRegisterRelIndir.Hdr.Register;
1164 const uint64_t Operand2 = DefRangeRegisterRelIndir.Hdr.BasePointerOffset;
1165 const uint64_t Operand3 = DefRangeRegisterRelIndir.Hdr.OffsetInUdt;
1166
1167 const LocalVariableAddrRange Range = DefRangeRegisterRelIndir.Range;
1168 const LVAddress Address =
1169 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1170
1171 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1172 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1, Operand2, Operand3});
1173 }
1174
1175 return Error::success();
1176}
1177
1178// S_DEFRANGE_REGISTER
1179Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1180 DefRangeRegisterSym &DefRangeRegister) {
1181 // DefRanges don't have types, just registers and code offsets.
1182 LLVM_DEBUG({
1183 if (LocalSymbol)
1184 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1185
1186 W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
1187 getRegisterNames(Reader->getCompileUnitCPUType()));
1188 W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
1189 printLocalVariableAddrRange(DefRangeRegister.Range,
1190 DefRangeRegister.getRelocationOffset());
1191 printLocalVariableAddrGap(DefRangeRegister.Gaps);
1192 });
1193
1194 if (LVSymbol *Symbol = LocalSymbol) {
1195 Symbol->setHasCodeViewLocation();
1196 LocalSymbol = nullptr;
1197
1198 // Add location debug location. Operands: [Register, 0].
1199 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER);
1200 uint64_t Operand1 = DefRangeRegister.Hdr.Register;
1201
1202 LocalVariableAddrRange Range = DefRangeRegister.Range;
1203 LVAddress Address =
1204 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1205
1206 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1207 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1});
1208 }
1209
1210 return Error::success();
1211}
1212
1213// S_DEFRANGE_SUBFIELD_REGISTER
1214Error LVSymbolVisitor::visitKnownRecord(
1215 CVSymbol &Record, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
1216 // DefRanges don't have types, just registers and code offsets.
1217 LLVM_DEBUG({
1218 if (LocalSymbol)
1219 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1220
1221 W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
1222 getRegisterNames(Reader->getCompileUnitCPUType()));
1223 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
1224 W.printNumber("OffsetInParent",
1225 DefRangeSubfieldRegister.Hdr.OffsetInParent);
1226 printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
1227 DefRangeSubfieldRegister.getRelocationOffset());
1228 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
1229 });
1230
1231 if (LVSymbol *Symbol = LocalSymbol) {
1232 Symbol->setHasCodeViewLocation();
1233 LocalSymbol = nullptr;
1234
1235 // Add location debug location. Operands: [Register, 0].
1236 dwarf::Attribute Attr =
1237 dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER);
1238 uint64_t Operand1 = DefRangeSubfieldRegister.Hdr.Register;
1239
1240 LocalVariableAddrRange Range = DefRangeSubfieldRegister.Range;
1241 LVAddress Address =
1242 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1243
1244 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1245 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1});
1246 }
1247
1248 return Error::success();
1249}
1250
1251// S_DEFRANGE_SUBFIELD
1252Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1253 DefRangeSubfieldSym &DefRangeSubfield) {
1254 // DefRanges don't have types, just registers and code offsets.
1255 LLVM_DEBUG({
1256 if (LocalSymbol)
1257 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1258
1259 if (ObjDelegate) {
1260 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
1261 auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
1262 if (!ExpectedProgram) {
1263 consumeError(ExpectedProgram.takeError());
1264 return llvm::make_error<CodeViewError>(
1265 "String table offset outside of bounds of String Table!");
1266 }
1267 W.printString("Program", *ExpectedProgram);
1268 }
1269 W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
1270 printLocalVariableAddrRange(DefRangeSubfield.Range,
1271 DefRangeSubfield.getRelocationOffset());
1272 printLocalVariableAddrGap(DefRangeSubfield.Gaps);
1273 });
1274
1275 if (LVSymbol *Symbol = LocalSymbol) {
1276 Symbol->setHasCodeViewLocation();
1277 LocalSymbol = nullptr;
1278
1279 // Add location debug location. Operands: [Program, 0].
1280 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD);
1281 uint64_t Operand1 = DefRangeSubfield.Program;
1282
1283 LocalVariableAddrRange Range = DefRangeSubfield.Range;
1284 LVAddress Address =
1285 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1286
1287 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1288 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1, /*Operand2=*/0});
1289 }
1290
1291 return Error::success();
1292}
1293
1294// S_DEFRANGE
1295Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1296 DefRangeSym &DefRange) {
1297 // DefRanges don't have types, just registers and code offsets.
1298 LLVM_DEBUG({
1299 if (LocalSymbol)
1300 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1301
1302 if (ObjDelegate) {
1303 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
1304 auto ExpectedProgram = Strings.getString(DefRange.Program);
1305 if (!ExpectedProgram) {
1306 consumeError(ExpectedProgram.takeError());
1307 return llvm::make_error<CodeViewError>(
1308 "String table offset outside of bounds of String Table!");
1309 }
1310 W.printString("Program", *ExpectedProgram);
1311 }
1312 printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
1313 printLocalVariableAddrGap(DefRange.Gaps);
1314 });
1315
1316 if (LVSymbol *Symbol = LocalSymbol) {
1317 Symbol->setHasCodeViewLocation();
1318 LocalSymbol = nullptr;
1319
1320 // Add location debug location. Operands: [Program, 0].
1321 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE);
1322 uint64_t Operand1 = DefRange.Program;
1323
1324 LocalVariableAddrRange Range = DefRange.Range;
1325 LVAddress Address =
1326 Reader->linearAddress(Segment: Range.ISectStart, Offset: Range.OffsetStart);
1327
1328 Symbol->addLocation(Attr, LowPC: Address, HighPC: Address + Range.Range, SectionOffset: 0, LocDescOffset: 0);
1329 Symbol->addLocationOperands(Opcode: LVSmall(Attr), Operands: {Operand1, /*Operand2=*/0});
1330 }
1331
1332 return Error::success();
1333}
1334
1335// S_FRAMEPROC
1336Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1337 FrameProcSym &FrameProc) {
1338 if (LVScope *Function = LogicalVisitor->getReaderScope()) {
1339 // S_FRAMEPROC contains extra information for the function described
1340 // by any of the previous generated records:
1341 // S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID.
1342
1343 // The generated sequence is:
1344 // S_GPROC32_ID ...
1345 // S_FRAMEPROC ...
1346
1347 // Collect additional inline flags for the current scope function.
1348 FrameProcedureOptions Flags = FrameProc.Flags;
1349 if (FrameProcedureOptions::MarkedInline ==
1350 (Flags & FrameProcedureOptions::MarkedInline))
1351 Function->setInlineCode(dwarf::DW_INL_declared_inlined);
1352 if (FrameProcedureOptions::Inlined ==
1353 (Flags & FrameProcedureOptions::Inlined))
1354 Function->setInlineCode(dwarf::DW_INL_inlined);
1355
1356 // To determine the symbol kind for any symbol declared in that function,
1357 // we can access the S_FRAMEPROC for the parent scope function. It contains
1358 // information about the local fp and param fp registers and compare with
1359 // the register in the S_REGREL32 to get a match.
1360 codeview::CPUType CPU = Reader->getCompileUnitCPUType();
1361 LocalFrameRegister = FrameProc.getLocalFramePtrReg(CPU);
1362 ParamFrameRegister = FrameProc.getParamFramePtrReg(CPU);
1363 }
1364
1365 return Error::success();
1366}
1367
1368// S_GDATA32, S_LDATA32, S_LMANDATA, S_GMANDATA
1369Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, DataSym &Data) {
1370 LLVM_DEBUG({
1371 printTypeIndex("Type", Data.Type);
1372 W.printString("DisplayName", Data.Name);
1373 });
1374
1375 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1376 StringRef LinkageName;
1377 if (ObjDelegate)
1378 ObjDelegate->getLinkageName(RelocOffset: Data.getRelocationOffset(), Offset: Data.DataOffset,
1379 RelocSym: &LinkageName);
1380
1381 Symbol->setName(Data.Name);
1382 Symbol->setLinkageName(LinkageName);
1383
1384 // The MSVC generates local data as initialization for aggregates. It
1385 // contains the address for an initialization function.
1386 // The symbols contains the '$initializer$' pattern. Allow them only if
1387 // the '--internal=system' option is given.
1388 // 0 | S_LDATA32 `Struct$initializer$`
1389 // type = 0x1040 (void ()*)
1390 if (getReader().isSystemEntry(Element: Symbol) && !options().getAttributeSystem()) {
1391 Symbol->resetIncludeInPrint();
1392 return Error::success();
1393 }
1394
1395 if (LVScope *Namespace = Shared->NamespaceDeduction.get(ScopedName: Data.Name)) {
1396 // The variable is already at different scope. In order to reflect
1397 // the correct parent, move it to the namespace.
1398 if (Symbol->getParentScope()->removeElement(Element: Symbol))
1399 Namespace->addElement(Symbol);
1400 }
1401
1402 Symbol->setType(LogicalVisitor->getElement(StreamIdx: StreamTPI, TI: Data.Type));
1403 if (Record.kind() == SymbolKind::S_GDATA32)
1404 Symbol->setIsExternal();
1405 }
1406
1407 return Error::success();
1408}
1409
1410// S_INLINESITE
1411Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1412 InlineSiteSym &InlineSite) {
1413 LLVM_DEBUG({ printTypeIndex("Inlinee", InlineSite.Inlinee); });
1414
1415 if (LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1416 LVScope *AbstractFunction = Reader->createScopeFunction();
1417 AbstractFunction->setIsSubprogram();
1418 AbstractFunction->setTag(dwarf::DW_TAG_subprogram);
1419 AbstractFunction->setInlineCode(dwarf::DW_INL_inlined);
1420 AbstractFunction->setIsInlinedAbstract();
1421 InlinedFunction->setReference(AbstractFunction);
1422
1423 LogicalVisitor->startProcessArgumentList();
1424 // 'Inlinee' is a Type ID.
1425 CVType CVFunctionType = Ids.getType(Index: InlineSite.Inlinee);
1426 if (Error Err = LogicalVisitor->finishVisitation(
1427 Record&: CVFunctionType, TI: InlineSite.Inlinee, Element: AbstractFunction))
1428 return Err;
1429 LogicalVisitor->stopProcessArgumentList();
1430
1431 // For inlined functions set the linkage name to be the same as
1432 // the name. It used to find their lines and ranges.
1433 StringRef Name = AbstractFunction->getName();
1434 InlinedFunction->setName(Name);
1435 InlinedFunction->setLinkageName(Name);
1436
1437 // Process annotation bytes to calculate code and line offsets.
1438 if (Error Err = LogicalVisitor->inlineSiteAnnotation(
1439 AbstractFunction, InlinedFunction, InlineSite))
1440 return Err;
1441 }
1442
1443 return Error::success();
1444}
1445
1446// S_LOCAL
1447Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, LocalSym &Local) {
1448 LLVM_DEBUG({
1449 printTypeIndex("Type", Local.Type);
1450 W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
1451 W.printString("VarName", Local.Name);
1452 });
1453
1454 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1455 Symbol->setName(Local.Name);
1456
1457 // Symbol was created as 'variable'; determine its real kind.
1458 Symbol->resetIsVariable();
1459
1460 // Be sure the 'this' symbol is marked as 'compiler generated'.
1461 if (bool(Local.Flags & LocalSymFlags::IsCompilerGenerated) ||
1462 Local.Name == "this") {
1463 Symbol->setIsArtificial();
1464 Symbol->setIsParameter();
1465 } else {
1466 bool(Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()
1467 : Symbol->setIsVariable();
1468 }
1469
1470 // Update correct debug information tag.
1471 if (Symbol->getIsParameter())
1472 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1473
1474 setLocalVariableType(Symbol, TI: Local.Type);
1475
1476 // The CodeView records (S_DEFFRAME_*) describing debug location for
1477 // this symbol, do not have any direct reference to it. Those records
1478 // are emitted after this symbol. Record the current symbol.
1479 LocalSymbol = Symbol;
1480 }
1481
1482 return Error::success();
1483}
1484
1485// S_OBJNAME
1486Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ObjNameSym &ObjName) {
1487 LLVM_DEBUG({
1488 W.printHex("Signature", ObjName.Signature);
1489 W.printString("ObjectName", ObjName.Name);
1490 });
1491
1492 CurrentObjectName = ObjName.Name;
1493 return Error::success();
1494}
1495
1496// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID
1497Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ProcSym &Proc) {
1498 if (InFunctionScope)
1499 return llvm::make_error<CodeViewError>(Args: "Visiting a ProcSym while inside "
1500 "function scope!");
1501
1502 InFunctionScope = true;
1503
1504 LLVM_DEBUG({
1505 printTypeIndex("FunctionType", Proc.FunctionType);
1506 W.printHex("Segment", Proc.Segment);
1507 W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
1508 getProcSymFlagNames());
1509 W.printString("DisplayName", Proc.Name);
1510 });
1511
1512 // Clang and Microsoft generated different debug information records:
1513 // For functions definitions:
1514 // Clang: S_GPROC32 -> LF_FUNC_ID -> LF_PROCEDURE
1515 // Microsoft: S_GPROC32 -> LF_PROCEDURE
1516
1517 // For member function definition:
1518 // Clang: S_GPROC32 -> LF_MFUNC_ID -> LF_MFUNCTION
1519 // Microsoft: S_GPROC32 -> LF_MFUNCTION
1520 // In order to support both sequences, if we found LF_FUNCTION_ID, just
1521 // get the TypeIndex for LF_PROCEDURE.
1522
1523 // For the given test case, we have the sequence:
1524 // namespace NSP_local {
1525 // void foo_local() {
1526 // }
1527 // }
1528 //
1529 // 0x1000 | LF_STRING_ID String: NSP_local
1530 // 0x1002 | LF_PROCEDURE
1531 // return type = 0x0003 (void), # args = 0, param list = 0x1001
1532 // calling conv = cdecl, options = None
1533 // 0x1003 | LF_FUNC_ID
1534 // name = foo_local, type = 0x1002, parent scope = 0x1000
1535 // 0 | S_GPROC32_ID `NSP_local::foo_local`
1536 // type = `0x1003 (foo_local)`
1537 // 0x1004 | LF_STRING_ID String: suite
1538 // 0x1005 | LF_STRING_ID String: suite_local.cpp
1539 //
1540 // The LF_STRING_ID can hold different information:
1541 // 0x1000 - The enclosing namespace.
1542 // 0x1004 - The compile unit directory name.
1543 // 0x1005 - The compile unit name.
1544 //
1545 // Before deducting its scope, we need to evaluate its type and create any
1546 // associated namespaces.
1547 if (LVScope *Function = LogicalVisitor->CurrentScope) {
1548 StringRef LinkageName;
1549 if (ObjDelegate)
1550 ObjDelegate->getLinkageName(RelocOffset: Proc.getRelocationOffset(), Offset: Proc.CodeOffset,
1551 RelocSym: &LinkageName);
1552
1553 // The line table can be accessed using the linkage name.
1554 Reader->addToSymbolTable(Name: LinkageName, Function);
1555 Function->setName(Proc.Name);
1556 Function->setLinkageName(LinkageName);
1557
1558 if (options().getGeneralCollectRanges()) {
1559 // Record converted segment::offset addressing for this scope.
1560 LVAddress Addendum = Reader->getSymbolTableAddress(Name: LinkageName);
1561 LVAddress LowPC =
1562 Reader->linearAddress(Segment: Proc.Segment, Offset: Proc.CodeOffset, Addendum);
1563 LVAddress HighPC = LowPC + Proc.CodeSize - 1;
1564 Function->addObject(LowerAddress: LowPC, UpperAddress: HighPC);
1565
1566 // If the scope is a function, add it to the public names.
1567 if ((options().getAttributePublics() || options().getPrintAnyLine()) &&
1568 !Function->getIsInlinedFunction())
1569 Reader->getCompileUnit()->addPublicName(Scope: Function, LowPC, HighPC);
1570 }
1571
1572 if (Function->getIsSystem() && !options().getAttributeSystem()) {
1573 Function->resetIncludeInPrint();
1574 return Error::success();
1575 }
1576
1577 TypeIndex TIFunctionType = Proc.FunctionType;
1578 if (TIFunctionType.isSimple())
1579 Function->setType(LogicalVisitor->getElement(StreamIdx: StreamTPI, TI: TIFunctionType));
1580 else {
1581 // We have to detect the correct stream, using the lexical parent
1582 // name, as there is not other obvious way to get the stream.
1583 // Normal function: LF_FUNC_ID (TPI)/(IPI)
1584 // LF_PROCEDURE (TPI)
1585 // Lambda function: LF_MFUNCTION (TPI)
1586 // Member function: LF_MFUNC_ID (TPI)/(IPI)
1587
1588 StringRef OuterComponent;
1589 std::tie(args&: OuterComponent, args: std::ignore) = getInnerComponent(Name: Proc.Name);
1590 TypeIndex TI = Shared->ForwardReferences.find(Name: OuterComponent);
1591
1592 std::optional<CVType> CVFunctionType;
1593 auto GetRecordType = [&]() -> bool {
1594 CVFunctionType = Ids.tryGetType(Index: TIFunctionType);
1595 if (!CVFunctionType)
1596 return false;
1597
1598 if (TI.isNoneType())
1599 // Normal function.
1600 if (CVFunctionType->kind() == LF_FUNC_ID)
1601 return true;
1602
1603 // Member function.
1604 return (CVFunctionType->kind() == LF_MFUNC_ID);
1605 };
1606
1607 // We can have a LF_FUNC_ID, LF_PROCEDURE or LF_MFUNCTION.
1608 if (!GetRecordType()) {
1609 CVFunctionType = Types.tryGetType(Index: TIFunctionType);
1610 if (!CVFunctionType)
1611 return llvm::make_error<CodeViewError>(Args: "Invalid type index");
1612 }
1613
1614 if (Error Err = LogicalVisitor->finishVisitation(
1615 Record&: *CVFunctionType, TI: TIFunctionType, Element: Function))
1616 return Err;
1617 }
1618
1619 if (Record.kind() == SymbolKind::S_GPROC32 ||
1620 Record.kind() == SymbolKind::S_GPROC32_ID)
1621 Function->setIsExternal();
1622
1623 // We don't have a way to see if the symbol is compiler generated. Use
1624 // the linkage name, to detect `scalar deleting destructor' functions.
1625 std::string DemangledSymbol = demangle(MangledName: LinkageName);
1626 if (DemangledSymbol.find(s: "scalar deleting dtor") != std::string::npos) {
1627 Function->setIsArtificial();
1628 } else {
1629 // Clang generates global ctor and dtor names containing the substrings:
1630 // 'dynamic initializer for' and 'dynamic atexit destructor for'.
1631 if (DemangledSymbol.find(s: "dynamic atexit destructor for") !=
1632 std::string::npos)
1633 Function->setIsArtificial();
1634 }
1635 }
1636
1637 return Error::success();
1638}
1639
1640// S_END
1641Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1642 ScopeEndSym &ScopeEnd) {
1643 InFunctionScope = false;
1644 return Error::success();
1645}
1646
1647// S_THUNK32
1648Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, Thunk32Sym &Thunk) {
1649 if (InFunctionScope)
1650 return llvm::make_error<CodeViewError>(Args: "Visiting a Thunk32Sym while inside "
1651 "function scope!");
1652
1653 InFunctionScope = true;
1654
1655 LLVM_DEBUG({
1656 W.printHex("Segment", Thunk.Segment);
1657 W.printString("Name", Thunk.Name);
1658 });
1659
1660 if (LVScope *Function = LogicalVisitor->CurrentScope)
1661 Function->setName(Thunk.Name);
1662
1663 return Error::success();
1664}
1665
1666// S_UDT, S_COBOLUDT
1667Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, UDTSym &UDT) {
1668 LLVM_DEBUG({
1669 printTypeIndex("Type", UDT.Type);
1670 W.printString("UDTName", UDT.Name);
1671 });
1672
1673 if (LVType *Type = LogicalVisitor->CurrentType) {
1674 if (LVScope *Namespace = Shared->NamespaceDeduction.get(ScopedName: UDT.Name)) {
1675 if (Type->getParentScope()->removeElement(Element: Type))
1676 Namespace->addElement(Type);
1677 }
1678
1679 Type->setName(UDT.Name);
1680
1681 // We have to determine if the typedef is a real C/C++ definition or is
1682 // the S_UDT record that describe all the user defined types.
1683 // 0 | S_UDT `Name` original type = 0x1009
1684 // 0x1009 | LF_STRUCTURE `Name`
1685 // Ignore type definitions for RTTI types:
1686 // _s__RTTIBaseClassArray, _s__RTTIBaseClassDescriptor,
1687 // _s__RTTICompleteObjectLocator, _s__RTTIClassHierarchyDescriptor.
1688 if (getReader().isSystemEntry(Element: Type))
1689 Type->resetIncludeInPrint();
1690 else {
1691 StringRef RecordName = getRecordName(Types, TI: UDT.Type);
1692 if (UDT.Name == RecordName)
1693 Type->resetIncludeInPrint();
1694 Type->setType(LogicalVisitor->getElement(StreamIdx: StreamTPI, TI: UDT.Type));
1695 }
1696 }
1697
1698 return Error::success();
1699}
1700
1701// S_UNAMESPACE
1702Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
1703 UsingNamespaceSym &UN) {
1704 LLVM_DEBUG({ W.printString("Namespace", UN.Name); });
1705 return Error::success();
1706}
1707
1708// S_ARMSWITCHTABLE
1709Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
1710 JumpTableSym &JumpTable) {
1711 LLVM_DEBUG({
1712 W.printHex("BaseOffset", JumpTable.BaseOffset);
1713 W.printNumber("BaseSegment", JumpTable.BaseSegment);
1714 W.printFlags("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),
1715 getJumpTableEntrySizeNames());
1716 W.printHex("BranchOffset", JumpTable.BranchOffset);
1717 W.printHex("TableOffset", JumpTable.TableOffset);
1718 W.printNumber("BranchSegment", JumpTable.BranchSegment);
1719 W.printNumber("TableSegment", JumpTable.TableSegment);
1720 W.printNumber("EntriesCount", JumpTable.EntriesCount);
1721 });
1722 return Error::success();
1723}
1724
1725// S_CALLERS, S_CALLEES, S_INLINEES
1726Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {
1727 LLVM_DEBUG({
1728 llvm::StringRef FieldName;
1729 switch (Caller.getKind()) {
1730 case SymbolRecordKind::CallerSym:
1731 FieldName = "Callee";
1732 break;
1733 case SymbolRecordKind::CalleeSym:
1734 FieldName = "Caller";
1735 break;
1736 case SymbolRecordKind::InlineesSym:
1737 FieldName = "Inlinee";
1738 break;
1739 default:
1740 return llvm::make_error<CodeViewError>(
1741 "Unknown CV Record type for a CallerSym object!");
1742 }
1743 for (auto FuncID : Caller.Indices) {
1744 printTypeIndex(FieldName, FuncID);
1745 }
1746 });
1747 return Error::success();
1748}
1749
1750void LVSymbolVisitor::setLocalVariableType(LVSymbol *Symbol, TypeIndex TI) {
1751 LVElement *Element = LogicalVisitor->getElement(StreamIdx: StreamTPI, TI);
1752 if (Element && Element->getIsScoped()) {
1753 // We have a local type. Find its parent function.
1754 LVScope *Parent = Symbol->getFunctionParent();
1755 // The element representing the type has been already finalized. If
1756 // the type is an aggregate type, its members have been already added.
1757 // As the type is local, its level will be changed.
1758
1759 // FIXME: Currently the algorithm used to scope lambda functions is
1760 // incorrect. Before we allocate the type at this scope, check if is
1761 // already allocated in other scope.
1762 if (!Element->getParentScope()) {
1763 Parent->addElement(Element);
1764 Element->updateLevel(Parent);
1765 }
1766 }
1767 Symbol->setType(Element);
1768}
1769
1770#undef DEBUG_TYPE
1771#define DEBUG_TYPE "CodeViewLogicalVisitor"
1772
1773//===----------------------------------------------------------------------===//
1774// Logical visitor.
1775//===----------------------------------------------------------------------===//
1776LVLogicalVisitor::LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W,
1777 InputFile &Input)
1778 : Reader(Reader), W(W), Input(Input) {
1779 // The LogicalVisitor connects the CodeViewReader with the visitors that
1780 // traverse the types, symbols, etc. Do any initialization that is needed.
1781 Shared = std::make_shared<LVShared>(args&: Reader, args: this);
1782}
1783
1784void LVLogicalVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
1785 uint32_t StreamIdx) {
1786 codeview::printTypeIndex(Printer&: W, FieldName, TI,
1787 Types&: StreamIdx == StreamTPI ? types() : ids());
1788}
1789
1790void LVLogicalVisitor::printTypeBegin(CVType &Record, TypeIndex TI,
1791 LVElement *Element, uint32_t StreamIdx) {
1792 W.getOStream() << "\n";
1793 W.startLine() << formatTypeLeafKind(K: Record.kind());
1794 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
1795 W.getOStream() << " {\n";
1796 W.indent();
1797 W.printEnum(Label: "TypeLeafKind", Value: unsigned(Record.kind()), EnumValues: getTypeLeafNames());
1798 printTypeIndex(FieldName: "TI", TI, StreamIdx);
1799 W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
1800 << Element->getName() << "\n";
1801}
1802
1803void LVLogicalVisitor::printTypeEnd(CVType &Record) {
1804 W.unindent();
1805 W.startLine() << "}\n";
1806}
1807
1808void LVLogicalVisitor::printMemberBegin(CVMemberRecord &Record, TypeIndex TI,
1809 LVElement *Element,
1810 uint32_t StreamIdx) {
1811 W.getOStream() << "\n";
1812 W.startLine() << formatTypeLeafKind(K: Record.Kind);
1813 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
1814 W.getOStream() << " {\n";
1815 W.indent();
1816 W.printEnum(Label: "TypeLeafKind", Value: unsigned(Record.Kind), EnumValues: getTypeLeafNames());
1817 printTypeIndex(FieldName: "TI", TI, StreamIdx);
1818 W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
1819 << Element->getName() << "\n";
1820}
1821
1822void LVLogicalVisitor::printMemberEnd(CVMemberRecord &Record) {
1823 W.unindent();
1824 W.startLine() << "}\n";
1825}
1826
1827Error LVLogicalVisitor::visitUnknownType(CVType &Record, TypeIndex TI) {
1828 LLVM_DEBUG({
1829 printTypeIndex("\nTI", TI, StreamTPI);
1830 W.printNumber("Length", uint32_t(Record.content().size()));
1831 });
1832 return Error::success();
1833}
1834
1835// LF_ARGLIST (TPI)
1836Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArgListRecord &Args,
1837 TypeIndex TI, LVElement *Element) {
1838 ArrayRef<TypeIndex> Indices = Args.getIndices();
1839 uint32_t Size = Indices.size();
1840 LLVM_DEBUG({
1841 printTypeBegin(Record, TI, Element, StreamTPI);
1842 W.printNumber("NumArgs", Size);
1843 ListScope Arguments(W, "Arguments");
1844 for (uint32_t I = 0; I < Size; ++I)
1845 printTypeIndex("ArgType", Indices[I], StreamTPI);
1846 printTypeEnd(Record);
1847 });
1848
1849 LVScope *Function = static_cast<LVScope *>(Element);
1850 for (uint32_t Index = 0; Index < Size; ++Index) {
1851 TypeIndex ParameterType = Indices[Index];
1852 createParameter(TI: ParameterType, Name: StringRef(), Parent: Function);
1853 }
1854
1855 return Error::success();
1856}
1857
1858// LF_ARRAY (TPI)
1859Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArrayRecord &AT,
1860 TypeIndex TI, LVElement *Element) {
1861 LLVM_DEBUG({
1862 printTypeBegin(Record, TI, Element, StreamTPI);
1863 printTypeIndex("ElementType", AT.getElementType(), StreamTPI);
1864 printTypeIndex("IndexType", AT.getIndexType(), StreamTPI);
1865 W.printNumber("SizeOf", AT.getSize());
1866 W.printString("Name", AT.getName());
1867 printTypeEnd(Record);
1868 });
1869
1870 if (Element->getIsFinalized())
1871 return Error::success();
1872 Element->setIsFinalized();
1873
1874 LVScopeArray *Array = static_cast<LVScopeArray *>(Element);
1875 if (!Array)
1876 return Error::success();
1877
1878 Reader->getCompileUnit()->addElement(Scope: Array);
1879 TypeIndex TIElementType = AT.getElementType();
1880
1881 LVType *PrevSubrange = nullptr;
1882 LazyRandomTypeCollection &Types = types();
1883
1884 // As the logical view is modeled on DWARF, for each dimension we have to
1885 // create a DW_TAG_subrange_type, with dimension size.
1886 // The subrange type can be: unsigned __int32 or unsigned __int64.
1887 auto AddSubrangeType = [&](ArrayRecord &AR) {
1888 LVType *Subrange = Reader->createTypeSubrange();
1889 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1890 Subrange->setType(getElement(StreamIdx: StreamTPI, TI: AR.getIndexType()));
1891 Subrange->setCount(AR.getSize());
1892 Subrange->setOffset(
1893 TIElementType.isSimple()
1894 ? (uint32_t)(TypeLeafKind)TIElementType.getSimpleKind()
1895 : TIElementType.getIndex());
1896 Array->addElement(Type: Subrange);
1897
1898 if (PrevSubrange)
1899 if (int64_t Count = Subrange->getCount())
1900 PrevSubrange->setCount(PrevSubrange->getCount() / Count);
1901 PrevSubrange = Subrange;
1902 };
1903
1904 // Preserve the original TypeIndex; it would be updated in the case of:
1905 // - The array type contains qualifiers.
1906 // - In multidimensional arrays, the last LF_ARRAY entry contains the type.
1907 TypeIndex TIArrayType;
1908
1909 // For each dimension in the array, there is a LF_ARRAY entry. The last
1910 // entry contains the array type, which can be a LF_MODIFIER in the case
1911 // of the type being modified by a qualifier (const, etc).
1912 ArrayRecord AR(AT);
1913 CVType CVEntry = Record;
1914 while (CVEntry.kind() == LF_ARRAY) {
1915 // Create the subrange information, required by the logical view. Once
1916 // the array has been processed, the dimension sizes will updated, as
1917 // the sizes are a progression. For instance:
1918 // sizeof(int) = 4
1919 // int Array[2]; Sizes: 8 Dim: 8 / 4 -> [2]
1920 // int Array[2][3]; Sizes: 24, 12 Dim: 24 / 12 -> [2]
1921 // Dim: 12 / 4 -> [3]
1922 // int Array[2][3][4]; sizes: 96, 48, 16 Dim: 96 / 48 -> [2]
1923 // Dim: 48 / 16 -> [3]
1924 // Dim: 16 / 4 -> [4]
1925 AddSubrangeType(AR);
1926 TIArrayType = TIElementType;
1927
1928 // The current ElementType can be a modifier, in which case we need to
1929 // get the type being modified.
1930 // If TypeIndex is not a simple type, check if we have a qualified type.
1931 if (!TIElementType.isSimple()) {
1932 CVType CVElementType = Types.getType(Index: TIElementType);
1933 if (CVElementType.kind() == LF_MODIFIER) {
1934 LVElement *QualifiedType =
1935 Shared->TypeRecords.find(StreamIdx: StreamTPI, TI: TIElementType);
1936 if (Error Err =
1937 finishVisitation(Record&: CVElementType, TI: TIElementType, Element: QualifiedType))
1938 return Err;
1939 // Get the TypeIndex of the type that the LF_MODIFIER modifies.
1940 TIElementType = getModifiedType(CVT: CVElementType);
1941 }
1942 }
1943 // Ends the traversal, as we have reached a simple type (int, char, etc).
1944 if (TIElementType.isSimple())
1945 break;
1946
1947 // Read next dimension linked entry, if any.
1948 CVEntry = Types.getType(Index: TIElementType);
1949 if (Error Err = TypeDeserializer::deserializeAs(
1950 CVT&: const_cast<CVType &>(CVEntry), Record&: AR)) {
1951 consumeError(Err: std::move(Err));
1952 break;
1953 }
1954 TIElementType = AR.getElementType();
1955 // NOTE: The typeindex has a value of: 0x0280.0000
1956 getTrueType(TI&: TIElementType);
1957 }
1958
1959 Array->setName(AT.getName());
1960 TIArrayType = Shared->ForwardReferences.remap(TI: TIArrayType);
1961 Array->setType(getElement(StreamIdx: StreamTPI, TI: TIArrayType));
1962
1963 if (PrevSubrange)
1964 // In the case of an aggregate type (class, struct, union, interface),
1965 // get the aggregate size. As the original record is pointing to its
1966 // reference, we have to update it.
1967 if (uint64_t Size =
1968 isAggregate(CVT: CVEntry)
1969 ? getSizeInBytesForTypeRecord(CVT: Types.getType(Index: TIArrayType))
1970 : getSizeInBytesForTypeIndex(TI: TIElementType))
1971 PrevSubrange->setCount(PrevSubrange->getCount() / Size);
1972
1973 return Error::success();
1974}
1975
1976// LF_BITFIELD (TPI)
1977Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BitFieldRecord &BF,
1978 TypeIndex TI, LVElement *Element) {
1979 LLVM_DEBUG({
1980 printTypeBegin(Record, TI, Element, StreamTPI);
1981 printTypeIndex("Type", TI, StreamTPI);
1982 W.printNumber("BitSize", BF.getBitSize());
1983 W.printNumber("BitOffset", BF.getBitOffset());
1984 printTypeEnd(Record);
1985 });
1986
1987 Element->setType(getElement(StreamIdx: StreamTPI, TI: BF.getType()));
1988 Element->setBitSize(BF.getBitSize());
1989 return Error::success();
1990}
1991
1992// LF_BUILDINFO (TPI)/(IPI)
1993Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &BI,
1994 TypeIndex TI, LVElement *Element) {
1995 LLVM_DEBUG({
1996 printTypeBegin(Record, TI, Element, StreamIPI);
1997 W.printNumber("NumArgs", static_cast<uint32_t>(BI.getArgs().size()));
1998 ListScope Arguments(W, "Arguments");
1999 for (TypeIndex Arg : BI.getArgs())
2000 printTypeIndex("ArgType", Arg, StreamIPI);
2001 printTypeEnd(Record);
2002 });
2003
2004 // The given 'Element' refers to the current compilation unit.
2005 // All the args are references into the TPI/IPI stream.
2006 TypeIndex TIName = BI.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
2007 std::string Name = std::string(ids().getTypeName(Index: TIName));
2008
2009 // There are cases where LF_BUILDINFO fields are empty.
2010 if (!Name.empty())
2011 Element->setName(Name);
2012
2013 return Error::success();
2014}
2015
2016// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)
2017Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,
2018 TypeIndex TI, LVElement *Element) {
2019 LLVM_DEBUG({
2020 printTypeBegin(Record, TI, Element, StreamTPI);
2021 W.printNumber("MemberCount", Class.getMemberCount());
2022 printTypeIndex("FieldList", Class.getFieldList(), StreamTPI);
2023 printTypeIndex("DerivedFrom", Class.getDerivationList(), StreamTPI);
2024 printTypeIndex("VShape", Class.getVTableShape(), StreamTPI);
2025 W.printNumber("SizeOf", Class.getSize());
2026 W.printString("Name", Class.getName());
2027 if (Class.hasUniqueName())
2028 W.printString("UniqueName", Class.getUniqueName());
2029 printTypeEnd(Record);
2030 });
2031
2032 if (Element->getIsFinalized())
2033 return Error::success();
2034 Element->setIsFinalized();
2035
2036 LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);
2037 if (!Scope)
2038 return Error::success();
2039
2040 Scope->setName(Class.getName());
2041 if (Class.hasUniqueName())
2042 Scope->setLinkageName(Class.getUniqueName());
2043 Scope->setBitSize(Class.getSize() * DWARF_CHAR_BIT);
2044
2045 if (Class.isNested()) {
2046 Scope->setIsNested();
2047 createParents(ScopedName: Class.getName(), Element: Scope);
2048 }
2049
2050 if (Class.isScoped())
2051 Scope->setIsScoped();
2052
2053 // Nested types will be added to their parents at creation. The forward
2054 // references are only processed to finish the referenced element creation.
2055 if (!(Class.isNested() || Class.isScoped())) {
2056 if (LVScope *Namespace = Shared->NamespaceDeduction.get(ScopedName: Class.getName()))
2057 Namespace->addElement(Scope);
2058 else
2059 Reader->getCompileUnit()->addElement(Scope);
2060 }
2061
2062 LazyRandomTypeCollection &Types = types();
2063 TypeIndex TIFieldList = Class.getFieldList();
2064 if (TIFieldList.isNoneType()) {
2065 TypeIndex ForwardType = Shared->ForwardReferences.find(Name: Class.getName());
2066 if (!ForwardType.isNoneType()) {
2067 CVType CVReference = Types.getType(Index: ForwardType);
2068 TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());
2069 ClassRecord ReferenceRecord(RK);
2070 if (Error Err = TypeDeserializer::deserializeAs(
2071 CVT&: const_cast<CVType &>(CVReference), Record&: ReferenceRecord))
2072 return Err;
2073 TIFieldList = ReferenceRecord.getFieldList();
2074 }
2075 }
2076
2077 if (!TIFieldList.isNoneType()) {
2078 // Pass down the TypeIndex 'TI' for the aggregate containing the field list.
2079 CVType CVFieldList = Types.getType(Index: TIFieldList);
2080 if (Error Err = finishVisitation(Record&: CVFieldList, TI, Element: Scope))
2081 return Err;
2082 }
2083
2084 return Error::success();
2085}
2086
2087// LF_ENUM (TPI)
2088Error LVLogicalVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum,
2089 TypeIndex TI, LVElement *Element) {
2090 LLVM_DEBUG({
2091 printTypeBegin(Record, TI, Element, StreamTPI);
2092 W.printNumber("NumEnumerators", Enum.getMemberCount());
2093 printTypeIndex("UnderlyingType", Enum.getUnderlyingType(), StreamTPI);
2094 printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);
2095 W.printString("Name", Enum.getName());
2096 printTypeEnd(Record);
2097 });
2098
2099 LVScopeEnumeration *Scope = static_cast<LVScopeEnumeration *>(Element);
2100 if (!Scope)
2101 return Error::success();
2102
2103 if (Scope->getIsFinalized())
2104 return Error::success();
2105 Scope->setIsFinalized();
2106
2107 // Set the name, as in the case of nested, it would determine the relation
2108 // to any potential parent, via the LF_NESTTYPE record.
2109 Scope->setName(Enum.getName());
2110 if (Enum.hasUniqueName())
2111 Scope->setLinkageName(Enum.getUniqueName());
2112
2113 Scope->setType(getElement(StreamIdx: StreamTPI, TI: Enum.getUnderlyingType()));
2114
2115 if (Enum.isNested()) {
2116 Scope->setIsNested();
2117 createParents(ScopedName: Enum.getName(), Element: Scope);
2118 }
2119
2120 if (Enum.isScoped()) {
2121 Scope->setIsScoped();
2122 Scope->setIsEnumClass();
2123 }
2124
2125 // Nested types will be added to their parents at creation.
2126 if (!(Enum.isNested() || Enum.isScoped())) {
2127 if (LVScope *Namespace = Shared->NamespaceDeduction.get(ScopedName: Enum.getName()))
2128 Namespace->addElement(Scope);
2129 else
2130 Reader->getCompileUnit()->addElement(Scope);
2131 }
2132
2133 TypeIndex TIFieldList = Enum.getFieldList();
2134 if (!TIFieldList.isNoneType()) {
2135 LazyRandomTypeCollection &Types = types();
2136 CVType CVFieldList = Types.getType(Index: TIFieldList);
2137 if (Error Err = finishVisitation(Record&: CVFieldList, TI: TIFieldList, Element: Scope))
2138 return Err;
2139 }
2140
2141 return Error::success();
2142}
2143
2144// LF_FIELDLIST (TPI)
2145Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2146 FieldListRecord &FieldList,
2147 TypeIndex TI, LVElement *Element) {
2148 LLVM_DEBUG({
2149 printTypeBegin(Record, TI, Element, StreamTPI);
2150 printTypeEnd(Record);
2151 });
2152
2153 if (Error Err = visitFieldListMemberStream(TI, Element, FieldList: FieldList.Data))
2154 return Err;
2155
2156 return Error::success();
2157}
2158
2159// LF_FUNC_ID (TPI)/(IPI)
2160Error LVLogicalVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func,
2161 TypeIndex TI, LVElement *Element) {
2162 // ParentScope and FunctionType are references into the TPI stream.
2163 LLVM_DEBUG({
2164 printTypeBegin(Record, TI, Element, StreamIPI);
2165 printTypeIndex("ParentScope", Func.getParentScope(), StreamTPI);
2166 printTypeIndex("FunctionType", Func.getFunctionType(), StreamTPI);
2167 W.printString("Name", Func.getName());
2168 printTypeEnd(Record);
2169 });
2170
2171 // The TypeIndex (LF_PROCEDURE) returned by 'getFunctionType' is the
2172 // function propotype, we need to use the function definition.
2173 if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {
2174 // For inlined functions, the inlined instance has been already processed
2175 // (all its information is contained in the Symbols section).
2176 // 'Element' points to the created 'abstract' (out-of-line) function.
2177 // Use the parent scope information to allocate it to the correct scope.
2178 LazyRandomTypeCollection &Types = types();
2179 TypeIndex TIParent = Func.getParentScope();
2180 if (FunctionDcl->getIsInlinedAbstract()) {
2181 FunctionDcl->setName(Func.getName());
2182 if (TIParent.isNoneType())
2183 Reader->getCompileUnit()->addElement(Scope: FunctionDcl);
2184 }
2185
2186 if (!TIParent.isNoneType()) {
2187 CVType CVParentScope = ids().getType(Index: TIParent);
2188 if (Error Err = finishVisitation(Record&: CVParentScope, TI: TIParent, Element: FunctionDcl))
2189 return Err;
2190 }
2191
2192 TypeIndex TIFunctionType = Func.getFunctionType();
2193 CVType CVFunctionType = Types.getType(Index: TIFunctionType);
2194 if (Error Err =
2195 finishVisitation(Record&: CVFunctionType, TI: TIFunctionType, Element: FunctionDcl))
2196 return Err;
2197
2198 FunctionDcl->setIsFinalized();
2199 }
2200
2201 return Error::success();
2202}
2203
2204// LF_LABEL (TPI)
2205Error LVLogicalVisitor::visitKnownRecord(CVType &Record, LabelRecord &LR,
2206 TypeIndex TI, LVElement *Element) {
2207 LLVM_DEBUG({
2208 printTypeBegin(Record, TI, Element, StreamTPI);
2209 printTypeEnd(Record);
2210 });
2211 return Error::success();
2212}
2213
2214// LF_MFUNC_ID (TPI)/(IPI)
2215Error LVLogicalVisitor::visitKnownRecord(CVType &Record, MemberFuncIdRecord &Id,
2216 TypeIndex TI, LVElement *Element) {
2217 // ClassType and FunctionType are references into the TPI stream.
2218 LLVM_DEBUG({
2219 printTypeBegin(Record, TI, Element, StreamIPI);
2220 printTypeIndex("ClassType", Id.getClassType(), StreamTPI);
2221 printTypeIndex("FunctionType", Id.getFunctionType(), StreamTPI);
2222 W.printString("Name", Id.getName());
2223 printTypeEnd(Record);
2224 });
2225
2226 LVScope *FunctionDcl = static_cast<LVScope *>(Element);
2227 if (FunctionDcl->getIsInlinedAbstract()) {
2228 // For inlined functions, the inlined instance has been already processed
2229 // (all its information is contained in the Symbols section).
2230 // 'Element' points to the created 'abstract' (out-of-line) function.
2231 // Use the parent scope information to allocate it to the correct scope.
2232 if (LVScope *Class = static_cast<LVScope *>(
2233 Shared->TypeRecords.find(StreamIdx: StreamTPI, TI: Id.getClassType())))
2234 Class->addElement(Scope: FunctionDcl);
2235 }
2236
2237 TypeIndex TIFunctionType = Id.getFunctionType();
2238 CVType CVFunction = types().getType(Index: TIFunctionType);
2239 if (Error Err = finishVisitation(Record&: CVFunction, TI: TIFunctionType, Element))
2240 return Err;
2241
2242 return Error::success();
2243}
2244
2245// LF_MFUNCTION (TPI)
2246Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2247 MemberFunctionRecord &MF, TypeIndex TI,
2248 LVElement *Element) {
2249 LLVM_DEBUG({
2250 printTypeBegin(Record, TI, Element, StreamTPI);
2251 printTypeIndex("ReturnType", MF.getReturnType(), StreamTPI);
2252 printTypeIndex("ClassType", MF.getClassType(), StreamTPI);
2253 printTypeIndex("ThisType", MF.getThisType(), StreamTPI);
2254 W.printNumber("NumParameters", MF.getParameterCount());
2255 printTypeIndex("ArgListType", MF.getArgumentList(), StreamTPI);
2256 W.printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
2257 printTypeEnd(Record);
2258 });
2259
2260 if (LVScope *MemberFunction = static_cast<LVScope *>(Element)) {
2261 LVElement *Class = getElement(StreamIdx: StreamTPI, TI: MF.getClassType());
2262
2263 MemberFunction->setIsFinalized();
2264 MemberFunction->setType(getElement(StreamIdx: StreamTPI, TI: MF.getReturnType()));
2265 MemberFunction->setOffset(TI.getIndex());
2266 MemberFunction->setOffsetFromTypeIndex();
2267
2268 if (ProcessArgumentList) {
2269 ProcessArgumentList = false;
2270
2271 if (!MemberFunction->getIsStatic()) {
2272 LVElement *ThisPointer = getElement(StreamIdx: StreamTPI, TI: MF.getThisType());
2273 // When creating the 'this' pointer, check if it points to a reference.
2274 ThisPointer->setType(Class);
2275 LVSymbol *This =
2276 createParameter(Element: ThisPointer, Name: StringRef(), Parent: MemberFunction);
2277 This->setIsArtificial();
2278 }
2279
2280 // Create formal parameters.
2281 LazyRandomTypeCollection &Types = types();
2282 CVType CVArguments = Types.getType(Index: MF.getArgumentList());
2283 if (Error Err = finishVisitation(Record&: CVArguments, TI: MF.getArgumentList(),
2284 Element: MemberFunction))
2285 return Err;
2286 }
2287 }
2288
2289 return Error::success();
2290}
2291
2292// LF_METHODLIST (TPI)
2293Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2294 MethodOverloadListRecord &Overloads,
2295 TypeIndex TI, LVElement *Element) {
2296 LLVM_DEBUG({
2297 printTypeBegin(Record, TI, Element, StreamTPI);
2298 printTypeEnd(Record);
2299 });
2300
2301 for (OneMethodRecord &Method : Overloads.Methods) {
2302 CVMemberRecord Record;
2303 Record.Kind = LF_METHOD;
2304 Method.Name = OverloadedMethodName;
2305 if (Error Err = visitKnownMember(Record, Method, TI, Element))
2306 return Err;
2307 }
2308
2309 return Error::success();
2310}
2311
2312// LF_MODIFIER (TPI)
2313Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ModifierRecord &Mod,
2314 TypeIndex TI, LVElement *Element) {
2315 LLVM_DEBUG({
2316 printTypeBegin(Record, TI, Element, StreamTPI);
2317 printTypeIndex("ModifiedType", Mod.getModifiedType(), StreamTPI);
2318 printTypeEnd(Record);
2319 });
2320
2321 // Create the modified type, which will be attached to the type(s) that
2322 // contains the modifiers.
2323 LVElement *ModifiedType = getElement(StreamIdx: StreamTPI, TI: Mod.getModifiedType());
2324
2325 // At this point the types recording the qualifiers do not have a
2326 // scope parent. They must be assigned to the current compile unit.
2327 LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();
2328
2329 // The incoming element does not have a defined kind. Use the given
2330 // modifiers to complete its type. A type can have more than one modifier;
2331 // in that case, we have to create an extra type to have the other modifier.
2332 LVType *LastLink = static_cast<LVType *>(Element);
2333 if (!LastLink->getParentScope())
2334 CompileUnit->addElement(Type: LastLink);
2335
2336 bool SeenModifier = false;
2337 uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
2338 if (Mods & uint16_t(ModifierOptions::Const)) {
2339 SeenModifier = true;
2340 LastLink->setTag(dwarf::DW_TAG_const_type);
2341 LastLink->setIsConst();
2342 LastLink->setName("const");
2343 }
2344 if (Mods & uint16_t(ModifierOptions::Volatile)) {
2345 if (SeenModifier) {
2346 LVType *Volatile = Reader->createType();
2347 Volatile->setIsModifier();
2348 LastLink->setType(Volatile);
2349 LastLink = Volatile;
2350 CompileUnit->addElement(Type: LastLink);
2351 }
2352 LastLink->setTag(dwarf::DW_TAG_volatile_type);
2353 LastLink->setIsVolatile();
2354 LastLink->setName("volatile");
2355 }
2356 if (Mods & uint16_t(ModifierOptions::Unaligned)) {
2357 if (SeenModifier) {
2358 LVType *Unaligned = Reader->createType();
2359 Unaligned->setIsModifier();
2360 LastLink->setType(Unaligned);
2361 LastLink = Unaligned;
2362 CompileUnit->addElement(Type: LastLink);
2363 }
2364 LastLink->setTag(dwarf::DW_TAG_unaligned);
2365 LastLink->setIsUnaligned();
2366 LastLink->setName("unaligned");
2367 }
2368
2369 LastLink->setType(ModifiedType);
2370 return Error::success();
2371}
2372
2373// LF_POINTER (TPI)
2374Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PointerRecord &Ptr,
2375 TypeIndex TI, LVElement *Element) {
2376 LLVM_DEBUG({
2377 printTypeBegin(Record, TI, Element, StreamTPI);
2378 printTypeIndex("PointeeType", Ptr.getReferentType(), StreamTPI);
2379 W.printNumber("IsFlat", Ptr.isFlat());
2380 W.printNumber("IsConst", Ptr.isConst());
2381 W.printNumber("IsVolatile", Ptr.isVolatile());
2382 W.printNumber("IsUnaligned", Ptr.isUnaligned());
2383 W.printNumber("IsRestrict", Ptr.isRestrict());
2384 W.printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
2385 W.printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
2386 W.printNumber("SizeOf", Ptr.getSize());
2387
2388 if (Ptr.isPointerToMember()) {
2389 const MemberPointerInfo &MI = Ptr.getMemberInfo();
2390 printTypeIndex("ClassType", MI.getContainingType(), StreamTPI);
2391 }
2392 printTypeEnd(Record);
2393 });
2394
2395 // Find the pointed-to type.
2396 LVType *Pointer = static_cast<LVType *>(Element);
2397 LVElement *Pointee = nullptr;
2398
2399 PointerMode Mode = Ptr.getMode();
2400 Pointee = Ptr.isPointerToMember()
2401 ? Shared->TypeRecords.find(StreamIdx: StreamTPI, TI: Ptr.getReferentType())
2402 : getElement(StreamIdx: StreamTPI, TI: Ptr.getReferentType());
2403
2404 // At this point the types recording the qualifiers do not have a
2405 // scope parent. They must be assigned to the current compile unit.
2406 LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();
2407
2408 // Order for the different modifiers:
2409 // <restrict> <pointer, Reference, ValueReference> <const, volatile>
2410 // Const and volatile already processed.
2411 bool SeenModifier = false;
2412 LVType *LastLink = Pointer;
2413 if (!LastLink->getParentScope())
2414 CompileUnit->addElement(Type: LastLink);
2415
2416 if (Ptr.isRestrict()) {
2417 SeenModifier = true;
2418 LVType *Restrict = Reader->createType();
2419 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2420 Restrict->setIsRestrict();
2421 Restrict->setName("restrict");
2422 LastLink->setType(Restrict);
2423 LastLink = Restrict;
2424 CompileUnit->addElement(Type: LastLink);
2425 }
2426 if (Mode == PointerMode::LValueReference) {
2427 if (SeenModifier) {
2428 LVType *LReference = Reader->createType();
2429 LReference->setIsModifier();
2430 LastLink->setType(LReference);
2431 LastLink = LReference;
2432 CompileUnit->addElement(Type: LastLink);
2433 }
2434 LastLink->setTag(dwarf::DW_TAG_reference_type);
2435 LastLink->setIsReference();
2436 LastLink->setName("&");
2437 }
2438 if (Mode == PointerMode::RValueReference) {
2439 if (SeenModifier) {
2440 LVType *RReference = Reader->createType();
2441 RReference->setIsModifier();
2442 LastLink->setType(RReference);
2443 LastLink = RReference;
2444 CompileUnit->addElement(Type: LastLink);
2445 }
2446 LastLink->setTag(dwarf::DW_TAG_rvalue_reference_type);
2447 LastLink->setIsRvalueReference();
2448 LastLink->setName("&&");
2449 }
2450
2451 // When creating the pointer, check if it points to a reference.
2452 LastLink->setType(Pointee);
2453 return Error::success();
2454}
2455
2456// LF_PROCEDURE (TPI)
2457Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc,
2458 TypeIndex TI, LVElement *Element) {
2459 LLVM_DEBUG({
2460 printTypeBegin(Record, TI, Element, StreamTPI);
2461 printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);
2462 W.printNumber("NumParameters", Proc.getParameterCount());
2463 printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);
2464 printTypeEnd(Record);
2465 });
2466
2467 // There is no need to traverse the argument list, as the CodeView format
2468 // declares the parameters as a 'S_LOCAL' symbol tagged as parameter.
2469 // Only process parameters when dealing with inline functions.
2470 if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {
2471 FunctionDcl->setType(getElement(StreamIdx: StreamTPI, TI: Proc.getReturnType()));
2472
2473 if (ProcessArgumentList) {
2474 ProcessArgumentList = false;
2475 // Create formal parameters.
2476 LazyRandomTypeCollection &Types = types();
2477 CVType CVArguments = Types.getType(Index: Proc.getArgumentList());
2478 if (Error Err = finishVisitation(Record&: CVArguments, TI: Proc.getArgumentList(),
2479 Element: FunctionDcl))
2480 return Err;
2481 }
2482 }
2483
2484 return Error::success();
2485}
2486
2487// LF_UNION (TPI)
2488Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,
2489 TypeIndex TI, LVElement *Element) {
2490 LLVM_DEBUG({
2491 printTypeBegin(Record, TI, Element, StreamTPI);
2492 W.printNumber("MemberCount", Union.getMemberCount());
2493 printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);
2494 W.printNumber("SizeOf", Union.getSize());
2495 W.printString("Name", Union.getName());
2496 if (Union.hasUniqueName())
2497 W.printString("UniqueName", Union.getUniqueName());
2498 printTypeEnd(Record);
2499 });
2500
2501 LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);
2502 if (!Scope)
2503 return Error::success();
2504
2505 if (Scope->getIsFinalized())
2506 return Error::success();
2507 Scope->setIsFinalized();
2508
2509 Scope->setName(Union.getName());
2510 if (Union.hasUniqueName())
2511 Scope->setLinkageName(Union.getUniqueName());
2512 Scope->setBitSize(Union.getSize() * DWARF_CHAR_BIT);
2513
2514 if (Union.isNested()) {
2515 Scope->setIsNested();
2516 createParents(ScopedName: Union.getName(), Element: Scope);
2517 } else {
2518 if (LVScope *Namespace = Shared->NamespaceDeduction.get(ScopedName: Union.getName()))
2519 Namespace->addElement(Scope);
2520 else
2521 Reader->getCompileUnit()->addElement(Scope);
2522 }
2523
2524 if (!Union.getFieldList().isNoneType()) {
2525 LazyRandomTypeCollection &Types = types();
2526 // Pass down the TypeIndex 'TI' for the aggregate containing the field list.
2527 CVType CVFieldList = Types.getType(Index: Union.getFieldList());
2528 if (Error Err = finishVisitation(Record&: CVFieldList, TI, Element: Scope))
2529 return Err;
2530 }
2531
2532 return Error::success();
2533}
2534
2535// LF_TYPESERVER2 (TPI)
2536Error LVLogicalVisitor::visitKnownRecord(CVType &Record, TypeServer2Record &TS,
2537 TypeIndex TI, LVElement *Element) {
2538 LLVM_DEBUG({
2539 printTypeBegin(Record, TI, Element, StreamTPI);
2540 W.printString("Guid", formatv("{0}", TS.getGuid()).str());
2541 W.printNumber("Age", TS.getAge());
2542 W.printString("Name", TS.getName());
2543 printTypeEnd(Record);
2544 });
2545 return Error::success();
2546}
2547
2548// LF_VFTABLE (TPI)
2549Error LVLogicalVisitor::visitKnownRecord(CVType &Record, VFTableRecord &VFT,
2550 TypeIndex TI, LVElement *Element) {
2551 LLVM_DEBUG({
2552 printTypeBegin(Record, TI, Element, StreamTPI);
2553 printTypeIndex("CompleteClass", VFT.getCompleteClass(), StreamTPI);
2554 printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable(), StreamTPI);
2555 W.printHex("VFPtrOffset", VFT.getVFPtrOffset());
2556 W.printString("VFTableName", VFT.getName());
2557 for (const StringRef &N : VFT.getMethodNames())
2558 W.printString("MethodName", N);
2559 printTypeEnd(Record);
2560 });
2561 return Error::success();
2562}
2563
2564// LF_VTSHAPE (TPI)
2565Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2566 VFTableShapeRecord &Shape,
2567 TypeIndex TI, LVElement *Element) {
2568 LLVM_DEBUG({
2569 printTypeBegin(Record, TI, Element, StreamTPI);
2570 W.printNumber("VFEntryCount", Shape.getEntryCount());
2571 printTypeEnd(Record);
2572 });
2573 return Error::success();
2574}
2575
2576// LF_SUBSTR_LIST (TPI)/(IPI)
2577Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2578 StringListRecord &Strings,
2579 TypeIndex TI, LVElement *Element) {
2580 // All the indices are references into the TPI/IPI stream.
2581 LLVM_DEBUG({
2582 printTypeBegin(Record, TI, Element, StreamIPI);
2583 ArrayRef<TypeIndex> Indices = Strings.getIndices();
2584 uint32_t Size = Indices.size();
2585 W.printNumber("NumStrings", Size);
2586 ListScope Arguments(W, "Strings");
2587 for (uint32_t I = 0; I < Size; ++I)
2588 printTypeIndex("String", Indices[I], StreamIPI);
2589 printTypeEnd(Record);
2590 });
2591 return Error::success();
2592}
2593
2594// LF_STRING_ID (TPI)/(IPI)
2595Error LVLogicalVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String,
2596 TypeIndex TI, LVElement *Element) {
2597 // All args are references into the TPI/IPI stream.
2598 LLVM_DEBUG({
2599 printTypeIndex("\nTI", TI, StreamIPI);
2600 printTypeIndex("Id", String.getId(), StreamIPI);
2601 W.printString("StringData", String.getString());
2602 });
2603
2604 if (LVScope *Namespace = Shared->NamespaceDeduction.get(
2605 ScopedName: String.getString(), /*CheckScope=*/false)) {
2606 // The function is already at different scope. In order to reflect
2607 // the correct parent, move it to the namespace.
2608 if (LVScope *Scope = Element->getParentScope())
2609 Scope->removeElement(Element);
2610 Namespace->addElement(Element);
2611 }
2612
2613 return Error::success();
2614}
2615
2616// LF_UDT_SRC_LINE (TPI)/(IPI)
2617Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2618 UdtSourceLineRecord &SourceLine,
2619 TypeIndex TI, LVElement *Element) {
2620 // All args are references into the TPI/IPI stream.
2621 LLVM_DEBUG({
2622 printTypeIndex("\nTI", TI, StreamIPI);
2623 printTypeIndex("UDT", SourceLine.getUDT(), StreamIPI);
2624 printTypeIndex("SourceFile", SourceLine.getSourceFile(), StreamIPI);
2625 W.printNumber("LineNumber", SourceLine.getLineNumber());
2626 });
2627 return Error::success();
2628}
2629
2630// LF_UDT_MOD_SRC_LINE (TPI)/(IPI)
2631Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2632 UdtModSourceLineRecord &ModSourceLine,
2633 TypeIndex TI, LVElement *Element) {
2634 // All args are references into the TPI/IPI stream.
2635 LLVM_DEBUG({
2636 printTypeBegin(Record, TI, Element, StreamIPI);
2637 printTypeIndex("\nTI", TI, StreamIPI);
2638 printTypeIndex("UDT", ModSourceLine.getUDT(), StreamIPI);
2639 printTypeIndex("SourceFile", ModSourceLine.getSourceFile(), StreamIPI);
2640 W.printNumber("LineNumber", ModSourceLine.getLineNumber());
2641 W.printNumber("Module", ModSourceLine.getModule());
2642 printTypeEnd(Record);
2643 });
2644 return Error::success();
2645}
2646
2647// LF_PRECOMP (TPI)
2648Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PrecompRecord &Precomp,
2649 TypeIndex TI, LVElement *Element) {
2650 LLVM_DEBUG({
2651 printTypeBegin(Record, TI, Element, StreamTPI);
2652 W.printHex("StartIndex", Precomp.getStartTypeIndex());
2653 W.printHex("Count", Precomp.getTypesCount());
2654 W.printHex("Signature", Precomp.getSignature());
2655 W.printString("PrecompFile", Precomp.getPrecompFilePath());
2656 printTypeEnd(Record);
2657 });
2658 return Error::success();
2659}
2660
2661// LF_ENDPRECOMP (TPI)
2662Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
2663 EndPrecompRecord &EndPrecomp,
2664 TypeIndex TI, LVElement *Element) {
2665 LLVM_DEBUG({
2666 printTypeBegin(Record, TI, Element, StreamTPI);
2667 W.printHex("Signature", EndPrecomp.getSignature());
2668 printTypeEnd(Record);
2669 });
2670 return Error::success();
2671}
2672
2673Error LVLogicalVisitor::visitUnknownMember(CVMemberRecord &Record,
2674 TypeIndex TI) {
2675 LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
2676 return Error::success();
2677}
2678
2679// LF_BCLASS, LF_BINTERFACE
2680Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2681 BaseClassRecord &Base, TypeIndex TI,
2682 LVElement *Element) {
2683 LLVM_DEBUG({
2684 printMemberBegin(Record, TI, Element, StreamTPI);
2685 printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);
2686 W.printHex("BaseOffset", Base.getBaseOffset());
2687 printMemberEnd(Record);
2688 });
2689
2690 createElement(Kind: Record.Kind);
2691 if (LVSymbol *Symbol = CurrentSymbol) {
2692 LVElement *BaseClass = getElement(StreamIdx: StreamTPI, TI: Base.getBaseType());
2693 Symbol->setName(BaseClass->getName());
2694 Symbol->setType(BaseClass);
2695 Symbol->setAccessibilityCode(Base.getAccess());
2696 static_cast<LVScope *>(Element)->addElement(Symbol);
2697 }
2698
2699 return Error::success();
2700}
2701
2702// LF_MEMBER
2703Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2704 DataMemberRecord &Field, TypeIndex TI,
2705 LVElement *Element) {
2706 LLVM_DEBUG({
2707 printMemberBegin(Record, TI, Element, StreamTPI);
2708 printTypeIndex("Type", Field.getType(), StreamTPI);
2709 W.printHex("FieldOffset", Field.getFieldOffset());
2710 W.printString("Name", Field.getName());
2711 printMemberEnd(Record);
2712 });
2713
2714 // Create the data member.
2715 createDataMember(Record, Parent: static_cast<LVScope *>(Element), Name: Field.getName(),
2716 Type: Field.getType(), Access: Field.getAccess());
2717 return Error::success();
2718}
2719
2720// LF_ENUMERATE
2721Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2722 EnumeratorRecord &Enum, TypeIndex TI,
2723 LVElement *Element) {
2724 LLVM_DEBUG({
2725 printMemberBegin(Record, TI, Element, StreamTPI);
2726 W.printNumber("EnumValue", Enum.getValue());
2727 W.printString("Name", Enum.getName());
2728 printMemberEnd(Record);
2729 });
2730
2731 createElement(Kind: Record.Kind);
2732 if (LVType *Type = CurrentType) {
2733 Type->setName(Enum.getName());
2734 SmallString<16> Value;
2735 Enum.getValue().toString(Str&: Value, Radix: 16, Signed: true, formatAsCLiteral: true);
2736 Type->setValue(Value);
2737 static_cast<LVScope *>(Element)->addElement(Type: CurrentType);
2738 }
2739
2740 return Error::success();
2741}
2742
2743// LF_INDEX
2744Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2745 ListContinuationRecord &Cont,
2746 TypeIndex TI, LVElement *Element) {
2747 LLVM_DEBUG({
2748 printMemberBegin(Record, TI, Element, StreamTPI);
2749 printTypeIndex("ContinuationIndex", Cont.getContinuationIndex(), StreamTPI);
2750 printMemberEnd(Record);
2751 });
2752 return Error::success();
2753}
2754
2755// LF_NESTTYPE
2756Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2757 NestedTypeRecord &Nested, TypeIndex TI,
2758 LVElement *Element) {
2759 LLVM_DEBUG({
2760 printMemberBegin(Record, TI, Element, StreamTPI);
2761 printTypeIndex("Type", Nested.getNestedType(), StreamTPI);
2762 W.printString("Name", Nested.getName());
2763 printMemberEnd(Record);
2764 });
2765
2766 if (LVElement *Typedef = createElement(Kind: SymbolKind::S_UDT)) {
2767 Typedef->setName(Nested.getName());
2768 LVElement *NestedType = getElement(StreamIdx: StreamTPI, TI: Nested.getNestedType());
2769 Typedef->setType(NestedType);
2770 LVScope *Scope = static_cast<LVScope *>(Element);
2771 Scope->addElement(Element: Typedef);
2772
2773 if (NestedType && NestedType->getIsNested()) {
2774 // 'Element' is an aggregate type that may contains this nested type
2775 // definition. Used their scoped names, to decide on their relationship.
2776 StringRef RecordName = getRecordName(Types&: types(), TI);
2777
2778 StringRef NestedTypeName = NestedType->getName();
2779 if (NestedTypeName.size() && RecordName.size()) {
2780 StringRef OuterComponent;
2781 std::tie(args&: OuterComponent, args: std::ignore) =
2782 getInnerComponent(Name: NestedTypeName);
2783 // We have an already created nested type. Add it to the current scope
2784 // and update all its children if any.
2785 if (OuterComponent.size() && OuterComponent == RecordName) {
2786 if (!NestedType->getIsScopedAlready()) {
2787 Scope->addElement(Element: NestedType);
2788 NestedType->setIsScopedAlready();
2789 NestedType->updateLevel(Parent: Scope);
2790 }
2791 Typedef->resetIncludeInPrint();
2792 }
2793 }
2794 }
2795 }
2796
2797 return Error::success();
2798}
2799
2800// LF_ONEMETHOD
2801Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2802 OneMethodRecord &Method, TypeIndex TI,
2803 LVElement *Element) {
2804 LLVM_DEBUG({
2805 printMemberBegin(Record, TI, Element, StreamTPI);
2806 printTypeIndex("Type", Method.getType(), StreamTPI);
2807 // If virtual, then read the vftable offset.
2808 if (Method.isIntroducingVirtual())
2809 W.printHex("VFTableOffset", Method.getVFTableOffset());
2810 W.printString("Name", Method.getName());
2811 printMemberEnd(Record);
2812 });
2813
2814 // All the LF_ONEMETHOD objects share the same type description.
2815 // We have to create a scope object for each one and get the required
2816 // information from the LF_MFUNCTION object.
2817 ProcessArgumentList = true;
2818 if (LVElement *MemberFunction = createElement(Kind: TypeLeafKind::LF_ONEMETHOD)) {
2819 MemberFunction->setIsFinalized();
2820 static_cast<LVScope *>(Element)->addElement(Element: MemberFunction);
2821
2822 MemberFunction->setName(Method.getName());
2823 MemberFunction->setAccessibilityCode(Method.getAccess());
2824
2825 MethodKind Kind = Method.getMethodKind();
2826 if (Kind == MethodKind::Static)
2827 MemberFunction->setIsStatic();
2828 MemberFunction->setVirtualityCode(Kind);
2829
2830 MethodOptions Flags = Method.Attrs.getFlags();
2831 if (MethodOptions::CompilerGenerated ==
2832 (Flags & MethodOptions::CompilerGenerated))
2833 MemberFunction->setIsArtificial();
2834
2835 LazyRandomTypeCollection &Types = types();
2836 CVType CVMethodType = Types.getType(Index: Method.getType());
2837 if (Error Err =
2838 finishVisitation(Record&: CVMethodType, TI: Method.getType(), Element: MemberFunction))
2839 return Err;
2840 }
2841 ProcessArgumentList = false;
2842
2843 return Error::success();
2844}
2845
2846// LF_METHOD
2847Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2848 OverloadedMethodRecord &Method,
2849 TypeIndex TI, LVElement *Element) {
2850 LLVM_DEBUG({
2851 printMemberBegin(Record, TI, Element, StreamTPI);
2852 W.printHex("MethodCount", Method.getNumOverloads());
2853 printTypeIndex("MethodListIndex", Method.getMethodList(), StreamTPI);
2854 W.printString("Name", Method.getName());
2855 printMemberEnd(Record);
2856 });
2857
2858 // Record the overloaded method name, which will be used during the
2859 // traversal of the method list.
2860 LazyRandomTypeCollection &Types = types();
2861 OverloadedMethodName = Method.getName();
2862 CVType CVMethods = Types.getType(Index: Method.getMethodList());
2863 if (Error Err = finishVisitation(Record&: CVMethods, TI: Method.getMethodList(), Element))
2864 return Err;
2865
2866 return Error::success();
2867}
2868
2869// LF_STMEMBER
2870Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2871 StaticDataMemberRecord &Field,
2872 TypeIndex TI, LVElement *Element) {
2873 LLVM_DEBUG({
2874 printMemberBegin(Record, TI, Element, StreamTPI);
2875 printTypeIndex("Type", Field.getType(), StreamTPI);
2876 W.printString("Name", Field.getName());
2877 printMemberEnd(Record);
2878 });
2879
2880 // Create the data member.
2881 createDataMember(Record, Parent: static_cast<LVScope *>(Element), Name: Field.getName(),
2882 Type: Field.getType(), Access: Field.getAccess());
2883 return Error::success();
2884}
2885
2886// LF_VFUNCTAB
2887Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2888 VFPtrRecord &VFTable, TypeIndex TI,
2889 LVElement *Element) {
2890 LLVM_DEBUG({
2891 printMemberBegin(Record, TI, Element, StreamTPI);
2892 printTypeIndex("Type", VFTable.getType(), StreamTPI);
2893 printMemberEnd(Record);
2894 });
2895 return Error::success();
2896}
2897
2898// LF_VBCLASS, LF_IVBCLASS
2899Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
2900 VirtualBaseClassRecord &Base,
2901 TypeIndex TI, LVElement *Element) {
2902 LLVM_DEBUG({
2903 printMemberBegin(Record, TI, Element, StreamTPI);
2904 printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);
2905 printTypeIndex("VBPtrType", Base.getVBPtrType(), StreamTPI);
2906 W.printHex("VBPtrOffset", Base.getVBPtrOffset());
2907 W.printHex("VBTableIndex", Base.getVTableIndex());
2908 printMemberEnd(Record);
2909 });
2910
2911 createElement(Kind: Record.Kind);
2912 if (LVSymbol *Symbol = CurrentSymbol) {
2913 LVElement *BaseClass = getElement(StreamIdx: StreamTPI, TI: Base.getBaseType());
2914 Symbol->setName(BaseClass->getName());
2915 Symbol->setType(BaseClass);
2916 Symbol->setAccessibilityCode(Base.getAccess());
2917 Symbol->setVirtualityCode(MethodKind::Virtual);
2918 static_cast<LVScope *>(Element)->addElement(Symbol);
2919 }
2920
2921 return Error::success();
2922}
2923
2924Error LVLogicalVisitor::visitMemberRecord(CVMemberRecord &Record,
2925 TypeVisitorCallbacks &Callbacks,
2926 TypeIndex TI, LVElement *Element) {
2927 if (Error Err = Callbacks.visitMemberBegin(Record))
2928 return Err;
2929
2930 switch (Record.Kind) {
2931 default:
2932 if (Error Err = Callbacks.visitUnknownMember(Record))
2933 return Err;
2934 break;
2935#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2936 case EnumName: { \
2937 if (Error Err = \
2938 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2939 return Err; \
2940 break; \
2941 }
2942#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2943 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2944#define TYPE_RECORD(EnumName, EnumVal, Name)
2945#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2946#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2947 }
2948
2949 if (Error Err = Callbacks.visitMemberEnd(Record))
2950 return Err;
2951
2952 return Error::success();
2953}
2954
2955Error LVLogicalVisitor::finishVisitation(CVType &Record, TypeIndex TI,
2956 LVElement *Element) {
2957 switch (Record.kind()) {
2958 default:
2959 if (Error Err = visitUnknownType(Record, TI))
2960 return Err;
2961 break;
2962#define TYPE_RECORD(EnumName, EnumVal, Name) \
2963 case EnumName: { \
2964 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2965 return Err; \
2966 break; \
2967 }
2968#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2969 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2970#define MEMBER_RECORD(EnumName, EnumVal, Name)
2971#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2972#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2973 }
2974
2975 return Error::success();
2976}
2977
2978// Customized version of 'FieldListVisitHelper'.
2979Error LVLogicalVisitor::visitFieldListMemberStream(
2980 TypeIndex TI, LVElement *Element, ArrayRef<uint8_t> FieldList) {
2981 BinaryByteStream Stream(FieldList, llvm::endianness::little);
2982 BinaryStreamReader Reader(Stream);
2983 FieldListDeserializer Deserializer(Reader);
2984 TypeVisitorCallbackPipeline Pipeline;
2985 Pipeline.addCallbackToPipeline(Callbacks&: Deserializer);
2986
2987 TypeLeafKind Leaf;
2988 while (!Reader.empty()) {
2989 if (Error Err = Reader.readEnum(Dest&: Leaf))
2990 return Err;
2991
2992 CVMemberRecord Record;
2993 Record.Kind = Leaf;
2994 if (Error Err = visitMemberRecord(Record, Callbacks&: Pipeline, TI, Element))
2995 return Err;
2996 }
2997
2998 return Error::success();
2999}
3000
3001void LVLogicalVisitor::addElement(LVScope *Scope, bool IsCompileUnit) {
3002 // The CodeView specifications does not treat S_COMPILE2 and S_COMPILE3
3003 // as symbols that open a scope. The CodeView reader, treat them in a
3004 // similar way as DWARF. As there is no a symbole S_END to close the
3005 // compile unit, we need to check for the next compile unit.
3006 if (IsCompileUnit) {
3007 if (!ScopeStack.empty())
3008 popScope();
3009 InCompileUnitScope = true;
3010 }
3011
3012 pushScope(Scope);
3013 ReaderParent->addElement(Scope);
3014}
3015
3016void LVLogicalVisitor::addElement(LVSymbol *Symbol) {
3017 ReaderScope->addElement(Symbol);
3018}
3019
3020void LVLogicalVisitor::addElement(LVType *Type) {
3021 ReaderScope->addElement(Type);
3022}
3023
3024LVElement *LVLogicalVisitor::createElement(TypeLeafKind Kind) {
3025 CurrentScope = nullptr;
3026 CurrentSymbol = nullptr;
3027 CurrentType = nullptr;
3028
3029 if (Kind < TypeIndex::FirstNonSimpleIndex) {
3030 CurrentType = Reader->createType();
3031 CurrentType->setIsBase();
3032 CurrentType->setTag(dwarf::DW_TAG_base_type);
3033 if (options().getAttributeBase())
3034 CurrentType->setIncludeInPrint();
3035 return CurrentType;
3036 }
3037
3038 switch (Kind) {
3039 // Types.
3040 case TypeLeafKind::LF_ENUMERATE:
3041 CurrentType = Reader->createTypeEnumerator();
3042 CurrentType->setTag(dwarf::DW_TAG_enumerator);
3043 return CurrentType;
3044 case TypeLeafKind::LF_MODIFIER:
3045 CurrentType = Reader->createType();
3046 CurrentType->setIsModifier();
3047 return CurrentType;
3048 case TypeLeafKind::LF_POINTER:
3049 CurrentType = Reader->createType();
3050 CurrentType->setIsPointer();
3051 CurrentType->setName("*");
3052 CurrentType->setTag(dwarf::DW_TAG_pointer_type);
3053 return CurrentType;
3054
3055 // Symbols.
3056 case TypeLeafKind::LF_BCLASS:
3057 case TypeLeafKind::LF_IVBCLASS:
3058 case TypeLeafKind::LF_VBCLASS:
3059 CurrentSymbol = Reader->createSymbol();
3060 CurrentSymbol->setTag(dwarf::DW_TAG_inheritance);
3061 CurrentSymbol->setIsInheritance();
3062 return CurrentSymbol;
3063 case TypeLeafKind::LF_MEMBER:
3064 case TypeLeafKind::LF_STMEMBER:
3065 CurrentSymbol = Reader->createSymbol();
3066 CurrentSymbol->setIsMember();
3067 CurrentSymbol->setTag(dwarf::DW_TAG_member);
3068 return CurrentSymbol;
3069
3070 // Scopes.
3071 case TypeLeafKind::LF_ARRAY:
3072 CurrentScope = Reader->createScopeArray();
3073 CurrentScope->setTag(dwarf::DW_TAG_array_type);
3074 return CurrentScope;
3075 case TypeLeafKind::LF_CLASS:
3076 CurrentScope = Reader->createScopeAggregate();
3077 CurrentScope->setTag(dwarf::DW_TAG_class_type);
3078 CurrentScope->setIsClass();
3079 return CurrentScope;
3080 case TypeLeafKind::LF_ENUM:
3081 CurrentScope = Reader->createScopeEnumeration();
3082 CurrentScope->setTag(dwarf::DW_TAG_enumeration_type);
3083 return CurrentScope;
3084 case TypeLeafKind::LF_METHOD:
3085 case TypeLeafKind::LF_ONEMETHOD:
3086 case TypeLeafKind::LF_PROCEDURE:
3087 CurrentScope = Reader->createScopeFunction();
3088 CurrentScope->setIsSubprogram();
3089 CurrentScope->setTag(dwarf::DW_TAG_subprogram);
3090 return CurrentScope;
3091 case TypeLeafKind::LF_STRUCTURE:
3092 CurrentScope = Reader->createScopeAggregate();
3093 CurrentScope->setIsStructure();
3094 CurrentScope->setTag(dwarf::DW_TAG_structure_type);
3095 return CurrentScope;
3096 case TypeLeafKind::LF_UNION:
3097 CurrentScope = Reader->createScopeAggregate();
3098 CurrentScope->setIsUnion();
3099 CurrentScope->setTag(dwarf::DW_TAG_union_type);
3100 return CurrentScope;
3101 default:
3102 // If '--internal=tag' and '--print=warning' are specified in the command
3103 // line, we record and print each seen 'TypeLeafKind'.
3104 break;
3105 }
3106 return nullptr;
3107}
3108
3109LVElement *LVLogicalVisitor::createElement(SymbolKind Kind) {
3110 CurrentScope = nullptr;
3111 CurrentSymbol = nullptr;
3112 CurrentType = nullptr;
3113 switch (Kind) {
3114 // Types.
3115 case SymbolKind::S_UDT:
3116 CurrentType = Reader->createTypeDefinition();
3117 CurrentType->setTag(dwarf::DW_TAG_typedef);
3118 return CurrentType;
3119
3120 // Symbols.
3121 case SymbolKind::S_CONSTANT:
3122 CurrentSymbol = Reader->createSymbol();
3123 CurrentSymbol->setIsConstant();
3124 CurrentSymbol->setTag(dwarf::DW_TAG_constant);
3125 return CurrentSymbol;
3126
3127 case SymbolKind::S_BPREL32:
3128 case SymbolKind::S_REGREL32:
3129 case SymbolKind::S_REGREL32_INDIR:
3130 case SymbolKind::S_GDATA32:
3131 case SymbolKind::S_LDATA32:
3132 case SymbolKind::S_LOCAL:
3133 // During the symbol traversal more information is available to
3134 // determine if the symbol is a parameter or a variable. At this
3135 // stage mark it as variable.
3136 CurrentSymbol = Reader->createSymbol();
3137 CurrentSymbol->setIsVariable();
3138 CurrentSymbol->setTag(dwarf::DW_TAG_variable);
3139 return CurrentSymbol;
3140
3141 // Scopes.
3142 case SymbolKind::S_BLOCK32:
3143 CurrentScope = Reader->createScope();
3144 CurrentScope->setIsLexicalBlock();
3145 CurrentScope->setTag(dwarf::DW_TAG_lexical_block);
3146 return CurrentScope;
3147 case SymbolKind::S_COMPILE2:
3148 case SymbolKind::S_COMPILE3:
3149 CurrentScope = Reader->createScopeCompileUnit();
3150 CurrentScope->setTag(dwarf::DW_TAG_compile_unit);
3151 Reader->setCompileUnit(static_cast<LVScopeCompileUnit *>(CurrentScope));
3152 return CurrentScope;
3153 case SymbolKind::S_INLINESITE:
3154 case SymbolKind::S_INLINESITE2:
3155 CurrentScope = Reader->createScopeFunctionInlined();
3156 CurrentScope->setIsInlinedFunction();
3157 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3158 return CurrentScope;
3159 case SymbolKind::S_LPROC32:
3160 case SymbolKind::S_GPROC32:
3161 case SymbolKind::S_LPROC32_ID:
3162 case SymbolKind::S_GPROC32_ID:
3163 case SymbolKind::S_SEPCODE:
3164 case SymbolKind::S_THUNK32:
3165 CurrentScope = Reader->createScopeFunction();
3166 CurrentScope->setIsSubprogram();
3167 CurrentScope->setTag(dwarf::DW_TAG_subprogram);
3168 return CurrentScope;
3169 default:
3170 // If '--internal=tag' and '--print=warning' are specified in the command
3171 // line, we record and print each seen 'SymbolKind'.
3172 break;
3173 }
3174 return nullptr;
3175}
3176
3177LVElement *LVLogicalVisitor::createElement(TypeIndex TI, TypeLeafKind Kind) {
3178 LVElement *Element = Shared->TypeRecords.find(StreamIdx: StreamTPI, TI);
3179 if (!Element) {
3180 // We are dealing with a base type or pointer to a base type, which are
3181 // not included explicitly in the CodeView format.
3182 if (Kind < TypeIndex::FirstNonSimpleIndex) {
3183 Element = createElement(Kind);
3184 Element->setIsFinalized();
3185 Shared->TypeRecords.add(StreamIdx: StreamTPI, TI: (TypeIndex)Kind, Kind, Element);
3186 Element->setOffset(Kind);
3187 return Element;
3188 }
3189 // We are dealing with a pointer to a base type.
3190 if (TI.getIndex() < TypeIndex::FirstNonSimpleIndex) {
3191 Element = createElement(Kind);
3192 Shared->TypeRecords.add(StreamIdx: StreamTPI, TI, Kind, Element);
3193 Element->setOffset(TI.getIndex());
3194 Element->setOffsetFromTypeIndex();
3195 return Element;
3196 }
3197
3198 W.printString(Value: "** Not implemented. **");
3199 printTypeIndex(FieldName: "TypeIndex", TI, StreamIdx: StreamTPI);
3200 W.printString(Label: "TypeLeafKind", Value: formatTypeLeafKind(K: Kind));
3201 return nullptr;
3202 }
3203
3204 Element->setOffset(TI.getIndex());
3205 Element->setOffsetFromTypeIndex();
3206 return Element;
3207}
3208
3209void LVLogicalVisitor::createDataMember(CVMemberRecord &Record, LVScope *Parent,
3210 StringRef Name, TypeIndex TI,
3211 MemberAccess Access) {
3212 LLVM_DEBUG({
3213 printTypeIndex("TypeIndex", TI, StreamTPI);
3214 W.printString("TypeName", Name);
3215 });
3216
3217 createElement(Kind: Record.Kind);
3218 if (LVSymbol *Symbol = CurrentSymbol) {
3219 Symbol->setName(Name);
3220 if (TI.isNoneType() || TI.isSimple())
3221 Symbol->setType(getElement(StreamIdx: StreamTPI, TI));
3222 else {
3223 LazyRandomTypeCollection &Types = types();
3224 CVType CVMemberType = Types.getType(Index: TI);
3225 if (CVMemberType.kind() == LF_BITFIELD) {
3226 if (Error Err = finishVisitation(Record&: CVMemberType, TI, Element: Symbol)) {
3227 consumeError(Err: std::move(Err));
3228 return;
3229 }
3230 } else
3231 Symbol->setType(getElement(StreamIdx: StreamTPI, TI));
3232 }
3233 Symbol->setAccessibilityCode(Access);
3234 Parent->addElement(Symbol);
3235 }
3236}
3237
3238LVSymbol *LVLogicalVisitor::createParameter(LVElement *Element, StringRef Name,
3239 LVScope *Parent) {
3240 LVSymbol *Parameter = Reader->createSymbol();
3241 Parent->addElement(Symbol: Parameter);
3242 Parameter->setIsParameter();
3243 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3244 Parameter->setName(Name);
3245 Parameter->setType(Element);
3246 return Parameter;
3247}
3248
3249LVSymbol *LVLogicalVisitor::createParameter(TypeIndex TI, StringRef Name,
3250 LVScope *Parent) {
3251 return createParameter(Element: getElement(StreamIdx: StreamTPI, TI), Name, Parent);
3252}
3253
3254LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {
3255 TypeLeafKind SimpleKind = (TypeLeafKind)TI.getSimpleKind();
3256 TypeIndex TIR = (TypeIndex)SimpleKind;
3257 LLVM_DEBUG({
3258 printTypeIndex("TypeIndex", TIR, StreamTPI);
3259 W.printString("TypeName", TypeName);
3260 });
3261
3262 if (LVElement *Element = Shared->TypeRecords.find(StreamIdx: StreamTPI, TI: TIR))
3263 return static_cast<LVType *>(Element);
3264
3265 if (createElement(TI: TIR, Kind: SimpleKind)) {
3266 CurrentType->setName(TypeName);
3267 CurrentType->setBitSize(getSizeInBytesForTypeIndex(TI: TIR) * DWARF_CHAR_BIT);
3268 Reader->getCompileUnit()->addElement(Type: CurrentType);
3269 }
3270 return CurrentType;
3271}
3272
3273LVType *LVLogicalVisitor::createPointerType(TypeIndex TI, StringRef TypeName) {
3274 LLVM_DEBUG({
3275 printTypeIndex("TypeIndex", TI, StreamTPI);
3276 W.printString("TypeName", TypeName);
3277 });
3278
3279 if (LVElement *Element = Shared->TypeRecords.find(StreamIdx: StreamTPI, TI))
3280 return static_cast<LVType *>(Element);
3281
3282 LVType *Pointee = createBaseType(TI, TypeName: TypeName.drop_back(N: 1));
3283 if (createElement(TI, Kind: TypeLeafKind::LF_POINTER)) {
3284 CurrentType->setIsFinalized();
3285 CurrentType->setType(Pointee);
3286 Reader->getCompileUnit()->addElement(Type: CurrentType);
3287 }
3288 return CurrentType;
3289}
3290
3291void LVLogicalVisitor::createParents(StringRef ScopedName, LVElement *Element) {
3292 // For the given test case:
3293 //
3294 // struct S { enum E { ... }; };
3295 // S::E V;
3296 //
3297 // 0 | S_LOCAL `V`
3298 // type=0x1004 (S::E), flags = none
3299 // 0x1004 | LF_ENUM `S::E`
3300 // options: has unique name | is nested
3301 // 0x1009 | LF_STRUCTURE `S`
3302 // options: contains nested class
3303 //
3304 // When the local 'V' is processed, its type 'E' is created. But There is
3305 // no direct reference to its parent 'S'. We use the scoped name for 'E',
3306 // to create its parents.
3307
3308 // The input scoped name must have at least parent and nested names.
3309 // Drop the last element name, as it corresponds to the nested type.
3310 LVStringRefs Components = getAllLexicalComponents(Name: ScopedName);
3311 if (Components.size() < 2)
3312 return;
3313 Components.pop_back();
3314
3315 LVStringRefs::size_type FirstNamespace;
3316 LVStringRefs::size_type FirstAggregate;
3317 std::tie(args&: FirstNamespace, args&: FirstAggregate) =
3318 Shared->NamespaceDeduction.find(Components);
3319
3320 LLVM_DEBUG({
3321 W.printString("First Namespace", Components[FirstNamespace]);
3322 W.printString("First NonNamespace", Components[FirstAggregate]);
3323 });
3324
3325 // Create any referenced namespaces.
3326 if (FirstNamespace < FirstAggregate) {
3327 Shared->NamespaceDeduction.get(
3328 Components: LVStringRefs(Components.begin() + FirstNamespace,
3329 Components.begin() + FirstAggregate));
3330 }
3331
3332 // Traverse the enclosing scopes (aggregates) and create them. In the
3333 // case of nested empty aggregates, MSVC does not emit a full record
3334 // description. It emits only the reference record.
3335 LVScope *Aggregate = nullptr;
3336 TypeIndex TIAggregate;
3337 std::string AggregateName = getScopedName(
3338 Components: LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3339
3340 // This traversal is executed at least once.
3341 for (LVStringRefs::size_type Index = FirstAggregate;
3342 Index < Components.size(); ++Index) {
3343 AggregateName = getScopedName(Components: LVStringRefs(Components.begin() + Index,
3344 Components.begin() + Index + 1),
3345 BaseName: AggregateName);
3346 TIAggregate = Shared->ForwardReferences.remap(
3347 TI: Shared->TypeRecords.find(StreamIdx: StreamTPI, Name: AggregateName));
3348 Aggregate =
3349 TIAggregate.isNoneType()
3350 ? nullptr
3351 : static_cast<LVScope *>(getElement(StreamIdx: StreamTPI, TI: TIAggregate));
3352 }
3353
3354 // Workaround for cases where LF_NESTTYPE is missing for nested templates.
3355 // If we manage to get parent information from the scoped name, we can add
3356 // the nested type without relying on the LF_NESTTYPE.
3357 if (Aggregate && !Element->getIsScopedAlready()) {
3358 Aggregate->addElement(Element);
3359 Element->setIsScopedAlready();
3360 }
3361}
3362
3363LVElement *LVLogicalVisitor::getElement(uint32_t StreamIdx, TypeIndex TI,
3364 LVScope *Parent) {
3365 LLVM_DEBUG({ printTypeIndex("TypeIndex", TI, StreamTPI); });
3366 TI = Shared->ForwardReferences.remap(TI);
3367 LLVM_DEBUG({ printTypeIndex("TypeIndex Remap", TI, StreamTPI); });
3368
3369 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3370 if (!Element) {
3371 if (TI.isNoneType() || TI.isSimple()) {
3372 StringRef TypeName = TypeIndex::simpleTypeName(TI);
3373 // If the name ends with "*", create 2 logical types: a pointer and a
3374 // pointee type. TypeIndex is composed of a SympleTypeMode byte followed
3375 // by a SimpleTypeKind byte. The logical pointer will be identified by
3376 // the full TypeIndex value and the pointee by the SimpleTypeKind.
3377 return (TypeName.back() == '*') ? createPointerType(TI, TypeName)
3378 : createBaseType(TI, TypeName);
3379 }
3380
3381 LLVM_DEBUG({ W.printHex("TypeIndex not implemented: ", TI.getIndex()); });
3382 return nullptr;
3383 }
3384
3385 // The element has been finalized.
3386 if (Element->getIsFinalized())
3387 return Element;
3388
3389 // Add the element in case of a given parent.
3390 if (Parent)
3391 Parent->addElement(Element);
3392
3393 // Check for a composite type.
3394 LazyRandomTypeCollection &Types = types();
3395 CVType CVRecord = Types.getType(Index: TI);
3396 if (Error Err = finishVisitation(Record&: CVRecord, TI, Element)) {
3397 consumeError(Err: std::move(Err));
3398 return nullptr;
3399 }
3400 Element->setIsFinalized();
3401 return Element;
3402}
3403
3404void LVLogicalVisitor::processLines() {
3405 // Traverse the collected LF_UDT_SRC_LINE records and add the source line
3406 // information to the logical elements.
3407 for (const TypeIndex &Entry : Shared->LineRecords) {
3408 CVType CVRecord = ids().getType(Index: Entry);
3409 UdtSourceLineRecord Line;
3410 if (Error Err = TypeDeserializer::deserializeAs(
3411 CVT&: const_cast<CVType &>(CVRecord), Record&: Line))
3412 consumeError(Err: std::move(Err));
3413 else {
3414 LLVM_DEBUG({
3415 printTypeIndex("UDT", Line.getUDT(), StreamIPI);
3416 printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);
3417 W.printNumber("LineNumber", Line.getLineNumber());
3418 });
3419
3420 // The TypeIndex returned by 'getUDT()' must point to an already
3421 // created logical element. If no logical element is found, it means
3422 // the LF_UDT_SRC_LINE is associated with a system TypeIndex.
3423 if (LVElement *Element = Shared->TypeRecords.find(
3424 StreamIdx: StreamTPI, TI: Line.getUDT(), /*Create=*/false)) {
3425 Element->setLineNumber(Line.getLineNumber());
3426 Element->setFilenameIndex(
3427 Shared->StringRecords.findIndex(TI: Line.getSourceFile()));
3428 }
3429 }
3430 }
3431}
3432
3433void LVLogicalVisitor::processNamespaces() {
3434 // Create namespaces.
3435 Shared->NamespaceDeduction.init();
3436}
3437
3438void LVLogicalVisitor::processFiles() { Shared->StringRecords.addFilenames(); }
3439
3440void LVLogicalVisitor::printRecords(raw_ostream &OS) const {
3441 if (!options().getInternalTag())
3442 return;
3443
3444 unsigned Count = 0;
3445 auto PrintItem = [&](StringRef Name) {
3446 auto NewLine = [&]() {
3447 if (++Count == 4) {
3448 Count = 0;
3449 OS << "\n";
3450 }
3451 };
3452 OS << formatv(Fmt: "{0,20}", Vals&: Name);
3453 NewLine();
3454 };
3455
3456 OS << "\nTypes:\n";
3457 for (const TypeLeafKind &Kind : Shared->TypeKinds)
3458 PrintItem(formatTypeLeafKind(K: Kind));
3459 Shared->TypeKinds.clear();
3460
3461 Count = 0;
3462 OS << "\nSymbols:\n";
3463 for (const SymbolKind &Kind : Shared->SymbolKinds)
3464 PrintItem(LVCodeViewReader::getSymbolKindName(Kind));
3465 Shared->SymbolKinds.clear();
3466
3467 OS << "\n";
3468}
3469
3470Error LVLogicalVisitor::inlineSiteAnnotation(LVScope *AbstractFunction,
3471 LVScope *InlinedFunction,
3472 InlineSiteSym &InlineSite) {
3473 // Get the parent scope to update the address ranges of the nested
3474 // scope representing the inlined function.
3475 LVAddress ParentLowPC = 0;
3476 LVScope *Parent = InlinedFunction->getParentScope();
3477 if (const LVLocations *Locations = Parent->getRanges()) {
3478 if (!Locations->empty())
3479 ParentLowPC = (*Locations->begin())->getLowerAddress();
3480 }
3481
3482 // For the given inlinesite, get the initial line number and its
3483 // source filename. Update the logical scope representing it.
3484 uint32_t LineNumber = 0;
3485 StringRef Filename;
3486 LVInlineeInfo::iterator Iter = InlineeInfo.find(x: InlineSite.Inlinee);
3487 if (Iter != InlineeInfo.end()) {
3488 LineNumber = Iter->second.first;
3489 Filename = Iter->second.second;
3490 AbstractFunction->setLineNumber(LineNumber);
3491 // TODO: This part needs additional work in order to set properly the
3492 // correct filename in order to detect changes between filenames.
3493 // AbstractFunction->setFilename(Filename);
3494 }
3495
3496 LLVM_DEBUG({
3497 dbgs() << "inlineSiteAnnotation\n"
3498 << "Abstract: " << AbstractFunction->getName() << "\n"
3499 << "Inlined: " << InlinedFunction->getName() << "\n"
3500 << "Parent: " << Parent->getName() << "\n"
3501 << "Low PC: " << hexValue(ParentLowPC) << "\n";
3502 });
3503
3504 // Get the source lines if requested by command line option.
3505 if (!options().getPrintLines())
3506 return Error::success();
3507
3508 // Limitation: Currently we don't track changes in the FileOffset. The
3509 // side effects are the caller that it is unable to differentiate the
3510 // source filename for the inlined code.
3511 uint64_t CodeOffset = ParentLowPC;
3512 int32_t LineOffset = LineNumber;
3513 uint32_t FileOffset = 0;
3514
3515 auto UpdateClose = [&]() { LLVM_DEBUG({ dbgs() << ("\n"); }); };
3516 auto UpdateCodeOffset = [&](uint32_t Delta) {
3517 CodeOffset += Delta;
3518 LLVM_DEBUG({
3519 dbgs() << formatv(" code 0x{0} (+0x{1})", utohexstr(CodeOffset),
3520 utohexstr(Delta));
3521 });
3522 };
3523 auto UpdateLineOffset = [&](int32_t Delta) {
3524 LineOffset += Delta;
3525 LLVM_DEBUG({
3526 char Sign = Delta > 0 ? '+' : '-';
3527 dbgs() << formatv(" line {0} ({1}{2})", LineOffset, Sign,
3528 std::abs(Delta));
3529 });
3530 };
3531 auto UpdateFileOffset = [&](int32_t Offset) {
3532 FileOffset = Offset;
3533 LLVM_DEBUG({ dbgs() << formatv(" file {0}", FileOffset); });
3534 };
3535
3536 LVLines InlineeLines;
3537 auto CreateLine = [&]() {
3538 // Create the logical line record.
3539 LVLineDebug *Line = Reader->createLineDebug();
3540 Line->setAddress(CodeOffset);
3541 Line->setLineNumber(LineOffset);
3542 // TODO: This part needs additional work in order to set properly the
3543 // correct filename in order to detect changes between filenames.
3544 // Line->setFilename(Filename);
3545 InlineeLines.push_back(Elt: Line);
3546 };
3547
3548 bool SeenLowAddress = false;
3549 bool SeenHighAddress = false;
3550 uint64_t LowPC = 0;
3551 uint64_t HighPC = 0;
3552
3553 for (auto &Annot : InlineSite.annotations()) {
3554 LLVM_DEBUG({
3555 dbgs() << formatv(" {0}",
3556 fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));
3557 });
3558
3559 // Use the opcode to interpret the integer values.
3560 switch (Annot.OpCode) {
3561 case BinaryAnnotationsOpCode::ChangeCodeOffset:
3562 case BinaryAnnotationsOpCode::CodeOffset:
3563 case BinaryAnnotationsOpCode::ChangeCodeLength:
3564 UpdateCodeOffset(Annot.U1);
3565 UpdateClose();
3566 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {
3567 CreateLine();
3568 LowPC = CodeOffset;
3569 SeenLowAddress = true;
3570 break;
3571 }
3572 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {
3573 HighPC = CodeOffset - 1;
3574 SeenHighAddress = true;
3575 }
3576 break;
3577 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
3578 UpdateCodeOffset(Annot.U2);
3579 UpdateClose();
3580 break;
3581 case BinaryAnnotationsOpCode::ChangeLineOffset:
3582 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
3583 UpdateCodeOffset(Annot.U1);
3584 UpdateLineOffset(Annot.S1);
3585 UpdateClose();
3586 if (Annot.OpCode ==
3587 BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)
3588 CreateLine();
3589 break;
3590 case BinaryAnnotationsOpCode::ChangeFile:
3591 UpdateFileOffset(Annot.U1);
3592 UpdateClose();
3593 break;
3594 default:
3595 break;
3596 }
3597 if (SeenLowAddress && SeenHighAddress) {
3598 SeenLowAddress = false;
3599 SeenHighAddress = false;
3600 InlinedFunction->addObject(LowerAddress: LowPC, UpperAddress: HighPC);
3601 }
3602 }
3603
3604 Reader->addInlineeLines(Scope: InlinedFunction, Lines&: InlineeLines);
3605 UpdateClose();
3606
3607 return Error::success();
3608}
3609