40#define DEBUG_TYPE "CodeViewUtilities"
43namespace logicalview {
74#define CV_TYPE(enum, val) {#enum, enum},
75#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
86 auto GetName = [&](
auto Record) {
95 if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
97 else if (RK == TypeRecordKind::Union)
99 else if (RK == TypeRecordKind::Enum)
109#define DEBUG_TYPE "CodeViewDataVisitor"
112namespace logicalview {
123 using RecordEntry = std::pair<TypeLeafKind, LVElement *>;
124 using RecordTable = std::map<TypeIndex, RecordEntry>;
125 RecordTable RecordFromTypes;
126 RecordTable RecordFromIds;
128 using NameTable = std::map<StringRef, TypeIndex>;
129 NameTable NameFromTypes;
130 NameTable NameFromIds;
133 LVTypeRecords(
LVShared *Shared) : Shared(Shared) {}
142class LVForwardReferences {
144 using ForwardEntry = std::pair<TypeIndex, TypeIndex>;
145 using ForwardTypeNames = std::map<StringRef, ForwardEntry>;
146 ForwardTypeNames ForwardTypesNames;
149 using ForwardType = std::map<TypeIndex, TypeIndex>;
150 ForwardType ForwardTypes;
154 ForwardTypes.emplace(TIForward, TIReference);
158 if (ForwardTypesNames.find(
Name) == ForwardTypesNames.end()) {
159 ForwardTypesNames.emplace(
160 std::piecewise_construct, std::forward_as_tuple(
Name),
164 ForwardTypesNames[
Name].first = TIForward;
165 add(TIForward, ForwardTypesNames[
Name].second);
171 auto It = ForwardTypesNames.find(
Name);
172 if (It != ForwardTypesNames.end()) {
174 It->second.second = TIReference;
175 add(It->second.first, TIReference);
178 ForwardTypesNames.emplace(
179 std::piecewise_construct, std::forward_as_tuple(
Name),
185 LVForwardReferences() =
default;
191 (IsForwardRef) ? add(
Name, TI) : update(
Name, TI);
195 auto It = ForwardTypes.find(TIForward);
200 auto It = ForwardTypesNames.find(
Name);
201 return It != ForwardTypesNames.end() ? It->second.second
214class LVNamespaceDeduction {
217 using Names = std::map<StringRef, LVScope *>;
218 Names NamespaceNames;
220 using LookupSet = std::set<StringRef>;
221 LookupSet DeducedScopes;
222 LookupSet UnresolvedScopes;
223 LookupSet IdentifiedNamespaces;
226 if (NamespaceNames.find(
Name) == NamespaceNames.end())
227 NamespaceNames.emplace(
Name, Namespace);
231 LVNamespaceDeduction(
LVShared *Shared) : Shared(Shared) {}
240 auto It = NamespaceNames.find(
Name);
241 LVScope *Namespace = It != NamespaceNames.end() ? It->second :
nullptr;
249 if (Components.empty())
252 LVStringRefs::size_type FirstNamespace = 0;
253 LVStringRefs::size_type FirstNonNamespace;
254 for (LVStringRefs::size_type Index = 0; Index < Components.size();
256 FirstNonNamespace = Index;
257 LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);
258 if (Iter == IdentifiedNamespaces.end())
262 return std::make_tuple(FirstNamespace, FirstNonNamespace);
267class LVStringRecords {
268 using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
269 using StringIds = std::map<TypeIndex, StringEntry>;
273 LVStringRecords() =
default;
277 if (Strings.find(TI) == Strings.end())
279 std::piecewise_construct, std::forward_as_tuple(TI),
280 std::forward_as_tuple(++Index, std::string(
String),
nullptr));
284 StringIds::iterator Iter = Strings.find(TI);
285 return Iter != Strings.end() ? std::get<1>(Iter->second) :
StringRef{};
289 StringIds::iterator Iter = Strings.find(TI);
290 return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;
333 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
334 Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
335 std::forward_as_tuple(
Kind, Element));
339 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
345 (StreamIdx ==
StreamTPI) ? RecordFromTypes : RecordFromIds;
348 RecordTable::iterator Iter =
Target.find(TI);
349 if (Iter !=
Target.end()) {
350 Element = Iter->second.second;
351 if (Element || !Create)
358 Element->setOffsetFromTypeIndex();
359 Target[TI].second = Element;
366 NameTable &
Target = (StreamIdx ==
StreamTPI) ? NameFromTypes : NameFromIds;
371void LVStringRecords::addFilenames() {
372 for (StringIds::const_reference Entry : Strings) {
381 for (StringIds::reference Entry : Strings)
382 if (!std::get<2>(
Entry.second))
390 DeducedScopes.insert(InnerComponent);
391 if (OuterComponent.
size())
392 UnresolvedScopes.insert(OuterComponent);
395void LVNamespaceDeduction::init() {
402 for (
const StringRef &Unresolved : UnresolvedScopes) {
404 for (
const StringRef &Component : Components) {
405 LookupSet::iterator Iter = DeducedScopes.find(Component);
406 if (Iter == DeducedScopes.end())
407 IdentifiedNamespaces.insert(Component);
412 auto Print = [&](LookupSet &Container,
const char *Title) {
413 auto Header = [&]() {
423 Print(DeducedScopes,
"Deducted Scopes");
424 Print(UnresolvedScopes,
"Unresolved Scopes");
425 Print(IdentifiedNamespaces,
"Namespaces");
431 for (
const StringRef &Component : Components)
435 if (Components.empty())
441 for (
const StringRef &Component : Components) {
443 Namespace =
find(Component);
447 Namespace = Shared->
Reader->createScopeNamespace();
448 Namespace->
setTag(dwarf::DW_TAG_namespace);
452 add(Component, Namespace);
463 LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
464 return Iter == IdentifiedNamespaces.end();
468 {
dbgs() <<
formatv(
"ScopedName: '{0}'\n", ScopedName.
str().c_str()); });
470 return get(Components);
474#define DEBUG_TYPE "CodeViewTypeVisitor"
495 if (
options().getInternalTag())
500 CurrentTypeIndex = TI;
539 printTypeIndex(
"ArgType", Arg,
StreamIPI);
549 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];
555 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
567 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
585 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
586 printTypeIndex(
"FieldListType",
Enum.getFieldList(),
StreamTPI);
598 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
599 printTypeIndex(
"Type", Func.getFunctionType(),
StreamTPI);
600 printTypeIndex(
"Parent", Func.getParentScope(),
StreamTPI);
612 printTypeIndex(
"TypeIndex", CurrentTypeIndex,
StreamTPI);
639 printTypeIndex(
"SourceFile",
Line.getSourceFile(),
StreamIPI);
669#define DEBUG_TYPE "CodeViewSymbolVisitor"
678 Reader->printRelocatedField(
Label, CoffSection, RelocOffset,
Offset,
699 return Reader->CVStringTable;
702void LVSymbolVisitor::printLocalVariableAddrRange(
704 DictScope S(W,
"LocalVariableAddrRange");
712void LVSymbolVisitor::printLocalVariableAddrGap(
716 W.
printHex(
"GapStartOffset", Gap.GapStartOffset);
736 if (
options().getInternalTag())
750 IsCompileUnit =
false;
798 if (
options().getGeneralCollectRanges()) {
804 Scope->addObject(LowPC, HighPC);
815 printTypeIndex(
"Type",
Local.Type);
821 Symbol->setName(
Local.Name);
829 Symbol->resetIsVariable();
831 if (
Local.Name ==
"this") {
832 Symbol->setIsParameter();
833 Symbol->setIsArtificial();
836 bool(
Local.Offset > 0) ? Symbol->setIsParameter()
837 : Symbol->setIsVariable();
841 if (Symbol->getIsParameter())
842 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
845 if (Element && Element->getIsScoped()) {
847 LVScope *Parent = Symbol->getFunctionParent();
860 Symbol->setType(Element);
870 printTypeIndex(
"Type",
Local.Type);
876 Symbol->setName(
Local.Name);
879 Symbol->resetIsVariable();
882 if (
Local.Name ==
"this") {
883 Symbol->setIsArtificial();
884 Symbol->setIsParameter();
887 determineSymbolKind(Symbol,
Local.Register);
891 if (Symbol->getIsParameter())
892 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
895 if (Element && Element->getIsScoped()) {
897 LVScope *Parent = Symbol->getFunctionParent();
910 Symbol->setType(Element);
956 Scope->setName(CurrentObjectName);
957 if (
options().getAttributeProducer())
958 Scope->setProducer(Compile2.
Version);
970 CurrentObjectName =
"";
1001 Scope->setName(CurrentObjectName);
1002 if (
options().getAttributeProducer())
1003 Scope->setProducer(Compile3.
Version);
1015 CurrentObjectName =
"";
1023 printTypeIndex(
"Type",
Constant.Type);
1031 Symbol->resetIncludeInPrint();
1049 if (
LVSymbol *Symbol = LocalSymbol) {
1050 Symbol->setHasCodeViewLocation();
1051 LocalSymbol =
nullptr;
1058 Symbol->addLocation(Attr, 0, 0, 0, 0);
1059 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1074 printLocalVariableAddrRange(DefRangeFramePointerRel.
Range,
1076 printLocalVariableAddrGap(DefRangeFramePointerRel.
Gaps);
1083 if (
LVSymbol *Symbol = LocalSymbol) {
1084 Symbol->setHasCodeViewLocation();
1085 LocalSymbol =
nullptr;
1097 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1116 printLocalVariableAddrRange(DefRangeRegisterRel.
Range,
1118 printLocalVariableAddrGap(DefRangeRegisterRel.
Gaps);
1121 if (
LVSymbol *Symbol = LocalSymbol) {
1122 Symbol->setHasCodeViewLocation();
1123 LocalSymbol =
nullptr;
1136 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, Operand2});
1153 printLocalVariableAddrRange(DefRangeRegister.
Range,
1155 printLocalVariableAddrGap(DefRangeRegister.
Gaps);
1158 if (
LVSymbol *Symbol = LocalSymbol) {
1159 Symbol->setHasCodeViewLocation();
1160 LocalSymbol =
nullptr;
1171 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1190 printLocalVariableAddrRange(DefRangeSubfieldRegister.
Range,
1192 printLocalVariableAddrGap(DefRangeSubfieldRegister.
Gaps);
1195 if (
LVSymbol *Symbol = LocalSymbol) {
1196 Symbol->setHasCodeViewLocation();
1197 LocalSymbol =
nullptr;
1209 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1});
1225 auto ExpectedProgram = Strings.getString(DefRangeSubfield.
Program);
1226 if (!ExpectedProgram) {
1228 return llvm::make_error<CodeViewError>(
1229 "String table offset outside of bounds of String Table!");
1234 printLocalVariableAddrRange(DefRangeSubfield.
Range,
1236 printLocalVariableAddrGap(DefRangeSubfield.
Gaps);
1239 if (
LVSymbol *Symbol = LocalSymbol) {
1240 Symbol->setHasCodeViewLocation();
1241 LocalSymbol =
nullptr;
1252 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1268 auto ExpectedProgram = Strings.getString(DefRange.
Program);
1269 if (!ExpectedProgram) {
1271 return llvm::make_error<CodeViewError>(
1272 "String table offset outside of bounds of String Table!");
1277 printLocalVariableAddrGap(DefRange.
Gaps);
1280 if (
LVSymbol *Symbol = LocalSymbol) {
1281 Symbol->setHasCodeViewLocation();
1282 LocalSymbol =
nullptr;
1293 Symbol->addLocationOperands(
LVSmall(Attr), {Operand1, 0});
1313 if (FrameProcedureOptions::MarkedInline ==
1314 (Flags & FrameProcedureOptions::MarkedInline))
1316 if (FrameProcedureOptions::Inlined ==
1317 (Flags & FrameProcedureOptions::Inlined))
1335 printTypeIndex(
"Type",
Data.Type);
1345 Symbol->setName(
Data.Name);
1355 Symbol->resetIncludeInPrint();
1362 if (Symbol->getParentScope()->removeElement(Symbol))
1367 if (
Record.kind() == SymbolKind::S_GDATA32)
1368 Symbol->setIsExternal();
1380 LVScope *AbstractFunction = Reader->createScopeFunction();
1381 AbstractFunction->setIsSubprogram();
1382 AbstractFunction->
setTag(dwarf::DW_TAG_subprogram);
1384 AbstractFunction->setIsInlinedAbstract();
1391 CVFunctionType,
InlineSite.Inlinee, AbstractFunction))
1398 InlinedFunction->setName(
Name);
1399 InlinedFunction->setLinkageName(
Name);
1403 AbstractFunction, InlinedFunction,
InlineSite))
1413 printTypeIndex(
"Type",
Local.Type);
1419 Symbol->setName(
Local.Name);
1422 Symbol->resetIsVariable();
1425 if (
bool(
Local.Flags & LocalSymFlags::IsCompilerGenerated) ||
1426 Local.Name ==
"this") {
1427 Symbol->setIsArtificial();
1428 Symbol->setIsParameter();
1430 bool(
Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()
1431 : Symbol->setIsVariable();
1435 if (Symbol->getIsParameter())
1436 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1439 if (Element && Element->getIsScoped()) {
1441 LVScope *Parent = Symbol->getFunctionParent();
1448 Symbol->setType(Element);
1453 LocalSymbol = Symbol;
1466 CurrentObjectName = ObjName.
Name;
1472 if (InFunctionScope)
1473 return llvm::make_error<CodeViewError>(
"Visiting a ProcSym while inside "
1476 InFunctionScope =
true;
1532 if (
options().getGeneralCollectRanges()) {
1538 Function->addObject(LowPC, HighPC);
1541 if ((
options().getAttributePublics() ||
options().getPrintAnyLine()) &&
1566 std::optional<CVType> CVFunctionType;
1567 auto GetRecordType = [&]() ->
bool {
1568 CVFunctionType = Ids.
tryGetType(TIFunctionType);
1569 if (!CVFunctionType)
1574 if (CVFunctionType->kind() == LF_FUNC_ID)
1578 return (CVFunctionType->kind() == LF_MFUNC_ID);
1582 if (!GetRecordType()) {
1583 CVFunctionType = Types.
tryGetType(TIFunctionType);
1584 if (!CVFunctionType)
1585 return llvm::make_error<CodeViewError>(
"Invalid type index");
1589 *CVFunctionType, TIFunctionType,
Function))
1593 if (
Record.kind() == SymbolKind::S_GPROC32 ||
1594 Record.kind() == SymbolKind::S_GPROC32_ID)
1600 if (DemangledSymbol.find(
"scalar deleting dtor") != std::string::npos) {
1605 if (DemangledSymbol.find(
"dynamic atexit destructor for") !=
1617 InFunctionScope =
false;
1623 if (InFunctionScope)
1624 return llvm::make_error<CodeViewError>(
"Visiting a Thunk32Sym while inside "
1627 InFunctionScope =
true;
1643 printTypeIndex(
"Type",
UDT.Type);
1649 if (
Type->getParentScope()->removeElement(
Type))
1663 Type->resetIncludeInPrint();
1666 if (
UDT.Name == RecordName)
1667 Type->resetIncludeInPrint();
1686 W.
printHex(
"BaseOffset", JumpTable.BaseOffset);
1687 W.
printNumber(
"BaseSegment", JumpTable.BaseSegment);
1690 W.
printHex(
"BranchOffset", JumpTable.BranchOffset);
1691 W.
printHex(
"TableOffset", JumpTable.TableOffset);
1692 W.
printNumber(
"BranchSegment", JumpTable.BranchSegment);
1693 W.
printNumber(
"TableSegment", JumpTable.TableSegment);
1694 W.
printNumber(
"EntriesCount", JumpTable.EntriesCount);
1703 switch (
Caller.getKind()) {
1704 case SymbolRecordKind::CallerSym:
1705 FieldName =
"Callee";
1707 case SymbolRecordKind::CalleeSym:
1708 FieldName =
"Caller";
1710 case SymbolRecordKind::InlineesSym:
1711 FieldName =
"Inlinee";
1714 return llvm::make_error<CodeViewError>(
1715 "Unknown CV Record type for a CallerSym object!");
1718 printTypeIndex(FieldName, FuncID);
1725#define DEBUG_TYPE "CodeViewLogicalVisitor"
1732 : Reader(Reader), W(W), Input(Input) {
1735 Shared = std::make_shared<LVShared>(Reader,
this);
1741 StreamIdx ==
StreamTPI ? types() : ids());
1754 << Element->
getName() <<
"\n";
1773 << Element->
getName() <<
"\n";
1805 TypeIndex ParameterType = Indices[Index];
1824 if (Element->getIsFinalized())
1826 Element->setIsFinalized();
1835 LVType *PrevSubrange =
nullptr;
1843 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1853 if (int64_t Count =
Subrange->getCount())
1868 while (CVEntry.
kind() == LF_ARRAY) {
1879 AddSubrangeType(AR);
1880 TIArrayType = TIElementType;
1886 CVType CVElementType =
Types.getType(TIElementType);
1887 if (CVElementType.
kind() == LF_MODIFIER) {
1889 Shared->TypeRecords.find(
StreamTPI, TIElementType);
1902 CVEntry =
Types.getType(TIElementType);
1904 const_cast<CVType &
>(CVEntry), AR)) {
1914 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
1960 TypeIndex TIName = BI.
getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
1981 if (
Class.hasUniqueName())
1986 if (Element->getIsFinalized())
1988 Element->setIsFinalized();
1994 Scope->setName(
Class.getName());
1995 if (
Class.hasUniqueName())
1996 Scope->setLinkageName(
Class.getUniqueName());
1998 if (
Class.isNested()) {
1999 Scope->setIsNested();
2000 createParents(
Class.getName(), Scope);
2003 if (
Class.isScoped())
2004 Scope->setIsScoped();
2008 if (!(
Class.isNested() ||
Class.isScoped())) {
2009 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Class.getName()))
2018 TypeIndex ForwardType = Shared->ForwardReferences.find(
Class.getName());
2024 const_cast<CVType &
>(CVReference), ReferenceRecord))
2056 if (Scope->getIsFinalized())
2058 Scope->setIsFinalized();
2062 Scope->setName(
Enum.getName());
2063 if (
Enum.hasUniqueName())
2064 Scope->setLinkageName(
Enum.getUniqueName());
2068 if (
Enum.isNested()) {
2069 Scope->setIsNested();
2070 createParents(
Enum.getName(), Scope);
2073 if (
Enum.isScoped()) {
2074 Scope->setIsScoped();
2075 Scope->setIsEnumClass();
2079 if (!(
Enum.isNested() ||
Enum.isScoped())) {
2080 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Enum.getName()))
2106 if (
Error Err = visitFieldListMemberStream(TI, Element,
FieldList.Data))
2132 TypeIndex TIParent = Func.getParentScope();
2133 if (FunctionDcl->getIsInlinedAbstract()) {
2134 FunctionDcl->setName(Func.getName());
2145 TypeIndex TIFunctionType = Func.getFunctionType();
2146 CVType CVFunctionType =
Types.getType(TIFunctionType);
2151 FunctionDcl->setIsFinalized();
2180 if (FunctionDcl->getIsInlinedAbstract()) {
2186 Shared->TypeRecords.find(
StreamTPI, Id.getClassType())))
2187 Class->addElement(FunctionDcl);
2190 TypeIndex TIFunctionType = Id.getFunctionType();
2216 MemberFunction->setIsFinalized();
2218 MemberFunction->setOffset(TI.
getIndex());
2219 MemberFunction->setOffsetFromTypeIndex();
2221 if (ProcessArgumentList) {
2222 ProcessArgumentList =
false;
2224 if (!MemberFunction->getIsStatic()) {
2229 createParameter(ThisPointer,
StringRef(), MemberFunction);
2230 This->setIsArtificial();
2257 Method.
Name = OverloadedMethodName;
2289 bool SeenModifier =
false;
2291 if (Mods &
uint16_t(ModifierOptions::Const)) {
2292 SeenModifier =
true;
2293 LastLink->
setTag(dwarf::DW_TAG_const_type);
2294 LastLink->setIsConst();
2297 if (Mods &
uint16_t(ModifierOptions::Volatile)) {
2305 LastLink->
setTag(dwarf::DW_TAG_volatile_type);
2306 LastLink->setIsVolatile();
2307 LastLink->
setName(
"volatile");
2309 if (Mods &
uint16_t(ModifierOptions::Unaligned)) {
2318 LastLink->setIsUnaligned();
2319 LastLink->
setName(
"unaligned");
2322 LastLink->
setType(ModifiedType);
2341 if (
Ptr.isPointerToMember()) {
2353 Pointee =
Ptr.isPointerToMember()
2354 ? Shared->TypeRecords.find(
StreamTPI,
Ptr.getReferentType())
2364 bool SeenModifier =
false;
2369 if (
Ptr.isRestrict()) {
2370 SeenModifier =
true;
2372 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2379 if (Mode == PointerMode::LValueReference) {
2381 LVType *LReference = Reader->createType();
2382 LReference->setIsModifier();
2383 LastLink->
setType(LReference);
2384 LastLink = LReference;
2387 LastLink->
setTag(dwarf::DW_TAG_reference_type);
2388 LastLink->setIsReference();
2391 if (Mode == PointerMode::RValueReference) {
2393 LVType *RReference = Reader->createType();
2394 RReference->setIsModifier();
2395 LastLink->
setType(RReference);
2396 LastLink = RReference;
2399 LastLink->
setTag(dwarf::DW_TAG_rvalue_reference_type);
2400 LastLink->setIsRvalueReference();
2426 if (ProcessArgumentList) {
2427 ProcessArgumentList =
false;
2449 if (
Union.hasUniqueName())
2458 if (Scope->getIsFinalized())
2460 Scope->setIsFinalized();
2462 Scope->setName(
Union.getName());
2463 if (
Union.hasUniqueName())
2464 Scope->setLinkageName(
Union.getUniqueName());
2466 if (
Union.isNested()) {
2467 Scope->setIsNested();
2468 createParents(
Union.getName(), Scope);
2470 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
Union.getName()))
2476 if (!
Union.getFieldList().isNoneType()) {
2556 if (
LVScope *Namespace = Shared->NamespaceDeduction.get(
2557 String.getString(),
false)) {
2561 Scope->removeElement(Element);
2647 Symbol->setAccessibilityCode(
Base.getAccess());
2687 Enum.getValue().toString(
Value, 16,
true,
true);
2725 if (NestedType && NestedType->getIsNested()) {
2731 if (NestedTypeName.
size() && RecordName.
size()) {
2733 std::tie(OuterComponent, std::ignore) =
2737 if (OuterComponent.
size() && OuterComponent == RecordName) {
2738 if (!NestedType->getIsScopedAlready()) {
2739 Scope->addElement(NestedType);
2740 NestedType->setIsScopedAlready();
2743 Typedef->resetIncludeInPrint();
2769 ProcessArgumentList =
true;
2771 MemberFunction->setIsFinalized();
2774 MemberFunction->setName(Method.
getName());
2775 MemberFunction->setAccessibilityCode(Method.
getAccess());
2778 if (
Kind == MethodKind::Static)
2779 MemberFunction->setIsStatic();
2780 MemberFunction->setVirtualityCode(
Kind);
2783 if (MethodOptions::CompilerGenerated ==
2784 (Flags & MethodOptions::CompilerGenerated))
2785 MemberFunction->setIsArtificial();
2793 ProcessArgumentList =
false;
2813 OverloadedMethodName = Method.
getName();
2868 Symbol->setAccessibilityCode(
Base.getAccess());
2869 Symbol->setVirtualityCode(MethodKind::Virtual);
2887#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2890 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2894#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2895 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2896#define TYPE_RECORD(EnumName, EnumVal, Name)
2897#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2898#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2914#define TYPE_RECORD(EnumName, EnumVal, Name) \
2916 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2920#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2921 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2922#define MEMBER_RECORD(EnumName, EnumVal, Name)
2923#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2924#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2931Error LVLogicalVisitor::visitFieldListMemberStream(
2940 while (!Reader.empty()) {
2941 if (
Error Err = Reader.readEnum(Leaf))
2959 if (!ScopeStack.empty())
2961 InCompileUnitScope =
true;
2985 if (
options().getAttributeBase())
2992 case TypeLeafKind::LF_ENUMERATE:
2996 case TypeLeafKind::LF_MODIFIER:
3000 case TypeLeafKind::LF_POINTER:
3008 case TypeLeafKind::LF_BCLASS:
3009 case TypeLeafKind::LF_IVBCLASS:
3010 case TypeLeafKind::LF_VBCLASS:
3015 case TypeLeafKind::LF_MEMBER:
3016 case TypeLeafKind::LF_STMEMBER:
3023 case TypeLeafKind::LF_ARRAY:
3027 case TypeLeafKind::LF_CLASS:
3032 case TypeLeafKind::LF_ENUM:
3036 case TypeLeafKind::LF_METHOD:
3037 case TypeLeafKind::LF_ONEMETHOD:
3038 case TypeLeafKind::LF_PROCEDURE:
3043 case TypeLeafKind::LF_STRUCTURE:
3048 case TypeLeafKind::LF_UNION:
3067 case SymbolKind::S_UDT:
3073 case SymbolKind::S_CONSTANT:
3079 case SymbolKind::S_BPREL32:
3080 case SymbolKind::S_REGREL32:
3081 case SymbolKind::S_GDATA32:
3082 case SymbolKind::S_LDATA32:
3083 case SymbolKind::S_LOCAL:
3093 case SymbolKind::S_BLOCK32:
3098 case SymbolKind::S_COMPILE2:
3099 case SymbolKind::S_COMPILE3:
3104 case SymbolKind::S_INLINESITE:
3105 case SymbolKind::S_INLINESITE2:
3110 case SymbolKind::S_LPROC32:
3111 case SymbolKind::S_GPROC32:
3112 case SymbolKind::S_LPROC32_ID:
3113 case SymbolKind::S_GPROC32_ID:
3114 case SymbolKind::S_SEPCODE:
3115 case SymbolKind::S_THUNK32:
3135 Element->setIsFinalized();
3145 Element->setOffsetFromTypeIndex();
3156 Element->setOffsetFromTypeIndex();
3170 Symbol->setName(
Name);
3176 if (CVMemberType.
kind() == LF_BITFIELD) {
3191 LVSymbol *Parameter = Reader->createSymbol();
3193 Parameter->setIsParameter();
3194 Parameter->
setTag(dwarf::DW_TAG_formal_parameter);
3214 return static_cast<LVType *
>(Element);
3230 return static_cast<LVType *
>(Element);
3261 if (Components.size() < 2)
3263 Components.pop_back();
3265 LVStringRefs::size_type FirstNamespace;
3266 LVStringRefs::size_type FirstAggregate;
3267 std::tie(FirstNamespace, FirstAggregate) =
3268 Shared->NamespaceDeduction.find(Components);
3271 W.
printString(
"First Namespace", Components[FirstNamespace]);
3272 W.
printString(
"First NonNamespace", Components[FirstAggregate]);
3276 if (FirstNamespace < FirstAggregate) {
3277 Shared->NamespaceDeduction.get(
3279 Components.begin() + FirstAggregate));
3288 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3291 for (LVStringRefs::size_type Index = FirstAggregate;
3294 Components.begin() + Index + 1),
3296 TIAggregate = Shared->ForwardReferences.remap(
3297 Shared->TypeRecords.find(
StreamTPI, AggregateName));
3307 if (Aggregate && !Element->getIsScopedAlready()) {
3309 Element->setIsScopedAlready();
3316 TI = Shared->ForwardReferences.remap(TI);
3319 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3327 return (TypeName.back() ==
'*') ? createPointerType(TI, TypeName)
3328 : createBaseType(TI, TypeName);
3336 if (Element->getIsFinalized())
3350 Element->setIsFinalized();
3357 for (
const TypeIndex &Entry : Shared->LineRecords) {
3373 if (
LVElement *Element = Shared->TypeRecords.find(
3377 Shared->StringRecords.findIndex(
Line.getSourceFile()));
3385 Shared->NamespaceDeduction.init();
3391 if (!
options().getInternalTag())
3396 auto NewLine = [&]() {
3409 Shared->TypeKinds.clear();
3412 OS <<
"\nSymbols:\n";
3415 Shared->SymbolKinds.clear();
3429 ParentLowPC = (*
Locations->begin())->getLowerAddress();
3436 LVInlineeInfo::iterator Iter = InlineeInfo.find(
InlineSite.Inlinee);
3437 if (Iter != InlineeInfo.end()) {
3438 LineNumber = Iter->second.first;
3447 dbgs() <<
"inlineSiteAnnotation\n"
3448 <<
"Abstract: " << AbstractFunction->
getName() <<
"\n"
3449 <<
"Inlined: " << InlinedFunction->
getName() <<
"\n"
3450 <<
"Parent: " << Parent->
getName() <<
"\n"
3451 <<
"Low PC: " <<
hexValue(ParentLowPC) <<
"\n";
3455 if (!
options().getPrintLines())
3462 int32_t LineOffset = LineNumber;
3466 auto UpdateCodeOffset = [&](
uint32_t Delta) {
3473 auto UpdateLineOffset = [&](int32_t Delta) {
3474 LineOffset += Delta;
3476 char Sign = Delta > 0 ?
'+' :
'-';
3477 dbgs() <<
formatv(
" line {0} ({1}{2})", LineOffset, Sign,
3481 auto UpdateFileOffset = [&](int32_t
Offset) {
3487 auto CreateLine = [&]() {
3491 Line->setLineNumber(LineOffset);
3498 bool SeenLowAddress =
false;
3499 bool SeenHighAddress =
false;
3503 for (
auto &Annot :
InlineSite.annotations()) {
3510 switch (Annot.OpCode) {
3511 case BinaryAnnotationsOpCode::ChangeCodeOffset:
3512 case BinaryAnnotationsOpCode::CodeOffset:
3513 case BinaryAnnotationsOpCode::ChangeCodeLength:
3514 UpdateCodeOffset(Annot.U1);
3516 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {
3519 SeenLowAddress =
true;
3522 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {
3524 SeenHighAddress =
true;
3527 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
3528 UpdateCodeOffset(Annot.U2);
3531 case BinaryAnnotationsOpCode::ChangeLineOffset:
3532 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
3533 UpdateCodeOffset(Annot.U1);
3534 UpdateLineOffset(Annot.S1);
3537 BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)
3540 case BinaryAnnotationsOpCode::ChangeFile:
3541 UpdateFileOffset(Annot.U1);
3547 if (SeenLowAddress && SeenHighAddress) {
3548 SeenLowAddress =
false;
3549 SeenHighAddress =
false;
3550 InlinedFunction->
addObject(LowPC, HighPC);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
AMDGPU Lower Kernel Arguments
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
This is an important base class in LLVM.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringRef getName() const
virtual void printString(StringRef Value)
void indent(int Levels=1)
void unindent(int Levels=1)
void printEnum(StringRef Label, T Value, ArrayRef< EnumEntry< TEnum > > EnumValues)
virtual raw_ostream & getOStream()
virtual raw_ostream & startLine()
virtual void printNumber(StringRef Label, char Value)
void printHex(StringRef Label, T Value)
void printFlags(StringRef Label, T Value, ArrayRef< EnumEntry< TFlag > > Flags, TFlag EnumMask1={}, TFlag EnumMask2={}, TFlag EnumMask3={}, ArrayRef< FlagEntry > ExtraFlags={})
virtual void printBoolean(StringRef Label, bool Value)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr size_t size() const
size - Get the string size.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Value(Type *Ty, unsigned scid)
void setName(const Twine &Name)
Change the name of the value.
TypeIndex getElementType() const
TypeIndex getIndexType() const
StringRef getName() const
uint8_t getBitSize() const
TypeIndex getType() const
uint8_t getBitOffset() const
ArrayRef< TypeIndex > getArgs() const
uint8_t getLanguage() const
uint32_t getFlags() const
CompileSym3Flags getFlags() const
SourceLanguage getLanguage() const
Represents a read-only view of a CodeView string table.
DefRangeFramePointerRelHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeRegisterRelHeader Hdr
bool hasSpilledUDTMember() const
uint32_t getRelocationOffset() const
uint16_t offsetInParent() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
DefRangeRegisterHeader Hdr
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
LocalVariableAddrRange Range
uint32_t getRelocationOffset() const
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
LocalVariableAddrRange Range
uint32_t getSignature() const
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
FrameProcedureOptions Flags
Provides amortized O(1) random access to a CodeView type stream.
std::optional< CVType > tryGetType(TypeIndex Index)
CVType getType(TypeIndex Index) override
StringRef getTypeName(TypeIndex Index) override
LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records together.
TypeIndex getContinuationIndex() const
TypeIndex getReturnType() const
int32_t getThisPointerAdjustment() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getThisType() const
TypeIndex getClassType() const
std::vector< OneMethodRecord > Methods
int32_t getVFTableOffset() const
TypeIndex getType() const
bool isIntroducingVirtual() const
MemberAccess getAccess() const
MethodKind getMethodKind() const
StringRef getName() const
For method overload sets. LF_METHOD.
StringRef getName() const
uint16_t getNumOverloads() const
TypeIndex getMethodList() const
uint32_t getSignature() const
StringRef getPrecompFilePath() const
uint32_t getTypesCount() const
uint32_t getStartTypeIndex() const
uint32_t getRelocationOffset() const
TypeIndex getReturnType() const
TypeIndex getArgumentList() const
uint16_t getParameterCount() const
TypeIndex getFieldList() const
static Error deserializeAs(CVType &CVT, T &Record)
static TypeIndex fromArrayIndex(uint32_t Index)
SimpleTypeKind getSimpleKind() const
void setIndex(uint32_t I)
static const uint32_t FirstNonSimpleIndex
static StringRef simpleTypeName(TypeIndex TI)
uint32_t getIndex() const
StringRef getName() const
const GUID & getGuid() const
void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks)
virtual Error visitUnknownMember(CVMemberRecord &Record)
virtual Error visitMemberEnd(CVMemberRecord &Record)
virtual Error visitMemberBegin(CVMemberRecord &Record)
TypeIndex getSourceFile() const
uint16_t getModule() const
uint32_t getLineNumber() const
uint32_t getLineNumber() const
TypeIndex getSourceFile() const
TypeIndex getType() const
uint32_t getVFPtrOffset() const
TypeIndex getOverriddenVTable() const
ArrayRef< StringRef > getMethodNames() const
StringRef getName() const
TypeIndex getCompleteClass() const
uint32_t getEntryCount() const
Stores all information relating to a compile unit, be it in its original instance in the object file ...
void addInlineeLines(LVScope *Scope, LVLines &Lines)
LVAddress getSymbolTableAddress(StringRef Name)
LVAddress linearAddress(uint16_t Segment, uint32_t Offset, LVAddress Addendum=0)
void addToSymbolTable(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex=0)
void addModule(LVScope *Scope)
void getLinkageName(const llvm::object::coff_section *CoffSection, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym)
static StringRef getSymbolKindName(SymbolKind Kind)
virtual void setCount(int64_t Value)
virtual void setBitSize(uint32_t Size)
virtual void updateLevel(LVScope *Parent, bool Moved=false)
virtual int64_t getCount() const
void setInlineCode(uint32_t Code)
virtual void setReference(LVElement *Element)
void setName(StringRef ElementName) override
StringRef getName() const override
void setType(LVElement *Element=nullptr)
void setFilenameIndex(size_t Index)
Error visitKnownRecord(CVType &Record, ArgListRecord &Args, TypeIndex TI, LVElement *Element)
void printRecords(raw_ostream &OS) const
void stopProcessArgumentList()
void printTypeEnd(CVType &Record)
Error visitMemberRecord(CVMemberRecord &Record, TypeVisitorCallbacks &Callbacks, TypeIndex TI, LVElement *Element)
Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base, TypeIndex TI, LVElement *Element)
void printMemberEnd(CVMemberRecord &Record)
void setCompileUnitName(std::string Name)
LVElement * CurrentElement
Error inlineSiteAnnotation(LVScope *AbstractFunction, LVScope *InlinedFunction, InlineSiteSym &InlineSite)
LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W, llvm::pdb::InputFile &Input)
void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx)
Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI)
void pushScope(LVScope *Scope)
Error visitUnknownType(CVType &Record, TypeIndex TI)
void startProcessArgumentList()
void addElement(LVScope *Scope, bool IsCompileUnit)
void printTypeBegin(CVType &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
LVElement * getElement(uint32_t StreamIdx, TypeIndex TI, LVScope *Parent=nullptr)
LVScope * getReaderScope() const
void printMemberBegin(CVMemberRecord &Record, TypeIndex TI, LVElement *Element, uint32_t StreamIdx)
Error finishVisitation(CVType &Record, TypeIndex TI, LVElement *Element)
LVElement * createElement(TypeLeafKind Kind)
LVScope * getParentScope() const
void setOffset(LVOffset DieOffset)
LVOffset getOffset() const
void setLineNumber(uint32_t Number)
void setTag(dwarf::Tag Tag)
codeview::CPUType getCompileUnitCPUType()
void setCompileUnitCPUType(codeview::CPUType Type)
virtual bool isSystemEntry(LVElement *Element, StringRef Name={}) const
LVScopeCompileUnit * getCompileUnit() const
void setCompileUnit(LVScope *Scope)
void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC)
void addElement(LVElement *Element)
void addObject(LVLocation *Location)
const LVLocations * getRanges() const
void getLinkageName(uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
void printRelocatedField(StringRef Label, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym=nullptr)
DebugStringTableSubsectionRef getStringTable() override
StringRef getFileNameForFileOffset(uint32_t FileOffset) override
Error visitSymbolEnd(CVSymbol &Record) override
Error visitKnownRecord(CVSymbol &Record, BlockSym &Block) override
Error visitSymbolBegin(CVSymbol &Record) override
Error visitUnknownSymbol(CVSymbol &Record) override
Action to take on unknown symbols. By default, they are ignored.
Error visitMemberEnd(CVMemberRecord &Record) override
Error visitUnknownMember(CVMemberRecord &Record) override
Error visitTypeBegin(CVType &Record) override
Paired begin/end actions for all types.
Error visitMemberBegin(CVMemberRecord &Record) override
Error visitKnownRecord(CVType &Record, BuildInfoRecord &Args) override
Error visitUnknownType(CVType &Record) override
Action to take on unknown types. By default, they are ignored.
This class implements an extremely fast bulk output stream that can only output to a stream.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
PointerMode
Equivalent to CV_ptrmode_e.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
ArrayRef< EnumEntry< uint16_t > > getJumpTableEntrySizeNames()
bool symbolEndsScope(SymbolKind Kind)
Return true if this ssymbol ends a scope.
MethodOptions
Equivalent to CV_fldattr_t bitfield.
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
MemberAccess
Source-level access specifier. (CV_access_e)
bool symbolOpensScope(SymbolKind Kind)
Return true if this symbol opens a scope.
TypeLeafKind
Duplicate copy of the above enum, but using the official CV names.
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
bool isAggregate(CVType CVT)
Given an arbitrary codeview type, determine if it is an LF_STRUCTURE, LF_CLASS, LF_INTERFACE,...
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
uint64_t getSizeInBytesForTypeRecord(CVType CVT)
Given an arbitrary codeview type, return the type's size in the case of aggregate (LF_STRUCTURE,...
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
ArrayRef< EnumEntry< SourceLanguage > > getSourceLanguageNames()
uint64_t getSizeInBytesForTypeIndex(TypeIndex TI)
Given an arbitrary codeview type index, determine its size.
TypeIndex getModifiedType(const CVType &CVT)
Given a CVType which is assumed to be an LF_MODIFIER, return the TypeIndex of the type that the LF_MO...
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
@ DW_INL_declared_inlined
constexpr Tag DW_TAG_unaligned
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
static TypeIndex getTrueType(TypeIndex &TI)
std::vector< StringRef > LVStringRefs
static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI)
std::vector< TypeIndex > LVLineRecords
LVStringRefs getAllLexicalComponents(StringRef Name)
std::string transformPath(StringRef Path)
LVLexicalComponent getInnerComponent(StringRef Name)
static const EnumEntry< TypeLeafKind > LeafTypeNames[]
std::set< SymbolKind > LVSymbolKinds
std::set< TypeLeafKind > LVTypeKinds
std::string getScopedName(const LVStringRefs &Components, StringRef BaseName={})
std::tuple< LVStringRefs::size_type, LVStringRefs::size_type > LVLexicalIndex
std::string formatTypeLeafKind(codeview::TypeLeafKind K)
Print(const T &, const DataFlowGraph &) -> Print< T >
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
std::tuple< uint64_t, uint32_t > InlineSite
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
@ Mod
The access may modify the value stored in memory.
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
support::detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
void consumeError(Error Err)
Consume a Error without doing anything.
std::string demangle(std::string_view MangledName)
Attempt to demangle a string using different demangling schemes.
MethodOptions getFlags() const
Get the flags that are not included in access control or method properties.
LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)
LVLineRecords LineRecords
LVTypeRecords TypeRecords
LVCodeViewReader * Reader
LVLogicalVisitor * Visitor
LVNamespaceDeduction NamespaceDeduction
LVSymbolKinds SymbolKinds
LVStringRecords StringRecords
LVForwardReferences ForwardReferences