mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
llvm-mc: Support reassignment of variables in one special case, when the
variable has not yet been used in an expression. This allows us to support a few cases that show up in real code (mostly because gcc generates it for Objective-C on Darwin), without giving up a reasonable semantic model for assignment. llvm-svn: 103950
This commit is contained in:
parent
c07fd51d56
commit
8f5da3624f
@ -52,10 +52,15 @@ namespace llvm {
|
||||
/// "Lfoo" or ".foo".
|
||||
unsigned IsTemporary : 1;
|
||||
|
||||
/// IsUsedInExpr - True if this symbol has been used in an expression and
|
||||
/// cannot be redefined.
|
||||
unsigned IsUsedInExpr : 1;
|
||||
|
||||
private: // MCContext creates and uniques these.
|
||||
friend class MCContext;
|
||||
MCSymbol(StringRef name, bool isTemporary)
|
||||
: Name(name), Section(0), Value(0), IsTemporary(isTemporary) {}
|
||||
: Name(name), Section(0), Value(0),
|
||||
IsTemporary(isTemporary), IsUsedInExpr(false) {}
|
||||
|
||||
MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
|
||||
void operator=(const MCSymbol&); // DO NOT IMPLEMENT
|
||||
@ -63,13 +68,15 @@ namespace llvm {
|
||||
/// getName - Get the symbol name.
|
||||
StringRef getName() const { return Name; }
|
||||
|
||||
/// @name Symbol Type
|
||||
/// @name Accessors
|
||||
/// @{
|
||||
|
||||
/// isTemporary - Check if this is an assembler temporary symbol.
|
||||
bool isTemporary() const {
|
||||
return IsTemporary;
|
||||
}
|
||||
bool isTemporary() const { return IsTemporary; }
|
||||
|
||||
/// isUsedInExpr - Check if this is an assembler temporary symbol.
|
||||
bool isUsedInExpr() const { return IsUsedInExpr; }
|
||||
void setUsedInExpr(bool Value) { IsUsedInExpr = Value; }
|
||||
|
||||
/// @}
|
||||
/// @name Associated Sections
|
||||
|
@ -189,6 +189,9 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
|
||||
std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
|
||||
MCSymbol *Sym = CreateSymbol(Split.first);
|
||||
|
||||
// Mark the symbol as used in an expression.
|
||||
Sym->setUsedInExpr(true);
|
||||
|
||||
// Lookup the symbol variant if used.
|
||||
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
|
||||
if (Split.first.size() != getTok().getIdentifier().size())
|
||||
@ -788,7 +791,9 @@ bool AsmParser::ParseAssignment(const StringRef &Name) {
|
||||
//
|
||||
// FIXME: Diagnostics. Note the location of the definition as a label.
|
||||
// FIXME: Diagnose assignment to protected identifier (e.g., register name).
|
||||
if (!Sym->isUndefined() && !Sym->isAbsolute())
|
||||
if (Sym->isUndefined() && !Sym->isUsedInExpr())
|
||||
; // Allow redefinitions of undefined symbols only used in directives.
|
||||
else if (!Sym->isUndefined() && !Sym->isAbsolute())
|
||||
return Error(EqualLoc, "redefinition of '" + Name + "'");
|
||||
else if (!Sym->isVariable())
|
||||
return Error(EqualLoc, "invalid assignment to '" + Name + "'");
|
||||
@ -800,6 +805,8 @@ bool AsmParser::ParseAssignment(const StringRef &Name) {
|
||||
|
||||
// FIXME: Handle '.'.
|
||||
|
||||
Sym->setUsedInExpr(true);
|
||||
|
||||
// Do the assignment.
|
||||
Out.EmitAssignment(Sym, Value);
|
||||
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
# CHECK: TEST0:
|
||||
# CHECK: a = 0
|
||||
TEST0:
|
||||
TEST0:
|
||||
a = 0
|
||||
|
||||
|
||||
# CHECK: .globl _f1
|
||||
# CHECK: _f1 = 0
|
||||
.globl _f1
|
||||
_f1 = 0
|
||||
|
Loading…
Reference in New Issue
Block a user