diff options
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 1 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 202 | ||||
-rw-r--r-- | lib/MC/MCParser/COFFAsmParser.cpp | 298 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 6 |
4 files changed, 457 insertions, 50 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index a3d3a49..0c1f8f0 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -388,6 +388,7 @@ AsmToken AsmLexer::LexToken() { case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1)); case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1)); case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1)); + case '\\': return AsmToken(AsmToken::BackSlash, StringRef(TokStart, 1)); case '=': if (*CurPtr == '=') return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2)); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index d8fd27d..4f55cea 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -27,6 +27,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" @@ -36,15 +37,21 @@ #include <vector> using namespace llvm; +static cl::opt<bool> +FatalAssemblerWarnings("fatal-assembler-warnings", + cl::desc("Consider warnings as error")); + namespace { /// \brief Helper class for tracking macro definitions. struct Macro { StringRef Name; StringRef Body; + std::vector<StringRef> Parameters; public: - Macro(StringRef N, StringRef B) : Name(N), Body(B) {} + Macro(StringRef N, StringRef B, const std::vector<StringRef> &P) : + Name(N), Body(B), Parameters(P) {} }; /// \brief Helper class for storing information about an active macro @@ -64,7 +71,7 @@ struct MacroInstantiation { public: MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, - const std::vector<std::vector<AsmToken> > &A); + MemoryBuffer *I); }; /// \brief The concrete assembly parser instance. @@ -128,7 +135,7 @@ public: virtual MCContext &getContext() { return Ctx; } virtual MCStreamer &getStreamer() { return Out; } - virtual void Warning(SMLoc L, const Twine &Meg); + virtual bool Warning(SMLoc L, const Twine &Meg); virtual bool Error(SMLoc L, const Twine &Msg); const AsmToken &Lex(); @@ -146,6 +153,10 @@ private: bool ParseStatement(); bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M); + bool expandMacro(SmallString<256> &Buf, StringRef Body, + const std::vector<StringRef> &Parameters, + const std::vector<std::vector<AsmToken> > &A, + const SMLoc &L); void HandleMacroExit(); void PrintMacroInstantiations(); @@ -243,6 +254,8 @@ public: AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs"); // CFI directives. + AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>( + ".cfi_sections"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>( ".cfi_startproc"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>( @@ -289,6 +302,7 @@ public: bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc); + bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc); @@ -367,9 +381,12 @@ void AsmParser::PrintMacroInstantiations() { "note"); } -void AsmParser::Warning(SMLoc L, const Twine &Msg) { +bool AsmParser::Warning(SMLoc L, const Twine &Msg) { + if (FatalAssemblerWarnings) + return Error(L, Msg); PrintMessage(L, Msg, "warning"); PrintMacroInstantiations(); + return false; } bool AsmParser::Error(SMLoc L, const Twine &Msg) { @@ -380,7 +397,8 @@ bool AsmParser::Error(SMLoc L, const Twine &Msg) { } bool AsmParser::EnterIncludeFile(const std::string &Filename) { - int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc()); + std::string IncludedFile; + int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); if (NewBuf == -1) return true; @@ -542,7 +560,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { StringRef Identifier; if (ParseIdentifier(Identifier)) - return false; + return true; // This is a symbol reference. std::pair<StringRef, StringRef> Split = Identifier.split('@'); @@ -1126,9 +1144,9 @@ bool AsmParser::ParseStatement() { if (!getTargetParser().ParseDirective(ID)) return false; - Warning(IDLoc, "ignoring directive for now"); + bool retval = Warning(IDLoc, "ignoring directive for now"); EatToEndOfStatement(); - return false; + return retval; } CheckForValidSection(); @@ -1171,27 +1189,33 @@ bool AsmParser::ParseStatement() { return false; } -MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, - const std::vector<std::vector<AsmToken> > &A) - : TheMacro(M), InstantiationLoc(IL), ExitLoc(EL) -{ - // Macro instantiation is lexical, unfortunately. We construct a new buffer - // to hold the macro body with substitutions. - SmallString<256> Buf; +bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body, + const std::vector<StringRef> &Parameters, + const std::vector<std::vector<AsmToken> > &A, + const SMLoc &L) { raw_svector_ostream OS(Buf); + unsigned NParameters = Parameters.size(); + if (NParameters != 0 && NParameters != A.size()) + return Error(L, "Wrong number of arguments"); - StringRef Body = M->Body; while (!Body.empty()) { // Scan for the next substitution. std::size_t End = Body.size(), Pos = 0; for (; Pos != End; ++Pos) { // Check for a substitution or escape. - if (Body[Pos] != '$' || Pos + 1 == End) - continue; - - char Next = Body[Pos + 1]; - if (Next == '$' || Next == 'n' || isdigit(Next)) - break; + if (!NParameters) { + // This macro has no parameters, look for $0, $1, etc. + if (Body[Pos] != '$' || Pos + 1 == End) + continue; + + char Next = Body[Pos + 1]; + if (Next == '$' || Next == 'n' || isdigit(Next)) + break; + } else { + // This macro has parameters, look for \foo, \bar, etc. + if (Body[Pos] == '\\' && Pos + 1 != End) + break; + } } // Add the prefix. @@ -1201,41 +1225,69 @@ MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, if (Pos == End) break; - switch (Body[Pos+1]) { - // $$ => $ - case '$': - OS << '$'; - break; + if (!NParameters) { + switch (Body[Pos+1]) { + // $$ => $ + case '$': + OS << '$'; + break; - // $n => number of arguments - case 'n': - OS << A.size(); - break; + // $n => number of arguments + case 'n': + OS << A.size(); + break; - // $[0-9] => argument - default: { - // Missing arguments are ignored. - unsigned Index = Body[Pos+1] - '0'; - if (Index >= A.size()) + // $[0-9] => argument + default: { + // Missing arguments are ignored. + unsigned Index = Body[Pos+1] - '0'; + if (Index >= A.size()) + break; + + // Otherwise substitute with the token values, with spaces eliminated. + for (std::vector<AsmToken>::const_iterator it = A[Index].begin(), + ie = A[Index].end(); it != ie; ++it) + OS << it->getString(); break; + } + } + Pos += 2; + } else { + unsigned I = Pos + 1; + while (isalnum(Body[I]) && I + 1 != End) + ++I; + + const char *Begin = Body.data() + Pos +1; + StringRef Argument(Begin, I - (Pos +1)); + unsigned Index = 0; + for (; Index < NParameters; ++Index) + if (Parameters[Index] == Argument) + break; + + // FIXME: We should error at the macro definition. + if (Index == NParameters) + return Error(L, "Parameter not found"); - // Otherwise substitute with the token values, with spaces eliminated. for (std::vector<AsmToken>::const_iterator it = A[Index].begin(), ie = A[Index].end(); it != ie; ++it) OS << it->getString(); - break; - } - } + Pos += 1 + Argument.size(); + } // Update the scan point. - Body = Body.substr(Pos + 2); + Body = Body.substr(Pos); } // We include the .endmacro in the buffer as our queue to exit the macro // instantiation. OS << ".endmacro\n"; + return false; +} - Instantiation = MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); +MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, + MemoryBuffer *I) + : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitLoc(EL) +{ } bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, @@ -1272,11 +1324,22 @@ bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, Lex(); } + // Macro instantiation is lexical, unfortunately. We construct a new buffer + // to hold the macro body with substitutions. + SmallString<256> Buf; + StringRef Body = M->Body; + + if (expandMacro(Buf, Body, M->Parameters, MacroArguments, getTok().getLoc())) + return true; + + MemoryBuffer *Instantiation = + MemoryBuffer::getMemBufferCopy(Buf.str(), "<instantiation>"); + // Create the macro instantiation object and add to the current macro // instantiation stack. MacroInstantiation *MI = new MacroInstantiation(M, NameLoc, getTok().getLoc(), - MacroArguments); + Instantiation); ActiveMacros.push_back(MI); // Jump to the macro instantiation and prime the lexer. @@ -2265,6 +2328,39 @@ bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive, return TokError("unsupported directive '" + Directive + "'"); } +/// ParseDirectiveCFISections +/// ::= .cfi_sections section [, section] +bool GenericAsmParser::ParseDirectiveCFISections(StringRef, + SMLoc DirectiveLoc) { + StringRef Name; + bool EH = false; + bool Debug = false; + + if (getParser().ParseIdentifier(Name)) + return TokError("Expected an identifier"); + + if (Name == ".eh_frame") + EH = true; + else if (Name == ".debug_frame") + Debug = true; + + if (getLexer().is(AsmToken::Comma)) { + Lex(); + + if (getParser().ParseIdentifier(Name)) + return TokError("Expected an identifier"); + + if (Name == ".eh_frame") + EH = true; + else if (Name == ".debug_frame") + Debug = true; + } + + getStreamer().EmitCFISections(EH, Debug); + + return false; +} + /// ParseDirectiveCFIStartProc /// ::= .cfi_startproc bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef, @@ -2285,7 +2381,7 @@ bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc) { unsigned RegNo; - if (getLexer().is(AsmToken::Percent)) { + if (getLexer().isNot(AsmToken::Integer)) { if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) return true; @@ -2493,13 +2589,27 @@ bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive, } /// ParseDirectiveMacro -/// ::= .macro name +/// ::= .macro name [parameters] bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, SMLoc DirectiveLoc) { StringRef Name; if (getParser().ParseIdentifier(Name)) return TokError("expected identifier in directive"); + std::vector<StringRef> Parameters; + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for(;;) { + StringRef Parameter; + if (getParser().ParseIdentifier(Parameter)) + return TokError("expected identifier in directive"); + Parameters.push_back(Parameter); + + if (getLexer().isNot(AsmToken::Comma)) + break; + Lex(); + } + } + if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.macro' directive"); @@ -2537,7 +2647,7 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, const char *BodyStart = StartToken.getLoc().getPointer(); const char *BodyEnd = EndToken.getLoc().getPointer(); StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); - getParser().MacroMap[Name] = new Macro(Name, Body); + getParser().MacroMap[Name] = new Macro(Name, Body, Parameters); return false; } diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index 5ecab03..64f6355 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -14,6 +14,9 @@ #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetAsmParser.h" #include "llvm/Support/COFF.h" using namespace llvm; @@ -41,6 +44,34 @@ class COFFAsmParser : public MCAsmParserExtension { AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl"); AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type"); AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef"); + + // Win64 EH directives. + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>( + ".seh_proc"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>( + ".seh_endproc"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>( + ".seh_startchained"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>( + ".seh_endchained"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>( + ".seh_handler"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>( + ".seh_handlerdata"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>( + ".seh_pushreg"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>( + ".seh_setframe"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>( + ".seh_stackalloc"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>( + ".seh_savereg"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>( + ".seh_savexmm"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>( + ".seh_pushframe"); + AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>( + ".seh_endprologue"); } bool ParseSectionDirectiveText(StringRef, SMLoc) { @@ -70,6 +101,23 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseDirectiveType(StringRef, SMLoc); bool ParseDirectiveEndef(StringRef, SMLoc); + // Win64 EH directives. + bool ParseSEHDirectiveStartProc(StringRef, SMLoc); + bool ParseSEHDirectiveEndProc(StringRef, SMLoc); + bool ParseSEHDirectiveStartChained(StringRef, SMLoc); + bool ParseSEHDirectiveEndChained(StringRef, SMLoc); + bool ParseSEHDirectiveHandler(StringRef, SMLoc); + bool ParseSEHDirectiveHandlerData(StringRef, SMLoc); + bool ParseSEHDirectivePushReg(StringRef, SMLoc); + bool ParseSEHDirectiveSetFrame(StringRef, SMLoc); + bool ParseSEHDirectiveAllocStack(StringRef, SMLoc); + bool ParseSEHDirectiveSaveReg(StringRef, SMLoc); + bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc); + bool ParseSEHDirectivePushFrame(StringRef, SMLoc); + bool ParseSEHDirectiveEndProlog(StringRef, SMLoc); + + bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); + bool ParseSEHRegisterNumber(unsigned &RegNo); public: COFFAsmParser() {} }; @@ -135,6 +183,256 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) { return false; } +bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { + StringRef SymbolID; + if (getParser().ParseIdentifier(SymbolID)) + return true; + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); + + Lex(); + getStreamer().EmitWin64EHStartProc(Symbol); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) { + Lex(); + getStreamer().EmitWin64EHEndProc(); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) { + Lex(); + getStreamer().EmitWin64EHStartChained(); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) { + Lex(); + getStreamer().EmitWin64EHEndChained(); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) { + StringRef SymbolID; + if (getParser().ParseIdentifier(SymbolID)) + return true; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("you must specify one or both of @unwind or @except"); + Lex(); + bool unwind = false, except = false; + if (ParseAtUnwindOrAtExcept(unwind, except)) + return true; + if (getLexer().is(AsmToken::Comma)) { + Lex(); + if (ParseAtUnwindOrAtExcept(unwind, except)) + return true; + } + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID); + + Lex(); + getStreamer().EmitWin64EHHandler(handler, unwind, except); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) { + Lex(); + getStreamer().EmitWin64EHHandlerData(); + return false; +} + +bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) { + unsigned Reg; + if (ParseSEHRegisterNumber(Reg)) + return true; + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + Lex(); + getStreamer().EmitWin64EHPushReg(Reg); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) { + unsigned Reg; + int64_t Off; + if (ParseSEHRegisterNumber(Reg)) + return true; + if (getLexer().isNot(AsmToken::Comma)) + return TokError("you must specify a stack pointer offset"); + + Lex(); + SMLoc startLoc = getLexer().getLoc(); + if (getParser().ParseAbsoluteExpression(Off)) + return true; + + if (Off & 0x0F) + return Error(startLoc, "offset is not a multiple of 16"); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + Lex(); + getStreamer().EmitWin64EHSetFrame(Reg, Off); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) { + int64_t Size; + SMLoc startLoc = getLexer().getLoc(); + if (getParser().ParseAbsoluteExpression(Size)) + return true; + + if (Size & 7) + return Error(startLoc, "size is not a multiple of 8"); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + Lex(); + getStreamer().EmitWin64EHAllocStack(Size); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) { + unsigned Reg; + int64_t Off; + if (ParseSEHRegisterNumber(Reg)) + return true; + if (getLexer().isNot(AsmToken::Comma)) + return TokError("you must specify an offset on the stack"); + + Lex(); + SMLoc startLoc = getLexer().getLoc(); + if (getParser().ParseAbsoluteExpression(Off)) + return true; + + if (Off & 7) + return Error(startLoc, "size is not a multiple of 8"); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + Lex(); + // FIXME: Err on %xmm* registers + getStreamer().EmitWin64EHSaveReg(Reg, Off); + return false; +} + +// FIXME: This method is inherently x86-specific. It should really be in the +// x86 backend. +bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) { + unsigned Reg; + int64_t Off; + if (ParseSEHRegisterNumber(Reg)) + return true; + if (getLexer().isNot(AsmToken::Comma)) + return TokError("you must specify an offset on the stack"); + + Lex(); + SMLoc startLoc = getLexer().getLoc(); + if (getParser().ParseAbsoluteExpression(Off)) + return true; + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + if (Off & 0x0F) + return Error(startLoc, "offset is not a multiple of 16"); + + Lex(); + // FIXME: Err on non-%xmm* registers + getStreamer().EmitWin64EHSaveXMM(Reg, Off); + return false; +} + +bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) { + bool Code = false; + StringRef CodeID; + if (getLexer().is(AsmToken::At)) { + SMLoc startLoc = getLexer().getLoc(); + Lex(); + if (!getParser().ParseIdentifier(CodeID)) { + if (CodeID != "code") + return Error(startLoc, "expected @code"); + Code = true; + } + } + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + Lex(); + getStreamer().EmitWin64EHPushFrame(Code); + return false; +} + +bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) { + Lex(); + getStreamer().EmitWin64EHEndProlog(); + return false; +} + +bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { + StringRef identifier; + if (getLexer().isNot(AsmToken::At)) + return TokError("a handler attribute must begin with '@'"); + SMLoc startLoc = getLexer().getLoc(); + Lex(); + if (getParser().ParseIdentifier(identifier)) + return Error(startLoc, "expected @unwind or @except"); + if (identifier == "unwind") + unwind = true; + else if (identifier == "except") + except = true; + else + return Error(startLoc, "expected @unwind or @except"); + return false; +} + +bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) { + SMLoc startLoc = getLexer().getLoc(); + if (getLexer().is(AsmToken::Percent)) { + const TargetAsmInfo &asmInfo = getContext().getTargetAsmInfo(); + SMLoc endLoc; + unsigned LLVMRegNo; + if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc)) + return true; + + // Check that this is a non-volatile register. + const unsigned *NVRegs = asmInfo.getCalleeSavedRegs(); + unsigned i; + for (i = 0; NVRegs[i] != 0; ++i) + if (NVRegs[i] == LLVMRegNo) + break; + if (NVRegs[i] == 0) + return Error(startLoc, "expected non-volatile register"); + + int SEHRegNo = asmInfo.getSEHRegNum(LLVMRegNo); + if (SEHRegNo < 0) + return Error(startLoc,"register can't be represented in SEH unwind info"); + RegNo = SEHRegNo; + } + else { + int64_t n; + if (getParser().ParseAbsoluteExpression(n)) + return true; + if (n > 15) + return Error(startLoc, "register number is too high"); + RegNo = n; + } + + return false; +} + namespace llvm { MCAsmParserExtension *createCOFFAsmParser() { diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 3c092cd..6f45068 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -369,11 +369,9 @@ bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive, // FIXME: If/when .dump and .load are implemented they will be done in the // the assembly parser and not have any need for an MCStreamer API. if (IsDump) - Warning(IDLoc, "ignoring directive .dump for now"); + return Warning(IDLoc, "ignoring directive .dump for now"); else - Warning(IDLoc, "ignoring directive .load for now"); - - return false; + return Warning(IDLoc, "ignoring directive .load for now"); } /// ParseDirectiveLsym |