Index: include/llvm/MC/MCParser/AsmLexer.h =================================================================== --- include/llvm/MC/MCParser/AsmLexer.h +++ include/llvm/MC/MCParser/AsmLexer.h @@ -36,7 +36,7 @@ protected: /// LexToken - Read the next token and return its code. - AsmToken LexToken() override; + AsmToken LexToken(bool AltMacroMode = false) override; public: AsmLexer(const MCAsmInfo &MAI); @@ -55,6 +55,7 @@ const MCAsmInfo &getMAI() const { return MAI; } private: + bool isAtString(const char* stringLine); int getNextChar(); AsmToken ReturnError(const char *Loc, const std::string &Msg); @@ -62,8 +63,10 @@ AsmToken LexSlash(); AsmToken LexLineComment(); AsmToken LexDigit(); - AsmToken LexSingleQuote(); - AsmToken LexQuote(); + AsmToken LexSingleQuote(bool AltMacroMode = false); + AsmToken LexAltMacro(char FirstChar); + AsmToken LexQuote(char FirstChar = '"'); + AsmToken LexStringHandel(char FirstChar = '"'); AsmToken LexFloatLiteral(); AsmToken LexHexFloatLiteral(bool NoIntDigits); }; Index: include/llvm/MC/MCParser/MCAsmLexer.h =================================================================== --- include/llvm/MC/MCParser/MCAsmLexer.h +++ include/llvm/MC/MCParser/MCAsmLexer.h @@ -133,7 +133,7 @@ MCAsmLexer(); - virtual AsmToken LexToken() = 0; + virtual AsmToken LexToken(bool AltMacroMode = false) = 0; void SetError(const SMLoc &errLoc, const std::string &err) { ErrLoc = errLoc; @@ -147,10 +147,9 @@ /// /// The lexer will continuosly return the end-of-file token once the end of /// the main input file has been reached. - const AsmToken &Lex() { - return CurTok = LexToken(); + const AsmToken &Lex(bool AltMacroMode = false) { + return CurTok = LexToken(AltMacroMode); } - virtual StringRef LexUntilEndOfStatement() = 0; /// Get the current source location. Index: lib/MC/MCParser/AsmLexer.cpp =================================================================== --- lib/MC/MCParser/AsmLexer.cpp +++ lib/MC/MCParser/AsmLexer.cpp @@ -359,8 +359,12 @@ return intToken(Result, Value); } -/// LexSingleQuote: Integer: 'b' -AsmToken AsmLexer::LexSingleQuote() { +/// LexSingleQuote: +/// If AltMacro = true 'string' +/// Else only one character Integer: 'b' +AsmToken AsmLexer::LexSingleQuote(bool AltMacroMode) { + if (AltMacroMode) + return LexStringHandel('\''); int CurChar = getNextChar(); if (CurChar == '\\') @@ -395,23 +399,41 @@ } -/// LexQuote: String: "..." -AsmToken AsmLexer::LexQuote() { - int CurChar = getNextChar(); - // TODO: does gas allow multiline string constants? - while (CurChar != '"') { - if (CurChar == '\\') { - // Allow \", etc. - CurChar = getNextChar(); - } - - if (CurChar == EOF) - return ReturnError(TokStart, "unterminated string constant"); - - CurChar = getNextChar(); - } +/// LexStringHandel: String: "..." in altmacro also <...> and '...' string. - return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart)); +AsmToken AsmLexer::LexStringHandel(char FirstChar){ + char lastChar; + if (FirstChar == '<') + lastChar = '>'; + else + lastChar = FirstChar; + int CurChar = getNextChar(); + // TODO: does gas allow multiline string constants? + while (CurChar != lastChar) { + if (CurChar == '\\') { + // Allow \", etc. + CurChar = getNextChar(); + } + if (CurChar == EOF){ + if (FirstChar == '"') + return ReturnError(TokStart, "unterminated string constant - missing '\"' at the end"); + else if (FirstChar == '\'') + return ReturnError(TokStart, "unterminated string constant - missing '\'' at the end"); + else + return ReturnError(TokStart, "unterminated string constant"); + } + CurChar = getNextChar(); + if ((CurChar == '>')&& (lastChar == '>')){ + CurChar = getNextChar(); + if (CurChar == EOF) + break; + if ((CurChar == ',') || (CurChar == '\n')){ + CurPtr--; + break; + } + } + } + return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart)); } StringRef AsmLexer::LexUntilEndOfStatement() { @@ -476,123 +498,141 @@ strlen(MAI.getSeparatorString())) == 0; } -AsmToken AsmLexer::LexToken() { - TokStart = CurPtr; - // This always consumes at least one character. - int CurChar = getNextChar(); - - if (isAtStartOfComment(TokStart)) { - // If this comment starts with a '#', then return the Hash token and let - // the assembler parser see if it can be parsed as a cpp line filename - // comment. We do this only if we are at the start of a line. - if (CurChar == '#' && isAtStartOfLine) - return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); - isAtStartOfLine = true; - return LexLineComment(); - } - if (isAtStatementSeparator(TokStart)) { - CurPtr += strlen(MAI.getSeparatorString()) - 1; - return AsmToken(AsmToken::EndOfStatement, - StringRef(TokStart, strlen(MAI.getSeparatorString()))); - } - - // If we're missing a newline at EOF, make sure we still get an - // EndOfStatement token before the Eof token. - if (CurChar == EOF && !isAtStartOfLine) { - isAtStartOfLine = true; - return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1)); - } - - isAtStartOfLine = false; - switch (CurChar) { - default: - // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]* - if (isalpha(CurChar) || CurChar == '_' || CurChar == '.') - return LexIdentifier(); - - // Unknown character, emit an error. - return ReturnError(TokStart, "invalid character in input"); - case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0)); - case 0: - case ' ': - case '\t': - if (SkipSpace) { - // Ignore whitespace. - return LexToken(); - } else { - int len = 1; - while (*CurPtr==' ' || *CurPtr=='\t') { - CurPtr++; - len++; - } - return AsmToken(AsmToken::Space, StringRef(TokStart, len)); - } - case '\n': // FALL THROUGH. - case '\r': - isAtStartOfLine = true; - return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1)); - case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1)); - case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1)); - case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1)); - case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1)); - case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1)); - case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1)); - case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1)); - case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1)); - case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1)); - case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1)); - case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1)); - 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)); - return AsmToken(AsmToken::Equal, StringRef(TokStart, 1)); - case '|': - if (*CurPtr == '|') - return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2)); - return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1)); - case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1)); - case '&': - if (*CurPtr == '&') - return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2)); - return AsmToken(AsmToken::Amp, StringRef(TokStart, 1)); - case '!': - if (*CurPtr == '=') - return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2)); - return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1)); - case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1)); - case '/': return LexSlash(); - case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); - case '\'': return LexSingleQuote(); - case '"': return LexQuote(); - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - return LexDigit(); - case '<': - switch (*CurPtr) { - case '<': return ++CurPtr, AsmToken(AsmToken::LessLess, - StringRef(TokStart, 2)); - case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual, - StringRef(TokStart, 2)); - case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater, - StringRef(TokStart, 2)); - default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1)); - } - case '>': - switch (*CurPtr) { - case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater, - StringRef(TokStart, 2)); - case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual, - StringRef(TokStart, 2)); - default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1)); - } - - // TODO: Quoted identifiers (objc methods etc) - // local labels: [0-9][:] - // Forward/backward labels: [0-9][fb] - // Integers, fp constants, character constants. - } -} +/// isAtString check if the next token is type or arithmetic. +/// string that begin with char '<' must to end with char '>' otherwise it is no a string. +/// True - +/// false- a') + return true; + else + return false; +} + +AsmToken AsmLexer::LexToken(bool AltMacro){ + TokStart = CurPtr; + // This always consumes at least one character. + int CurChar = getNextChar(); + + if (isAtStartOfComment(TokStart)) { + // If this comment starts with a '#', then return the Hash token and let + // the assembler parser see if it can be parsed as a cpp line filename + // comment. We do this only if we are at the start of a line. + if (CurChar == '#' && isAtStartOfLine) + return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); + isAtStartOfLine = true; + return LexLineComment(); + } + if (isAtStatementSeparator(TokStart)) { + CurPtr += strlen(MAI.getSeparatorString()) - 1; + return AsmToken(AsmToken::EndOfStatement, + StringRef(TokStart, strlen(MAI.getSeparatorString()))); + } + + // If we're missing a newline at EOF, make sure we still get an + // EndOfStatement token before the Eof token. + if (CurChar == EOF && !isAtStartOfLine) { + isAtStartOfLine = true; + return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1)); + } + + isAtStartOfLine = false; + switch (CurChar) { + default: + // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]* + if (isalpha(CurChar) || CurChar == '_' || CurChar == '.') + return LexIdentifier(); + + // Unknown character, emit an error. + return ReturnError(TokStart, "invalid character in input"); + case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0)); + case 0: + case ' ': + case '\t': + if (SkipSpace) { + // Ignore whitespace. + return LexToken(AltMacro); + }else{ + int len = 1; + while (*CurPtr == ' ' || *CurPtr == '\t') { + CurPtr++; + len++; + } + return AsmToken(AsmToken::Space, StringRef(TokStart, len)); + } + case '\n': // FALL THROUGH. + case '\r': + isAtStartOfLine = true; + return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1)); + case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1)); + case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1)); + case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1)); + case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1)); + case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1)); + case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1)); + case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1)); + case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1)); + case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1)); + case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1)); + case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1)); + 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)); + return AsmToken(AsmToken::Equal, StringRef(TokStart, 1)); + case '|': + if (*CurPtr == '|') + return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2)); + return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1)); + case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1)); + case '&': + if (*CurPtr == '&') + return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2)); + return AsmToken(AsmToken::Amp, StringRef(TokStart, 1)); + case '!': + if (*CurPtr == '=') + return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2)); + return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1)); + case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1)); + case '/': return LexSlash(); + case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); + case '\'': return LexSingleQuote(AltMacro); + case '"': return LexStringHandel();//LexQuote(); + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return LexDigit(); + + case '<':{ + if (isAtString(CurPtr) && AltMacro) + return LexStringHandel('<'); + switch (*CurPtr) { + case '<': return ++CurPtr, AsmToken(AsmToken::LessLess, + StringRef(TokStart, 2)); + case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual, + StringRef(TokStart, 2)); + case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater, + StringRef(TokStart, 2)); + default:return AsmToken(AsmToken::Less, StringRef(TokStart, 1)); + } + } + case '>': + switch (*CurPtr) { + case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater, + StringRef(TokStart, 2)); + case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual, + StringRef(TokStart, 2)); + default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1)); + } + // TODO: Quoted identifiers (objc methods etc) + // local labels: [0-9][:] + // Forward/backward labels: [0-9][fb] + // Integers, fp constants, character constants. + } +} \ No newline at end of file Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -174,7 +174,10 @@ /// \brief Are we parsing ms-style inline assembly? bool ParsingInlineAsm; - + /// \ this is for the .altmode use. + bool AltMacroMode = false; + bool AltMacroPresent = false; + int64_t valueForTheAltMacro; public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); @@ -244,7 +247,7 @@ /// } private: - + bool PRE = false; bool parseStatement(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI); void eatToEndOfLine(); @@ -358,7 +361,7 @@ DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE, DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, - DK_MACROS_ON, DK_MACROS_OFF, + DK_MACROS_ON, DK_MACROS_OFF, DK_ALTMACRO_ON, DK_NOALTMACRO, DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM, DK_SLEB128, DK_ULEB128, DK_ERR, DK_ERROR, DK_WARNING, @@ -415,8 +418,9 @@ bool parseDirectiveEndMacro(StringRef Directive); bool parseDirectiveMacro(SMLoc DirectiveLoc); bool parseDirectiveMacrosOnOff(StringRef Directive); - - // ".bundle_align_mode" + // AltMacros + bool parseDirectiveAltMacrosOnOff(StringRef Directive); + // ".bundle_align_mode" bool parseDirectiveBundleAlignMode(); // ".bundle_lock" bool parseDirectiveBundleLock(); @@ -598,15 +602,15 @@ } const AsmToken &AsmParser::Lex() { - const AsmToken *tok = &Lexer.Lex(); + const AsmToken *tok = &Lexer.Lex(AltMacroMode); - if (tok->is(AsmToken::Eof)) { + if (tok->is(AsmToken::Eof)) { // If this is the end of an included file, pop the parent file off the // include stack. SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); if (ParentIncludeLoc != SMLoc()) { - jumpToLoc(ParentIncludeLoc); - tok = &Lexer.Lex(); + jumpToLoc(ParentIncludeLoc); + tok = &Lexer.Lex(AltMacroMode); } } @@ -776,6 +780,7 @@ /// primaryexpr ::= number /// primaryexpr ::= '.' /// primaryexpr ::= ~,+,- primaryexpr +/// primaryezpr ::= '%' bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { SMLoc FirstTokenLoc = getLexer().getLoc(); AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); @@ -791,6 +796,12 @@ return true; Res = MCUnaryExpr::createLNot(Res, getContext()); return false; + case AsmToken::Percent:{ + if (AltMacroMode) + return false; + else + return true; + } case AsmToken::Dollar: case AsmToken::At: case AsmToken::String: @@ -1227,7 +1238,8 @@ // Treat '.' as a valid identifier in this context. Lex(); IDVal = "."; - } else if (parseIdentifier(IDVal)) { + } + else if (parseIdentifier(IDVal)) { if (!TheCondState.Ignore) return TokError("unexpected token at start of statement"); IDVal = ""; @@ -1389,7 +1401,7 @@ // Finally, if no one else is interested in this directive, it must be // generic and familiar to this class. - switch (DirKind) { + switch (DirKind) { default: break; case DK_SET: @@ -1558,6 +1570,10 @@ return parseDirectiveMacrosOnOff(IDVal); case DK_MACRO: return parseDirectiveMacro(IDLoc); + case DK_ALTMACRO_ON: + return parseDirectiveAltMacrosOnOff(IDVal); + case DK_NOALTMACRO: + return parseDirectiveAltMacrosOnOff(IDVal); case DK_EXITM: return parseDirectiveExitMacro(IDVal); case DK_ENDM: @@ -1778,10 +1794,10 @@ ArrayRef A, bool EnableAtPseudoVariable, const SMLoc &L) { unsigned NParameters = Parameters.size(); - bool HasVararg = NParameters ? Parameters.back().Vararg : false; + bool Percent = false; + bool HasVararg = NParameters ? Parameters.back().Vararg : false; if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) return Error(L, "Wrong number of arguments"); - // A macro without parameters is handled differently on Darwin: // gas accepts no arguments and does no substitutions while (!Body.empty()) { @@ -1802,6 +1818,10 @@ // This macro has parameters, look for \foo, \bar, etc. if (Body[Pos] == '\\' && Pos + 1 != End) break; + if (Body[Pos] == '%' && Pos + 1 != End && AltMacroMode){ + Percent = true; + break; + } } } @@ -1871,16 +1891,21 @@ } } else { bool VarargParameter = HasVararg && Index == (NParameters - 1); - for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), - ie = A[Index].end(); - it != ie; ++it) - // We expect no quotes around the string's contents when - // parsing for varargs. - if (it->getKind() != AsmToken::String || VarargParameter) - OS << it->getString(); - else - OS << it->getStringContents(); - + if (Percent&&AltMacroPresent){ + AltMacroPresent = false; + OS << valueForTheAltMacro; + } + else{ + for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), + ie = A[Index].end(); + it != ie; ++it) + // We expect no quotes around the string's contents when + // parsing for varargs. + if (it->getKind() != AsmToken::String || VarargParameter) + OS << it->getString(); + else + OS << it->getStringContents(); + } Pos += 1 + Argument.size(); } } @@ -2024,12 +2049,12 @@ // Parse two kinds of macro invocations: // - macros defined without any parameters accept an arbitrary number of them // - macros defined with parameters accept at most that many of them - bool HasVararg = NParameters ? M->Parameters.back().Vararg : false; + + bool HasVararg = NParameters ? M->Parameters.back().Vararg : false; for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; ++Parameter) { SMLoc IDLoc = Lexer.getLoc(); MCAsmMacroParameter FA; - if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) { if (parseIdentifier(FA.Name)) { Error(IDLoc, "invalid argument identifier for formal argument"); @@ -2046,7 +2071,10 @@ NamedParametersFound = true; } - + if (Lexer.is(AsmToken::LParen)&&AltMacroMode){ + AltMacroPresent = true; + parseAbsoluteExpression(valueForTheAltMacro); + } if (NamedParametersFound && FA.Name.empty()) { Error(IDLoc, "cannot mix positional and keyword arguments"); eatToEndOfStatement(); @@ -3280,7 +3308,15 @@ getStreamer().EmitCFIUndefined(Register); return false; } - +/// parseDirectiveAltMacrosOnOff +/// ::= .altmacro_on +/// ::= .altmacro_off +bool AsmParser::parseDirectiveAltMacrosOnOff(StringRef Directive) { + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '" + Directive + "' directive"); + AltMacroMode = (Directive == ".altmacro"); + return false; +} /// parseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off @@ -3297,12 +3333,13 @@ /// ::= .macro name[,] [parameters] bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { StringRef Name; + if (parseIdentifier(Name)) return TokError("expected identifier in '.macro' directive"); if (getLexer().is(AsmToken::Comma)) Lex(); - + MCAsmMacroParameters Parameters; while (getLexer().isNot(AsmToken::EndOfStatement)) { @@ -4305,6 +4342,8 @@ DirectiveKindMap[".err"] = DK_ERR; DirectiveKindMap[".error"] = DK_ERROR; DirectiveKindMap[".warning"] = DK_WARNING; + DirectiveKindMap[".altmacro"] = DK_ALTMACRO_ON; + DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO; } MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { Index: test/MC/AsmParser/altMacroTest.s =================================================================== --- test/MC/AsmParser/altMacroTest.s +++ test/MC/AsmParser/altMacroTest.s @@ -0,0 +1,55 @@ +# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + +.altmacro +.macro test1 name num + \name\num\(): + .long \name\num +.endm +test1 'b',1 +test1 'ab',1 +test1 "a",1 +test1 "ba",1 +test1 ,1 +.noaltmacro +# CHECK: b1 +# CHECK: .long b1 +# CHECK: ab1: +# CHECK: .long ab1 +# CHECK: a1: +# CHECK: .long a1 +# CHECK: ba1: +# CHECK: .long ba1 +# CHECK: bac1: +# CHECK: .long bac1 + +.altmacro +.macro test2 name, number +__mksym \name, %number +.endm + +.macro __mksym, name, number +\name\number\(): + .long \number +.endm + +.section .rodata + +/* now define symbols by hand... */ +test2 bar, 1 +test2 bar, (9/3 + (7-1)) + +/* ...or use other pseudo ops to do it in a loop */ +.irp i, 3, 2, 1 +test2 foobar, (\i * 2 + 1) +.endr + +# CHECK: bar1: +# CHECK: .long 1 +# CHECK: bar9: +# CHECK: .long 9 +# CHECK: foobar7: +# CHECK: .long 7 +# CHECK: foobar5: +# CHECK: .long 5 +# CHECK: foobar3: +# CHECK: .long 3 \ No newline at end of file Index: test/MC/AsmParser/altMacroTestFail.s =================================================================== --- test/MC/AsmParser/altMacroTestFail.s +++ test/MC/AsmParser/altMacroTestFail.s @@ -0,0 +1,10 @@ +# RUN: not llvm-mc -triple i386 -o /dev/null %s 2>&1 | FileCheck %s + +.macro lableRun name num + \name\num\(): + .long \name\num +.endm +.altmacro +.noaltmacro +lableRun 'bc',1 +# CHECK: error: single quote way too long \ No newline at end of file