aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCParser/AsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCParser/AsmParser.cpp')
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp651
1 files changed, 414 insertions, 237 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index c5ff241ead74..d3cb5ca59bf3 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -168,6 +169,8 @@ private:
/// List of forward directional labels for diagnosis at the end.
SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
+ SmallSet<StringRef, 2> LTODiscardSymbols;
+
/// AssemblerDialect. ~OU means unset value and use value provided by MAI.
unsigned AssemblerDialect = ~0U;
@@ -183,6 +186,22 @@ private:
// Is alt macro mode enabled.
bool AltMacroMode = false;
+protected:
+ virtual bool parseStatement(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI);
+
+ /// This routine uses the target specific ParseInstruction function to
+ /// parse an instruction into Operands, and then call the target specific
+ /// MatchAndEmit function to match and emit the instruction.
+ bool parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
+ StringRef IDVal, AsmToken ID,
+ SMLoc IDLoc);
+
+ /// Should we emit DWARF describing this assembler source? (Returns false if
+ /// the source has .file directives, which means we don't want to generate
+ /// info describing the assembler source itself.)
+ bool enabledGenDwarfForAssembly();
+
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI, unsigned CB);
@@ -235,9 +254,13 @@ public:
}
bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
- bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
- unsigned &NumOutputs, unsigned &NumInputs,
- SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
+ bool discardLTOSymbol(StringRef Name) const override {
+ return LTODiscardSymbols.contains(Name);
+ }
+
+ bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs,
+ unsigned &NumInputs,
+ SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers,
const MCInstrInfo *MII, const MCInstPrinter *IP,
@@ -266,8 +289,6 @@ public:
/// }
private:
- bool parseStatement(ParseStatementInfo &Info,
- MCAsmParserSemaCallback *SI);
bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
bool parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo = true);
@@ -310,11 +331,6 @@ private:
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
- /// Should we emit DWARF describing this assembler source? (Returns false if
- /// the source has .file directives, which means we don't want to generate
- /// info describing the assembler source itself.)
- bool enabledGenDwarfForAssembly();
-
/// Enter the specified file. This returns true on failure.
bool enterIncludeFile(const std::string &Filename);
@@ -483,6 +499,7 @@ private:
DK_CFI_DEF_CFA_OFFSET,
DK_CFI_ADJUST_CFA_OFFSET,
DK_CFI_DEF_CFA_REGISTER,
+ DK_CFI_LLVM_DEF_ASPACE_CFA,
DK_CFI_OFFSET,
DK_CFI_REL_OFFSET,
DK_CFI_PERSONALITY,
@@ -516,6 +533,7 @@ private:
DK_ADDRSIG,
DK_ADDRSIG_SYM,
DK_PSEUDO_PROBE,
+ DK_LTO_DISCARD,
DK_END
};
@@ -583,6 +601,7 @@ private:
bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
bool parseDirectiveCFIAdjustCfaOffset();
bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
+ bool parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc);
bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
@@ -682,6 +701,9 @@ private:
// .pseudoprobe
bool parseDirectivePseudoProbe();
+ // ".lto_discard"
+ bool parseDirectiveLTODiscard();
+
// Directives to support address-significance tables.
bool parseDirectiveAddrsig();
bool parseDirectiveAddrsigSym();
@@ -690,6 +712,36 @@ private:
void initializeCVDefRangeTypeMap();
};
+class HLASMAsmParser final : public AsmParser {
+private:
+ MCAsmLexer &Lexer;
+ MCStreamer &Out;
+
+ void lexLeadingSpaces() {
+ while (Lexer.is(AsmToken::Space))
+ Lexer.Lex();
+ }
+
+ bool parseAsHLASMLabel(ParseStatementInfo &Info, MCAsmParserSemaCallback *SI);
+ bool parseAsMachineInstruction(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI);
+
+public:
+ HLASMAsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
+ const MCAsmInfo &MAI, unsigned CB = 0)
+ : AsmParser(SM, Ctx, Out, MAI, CB), Lexer(getLexer()), Out(Out) {
+ Lexer.setSkipSpace(false);
+ Lexer.setAllowHashInIdentifier(true);
+ Lexer.setLexHLASMIntegers(true);
+ Lexer.setLexHLASMStrings(true);
+ }
+
+ ~HLASMAsmParser() { Lexer.setSkipSpace(true); }
+
+ bool parseStatement(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI) override;
+};
+
} // end anonymous namespace
namespace llvm {
@@ -697,6 +749,7 @@ namespace llvm {
extern MCAsmParserExtension *createDarwinAsmParser();
extern MCAsmParserExtension *createELFAsmParser();
extern MCAsmParserExtension *createCOFFAsmParser();
+extern MCAsmParserExtension *createXCOFFAsmParser();
extern MCAsmParserExtension *createWasmAsmParser();
} // end namespace llvm
@@ -718,23 +771,24 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
Out.setStartTokLocPtr(&StartTokLoc);
// Initialize the platform / file format parser.
- switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
- case MCObjectFileInfo::IsCOFF:
+ switch (Ctx.getObjectFileType()) {
+ case MCContext::IsCOFF:
PlatformParser.reset(createCOFFAsmParser());
break;
- case MCObjectFileInfo::IsMachO:
+ case MCContext::IsMachO:
PlatformParser.reset(createDarwinAsmParser());
IsDarwin = true;
break;
- case MCObjectFileInfo::IsELF:
+ case MCContext::IsELF:
PlatformParser.reset(createELFAsmParser());
break;
- case MCObjectFileInfo::IsWasm:
+ case MCContext::IsGOFF:
+ report_fatal_error("GOFFAsmParser support not implemented yet");
+ case MCContext::IsWasm:
PlatformParser.reset(createWasmAsmParser());
break;
- case MCObjectFileInfo::IsXCOFF:
- report_fatal_error(
- "Need to implement createXCOFFAsmParser for XCOFF format.");
+ case MCContext::IsXCOFF:
+ PlatformParser.reset(createXCOFFAsmParser());
break;
}
@@ -892,6 +946,8 @@ bool AsmParser::enabledGenDwarfForAssembly() {
}
bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
+ LTODiscardSymbols.clear();
+
// Create the initial section, if requested.
if (!NoInitialTextSection)
Out.InitSections(false);
@@ -919,6 +975,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
(void)InsertResult;
}
+ getTargetParser().onBeginOfFile();
+
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
ParseStatementInfo Info(&AsmStrRewrites);
@@ -1095,25 +1153,33 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
return false;
case AsmToken::Dollar:
+ case AsmToken::Star:
case AsmToken::At:
case AsmToken::String:
case AsmToken::Identifier: {
StringRef Identifier;
if (parseIdentifier(Identifier)) {
- // We may have failed but $ may be a valid token.
- if (getTok().is(AsmToken::Dollar)) {
- if (Lexer.getMAI().getDollarIsPC()) {
- Lex();
- // This is a '$' reference, which references the current PC. Emit a
- // temporary label to the streamer and refer to it.
- MCSymbol *Sym = Ctx.createTempSymbol();
- Out.emitLabel(Sym);
- Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
- getContext());
- EndLoc = FirstTokenLoc;
- return false;
- }
- return Error(FirstTokenLoc, "invalid token in expression");
+ // We may have failed but '$'|'*' may be a valid token in context of
+ // the current PC.
+ if (getTok().is(AsmToken::Dollar) || getTok().is(AsmToken::Star)) {
+ bool ShouldGenerateTempSymbol = false;
+ if ((getTok().is(AsmToken::Dollar) && MAI.getDollarIsPC()) ||
+ (getTok().is(AsmToken::Star) && MAI.getStarIsPC()))
+ ShouldGenerateTempSymbol = true;
+
+ if (!ShouldGenerateTempSymbol)
+ return Error(FirstTokenLoc, "invalid token in expression");
+
+ // Eat the '$'|'*' token.
+ Lex();
+ // This is either a '$'|'*' reference, which references the current PC.
+ // Emit a temporary label to the streamer and refer to it.
+ MCSymbol *Sym = Ctx.createTempSymbol();
+ Out.emitLabel(Sym);
+ Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
+ getContext());
+ EndLoc = FirstTokenLoc;
+ return false;
}
}
// Parse symbol variant
@@ -1167,7 +1233,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
if (!Sym)
- Sym = getContext().getOrCreateSymbol(SymbolName);
+ Sym = getContext().getOrCreateSymbol(
+ MAI.shouldEmitLabelsInUpperCase() ? SymbolName.upper() : SymbolName);
// If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment.
@@ -1230,6 +1297,9 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
return false;
}
case AsmToken::Dot: {
+ if (!MAI.getDotIsPC())
+ return TokError("cannot use . as current PC");
+
// This is a '.' reference, which references the current PC. Emit a
// temporary label to the streamer and refer to it.
MCSymbol *Sym = Ctx.createTempSymbol();
@@ -1770,7 +1840,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
StringMap<DirectiveKind>::const_iterator DirKindIt =
DirectiveKindMap.find(IDVal.lower());
DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
-
? DK_NO_DIRECTIVE
: DirKindIt->getValue();
switch (DirKind) {
@@ -1868,6 +1937,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
Lex();
}
+ if (discardLTOSymbol(IDVal))
+ return false;
+
getTargetParser().doBeforeLabelEmit(Sym);
// Emit the label.
@@ -2119,6 +2191,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveCFIAdjustCfaOffset();
case DK_CFI_DEF_CFA_REGISTER:
return parseDirectiveCFIDefCfaRegister(IDLoc);
+ case DK_CFI_LLVM_DEF_ASPACE_CFA:
+ return parseDirectiveCFILLVMDefAspaceCfa(IDLoc);
case DK_CFI_OFFSET:
return parseDirectiveCFIOffset(IDLoc);
case DK_CFI_REL_OFFSET:
@@ -2208,6 +2282,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveAddrsigSym();
case DK_PSEUDO_PROBE:
return parseDirectivePseudoProbe();
+ case DK_LTO_DISCARD:
+ return parseDirectiveLTODiscard();
}
return Error(IDLoc, "unknown directive");
@@ -2227,6 +2303,13 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (checkForValidSection())
return true;
+ return parseAndMatchAndEmitTargetInstruction(Info, IDVal, ID, IDLoc);
+}
+
+bool AsmParser::parseAndMatchAndEmitTargetInstruction(ParseStatementInfo &Info,
+ StringRef IDVal,
+ AsmToken ID,
+ SMLoc IDLoc) {
// Canonicalize the opcode to lower case.
std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
@@ -2348,7 +2431,7 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
/// will use the last parsed cpp hash line filename comment
/// for the Filename and LineNo if any in the diagnostic.
void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
- const AsmParser *Parser = static_cast<const AsmParser *>(Context);
+ auto *Parser = static_cast<AsmParser *>(Context);
raw_ostream &OS = errs();
const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
@@ -2369,12 +2452,11 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
// If we have not parsed a cpp hash line filename comment or the source
// manager changed or buffer changed (like in a nested include) then just
// print the normal diagnostic using its Filename and LineNo.
- if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
- DiagBuf != CppHashBuf) {
+ if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
else
- Diag.print(nullptr, OS);
+ Parser->getContext().diagnose(Diag);
return;
}
@@ -2394,9 +2476,9 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
Diag.getLineContents(), Diag.getRanges());
if (Parser->SavedDiagHandler)
- Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
+ Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
else
- NewDiag.print(nullptr, OS);
+ Parser->getContext().diagnose(NewDiag);
}
// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The
@@ -2853,6 +2935,9 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
return false;
}
+ if (discardLTOSymbol(Name))
+ return false;
+
// Do the assignment.
Out.emitAssignment(Sym, Value);
if (NoDeadStrip)
@@ -2910,9 +2995,9 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
/// ::= .set identifier ',' expression
bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
- if (check(parseIdentifier(Name), "expected identifier") ||
- parseToken(AsmToken::Comma) || parseAssignment(Name, allow_redef, true))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
+ if (check(parseIdentifier(Name), "expected identifier") || parseComma() ||
+ parseAssignment(Name, allow_redef, true))
+ return true;
return false;
}
@@ -3027,9 +3112,7 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
return false;
};
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- return false;
+ return parseMany(parseOp);
}
/// parseDirectiveReloc
@@ -3041,7 +3124,7 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
if (parseExpression(Offset))
return true;
- if (parseToken(AsmToken::Comma, "expected comma") ||
+ if (parseComma() ||
check(getTok().isNot(AsmToken::Identifier), "expected relocation name"))
return true;
@@ -3060,9 +3143,8 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
return Error(ExprLoc, "expression must be relocatable");
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in .reloc directive"))
- return true;
+ if (parseEOL())
+ return true;
const MCTargetAsmParser &MCT = getTargetParser();
const MCSubtargetInfo &STI = MCT.getSTI();
@@ -3094,9 +3176,7 @@ bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
return false;
};
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- return false;
+ return parseMany(parseOp);
}
static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo) {
@@ -3138,9 +3218,7 @@ bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
return false;
};
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- return false;
+ return parseMany(parseOp);
}
bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
@@ -3163,9 +3241,10 @@ bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
APFloat Value(Semantics);
StringRef IDVal = getTok().getString();
if (getLexer().is(AsmToken::Identifier)) {
- if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
+ if (!IDVal.compare_insensitive("infinity") ||
+ !IDVal.compare_insensitive("inf"))
Value = APFloat::getInf(Semantics);
- else if (!IDVal.compare_lower("nan"))
+ else if (!IDVal.compare_insensitive("nan"))
Value = APFloat::getNaN(Semantics, false, ~0);
else
return TokError("invalid floating point literal");
@@ -3197,9 +3276,7 @@ bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
return false;
};
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- return false;
+ return parseMany(parseOp);
}
/// parseDirectiveZero
@@ -3217,8 +3294,7 @@ bool AsmParser::parseDirectiveZero() {
return true;
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.zero' directive"))
+ if (parseEOL())
return true;
getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
@@ -3248,8 +3324,7 @@ bool AsmParser::parseDirectiveFill() {
return true;
}
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.fill' directive"))
+ if (parseEOL())
return true;
if (FillSize < 0) {
@@ -3281,9 +3356,9 @@ bool AsmParser::parseDirectiveOrg() {
int64_t FillExpr = 0;
if (parseOptionalToken(AsmToken::Comma))
if (parseAbsoluteExpression(FillExpr))
- return addErrorSuffix(" in '.org' directive");
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.org' directive");
+ return true;
+ if (parseEOL())
+ return true;
getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
return false;
@@ -3316,18 +3391,18 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
parseAbsoluteExpression(MaxBytesToFill))
return true;
}
- return parseToken(AsmToken::EndOfStatement);
+ return parseEOL();
};
if (checkForValidSection())
- return addErrorSuffix(" in directive");
+ return true;
// Ignore empty '.p2align' directives for GNU-as compatibility
if (IsPow2 && (ValueSize == 1) && getTok().is(AsmToken::EndOfStatement)) {
Warning(AlignmentLoc, "p2align directive with no operand(s) is ignored");
- return parseToken(AsmToken::EndOfStatement);
+ return parseEOL();
}
if (parseAlign())
- return addErrorSuffix(" in directive");
+ return true;
// Always emit an alignment here even if we thrown an error.
bool ReturnVal = false;
@@ -3404,9 +3479,7 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
// Usually the directory and filename together, otherwise just the directory.
// Allow the strings to have escaped octal character sequence.
- if (check(getTok().isNot(AsmToken::String),
- "unexpected token in '.file' directive") ||
- parseEscapedString(Path))
+ if (parseEscapedString(Path))
return true;
StringRef Directory;
@@ -3485,8 +3558,9 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
Source = StringRef(SourceBuf, SourceString.size());
}
if (FileNumber == 0) {
+ // Upgrade to Version 5 for assembly actions like clang -c a.s.
if (Ctx.getDwarfVersion() < 5)
- return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
+ Ctx.setDwarfVersion(5);
getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
} else {
Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
@@ -3515,11 +3589,7 @@ bool AsmParser::parseDirectiveLine() {
(void)LineNumber;
// FIXME: Do something with the .line.
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.line' directive"))
- return true;
-
- return false;
+ return parseEOL();
}
/// parseDirectiveLoc
@@ -3841,15 +3911,13 @@ bool AsmParser::parseDirectiveCVLinetable() {
int64_t FunctionId;
StringRef FnStartName, FnEndName;
SMLoc Loc = getTok().getLoc();
- if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
- parseToken(AsmToken::Comma,
- "unexpected token in '.cv_linetable' directive") ||
- parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
- "expected identifier in directive") ||
- parseToken(AsmToken::Comma,
- "unexpected token in '.cv_linetable' directive") ||
- parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
- "expected identifier in directive"))
+ if (parseCVFunctionId(FunctionId, ".cv_linetable") || parseComma() ||
+ parseTokenLoc(Loc) ||
+ check(parseIdentifier(FnStartName), Loc,
+ "expected identifier in directive") ||
+ parseComma() || parseTokenLoc(Loc) ||
+ check(parseIdentifier(FnEndName), Loc,
+ "expected identifier in directive"))
return true;
MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
@@ -4016,7 +4084,7 @@ bool AsmParser::parseDirectiveCVDefRange() {
bool AsmParser::parseDirectiveCVString() {
std::string Data;
if (checkForValidSection() || parseEscapedString(Data))
- return addErrorSuffix(" in '.cv_string' directive");
+ return true;
// Put the string in the table and emit the offset.
std::pair<StringRef, unsigned> Insertion =
@@ -4058,8 +4126,8 @@ bool AsmParser::parseDirectiveCVFPOData() {
StringRef ProcName;
if (parseIdentifier(ProcName))
return TokError("expected symbol name");
- if (parseEOL("unexpected tokens"))
- return addErrorSuffix(" in '.cv_fpo_data' directive");
+ if (parseEOL())
+ return true;
MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
getStreamer().EmitCVFPOData(ProcSym, DirLoc);
return false;
@@ -4072,29 +4140,20 @@ bool AsmParser::parseDirectiveCFISections() {
bool EH = false;
bool Debug = false;
- if (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 (parseIdentifier(Name))
- return TokError("Expected an identifier");
-
- if (Name == ".eh_frame")
- EH = true;
- else if (Name == ".debug_frame")
- Debug = true;
+ if (!parseOptionalToken(AsmToken::EndOfStatement)) {
+ for (;;) {
+ if (parseIdentifier(Name))
+ return TokError("expected .eh_frame or .debug_frame");
+ if (Name == ".eh_frame")
+ EH = true;
+ else if (Name == ".debug_frame")
+ Debug = true;
+ if (parseOptionalToken(AsmToken::EndOfStatement))
+ break;
+ if (parseComma())
+ return true;
+ }
}
-
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.cfi_sections' directive");
-
getStreamer().emitCFISections(EH, Debug);
return false;
}
@@ -4106,8 +4165,8 @@ bool AsmParser::parseDirectiveCFIStartProc() {
if (!parseOptionalToken(AsmToken::EndOfStatement)) {
if (check(parseIdentifier(Simple) || Simple != "simple",
"unexpected token") ||
- parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.cfi_startproc' directive");
+ parseEOL())
+ return true;
}
// TODO(kristina): Deal with a corner case of incorrect diagnostic context
@@ -4122,8 +4181,8 @@ bool AsmParser::parseDirectiveCFIStartProc() {
/// parseDirectiveCFIEndProc
/// ::= .cfi_endproc
bool AsmParser::parseDirectiveCFIEndProc() {
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.cfi_endproc' directive");
+ if (parseEOL())
+ return true;
getStreamer().emitCFIEndProc();
return false;
}
@@ -4147,9 +4206,8 @@ bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
/// ::= .cfi_def_cfa register, offset
bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
int64_t Register = 0, Offset = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseAbsoluteExpression(Offset))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
+ parseAbsoluteExpression(Offset) || parseEOL())
return true;
getStreamer().emitCFIDefCfa(Register, Offset);
@@ -4160,7 +4218,7 @@ bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
/// ::= .cfi_def_cfa_offset offset
bool AsmParser::parseDirectiveCFIDefCfaOffset() {
int64_t Offset = 0;
- if (parseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset) || parseEOL())
return true;
getStreamer().emitCFIDefCfaOffset(Offset);
@@ -4171,9 +4229,8 @@ bool AsmParser::parseDirectiveCFIDefCfaOffset() {
/// ::= .cfi_register register, register
bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
int64_t Register1 = 0, Register2 = 0;
- if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || parseComma() ||
+ parseRegisterOrRegisterNumber(Register2, DirectiveLoc) || parseEOL())
return true;
getStreamer().emitCFIRegister(Register1, Register2);
@@ -4183,6 +4240,8 @@ bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
/// parseDirectiveCFIWindowSave
/// ::= .cfi_window_save
bool AsmParser::parseDirectiveCFIWindowSave() {
+ if (parseEOL())
+ return true;
getStreamer().emitCFIWindowSave();
return false;
}
@@ -4191,7 +4250,7 @@ bool AsmParser::parseDirectiveCFIWindowSave() {
/// ::= .cfi_adjust_cfa_offset adjustment
bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
int64_t Adjustment = 0;
- if (parseAbsoluteExpression(Adjustment))
+ if (parseAbsoluteExpression(Adjustment) || parseEOL())
return true;
getStreamer().emitCFIAdjustCfaOffset(Adjustment);
@@ -4202,22 +4261,34 @@ bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
/// ::= .cfi_def_cfa_register register
bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
return true;
getStreamer().emitCFIDefCfaRegister(Register);
return false;
}
+/// parseDirectiveCFILLVMDefAspaceCfa
+/// ::= .cfi_llvm_def_aspace_cfa register, offset, address_space
+bool AsmParser::parseDirectiveCFILLVMDefAspaceCfa(SMLoc DirectiveLoc) {
+ int64_t Register = 0, Offset = 0, AddressSpace = 0;
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
+ parseAbsoluteExpression(Offset) || parseComma() ||
+ parseAbsoluteExpression(AddressSpace) || parseEOL())
+ return true;
+
+ getStreamer().emitCFILLVMDefAspaceCfa(Register, Offset, AddressSpace);
+ return false;
+}
+
/// parseDirectiveCFIOffset
/// ::= .cfi_offset register, offset
bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
int64_t Offset = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseAbsoluteExpression(Offset))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
+ parseAbsoluteExpression(Offset) || parseEOL())
return true;
getStreamer().emitCFIOffset(Register, Offset);
@@ -4229,9 +4300,8 @@ bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
int64_t Register = 0, Offset = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseAbsoluteExpression(Offset))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseComma() ||
+ parseAbsoluteExpression(Offset) || parseEOL())
return true;
getStreamer().emitCFIRelOffset(Register, Offset);
@@ -4273,8 +4343,9 @@ bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
StringRef Name;
if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- check(parseIdentifier(Name), "expected identifier in directive"))
+ parseComma() ||
+ check(parseIdentifier(Name), "expected identifier in directive") ||
+ parseEOL())
return true;
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
@@ -4289,6 +4360,8 @@ bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
/// parseDirectiveCFIRememberState
/// ::= .cfi_remember_state
bool AsmParser::parseDirectiveCFIRememberState() {
+ if (parseEOL())
+ return true;
getStreamer().emitCFIRememberState();
return false;
}
@@ -4296,6 +4369,8 @@ bool AsmParser::parseDirectiveCFIRememberState() {
/// parseDirectiveCFIRestoreState
/// ::= .cfi_remember_state
bool AsmParser::parseDirectiveCFIRestoreState() {
+ if (parseEOL())
+ return true;
getStreamer().emitCFIRestoreState();
return false;
}
@@ -4305,7 +4380,7 @@ bool AsmParser::parseDirectiveCFIRestoreState() {
bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
return true;
getStreamer().emitCFISameValue(Register);
@@ -4316,7 +4391,7 @@ bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
/// ::= .cfi_restore register
bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
return true;
getStreamer().emitCFIRestore(Register);
@@ -4350,7 +4425,7 @@ bool AsmParser::parseDirectiveCFIEscape() {
/// ::= .cfi_return_column register
bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
return true;
getStreamer().emitCFIReturnColumn(Register);
return false;
@@ -4359,8 +4434,7 @@ bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
/// parseDirectiveCFISignalFrame
/// ::= .cfi_signal_frame
bool AsmParser::parseDirectiveCFISignalFrame() {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.cfi_signal_frame'"))
+ if (parseEOL())
return true;
getStreamer().emitCFISignalFrame();
@@ -4372,7 +4446,7 @@ bool AsmParser::parseDirectiveCFISignalFrame() {
bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || parseEOL())
return true;
getStreamer().emitCFIUndefined(Register);
@@ -4383,8 +4457,8 @@ bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
/// ::= .altmacro
/// ::= .noaltmacro
bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + Directive + "' directive");
+ if (parseEOL())
+ return true;
AltMacroMode = (Directive == ".altmacro");
return false;
}
@@ -4393,10 +4467,8 @@ bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
/// ::= .macros_on
/// ::= .macros_off
bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Directive + "' directive"))
+ if (parseEOL())
return true;
-
setMacrosEnabled(Directive == ".macros_on");
return false;
}
@@ -4635,8 +4707,7 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
/// parseDirectiveExitMacro
/// ::= .exitm
bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Directive + "' directive"))
+ if (parseEOL())
return true;
if (!isInsideMacroInstantiation())
@@ -4674,15 +4745,14 @@ bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
}
/// parseDirectivePurgeMacro
-/// ::= .purgem
+/// ::= .purgem name
bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
SMLoc Loc;
if (parseTokenLoc(Loc) ||
check(parseIdentifier(Name), Loc,
"expected identifier in '.purgem' directive") ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.purgem' directive"))
+ parseEOL())
return true;
if (!getContext().lookupMacro(Name))
@@ -4702,9 +4772,7 @@ bool AsmParser::parseDirectiveBundleAlignMode() {
SMLoc ExprLoc = getLexer().getLoc();
int64_t AlignSizePow2;
if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
- parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
- "in '.bundle_align_mode' "
- "directive") ||
+ parseEOL() ||
check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
"invalid bundle alignment size (expected between 0 and 30)"))
return true;
@@ -4729,9 +4797,7 @@ bool AsmParser::parseDirectiveBundleLock() {
if (!parseOptionalToken(AsmToken::EndOfStatement)) {
if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
- check(Option != "align_to_end", Loc, kInvalidOptionError) ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token after '.bundle_lock' directive option"))
+ check(Option != "align_to_end", Loc, kInvalidOptionError) || parseEOL())
return true;
AlignToEnd = true;
}
@@ -4743,9 +4809,7 @@ bool AsmParser::parseDirectiveBundleLock() {
/// parseDirectiveBundleLock
/// ::= {.bundle_lock}
bool AsmParser::parseDirectiveBundleUnlock() {
- if (checkForValidSection() ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.bundle_unlock' directive"))
+ if (checkForValidSection() || parseEOL())
return true;
getStreamer().emitBundleUnlock();
@@ -4763,9 +4827,9 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
int64_t FillExpr = 0;
if (parseOptionalToken(AsmToken::Comma))
if (parseAbsoluteExpression(FillExpr))
- return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
+ return true;
+ if (parseEOL())
+ return true;
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
@@ -4786,8 +4850,7 @@ bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
return false;
}
- if (parseToken(AsmToken::Comma,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
+ if (parseComma())
return true;
const MCExpr *Value;
@@ -4808,11 +4871,7 @@ bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
getStreamer().emitValue(Value, Size, ExprLoc);
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
-
- return false;
+ return parseEOL();
}
/// parseDirectiveRealDCB
@@ -4828,16 +4887,11 @@ bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Seman
return false;
}
- if (parseToken(AsmToken::Comma,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
+ if (parseComma())
return true;
APInt AsInt;
- if (parseRealValue(Semantics, AsInt))
- return true;
-
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
+ if (parseRealValue(Semantics, AsInt) || parseEOL())
return true;
for (uint64_t i = 0, e = NumValues; i != e; ++i)
@@ -4852,7 +4906,8 @@ bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Seman
bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
SMLoc NumValuesLoc = Lexer.getLoc();
int64_t NumValues;
- if (checkForValidSection() || parseAbsoluteExpression(NumValues))
+ if (checkForValidSection() || parseAbsoluteExpression(NumValues) ||
+ parseEOL())
return true;
if (NumValues < 0) {
@@ -4860,10 +4915,6 @@ bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
return false;
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
-
for (uint64_t i = 0, e = NumValues; i != e; ++i)
getStreamer().emitFill(Size, 0);
@@ -4887,10 +4938,7 @@ bool AsmParser::parseDirectiveLEB128(bool Signed) {
return false;
};
- if (parseMany(parseOp))
- return addErrorSuffix(" in directive");
-
- return false;
+ return parseMany(parseOp);
}
/// parseDirectiveSymbolAttribute
@@ -4901,6 +4949,10 @@ bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
SMLoc Loc = getTok().getLoc();
if (parseIdentifier(Name))
return Error(Loc, "expected identifier");
+
+ if (discardLTOSymbol(Name))
+ return false;
+
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
// Assembler local symbols don't make any sense here. Complain loudly.
@@ -4912,9 +4964,7 @@ bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
return false;
};
- if (parseMany(parseOp))
- return addErrorSuffix(" in directive");
- return false;
+ return parseMany(parseOp);
}
/// parseDirectiveComm
@@ -4931,9 +4981,8 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) {
// Handle the identifier as the key symbol.
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseComma())
+ return true;
int64_t Size;
SMLoc SizeLoc = getLexer().getLoc();
@@ -4961,8 +5010,7 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) {
}
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.comm' or '.lcomm' directive"))
+ if (parseEOL())
return true;
// NOTE: a size of zero for a .comm should create a undefined symbol
@@ -4999,8 +5047,7 @@ bool AsmParser::parseDirectiveAbort() {
SMLoc Loc = getLexer().getLoc();
StringRef Str = parseStringToEndOfStatement();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.abort' directive"))
+ if (parseEOL())
return true;
if (Str.empty())
@@ -5061,8 +5108,7 @@ bool AsmParser::parseDirectiveIncbin() {
}
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.incbin' directive"))
+ if (parseEOL())
return true;
if (check(Skip < 0, SkipLoc, "skip is negative"))
@@ -5083,9 +5129,7 @@ bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
eatToEndOfStatement();
} else {
int64_t ExprValue;
- if (parseAbsoluteExpression(ExprValue) ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.if' directive"))
+ if (parseAbsoluteExpression(ExprValue) || parseEOL())
return true;
switch (DirKind) {
@@ -5129,8 +5173,7 @@ bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
} else {
StringRef Str = parseStringToEndOfStatement();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.ifb' directive"))
+ if (parseEOL())
return true;
TheCondState.CondMet = ExpectBlank == Str.empty();
@@ -5152,13 +5195,12 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
} else {
StringRef Str1 = parseStringToComma();
- if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
+ if (parseComma())
return true;
StringRef Str2 = parseStringToEndOfStatement();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.ifc' directive"))
+ if (parseEOL())
return true;
TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
@@ -5217,7 +5259,7 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
eatToEndOfStatement();
} else {
if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
- parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
+ parseEOL())
return true;
MCSymbol *Sym = getContext().lookupSymbol(Name);
@@ -5252,8 +5294,7 @@ bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
if (parseAbsoluteExpression(ExprValue))
return true;
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.elseif' directive"))
+ if (parseEOL())
return true;
TheCondState.CondMet = ExprValue;
@@ -5266,8 +5307,7 @@ bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
/// parseDirectiveElse
/// ::= .else
bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.else' directive"))
+ if (parseEOL())
return true;
if (TheCondState.TheCond != AsmCond::IfCond &&
@@ -5289,8 +5329,7 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
/// parseDirectiveEnd
/// ::= .end
bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.end' directive"))
+ if (parseEOL())
return true;
while (Lexer.isNot(AsmToken::Eof))
@@ -5343,8 +5382,7 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
Message = getTok().getStringContents();
Lex();
- if (parseToken(AsmToken::EndOfStatement,
- "expected end of statement in '.warning' directive"))
+ if (parseEOL())
return true;
}
@@ -5354,8 +5392,7 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.endif' directive"))
+ if (parseEOL())
return true;
if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
@@ -5481,6 +5518,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
+ DirectiveKindMap[".cfi_llvm_def_aspace_cfa"] = DK_CFI_LLVM_DEF_ASPACE_CFA;
DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
@@ -5536,6 +5574,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".addrsig"] = DK_ADDRSIG;
DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM;
DirectiveKindMap[".pseudoprobe"] = DK_PSEUDO_PROBE;
+ DirectiveKindMap[".lto_discard"] = DK_LTO_DISCARD;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
@@ -5617,9 +5656,7 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
}
- if (check(Count < 0, CountLoc, "Count is negative") ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Dir + "' directive"))
+ if (check(Count < 0, CountLoc, "Count is negative") || parseEOL())
return true;
// Lex the rept definition.
@@ -5648,9 +5685,7 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
MCAsmMacroArguments A;
if (check(parseIdentifier(Parameter.Name),
"expected identifier in '.irp' directive") ||
- parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
- parseMacroArguments(nullptr, A) ||
- parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
+ parseComma() || parseMacroArguments(nullptr, A) || parseEOL())
return true;
// Lex the irp definition.
@@ -5683,15 +5718,12 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
if (check(parseIdentifier(Parameter.Name),
"expected identifier in '.irpc' directive") ||
- parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
- parseMacroArguments(nullptr, A))
+ parseComma() || parseMacroArguments(nullptr, A))
return true;
if (A.size() != 1 || A.front().size() != 1)
return TokError("unexpected token in '.irpc' directive");
-
- // Eat the end of statement.
- if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
+ if (parseEOL())
return true;
// Lex the irpc definition.
@@ -5770,21 +5802,22 @@ bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
Lex();
if (StrTok.isNot(AsmToken::String) || StrTok.getString().front() != '"')
return Error(DirectiveLoc, "expected double quoted string after .print");
- if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
+ if (parseEOL())
return true;
llvm::outs() << StrTok.getStringContents() << '\n';
return false;
}
bool AsmParser::parseDirectiveAddrsig() {
+ if (parseEOL())
+ return true;
getStreamer().emitAddrsig();
return false;
}
bool AsmParser::parseDirectiveAddrsigSym() {
StringRef Name;
- if (check(parseIdentifier(Name),
- "expected identifier in '.addrsig_sym' directive"))
+ if (check(parseIdentifier(Name), "expected identifier") || parseEOL())
return true;
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
getStreamer().emitAddrsigSym(Sym);
@@ -5846,14 +5879,32 @@ bool AsmParser::parseDirectivePseudoProbe() {
InlineStack.push_back(Site);
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.pseudoprobe' directive"))
+ if (parseEOL())
return true;
getStreamer().emitPseudoProbe(Guid, Index, Type, Attr, InlineStack);
return false;
}
+/// parseDirectiveLTODiscard
+/// ::= ".lto_discard" [ identifier ( , identifier )* ]
+/// The LTO library emits this directive to discard non-prevailing symbols.
+/// We ignore symbol assignments and attribute changes for the specified
+/// symbols.
+bool AsmParser::parseDirectiveLTODiscard() {
+ auto ParseOp = [&]() -> bool {
+ StringRef Name;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIdentifier(Name))
+ return Error(Loc, "expected identifier");
+ LTODiscardSymbols.insert(Name);
+ return false;
+ };
+
+ LTODiscardSymbols.clear();
+ return parseMany(ParseOp);
+}
+
// We are comparing pointers, but the pointers are relative to a single string.
// Thus, this should always be deterministic.
static int rewritesSort(const AsmRewrite *AsmRewriteA,
@@ -5878,8 +5929,8 @@ static int rewritesSort(const AsmRewrite *AsmRewriteA,
}
bool AsmParser::parseMSInlineAsm(
- void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
- unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
+ std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs,
+ SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
SmallVectorImpl<std::string> &Constraints,
SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
@@ -6141,6 +6192,129 @@ bool AsmParser::parseMSInlineAsm(
return false;
}
+bool HLASMAsmParser::parseAsHLASMLabel(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI) {
+ AsmToken LabelTok = getTok();
+ SMLoc LabelLoc = LabelTok.getLoc();
+ StringRef LabelVal;
+
+ if (parseIdentifier(LabelVal))
+ return Error(LabelLoc, "The HLASM Label has to be an Identifier");
+
+ // We have validated whether the token is an Identifier.
+ // Now we have to validate whether the token is a
+ // valid HLASM Label.
+ if (!getTargetParser().isLabel(LabelTok) || checkForValidSection())
+ return true;
+
+ // Lex leading spaces to get to the next operand.
+ lexLeadingSpaces();
+
+ // We shouldn't emit the label if there is nothing else after the label.
+ // i.e asm("<token>\n")
+ if (getTok().is(AsmToken::EndOfStatement))
+ return Error(LabelLoc,
+ "Cannot have just a label for an HLASM inline asm statement");
+
+ MCSymbol *Sym = getContext().getOrCreateSymbol(
+ getContext().getAsmInfo()->shouldEmitLabelsInUpperCase()
+ ? LabelVal.upper()
+ : LabelVal);
+
+ getTargetParser().doBeforeLabelEmit(Sym);
+
+ // Emit the label.
+ Out.emitLabel(Sym, LabelLoc);
+
+ // If we are generating dwarf for assembly source files then gather the
+ // info to make a dwarf label entry for this label if needed.
+ if (enabledGenDwarfForAssembly())
+ MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
+ LabelLoc);
+
+ getTargetParser().onLabelParsed(Sym);
+
+ return false;
+}
+
+bool HLASMAsmParser::parseAsMachineInstruction(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI) {
+ AsmToken OperationEntryTok = Lexer.getTok();
+ SMLoc OperationEntryLoc = OperationEntryTok.getLoc();
+ StringRef OperationEntryVal;
+
+ // Attempt to parse the first token as an Identifier
+ if (parseIdentifier(OperationEntryVal))
+ return Error(OperationEntryLoc, "unexpected token at start of statement");
+
+ // Once we've parsed the operation entry successfully, lex
+ // any spaces to get to the OperandEntries.
+ lexLeadingSpaces();
+
+ return parseAndMatchAndEmitTargetInstruction(
+ Info, OperationEntryVal, OperationEntryTok, OperationEntryLoc);
+}
+
+bool HLASMAsmParser::parseStatement(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI) {
+ assert(!hasPendingError() && "parseStatement started with pending error");
+
+ // Should the first token be interpreted as a HLASM Label.
+ bool ShouldParseAsHLASMLabel = false;
+
+ // If a Name Entry exists, it should occur at the very
+ // start of the string. In this case, we should parse the
+ // first non-space token as a Label.
+ // If the Name entry is missing (i.e. there's some other
+ // token), then we attempt to parse the first non-space
+ // token as a Machine Instruction.
+ if (getTok().isNot(AsmToken::Space))
+ ShouldParseAsHLASMLabel = true;
+
+ // If we have an EndOfStatement (which includes the target's comment
+ // string) we can appropriately lex it early on)
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ // if this is a line comment we can drop it safely
+ if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
+ getTok().getString().front() == '\n')
+ Out.AddBlankLine();
+ Lex();
+ return false;
+ }
+
+ // We have established how to parse the inline asm statement.
+ // Now we can safely lex any leading spaces to get to the
+ // first token.
+ lexLeadingSpaces();
+
+ // If we see a new line or carriage return as the first operand,
+ // after lexing leading spaces, emit the new line and lex the
+ // EndOfStatement token.
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ if (getTok().getString().front() == '\n' ||
+ getTok().getString().front() == '\r') {
+ Out.AddBlankLine();
+ Lex();
+ return false;
+ }
+ }
+
+ // Handle the label first if we have to before processing the rest
+ // of the tokens as a machine instruction.
+ if (ShouldParseAsHLASMLabel) {
+ // If there were any errors while handling and emitting the label,
+ // early return.
+ if (parseAsHLASMLabel(Info, SI)) {
+ // If we know we've failed in parsing, simply eat until end of the
+ // statement. This ensures that we don't process any other statements.
+ eatToEndOfStatement();
+ return true;
+ }
+ }
+
+ return parseAsMachineInstruction(Info, SI);
+}
+
namespace llvm {
namespace MCParserUtils {
@@ -6184,7 +6358,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
// a = b
// b = c
- if (Parser.parseToken(AsmToken::EndOfStatement))
+ if (Parser.parseEOL())
return true;
// Validate that the LHS is allowed to be a variable (either it has not been
@@ -6228,5 +6402,8 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,
MCStreamer &Out, const MCAsmInfo &MAI,
unsigned CB) {
+ if (C.getTargetTriple().isSystemZ() && C.getTargetTriple().isOSzOS())
+ return new HLASMAsmParser(SM, C, Out, MAI, CB);
+
return new AsmParser(SM, C, Out, MAI, CB);
}