@@ -136,12 +136,16 @@ getFileLine(const SectionChunk *c, uint32_t addr) {
136
136
// of all references to that symbol from that file. If no debug information is
137
137
// available, returns just the name of the file, else one string per actual
138
138
// reference as described in the debug info.
139
- std::vector<std::string> getSymbolLocations (ObjFile *file, uint32_t symIndex) {
139
+ // Returns up to maxStrings string descriptions, along with the total number of
140
+ // locations found.
141
+ static std::pair<std::vector<std::string>, size_t >
142
+ getSymbolLocations (ObjFile *file, uint32_t symIndex, size_t maxStrings) {
140
143
struct Location {
141
144
Symbol *sym;
142
145
std::pair<StringRef, uint32_t > fileLine;
143
146
};
144
147
std::vector<Location> locations;
148
+ size_t numLocations = 0 ;
145
149
146
150
for (Chunk *c : file->getChunks ()) {
147
151
auto *sc = dyn_cast<SectionChunk>(c);
@@ -150,6 +154,10 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
150
154
for (const coff_relocation &r : sc->getRelocs ()) {
151
155
if (r.SymbolTableIndex != symIndex)
152
156
continue ;
157
+ numLocations++;
158
+ if (locations.size () >= maxStrings)
159
+ continue ;
160
+
153
161
Optional<std::pair<StringRef, uint32_t >> fileLine =
154
162
getFileLine (sc, r.VirtualAddress );
155
163
Symbol *sym = getSymbol (sc, r.VirtualAddress );
@@ -160,8 +168,12 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
160
168
}
161
169
}
162
170
163
- if (locations.empty ())
164
- return std::vector<std::string>({" \n >>> referenced by " + toString (file)});
171
+ if (maxStrings == 0 )
172
+ return std::make_pair (std::vector<std::string>(), numLocations);
173
+
174
+ if (numLocations == 0 )
175
+ return std::make_pair (
176
+ std::vector<std::string>{" \n >>> referenced by " + toString (file)}, 1 );
165
177
166
178
std::vector<std::string> symbolLocations (locations.size ());
167
179
size_t i = 0 ;
@@ -175,17 +187,26 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
175
187
if (loc.sym )
176
188
os << " :(" << toString (*loc.sym ) << ' )' ;
177
189
}
178
- return symbolLocations;
190
+ return std::make_pair (symbolLocations, numLocations);
191
+ }
192
+
193
+ std::vector<std::string> getSymbolLocations (ObjFile *file, uint32_t symIndex) {
194
+ return getSymbolLocations (file, symIndex, SIZE_MAX).first ;
179
195
}
180
196
181
- std::vector<std::string> getSymbolLocations (InputFile *file,
182
- uint32_t symIndex) {
197
+ static std::pair<std:: vector<std::string>, size_t >
198
+ getSymbolLocations (InputFile *file, uint32_t symIndex, size_t maxStrings ) {
183
199
if (auto *o = dyn_cast<ObjFile>(file))
184
- return getSymbolLocations (o, symIndex);
185
- if (auto *b = dyn_cast<BitcodeFile>(file))
186
- return getSymbolLocations (b);
200
+ return getSymbolLocations (o, symIndex, maxStrings);
201
+ if (auto *b = dyn_cast<BitcodeFile>(file)) {
202
+ std::vector<std::string> symbolLocations = getSymbolLocations (b);
203
+ size_t numLocations = symbolLocations.size ();
204
+ if (symbolLocations.size () > maxStrings)
205
+ symbolLocations.resize (maxStrings);
206
+ return std::make_pair (symbolLocations, numLocations);
207
+ }
187
208
llvm_unreachable (" unsupported file type passed to getSymbolLocations" );
188
- return {} ;
209
+ return std::make_pair (std::vector<std::string>(), ( size_t ) 0 ) ;
189
210
}
190
211
191
212
// For an undefined symbol, stores all files referencing it and the index of
@@ -205,20 +226,21 @@ static void reportUndefinedSymbol(const UndefinedDiag &undefDiag) {
205
226
os << " undefined symbol: " << toString (*undefDiag.sym );
206
227
207
228
const size_t maxUndefReferences = 3 ;
208
- size_t i = 0 , numRefs = 0 ;
229
+ size_t numDisplayedRefs = 0 , numRefs = 0 ;
209
230
for (const UndefinedDiag::File &ref : undefDiag.files ) {
210
- std::vector<std::string> symbolLocations =
211
- getSymbolLocations (ref.file , ref.symIndex );
212
- numRefs += symbolLocations.size ();
231
+ std::vector<std::string> symbolLocations;
232
+ size_t totalLocations = 0 ;
233
+ std::tie (symbolLocations, totalLocations) = getSymbolLocations (
234
+ ref.file , ref.symIndex , maxUndefReferences - numDisplayedRefs);
235
+
236
+ numRefs += totalLocations;
237
+ numDisplayedRefs += symbolLocations.size ();
213
238
for (const std::string &s : symbolLocations) {
214
- if (i >= maxUndefReferences)
215
- break ;
216
239
os << s;
217
- i++;
218
240
}
219
241
}
220
- if (i < numRefs)
221
- os << " \n >>> referenced " << numRefs - i << " more times" ;
242
+ if (numDisplayedRefs < numRefs)
243
+ os << " \n >>> referenced " << numRefs - numDisplayedRefs << " more times" ;
222
244
errorOrWarn (os.str ());
223
245
}
224
246
0 commit comments