diff options
| author | 2019-06-23 22:05:08 +0000 | |
|---|---|---|
| committer | 2019-06-23 22:05:08 +0000 | |
| commit | f27a781c9811da94fe68b2cf34237c2a61b48c96 (patch) | |
| tree | 820064216b8f115ba79122ebd03c5451b59fd690 /gnu/llvm/lib/MC/MCParser/AsmParser.cpp | |
| parent | Import LLVM 8.0.0 release including clang, lld and lldb. (diff) | |
| download | wireguard-openbsd-f27a781c9811da94fe68b2cf34237c2a61b48c96.tar.xz wireguard-openbsd-f27a781c9811da94fe68b2cf34237c2a61b48c96.zip | |
Merge LLVM 8.0.0 release.
Prepared with help from jsg@ and mortimer@
Tested on amd64 by bcallah@, krw@, naddy@
Tested on arm64 by patrick@
Tested on macppc by kettenis@
Tested on octeon by visa@
Tested on sparc64 by claudio@
Diffstat (limited to 'gnu/llvm/lib/MC/MCParser/AsmParser.cpp')
| -rw-r--r-- | gnu/llvm/lib/MC/MCParser/AsmParser.cpp | 167 |
1 files changed, 102 insertions, 65 deletions
diff --git a/gnu/llvm/lib/MC/MCParser/AsmParser.cpp b/gnu/llvm/lib/MC/MCParser/AsmParser.cpp index 4ce5ef73c83..ca8dd2d51a2 100644 --- a/gnu/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/gnu/llvm/lib/MC/MCParser/AsmParser.cpp @@ -180,6 +180,9 @@ private: /// Did we already inform the user about inconsistent MD5 usage? bool ReportedInconsistentMD5 = false; + // Is alt macro mode enabled. + bool AltMacroMode = false; + public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI, unsigned CB); @@ -226,7 +229,9 @@ public: void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; - Lexer.setParsingMSInlineAsm(V); + // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and + // hex integer literals. + Lexer.setLexMasmIntegers(V); } bool isParsingInlineAsm() override { return ParsingInlineAsm; } @@ -260,8 +265,6 @@ public: /// } private: - bool isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc); - void altMacroString(StringRef AltMacroStr, std::string &Res); bool parseStatement(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI); bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites); @@ -467,6 +470,7 @@ private: DK_CV_INLINE_LINETABLE, DK_CV_DEF_RANGE, DK_CV_STRINGTABLE, + DK_CV_STRING, DK_CV_FILECHECKSUMS, DK_CV_FILECHECKSUM_OFFSET, DK_CV_FPO_DATA, @@ -491,6 +495,7 @@ private: DK_CFI_UNDEFINED, DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, + DK_CFI_B_KEY_FRAME, DK_MACROS_ON, DK_MACROS_OFF, DK_ALTMACRO, @@ -538,7 +543,7 @@ private: bool parseDirectiveStabs(); // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable", - // ".cv_inline_linetable", ".cv_def_range" + // ".cv_inline_linetable", ".cv_def_range", ".cv_string" bool parseDirectiveCVFile(); bool parseDirectiveCVFuncId(); bool parseDirectiveCVInlineSiteId(); @@ -546,6 +551,7 @@ private: bool parseDirectiveCVLinetable(); bool parseDirectiveCVInlineLinetable(); bool parseDirectiveCVDefRange(); + bool parseDirectiveCVString(); bool parseDirectiveCVStringTable(); bool parseDirectiveCVFileChecksums(); bool parseDirectiveCVFileChecksumOffset(); @@ -670,6 +676,7 @@ namespace llvm { extern MCAsmParserExtension *createDarwinAsmParser(); extern MCAsmParserExtension *createELFAsmParser(); extern MCAsmParserExtension *createCOFFAsmParser(); +extern MCAsmParserExtension *createWasmAsmParser(); } // end namespace llvm @@ -700,10 +707,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, PlatformParser.reset(createELFAsmParser()); break; case MCObjectFileInfo::IsWasm: - // TODO: WASM will need its own MCAsmParserExtension implementation, but - // for now we can re-use the ELF one, since the directives can be the - // same for now. - PlatformParser.reset(createELFAsmParser()); + PlatformParser.reset(createWasmAsmParser()); break; } @@ -899,6 +903,9 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { eatToEndOfStatement(); } + getTargetParser().onEndOfFile(); + printPendingErrors(); + // All errors should have been emitted. assert(!hasPendingError() && "unexpected error from parseStatement"); @@ -1104,7 +1111,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { // This is a symbol reference. StringRef SymbolName = Identifier; if (SymbolName.empty()) - return true; + return Error(getLexer().getLoc(), "expected a symbol reference"); MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; @@ -1127,7 +1134,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { // semantics in the face of reassignment. if (Sym->isVariable()) { auto V = Sym->getVariableValue(/*SetUsed*/ false); - bool DoInline = isa<MCConstantExpr>(V); + bool DoInline = isa<MCConstantExpr>(V) && !Variant; if (auto TV = dyn_cast<MCTargetExpr>(V)) DoInline = TV->inlineAssignedExpr(); if (DoInline) { @@ -1325,11 +1332,12 @@ AsmParser::applyModifierToExpr(const MCExpr *E, /// the End argument will be filled with the last location pointed to the '>' /// character. -/// There is a gap between the AltMacro's documentation and the single quote implementation. -/// GCC does not fully support this feature and so we will not support it. +/// There is a gap between the AltMacro's documentation and the single quote +/// implementation. GCC does not fully support this feature and so we will not +/// support it. /// TODO: Adding single quote as a string. -bool AsmParser::isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc) { - assert((StrLoc.getPointer() != NULL) && +static bool isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc) { + assert((StrLoc.getPointer() != nullptr) && "Argument to the function cannot be a NULL value"); const char *CharPtr = StrLoc.getPointer(); while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') && @@ -1346,12 +1354,14 @@ bool AsmParser::isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc) { } /// creating a string without the escape characters '!'. -void AsmParser::altMacroString(StringRef AltMacroStr,std::string &Res) { +static std::string altMacroString(StringRef AltMacroStr) { + std::string Res; for (size_t Pos = 0; Pos < AltMacroStr.size(); Pos++) { if (AltMacroStr[Pos] == '!') Pos++; Res += AltMacroStr[Pos]; } + return Res; } /// Parse an expression and return it. @@ -1810,6 +1820,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, Lex(); } + getTargetParser().doBeforeLabelEmit(Sym); + // Emit the label. if (!getTargetParser().isParsingInlineAsm()) Out.EmitLabel(Sym, IDLoc); @@ -1846,7 +1858,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, // Otherwise, we have a normal instruction or directive. // Directives start with "." - if (IDVal[0] == '.' && IDVal != ".") { + if (IDVal.startswith(".") && IDVal != ".") { // There are several entities interested in parsing directives: // // 1. The target-specific assembly parser. Some directives are target @@ -2033,6 +2045,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveCVInlineLinetable(); case DK_CV_DEF_RANGE: return parseDirectiveCVDefRange(); + case DK_CV_STRING: + return parseDirectiveCVString(); case DK_CV_STRINGTABLE: return parseDirectiveCVStringTable(); case DK_CV_FILECHECKSUMS: @@ -2435,21 +2449,20 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, for (const AsmToken &Token : A[Index]) // For altmacro mode, you can write '%expr'. // The prefix '%' evaluates the expression 'expr' - // and uses the result as a string (e.g. replace %(1+2) with the string "3"). + // and uses the result as a string (e.g. replace %(1+2) with the + // string "3"). // Here, we identify the integer token which is the result of the - // absolute expression evaluation and replace it with its string representation. - if ((Lexer.IsaAltMacroMode()) && - (*(Token.getString().begin()) == '%') && Token.is(AsmToken::Integer)) + // absolute expression evaluation and replace it with its string + // representation. + if (AltMacroMode && Token.getString().front() == '%' && + Token.is(AsmToken::Integer)) // Emit an integer value to the buffer. OS << Token.getIntVal(); // Only Token that was validated as a string and begins with '<' // is considered altMacroString!!! - else if ((Lexer.IsaAltMacroMode()) && - (*(Token.getString().begin()) == '<') && + else if (AltMacroMode && Token.getString().front() == '<' && Token.is(AsmToken::String)) { - std::string Res; - altMacroString(Token.getStringContents(), Res); - OS << Res; + OS << altMacroString(Token.getStringContents()); } // We expect no quotes around the string's contents when // parsing for varargs. @@ -2631,31 +2644,33 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, SMLoc StrLoc = Lexer.getLoc(); SMLoc EndLoc; - if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Percent)) { - const MCExpr *AbsoluteExp; - int64_t Value; - /// Eat '%' - Lex(); - if (parseExpression(AbsoluteExp, EndLoc)) - return false; - if (!AbsoluteExp->evaluateAsAbsolute(Value, - getStreamer().getAssemblerPtr())) - return Error(StrLoc, "expected absolute expression"); - const char *StrChar = StrLoc.getPointer(); - const char *EndChar = EndLoc.getPointer(); - AsmToken newToken(AsmToken::Integer, StringRef(StrChar , EndChar - StrChar), Value); - FA.Value.push_back(newToken); - } else if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Less) && + if (AltMacroMode && Lexer.is(AsmToken::Percent)) { + const MCExpr *AbsoluteExp; + int64_t Value; + /// Eat '%' + Lex(); + if (parseExpression(AbsoluteExp, EndLoc)) + return false; + if (!AbsoluteExp->evaluateAsAbsolute(Value, + getStreamer().getAssemblerPtr())) + return Error(StrLoc, "expected absolute expression"); + const char *StrChar = StrLoc.getPointer(); + const char *EndChar = EndLoc.getPointer(); + AsmToken newToken(AsmToken::Integer, + StringRef(StrChar, EndChar - StrChar), Value); + FA.Value.push_back(newToken); + } else if (AltMacroMode && Lexer.is(AsmToken::Less) && isAltmacroString(StrLoc, EndLoc)) { - const char *StrChar = StrLoc.getPointer(); - const char *EndChar = EndLoc.getPointer(); - jumpToLoc(EndLoc, CurBuffer); - /// Eat from '<' to '>' - Lex(); - AsmToken newToken(AsmToken::String, StringRef(StrChar, EndChar - StrChar)); - FA.Value.push_back(newToken); + const char *StrChar = StrLoc.getPointer(); + const char *EndChar = EndLoc.getPointer(); + jumpToLoc(EndLoc, CurBuffer); + /// Eat from '<' to '>' + Lex(); + AsmToken newToken(AsmToken::String, + StringRef(StrChar, EndChar - StrChar)); + FA.Value.push_back(newToken); } else if(parseMacroArgument(FA.Value, Vararg)) - return true; + return true; unsigned PI = Parameter; if (!FA.Name.empty()) { @@ -2931,20 +2946,20 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) { const MCExpr *Offset; const MCExpr *Expr = nullptr; - - SMLoc OffsetLoc = Lexer.getTok().getLoc(); int64_t OffsetValue; - // We can only deal with constant expressions at the moment. + SMLoc OffsetLoc = Lexer.getTok().getLoc(); if (parseExpression(Offset)) return true; - if (check(!Offset->evaluateAsAbsolute(OffsetValue, - getStreamer().getAssemblerPtr()), - OffsetLoc, "expression is not a constant value") || - check(OffsetValue < 0, OffsetLoc, "expression is negative") || - parseToken(AsmToken::Comma, "expected comma") || - check(getTok().isNot(AsmToken::Identifier), "expected relocation name")) + if ((Offset->evaluateAsAbsolute(OffsetValue, + getStreamer().getAssemblerPtr()) && + check(OffsetValue < 0, OffsetLoc, "expression is negative")) || + (check(Offset->getKind() != llvm::MCExpr::Constant && + Offset->getKind() != llvm::MCExpr::SymbolRef, + OffsetLoc, "expected non-negative number or a label")) || + (parseToken(AsmToken::Comma, "expected comma") || + check(getTok().isNot(AsmToken::Identifier), "expected relocation name"))) return true; SMLoc NameLoc = Lexer.getTok().getLoc(); @@ -3352,9 +3367,13 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { } } - if (FileNumber == -1) - getStreamer().EmitFileDirective(Filename); - else { + if (FileNumber == -1) { + // Ignore the directive if there is no number and the target doesn't support + // numberless .file directives. This allows some portability of assembler + // between different object file formats. + if (getContext().getAsmInfo()->hasSingleParameterDotFile()) + getStreamer().EmitFileDirective(Filename); + } else { // In case there is a -g option as well as debug info from directive .file, // we turn off the -g option, directly use the existing debug info instead. // Also reset any implicit ".file 0" for the assembler source. @@ -3817,6 +3836,20 @@ bool AsmParser::parseDirectiveCVDefRange() { return false; } +/// parseDirectiveCVString +/// ::= .cv_stringtable "string" +bool AsmParser::parseDirectiveCVString() { + std::string Data; + if (checkForValidSection() || parseEscapedString(Data)) + return addErrorSuffix(" in '.cv_string' directive"); + + // Put the string in the table and emit the offset. + std::pair<StringRef, unsigned> Insertion = + getCVContext().addToStringTable(Data); + getStreamer().EmitIntValue(Insertion.second, 4); + return false; +} + /// parseDirectiveCVStringTable /// ::= .cv_stringtable bool AsmParser::parseDirectiveCVStringTable() { @@ -3899,7 +3932,12 @@ bool AsmParser::parseDirectiveCFIStartProc() { return addErrorSuffix(" in '.cfi_startproc' directive"); } - getStreamer().EmitCFIStartProc(!Simple.empty()); + // TODO(kristina): Deal with a corner case of incorrect diagnostic context + // being produced if this directive is emitted as part of preprocessor macro + // expansion which can *ONLY* happen if Clang's cc1as is the API consumer. + // Tools like llvm-mc on the other hand are not affected by it, and report + // correct context information. + getStreamer().EmitCFIStartProc(!Simple.empty(), Lexer.getLoc()); return false; } @@ -4167,10 +4205,7 @@ bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { bool AsmParser::parseDirectiveAltmacro(StringRef Directive) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '" + Directive + "' directive"); - if (Directive == ".altmacro") - getLexer().SetAltMacroMode(true); - else - getLexer().SetAltMacroMode(false); + AltMacroMode = (Directive == ".altmacro"); return false; } @@ -5242,6 +5277,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE; DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID; DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE; + DirectiveKindMap[".cv_string"] = DK_CV_STRING; DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE; DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS; DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET; @@ -5269,6 +5305,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; + DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME; DirectiveKindMap[".macros_on"] = DK_MACROS_ON; DirectiveKindMap[".macros_off"] = DK_MACROS_OFF; DirectiveKindMap[".macro"] = DK_MACRO; |
