aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/MCParser/AsmParser.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2012-03-05 14:40:54 -0800
committerStephen Hines <srhines@google.com>2012-03-05 14:40:54 -0800
commitc02a5c5e8d9c1fd2a20ad4aed40f328564e95b40 (patch)
tree9a892d465bc8a229322b6c296c346250a95ecd6c /lib/MC/MCParser/AsmParser.cpp
parent2987cbcdaef9e14f635b6f9ac32c58ff26a2fc0f (diff)
parentc3384c93c0e4c50da4ad093f08997507f9281c75 (diff)
downloadexternal_llvm-c02a5c5e8d9c1fd2a20ad4aed40f328564e95b40.zip
external_llvm-c02a5c5e8d9c1fd2a20ad4aed40f328564e95b40.tar.gz
external_llvm-c02a5c5e8d9c1fd2a20ad4aed40f328564e95b40.tar.bz2
Merge branch 'upstream' into merge-20120305
Conflicts: lib/Support/Atomic.cpp Change-Id: I563b3bc2a82942ccbae5bed42e53b9149a8bf3a0
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp132
1 files changed, 107 insertions, 25 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index aac020d..bd5956f 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -30,6 +30,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
@@ -122,6 +123,9 @@ private:
int64_t CppHashLineNumber;
SMLoc CppHashLoc;
+ /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
+ unsigned AssemblerDialect;
+
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI);
@@ -143,6 +147,15 @@ public:
virtual MCAsmLexer &getLexer() { return Lexer; }
virtual MCContext &getContext() { return Ctx; }
virtual MCStreamer &getStreamer() { return Out; }
+ virtual unsigned getAssemblerDialect() {
+ if (AssemblerDialect == ~0U)
+ return MAI.getAssemblerDialect();
+ else
+ return AssemblerDialect;
+ }
+ virtual void setAssemblerDialect(unsigned i) {
+ AssemblerDialect = i;
+ }
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
@@ -301,6 +314,12 @@ public:
&GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
AddDirectiveHandler<
&GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape");
+ AddDirectiveHandler<
+ &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame");
// Macro directives.
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
@@ -334,6 +353,9 @@ public:
bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc);
+ bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
@@ -358,7 +380,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
MCStreamer &_Out, const MCAsmInfo &_MAI)
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
GenericParser(new GenericAsmParser), PlatformParser(0),
- CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0) {
+ CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
+ AssemblerDialect(~0U) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -782,8 +805,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
}
}
- assert(0 && "Invalid expression kind!");
- return 0;
+ llvm_unreachable("Invalid expression kind!");
}
/// ParseExpression - Parse an expression and return it.
@@ -820,7 +842,6 @@ bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
if (!ModifiedRes) {
return TokError("invalid modifier '" + getTok().getIdentifier() +
"' (no symbols present)");
- return true;
}
Res = ModifiedRes;
@@ -1070,10 +1091,10 @@ bool AsmParser::ParseStatement() {
Out.EmitLabel(Sym);
// If we are generating dwarf for assembly source files then gather the
- // info to make a dwarf subprogram entry for this label if needed.
+ // info to make a dwarf label entry for this label if needed.
if (getContext().getGenDwarfForAssembly())
- MCGenDwarfSubprogramEntry::Make(Sym, &getStreamer(), getSourceManager(),
- IDLoc);
+ MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
+ IDLoc);
// Consume any end of statement token, if present, to avoid spurious
// AddBlankLine calls().
@@ -1544,23 +1565,27 @@ void AsmParser::HandleMacroExit() {
ActiveMacros.pop_back();
}
-static void MarkUsed(const MCExpr *Value) {
+static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
switch (Value->getKind()) {
- case MCExpr::Binary:
- MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getLHS());
- MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getRHS());
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value);
+ return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS());
break;
+ }
case MCExpr::Target:
case MCExpr::Constant:
- break;
+ return false;
case MCExpr::SymbolRef: {
- static_cast<const MCSymbolRefExpr*>(Value)->getSymbol().setUsed(true);
- break;
+ const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol();
+ if (S.isVariable())
+ return IsUsedIn(Sym, S.getVariableValue());
+ return &S == Sym;
}
case MCExpr::Unary:
- MarkUsed(static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
- break;
+ return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
}
+
+ llvm_unreachable("Unknown expr kind!");
}
bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
@@ -1571,7 +1596,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
if (ParseExpression(Value))
return true;
- MarkUsed(Value);
+ // Note: we don't count b as used in "a = b". This is to allow
+ // a = b
+ // b = c
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in assignment");
@@ -1593,7 +1620,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
//
// 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->isUsed() && !Sym->isVariable())
+ if (IsUsedIn(Sym, Value))
+ return Error(EqualLoc, "Recursive use of '" + Name + "'");
+ else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
; // Allow redefinitions of undefined symbols only used in directives.
else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
return Error(EqualLoc, "redefinition of '" + Name + "'");
@@ -1961,6 +1990,7 @@ bool AsmParser::ParseDirectiveOrg() {
CheckForValidSection();
const MCExpr *Offset;
+ SMLoc Loc = getTok().getLoc();
if (ParseExpression(Offset))
return true;
@@ -1980,9 +2010,11 @@ bool AsmParser::ParseDirectiveOrg() {
Lex();
- // FIXME: Only limited forms of relocatable expressions are accepted here, it
- // has to be relative to the current section.
- getStreamer().EmitValueToOffset(Offset, FillExpr);
+ // Only limited forms of relocatable expressions are accepted here, it
+ // has to be relative to the current section. The streamer will return
+ // 'true' if the expression wasn't evaluatable.
+ if (getStreamer().EmitValueToOffset(Offset, FillExpr))
+ return Error(Loc, "expected assembly-time absolute expression");
return false;
}
@@ -2417,13 +2449,13 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.file' directive");
- if (getContext().getGenDwarfForAssembly() == true)
- Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
- "used to generate dwarf debug info for assembly code");
-
if (FileNumber == -1)
getStreamer().EmitFileDirective(Filename);
else {
+ if (getContext().getGenDwarfForAssembly() == true)
+ Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
+ "used to generate dwarf debug info for assembly code");
+
if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename))
Error(FileNumberLoc, "file number already allocated");
}
@@ -2812,6 +2844,56 @@ bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal,
return false;
}
+/// ParseDirectiveCFIRestore
+/// ::= .cfi_restore register
+bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ int64_t Register = 0;
+ if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ getStreamer().EmitCFIRestore(Register);
+
+ return false;
+}
+
+/// ParseDirectiveCFIEscape
+/// ::= .cfi_escape expression[,...]
+bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
+ SMLoc DirectiveLoc) {
+ std::string Values;
+ int64_t CurrValue;
+ if (getParser().ParseAbsoluteExpression(CurrValue))
+ return true;
+
+ Values.push_back((uint8_t)CurrValue);
+
+ while (getLexer().is(AsmToken::Comma)) {
+ Lex();
+
+ if (getParser().ParseAbsoluteExpression(CurrValue))
+ return true;
+
+ Values.push_back((uint8_t)CurrValue);
+ }
+
+ getStreamer().EmitCFIEscape(Values);
+ return false;
+}
+
+/// ParseDirectiveCFISignalFrame
+/// ::= .cfi_signal_frame
+bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive,
+ SMLoc DirectiveLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token in '" + Directive + "' directive");
+
+ getStreamer().EmitCFISignalFrame();
+
+ return false;
+}
+
/// ParseDirectiveMacrosOnOff
/// ::= .macros_on
/// ::= .macros_off