Rename temporary symbols if they conflict with artificial symbols created

by the assembler. This was blocking parsing any large .s produced by clang for
example.

Fixes PR8596.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120603 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2010-12-01 20:46:11 +00:00
parent 871498e2ce
commit 9f44724be0
3 changed files with 52 additions and 10 deletions

View File

@ -45,6 +45,10 @@ namespace llvm {
/// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*> Symbols;
/// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols.
StringMap<bool> UsedNames;
/// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
/// symbol.
unsigned NextUniqueID;
@ -91,6 +95,9 @@ namespace llvm {
BumpPtrAllocator Allocator;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
MCSymbol *CreateSymbol(StringRef Name);
public:
explicit MCContext(const MCAsmInfo &MAI);
~MCContext();

View File

@ -57,19 +57,41 @@ MCContext::~MCContext() {
MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
assert(!Name.empty() && "Normal symbols cannot be unnamed!");
// Determine whether this is an assembler temporary or normal label.
bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
// Do the lookup and get the entire StringMapEntry. We want access to the
// key if we are creating the entry.
StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
if (Entry.getValue()) return Entry.getValue();
MCSymbol *Sym = Entry.getValue();
if (Sym)
return Sym;
Sym = CreateSymbol(Name);
Entry.setValue(Sym);
return Sym;
}
MCSymbol *MCContext::CreateSymbol(StringRef Name) {
// Determine whether this is an assembler temporary or normal label.
bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
if (NameEntry->getValue()) {
assert(isTemporary && "Cannot rename non temporary symbols");
SmallString<128> NewName;
do {
Twine T = Name + Twine(NextUniqueID++);
T.toVector(NewName);
StringRef foo = NewName;
NameEntry = &UsedNames.GetOrCreateValue(foo);
} while (NameEntry->getValue());
}
NameEntry->setValue(true);
// Ok, the entry doesn't already exist. Have the MCSymbol object itself refer
// to the copy of the string that is embedded in the StringMapEntry.
MCSymbol *Result = new (*this) MCSymbol(Entry.getKey(), isTemporary);
Entry.setValue(Result);
return Result;
// to the copy of the string that is embedded in the UsedNames entry.
MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary);
return Result;
}
MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
@ -79,8 +101,11 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
}
MCSymbol *MCContext::CreateTempSymbol() {
return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
"tmp" + Twine(NextUniqueID++));
SmallString<128> NameSV;
Twine Name = Twine(MAI.getPrivateGlobalPrefix()) + "tmp" +
Twine(NextUniqueID++);
Name.toVector(NameSV);
return CreateSymbol(NameSV);
}
unsigned MCContext::NextInstance(int64_t LocalLabelVal) {

View File

@ -0,0 +1,10 @@
// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
.size bar, . - bar
.Ltmp0:
.size foo, .Ltmp0 - foo
// CHECK: .Ltmp0:
// CHECK: .size bar, .Ltmp0-bar
// CHECK: .Ltmp01
// CHECK: .size foo, .Ltmp01-foo