Skip to content

Commit ff97b28

Browse files
committed
[ELF] Simplif reportUndefinedSymbol. NFC
1 parent 0a6d797 commit ff97b28

File tree

3 files changed

+38
-44
lines changed

3 files changed

+38
-44
lines changed

lld/Common/ErrorHandler.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@ void ErrorHandler::fatal(const Twine &msg) {
337337
}
338338

339339
SyncStream::~SyncStream() {
340-
os.flush();
341340
switch (level) {
342341
case DiagLevel::None:
343342
break;

lld/ELF/Relocations.cpp

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -522,42 +522,39 @@ int64_t RelocationScanner::computeMipsAddend(const RelTy &rel, RelExpr expr,
522522

523523
// Custom error message if Sym is defined in a discarded section.
524524
template <class ELFT>
525-
static std::string maybeReportDiscarded(Ctx &ctx, Undefined &sym) {
525+
static void maybeReportDiscarded(Ctx &ctx, ELFSyncStream &msg, Undefined &sym) {
526526
auto *file = dyn_cast_or_null<ObjFile<ELFT>>(sym.file);
527527
if (!file || !sym.discardedSecIdx)
528-
return "";
528+
return;
529529
ArrayRef<typename ELFT::Shdr> objSections =
530530
file->template getELFShdrs<ELFT>();
531531

532-
std::string msg;
533532
if (sym.type == ELF::STT_SECTION) {
534-
msg = "relocation refers to a discarded section: ";
535-
msg += CHECK2(
533+
msg << "relocation refers to a discarded section: ";
534+
msg << CHECK2(
536535
file->getObj().getSectionName(objSections[sym.discardedSecIdx]), file);
537536
} else {
538-
msg = "relocation refers to a symbol in a discarded section: " +
539-
toStr(ctx, sym);
537+
msg << "relocation refers to a symbol in a discarded section: " << &sym;
540538
}
541-
msg += "\n>>> defined in " + toStr(ctx, file);
539+
msg << "\n>>> defined in " << file;
542540

543541
Elf_Shdr_Impl<ELFT> elfSec = objSections[sym.discardedSecIdx - 1];
544542
if (elfSec.sh_type != SHT_GROUP)
545-
return msg;
543+
return;
546544

547545
// If the discarded section is a COMDAT.
548546
StringRef signature = file->getShtGroupSignature(objSections, elfSec);
549547
if (const InputFile *prevailing =
550548
ctx.symtab->comdatGroups.lookup(CachedHashStringRef(signature))) {
551-
msg += "\n>>> section group signature: " + signature.str() +
552-
"\n>>> prevailing definition is in " + toStr(ctx, prevailing);
549+
msg << "\n>>> section group signature: "
550+
<< signature.str() + "\n>>> prevailing definition is in " << prevailing;
553551
if (sym.nonPrevailing) {
554-
msg += "\n>>> or the symbol in the prevailing group had STB_WEAK "
552+
msg << "\n>>> or the symbol in the prevailing group had STB_WEAK "
555553
"binding and the symbol in a non-prevailing group had STB_GLOBAL "
556554
"binding. Mixing groups with STB_WEAK and STB_GLOBAL binding "
557555
"signature is not supported";
558556
}
559557
}
560-
return msg;
561558
}
562559

563560
// Check whether the definition name def is a mangled function name that matches
@@ -695,8 +692,9 @@ static const Symbol *getAlternativeSpelling(Ctx &ctx, const Undefined &sym,
695692
static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
696693
bool correctSpelling) {
697694
Undefined &sym = *undef.sym;
695+
ELFSyncStream msg(ctx, DiagLevel::None);
698696

699-
auto visibility = [&]() -> std::string {
697+
auto visibility = [&]() {
700698
switch (sym.visibility()) {
701699
case STV_INTERNAL:
702700
return "internal ";
@@ -709,75 +707,70 @@ static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
709707
}
710708
};
711709

712-
std::string msg;
713710
switch (ctx.arg.ekind) {
714711
case ELF32LEKind:
715-
msg = maybeReportDiscarded<ELF32LE>(ctx, sym);
712+
maybeReportDiscarded<ELF32LE>(ctx, msg, sym);
716713
break;
717714
case ELF32BEKind:
718-
msg = maybeReportDiscarded<ELF32BE>(ctx, sym);
715+
maybeReportDiscarded<ELF32BE>(ctx, msg, sym);
719716
break;
720717
case ELF64LEKind:
721-
msg = maybeReportDiscarded<ELF64LE>(ctx, sym);
718+
maybeReportDiscarded<ELF64LE>(ctx, msg, sym);
722719
break;
723720
case ELF64BEKind:
724-
msg = maybeReportDiscarded<ELF64BE>(ctx, sym);
721+
maybeReportDiscarded<ELF64BE>(ctx, msg, sym);
725722
break;
726723
default:
727724
llvm_unreachable("");
728725
}
729-
if (msg.empty())
730-
msg = "undefined " + visibility() + "symbol: " + toStr(ctx, sym);
726+
if (msg.str().empty())
727+
msg << "undefined " << visibility() << "symbol: " << &sym;
731728

732729
const size_t maxUndefReferences = 3;
733-
size_t i = 0;
734-
for (UndefinedDiag::Loc l : undef.locs) {
735-
if (i >= maxUndefReferences)
736-
break;
730+
for (UndefinedDiag::Loc l :
731+
ArrayRef(undef.locs).take_front(maxUndefReferences)) {
737732
InputSectionBase &sec = *l.sec;
738733
uint64_t offset = l.offset;
739734

740-
msg += "\n>>> referenced by ";
735+
msg << "\n>>> referenced by ";
741736
// In the absence of line number information, utilize DW_TAG_variable (if
742737
// present) for the enclosing symbol (e.g. var in `int *a[] = {&undef};`).
743738
Symbol *enclosing = sec.getEnclosingSymbol(offset);
744739
std::string src = sec.getSrcMsg(enclosing ? *enclosing : sym, offset);
745740
if (!src.empty())
746-
msg += src + "\n>>> ";
747-
msg += sec.getObjMsg(offset);
748-
i++;
741+
msg << src << "\n>>> ";
742+
msg << sec.getObjMsg(offset);
749743
}
750744

751-
if (i < undef.locs.size())
752-
msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times")
753-
.str();
745+
if (maxUndefReferences < undef.locs.size())
746+
msg << "\n>>> referenced " << (undef.locs.size() - maxUndefReferences)
747+
<< " more times";
754748

755749
if (correctSpelling) {
756750
std::string pre_hint = ": ", post_hint;
757751
if (const Symbol *corrected =
758752
getAlternativeSpelling(ctx, sym, pre_hint, post_hint)) {
759-
msg +=
760-
"\n>>> did you mean" + pre_hint + toStr(ctx, *corrected) + post_hint;
753+
msg << "\n>>> did you mean" << pre_hint << corrected << post_hint;
761754
if (corrected->file)
762-
msg += "\n>>> defined in: " + toStr(ctx, corrected->file);
755+
msg << "\n>>> defined in: " << corrected->file;
763756
}
764757
}
765758

766759
if (sym.getName().starts_with("_ZTV"))
767-
msg +=
768-
"\n>>> the vtable symbol may be undefined because the class is missing "
769-
"its key function (see https://lld.llvm.org/missingkeyfunction)";
760+
msg << "\n>>> the vtable symbol may be undefined because the class is "
761+
"missing its key function "
762+
"(see https://lld.llvm.org/missingkeyfunction)";
770763
if (ctx.arg.gcSections && ctx.arg.zStartStopGC &&
771764
sym.getName().starts_with("__start_")) {
772-
msg += "\n>>> the encapsulation symbol needs to be retained under "
765+
msg << "\n>>> the encapsulation symbol needs to be retained under "
773766
"--gc-sections properly; consider -z nostart-stop-gc "
774767
"(see https://lld.llvm.org/ELF/start-stop-gc)";
775768
}
776769

777770
if (undef.isWarning)
778-
Warn(ctx) << msg;
771+
Warn(ctx) << msg.str();
779772
else
780-
ctx.e.error(msg, ErrorTag::SymbolNotFound, {sym.getName()});
773+
ctx.e.error(msg.str(), ErrorTag::SymbolNotFound, {sym.getName()});
781774
}
782775

783776
void elf::reportUndefinedSymbols(Ctx &ctx) {

lld/include/lld/Common/ErrorHandler.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#include "lld/Common/LLVM.h"
7272

7373
#include "llvm/ADT/STLExtras.h"
74+
#include "llvm/ADT/SmallString.h"
7475
#include "llvm/Support/Error.h"
7576
#include "llvm/Support/FileOutputBuffer.h"
7677
#include "llvm/Support/raw_ostream.h"
@@ -158,13 +159,14 @@ enum class DiagLevel { None, Log, Msg, Warn, Err, Fatal };
158159
class SyncStream {
159160
ErrorHandler &e;
160161
DiagLevel level;
161-
std::string buf;
162+
llvm::SmallString<0> buf;
162163

163164
public:
164-
mutable llvm::raw_string_ostream os{buf};
165+
mutable llvm::raw_svector_ostream os{buf};
165166
SyncStream(ErrorHandler &e, DiagLevel level) : e(e), level(level) {}
166167
SyncStream(SyncStream &&o) : e(o.e), level(o.level), buf(std::move(o.buf)) {}
167168
~SyncStream();
169+
StringRef str() { return os.str(); }
168170
};
169171

170172
[[noreturn]] void exitLld(int val);

0 commit comments

Comments
 (0)