| File: | build/source/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp |
| Warning: | line 312, column 10 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //===-- LVType.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 LVType class. | |||
| 10 | // | |||
| 11 | //===----------------------------------------------------------------------===// | |||
| 12 | ||||
| 13 | #include "llvm/DebugInfo/LogicalView/Core/LVType.h" | |||
| 14 | #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h" | |||
| 15 | #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" | |||
| 16 | #include "llvm/DebugInfo/LogicalView/Core/LVScope.h" | |||
| 17 | ||||
| 18 | using namespace llvm; | |||
| 19 | using namespace llvm::logicalview; | |||
| 20 | ||||
| 21 | #define DEBUG_TYPE"Type" "Type" | |||
| 22 | ||||
| 23 | namespace { | |||
| 24 | const char *const KindBaseType = "BaseType"; | |||
| 25 | const char *const KindConst = "Const"; | |||
| 26 | const char *const KindEnumerator = "Enumerator"; | |||
| 27 | const char *const KindImport = "Import"; | |||
| 28 | const char *const KindPointer = "Pointer"; | |||
| 29 | const char *const KindPointerMember = "PointerMember"; | |||
| 30 | const char *const KindReference = "Reference"; | |||
| 31 | const char *const KindRestrict = "Restrict"; | |||
| 32 | const char *const KindRvalueReference = "RvalueReference"; | |||
| 33 | const char *const KindSubrange = "Subrange"; | |||
| 34 | const char *const KindTemplateTemplate = "TemplateTemplate"; | |||
| 35 | const char *const KindTemplateType = "TemplateType"; | |||
| 36 | const char *const KindTemplateValue = "TemplateValue"; | |||
| 37 | const char *const KindTypeAlias = "TypeAlias"; | |||
| 38 | const char *const KindUndefined = "Undefined"; | |||
| 39 | const char *const KindUnaligned = "Unaligned"; | |||
| 40 | const char *const KindUnspecified = "Unspecified"; | |||
| 41 | const char *const KindVolatile = "Volatile"; | |||
| 42 | } // end anonymous namespace | |||
| 43 | ||||
| 44 | //===----------------------------------------------------------------------===// | |||
| 45 | // DWARF Type. | |||
| 46 | //===----------------------------------------------------------------------===// | |||
| 47 | // Return a string representation for the type kind. | |||
| 48 | const char *LVType::kind() const { | |||
| 49 | const char *Kind = KindUndefined; | |||
| 50 | if (getIsBase()) | |||
| 51 | Kind = KindBaseType; | |||
| 52 | else if (getIsConst()) | |||
| 53 | Kind = KindConst; | |||
| 54 | else if (getIsEnumerator()) | |||
| 55 | Kind = KindEnumerator; | |||
| 56 | else if (getIsImport()) | |||
| 57 | Kind = KindImport; | |||
| 58 | else if (getIsPointerMember()) | |||
| 59 | Kind = KindPointerMember; | |||
| 60 | else if (getIsPointer()) | |||
| 61 | Kind = KindPointer; | |||
| 62 | else if (getIsReference()) | |||
| 63 | Kind = KindReference; | |||
| 64 | else if (getIsRestrict()) | |||
| 65 | Kind = KindRestrict; | |||
| 66 | else if (getIsRvalueReference()) | |||
| 67 | Kind = KindRvalueReference; | |||
| 68 | else if (getIsSubrange()) | |||
| 69 | Kind = KindSubrange; | |||
| 70 | else if (getIsTemplateTypeParam()) | |||
| 71 | Kind = KindTemplateType; | |||
| 72 | else if (getIsTemplateValueParam()) | |||
| 73 | Kind = KindTemplateValue; | |||
| 74 | else if (getIsTemplateTemplateParam()) | |||
| 75 | Kind = KindTemplateTemplate; | |||
| 76 | else if (getIsTypedef()) | |||
| 77 | Kind = KindTypeAlias; | |||
| 78 | else if (getIsUnaligned()) | |||
| 79 | Kind = KindUnaligned; | |||
| 80 | else if (getIsUnspecified()) | |||
| 81 | Kind = KindUnspecified; | |||
| 82 | else if (getIsVolatile()) | |||
| 83 | Kind = KindVolatile; | |||
| 84 | return Kind; | |||
| 85 | } | |||
| 86 | ||||
| 87 | LVTypeDispatch LVType::Dispatch = { | |||
| 88 | {LVTypeKind::IsBase, &LVType::getIsBase}, | |||
| 89 | {LVTypeKind::IsConst, &LVType::getIsConst}, | |||
| 90 | {LVTypeKind::IsEnumerator, &LVType::getIsEnumerator}, | |||
| 91 | {LVTypeKind::IsImport, &LVType::getIsImport}, | |||
| 92 | {LVTypeKind::IsImportDeclaration, &LVType::getIsImportDeclaration}, | |||
| 93 | {LVTypeKind::IsImportModule, &LVType::getIsImportModule}, | |||
| 94 | {LVTypeKind::IsPointer, &LVType::getIsPointer}, | |||
| 95 | {LVTypeKind::IsPointerMember, &LVType::getIsPointerMember}, | |||
| 96 | {LVTypeKind::IsReference, &LVType::getIsReference}, | |||
| 97 | {LVTypeKind::IsRestrict, &LVType::getIsRestrict}, | |||
| 98 | {LVTypeKind::IsRvalueReference, &LVType::getIsRvalueReference}, | |||
| 99 | {LVTypeKind::IsSubrange, &LVType::getIsSubrange}, | |||
| 100 | {LVTypeKind::IsTemplateParam, &LVType::getIsTemplateParam}, | |||
| 101 | {LVTypeKind::IsTemplateTemplateParam, &LVType::getIsTemplateTemplateParam}, | |||
| 102 | {LVTypeKind::IsTemplateTypeParam, &LVType::getIsTemplateTypeParam}, | |||
| 103 | {LVTypeKind::IsTemplateValueParam, &LVType::getIsTemplateValueParam}, | |||
| 104 | {LVTypeKind::IsTypedef, &LVType::getIsTypedef}, | |||
| 105 | {LVTypeKind::IsUnaligned, &LVType::getIsUnaligned}, | |||
| 106 | {LVTypeKind::IsUnspecified, &LVType::getIsUnspecified}, | |||
| 107 | {LVTypeKind::IsVolatile, &LVType::getIsVolatile}}; | |||
| 108 | ||||
| 109 | void LVType::resolveReferences() { | |||
| 110 | // Some DWARF tags are the representation of types. However, we associate | |||
| 111 | // some of them to scopes. The ones associated with types, do not have | |||
| 112 | // any reference tags, such as DW_AT_specification, DW_AT_abstract_origin, | |||
| 113 | // DW_AT_extension. | |||
| 114 | ||||
| 115 | // Set the file/line information using the Debug Information entry. | |||
| 116 | setFile(/*Reference=*/nullptr); | |||
| 117 | ||||
| 118 | if (LVElement *Element = getType()) | |||
| 119 | Element->resolve(); | |||
| 120 | } | |||
| 121 | ||||
| 122 | void LVType::resolveName() { | |||
| 123 | if (getIsResolvedName()) | |||
| 124 | return; | |||
| 125 | setIsResolvedName(); | |||
| 126 | ||||
| 127 | // The templates are recorded as normal DWARF objects relationships; | |||
| 128 | // the template parameters are preserved to show the types used during | |||
| 129 | // the instantiation; however if a compare have been requested, those | |||
| 130 | // parameters needs to be resolved, so no conflicts are generated. | |||
| 131 | // The following DWARF illustrates this issue: | |||
| 132 | // | |||
| 133 | // a) Template Parameters are preserved: | |||
| 134 | // {Class} 'ConstArray<AtomTable>' | |||
| 135 | // {Inherits} -> 'ArrayBase' | |||
| 136 | // {TemplateType} 'taTYPE' -> 'AtomTable' | |||
| 137 | // {Member} 'mData' -> '* taTYPE' | |||
| 138 | // | |||
| 139 | // b) Template Parameters are resolved: | |||
| 140 | // {Class} 'ConstArray<AtomTable>' | |||
| 141 | // {Inherits} -> 'ArrayBase' | |||
| 142 | // {TemplateType} 'taTYPE' -> 'AtomTable' | |||
| 143 | // {Member} 'mData' -> '* AtomTable' | |||
| 144 | // | |||
| 145 | // In (b), the {Member} type have been resolved to use the real type. | |||
| 146 | ||||
| 147 | LVElement *BaseType = getType(); | |||
| 148 | if (BaseType && options().getAttributeArgument()) | |||
| 149 | if (BaseType->isTemplateParam()) | |||
| 150 | BaseType = BaseType->getType(); | |||
| 151 | ||||
| 152 | if (BaseType && !BaseType->getIsResolvedName()) | |||
| 153 | BaseType->resolveName(); | |||
| 154 | resolveFullname(BaseType, getName()); | |||
| 155 | ||||
| 156 | // In the case of unnamed types, try to generate a name for it, using | |||
| 157 | // the parents name and the line information. Ignore the template parameters. | |||
| 158 | if (!isNamed() && !getIsTemplateParam()) | |||
| 159 | generateName(); | |||
| 160 | ||||
| 161 | LVElement::resolveName(); | |||
| 162 | ||||
| 163 | // Resolve any given pattern. | |||
| 164 | patterns().resolvePatternMatch(this); | |||
| 165 | } | |||
| 166 | ||||
| 167 | StringRef LVType::resolveReferencesChain() { | |||
| 168 | // The types do not have a DW_AT_specification or DW_AT_abstract_origin | |||
| 169 | // reference. Just return the type name. | |||
| 170 | return getName(); | |||
| 171 | } | |||
| 172 | ||||
| 173 | void LVType::markMissingParents(const LVTypes *References, | |||
| 174 | const LVTypes *Targets) { | |||
| 175 | if (!(References && Targets)) | |||
| 176 | return; | |||
| 177 | ||||
| 178 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 179 | dbgs() << "\n[LVType::markMissingParents]\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 180 | for (const LVType *Reference : *References)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 181 | dbgs() << "References: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 182 | << "Kind = " << formattedKind(Reference->kind()) << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 183 | << "Name = " << formattedName(Reference->getName()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 184 | for (const LVType *Target : *Targets)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 185 | dbgs() << "Targets : "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 186 | << "Kind = " << formattedKind(Target->kind()) << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 187 | << "Name = " << formattedName(Target->getName()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false) | |||
| 188 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::markMissingParents]\n" ; for (const LVType *Reference : *References) dbgs() << "References: " << "Kind = " << formattedKind(Reference ->kind()) << ", " << "Name = " << formattedName (Reference->getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Targets : " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target->getName()) << "\n"; }; } } while (false); | |||
| 189 | ||||
| 190 | for (LVType *Reference : *References) { | |||
| 191 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "Search Reference: Name = " << formattedName(Reference->getName()) << "\n"; }; } } while (false) | |||
| 192 | dbgs() << "Search Reference: Name = "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "Search Reference: Name = " << formattedName(Reference->getName()) << "\n"; }; } } while (false) | |||
| 193 | << formattedName(Reference->getName()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "Search Reference: Name = " << formattedName(Reference->getName()) << "\n"; }; } } while (false) | |||
| 194 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "Search Reference: Name = " << formattedName(Reference->getName()) << "\n"; }; } } while (false); | |||
| 195 | if (!Reference->findIn(Targets)) | |||
| 196 | Reference->markBranchAsMissing(); | |||
| 197 | } | |||
| 198 | } | |||
| 199 | ||||
| 200 | LVType *LVType::findIn(const LVTypes *Targets) const { | |||
| 201 | if (!Targets) | |||
| 202 | return nullptr; | |||
| 203 | ||||
| 204 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 205 | dbgs() << "\n[LVType::findIn]\n"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 206 | << "Reference: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 207 | << "Level = " << getLevel() << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 208 | << "Kind = " << formattedKind(kind()) << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 209 | << "Name = " << formattedName(getName()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 210 | for (const LVType *Target : *Targets)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 211 | dbgs() << "Target : "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 212 | << "Level = " << Target->getLevel() << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 213 | << "Kind = " << formattedKind(Target->kind()) << ", "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 214 | << "Name = " << formattedName(Target->getName()) << "\n";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false) | |||
| 215 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("Type")) { { dbgs() << "\n[LVType::findIn]\n" << "Reference: " << "Level = " << getLevel() << ", " << "Kind = " << formattedKind(kind()) << ", " << "Name = " << formattedName(getName()) << "\n"; for (const LVType *Target : *Targets) dbgs() << "Target : " << "Level = " << Target->getLevel() << ", " << "Kind = " << formattedKind(Target->kind()) << ", " << "Name = " << formattedName(Target ->getName()) << "\n"; }; } } while (false); | |||
| 216 | ||||
| 217 | for (LVType *Target : *Targets) | |||
| 218 | if (equals(Target)) | |||
| 219 | return Target; | |||
| 220 | ||||
| 221 | return nullptr; | |||
| 222 | } | |||
| 223 | ||||
| 224 | // Check for a match on the arguments of a function. | |||
| 225 | bool LVType::parametersMatch(const LVTypes *References, | |||
| 226 | const LVTypes *Targets) { | |||
| 227 | if (!References && !Targets) | |||
| 228 | return true; | |||
| 229 | if (References && Targets) { | |||
| 230 | LVTypes ReferenceTypes; | |||
| 231 | LVScopes ReferenceScopes; | |||
| 232 | getParameters(References, &ReferenceTypes, &ReferenceScopes); | |||
| 233 | LVTypes TargetTypes; | |||
| 234 | LVScopes TargetScopes; | |||
| 235 | getParameters(Targets, &TargetTypes, &TargetScopes); | |||
| 236 | if (!LVType::equals(&ReferenceTypes, &TargetTypes) || | |||
| 237 | !LVScope::equals(&ReferenceScopes, &TargetScopes)) | |||
| 238 | return false; | |||
| 239 | return true; | |||
| 240 | } | |||
| 241 | return false; | |||
| 242 | } | |||
| 243 | ||||
| 244 | // Return the types which are parameters. | |||
| 245 | void LVType::getParameters(const LVTypes *Types, LVTypes *TypesParam, | |||
| 246 | LVScopes *ScopesParam) { | |||
| 247 | if (!Types) | |||
| 248 | return; | |||
| 249 | ||||
| 250 | // During a compare task, the template parameters are expanded to | |||
| 251 | // point to their real types, to avoid compare conflicts. | |||
| 252 | for (LVType *Type : *Types) { | |||
| 253 | if (!Type->getIsTemplateParam()) | |||
| 254 | continue; | |||
| 255 | if (options().getAttributeArgument()) { | |||
| 256 | if (Type->getIsKindType()) | |||
| 257 | TypesParam->push_back(Type->getTypeAsType()); | |||
| 258 | else if (Type->getIsKindScope()) | |||
| 259 | ScopesParam->push_back(Type->getTypeAsScope()); | |||
| 260 | } else | |||
| 261 | TypesParam->push_back(Type); | |||
| 262 | } | |||
| 263 | } | |||
| 264 | ||||
| 265 | bool LVType::equals(const LVType *Type) const { | |||
| 266 | return LVElement::equals(Type); | |||
| 267 | } | |||
| 268 | ||||
| 269 | bool LVType::equals(const LVTypes *References, const LVTypes *Targets) { | |||
| 270 | if (!References && !Targets) | |||
| 271 | return true; | |||
| 272 | if (References && Targets && References->size() == Targets->size()) { | |||
| 273 | for (const LVType *Reference : *References) | |||
| 274 | if (!Reference->findIn(Targets)) | |||
| 275 | return false; | |||
| 276 | return true; | |||
| 277 | } | |||
| 278 | return false; | |||
| 279 | } | |||
| 280 | ||||
| 281 | void LVType::report(LVComparePass Pass) { | |||
| 282 | getComparator().printItem(this, Pass); | |||
| 283 | } | |||
| 284 | ||||
| 285 | void LVType::print(raw_ostream &OS, bool Full) const { | |||
| 286 | if (getIncludeInPrint() && | |||
| 287 | (getIsReference() || getReader().doPrintType(this))) { | |||
| 288 | getReaderCompileUnit()->incrementPrintedTypes(); | |||
| 289 | LVElement::print(OS, Full); | |||
| 290 | printExtra(OS, Full); | |||
| 291 | } | |||
| 292 | } | |||
| 293 | ||||
| 294 | void LVType::printExtra(raw_ostream &OS, bool Full) const { | |||
| 295 | OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n"; | |||
| 296 | } | |||
| 297 | ||||
| 298 | //===----------------------------------------------------------------------===// | |||
| 299 | // DWARF typedef. | |||
| 300 | //===----------------------------------------------------------------------===// | |||
| 301 | // Return the underlying type for a typedef, which can be a type or scope. | |||
| 302 | LVElement *LVTypeDefinition::getUnderlyingType() { | |||
| 303 | LVElement *BaseType = getTypeAsScope(); | |||
| 304 | if (BaseType) | |||
| 305 | // Underlying type is a scope. | |||
| 306 | return BaseType; | |||
| 307 | ||||
| 308 | LVType *Type = getTypeAsType(); | |||
| 309 | assert(Type && "Type definition does not have a type.")(static_cast <bool> (Type && "Type definition does not have a type." ) ? void (0) : __assert_fail ("Type && \"Type definition does not have a type.\"" , "llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp", 309, __extension__ __PRETTY_FUNCTION__)); | |||
| 310 | ||||
| 311 | BaseType = Type; | |||
| 312 | while (Type->getIsTypedef()) { | |||
| ||||
| 313 | BaseType = Type->getTypeAsScope(); | |||
| 314 | if (BaseType) | |||
| 315 | // Underlying type is a scope. | |||
| 316 | return BaseType; | |||
| 317 | ||||
| 318 | Type = Type->getTypeAsType(); | |||
| 319 | if (Type) | |||
| 320 | BaseType = Type; | |||
| 321 | } | |||
| 322 | ||||
| 323 | return BaseType; | |||
| 324 | } | |||
| 325 | ||||
| 326 | void LVTypeDefinition::resolveExtra() { | |||
| 327 | // In the case of CodeView, the MSVC toolset generates a series of typedefs | |||
| 328 | // that refer to internal runtime structures, that we do not process. Those | |||
| 329 | // typedefs are marked as 'system'. They have an associated logical type, | |||
| 330 | // but the underlying type always is null. | |||
| 331 | if (getIsSystem()) | |||
| ||||
| 332 | return; | |||
| 333 | ||||
| 334 | // Set the reference to the typedef type. | |||
| 335 | if (options().getAttributeUnderlying()) { | |||
| 336 | setUnderlyingType(getUnderlyingType()); | |||
| 337 | setIsTypedefReduced(); | |||
| 338 | if (LVElement *Type = getType()) { | |||
| 339 | Type->resolveName(); | |||
| 340 | resolveFullname(Type); | |||
| 341 | } | |||
| 342 | } | |||
| 343 | ||||
| 344 | // For the case of typedef'd anonymous structures: | |||
| 345 | // typedef struct { ... } Name; | |||
| 346 | // Propagate the typedef name to the anonymous structure. | |||
| 347 | LVScope *Aggregate = getTypeAsScope(); | |||
| 348 | if (Aggregate && Aggregate->getIsAnonymous()) | |||
| 349 | Aggregate->setName(getName()); | |||
| 350 | } | |||
| 351 | ||||
| 352 | bool LVTypeDefinition::equals(const LVType *Type) const { | |||
| 353 | return LVType::equals(Type); | |||
| 354 | } | |||
| 355 | ||||
| 356 | void LVTypeDefinition::printExtra(raw_ostream &OS, bool Full) const { | |||
| 357 | OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> " | |||
| 358 | << typeOffsetAsString() | |||
| 359 | << formattedName((getType() ? getType()->getName() : "")) << "\n"; | |||
| 360 | } | |||
| 361 | ||||
| 362 | //===----------------------------------------------------------------------===// | |||
| 363 | // DWARF enumerator (DW_TAG_enumerator). | |||
| 364 | //===----------------------------------------------------------------------===// | |||
| 365 | bool LVTypeEnumerator::equals(const LVType *Type) const { | |||
| 366 | return LVType::equals(Type); | |||
| 367 | } | |||
| 368 | ||||
| 369 | void LVTypeEnumerator::printExtra(raw_ostream &OS, bool Full) const { | |||
| 370 | OS << formattedKind(kind()) << " '" << getName() | |||
| 371 | << "' = " << formattedName(getValue()) << "\n"; | |||
| 372 | } | |||
| 373 | ||||
| 374 | //===----------------------------------------------------------------------===// | |||
| 375 | // DWARF import (DW_TAG_imported_module / DW_TAG_imported_declaration). | |||
| 376 | //===----------------------------------------------------------------------===// | |||
| 377 | bool LVTypeImport::equals(const LVType *Type) const { | |||
| 378 | return LVType::equals(Type); | |||
| 379 | } | |||
| 380 | ||||
| 381 | void LVTypeImport::printExtra(raw_ostream &OS, bool Full) const { | |||
| 382 | std::string Attributes = | |||
| 383 | formatAttributes(virtualityString(), accessibilityString()); | |||
| 384 | ||||
| 385 | OS << formattedKind(kind()) << " " << typeOffsetAsString() << Attributes | |||
| 386 | << formattedName((getType() ? getType()->getName() : "")) << "\n"; | |||
| 387 | } | |||
| 388 | ||||
| 389 | //===----------------------------------------------------------------------===// | |||
| 390 | // DWARF Template parameter holder (type or param). | |||
| 391 | //===----------------------------------------------------------------------===// | |||
| 392 | LVTypeParam::LVTypeParam() : LVType() { | |||
| 393 | options().getAttributeTypename() ? setIncludeInPrint() | |||
| 394 | : resetIncludeInPrint(); | |||
| 395 | } | |||
| 396 | ||||
| 397 | // Encode the specific template argument. | |||
| 398 | void LVTypeParam::encodeTemplateArgument(std::string &Name) const { | |||
| 399 | // The incoming type is a template parameter; we have 3 kinds of parameters: | |||
| 400 | // - type parameter: resolve the instance (type); | |||
| 401 | // - value parameter: resolve the constant value | |||
| 402 | // - template parameter: resolve the name of the template. | |||
| 403 | // If the parameter type is a template instance (STL sample), we need to | |||
| 404 | // expand the type (template template case). For the following variable | |||
| 405 | // declarations: | |||
| 406 | // std::type<float> a_float; | |||
| 407 | // std::type<int> a_int; | |||
| 408 | // We must generate names like: | |||
| 409 | // "std::type<float,std::less<float>,std::allocator<float>,false>" | |||
| 410 | // "std::type<int,std::less<int>,std::allocator<int>,false>" | |||
| 411 | // Instead of the incomplete names: | |||
| 412 | // "type<float,less,allocator,false>" | |||
| 413 | // "type<int,less,allocator,false>" | |||
| 414 | ||||
| 415 | if (getIsTemplateTypeParam()) { | |||
| 416 | // Get the type instance recorded in the template type; it can be a | |||
| 417 | // reference to a type or to a scope. | |||
| 418 | ||||
| 419 | if (getIsKindType()) { | |||
| 420 | // The argument types always are qualified. | |||
| 421 | Name.append(std::string(getTypeQualifiedName())); | |||
| 422 | ||||
| 423 | LVType *ArgType = getTypeAsType(); | |||
| 424 | // For template arguments that are typedefs, use the underlying type, | |||
| 425 | // which can be a type or scope. | |||
| 426 | if (ArgType->getIsTypedef()) { | |||
| 427 | LVObject *BaseType = ArgType->getUnderlyingType(); | |||
| 428 | Name.append(std::string(BaseType->getName())); | |||
| 429 | } else { | |||
| 430 | Name.append(std::string(ArgType->getName())); | |||
| 431 | } | |||
| 432 | } else { | |||
| 433 | if (getIsKindScope()) { | |||
| 434 | LVScope *ArgScope = getTypeAsScope(); | |||
| 435 | // If the scope is a template, we have to resolve that template, | |||
| 436 | // by recursively traversing its arguments. | |||
| 437 | if (ArgScope->getIsTemplate()) | |||
| 438 | ArgScope->encodeTemplateArguments(Name); | |||
| 439 | else { | |||
| 440 | // The argument types always are qualified. | |||
| 441 | Name.append(std::string(getTypeQualifiedName())); | |||
| 442 | Name.append(std::string(ArgScope->getName())); | |||
| 443 | } | |||
| 444 | } | |||
| 445 | } | |||
| 446 | } else | |||
| 447 | // Template value parameter or template template parameter. | |||
| 448 | Name.append(getValue()); | |||
| 449 | } | |||
| 450 | ||||
| 451 | bool LVTypeParam::equals(const LVType *Type) const { | |||
| 452 | if (!LVType::equals(Type)) | |||
| 453 | return false; | |||
| 454 | ||||
| 455 | // Checks the kind of template argument. | |||
| 456 | if (getIsTemplateTypeParam() && Type->getIsTemplateTypeParam()) | |||
| 457 | return getType()->equals(Type->getType()); | |||
| 458 | ||||
| 459 | if ((getIsTemplateValueParam() && Type->getIsTemplateValueParam()) || | |||
| 460 | (getIsTemplateTemplateParam() && Type->getIsTemplateTemplateParam())) | |||
| 461 | return getValueIndex() == Type->getValueIndex(); | |||
| 462 | ||||
| 463 | return false; | |||
| 464 | } | |||
| 465 | ||||
| 466 | void LVTypeParam::printExtra(raw_ostream &OS, bool Full) const { | |||
| 467 | OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> " | |||
| 468 | << typeOffsetAsString(); | |||
| 469 | ||||
| 470 | // Depending on the type of parameter, the print includes different | |||
| 471 | // information: type, value or reference to a template. | |||
| 472 | if (getIsTemplateTypeParam()) { | |||
| 473 | OS << formattedNames(getTypeQualifiedName(), getTypeName()) << "\n"; | |||
| 474 | return; | |||
| 475 | } | |||
| 476 | if (getIsTemplateValueParam()) { | |||
| 477 | OS << formattedName(getValue()) << " " << formattedName(getName()) << "\n"; | |||
| 478 | return; | |||
| 479 | } | |||
| 480 | if (getIsTemplateTemplateParam()) | |||
| 481 | OS << formattedName(getValue()) << "\n"; | |||
| 482 | } | |||
| 483 | ||||
| 484 | //===----------------------------------------------------------------------===// | |||
| 485 | // DW_TAG_subrange_type | |||
| 486 | //===----------------------------------------------------------------------===// | |||
| 487 | void LVTypeSubrange::resolveExtra() { | |||
| 488 | // There are 2 cases to represent the bounds information for an array: | |||
| 489 | // 1) DW_TAG_subrange_type | |||
| 490 | // DW_AT_type --> ref_type (type of count) | |||
| 491 | // DW_AT_count --> value (number of elements in subrange) | |||
| 492 | ||||
| 493 | // 2) DW_TAG_subrange_type | |||
| 494 | // DW_AT_lower_bound --> value | |||
| 495 | // DW_AT_upper_bound --> value | |||
| 496 | ||||
| 497 | // The idea is to represent the bounds as a string, depending on the format: | |||
| 498 | // 1) [count] | |||
| 499 | // 2) [lower..upper] | |||
| 500 | ||||
| 501 | // Subrange information. | |||
| 502 | std::string String; | |||
| 503 | ||||
| 504 | // Check if we have DW_AT_count subrange style. | |||
| 505 | if (getIsSubrangeCount()) | |||
| 506 | // Get count subrange value. Assume 0 if missing. | |||
| 507 | raw_string_ostream(String) << "[" << getCount() << "]"; | |||
| 508 | else | |||
| 509 | raw_string_ostream(String) | |||
| 510 | << "[" << getLowerBound() << ".." << getUpperBound() << "]"; | |||
| 511 | ||||
| 512 | setName(String); | |||
| 513 | } | |||
| 514 | ||||
| 515 | bool LVTypeSubrange::equals(const LVType *Type) const { | |||
| 516 | if (!LVType::equals(Type)) | |||
| 517 | return false; | |||
| 518 | ||||
| 519 | return getTypeName() == Type->getTypeName() && getName() == Type->getName(); | |||
| 520 | } | |||
| 521 | ||||
| 522 | void LVTypeSubrange::printExtra(raw_ostream &OS, bool Full) const { | |||
| 523 | OS << formattedKind(kind()) << " -> " << typeOffsetAsString() | |||
| 524 | << formattedName(getTypeName()) << " " << formattedName(getName()) << "\n"; | |||
| 525 | } |