PECOFF: allow more than one /alternatename for the same symbol.

Previously we have a string -> string map to keep the weak alias
symbol mapping. Naturally we can't define more than one weak alias
with that data structure.

This patch is to allow multiple aliases for the same symbol by
changing the map type to string -> set of string map.

llvm-svn: 230702
This commit is contained in:
Rui Ueyama 2015-02-26 23:43:04 +00:00
parent 17512a95ae
commit 53a93c6c39
5 changed files with 22 additions and 27 deletions

View File

@ -257,11 +257,13 @@ public:
bool addSectionRenaming(raw_ostream &diagnostics,
StringRef from, StringRef to);
StringRef getAlternateName(StringRef def) const;
const std::map<std::string, std::string> &alternateNames() {
return _alternateNames;
const std::set<std::string> &getAlternateNames(StringRef name) {
return _alternateNames[name];
}
void addAlternateName(StringRef weak, StringRef def) {
_alternateNames[def].insert(weak);
}
void setAlternateName(StringRef def, StringRef weak);
void addNoDefaultLib(StringRef path) {
if (path.endswith_lower(".lib"))
@ -423,7 +425,7 @@ private:
std::unique_ptr<Writer> _writer;
// A map for weak aliases.
std::map<std::string, std::string> _alternateNames;
std::map<std::string, std::set<std::string>> _alternateNames;
// A map for section renaming. For example, if there is an entry in the map
// whose value is .rdata -> .text, the section contens of .rdata will be

View File

@ -954,7 +954,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
StringRef weak, def;
if (!parseAlternateName(arg->getValue(), weak, def, diag))
return false;
ctx.setAlternateName(weak, def);
ctx.addAlternateName(weak, def);
}
// Parse /base command line option. The argument for the parameter is in

View File

@ -215,17 +215,6 @@ bool PECOFFLinkingContext::addSectionRenaming(raw_ostream &diagnostics,
return true;
}
StringRef PECOFFLinkingContext::getAlternateName(StringRef def) const {
auto it = _alternateNames.find(def);
if (it == _alternateNames.end())
return "";
return it->second;
}
void PECOFFLinkingContext::setAlternateName(StringRef weak, StringRef def) {
_alternateNames[def] = weak;
}
/// Try to find the input library file from the search paths and append it to
/// the input file list. Returns true if the library file is found.
StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const {

View File

@ -112,7 +112,7 @@ public:
_undefinedAtoms._atoms.push_back(new (_alloc) COFFUndefinedAtom(*this, sym));
}
AliasAtom *createAlias(StringRef name, const DefinedAtom *target);
AliasAtom *createAlias(StringRef name, const DefinedAtom *target, int cnt);
void createAlternateNameAtoms();
std::error_code parseDirectiveSection(
StringRef directives, std::set<StringRef> *undefinedSymbols);
@ -860,24 +860,24 @@ std::error_code FileCOFF::getSectionContents(StringRef sectionName,
return std::error_code();
}
AliasAtom *FileCOFF::createAlias(StringRef name,
const DefinedAtom *target) {
AliasAtom *
FileCOFF::createAlias(StringRef name, const DefinedAtom *target, int cnt) {
AliasAtom *alias = new (_alloc) AliasAtom(*this, name);
alias->addReference(Reference::KindNamespace::all, Reference::KindArch::all,
Reference::kindLayoutAfter, 0, target, 0);
alias->setMerge(DefinedAtom::mergeAsWeak);
if (target->contentType() == DefinedAtom::typeCode)
alias->setDeadStrip(DefinedAtom::deadStripNever);
alias->setOrdinal(target->ordinal() - 1);
alias->setOrdinal(target->ordinal() - cnt);
return alias;
}
void FileCOFF::createAlternateNameAtoms() {
std::vector<AliasAtom *> aliases;
for (const DefinedAtom *atom : defined()) {
auto it = _ctx.alternateNames().find(atom->name());
if (it != _ctx.alternateNames().end())
aliases.push_back(createAlias(it->second, atom));
int cnt = 1;
for (StringRef alias : _ctx.getAlternateNames(atom->name()))
aliases.push_back(createAlias(alias, atom, cnt++));
}
for (AliasAtom *alias : aliases)
_definedAtoms._atoms.push_back(alias);

View File

@ -149,9 +149,13 @@ TEST_F(WinLinkParserTest, InputOrder) {
//
TEST_F(WinLinkParserTest, AlternateName) {
EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym2", "a.out", nullptr));
EXPECT_EQ("sym1", _ctx.getAlternateName("sym2"));
EXPECT_EQ("", _ctx.getAlternateName("foo"));
EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym",
"/alternatename:sym2=sym", "a.out", nullptr));
const std::set<std::string> &aliases = _ctx.getAlternateNames("sym");
EXPECT_EQ(2U, aliases.size());
auto it = aliases.begin();
EXPECT_EQ("sym1", *it++);
EXPECT_EQ("sym2", *it++);
}
TEST_F(WinLinkParserTest, Export) {