Bug Summary

File:build/source/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
Warning:line 312, column 10
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name LVType.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/DebugInfo/LogicalView -I /build/source/llvm/lib/DebugInfo/LogicalView -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
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
18using namespace llvm;
19using namespace llvm::logicalview;
20
21#define DEBUG_TYPE"Type" "Type"
22
23namespace {
24const char *const KindBaseType = "BaseType";
25const char *const KindConst = "Const";
26const char *const KindEnumerator = "Enumerator";
27const char *const KindImport = "Import";
28const char *const KindPointer = "Pointer";
29const char *const KindPointerMember = "PointerMember";
30const char *const KindReference = "Reference";
31const char *const KindRestrict = "Restrict";
32const char *const KindRvalueReference = "RvalueReference";
33const char *const KindSubrange = "Subrange";
34const char *const KindTemplateTemplate = "TemplateTemplate";
35const char *const KindTemplateType = "TemplateType";
36const char *const KindTemplateValue = "TemplateValue";
37const char *const KindTypeAlias = "TypeAlias";
38const char *const KindUndefined = "Undefined";
39const char *const KindUnaligned = "Unaligned";
40const char *const KindUnspecified = "Unspecified";
41const char *const KindVolatile = "Volatile";
42} // end anonymous namespace
43
44//===----------------------------------------------------------------------===//
45// DWARF Type.
46//===----------------------------------------------------------------------===//
47// Return a string representation for the type kind.
48const 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
87LVTypeDispatch 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
109void 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
122void 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
167StringRef 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
173void 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
200LVType *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.
225bool 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.
245void 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
265bool LVType::equals(const LVType *Type) const {
266 return LVElement::equals(Type);
267}
268
269bool 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
281void LVType::report(LVComparePass Pass) {
282 getComparator().printItem(this, Pass);
283}
284
285void 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
294void 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.
302LVElement *LVTypeDefinition::getUnderlyingType() {
303 LVElement *BaseType = getTypeAsScope();
304 if (BaseType)
4
Assuming 'BaseType' is null
5
Taking false branch
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__))
;
6
Assuming 'Type' is non-null
7
'?' condition is true
310
311 BaseType = Type;
312 while (Type->getIsTypedef()) {
8
Loop condition is true. Entering loop body
14
Called C++ object pointer is null
313 BaseType = Type->getTypeAsScope();
314 if (BaseType)
9
Assuming 'BaseType' is null
10
Taking false branch
315 // Underlying type is a scope.
316 return BaseType;
317
318 Type = Type->getTypeAsType();
11
Value assigned to 'Type'
319 if (Type)
12
Assuming 'Type' is null
13
Taking false branch
320 BaseType = Type;
321 }
322
323 return BaseType;
324}
325
326void 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())
1
Taking false branch
332 return;
333
334 // Set the reference to the typedef type.
335 if (options().getAttributeUnderlying()) {
2
Taking true branch
336 setUnderlyingType(getUnderlyingType());
3
Calling 'LVTypeDefinition::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
352bool LVTypeDefinition::equals(const LVType *Type) const {
353 return LVType::equals(Type);
354}
355
356void 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//===----------------------------------------------------------------------===//
365bool LVTypeEnumerator::equals(const LVType *Type) const {
366 return LVType::equals(Type);
367}
368
369void 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//===----------------------------------------------------------------------===//
377bool LVTypeImport::equals(const LVType *Type) const {
378 return LVType::equals(Type);
379}
380
381void 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//===----------------------------------------------------------------------===//
392LVTypeParam::LVTypeParam() : LVType() {
393 options().getAttributeTypename() ? setIncludeInPrint()
394 : resetIncludeInPrint();
395}
396
397// Encode the specific template argument.
398void 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
451bool 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
466void 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//===----------------------------------------------------------------------===//
487void 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
515bool 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
522void LVTypeSubrange::printExtra(raw_ostream &OS, bool Full) const {
523 OS << formattedKind(kind()) << " -> " << typeOffsetAsString()
524 << formattedName(getTypeName()) << " " << formattedName(getName()) << "\n";
525}