diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/AsmParser.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/AsmParser.cpp | 221 |
1 files changed, 139 insertions, 82 deletions
diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index ed1d704..8eff90a 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -45,10 +45,6 @@ #include <vector> using namespace llvm; -static cl::opt<bool> -FatalAssemblerWarnings("fatal-assembler-warnings", - cl::desc("Consider warnings as error")); - MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {} namespace { @@ -73,19 +69,13 @@ struct MCAsmMacro { MCAsmMacroParameters Parameters; public: - MCAsmMacro(StringRef N, StringRef B, ArrayRef<MCAsmMacroParameter> P) : - Name(N), Body(B), Parameters(P) {} + MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P) + : Name(N), Body(B), Parameters(std::move(P)) {} }; /// \brief Helper class for storing information about an active macro /// instantiation. struct MacroInstantiation { - /// The macro being instantiated. - const MCAsmMacro *TheMacro; - - /// The macro instantiation with substitutions. - MemoryBuffer *Instantiation; - /// The location of the instantiation. SMLoc InstantiationLoc; @@ -95,9 +85,11 @@ struct MacroInstantiation { /// The location where parsing should resume upon instantiation completion. SMLoc ExitLoc; + /// The depth of TheCondStack at the start of the instantiation. + size_t CondStackDepth; + public: - MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL, - MemoryBuffer *I); + MacroInstantiation(SMLoc IL, int EB, SMLoc EL, size_t CondStackDepth); }; struct ParseStatementInfo { @@ -129,7 +121,7 @@ private: SourceMgr &SrcMgr; SourceMgr::DiagHandlerTy SavedDiagHandler; void *SavedDiagContext; - MCAsmParserExtension *PlatformParser; + std::unique_ptr<MCAsmParserExtension> PlatformParser; /// This is the current buffer index we're lexing from as managed by the /// SourceMgr object. @@ -144,7 +136,7 @@ private: StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap; /// \brief Map of currently defined macros. - StringMap<MCAsmMacro*> MacroMap; + StringMap<MCAsmMacro> MacroMap; /// \brief Stack of active macro instantiations. std::vector<MacroInstantiation*> ActiveMacros; @@ -246,7 +238,8 @@ public: private: - bool parseStatement(ParseStatementInfo &Info); + bool parseStatement(ParseStatementInfo &Info, + MCAsmParserSemaCallback *SI); void eatToEndOfLine(); bool parseCppHashLineFilenameComment(const SMLoc &L); @@ -269,7 +262,7 @@ private: const MCAsmMacro* lookupMacro(StringRef Name); /// \brief Define a new macro with the given name and information. - void defineMacro(StringRef Name, const MCAsmMacro& Macro); + void defineMacro(StringRef Name, MCAsmMacro Macro); /// \brief Undefine a macro. If no such macro was defined, it's a no-op. void undefineMacro(StringRef Name); @@ -355,9 +348,10 @@ private: 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_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM, + DK_MACROS_ON, DK_MACROS_OFF, + DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM, DK_SLEB128, DK_ULEB128, - DK_ERR, DK_ERROR, + DK_ERR, DK_ERROR, DK_WARNING, DK_END }; @@ -407,6 +401,7 @@ private: // macro directives bool parseDirectivePurgeMacro(SMLoc DirectiveLoc); + bool parseDirectiveExitMacro(StringRef Directive); bool parseDirectiveEndMacro(StringRef Directive); bool parseDirectiveMacro(SMLoc DirectiveLoc); bool parseDirectiveMacrosOnOff(StringRef Directive); @@ -474,6 +469,9 @@ private: // ".err" or ".error" bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage); + // ".warning" + bool parseDirectiveWarning(SMLoc DirectiveLoc); + void initializeDirectiveKindMap(); }; } @@ -504,34 +502,24 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, // Initialize the platform / file format parser. switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { case MCObjectFileInfo::IsCOFF: - PlatformParser = createCOFFAsmParser(); - PlatformParser->Initialize(*this); - break; + PlatformParser.reset(createCOFFAsmParser()); + break; case MCObjectFileInfo::IsMachO: - PlatformParser = createDarwinAsmParser(); - PlatformParser->Initialize(*this); - IsDarwin = true; - break; + PlatformParser.reset(createDarwinAsmParser()); + IsDarwin = true; + break; case MCObjectFileInfo::IsELF: - PlatformParser = createELFAsmParser(); - PlatformParser->Initialize(*this); - break; + PlatformParser.reset(createELFAsmParser()); + break; } + PlatformParser->Initialize(*this); initializeDirectiveKindMap(); } AsmParser::~AsmParser() { assert((HadError || ActiveMacros.empty()) && "Unexpected active macro instantiation!"); - - // Destroy any macros. - for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(), - ie = MacroMap.end(); - it != ie; ++it) - delete it->getValue(); - - delete PlatformParser; } void AsmParser::printMacroInstantiations() { @@ -550,7 +538,7 @@ void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { } bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { - if (FatalAssemblerWarnings) + if (getTargetParser().getTargetOptions().MCFatalWarnings) return Error(L, Msg, Ranges); printMessage(L, SourceMgr::DK_Warning, Msg, Ranges); printMacroInstantiations(); @@ -619,7 +607,7 @@ const AsmToken &AsmParser::Lex() { bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // Create the initial section, if requested. if (!NoInitialTextSection) - Out.InitSections(); + Out.InitSections(false); // Prime the lexer. Lex(); @@ -643,7 +631,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // While we have input, parse each statement. while (Lexer.isNot(AsmToken::Eof)) { ParseStatementInfo Info; - if (!parseStatement(Info)) + if (!parseStatement(Info, nullptr)) continue; // We had an error, validate that one was emitted and recover by skipping to @@ -702,7 +690,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { void AsmParser::checkForValidSection() { if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) { TokError("expected section directive before assembly directive"); - Out.InitSections(); + Out.InitSections(false); } } @@ -1188,7 +1176,8 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, /// ::= EndOfStatement /// ::= Label* Directive ...Operands... EndOfStatement /// ::= Label* Identifier OperandList* EndOfStatement -bool AsmParser::parseStatement(ParseStatementInfo &Info) { +bool AsmParser::parseStatement(ParseStatementInfo &Info, + MCAsmParserSemaCallback *SI) { if (Lexer.is(AsmToken::EndOfStatement)) { Out.AddBlankLine(); Lex(); @@ -1298,10 +1287,20 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { // FIXME: This doesn't diagnose assignment to a symbol which has been // implicitly marked as external. MCSymbol *Sym; - if (LocalLabelVal == -1) + if (LocalLabelVal == -1) { + if (ParsingInlineAsm && SI) { + StringRef RewrittenLabel = SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true); + assert(RewrittenLabel.size() && "We should have an internal name here."); + Info.AsmRewrites->push_back(AsmRewrite(AOK_Label, IDLoc, + IDVal.size(), RewrittenLabel)); + IDVal = RewrittenLabel; + } Sym = getContext().GetOrCreateSymbol(IDVal); - else + } else Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); + + Sym->redefineIfPossible(); + if (!Sym->isUndefined() || Sym->isVariable()) return Error(IDLoc, "invalid symbol redefinition"); @@ -1542,6 +1541,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { return parseDirectiveMacrosOnOff(IDVal); case DK_MACRO: return parseDirectiveMacro(IDLoc); + case DK_EXITM: + return parseDirectiveExitMacro(IDVal); case DK_ENDM: case DK_ENDMACRO: return parseDirectiveEndMacro(IDVal); @@ -1553,6 +1554,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { return parseDirectiveError(IDLoc, false); case DK_ERROR: return parseDirectiveError(IDLoc, true); + case DK_WARNING: + return parseDirectiveWarning(IDLoc); } return Error(IDLoc, "unknown directive"); @@ -1595,14 +1598,18 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { // directive for the instruction. if (!HadError && getContext().getGenDwarfForAssembly() && getContext().getGenDwarfSectionSyms().count( - getStreamer().getCurrentSection().first)) { - - unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); + getStreamer().getCurrentSection().first)) { + unsigned Line; + if (ActiveMacros.empty()) + Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); + else + Line = SrcMgr.FindLineNumber(ActiveMacros.back()->InstantiationLoc, + ActiveMacros.back()->ExitBuffer); // If we previously parsed a cpp hash file line comment then make sure the // current Dwarf File is for the CppHashFilename if not then emit the // Dwarf File table for it and adjust the line number for the .loc. - if (CppHashFilename.size() != 0) { + if (CppHashFilename.size()) { unsigned FileNumber = getStreamer().EmitDwarfFileDirective( 0, StringRef(), CppHashFilename); getContext().setGenDwarfFileNumber(FileNumber); @@ -1630,7 +1637,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { // If parsing succeeded, match the instruction. if (!HadError) { - unsigned ErrorInfo; + uint64_t ErrorInfo; getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo, ParsingInlineAsm); @@ -1856,10 +1863,10 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, return false; } -MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, - SMLoc EL, MemoryBuffer *I) - : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), - ExitLoc(EL) {} +MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL, + size_t CondStackDepth) + : InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL), + CondStackDepth(CondStackDepth) {} static bool isOperator(AsmToken::TokenKind kind) { switch (kind) { @@ -2078,21 +2085,15 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, } const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) { - StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); - return (I == MacroMap.end()) ? nullptr : I->getValue(); + StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name); + return (I == MacroMap.end()) ? nullptr : &I->getValue(); } -void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) { - MacroMap[Name] = new MCAsmMacro(Macro); +void AsmParser::defineMacro(StringRef Name, MCAsmMacro Macro) { + MacroMap.insert(std::make_pair(Name, std::move(Macro))); } -void AsmParser::undefineMacro(StringRef Name) { - StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); - if (I != MacroMap.end()) { - delete I->getValue(); - MacroMap.erase(I); - } -} +void AsmParser::undefineMacro(StringRef Name) { MacroMap.erase(Name); } bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate @@ -2117,17 +2118,17 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { // instantiation. OS << ".endmacro\n"; - MemoryBuffer *Instantiation = + std::unique_ptr<MemoryBuffer> Instantiation = MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); // Create the macro instantiation object and add to the current macro // instantiation stack. MacroInstantiation *MI = new MacroInstantiation( - M, NameLoc, CurBuffer, getTok().getLoc(), Instantiation); + NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()); ActiveMacros.push_back(MI); // Jump to the macro instantiation and prime the lexer. - CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); + CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); Lex(); @@ -2219,6 +2220,8 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, } else Sym = getContext().GetOrCreateSymbol(Name); + Sym->setRedefinable(allow_redef); + // Do the assignment. Out.EmitAssignment(Sym, Value); if (NoDeadStrip) @@ -2600,12 +2603,14 @@ bool AsmParser::parseDirectiveFill() { if (!isUInt<32>(FillExpr) && FillSize > 4) Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits"); - int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize; - FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8); - - for (uint64_t i = 0, e = NumValues; i != e; ++i) { - getStreamer().EmitIntValue(FillExpr, NonZeroFillSize); - getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize); + if (NumValues > 0) { + int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize; + FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8); + for (uint64_t i = 0, e = NumValues; i != e; ++i) { + getStreamer().EmitIntValue(FillExpr, NonZeroFillSize); + if (NonZeroFillSize < FillSize) + getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize); + } } return false; @@ -3292,7 +3297,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { if (Qualifier == "req") Parameter.Required = true; - else if (Qualifier == "vararg" && !IsDarwin) + else if (Qualifier == "vararg") Parameter.Vararg = true; else return Error(QualLoc, Qualifier + " is not a valid parameter qualifier " @@ -3313,7 +3318,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { "'" + Parameter.Name + "' in macro '" + Name + "'"); } - Parameters.push_back(Parameter); + Parameters.push_back(std::move(Parameter)); if (getLexer().is(AsmToken::Comma)) Lex(); @@ -3365,7 +3370,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { const char *BodyEnd = EndToken.getLoc().getPointer(); StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); checkForBadMacro(DirectiveLoc, Name, Body, Parameters); - defineMacro(Name, MCAsmMacro(Name, Body, Parameters)); + defineMacro(Name, MCAsmMacro(Name, Body, std::move(Parameters))); return false; } @@ -3471,6 +3476,26 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, "found in body which will have no effect"); } +/// parseDirectiveExitMacro +/// ::= .exitm +bool AsmParser::parseDirectiveExitMacro(StringRef Directive) { + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '" + Directive + "' directive"); + + if (!isInsideMacroInstantiation()) + return TokError("unexpected '" + Directive + "' in file, " + "no current macro definition"); + + // Exit all conditionals that are active in the current macro. + while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) { + TheCondState = TheCondStack.back(); + TheCondStack.pop_back(); + } + + handleMacroExit(); + return false; +} + /// parseDirectiveEndMacro /// ::= .endm /// ::= .endmacro @@ -4073,6 +4098,32 @@ bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) { return true; } +/// parseDirectiveWarning +/// ::= .warning [string] +bool AsmParser::parseDirectiveWarning(SMLoc L) { + if (!TheCondStack.empty()) { + if (TheCondStack.back().Ignore) { + eatToEndOfStatement(); + return false; + } + } + + StringRef Message = ".warning directive invoked in source file"; + if (Lexer.isNot(AsmToken::EndOfStatement)) { + if (Lexer.isNot(AsmToken::String)) { + TokError(".warning argument must be a string"); + eatToEndOfStatement(); + return true; + } + + Message = getTok().getStringContents(); + Lex(); + } + + Warning(L, Message); + return false; +} + /// parseDirectiveEndIf /// ::= .endif bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { @@ -4200,11 +4251,13 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".macros_on"] = DK_MACROS_ON; DirectiveKindMap[".macros_off"] = DK_MACROS_OFF; DirectiveKindMap[".macro"] = DK_MACRO; + DirectiveKindMap[".exitm"] = DK_EXITM; DirectiveKindMap[".endm"] = DK_ENDM; DirectiveKindMap[".endmacro"] = DK_ENDMACRO; DirectiveKindMap[".purgem"] = DK_PURGEM; DirectiveKindMap[".err"] = DK_ERR; DirectiveKindMap[".error"] = DK_ERROR; + DirectiveKindMap[".warning"] = DK_WARNING; } MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { @@ -4246,7 +4299,8 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); // We Are Anonymous. - MacroLikeBodies.push_back(MCAsmMacro(StringRef(), Body, None)); + MacroLikeBodies.push_back( + MCAsmMacro(StringRef(), Body, MCAsmMacroParameters())); return &MacroLikeBodies.back(); } @@ -4254,17 +4308,17 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, raw_svector_ostream &OS) { OS << ".endr\n"; - MemoryBuffer *Instantiation = + std::unique_ptr<MemoryBuffer> Instantiation = MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); // Create the macro instantiation object and add to the current macro // instantiation stack. MacroInstantiation *MI = new MacroInstantiation( - M, DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation); + DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()); ActiveMacros.push_back(MI); // Jump to the macro instantiation and prime the lexer. - CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); + CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); Lex(); } @@ -4490,7 +4544,7 @@ bool AsmParser::parseMSInlineAsm( unsigned OutputIdx = 0; while (getLexer().isNot(AsmToken::Eof)) { ParseStatementInfo Info(&AsmStrRewrites); - if (parseStatement(Info)) + if (parseStatement(Info, &SI)) return true; if (Info.ParseError) @@ -4616,6 +4670,9 @@ bool AsmParser::parseMSInlineAsm( case AOK_ImmPrefix: OS << "$$"; break; + case AOK_Label: + OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label; + break; case AOK_Input: OS << '$' << InputIdx++; break; |