[lld] r288992 - COFF: Define overloaded toString functions.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 7 15:17:02 PST 2016
Author: ruiu
Date: Wed Dec 7 17:17:02 2016
New Revision: 288992
URL: http://llvm.org/viewvc/llvm-project?rev=288992&view=rev
Log:
COFF: Define overloaded toString functions.
Previously, we had different way to stringize SymbolBody and InputFile
to construct error messages. This patch defines overloaded function
toString() so that we don't need to memorize all these different
function names.
With that change, it is now easy to include demangled names in error
messages. Now, if there is a symbol name conflict, we'll print out
both mangled and demangled names.
Added:
lld/trunk/COFF/Strings.cpp
lld/trunk/COFF/Strings.h
lld/trunk/test/COFF/conflict-mangled.test
- copied, changed from r288982, lld/trunk/test/COFF/conflict.test
Modified:
lld/trunk/COFF/CMakeLists.txt
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/InputFiles.cpp
lld/trunk/COFF/InputFiles.h
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/Symbols.cpp
lld/trunk/COFF/Symbols.h
lld/trunk/test/COFF/conflict.test
Modified: lld/trunk/COFF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/CMakeLists.txt?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/CMakeLists.txt (original)
+++ lld/trunk/COFF/CMakeLists.txt Wed Dec 7 17:17:02 2016
@@ -14,6 +14,7 @@ add_lld_library(lldCOFF
MarkLive.cpp
ModuleDef.cpp
PDB.cpp
+ Strings.cpp
SymbolTable.cpp
Symbols.cpp
Writer.cpp
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Wed Dec 7 17:17:02 2016
@@ -581,7 +581,7 @@ void LinkerDriver::link(llvm::ArrayRef<c
continue;
}
if (Config->Machine != MT)
- fatal(File->getShortName() + ": machine type " + machineToStr(MT) +
+ fatal(toString(File.get()) + ": machine type " + machineToStr(MT) +
" conflicts with " + machineToStr(Config->Machine));
}
if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Wed Dec 7 17:17:02 2016
@@ -45,29 +45,13 @@ namespace coff {
int InputFile::NextIndex = 0;
llvm::LLVMContext BitcodeFile::Context;
-
-// Returns the last element of a path, which is supposed to be a filename.
-static StringRef getBasename(StringRef Path) {
- size_t Pos = Path.find_last_of("\\/");
- if (Pos == StringRef::npos)
- return Path;
- return Path.substr(Pos + 1);
-}
-
-// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
-std::string InputFile::getShortName() {
- if (ParentName == "")
- return getName().lower();
- std::string Res = (getBasename(ParentName) + "(" +
- getBasename(getName()) + ")").str();
- return StringRef(Res).lower();
-}
+std::mutex BitcodeFile::Mu;
ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
void ArchiveFile::parse() {
// Parse a MemoryBufferRef as an archive file.
- File = check(Archive::create(MB), getShortName());
+ File = check(Archive::create(MB), toString(this));
// Allocate a buffer for Lazy objects.
size_t NumSyms = File->getNumberOfSymbols();
@@ -84,7 +68,7 @@ void ArchiveFile::parse() {
for (auto &Child : File->children(Err))
Seen[Child.getChildOffset()].clear();
if (Err)
- fatal(Err, getShortName());
+ fatal(Err, toString(this));
}
// Returns a buffer pointing to a member file containing a given symbol.
@@ -113,14 +97,13 @@ MutableArrayRef<Lazy> ArchiveFile::getLa
void ObjectFile::parse() {
// Parse a memory buffer as a COFF file.
- std::unique_ptr<Binary> Bin =
- check(createBinary(MB), getShortName());
+ std::unique_ptr<Binary> Bin = check(createBinary(MB), toString(this));
if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
Bin.release();
COFFObj.reset(Obj);
} else {
- fatal(getShortName() + " is not a COFF file");
+ fatal(toString(this) + " is not a COFF file");
}
// Read section and symbol tables.
@@ -189,7 +172,7 @@ void ObjectFile::initializeSymbols() {
for (uint32_t I = 0; I < NumSymbols; ++I) {
// Get a COFFSymbolRef object.
COFFSymbolRef Sym =
- check(COFFObj->getSymbol(I), "broken object file: " + getShortName());
+ check(COFFObj->getSymbol(I), "broken object file: " + toString(this));
const void *AuxP = nullptr;
if (Sym.getNumberOfAuxSymbols())
@@ -251,12 +234,12 @@ Defined *ObjectFile::createDefined(COFFS
// Reserved sections numbers don't have contents.
if (llvm::COFF::isReservedSectionNumber(SectionNumber))
- fatal("broken object file: " + getShortName());
+ fatal("broken object file: " + toString(this));
// This symbol references a section which is not present in the section
// header.
if ((uint32_t)SectionNumber >= SparseChunks.size())
- fatal("broken object file: " + getShortName());
+ fatal("broken object file: " + toString(this));
// Nothing else to do without a section chunk.
auto *SC = cast_or_null<SectionChunk>(SparseChunks[SectionNumber]);
@@ -395,7 +378,26 @@ MachineTypes BitcodeFile::getMachineType
}
}
-std::mutex BitcodeFile::Mu;
+// Returns the last element of a path, which is supposed to be a filename.
+static StringRef getBasename(StringRef Path) {
+ size_t Pos = Path.find_last_of("\\/");
+ if (Pos == StringRef::npos)
+ return Path;
+ return Path.substr(Pos + 1);
+}
+
+// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
+std::string toString(InputFile *File) {
+ if (!File)
+ return "(internal)";
+ if (File->ParentName.empty())
+ return File->getName().lower();
+
+ std::string Res =
+ (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + ")")
+ .str();
+ return StringRef(Res).lower();
+}
} // namespace coff
} // namespace lld
Modified: lld/trunk/COFF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.h?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.h (original)
+++ lld/trunk/COFF/InputFiles.h Wed Dec 7 17:17:02 2016
@@ -61,13 +61,8 @@ public:
// Returns the CPU type this file was compiled to.
virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; }
- // Returns a short, human-friendly filename. If this is a member of
- // an archive file, a returned value includes parent's filename.
- // Used for logging or debugging.
- std::string getShortName();
-
- // Sets a parent filename if this file is created from an archive.
- void setParentName(StringRef N) { ParentName = N; }
+ // An archive file name if this file is created from an archive.
+ StringRef ParentName;
// Returns .drectve section contents if exist.
StringRef getDirectives() { return StringRef(Directives).trim(); }
@@ -86,7 +81,6 @@ protected:
private:
const Kind FileKind;
- StringRef ParentName;
};
// .lib or .a file.
@@ -222,6 +216,8 @@ private:
static std::mutex Mu;
};
+std::string toString(InputFile *File);
+
} // namespace coff
} // namespace lld
Added: lld/trunk/COFF/Strings.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Strings.cpp?rev=288992&view=auto
==============================================================================
--- lld/trunk/COFF/Strings.cpp (added)
+++ lld/trunk/COFF/Strings.cpp Wed Dec 7 17:17:02 2016
@@ -0,0 +1,30 @@
+//===- Strings.cpp -------------------------------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Strings.h"
+
+#if defined(_MSC_VER)
+#include <DbgHelp.h>
+#include <Windows.h>
+#pragma comment(lib, "dbghelp.lib")
+#endif
+
+using namespace lld;
+using namespace lld::coff;
+using namespace llvm;
+
+Optional<std::string> coff::demangle(StringRef S) {
+#if defined(_MSC_VER)
+ char Buf[4096];
+ if (S.startswith("?"))
+ if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))
+ return std::string(Buf, Len);
+#endif
+ return None;
+}
Added: lld/trunk/COFF/Strings.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Strings.h?rev=288992&view=auto
==============================================================================
--- lld/trunk/COFF/Strings.h (added)
+++ lld/trunk/COFF/Strings.h Wed Dec 7 17:17:02 2016
@@ -0,0 +1,23 @@
+//===- Strings.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_COFF_STRINGS_H
+#define LLD_COFF_STRINGS_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace lld {
+namespace coff {
+llvm::Optional<std::string> demangle(llvm::StringRef S);
+}
+}
+
+#endif
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Dec 7 17:17:02 2016
@@ -71,7 +71,7 @@ void SymbolTable::readArchives() {
for (std::future<ArchiveFile *> &Future : ArchiveQueue) {
ArchiveFile *File = Future.get();
if (Config->Verbose)
- llvm::outs() << "Reading " << File->getShortName() << "\n";
+ llvm::outs() << "Reading " << toString(File) << "\n";
for (Lazy &Sym : File->getLazySymbols())
addLazy(&Sym, &LazySyms);
}
@@ -92,7 +92,7 @@ void SymbolTable::readObjects() {
for (size_t I = 0; I < ObjectQueue.size(); ++I) {
InputFile *File = ObjectQueue[I].get();
if (Config->Verbose)
- llvm::outs() << "Reading " << File->getShortName() << "\n";
+ llvm::outs() << "Reading " << toString(File) << "\n";
// Adding symbols may add more files to ObjectQueue
// (but not to ArchiveQueue).
for (SymbolBody *Sym : File->getSymbols())
@@ -102,8 +102,7 @@ void SymbolTable::readObjects() {
if (!S.empty()) {
Directives.push_back(S);
if (Config->Verbose)
- llvm::outs() << "Directives: " << File->getShortName()
- << ": " << S << "\n";
+ llvm::outs() << "Directives: " << toString(File) << ": " << S << "\n";
}
}
ObjectQueue.clear();
@@ -161,8 +160,8 @@ void SymbolTable::reportRemainingUndefin
if (!isa<ArchiveFile>(File.get()))
for (SymbolBody *Sym : File->getSymbols())
if (Undefs.count(Sym->repl()))
- llvm::errs() << File->getShortName() << ": undefined symbol: "
- << Sym->getName() << "\n";
+ llvm::errs() << toString(File.get())
+ << ": undefined symbol: " << Sym->getName() << "\n";
if (!Config->Force)
fatal("link failed");
}
@@ -211,8 +210,9 @@ void SymbolTable::addSymbol(SymbolBody *
// equivalent (conflicting), or more preferable, respectively.
int Comp = Existing->compare(New);
if (Comp == 0)
- fatal("duplicate symbol: " + Existing->getDebugName() + " and " +
- New->getDebugName());
+ fatal("duplicate symbol: " + toString(*Existing) + " in " +
+ toString(Existing->getFile()) + " and in " +
+ toString(New->getFile()));
if (Comp < 0)
Sym->Body = New;
}
@@ -237,7 +237,7 @@ void SymbolTable::addMemberFile(Lazy *Bo
if (!File)
return;
if (Config->Verbose)
- llvm::outs() << "Loaded " << File->getShortName() << " for "
+ llvm::outs() << "Loaded " << toString(File.get()) << " for "
<< Body->getName() << "\n";
addFile(std::move(File));
}
@@ -321,7 +321,7 @@ DefinedAbsolute *SymbolTable::addAbsolut
void SymbolTable::printMap(llvm::raw_ostream &OS) {
for (ObjectFile *File : ObjectFiles) {
- OS << File->getShortName() << ":\n";
+ OS << toString(File) << ":\n";
for (SymbolBody *Body : File->getSymbols())
if (auto *R = dyn_cast<DefinedRegular>(Body))
if (R->getChunk()->isLive())
Modified: lld/trunk/COFF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.cpp?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.cpp (original)
+++ lld/trunk/COFF/Symbols.cpp Wed Dec 7 17:17:02 2016
@@ -7,13 +7,15 @@
//
//===----------------------------------------------------------------------===//
+#include "Symbols.h"
#include "Error.h"
#include "InputFiles.h"
-#include "Symbols.h"
+#include "Strings.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
using namespace llvm::object;
using llvm::sys::fs::identify_magic;
using llvm::sys::fs::file_magic;
@@ -36,6 +38,16 @@ StringRef SymbolBody::getName() {
return Name;
}
+InputFile *SymbolBody::getFile() {
+ if (auto *Sym = dyn_cast<DefinedCOFF>(this))
+ return Sym->File;
+ if (auto *Sym = dyn_cast<DefinedBitcode>(this))
+ return Sym->File;
+ if (auto *Sym = dyn_cast<Lazy>(this))
+ return Sym->File;
+ return nullptr;
+}
+
// Returns 1, 0 or -1 if this symbol should take precedence
// over the Other, tie or lose, respectively.
int SymbolBody::compare(SymbolBody *Other) {
@@ -150,18 +162,6 @@ int SymbolBody::compare(SymbolBody *Othe
llvm_unreachable("unknown symbol kind");
}
-std::string SymbolBody::getDebugName() {
- std::string N = getName().str();
- if (auto *D = dyn_cast<DefinedCOFF>(this)) {
- N += " ";
- N += D->File->getShortName();
- } else if (auto *D = dyn_cast<DefinedBitcode>(this)) {
- N += " ";
- N += D->File->getShortName();
- }
- return N;
-}
-
COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
size_t SymSize = File->getCOFFObj()->getSymbolTableEntrySize();
if (SymSize == sizeof(coff_symbol16))
@@ -201,7 +201,7 @@ std::unique_ptr<InputFile> Lazy::getMemb
else
fatal("unknown file type: " + File->getName());
- Obj->setParentName(File->getName());
+ Obj->ParentName = File->getName();
return Obj;
}
@@ -213,5 +213,12 @@ Defined *Undefined::getWeakAlias() {
return nullptr;
}
+// Returns a symbol name for an error message.
+std::string toString(SymbolBody &B) {
+ if (Optional<std::string> S = demangle(B.getName()))
+ return ("\"" + *S + "\" (" + B.getName() + ")").str();
+ return B.getName();
+}
+
} // namespace coff
} // namespace lld
Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Wed Dec 7 17:17:02 2016
@@ -75,6 +75,9 @@ public:
// Returns the symbol name.
StringRef getName();
+ // Returns the file from which this symbol was created.
+ InputFile *getFile();
+
// A SymbolBody has a backreference to a Symbol. Originally they are
// doubly-linked. A backreference will never change. But the pointer
// in the Symbol may be mutated by the resolver. If you have a
@@ -89,10 +92,6 @@ public:
// they are duplicate (conflicting) symbols.
int compare(SymbolBody *Other);
- // Returns a name of this symbol including source file name.
- // Used only for debugging and logging.
- std::string getDebugName();
-
protected:
explicit SymbolBody(Kind K, StringRef N = "")
: SymbolKind(K), IsExternal(true), IsCOMDAT(false),
@@ -149,12 +148,14 @@ public:
return S->kind() <= LastDefinedCOFFKind;
}
+ ObjectFile *getFile() { return File; }
int getFileIndex() { return File->Index; }
COFFSymbolRef getCOFFSymbol();
-protected:
ObjectFile *File;
+
+protected:
const coff_symbol_generic *Sym;
};
@@ -259,8 +260,9 @@ public:
int getFileIndex() { return File->Index; }
-private:
ArchiveFile *File;
+
+private:
const Archive::Symbol Sym;
};
@@ -368,7 +370,6 @@ public:
return S->kind() == DefinedBitcodeKind;
}
-private:
BitcodeFile *File;
};
@@ -397,6 +398,8 @@ inline uint64_t Defined::getRVA() {
llvm_unreachable("unknown symbol kind");
}
+std::string toString(SymbolBody &B);
+
} // namespace coff
} // namespace lld
Copied: lld/trunk/test/COFF/conflict-mangled.test (from r288982, lld/trunk/test/COFF/conflict.test)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/conflict-mangled.test?p2=lld/trunk/test/COFF/conflict-mangled.test&p1=lld/trunk/test/COFF/conflict.test&r1=288982&r2=288992&rev=288992&view=diff
==============================================================================
--- lld/trunk/test/COFF/conflict.test (original)
+++ lld/trunk/test/COFF/conflict-mangled.test Wed Dec 7 17:17:02 2016
@@ -1,14 +1,10 @@
+# REQUIRES: system-windows
# RUN: yaml2obj < %s > %t1.obj
# RUN: yaml2obj < %s > %t2.obj
# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log
# RUN: FileCheck %s < %t.log
-# RUN: llvm-as -o %t.lto1.obj %S/Inputs/conflict.ll
-# RUN: llvm-as -o %t.lto2.obj %S/Inputs/conflict.ll
-# RUN: not lld-link /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log
-# RUN: FileCheck %s < %t.log
-
-# CHECK: duplicate symbol: foo {{.+}}1.obj and foo {{.+}}2.obj
+# CHECK: duplicate symbol: "int __cdecl mangled(void)" (?mangled@@YAHXZ) in {{.+}}1.obj and in {{.+}}2.obj
--- !COFF
header:
@@ -32,7 +28,7 @@ symbols:
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- - Name: foo
+ - Name: '?mangled@@YAHXZ'
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
Modified: lld/trunk/test/COFF/conflict.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/conflict.test?rev=288992&r1=288991&r2=288992&view=diff
==============================================================================
--- lld/trunk/test/COFF/conflict.test (original)
+++ lld/trunk/test/COFF/conflict.test Wed Dec 7 17:17:02 2016
@@ -8,7 +8,7 @@
# RUN: not lld-link /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log
# RUN: FileCheck %s < %t.log
-# CHECK: duplicate symbol: foo {{.+}}1.obj and foo {{.+}}2.obj
+# CHECK: duplicate symbol: foo in {{.+}}1.obj and in {{.+}}2.obj
--- !COFF
header:
More information about the llvm-commits
mailing list