diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/AsmParser.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/AsmParser.cpp | 184 |
1 files changed, 114 insertions, 70 deletions
diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index e2a4fc1..1e805fd 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -111,8 +111,8 @@ struct ParseStatementInfo { /// \brief The concrete assembly parser instance. class AsmParser : public MCAsmParser { - AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION; - void operator=(const AsmParser &) LLVM_DELETED_FUNCTION; + AsmParser(const AsmParser &) = delete; + void operator=(const AsmParser &) = delete; private: AsmLexer Lexer; MCContext &Ctx; @@ -147,6 +147,9 @@ private: /// Boolean tracking whether macro substitution is enabled. unsigned MacrosEnabledFlag : 1; + /// \brief Keeps track of how many .macro's have been instantiated. + unsigned NumOfMacroInstantiations; + /// Flag tracking whether any errors have been encountered. unsigned HadError : 1; @@ -175,7 +178,7 @@ private: public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); - virtual ~AsmParser(); + ~AsmParser() override; bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; @@ -184,6 +187,10 @@ public: ExtensionDirectiveMap[Directive] = Handler; } + void addAliasForDirective(StringRef Directive, StringRef Alias) override { + DirectiveKindMap[Directive] = DirectiveKindMap[Alias]; + } + public: /// @name MCAsmParser Interface /// { @@ -247,7 +254,7 @@ private: ArrayRef<MCAsmMacroParameter> Parameters); bool expandMacro(raw_svector_ostream &OS, StringRef Body, ArrayRef<MCAsmMacroParameter> Parameters, - ArrayRef<MCAsmMacroArgument> A, + ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable, const SMLoc &L); /// \brief Are macros enabled in the parser? @@ -319,6 +326,9 @@ private: bool parseAssignment(StringRef Name, bool allow_redef, bool NoDeadStrip = false); + unsigned getBinOpPrecedence(AsmToken::TokenKind K, + MCBinaryExpr::Opcode &Kind); + bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); @@ -339,8 +349,8 @@ private: DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB, - DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, - DK_ELSEIF, DK_ELSE, DK_ENDIF, + DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFNES, DK_IFDEF, DK_IFNDEF, + DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF, DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, @@ -435,8 +445,8 @@ private: bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); // ".ifc" or ".ifnc", depending on ExpectEqual. bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); - // ".ifeqs" - bool parseDirectiveIfeqs(SMLoc DirectiveLoc); + // ".ifeqs" or ".ifnes", depending on ExpectEqual. + bool parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual); // ".ifdef" or ".ifndef", depending on expect_defined bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" @@ -486,10 +496,10 @@ extern MCAsmParserExtension *createCOFFAsmParser(); enum { DEFAULT_ADDRSPACE = 0 }; -AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, - const MCAsmInfo &_MAI) - : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), - PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()), +AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, + const MCAsmInfo &MAI) + : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM), + PlatformParser(nullptr), CurBuffer(SM.getMainFileID()), MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0), AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { // Save the old handler. @@ -500,7 +510,7 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); // Initialize the platform / file format parser. - switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { + switch (Ctx.getObjectFileInfo()->getObjectFileType()) { case MCObjectFileInfo::IsCOFF: PlatformParser.reset(createCOFFAsmParser()); break; @@ -515,6 +525,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, PlatformParser->Initialize(*this); initializeDirectiveKindMap(); + + NumOfMacroInstantiations = 0; } AsmParser::~AsmParser() { @@ -618,12 +630,13 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // If we are generating dwarf for assembly source files save the initial text // section and generate a .file directive. if (getContext().getGenDwarfForAssembly()) { - MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); + MCSymbol *SectionStartSym = getContext().createTempSymbol(); getStreamer().EmitLabel(SectionStartSym); - auto InsertResult = getContext().addGenDwarfSection( - getStreamer().getCurrentSection().first); - assert(InsertResult.second && ".text section should not have debug info yet"); - InsertResult.first->second.first = SectionStartSym; + MCSection *Sec = getStreamer().getCurrentSection().first; + bool InsertResult = getContext().addGenDwarfSection(Sec); + assert(InsertResult && ".text section should not have debug info yet"); + (void)InsertResult; + Sec->setBeginSymbol(SectionStartSym); getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( 0, StringRef(), getContext().getMainFileName())); } @@ -786,7 +799,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { if (Lexer.getMAI().getDollarIsPC()) { // This is a '$' reference, which references the current PC. Emit a // temporary label to the streamer and refer to it. - MCSymbol *Sym = Ctx.CreateTempSymbol(); + MCSymbol *Sym = Ctx.createTempSymbol(); Out.EmitLabel(Sym); Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); @@ -843,7 +856,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { } } - MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); + MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName); // If this is an absolute variable reference, substitute it now to preserve // semantics in the face of reassignment. @@ -881,7 +894,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { } if (IDVal == "f" || IDVal == "b") { MCSymbol *Sym = - Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "b"); + Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b"); Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); if (IDVal == "b" && Sym->isUndefined()) return Error(Loc, "invalid reference to undefined symbol"); @@ -902,7 +915,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { case AsmToken::Dot: { // This is a '.' reference, which references the current PC. Emit a // temporary label to the streamer and refer to it. - MCSymbol *Sym = Ctx.CreateTempSymbol(); + MCSymbol *Sym = Ctx.createTempSymbol(); Out.EmitLabel(Sym); Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); EndLoc = Lexer.getTok().getEndLoc(); @@ -1063,8 +1076,8 @@ bool AsmParser::parseAbsoluteExpression(int64_t &Res) { return false; } -static unsigned getBinOpPrecedence(AsmToken::TokenKind K, - MCBinaryExpr::Opcode &Kind) { +unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K, + MCBinaryExpr::Opcode &Kind) { switch (K) { default: return 0; // not a binop. @@ -1116,7 +1129,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::Shl; return 4; case AsmToken::GreaterGreater: - Kind = MCBinaryExpr::Shr; + Kind = MAI.shouldUseLogicalShr() ? MCBinaryExpr::LShr : MCBinaryExpr::AShr; return 4; // High Intermediate Precedence: +, - @@ -1244,9 +1257,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, case DK_IFC: return parseDirectiveIfc(IDLoc, true); case DK_IFEQS: - return parseDirectiveIfeqs(IDLoc); + return parseDirectiveIfeqs(IDLoc, true); case DK_IFNC: return parseDirectiveIfc(IDLoc, false); + case DK_IFNES: + return parseDirectiveIfeqs(IDLoc, false); case DK_IFDEF: return parseDirectiveIfdef(IDLoc, true); case DK_IFNDEF: @@ -1295,9 +1310,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, IDVal.size(), RewrittenLabel)); IDVal = RewrittenLabel; } - Sym = getContext().GetOrCreateSymbol(IDVal); + Sym = getContext().getOrCreateSymbol(IDVal); } else - Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); + Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal); Sym->redefineIfPossible(); @@ -1758,7 +1773,8 @@ static bool isIdentifierChar(char c) { bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, ArrayRef<MCAsmMacroParameter> Parameters, - ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) { + ArrayRef<MCAsmMacroArgument> A, + bool EnableAtPseudoVariable, const SMLoc &L) { unsigned NParameters = Parameters.size(); bool HasVararg = NParameters ? Parameters.back().Vararg : false; if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) @@ -1824,36 +1840,47 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, Pos += 2; } else { unsigned I = Pos + 1; - while (isIdentifierChar(Body[I]) && I + 1 != End) + + // Check for the \@ pseudo-variable. + if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End) ++I; + else + while (isIdentifierChar(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].Name == Argument) - break; - if (Index == NParameters) { - if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') - Pos += 3; - else { - OS << '\\' << Argument; - Pos = I; - } + if (Argument == "@") { + OS << NumOfMacroInstantiations; + Pos += 2; } 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(); - - Pos += 1 + Argument.size(); + for (; Index < NParameters; ++Index) + if (Parameters[Index].Name == Argument) + break; + + if (Index == NParameters) { + if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') + Pos += 3; + else { + OS << '\\' << Argument; + Pos = I; + } + } 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(); + + Pos += 1 + Argument.size(); + } } } // Update the scan point. @@ -2111,7 +2138,7 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { StringRef Body = M->Body; raw_svector_ostream OS(Buf); - if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) + if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc())) return true; // We include the .endmacro in the buffer as our cue to exit the macro @@ -2127,6 +2154,8 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()); ActiveMacros.push_back(MI); + ++NumOfMacroInstantiations; + // Jump to the macro instantiation and prime the lexer. CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); @@ -2189,7 +2218,7 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, // Validate that the LHS is allowed to be a variable (either it has not been // used as a symbol, or it is an absolute symbol). - MCSymbol *Sym = getContext().LookupSymbol(Name); + MCSymbol *Sym = getContext().lookupSymbol(Name); if (Sym) { // Diagnose assignment to a label. // @@ -2218,7 +2247,7 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, } return false; } else - Sym = getContext().GetOrCreateSymbol(Name); + Sym = getContext().getOrCreateSymbol(Name); Sym->setRedefinable(allow_redef); @@ -2791,7 +2820,7 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { if (FileNumber == -1) getStreamer().EmitFileDirective(Filename); else { - if (getContext().getGenDwarfForAssembly() == true) + if (getContext().getGenDwarfForAssembly()) Error(DirectiveLoc, "input can't have .file dwarf directives when -g is " "used to generate dwarf debug info for assembly code"); @@ -3158,7 +3187,7 @@ bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { if (parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (IsPersonality) getStreamer().EmitCFIPersonality(Sym, Encoding); @@ -3275,7 +3304,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { MCAsmMacroParameters Parameters; while (getLexer().isNot(AsmToken::EndOfStatement)) { - if (Parameters.size() && Parameters.back().Vararg) + if (!Parameters.empty() && Parameters.back().Vararg) return Error(Lexer.getLoc(), "Vararg parameter '" + Parameters.back().Name + "' should be last one in the list of parameters."); @@ -3672,7 +3701,7 @@ bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { if (parseIdentifier(Name)) return Error(Loc, "expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); // Assembler local symbols don't make any sense here. Complain loudly. if (Sym->isTemporary()) @@ -3705,7 +3734,7 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); @@ -3943,9 +3972,12 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { /// parseDirectiveIfeqs /// ::= .ifeqs string1, string2 -bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) { if (Lexer.isNot(AsmToken::String)) { - TokError("expected string parameter for '.ifeqs' directive"); + if (ExpectEqual) + TokError("expected string parameter for '.ifeqs' directive"); + else + TokError("expected string parameter for '.ifnes' directive"); eatToEndOfStatement(); return true; } @@ -3954,7 +3986,10 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { Lex(); if (Lexer.isNot(AsmToken::Comma)) { - TokError("expected comma after first string for '.ifeqs' directive"); + if (ExpectEqual) + TokError("expected comma after first string for '.ifeqs' directive"); + else + TokError("expected comma after first string for '.ifnes' directive"); eatToEndOfStatement(); return true; } @@ -3962,7 +3997,10 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { Lex(); if (Lexer.isNot(AsmToken::String)) { - TokError("expected string parameter for '.ifeqs' directive"); + if (ExpectEqual) + TokError("expected string parameter for '.ifeqs' directive"); + else + TokError("expected string parameter for '.ifnes' directive"); eatToEndOfStatement(); return true; } @@ -3972,7 +4010,7 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; - TheCondState.CondMet = String1 == String2; + TheCondState.CondMet = ExpectEqual == (String1 == String2); TheCondState.Ignore = !TheCondState.CondMet; return false; @@ -3993,7 +4031,7 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { Lex(); - MCSymbol *Sym = getContext().LookupSymbol(Name); + MCSymbol *Sym = getContext().lookupSymbol(Name); if (expect_defined) TheCondState.CondMet = (Sym && !Sym->isUndefined()); @@ -4219,6 +4257,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".ifc"] = DK_IFC; DirectiveKindMap[".ifeqs"] = DK_IFEQS; DirectiveKindMap[".ifnc"] = DK_IFNC; + DirectiveKindMap[".ifnes"] = DK_IFNES; DirectiveKindMap[".ifdef"] = DK_IFDEF; DirectiveKindMap[".ifndef"] = DK_IFNDEF; DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF; @@ -4362,7 +4401,8 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) { SmallString<256> Buf; raw_svector_ostream OS(Buf); while (Count--) { - if (expandMacro(OS, M->Body, None, None, getTok().getLoc())) + // Note that the AtPseudoVariable is disabled for instantiations of .rep(t). + if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc())) return true; } instantiateMacroLikeBody(M, DirectiveLoc, OS); @@ -4401,7 +4441,9 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { raw_svector_ostream OS(Buf); for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { - if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc())) + // Note that the AtPseudoVariable is enabled for instantiations of .irp. + // This is undocumented, but GAS seems to support it. + if (expandMacro(OS, M->Body, Parameter, *i, true, getTok().getLoc())) return true; } @@ -4448,7 +4490,9 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { MCAsmMacroArgument Arg; Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1))); - if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc())) + // Note that the AtPseudoVariable is enabled for instantiations of .irpc. + // This is undocumented, but GAS seems to support it. + if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc())) return true; } @@ -4594,7 +4638,7 @@ bool AsmParser::parseMSInlineAsm( ++InputIdx; OutputDecls.push_back(OpDecl); OutputDeclsAddressOf.push_back(Operand.needAddressOf()); - OutputConstraints.push_back('=' + Operand.getConstraint().str()); + OutputConstraints.push_back(("=" + Operand.getConstraint()).str()); AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size())); } else { InputDecls.push_back(OpDecl); |