@@ -136,12 +136,16 @@ getFileLine(const SectionChunk *c, uint32_t addr) {
136136// of all references to that symbol from that file. If no debug information is
137137// available, returns just the name of the file, else one string per actual
138138// 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) {
140143 struct Location {
141144 Symbol *sym;
142145 std::pair<StringRef, uint32_t > fileLine;
143146 };
144147 std::vector<Location> locations;
148+ size_t numLocations = 0 ;
145149
146150 for (Chunk *c : file->getChunks ()) {
147151 auto *sc = dyn_cast<SectionChunk>(c);
@@ -150,6 +154,10 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
150154 for (const coff_relocation &r : sc->getRelocs ()) {
151155 if (r.SymbolTableIndex != symIndex)
152156 continue ;
157+ numLocations++;
158+ if (locations.size () >= maxStrings)
159+ continue ;
160+
153161 Optional<std::pair<StringRef, uint32_t >> fileLine =
154162 getFileLine (sc, r.VirtualAddress );
155163 Symbol *sym = getSymbol (sc, r.VirtualAddress );
@@ -160,8 +168,12 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
160168 }
161169 }
162170
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 );
165177
166178 std::vector<std::string> symbolLocations (locations.size ());
167179 size_t i = 0 ;
@@ -175,17 +187,26 @@ std::vector<std::string> getSymbolLocations(ObjFile *file, uint32_t symIndex) {
175187 if (loc.sym )
176188 os << " :(" << toString (*loc.sym ) << ' )' ;
177189 }
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 ;
179195}
180196
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 ) {
183199 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+ }
187208 llvm_unreachable (" unsupported file type passed to getSymbolLocations" );
188- return {} ;
209+ return std::make_pair (std::vector<std::string>(), ( size_t ) 0 ) ;
189210}
190211
191212// For an undefined symbol, stores all files referencing it and the index of
@@ -205,20 +226,21 @@ static void reportUndefinedSymbol(const UndefinedDiag &undefDiag) {
205226 os << " undefined symbol: " << toString (*undefDiag.sym );
206227
207228 const size_t maxUndefReferences = 3 ;
208- size_t i = 0 , numRefs = 0 ;
229+ size_t numDisplayedRefs = 0 , numRefs = 0 ;
209230 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 ();
213238 for (const std::string &s : symbolLocations) {
214- if (i >= maxUndefReferences)
215- break ;
216239 os << s;
217- i++;
218240 }
219241 }
220- if (i < numRefs)
221- os << " \n >>> referenced " << numRefs - i << " more times" ;
242+ if (numDisplayedRefs < numRefs)
243+ os << " \n >>> referenced " << numRefs - numDisplayedRefs << " more times" ;
222244 errorOrWarn (os.str ());
223245}
224246
0 commit comments