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