|
53 | 53 | #include "lld/Common/Memory.h"
|
54 | 54 | #include "lld/Common/Strings.h"
|
55 | 55 | #include "llvm/ADT/SmallSet.h"
|
| 56 | +#include "llvm/Demangle/Demangle.h" |
56 | 57 | #include "llvm/Support/Endian.h"
|
57 | 58 | #include "llvm/Support/raw_ostream.h"
|
58 | 59 | #include <algorithm>
|
@@ -699,7 +700,8 @@ static std::vector<UndefinedDiag> undefs;
|
699 | 700 | // Suggest an alternative spelling of an "undefined symbol" diagnostic. Returns
|
700 | 701 | // the suggested symbol, which is either in the symbol table, or in the same
|
701 | 702 | // file of sym.
|
702 |
| -static const Symbol *getAlternativeSpelling(const Undefined &sym) { |
| 703 | +static const Symbol *getAlternativeSpelling(const Undefined &sym, |
| 704 | + std::string &pre_hint) { |
703 | 705 | // Build a map of local defined symbols.
|
704 | 706 | DenseMap<StringRef, const Symbol *> map;
|
705 | 707 | if (sym.file && !isa<SharedFile>(sym.file)) {
|
@@ -759,6 +761,21 @@ static const Symbol *getAlternativeSpelling(const Undefined &sym) {
|
759 | 761 | return s;
|
760 | 762 | }
|
761 | 763 |
|
| 764 | + // The reference may be a mangled name while the definition is not. Suggest a |
| 765 | + // missing extern "C". |
| 766 | + if (name.startswith("_Z")) { |
| 767 | + llvm::ItaniumPartialDemangler d; |
| 768 | + if (!d.partialDemangle(name.str().c_str())) |
| 769 | + if (char *buf = d.getFunctionName(nullptr, nullptr)) { |
| 770 | + const Symbol *s = suggest(buf); |
| 771 | + free(buf); |
| 772 | + if (s) { |
| 773 | + pre_hint = ": extern \"C\" "; |
| 774 | + return s; |
| 775 | + } |
| 776 | + } |
| 777 | + } |
| 778 | + |
762 | 779 | return nullptr;
|
763 | 780 | }
|
764 | 781 |
|
@@ -804,13 +821,15 @@ static void reportUndefinedSymbol(const UndefinedDiag &undef,
|
804 | 821 | msg += ("\n>>> referenced " + Twine(undef.locs.size() - i) + " more times")
|
805 | 822 | .str();
|
806 | 823 |
|
807 |
| - if (correctSpelling) |
| 824 | + if (correctSpelling) { |
| 825 | + std::string pre_hint = ": "; |
808 | 826 | if (const Symbol *corrected =
|
809 |
| - getAlternativeSpelling(cast<Undefined>(sym))) { |
810 |
| - msg += "\n>>> did you mean: " + toString(*corrected); |
| 827 | + getAlternativeSpelling(cast<Undefined>(sym), pre_hint)) { |
| 828 | + msg += "\n>>> did you mean" + pre_hint + toString(*corrected); |
811 | 829 | if (corrected->file)
|
812 | 830 | msg += "\n>>> defined in: " + toString(corrected->file);
|
813 | 831 | }
|
| 832 | + } |
814 | 833 |
|
815 | 834 | if (sym.getName().startswith("_ZTV"))
|
816 | 835 | msg += "\nthe vtable symbol may be undefined because the class is missing "
|
|
0 commit comments