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 | } |