summaryrefslogtreecommitdiff
path: root/gnu/llvm
diff options
context:
space:
mode:
authorPascal Stumpf <pascal@cvs.openbsd.org>2016-09-03 22:47:03 +0000
committerPascal Stumpf <pascal@cvs.openbsd.org>2016-09-03 22:47:03 +0000
commit96492d9ddd9680e3cc078bc1c8da8434c1ae7b7b (patch)
tree51d98c6b7543756ab1bb4693f9dc5f9cc4b10e04 /gnu/llvm
parent61f3b5b70eeb5a975fdbdaae0033ce025d2fd88b (diff)
Use the space freed up by sparc and zaurus to import LLVM.
ok hackroom@
Diffstat (limited to 'gnu/llvm')
-rw-r--r--gnu/llvm/lib/MC/MCParser/AsmParser.cpp2352
1 files changed, 908 insertions, 1444 deletions
diff --git a/gnu/llvm/lib/MC/MCParser/AsmParser.cpp b/gnu/llvm/lib/MC/MCParser/AsmParser.cpp
index da54155b3b9..646cbb43cae 100644
--- a/gnu/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/gnu/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -12,69 +12,44 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/AsmCond.h"
#include "llvm/MC/MCParser/AsmLexer.h"
-#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCAsmParserUtils.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
-#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
#include <cctype>
-#include <cstddef>
-#include <cstdint>
#include <deque>
-#include <memory>
-#include <sstream>
+#include <set>
#include <string>
-#include <tuple>
-#include <utility>
#include <vector>
-
using namespace llvm;
MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
-static cl::opt<unsigned> AsmMacroMaxNestingDepth(
- "asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
- cl::desc("The maximum nesting depth allowed for assembly macros."));
-
namespace {
-
/// \brief Helper types for tracking macro definitions.
typedef std::vector<AsmToken> MCAsmMacroArgument;
typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
@@ -140,7 +115,6 @@ struct ParseStatementInfo {
class AsmParser : public MCAsmParser {
AsmParser(const AsmParser &) = delete;
void operator=(const AsmParser &) = delete;
-
private:
AsmLexer Lexer;
MCContext &Ctx;
@@ -178,18 +152,14 @@ private:
/// \brief Keeps track of how many .macro's have been instantiated.
unsigned NumOfMacroInstantiations;
- /// The values from the last parsed cpp hash file line comment if any.
- struct CppHashInfoTy {
- StringRef Filename;
- int64_t LineNumber = 0;
- SMLoc Loc;
- unsigned Buf = 0;
- };
- CppHashInfoTy CppHashInfo;
-
- /// \brief List of forward directional labels for diagnosis at the end.
- SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
+ /// Flag tracking whether any errors have been encountered.
+ unsigned HadError : 1;
+ /// The values from the last parsed cpp hash file line comment if any.
+ StringRef CppHashFilename;
+ int64_t CppHashLineNumber;
+ SMLoc CppHashLoc;
+ unsigned CppHashBuf;
/// When generating dwarf for assembly source files we need to calculate the
/// logical line number based on the last parsed cpp hash file line comment
/// and current line. Since this is slow and messes up the SourceMgr's
@@ -231,9 +201,6 @@ public:
MCAsmLexer &getLexer() override { return Lexer; }
MCContext &getContext() override { return Ctx; }
MCStreamer &getStreamer() override { return Out; }
-
- CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
-
unsigned getAssemblerDialect() override {
if (AssemblerDialect == ~0U)
return MAI.getAssemblerDialect();
@@ -244,16 +211,16 @@ public:
AssemblerDialect = i;
}
- void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override;
- bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override;
- bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override;
+ void Note(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) override;
+ bool Warning(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) override;
+ bool Error(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) override;
const AsmToken &Lex() override;
- void setParsingInlineAsm(bool V) override {
- ParsingInlineAsm = V;
- Lexer.setParsingMSInlineAsm(V);
- }
+ void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; }
bool isParsingInlineAsm() override { return ParsingInlineAsm; }
bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
@@ -272,23 +239,19 @@ public:
SMLoc &EndLoc) override;
bool parseAbsoluteExpression(int64_t &Res) override;
- /// \brief Parse a floating point expression using the float \p Semantics
- /// and set \p Res to the value.
- bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
-
/// \brief Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
bool parseIdentifier(StringRef &Res) override;
void eatToEndOfStatement() override;
- bool checkForValidSection() override;
-
+ void checkForValidSection() override;
/// }
private:
+
bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
- bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
+ void eatToEndOfLine();
bool parseCppHashLineFilenameComment(SMLoc L);
void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
@@ -335,8 +298,7 @@ private:
void printMacroInstantiations();
void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
- SMRange Range = None) const {
- ArrayRef<SMRange> Ranges(Range);
+ ArrayRef<SMRange> Ranges = None) const {
SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
@@ -346,8 +308,7 @@ private:
/// \brief Process the specified file for the .incbin directive.
/// This returns true on failure.
- bool processIncbinFile(const std::string &Filename, int64_t Skip = 0,
- const MCExpr *Count = nullptr, SMLoc Loc = SMLoc());
+ bool processIncbinFile(const std::string &Filename);
/// \brief Reset the current lexer position to that given by \p Loc. The
/// current token is not set; clients should ensure Lex() is called
@@ -378,33 +339,24 @@ private:
bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
- bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
- bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
-
// Generic (target and platform independent) directive parsing.
enum DirectiveKind {
DK_NO_DIRECTIVE, // Placeholder
DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT,
DK_RELOC,
DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA,
- DK_DC, DK_DC_A, DK_DC_B, DK_DC_D, DK_DC_L, DK_DC_S, DK_DC_W, DK_DC_X,
- DK_DCB, DK_DCB_B, DK_DCB_D, DK_DCB_L, DK_DCB_S, DK_DCB_W, DK_DCB_X,
- DK_DS, DK_DS_B, DK_DS_D, DK_DS_L, DK_DS_P, DK_DS_S, DK_DS_W, DK_DS_X,
DK_SINGLE, DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL,
- DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER,
- DK_PRIVATE_EXTERN, DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
+ DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN,
+ DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
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_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_CV_FILE, DK_CV_FUNC_ID, DK_CV_INLINE_SITE_ID, DK_CV_LOC, DK_CV_LINETABLE,
- DK_CV_INLINE_LINETABLE, DK_CV_DEF_RANGE, DK_CV_STRINGTABLE,
- DK_CV_FILECHECKSUMS,
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,
DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,
@@ -425,11 +377,9 @@ private:
// ".ascii", ".asciz", ".string"
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc"
- bool parseDirectiveValue(StringRef IDVal,
- unsigned Size); // ".byte", ".long", ...
- bool parseDirectiveOctaValue(StringRef IDVal); // ".octa", ...
- bool parseDirectiveRealValue(StringRef IDVal,
- const fltSemantics &); // ".single", ...
+ bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ...
+ bool parseDirectiveOctaValue(); // ".octa"
+ bool parseDirectiveRealValue(const fltSemantics &); // ".single", ...
bool parseDirectiveFill(); // ".fill"
bool parseDirectiveZero(); // ".zero"
// ".set", ".equ", ".equiv"
@@ -444,18 +394,6 @@ private:
bool parseDirectiveLoc();
bool parseDirectiveStabs();
- // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
- // ".cv_inline_linetable", ".cv_def_range"
- bool parseDirectiveCVFile();
- bool parseDirectiveCVFuncId();
- bool parseDirectiveCVInlineSiteId();
- bool parseDirectiveCVLoc();
- bool parseDirectiveCVLinetable();
- bool parseDirectiveCVInlineLinetable();
- bool parseDirectiveCVDefRange();
- bool parseDirectiveCVStringTable();
- bool parseDirectiveCVFileChecksums();
-
// .cfi directives
bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
bool parseDirectiveCFIWindowSave();
@@ -494,12 +432,6 @@ private:
// ".space", ".skip"
bool parseDirectiveSpace(StringRef IDVal);
- // ".dcb"
- bool parseDirectiveDCB(StringRef IDVal, unsigned Size);
- bool parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &);
- // ".ds"
- bool parseDirectiveDS(StringRef IDVal, unsigned Size);
-
// .sleb128 (Signed=true) and .uleb128 (Signed=false)
bool parseDirectiveLEB128(bool Signed);
@@ -558,8 +490,7 @@ private:
void initializeDirectiveKindMap();
};
-
-} // end anonymous namespace
+}
namespace llvm {
@@ -567,7 +498,7 @@ extern MCAsmParserExtension *createDarwinAsmParser();
extern MCAsmParserExtension *createELFAsmParser();
extern MCAsmParserExtension *createCOFFAsmParser();
-} // end namespace llvm
+}
enum { DEFAULT_ADDRSPACE = 0 };
@@ -575,9 +506,8 @@ 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), CppHashInfo(), AssemblerDialect(~0U),
- IsDarwin(false), ParsingInlineAsm(false) {
- HadError = false;
+ MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0),
+ AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -620,25 +550,24 @@ void AsmParser::printMacroInstantiations() {
"while in macro instantiation");
}
-void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
- printPendingErrors();
- printMessage(L, SourceMgr::DK_Note, Msg, Range);
+void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
+ printMessage(L, SourceMgr::DK_Note, Msg, Ranges);
printMacroInstantiations();
}
-bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
+bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
if(getTargetParser().getTargetOptions().MCNoWarn)
return false;
if (getTargetParser().getTargetOptions().MCFatalWarnings)
- return Error(L, Msg, Range);
- printMessage(L, SourceMgr::DK_Warning, Msg, Range);
+ return Error(L, Msg, Ranges);
+ printMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
printMacroInstantiations();
return false;
}
-bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
+bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
HadError = true;
- printMessage(L, SourceMgr::DK_Error, Msg, Range);
+ printMessage(L, SourceMgr::DK_Error, Msg, Ranges);
printMacroInstantiations();
return true;
}
@@ -658,8 +587,7 @@ bool AsmParser::enterIncludeFile(const std::string &Filename) {
/// Process the specified .incbin file by searching for it in the include paths
/// then just emitting the byte contents of the file to the streamer. This
/// returns true on failure.
-bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
- const MCExpr *Count, SMLoc Loc) {
+bool AsmParser::processIncbinFile(const std::string &Filename) {
std::string IncludedFile;
unsigned NewBuf =
SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
@@ -667,17 +595,7 @@ bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
return true;
// Pick up the bytes from the file and emit them.
- StringRef Bytes = SrcMgr.getMemoryBuffer(NewBuf)->getBuffer();
- Bytes = Bytes.drop_front(Skip);
- if (Count) {
- int64_t Res;
- if (!Count->evaluateAsAbsolute(Res))
- return Error(Loc, "expected absolute expression");
- if (Res < 0)
- return Warning(Loc, "negative count has no effect");
- Bytes = Bytes.take_front(Res);
- }
- getStreamer().EmitBytes(Bytes);
+ getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer());
return false;
}
@@ -688,36 +606,21 @@ void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
}
const AsmToken &AsmParser::Lex() {
- if (Lexer.getTok().is(AsmToken::Error))
- Error(Lexer.getErrLoc(), Lexer.getErr());
-
- // if it's a end of statement with a comment in it
- if (getTok().is(AsmToken::EndOfStatement)) {
- // if this is a line comment output it.
- if (getTok().getString().front() != '\n' &&
- getTok().getString().front() != '\r' && MAI.preserveAsmComments())
- Out.addExplicitComment(Twine(getTok().getString()));
- }
-
const AsmToken *tok = &Lexer.Lex();
- // Parse comments here to be deferred until end of next statement.
- while (tok->is(AsmToken::Comment)) {
- if (MAI.preserveAsmComments())
- Out.addExplicitComment(Twine(tok->getString()));
- tok = &Lexer.Lex();
- }
-
if (tok->is(AsmToken::Eof)) {
// If this is the end of an included file, pop the parent file off the
// include stack.
SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
if (ParentIncludeLoc != SMLoc()) {
jumpToLoc(ParentIncludeLoc);
- return Lex();
+ tok = &Lexer.Lex();
}
}
+ if (tok->is(AsmToken::Error))
+ Error(Lexer.getErrLoc(), Lexer.getErr());
+
return *tok;
}
@@ -735,7 +638,7 @@ 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()) {
- MCSection *Sec = getStreamer().getCurrentSectionOnly();
+ MCSection *Sec = getStreamer().getCurrentSection().first;
if (!Sec->getBeginSymbol()) {
MCSymbol *SectionStartSym = getContext().createTempSymbol();
getStreamer().EmitLabel(SectionStartSym);
@@ -754,38 +657,24 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
if (!parseStatement(Info, nullptr))
continue;
- // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
- // for printing ErrMsg via Lex() only if no (presumably better) parser error
- // exists.
- if (!hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
- Lex();
- }
-
- // parseStatement returned true so may need to emit an error.
- printPendingErrors();
-
- // Skipping to the next line if needed.
- if (!getLexer().isAtStartOfStatement())
- eatToEndOfStatement();
+ // We had an error, validate that one was emitted and recover by skipping to
+ // the next line.
+ assert(HadError && "Parse statement returned an error, but none emitted!");
+ eatToEndOfStatement();
}
- // All errors should have been emitted.
- assert(!hasPendingError() && "unexpected error from parseStatement");
-
- getTargetParser().flushPendingInstructions(getStreamer());
-
if (TheCondState.TheCond != StartingCondState.TheCond ||
TheCondState.Ignore != StartingCondState.Ignore)
- printError(getTok().getLoc(), "unmatched .ifs or .elses");
+ return TokError("unmatched .ifs or .elses");
+
// Check to see there are no empty DwarfFile slots.
const auto &LineTables = getContext().getMCDwarfLineTables();
if (!LineTables.empty()) {
unsigned Index = 0;
for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
if (File.Name.empty() && Index != 0)
- printError(getTok().getLoc(), "unassigned file number: " +
- Twine(Index) +
- " for .file directives");
+ TokError("unassigned file number: " + Twine(Index) +
+ " for .file directives");
++Index;
}
}
@@ -794,31 +683,18 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Targets that don't do subsections via symbols may not want this, though,
// so conservatively exclude them. Only do this if we're finalizing, though,
// as otherwise we won't necessarilly have seen everything yet.
- if (!NoFinalize) {
- if (MAI.hasSubsectionsViaSymbols()) {
- for (const auto &TableEntry : getContext().getSymbols()) {
- MCSymbol *Sym = TableEntry.getValue();
- // Variable symbols may not be marked as defined, so check those
- // explicitly. If we know it's a variable, we have a definition for
- // the purposes of this check.
- if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
- // FIXME: We would really like to refer back to where the symbol was
- // first referenced for a source location. We need to add something
- // to track that. Currently, we just point to the end of the file.
- printError(getTok().getLoc(), "assembler local symbol '" +
- Sym->getName() + "' not defined");
- }
- }
-
- // Temporary symbols like the ones for directional jumps don't go in the
- // symbol table. They also need to be diagnosed in all (final) cases.
- for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
- if (std::get<2>(LocSym)->isUndefined()) {
- // Reset the state of any "# line file" directives we've seen to the
- // context as it was at the diagnostic site.
- CppHashInfo = std::get<1>(LocSym);
- printError(std::get<0>(LocSym), "directional label undefined");
- }
+ if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
+ for (const auto &TableEntry : getContext().getSymbols()) {
+ MCSymbol *Sym = TableEntry.getValue();
+ // Variable symbols may not be marked as defined, so check those
+ // explicitly. If we know it's a variable, we have a definition for
+ // the purposes of this check.
+ if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
+ // FIXME: We would really like to refer back to where the symbol was
+ // first referenced for a source location. We need to add something
+ // to track that. Currently, we just point to the end of the file.
+ return Error(getLexer().getLoc(), "assembler local symbol '" +
+ Sym->getName() + "' not defined");
}
}
@@ -830,30 +706,28 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
return HadError || getContext().hadError();
}
-bool AsmParser::checkForValidSection() {
- if (!ParsingInlineAsm && !getStreamer().getCurrentSectionOnly()) {
+void AsmParser::checkForValidSection() {
+ if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) {
+ TokError("expected section directive before assembly directive");
Out.InitSections(false);
- return Error(getTok().getLoc(),
- "expected section directive before assembly directive");
}
- return false;
}
/// \brief Throw away the rest of the line for testing purposes.
void AsmParser::eatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
- Lexer.Lex();
+ Lex();
// Eat EOL.
if (Lexer.is(AsmToken::EndOfStatement))
- Lexer.Lex();
+ Lex();
}
StringRef AsmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
- Lexer.Lex();
+ Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
@@ -864,7 +738,7 @@ StringRef AsmParser::parseStringToComma() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof))
- Lexer.Lex();
+ Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
@@ -893,9 +767,10 @@ bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (parseExpression(Res))
return true;
- EndLoc = getTok().getEndLoc();
- if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
- return true;
+ if (Lexer.isNot(AsmToken::RBrac))
+ return TokError("expected ']' in brackets expression");
+ EndLoc = Lexer.getTok().getEndLoc();
+ Lex();
return false;
}
@@ -926,10 +801,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
case AsmToken::Identifier: {
StringRef Identifier;
if (parseIdentifier(Identifier)) {
- // We may have failed but $ may be a valid token.
- if (getTok().is(AsmToken::Dollar)) {
+ if (FirstTokenKind == 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();
@@ -947,7 +820,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (!MAI.useParensForSymbolVariant()) {
if (FirstTokenKind == AsmToken::String) {
if (Lexer.is(AsmToken::At)) {
- Lex(); // eat @
+ Lexer.Lex(); // eat @
SMLoc AtLoc = getLexer().getLoc();
StringRef VName;
if (parseIdentifier(VName))
@@ -959,13 +832,14 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Split = Identifier.split('@');
}
} else if (Lexer.is(AsmToken::LParen)) {
- Lex(); // eat '('.
+ Lexer.Lex(); // eat (
StringRef VName;
parseIdentifier(VName);
- // eat ')'.
- if (parseToken(AsmToken::RParen,
- "unexpected token in variant, expected ')'"))
- return true;
+ if (Lexer.isNot(AsmToken::RParen)) {
+ return Error(Lexer.getTok().getLoc(),
+ "unexpected token in variant, expected ')'");
+ }
+ Lexer.Lex(); // eat )
Split = std::make_pair(Identifier, VName);
}
@@ -973,9 +847,6 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
// This is a symbol reference.
StringRef SymbolName = Identifier;
- if (SymbolName.empty())
- return true;
-
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
// Lookup the symbol variant if used.
@@ -1033,8 +904,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
if (IDVal == "b" && Sym->isUndefined())
- return Error(Loc, "directional label undefined");
- DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
+ return Error(Loc, "invalid reference to undefined symbol");
EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat identifier.
}
@@ -1042,7 +912,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
case AsmToken::Real: {
- APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
+ APFloat RealVal(APFloat::IEEEdouble, getTok().getString());
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
Res = MCConstantExpr::create(IntVal, getContext());
EndLoc = Lexer.getTok().getEndLoc();
@@ -1085,43 +955,6 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return true;
Res = MCUnaryExpr::createNot(Res, getContext());
return false;
- // MIPS unary expression operators. The lexer won't generate these tokens if
- // MCAsmInfo::HasMipsExpressions is false for the target.
- case AsmToken::PercentCall16:
- case AsmToken::PercentCall_Hi:
- case AsmToken::PercentCall_Lo:
- case AsmToken::PercentDtprel_Hi:
- case AsmToken::PercentDtprel_Lo:
- case AsmToken::PercentGot:
- case AsmToken::PercentGot_Disp:
- case AsmToken::PercentGot_Hi:
- case AsmToken::PercentGot_Lo:
- case AsmToken::PercentGot_Ofst:
- case AsmToken::PercentGot_Page:
- case AsmToken::PercentGottprel:
- case AsmToken::PercentGp_Rel:
- case AsmToken::PercentHi:
- case AsmToken::PercentHigher:
- case AsmToken::PercentHighest:
- case AsmToken::PercentLo:
- case AsmToken::PercentNeg:
- case AsmToken::PercentPcrel_Hi:
- case AsmToken::PercentPcrel_Lo:
- case AsmToken::PercentTlsgd:
- case AsmToken::PercentTlsldm:
- case AsmToken::PercentTprel_Hi:
- case AsmToken::PercentTprel_Lo:
- Lex(); // Eat the operator.
- if (Lexer.isNot(AsmToken::LParen))
- return TokError("expected '(' after operator");
- Lex(); // Eat the operator.
- if (parseExpression(Res, EndLoc))
- return true;
- if (Lexer.isNot(AsmToken::RParen))
- return TokError("expected ')'");
- Lex(); // Eat the operator.
- Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
- return !Res;
}
}
@@ -1249,10 +1082,10 @@ bool AsmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
// We don't Lex() the last RParen.
// This is the same behavior as parseParenExpression().
if (ParenDepth - 1 > 0) {
- EndLoc = getTok().getEndLoc();
- if (parseToken(AsmToken::RParen,
- "expected ')' in parentheses expression"))
- return true;
+ if (Lexer.isNot(AsmToken::RParen))
+ return TokError("expected ')' in parentheses expression");
+ EndLoc = Lexer.getTok().getEndLoc();
+ Lex();
}
}
return false;
@@ -1436,7 +1269,7 @@ unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K,
/// Res contains the LHS of the expression on input.
bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
SMLoc &EndLoc) {
- while (true) {
+ while (1) {
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
@@ -1470,52 +1303,34 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
/// ::= Label* Identifier OperandList* EndOfStatement
bool AsmParser::parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI) {
- assert(!hasPendingError() && "parseStatement started with pending error");
- // Eat initial spaces and comments
- while (Lexer.is(AsmToken::Space))
- Lex();
if (Lexer.is(AsmToken::EndOfStatement)) {
- // if this is a line comment we can drop it safely
- if (getTok().getString().front() == '\r' ||
- getTok().getString().front() == '\n')
- Out.AddBlankLine();
+ Out.AddBlankLine();
Lex();
return false;
}
- if (Lexer.is(AsmToken::Hash)) {
- // Seeing a hash here means that it was an end-of-line comment in
- // an asm syntax where hash's are not comment and the previous
- // statement parser did not check the end of statement. Relex as
- // EndOfStatement.
- StringRef CommentStr = parseStringToEndOfStatement();
- Lexer.Lex();
- Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
- return false;
- }
- // Statements always start with an identifier.
+
+ // Statements always start with an identifier or are a full line comment.
AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
int64_t LocalLabelVal = -1;
- if (Lexer.is(AsmToken::HashDirective))
+ // A full line comment is a '#' as the first token.
+ if (Lexer.is(AsmToken::Hash))
return parseCppHashLineFilenameComment(IDLoc);
+
// Allow an integer followed by a ':' as a directional local label.
if (Lexer.is(AsmToken::Integer)) {
LocalLabelVal = getTok().getIntVal();
if (LocalLabelVal < 0) {
- if (!TheCondState.Ignore) {
- Lex(); // always eat a token
- return Error(IDLoc, "unexpected token at start of statement");
- }
+ if (!TheCondState.Ignore)
+ return TokError("unexpected token at start of statement");
IDVal = "";
} else {
IDVal = getTok().getString();
Lex(); // Consume the integer token to be used as an identifier token.
if (Lexer.getKind() != AsmToken::Colon) {
- if (!TheCondState.Ignore) {
- Lex(); // always eat a token
- return Error(IDLoc, "unexpected token at start of statement");
- }
+ if (!TheCondState.Ignore)
+ return TokError("unexpected token at start of statement");
}
}
} else if (Lexer.is(AsmToken::Dot)) {
@@ -1532,10 +1347,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
Lex();
IDVal = "}";
} else if (parseIdentifier(IDVal)) {
- if (!TheCondState.Ignore) {
- Lex(); // always eat a token
- return Error(IDLoc, "unexpected token at start of statement");
- }
+ if (!TheCondState.Ignore)
+ return TokError("unexpected token at start of statement");
IDVal = "";
}
@@ -1597,8 +1410,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
case AsmToken::Colon: {
if (!getTargetParser().isLabel(ID))
break;
- if (checkForValidSection())
- return true;
+ checkForValidSection();
// identifier ':' -> Label.
Lex();
@@ -1632,22 +1444,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (!Sym->isUndefined() || Sym->isVariable())
return Error(IDLoc, "invalid symbol redefinition");
- // End of Labels should be treated as end of line for lexing
- // purposes but that information is not available to the Lexer who
- // does not understand Labels. This may cause us to see a Hash
- // here instead of a preprocessor line comment.
- if (getTok().is(AsmToken::Hash)) {
- StringRef CommentStr = parseStringToEndOfStatement();
- Lexer.Lex();
- Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
- }
-
- // Consume any end of statement token, if present, to avoid spurious
- // AddBlankLine calls().
- if (getTok().is(AsmToken::EndOfStatement)) {
- Lex();
- }
-
// Emit the label.
if (!ParsingInlineAsm)
Out.EmitLabel(Sym);
@@ -1660,6 +1456,14 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
getTargetParser().onLabelParsed(Sym);
+ // Consume any end of statement token, if present, to avoid spurious
+ // AddBlankLine calls().
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ Lex();
+ if (Lexer.is(AsmToken::Eof))
+ return false;
+ }
+
return false;
}
@@ -1696,22 +1500,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// manner, or at least have a default behavior that's shared between
// all targets and platforms.
- getTargetParser().flushPendingInstructions(getStreamer());
-
- SMLoc StartTokLoc = getTok().getLoc();
- bool TPDirectiveReturn = getTargetParser().ParseDirective(ID);
-
- if (hasPendingError())
- return true;
- // Currently the return value should be true if we are
- // uninterested but as this is at odds with the standard parsing
- // convention (return true = error) we have instances of a parsed
- // directive that fails returning true as an error. Catch these
- // cases as best as possible errors here.
- if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
- return true;
- // Return if we did some parsing or believe we succeeded.
- if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
+ // First query the target-specific parser. It will return 'true' if it
+ // isn't interested in this directive.
+ if (!getTargetParser().ParseDirective(ID))
return false;
// Next, check the extension directive map to see if any extension has
@@ -1737,34 +1528,25 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
case DK_STRING:
return parseDirectiveAscii(IDVal, true);
case DK_BYTE:
- case DK_DC_B:
- return parseDirectiveValue(IDVal, 1);
- case DK_DC:
- case DK_DC_W:
+ return parseDirectiveValue(1);
case DK_SHORT:
case DK_VALUE:
case DK_2BYTE:
- return parseDirectiveValue(IDVal, 2);
+ return parseDirectiveValue(2);
case DK_LONG:
case DK_INT:
case DK_4BYTE:
- case DK_DC_L:
- return parseDirectiveValue(IDVal, 4);
+ return parseDirectiveValue(4);
case DK_QUAD:
case DK_8BYTE:
- return parseDirectiveValue(IDVal, 8);
- case DK_DC_A:
- return parseDirectiveValue(IDVal,
- getContext().getAsmInfo()->getPointerSize());
+ return parseDirectiveValue(8);
case DK_OCTA:
- return parseDirectiveOctaValue(IDVal);
+ return parseDirectiveOctaValue();
case DK_SINGLE:
case DK_FLOAT:
- case DK_DC_S:
- return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
+ return parseDirectiveRealValue(APFloat::IEEEsingle);
case DK_DOUBLE:
- case DK_DC_D:
- return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
+ return parseDirectiveRealValue(APFloat::IEEEdouble);
case DK_ALIGN: {
bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
return parseDirectiveAlign(IsPow2, /*ExprSize=*/1);
@@ -1826,8 +1608,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveIncbin();
case DK_CODE16:
case DK_CODE16GCC:
- return TokError(Twine(IDVal) +
- " not currently supported for this target");
+ return TokError(Twine(IDVal) + " not supported yet");
case DK_REPT:
return parseDirectiveRept(IDLoc, IDVal);
case DK_IRP:
@@ -1857,24 +1638,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveLoc();
case DK_STABS:
return parseDirectiveStabs();
- case DK_CV_FILE:
- return parseDirectiveCVFile();
- case DK_CV_FUNC_ID:
- return parseDirectiveCVFuncId();
- case DK_CV_INLINE_SITE_ID:
- return parseDirectiveCVInlineSiteId();
- case DK_CV_LOC:
- return parseDirectiveCVLoc();
- case DK_CV_LINETABLE:
- return parseDirectiveCVLinetable();
- case DK_CV_INLINE_LINETABLE:
- return parseDirectiveCVInlineLinetable();
- case DK_CV_DEF_RANGE:
- return parseDirectiveCVDefRange();
- case DK_CV_STRINGTABLE:
- return parseDirectiveCVStringTable();
- case DK_CV_FILECHECKSUMS:
- return parseDirectiveCVFileChecksums();
case DK_CFI_SECTIONS:
return parseDirectiveCFISections();
case DK_CFI_STARTPROC:
@@ -1937,34 +1700,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveWarning(IDLoc);
case DK_RELOC:
return parseDirectiveReloc(IDLoc);
- case DK_DCB:
- case DK_DCB_W:
- return parseDirectiveDCB(IDVal, 2);
- case DK_DCB_B:
- return parseDirectiveDCB(IDVal, 1);
- case DK_DCB_D:
- return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
- case DK_DCB_L:
- return parseDirectiveDCB(IDVal, 4);
- case DK_DCB_S:
- return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
- case DK_DC_X:
- case DK_DCB_X:
- return TokError(Twine(IDVal) +
- " not currently supported for this target");
- case DK_DS:
- case DK_DS_W:
- return parseDirectiveDS(IDVal, 2);
- case DK_DS_B:
- return parseDirectiveDS(IDVal, 1);
- case DK_DS_D:
- return parseDirectiveDS(IDVal, 8);
- case DK_DS_L:
- case DK_DS_S:
- return parseDirectiveDS(IDVal, 4);
- case DK_DS_P:
- case DK_DS_X:
- return parseDirectiveDS(IDVal, 12);
}
return Error(IDLoc, "unknown directive");
@@ -1981,15 +1716,14 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (ParsingInlineAsm && (IDVal == "even"))
Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
- if (checkForValidSection())
- return true;
+ checkForValidSection();
// Canonicalize the opcode to lower case.
std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
- bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
- Info.ParsedOperands);
- Info.ParseError = ParseHadError;
+ bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
+ Info.ParsedOperands);
+ Info.ParseError = HadError;
// Dump the parsed representation, if requested.
if (getShowParsedOperands()) {
@@ -2006,15 +1740,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
}
- // Fail even if ParseInstruction erroneously returns false.
- if (hasPendingError() || ParseHadError)
- return true;
-
// If we are generating dwarf for the current section then generate a .loc
// directive for the instruction.
- if (!ParseHadError && getContext().getGenDwarfForAssembly() &&
+ if (!HadError && getContext().getGenDwarfForAssembly() &&
getContext().getGenDwarfSectionSyms().count(
- getStreamer().getCurrentSectionOnly())) {
+ getStreamer().getCurrentSection().first)) {
unsigned Line;
if (ActiveMacros.empty())
Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
@@ -2025,26 +1755,24 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// 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 (CppHashInfo.Filename.size()) {
+ if (CppHashFilename.size()) {
unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
- 0, StringRef(), CppHashInfo.Filename);
+ 0, StringRef(), CppHashFilename);
getContext().setGenDwarfFileNumber(FileNumber);
// Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's
// cache with the different Loc from the call above we save the last
// info we queried here with SrcMgr.FindLineNumber().
unsigned CppHashLocLineNo;
- if (LastQueryIDLoc == CppHashInfo.Loc &&
- LastQueryBuffer == CppHashInfo.Buf)
+ if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf)
CppHashLocLineNo = LastQueryLine;
else {
- CppHashLocLineNo =
- SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
+ CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf);
LastQueryLine = CppHashLocLineNo;
- LastQueryIDLoc = CppHashInfo.Loc;
- LastQueryBuffer = CppHashInfo.Buf;
+ LastQueryIDLoc = CppHashLoc;
+ LastQueryBuffer = CppHashBuf;
}
- Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
+ Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
}
getStreamer().EmitDwarfLocDirective(
@@ -2054,57 +1782,60 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
}
// If parsing succeeded, match the instruction.
- if (!ParseHadError) {
+ if (!HadError) {
uint64_t ErrorInfo;
- if (getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
- Info.ParsedOperands, Out,
- ErrorInfo, ParsingInlineAsm))
- return true;
+ getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
+ Info.ParsedOperands, Out,
+ ErrorInfo, ParsingInlineAsm);
}
+
+ // Don't skip the rest of the line, the instruction parser is responsible for
+ // that.
return false;
}
-// Parse and erase curly braces marking block start/end
-bool
-AsmParser::parseCurlyBlockScope(SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
- // Identify curly brace marking block start/end
- if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
- return false;
-
- SMLoc StartLoc = Lexer.getLoc();
- Lex(); // Eat the brace
- if (Lexer.is(AsmToken::EndOfStatement))
- Lex(); // Eat EndOfStatement following the brace
-
- // Erase the block start/end brace from the output asm string
- AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
- StartLoc.getPointer());
- return true;
+/// eatToEndOfLine uses the Lexer to eat the characters to the end of the line
+/// since they may not be able to be tokenized to get to the end of line token.
+void AsmParser::eatToEndOfLine() {
+ if (!Lexer.is(AsmToken::EndOfStatement))
+ Lexer.LexUntilEndOfLine();
+ // Eat EOL.
+ Lex();
}
/// parseCppHashLineFilenameComment as this:
/// ::= # number "filename"
+/// or just as a full line comment if it doesn't have a number and a string.
bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) {
Lex(); // Eat the hash token.
- // Lexer only ever emits HashDirective if it fully formed if it's
- // done the checking already so this is an internal error.
- assert(getTok().is(AsmToken::Integer) &&
- "Lexing Cpp line comment: Expected Integer");
+
+ if (getLexer().isNot(AsmToken::Integer)) {
+ // Consume the line since in cases it is not a well-formed line directive,
+ // as if were simply a full line comment.
+ eatToEndOfLine();
+ return false;
+ }
+
int64_t LineNumber = getTok().getIntVal();
Lex();
- assert(getTok().is(AsmToken::String) &&
- "Lexing Cpp line comment: Expected String");
- StringRef Filename = getTok().getString();
- Lex();
+ if (getLexer().isNot(AsmToken::String)) {
+ eatToEndOfLine();
+ return false;
+ }
+
+ StringRef Filename = getTok().getString();
// Get rid of the enclosing quotes.
Filename = Filename.substr(1, Filename.size() - 2);
// Save the SMLoc, Filename and LineNumber for later use by diagnostics.
- CppHashInfo.Loc = L;
- CppHashInfo.Filename = Filename;
- CppHashInfo.LineNumber = LineNumber;
- CppHashInfo.Buf = CurBuffer;
+ CppHashLoc = L;
+ CppHashFilename = Filename;
+ CppHashLineNumber = LineNumber;
+ CppHashBuf = CurBuffer;
+
+ // Ignore any trailing characters, they're just comment.
+ eatToEndOfLine();
return false;
}
@@ -2118,7 +1849,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
SMLoc DiagLoc = Diag.getLoc();
unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
unsigned CppHashBuf =
- Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
+ Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
// Like SourceMgr::printMessage() we need to print the include stack if any
// before printing the message.
@@ -2132,7 +1863,7 @@ 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 ||
+ if (!Parser->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
DiagBuf != CppHashBuf) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
@@ -2142,15 +1873,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
}
// Use the CppHashFilename and calculate a line number based on the
- // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
- // for the diagnostic.
- const std::string &Filename = Parser->CppHashInfo.Filename;
+ // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
+ // the diagnostic.
+ const std::string &Filename = Parser->CppHashFilename;
int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
int CppHashLocLineNo =
- Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
+ Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
int LineNo =
- Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
+ Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
@@ -2310,6 +2041,7 @@ static bool isOperator(AsmToken::TokenKind kind) {
case AsmToken::AmpAmp:
case AsmToken::Exclaim:
case AsmToken::ExclaimEqual:
+ case AsmToken::Percent:
case AsmToken::Less:
case AsmToken::LessEqual:
case AsmToken::LessLess:
@@ -2322,7 +2054,6 @@ static bool isOperator(AsmToken::TokenKind kind) {
}
namespace {
-
class AsmLexerSkipSpaceRAII {
public:
AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
@@ -2336,8 +2067,7 @@ public:
private:
AsmLexer &Lexer;
};
-
-} // end anonymous namespace
+}
bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
@@ -2350,44 +2080,37 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
}
unsigned ParenLevel = 0;
+ unsigned AddTokens = 0;
// Darwin doesn't use spaces to delmit arguments.
AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
- bool SpaceEaten;
-
- while (true) {
- SpaceEaten = false;
+ for (;;) {
if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
return TokError("unexpected token in macro instantiation");
- if (ParenLevel == 0) {
-
- if (Lexer.is(AsmToken::Comma))
- break;
+ if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
+ break;
- if (Lexer.is(AsmToken::Space)) {
- SpaceEaten = true;
- Lexer.Lex(); // Eat spaces
- }
+ if (Lexer.is(AsmToken::Space)) {
+ Lex(); // Eat spaces
// Spaces can delimit parameters, but could also be part an expression.
// If the token after a space is an operator, add the token and the next
// one into this argument
if (!IsDarwin) {
if (isOperator(Lexer.getKind())) {
- MA.push_back(getTok());
- Lexer.Lex();
-
- // Whitespace after an operator can be ignored.
- if (Lexer.is(AsmToken::Space))
- Lexer.Lex();
+ // Check to see whether the token is used as an operator,
+ // or part of an identifier
+ const char *NextChar = getTok().getEndLoc().getPointer();
+ if (*NextChar == ' ')
+ AddTokens = 2;
+ }
- continue;
+ if (!AddTokens && ParenLevel == 0) {
+ break;
}
}
- if (SpaceEaten)
- break;
}
// handleMacroEntry relies on not advancing the lexer here
@@ -2403,7 +2126,9 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
// Append the token to the current argument list.
MA.push_back(getTok());
- Lexer.Lex();
+ if (AddTokens)
+ AddTokens--;
+ Lex();
}
if (ParenLevel != 0)
@@ -2431,19 +2156,27 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
MCAsmMacroParameter FA;
if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
- if (parseIdentifier(FA.Name))
- return Error(IDLoc, "invalid argument identifier for formal argument");
-
- if (Lexer.isNot(AsmToken::Equal))
- return TokError("expected '=' after formal parameter identifier");
+ if (parseIdentifier(FA.Name)) {
+ Error(IDLoc, "invalid argument identifier for formal argument");
+ eatToEndOfStatement();
+ return true;
+ }
+ if (!Lexer.is(AsmToken::Equal)) {
+ TokError("expected '=' after formal parameter identifier");
+ eatToEndOfStatement();
+ return true;
+ }
Lex();
NamedParametersFound = true;
}
- if (NamedParametersFound && FA.Name.empty())
- return Error(IDLoc, "cannot mix positional and keyword arguments");
+ if (NamedParametersFound && FA.Name.empty()) {
+ Error(IDLoc, "cannot mix positional and keyword arguments");
+ eatToEndOfStatement();
+ return true;
+ }
bool Vararg = HasVararg && Parameter == (NParameters - 1);
if (parseMacroArgument(FA.Value, Vararg))
@@ -2457,9 +2190,11 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
break;
if (FAI >= NParameters) {
- assert(M && "expected macro to be defined");
- return Error(IDLoc, "parameter named '" + FA.Name +
- "' does not exist for macro '" + M->Name + "'");
+ assert(M && "expected macro to be defined");
+ Error(IDLoc,
+ "parameter named '" + FA.Name + "' does not exist for macro '" +
+ M->Name + "'");
+ return true;
}
PI = FAI;
}
@@ -2515,17 +2250,10 @@ void AsmParser::defineMacro(StringRef Name, MCAsmMacro Macro) {
void AsmParser::undefineMacro(StringRef Name) { MacroMap.erase(Name); }
bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
- // Arbitrarily limit macro nesting depth (default matches 'as'). We can
- // eliminate this, although we should protect against infinite loops.
- unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
- if (ActiveMacros.size() == MaxNestingDepth) {
- std::ostringstream MaxNestingDepthError;
- MaxNestingDepthError << "macros cannot be nested more than "
- << MaxNestingDepth << " levels deep."
- << " Use -asm-macro-max-nesting-depth to increase "
- "this limit.";
- return TokError(MaxNestingDepthError.str());
- }
+ // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
+ // this, although we should protect against infinite loops.
+ if (ActiveMacros.size() == 20)
+ return TokError("macros cannot be nested more than 20 levels deep");
MCAsmMacroArguments A;
if (parseMacroArguments(M, A))
@@ -2609,23 +2337,18 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
SMLoc PrefixLoc = getLexer().getLoc();
// Consume the prefix character, and check for a following identifier.
-
- AsmToken Buf[1];
- Lexer.peekTokens(Buf, false);
-
- if (Buf[0].isNot(AsmToken::Identifier))
+ Lex();
+ if (Lexer.isNot(AsmToken::Identifier))
return true;
// We have a '$' or '@' followed by an identifier, make sure they are adjacent.
- if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
+ if (PrefixLoc.getPointer() + 1 != getTok().getLoc().getPointer())
return true;
- // eat $ or @
- Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
// Construct the joined identifier and consume the token.
Res =
StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
- Lex(); // Parser Lex to maintain invariants.
+ Lex();
return false;
}
@@ -2645,15 +2368,19 @@ 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");
- return false;
+
+ if (parseIdentifier(Name))
+ return TokError("expected identifier after '" + Twine(IDVal) + "'");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '" + Twine(IDVal) + "'");
+ Lex();
+
+ return parseAssignment(Name, allow_redef, true);
}
bool AsmParser::parseEscapedString(std::string &Data) {
- if (check(getTok().isNot(AsmToken::String), "expected string"))
- return true;
+ assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
Data = "";
StringRef Str = getTok().getStringContents();
@@ -2707,25 +2434,39 @@ bool AsmParser::parseEscapedString(std::string &Data) {
}
}
- Lex();
return false;
}
/// parseDirectiveAscii:
/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
- auto parseOp = [&]() -> bool {
- std::string Data;
- if (checkForValidSection() || parseEscapedString(Data))
- return true;
- getStreamer().EmitBytes(Data);
- if (ZeroTerminated)
- getStreamer().EmitBytes(StringRef("\0", 1));
- return false;
- };
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ checkForValidSection();
+
+ for (;;) {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '" + Twine(IDVal) + "' directive");
+
+ std::string Data;
+ if (parseEscapedString(Data))
+ return true;
+
+ getStreamer().EmitBytes(Data);
+ if (ZeroTerminated)
+ getStreamer().EmitBytes(StringRef("\0", 1));
+
+ Lex();
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
+ Lex();
+ }
+ }
+
+ Lex();
return false;
}
@@ -2736,25 +2477,26 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
const MCExpr *Expr = nullptr;
SMLoc OffsetLoc = Lexer.getTok().getLoc();
- int64_t OffsetValue;
- // We can only deal with constant expressions at the moment.
-
if (parseExpression(Offset))
return true;
- if (check(!Offset->evaluateAsAbsolute(OffsetValue), 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"))
- return true;
+ // We can only deal with constant expressions at the moment.
+ int64_t OffsetValue;
+ if (!Offset->evaluateAsAbsolute(OffsetValue))
+ return Error(OffsetLoc, "expression is not a constant value");
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("expected comma");
+ Lexer.Lex();
+
+ if (Lexer.isNot(AsmToken::Identifier))
+ return TokError("expected relocation name");
SMLoc NameLoc = Lexer.getTok().getLoc();
StringRef Name = Lexer.getTok().getIdentifier();
- Lex();
+ Lexer.Lex();
if (Lexer.is(AsmToken::Comma)) {
- Lex();
+ Lexer.Lex();
SMLoc ExprLoc = Lexer.getLoc();
if (parseExpression(Expr))
return true;
@@ -2764,9 +2506,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 (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in .reloc directive");
if (getStreamer().EmitRelocDirective(*Offset, Name, Expr, DirectiveLoc))
return Error(NameLoc, "unknown relocation name");
@@ -2776,130 +2517,155 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
/// parseDirectiveValue
/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
-bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
- auto parseOp = [&]() -> bool {
- const MCExpr *Value;
- SMLoc ExprLoc = getLexer().getLoc();
- if (checkForValidSection() || parseExpression(Value))
- return true;
- // Special case constant expressions to match code generator.
- if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
- assert(Size <= 8 && "Invalid size");
- uint64_t IntValue = MCE->getValue();
- if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
- return Error(ExprLoc, "out of range literal value");
- getStreamer().EmitIntValue(IntValue, Size);
- } else
- getStreamer().EmitValue(Value, Size, ExprLoc);
- return false;
- };
+bool AsmParser::parseDirectiveValue(unsigned Size) {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ checkForValidSection();
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
- return false;
-}
+ for (;;) {
+ const MCExpr *Value;
+ SMLoc ExprLoc = getLexer().getLoc();
+ if (parseExpression(Value))
+ return true;
-/// ParseDirectiveOctaValue
-/// ::= .octa [ hexconstant (, hexconstant)* ]
+ // Special case constant expressions to match code generator.
+ if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
+ assert(Size <= 8 && "Invalid size");
+ uint64_t IntValue = MCE->getValue();
+ if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
+ return Error(ExprLoc, "literal value out of range for directive");
+ getStreamer().EmitIntValue(IntValue, Size);
+ } else
+ getStreamer().EmitValue(Value, Size, ExprLoc);
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
-bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
- auto parseOp = [&]() -> bool {
- if (checkForValidSection())
- return true;
- if (getTok().isNot(AsmToken::Integer) && getTok().isNot(AsmToken::BigNum))
- return TokError("unknown token in expression");
- SMLoc ExprLoc = getTok().getLoc();
- APInt IntValue = getTok().getAPIntVal();
- uint64_t hi, lo;
- Lex();
- if (!IntValue.isIntN(128))
- return Error(ExprLoc, "out of range literal value");
- if (!IntValue.isIntN(64)) {
- hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
- lo = IntValue.getLoBits(64).getZExtValue();
- } else {
- hi = 0;
- lo = IntValue.getZExtValue();
- }
- if (MAI.isLittleEndian()) {
- getStreamer().EmitIntValue(lo, 8);
- getStreamer().EmitIntValue(hi, 8);
- } else {
- getStreamer().EmitIntValue(hi, 8);
- getStreamer().EmitIntValue(lo, 8);
+ // FIXME: Improve diagnostic.
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
}
- return false;
- };
+ }
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
+ Lex();
return false;
}
-bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
- // We don't truly support arithmetic on floating point expressions, so we
- // have to manually parse unary prefixes.
- bool IsNeg = false;
- if (getLexer().is(AsmToken::Minus)) {
- Lexer.Lex();
- IsNeg = true;
- } else if (getLexer().is(AsmToken::Plus))
- Lexer.Lex();
+/// ParseDirectiveOctaValue
+/// ::= .octa [ hexconstant (, hexconstant)* ]
+bool AsmParser::parseDirectiveOctaValue() {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ checkForValidSection();
- if (Lexer.is(AsmToken::Error))
- return TokError(Lexer.getErr());
- if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
- Lexer.isNot(AsmToken::Identifier))
- return TokError("unexpected token in directive");
+ for (;;) {
+ if (Lexer.getKind() == AsmToken::Error)
+ return true;
+ if (Lexer.getKind() != AsmToken::Integer &&
+ Lexer.getKind() != AsmToken::BigNum)
+ return TokError("unknown token in expression");
- // Convert to an APFloat.
- APFloat Value(Semantics);
- StringRef IDVal = getTok().getString();
- if (getLexer().is(AsmToken::Identifier)) {
- if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
- Value = APFloat::getInf(Semantics);
- else if (!IDVal.compare_lower("nan"))
- Value = APFloat::getNaN(Semantics, false, ~0);
- else
- return TokError("invalid floating point literal");
- } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
- APFloat::opInvalidOp)
- return TokError("invalid floating point literal");
- if (IsNeg)
- Value.changeSign();
-
- // Consume the numeric token.
- Lex();
+ SMLoc ExprLoc = getLexer().getLoc();
+ APInt IntValue = getTok().getAPIntVal();
+ Lex();
+
+ uint64_t hi, lo;
+ if (IntValue.isIntN(64)) {
+ hi = 0;
+ lo = IntValue.getZExtValue();
+ } else if (IntValue.isIntN(128)) {
+ // It might actually have more than 128 bits, but the top ones are zero.
+ hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
+ lo = IntValue.getLoBits(64).getZExtValue();
+ } else
+ return Error(ExprLoc, "literal value out of range for directive");
+
+ if (MAI.isLittleEndian()) {
+ getStreamer().EmitIntValue(lo, 8);
+ getStreamer().EmitIntValue(hi, 8);
+ } else {
+ getStreamer().EmitIntValue(hi, 8);
+ getStreamer().EmitIntValue(lo, 8);
+ }
- Res = Value.bitcastToAPInt();
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ // FIXME: Improve diagnostic.
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
+ Lex();
return false;
}
/// parseDirectiveRealValue
/// ::= (.single | .double) [ expression (, expression)* ]
-bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
- const fltSemantics &Semantics) {
- auto parseOp = [&]() -> bool {
- APInt AsInt;
- if (checkForValidSection() || parseRealValue(Semantics, AsInt))
- return true;
- getStreamer().EmitIntValue(AsInt.getLimitedValue(),
- AsInt.getBitWidth() / 8);
- return false;
- };
+bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ checkForValidSection();
+
+ for (;;) {
+ // We don't truly support arithmetic on floating point expressions, so we
+ // have to manually parse unary prefixes.
+ bool IsNeg = false;
+ if (getLexer().is(AsmToken::Minus)) {
+ Lex();
+ IsNeg = true;
+ } else if (getLexer().is(AsmToken::Plus))
+ Lex();
+
+ if (getLexer().isNot(AsmToken::Integer) &&
+ getLexer().isNot(AsmToken::Real) &&
+ getLexer().isNot(AsmToken::Identifier))
+ return TokError("unexpected token in directive");
+
+ // Convert to an APFloat.
+ APFloat Value(Semantics);
+ StringRef IDVal = getTok().getString();
+ if (getLexer().is(AsmToken::Identifier)) {
+ if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
+ Value = APFloat::getInf(Semantics);
+ else if (!IDVal.compare_lower("nan"))
+ Value = APFloat::getNaN(Semantics, false, ~0);
+ else
+ return TokError("invalid floating point literal");
+ } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
+ APFloat::opInvalidOp)
+ return TokError("invalid floating point literal");
+ if (IsNeg)
+ Value.changeSign();
+
+ // Consume the numeric token.
+ Lex();
+
+ // Emit the value as an integer.
+ APInt AsInt = Value.bitcastToAPInt();
+ getStreamer().EmitIntValue(AsInt.getLimitedValue(),
+ AsInt.getBitWidth() / 8);
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
- if (parseMany(parseOp))
- return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
+ Lex();
return false;
}
/// parseDirectiveZero
/// ::= .zero expression
bool AsmParser::parseDirectiveZero() {
- SMLoc NumBytesLoc = Lexer.getLoc();
- const MCExpr *NumBytes;
- if (checkForValidSection() || parseExpression(NumBytes))
+ checkForValidSection();
+
+ int64_t NumBytes;
+ if (parseAbsoluteExpression(NumBytes))
return true;
int64_t Val = 0;
@@ -2909,10 +2675,12 @@ bool AsmParser::parseDirectiveZero() {
return true;
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.zero' directive"))
- return true;
- getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.zero' directive");
+
+ Lex();
+
+ getStreamer().EmitFill(NumBytes, Val);
return false;
}
@@ -2920,33 +2688,51 @@ bool AsmParser::parseDirectiveZero() {
/// parseDirectiveFill
/// ::= .fill expression [ , expression [ , expression ] ]
bool AsmParser::parseDirectiveFill() {
- SMLoc NumValuesLoc = Lexer.getLoc();
- const MCExpr *NumValues;
- if (checkForValidSection() || parseExpression(NumValues))
+ checkForValidSection();
+
+ SMLoc RepeatLoc = getLexer().getLoc();
+ int64_t NumValues;
+ if (parseAbsoluteExpression(NumValues))
return true;
+ if (NumValues < 0) {
+ Warning(RepeatLoc,
+ "'.fill' directive with negative repeat count has no effect");
+ NumValues = 0;
+ }
+
int64_t FillSize = 1;
int64_t FillExpr = 0;
SMLoc SizeLoc, ExprLoc;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lex();
- if (parseOptionalToken(AsmToken::Comma)) {
- SizeLoc = getTok().getLoc();
+ SizeLoc = getLexer().getLoc();
if (parseAbsoluteExpression(FillSize))
return true;
- if (parseOptionalToken(AsmToken::Comma)) {
- ExprLoc = getTok().getLoc();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lex();
+
+ ExprLoc = getLexer().getLoc();
if (parseAbsoluteExpression(FillExpr))
return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.fill' directive");
+
+ Lex();
}
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.fill' directive"))
- return true;
if (FillSize < 0) {
Warning(SizeLoc, "'.fill' directive with negative size has no effect");
- return false;
+ NumValues = 0;
}
if (FillSize > 8) {
Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
@@ -2956,7 +2742,15 @@ bool AsmParser::parseDirectiveFill() {
if (!isUInt<32>(FillExpr) && FillSize > 4)
Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
- getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
+ 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;
}
@@ -2964,64 +2758,83 @@ bool AsmParser::parseDirectiveFill() {
/// parseDirectiveOrg
/// ::= .org expression [ , expression ]
bool AsmParser::parseDirectiveOrg() {
+ checkForValidSection();
+
const MCExpr *Offset;
- SMLoc OffsetLoc = Lexer.getLoc();
- if (checkForValidSection() || parseExpression(Offset))
+ if (parseExpression(Offset))
return true;
// Parse optional fill expression.
int64_t FillExpr = 0;
- if (parseOptionalToken(AsmToken::Comma))
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.org' directive");
+ Lex();
+
if (parseAbsoluteExpression(FillExpr))
- return addErrorSuffix(" in '.org' directive");
- if (parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.org' directive");
+ return true;
- getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.org' directive");
+ }
+
+ Lex();
+ getStreamer().emitValueToOffset(Offset, FillExpr);
return false;
}
/// parseDirectiveAlign
/// ::= {.align, ...} expression [ , expression [ , expression ]]
bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
+ checkForValidSection();
+
SMLoc AlignmentLoc = getLexer().getLoc();
int64_t Alignment;
+ if (parseAbsoluteExpression(Alignment))
+ return true;
+
SMLoc MaxBytesLoc;
bool HasFillExpr = false;
int64_t FillExpr = 0;
int64_t MaxBytesToFill = 0;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
- auto parseAlign = [&]() -> bool {
- if (checkForValidSection() || parseAbsoluteExpression(Alignment))
- return true;
- if (parseOptionalToken(AsmToken::Comma)) {
- // The fill expression can be omitted while specifying a maximum number of
- // alignment bytes, e.g:
- // .align 3,,4
- if (getTok().isNot(AsmToken::Comma)) {
- HasFillExpr = true;
- if (parseAbsoluteExpression(FillExpr))
- return true;
- }
- if (parseOptionalToken(AsmToken::Comma))
- if (parseTokenLoc(MaxBytesLoc) ||
- parseAbsoluteExpression(MaxBytesToFill))
- return true;
+ // The fill expression can be omitted while specifying a maximum number of
+ // alignment bytes, e.g:
+ // .align 3,,4
+ if (getLexer().isNot(AsmToken::Comma)) {
+ HasFillExpr = true;
+ if (parseAbsoluteExpression(FillExpr))
+ return true;
}
- return parseToken(AsmToken::EndOfStatement);
- };
- if (parseAlign())
- return addErrorSuffix(" in directive");
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
- // Always emit an alignment here even if we thrown an error.
- bool ReturnVal = false;
+ MaxBytesLoc = getLexer().getLoc();
+ if (parseAbsoluteExpression(MaxBytesToFill))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+ }
+ }
+
+ Lex();
+
+ if (!HasFillExpr)
+ FillExpr = 0;
// Compute alignment in bytes.
if (IsPow2) {
// FIXME: Diagnose overflow.
if (Alignment >= 32) {
- ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
+ Error(AlignmentLoc, "invalid alignment value");
Alignment = 31;
}
@@ -3033,14 +2846,13 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
if (Alignment == 0)
Alignment = 1;
if (!isPowerOf2_64(Alignment))
- ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
+ Error(AlignmentLoc, "alignment must be a power of 2");
}
// Diagnose non-sensical max bytes to align.
if (MaxBytesLoc.isValid()) {
if (MaxBytesToFill < 1) {
- ReturnVal |= Error(MaxBytesLoc,
- "alignment directive can never be satisfied in this "
+ Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
"many bytes, ignoring maximum bytes expression");
MaxBytesToFill = 0;
}
@@ -3054,7 +2866,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
// Check whether we should use optimal code alignment for this .align
// directive.
- const MCSection *Section = getStreamer().getCurrentSectionOnly();
+ const MCSection *Section = getStreamer().getCurrentSection().first;
assert(Section && "must have section to emit alignment");
bool UseCodeAlign = Section->UseCodeAlign();
if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
@@ -3066,7 +2878,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
MaxBytesToFill);
}
- return ReturnVal;
+ return false;
}
/// parseDirectiveFile
@@ -3084,43 +2896,45 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
return TokError("file number less than one");
}
- std::string Path = getTok().getString();
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("unexpected token in '.file' directive");
// 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))
+ std::string Path = getTok().getString();
+ if (parseEscapedString(Path))
return true;
+ Lex();
StringRef Directory;
StringRef Filename;
std::string FilenameData;
if (getLexer().is(AsmToken::String)) {
- if (check(FileNumber == -1,
- "explicit path specified, but no file number") ||
- parseEscapedString(FilenameData))
+ if (FileNumber == -1)
+ return TokError("explicit path specified, but no file number");
+ if (parseEscapedString(FilenameData))
return true;
Filename = FilenameData;
Directory = Path;
+ Lex();
} else {
Filename = Path;
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.file' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.file' directive");
if (FileNumber == -1)
getStreamer().EmitFileDirective(Filename);
else {
- // If there is -g option as well as debug info from directive file,
- // we turn off -g option, directly use the existing debug info instead.
if (getContext().getGenDwarfForAssembly())
- getContext().setGenDwarfForAssembly(false);
- else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
+ Error(DirectiveLoc,
+ "input can't have .file dwarf directives when -g is "
+ "used to generate dwarf debug info for assembly code");
+
+ if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
0)
- return Error(FileNumberLoc, "file number already allocated");
+ Error(FileNumberLoc, "file number already allocated");
}
return false;
@@ -3129,16 +2943,19 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
/// parseDirectiveLine
/// ::= .line [number]
bool AsmParser::parseDirectiveLine() {
- int64_t LineNumber;
- if (getLexer().is(AsmToken::Integer)) {
- if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Integer))
+ return TokError("unexpected token in '.line' directive");
+
+ int64_t LineNumber = getTok().getIntVal();
(void)LineNumber;
+ Lex();
+
// FIXME: Do something with the .line.
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.line' directive"))
- return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.line' directive");
return false;
}
@@ -3151,16 +2968,16 @@ bool AsmParser::parseDirectiveLine() {
/// third number is a column position (zero if not specified). The remaining
/// optional items are .loc sub-directives.
bool AsmParser::parseDirectiveLoc() {
- int64_t FileNumber = 0, LineNumber = 0;
- SMLoc Loc = getTok().getLoc();
- if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
- check(FileNumber < 1, Loc,
- "file number less than one in '.loc' directive") ||
- check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
- "unassigned file number in '.loc' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::Integer))
+ return TokError("unexpected token in '.loc' directive");
+ int64_t FileNumber = getTok().getIntVal();
+ if (FileNumber < 1)
+ return TokError("file number less than one in '.loc' directive");
+ if (!getContext().isValidDwarfFileNumber(FileNumber))
+ return TokError("unassigned file number in '.loc' directive");
+ Lex();
- // optional
+ int64_t LineNumber = 0;
if (getLexer().is(AsmToken::Integer)) {
LineNumber = getTok().getIntVal();
if (LineNumber < 0)
@@ -3179,61 +2996,64 @@ bool AsmParser::parseDirectiveLoc() {
unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
unsigned Isa = 0;
int64_t Discriminator = 0;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
- auto parseLocOp = [&]() -> bool {
- StringRef Name;
- SMLoc Loc = getTok().getLoc();
- if (parseIdentifier(Name))
- return TokError("unexpected token in '.loc' directive");
-
- if (Name == "basic_block")
- Flags |= DWARF2_FLAG_BASIC_BLOCK;
- else if (Name == "prologue_end")
- Flags |= DWARF2_FLAG_PROLOGUE_END;
- else if (Name == "epilogue_begin")
- Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
- else if (Name == "is_stmt") {
- Loc = getTok().getLoc();
- const MCExpr *Value;
- if (parseExpression(Value))
- return true;
- // The expression must be the constant 0 or 1.
- if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
- int Value = MCE->getValue();
- if (Value == 0)
- Flags &= ~DWARF2_FLAG_IS_STMT;
- else if (Value == 1)
- Flags |= DWARF2_FLAG_IS_STMT;
- else
- return Error(Loc, "is_stmt value not 0 or 1");
- } else {
- return Error(Loc, "is_stmt value not the constant value of 0 or 1");
- }
- } else if (Name == "isa") {
- Loc = getTok().getLoc();
- const MCExpr *Value;
- if (parseExpression(Value))
- return true;
- // The expression must be a constant greater or equal to 0.
- if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
- int Value = MCE->getValue();
- if (Value < 0)
- return Error(Loc, "isa number less than zero");
- Isa = Value;
+ StringRef Name;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIdentifier(Name))
+ return TokError("unexpected token in '.loc' directive");
+
+ if (Name == "basic_block")
+ Flags |= DWARF2_FLAG_BASIC_BLOCK;
+ else if (Name == "prologue_end")
+ Flags |= DWARF2_FLAG_PROLOGUE_END;
+ else if (Name == "epilogue_begin")
+ Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
+ else if (Name == "is_stmt") {
+ Loc = getTok().getLoc();
+ const MCExpr *Value;
+ if (parseExpression(Value))
+ return true;
+ // The expression must be the constant 0 or 1.
+ if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
+ int Value = MCE->getValue();
+ if (Value == 0)
+ Flags &= ~DWARF2_FLAG_IS_STMT;
+ else if (Value == 1)
+ Flags |= DWARF2_FLAG_IS_STMT;
+ else
+ return Error(Loc, "is_stmt value not 0 or 1");
+ } else {
+ return Error(Loc, "is_stmt value not the constant value of 0 or 1");
+ }
+ } else if (Name == "isa") {
+ Loc = getTok().getLoc();
+ const MCExpr *Value;
+ if (parseExpression(Value))
+ return true;
+ // The expression must be a constant greater or equal to 0.
+ if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
+ int Value = MCE->getValue();
+ if (Value < 0)
+ return Error(Loc, "isa number less than zero");
+ Isa = Value;
+ } else {
+ return Error(Loc, "isa number not a constant value");
+ }
+ } else if (Name == "discriminator") {
+ if (parseAbsoluteExpression(Discriminator))
+ return true;
} else {
- return Error(Loc, "isa number not a constant value");
+ return Error(Loc, "unknown sub-directive in '.loc' directive");
}
- } else if (Name == "discriminator") {
- if (parseAbsoluteExpression(Discriminator))
- return true;
- } else {
- return Error(Loc, "unknown sub-directive in '.loc' directive");
- }
- return false;
- };
- if (parseMany(parseLocOp, false /*hasComma*/))
- return true;
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+ }
+ }
getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
Isa, Discriminator, StringRef());
@@ -3247,304 +3067,6 @@ bool AsmParser::parseDirectiveStabs() {
return TokError("unsupported directive '.stabs'");
}
-/// parseDirectiveCVFile
-/// ::= .cv_file number filename
-bool AsmParser::parseDirectiveCVFile() {
- SMLoc FileNumberLoc = getTok().getLoc();
- int64_t FileNumber;
- std::string Filename;
-
- if (parseIntToken(FileNumber,
- "expected file number in '.cv_file' directive") ||
- check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
- check(getTok().isNot(AsmToken::String),
- "unexpected token in '.cv_file' directive") ||
- // Usually directory and filename are together, otherwise just
- // directory. Allow the strings to have escaped octal character sequence.
- parseEscapedString(Filename) ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.cv_file' directive"))
- return true;
-
- if (!getStreamer().EmitCVFileDirective(FileNumber, Filename))
- return Error(FileNumberLoc, "file number already allocated");
-
- return false;
-}
-
-bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
- StringRef DirectiveName) {
- SMLoc Loc;
- return parseTokenLoc(Loc) ||
- parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
- "' directive") ||
- check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
- "expected function id within range [0, UINT_MAX)");
-}
-
-bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
- SMLoc Loc;
- return parseTokenLoc(Loc) ||
- parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
- "' directive") ||
- check(FileNumber < 1, Loc, "file number less than one in '" +
- DirectiveName + "' directive") ||
- check(!getCVContext().isValidFileNumber(FileNumber), Loc,
- "unassigned file number in '" + DirectiveName + "' directive");
-}
-
-/// parseDirectiveCVFuncId
-/// ::= .cv_func_id FunctionId
-///
-/// Introduces a function ID that can be used with .cv_loc.
-bool AsmParser::parseDirectiveCVFuncId() {
- SMLoc FunctionIdLoc = getTok().getLoc();
- int64_t FunctionId;
-
- if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.cv_func_id' directive"))
- return true;
-
- if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
- return Error(FunctionIdLoc, "function id already allocated");
-
- return false;
-}
-
-/// parseDirectiveCVInlineSiteId
-/// ::= .cv_inline_site_id FunctionId
-/// "within" IAFunc
-/// "inlined_at" IAFile IALine [IACol]
-///
-/// Introduces a function ID that can be used with .cv_loc. Includes "inlined
-/// at" source location information for use in the line table of the caller,
-/// whether the caller is a real function or another inlined call site.
-bool AsmParser::parseDirectiveCVInlineSiteId() {
- SMLoc FunctionIdLoc = getTok().getLoc();
- int64_t FunctionId;
- int64_t IAFunc;
- int64_t IAFile;
- int64_t IALine;
- int64_t IACol = 0;
-
- // FunctionId
- if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
- return true;
-
- // "within"
- if (check((getLexer().isNot(AsmToken::Identifier) ||
- getTok().getIdentifier() != "within"),
- "expected 'within' identifier in '.cv_inline_site_id' directive"))
- return true;
- Lex();
-
- // IAFunc
- if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
- return true;
-
- // "inlined_at"
- if (check((getLexer().isNot(AsmToken::Identifier) ||
- getTok().getIdentifier() != "inlined_at"),
- "expected 'inlined_at' identifier in '.cv_inline_site_id' "
- "directive") )
- return true;
- Lex();
-
- // IAFile IALine
- if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
- parseIntToken(IALine, "expected line number after 'inlined_at'"))
- return true;
-
- // [IACol]
- if (getLexer().is(AsmToken::Integer)) {
- IACol = getTok().getIntVal();
- Lex();
- }
-
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.cv_inline_site_id' directive"))
- return true;
-
- if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
- IALine, IACol, FunctionIdLoc))
- return Error(FunctionIdLoc, "function id already allocated");
-
- return false;
-}
-
-/// parseDirectiveCVLoc
-/// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
-/// [is_stmt VALUE]
-/// The first number is a file number, must have been previously assigned with
-/// a .file directive, the second number is the line number and optionally the
-/// third number is a column position (zero if not specified). The remaining
-/// optional items are .loc sub-directives.
-bool AsmParser::parseDirectiveCVLoc() {
- SMLoc DirectiveLoc = getTok().getLoc();
- SMLoc Loc;
- int64_t FunctionId, FileNumber;
- if (parseCVFunctionId(FunctionId, ".cv_loc") ||
- parseCVFileId(FileNumber, ".cv_loc"))
- return true;
-
- int64_t LineNumber = 0;
- if (getLexer().is(AsmToken::Integer)) {
- LineNumber = getTok().getIntVal();
- if (LineNumber < 0)
- return TokError("line number less than zero in '.cv_loc' directive");
- Lex();
- }
-
- int64_t ColumnPos = 0;
- if (getLexer().is(AsmToken::Integer)) {
- ColumnPos = getTok().getIntVal();
- if (ColumnPos < 0)
- return TokError("column position less than zero in '.cv_loc' directive");
- Lex();
- }
-
- bool PrologueEnd = false;
- uint64_t IsStmt = 0;
-
- auto parseOp = [&]() -> bool {
- StringRef Name;
- SMLoc Loc = getTok().getLoc();
- if (parseIdentifier(Name))
- return TokError("unexpected token in '.cv_loc' directive");
- if (Name == "prologue_end")
- PrologueEnd = true;
- else if (Name == "is_stmt") {
- Loc = getTok().getLoc();
- const MCExpr *Value;
- if (parseExpression(Value))
- return true;
- // The expression must be the constant 0 or 1.
- IsStmt = ~0ULL;
- if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
- IsStmt = MCE->getValue();
-
- if (IsStmt > 1)
- return Error(Loc, "is_stmt value not 0 or 1");
- } else {
- return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
- }
- return false;
- };
-
- if (parseMany(parseOp, false /*hasComma*/))
- return true;
-
- getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
- ColumnPos, PrologueEnd, IsStmt, StringRef(),
- DirectiveLoc);
- return false;
-}
-
-/// parseDirectiveCVLinetable
-/// ::= .cv_linetable FunctionId, FnStart, FnEnd
-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"))
- return true;
-
- MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
- MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
-
- getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
- return false;
-}
-
-/// parseDirectiveCVInlineLinetable
-/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
-bool AsmParser::parseDirectiveCVInlineLinetable() {
- int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
- StringRef FnStartName, FnEndName;
- SMLoc Loc = getTok().getLoc();
- if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
- parseTokenLoc(Loc) ||
- parseIntToken(
- SourceFileId,
- "expected SourceField in '.cv_inline_linetable' directive") ||
- check(SourceFileId <= 0, Loc,
- "File id less than zero in '.cv_inline_linetable' directive") ||
- parseTokenLoc(Loc) ||
- parseIntToken(
- SourceLineNum,
- "expected SourceLineNum in '.cv_inline_linetable' directive") ||
- check(SourceLineNum < 0, Loc,
- "Line number less than zero in '.cv_inline_linetable' directive") ||
- parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
- "expected identifier in directive") ||
- parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
- "expected identifier in directive"))
- return true;
-
- if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
- return true;
-
- MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
- MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
- getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
- SourceLineNum, FnStartSym,
- FnEndSym);
- return false;
-}
-
-/// parseDirectiveCVDefRange
-/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
-bool AsmParser::parseDirectiveCVDefRange() {
- SMLoc Loc;
- std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
- while (getLexer().is(AsmToken::Identifier)) {
- Loc = getLexer().getLoc();
- StringRef GapStartName;
- if (parseIdentifier(GapStartName))
- return Error(Loc, "expected identifier in directive");
- MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
-
- Loc = getLexer().getLoc();
- StringRef GapEndName;
- if (parseIdentifier(GapEndName))
- return Error(Loc, "expected identifier in directive");
- MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
-
- Ranges.push_back({GapStartSym, GapEndSym});
- }
-
- std::string FixedSizePortion;
- if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseEscapedString(FixedSizePortion))
- return true;
-
- getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
- return false;
-}
-
-/// parseDirectiveCVStringTable
-/// ::= .cv_stringtable
-bool AsmParser::parseDirectiveCVStringTable() {
- getStreamer().EmitCVStringTableDirective();
- return false;
-}
-
-/// parseDirectiveCVFileChecksums
-/// ::= .cv_filechecksums
-bool AsmParser::parseDirectiveCVFileChecksums() {
- getStreamer().EmitCVFileChecksumsDirective();
- return false;
-}
-
/// parseDirectiveCFISections
/// ::= .cfi_sections section [, section]
bool AsmParser::parseDirectiveCFISections() {
@@ -3580,12 +3102,9 @@ bool AsmParser::parseDirectiveCFISections() {
/// ::= .cfi_startproc [simple]
bool AsmParser::parseDirectiveCFIStartProc() {
StringRef Simple;
- if (!parseOptionalToken(AsmToken::EndOfStatement)) {
- if (check(parseIdentifier(Simple) || Simple != "simple",
- "unexpected token") ||
- parseToken(AsmToken::EndOfStatement))
- return addErrorSuffix(" in '.cfi_startproc' directive");
- }
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ if (parseIdentifier(Simple) || Simple != "simple")
+ return TokError("unexpected token in .cfi_startproc directive");
getStreamer().EmitCFIStartProc(!Simple.empty());
return false;
@@ -3616,10 +3135,16 @@ bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
/// parseDirectiveCFIDefCfa
/// ::= .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))
+ int64_t Register = 0;
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Offset = 0;
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfa(Register, Offset);
@@ -3640,10 +3165,16 @@ bool AsmParser::parseDirectiveCFIDefCfaOffset() {
/// parseDirectiveCFIRegister
/// ::= .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))
+ int64_t Register1 = 0;
+ if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Register2 = 0;
+ if (parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
return true;
getStreamer().EmitCFIRegister(Register1, Register2);
@@ -3685,9 +3216,14 @@ 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))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIOffset(Register, Offset);
@@ -3697,11 +3233,17 @@ bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
/// parseDirectiveCFIRelOffset
/// ::= .cfi_rel_offset register, offset
bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
- int64_t Register = 0, Offset = 0;
+ int64_t Register = 0;
+
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseAbsoluteExpression(Offset))
+ int64_t Offset = 0;
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIRelOffset(Register, Offset);
@@ -3741,11 +3283,16 @@ bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
if (Encoding == dwarf::DW_EH_PE_omit)
return false;
+ if (!isValidEncoding(Encoding))
+ return TokError("unsupported encoding.");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
StringRef Name;
- if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
- parseToken(AsmToken::Comma, "unexpected token in directive") ||
- check(parseIdentifier(Name), "expected identifier in directive"))
- return true;
+ if (parseIdentifier(Name))
+ return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
@@ -3819,9 +3366,9 @@ bool AsmParser::parseDirectiveCFIEscape() {
/// parseDirectiveCFISignalFrame
/// ::= .cfi_signal_frame
bool AsmParser::parseDirectiveCFISignalFrame() {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.cfi_signal_frame'"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token in '.cfi_signal_frame'");
getStreamer().EmitCFISignalFrame();
return false;
@@ -3843,9 +3390,9 @@ bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
/// ::= .macros_on
/// ::= .macros_off
bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Directive + "' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token in '" + Directive + "' directive");
setMacrosEnabled(Directive == ".macros_on");
return false;
@@ -3913,19 +3460,14 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
Lex();
}
- // Eat just the end of statement.
- Lexer.Lex();
+ // Eat the end of statement.
+ Lex();
- // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
AsmToken EndToken, StartToken = getTok();
unsigned MacroDepth = 0;
- // Lex the macro definition.
- while (true) {
- // Ignore Lexing errors in macros.
- while (Lexer.is(AsmToken::Error)) {
- Lexer.Lex();
- }
+ // Lex the macro definition.
+ for (;;) {
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof))
return Error(DirectiveLoc, "no matching '.endmacro' in definition");
@@ -3936,7 +3478,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
getTok().getIdentifier() == ".endmacro") {
if (MacroDepth == 0) { // Outermost macro.
EndToken = getTok();
- Lexer.Lex();
+ Lex();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + EndToken.getIdentifier() +
"' directive");
@@ -4073,9 +3615,8 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
/// parseDirectiveExitMacro
/// ::= .exitm
bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Directive + "' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Directive + "' directive");
if (!isInsideMacroInstantiation())
return TokError("unexpected '" + Directive + "' in file, "
@@ -4115,13 +3656,11 @@ bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
/// ::= .purgem
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"))
- return true;
+ if (parseIdentifier(Name))
+ return TokError("expected identifier in '.purgem' directive");
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.purgem' directive");
if (!lookupMacro(Name))
return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
@@ -4133,17 +3672,22 @@ bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
/// parseDirectiveBundleAlignMode
/// ::= {.bundle_align_mode} expression
bool AsmParser::parseDirectiveBundleAlignMode() {
+ checkForValidSection();
+
// Expect a single argument: an expression that evaluates to a constant
// in the inclusive range 0-30.
SMLoc ExprLoc = getLexer().getLoc();
int64_t AlignSizePow2;
- if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
- parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
- "in '.bundle_align_mode' "
- "directive") ||
- check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
- "invalid bundle alignment size (expected between 0 and 30)"))
+ if (parseAbsoluteExpression(AlignSizePow2))
return true;
+ else if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token after expression in"
+ " '.bundle_align_mode' directive");
+ else if (AlignSizePow2 < 0 || AlignSizePow2 > 30)
+ return Error(ExprLoc,
+ "invalid bundle alignment size (expected between 0 and 30)");
+
+ Lex();
// Because of AlignSizePow2's verified range we can safely truncate it to
// unsigned.
@@ -4154,24 +3698,28 @@ bool AsmParser::parseDirectiveBundleAlignMode() {
/// parseDirectiveBundleLock
/// ::= {.bundle_lock} [align_to_end]
bool AsmParser::parseDirectiveBundleLock() {
- if (checkForValidSection())
- return true;
+ checkForValidSection();
bool AlignToEnd = false;
- StringRef Option;
- SMLoc Loc = getTok().getLoc();
- const char *kInvalidOptionError =
- "invalid option for '.bundle_lock' directive";
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ StringRef Option;
+ SMLoc Loc = getTok().getLoc();
+ const char *kInvalidOptionError =
+ "invalid option for '.bundle_lock' directive";
+
+ if (parseIdentifier(Option))
+ return Error(Loc, kInvalidOptionError);
- 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"))
- return true;
+ if (Option != "align_to_end")
+ return Error(Loc, kInvalidOptionError);
+ else if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(Loc,
+ "unexpected token after '.bundle_lock' directive option");
AlignToEnd = true;
}
+ Lex();
+
getStreamer().EmitBundleLock(AlignToEnd);
return false;
}
@@ -4179,10 +3727,11 @@ bool AsmParser::parseDirectiveBundleLock() {
/// parseDirectiveBundleLock
/// ::= {.bundle_lock}
bool AsmParser::parseDirectiveBundleUnlock() {
- if (checkForValidSection() ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.bundle_unlock' directive"))
- return true;
+ checkForValidSection();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.bundle_unlock' directive");
+ Lex();
getStreamer().EmitBundleUnlock();
return false;
@@ -4191,119 +3740,33 @@ bool AsmParser::parseDirectiveBundleUnlock() {
/// parseDirectiveSpace
/// ::= (.skip | .space) expression [ , expression ]
bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
+ checkForValidSection();
- SMLoc NumBytesLoc = Lexer.getLoc();
- const MCExpr *NumBytes;
- if (checkForValidSection() || parseExpression(NumBytes))
+ int64_t NumBytes;
+ if (parseAbsoluteExpression(NumBytes))
return true;
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");
-
- // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
-
- return false;
-}
-
-/// parseDirectiveDCB
-/// ::= .dcb.{b, l, w} expression, expression
-bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
- SMLoc NumValuesLoc = Lexer.getLoc();
- int64_t NumValues;
- if (checkForValidSection() || parseAbsoluteExpression(NumValues))
- return true;
-
- if (NumValues < 0) {
- Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
- return false;
- }
-
- if (parseToken(AsmToken::Comma,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
+ Lex();
- const MCExpr *Value;
- SMLoc ExprLoc = getLexer().getLoc();
- if (parseExpression(Value))
- return true;
+ if (parseAbsoluteExpression(FillExpr))
+ return true;
- // Special case constant expressions to match code generator.
- if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
- assert(Size <= 8 && "Invalid size");
- uint64_t IntValue = MCE->getValue();
- if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
- return Error(ExprLoc, "literal value out of range for directive");
- for (uint64_t i = 0, e = NumValues; i != e; ++i)
- getStreamer().EmitIntValue(IntValue, Size);
- } else {
- for (uint64_t i = 0, e = NumValues; i != e; ++i)
- getStreamer().EmitValue(Value, Size, ExprLoc);
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
-
- return false;
-}
-
-/// parseDirectiveRealDCB
-/// ::= .dcb.{d, s} expression, expression
-bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
- SMLoc NumValuesLoc = Lexer.getLoc();
- int64_t NumValues;
- if (checkForValidSection() || parseAbsoluteExpression(NumValues))
- return true;
-
- if (NumValues < 0) {
- Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
- return false;
- }
-
- if (parseToken(AsmToken::Comma,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
-
- APInt AsInt;
- if (parseRealValue(Semantics, AsInt))
- return true;
-
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
-
- for (uint64_t i = 0, e = NumValues; i != e; ++i)
- getStreamer().EmitIntValue(AsInt.getLimitedValue(),
- AsInt.getBitWidth() / 8);
-
- return false;
-}
-
-/// parseDirectiveDS
-/// ::= .ds.{b, d, l, p, s, w, x} expression
-bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
-
- SMLoc NumValuesLoc = Lexer.getLoc();
- int64_t NumValues;
- if (checkForValidSection() || parseAbsoluteExpression(NumValues))
- return true;
-
- if (NumValues < 0) {
- Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
- return false;
- }
+ Lex();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Twine(IDVal) + "' directive"))
- return true;
+ if (NumBytes <= 0)
+ return TokError("invalid number of bytes in '" + Twine(IDVal) +
+ "' directive");
- for (uint64_t i = 0, e = NumValues; i != e; ++i)
- getStreamer().emitFill(Size, 0);
+ // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
+ getStreamer().EmitFill(NumBytes, FillExpr);
return false;
}
@@ -4311,22 +3774,25 @@ bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
/// parseDirectiveLEB128
/// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
bool AsmParser::parseDirectiveLEB128(bool Signed) {
- if (checkForValidSection())
- return true;
+ checkForValidSection();
+ const MCExpr *Value;
- auto parseOp = [&]() -> bool {
- const MCExpr *Value;
+ for (;;) {
if (parseExpression(Value))
return true;
+
if (Signed)
getStreamer().EmitSLEB128Value(Value);
else
getStreamer().EmitULEB128Value(Value);
- return false;
- };
- if (parseMany(parseOp))
- return addErrorSuffix(" in directive");
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
return false;
}
@@ -4334,32 +3800,40 @@ bool AsmParser::parseDirectiveLEB128(bool Signed) {
/// parseDirectiveSymbolAttribute
/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
- auto parseOp = [&]() -> bool {
- StringRef Name;
- SMLoc Loc = getTok().getLoc();
- if (parseIdentifier(Name))
- return Error(Loc, "expected identifier");
- MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ StringRef Name;
+ SMLoc Loc = getTok().getLoc();
- // Assembler local symbols don't make any sense here. Complain loudly.
- if (Sym->isTemporary())
- return Error(Loc, "non-local symbol required");
+ if (parseIdentifier(Name))
+ return Error(Loc, "expected identifier in directive");
- if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
- return Error(Loc, "unable to emit symbol attribute");
- return false;
- };
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
- if (parseMany(parseOp))
- return addErrorSuffix(" in directive");
+ // Assembler local symbols don't make any sense here. Complain loudly.
+ if (Sym->isTemporary())
+ return Error(Loc, "non-local symbol required in directive");
+
+ if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
+ return Error(Loc, "unable to emit symbol attribute");
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
+
+ Lex();
return false;
}
/// parseDirectiveComm
/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
bool AsmParser::parseDirectiveComm(bool IsLocal) {
- if (checkForValidSection())
- return true;
+ checkForValidSection();
SMLoc IDLoc = getLexer().getLoc();
StringRef Name;
@@ -4399,9 +3873,10 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) {
}
}
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.comm' or '.lcomm' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.comm' or '.lcomm' directive");
+
+ Lex();
// NOTE: a size of zero for a .comm should create a undefined symbol
// but a size of .lcomm creates a bss symbol of size zero.
@@ -4436,14 +3911,15 @@ bool AsmParser::parseDirectiveAbort() {
SMLoc Loc = getLexer().getLoc();
StringRef Str = parseStringToEndOfStatement();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.abort' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.abort' directive");
+
+ Lex();
if (Str.empty())
- return Error(Loc, ".abort detected. Assembly stopping.");
+ Error(Loc, ".abort detected. Assembly stopping.");
else
- return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
+ Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
// FIXME: Actually abort assembly here.
return false;
@@ -4452,62 +3928,51 @@ bool AsmParser::parseDirectiveAbort() {
/// parseDirectiveInclude
/// ::= .include "filename"
bool AsmParser::parseDirectiveInclude() {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '.include' directive");
+
// Allow the strings to have escaped octal character sequence.
std::string Filename;
- SMLoc IncludeLoc = getTok().getLoc();
-
- if (check(getTok().isNot(AsmToken::String),
- "expected string in '.include' directive") ||
- parseEscapedString(Filename) ||
- check(getTok().isNot(AsmToken::EndOfStatement),
- "unexpected token in '.include' directive") ||
- // Attempt to switch the lexer to the included file before consuming the
- // end of statement to avoid losing it when we switch.
- check(enterIncludeFile(Filename), IncludeLoc,
- "Could not find include file '" + Filename + "'"))
+ if (parseEscapedString(Filename))
+ return true;
+ SMLoc IncludeLoc = getLexer().getLoc();
+ Lex();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.include' directive");
+
+ // Attempt to switch the lexer to the included file before consuming the end
+ // of statement to avoid losing it when we switch.
+ if (enterIncludeFile(Filename)) {
+ Error(IncludeLoc, "Could not find include file '" + Filename + "'");
return true;
+ }
return false;
}
/// parseDirectiveIncbin
-/// ::= .incbin "filename" [ , skip [ , count ] ]
+/// ::= .incbin "filename"
bool AsmParser::parseDirectiveIncbin() {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '.incbin' directive");
+
// Allow the strings to have escaped octal character sequence.
std::string Filename;
- SMLoc IncbinLoc = getTok().getLoc();
- if (check(getTok().isNot(AsmToken::String),
- "expected string in '.incbin' directive") ||
- parseEscapedString(Filename))
+ if (parseEscapedString(Filename))
return true;
+ SMLoc IncbinLoc = getLexer().getLoc();
+ Lex();
- int64_t Skip = 0;
- const MCExpr *Count = nullptr;
- SMLoc SkipLoc, CountLoc;
- if (parseOptionalToken(AsmToken::Comma)) {
- // The skip expression can be omitted while specifying the count, e.g:
- // .incbin "filename",,4
- if (getTok().isNot(AsmToken::Comma)) {
- if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
- return true;
- }
- if (parseOptionalToken(AsmToken::Comma)) {
- CountLoc = getTok().getLoc();
- if (parseExpression(Count))
- return true;
- }
- }
-
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.incbin' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.incbin' directive");
- if (check(Skip < 0, SkipLoc, "skip is negative"))
+ // Attempt to process the included file.
+ if (processIncbinFile(Filename)) {
+ Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
return true;
+ }
- // Attempt to process the included file.
- if (processIncbinFile(Filename, Skip, Count, CountLoc))
- return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
return false;
}
@@ -4520,11 +3985,14 @@ 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))
return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.if' directive");
+
+ Lex();
+
switch (DirKind) {
default:
llvm_unreachable("unsupported directive");
@@ -4566,9 +4034,10 @@ bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
} else {
StringRef Str = parseStringToEndOfStatement();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.ifb' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ifb' directive");
+
+ Lex();
TheCondState.CondMet = ExpectBlank == Str.empty();
TheCondState.Ignore = !TheCondState.CondMet;
@@ -4589,14 +4058,17 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
} else {
StringRef Str1 = parseStringToComma();
- if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.ifc' directive");
+
+ Lex();
StringRef Str2 = parseStringToEndOfStatement();
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.ifc' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ifc' directive");
+
+ Lex();
TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
TheCondState.Ignore = !TheCondState.CondMet;
@@ -4610,8 +4082,11 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
if (Lexer.isNot(AsmToken::String)) {
if (ExpectEqual)
- return TokError("expected string parameter for '.ifeqs' directive");
- return TokError("expected string parameter for '.ifnes' directive");
+ TokError("expected string parameter for '.ifeqs' directive");
+ else
+ TokError("expected string parameter for '.ifnes' directive");
+ eatToEndOfStatement();
+ return true;
}
StringRef String1 = getTok().getStringContents();
@@ -4619,17 +4094,22 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
if (Lexer.isNot(AsmToken::Comma)) {
if (ExpectEqual)
- return TokError(
- "expected comma after first string for '.ifeqs' directive");
- return TokError("expected comma after first string for '.ifnes' directive");
+ TokError("expected comma after first string for '.ifeqs' directive");
+ else
+ TokError("expected comma after first string for '.ifnes' directive");
+ eatToEndOfStatement();
+ return true;
}
Lex();
if (Lexer.isNot(AsmToken::String)) {
if (ExpectEqual)
- return TokError("expected string parameter for '.ifeqs' directive");
- return TokError("expected string parameter for '.ifnes' directive");
+ TokError("expected string parameter for '.ifeqs' directive");
+ else
+ TokError("expected string parameter for '.ifnes' directive");
+ eatToEndOfStatement();
+ return true;
}
StringRef String2 = getTok().getStringContents();
@@ -4653,9 +4133,10 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
if (TheCondState.Ignore) {
eatToEndOfStatement();
} else {
- if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
- parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
- return true;
+ if (parseIdentifier(Name))
+ return TokError("expected identifier after '.ifdef'");
+
+ Lex();
MCSymbol *Sym = getContext().lookupSymbol(Name);
@@ -4674,8 +4155,8 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
- return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
- " .if or an .elseif");
+ Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
+ " an .elseif");
TheCondState.TheCond = AsmCond::ElseIfCond;
bool LastIgnoreState = false;
@@ -4689,10 +4170,10 @@ bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
if (parseAbsoluteExpression(ExprValue))
return true;
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.elseif' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.elseif' directive");
+ Lex();
TheCondState.CondMet = ExprValue;
TheCondState.Ignore = !TheCondState.CondMet;
}
@@ -4703,14 +4184,15 @@ bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
/// parseDirectiveElse
/// ::= .else
bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.else' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.else' directive");
+
+ Lex();
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
- return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
- " an .if or an .elseif");
+ Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
+ ".elseif");
TheCondState.TheCond = AsmCond::ElseCond;
bool LastIgnoreState = false;
if (!TheCondStack.empty())
@@ -4726,12 +4208,13 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
/// parseDirectiveEnd
/// ::= .end
bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.end' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.end' directive");
+
+ Lex();
while (Lexer.isNot(AsmToken::Eof))
- Lexer.Lex();
+ Lex();
return false;
}
@@ -4752,14 +4235,18 @@ bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
StringRef Message = ".error directive invoked in source file";
if (Lexer.isNot(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::String))
- return TokError(".error argument must be a string");
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError(".error argument must be a string");
+ eatToEndOfStatement();
+ return true;
+ }
Message = getTok().getStringContents();
Lex();
}
- return Error(L, Message);
+ Error(L, Message);
+ return true;
}
/// parseDirectiveWarning
@@ -4773,31 +4260,32 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
}
StringRef Message = ".warning directive invoked in source file";
-
- if (!parseOptionalToken(AsmToken::EndOfStatement)) {
- if (Lexer.isNot(AsmToken::String))
- return TokError(".warning argument must be a string");
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError(".warning argument must be a string");
+ eatToEndOfStatement();
+ return true;
+ }
Message = getTok().getStringContents();
Lex();
- if (parseToken(AsmToken::EndOfStatement,
- "expected end of statement in '.warning' directive"))
- return true;
}
- return Warning(L, Message);
+ Warning(L, Message);
+ return false;
}
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
- if (parseToken(AsmToken::EndOfStatement,
- "unexpected token in '.endif' directive"))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.endif' directive");
+
+ Lex();
if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
- return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
- "an .if or .else");
+ Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
+ ".else");
if (!TheCondStack.empty()) {
TheCondState = TheCondStack.back();
TheCondStack.pop_back();
@@ -4890,15 +4378,6 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".line"] = DK_LINE;
DirectiveKindMap[".loc"] = DK_LOC;
DirectiveKindMap[".stabs"] = DK_STABS;
- DirectiveKindMap[".cv_file"] = DK_CV_FILE;
- DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
- DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
- DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
- 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_stringtable"] = DK_CV_STRINGTABLE;
- DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
DirectiveKindMap[".sleb128"] = DK_SLEB128;
DirectiveKindMap[".uleb128"] = DK_ULEB128;
DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
@@ -4932,46 +4411,21 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".error"] = DK_ERROR;
DirectiveKindMap[".warning"] = DK_WARNING;
DirectiveKindMap[".reloc"] = DK_RELOC;
- DirectiveKindMap[".dc"] = DK_DC;
- DirectiveKindMap[".dc.a"] = DK_DC_A;
- DirectiveKindMap[".dc.b"] = DK_DC_B;
- DirectiveKindMap[".dc.d"] = DK_DC_D;
- DirectiveKindMap[".dc.l"] = DK_DC_L;
- DirectiveKindMap[".dc.s"] = DK_DC_S;
- DirectiveKindMap[".dc.w"] = DK_DC_W;
- DirectiveKindMap[".dc.x"] = DK_DC_X;
- DirectiveKindMap[".dcb"] = DK_DCB;
- DirectiveKindMap[".dcb.b"] = DK_DCB_B;
- DirectiveKindMap[".dcb.d"] = DK_DCB_D;
- DirectiveKindMap[".dcb.l"] = DK_DCB_L;
- DirectiveKindMap[".dcb.s"] = DK_DCB_S;
- DirectiveKindMap[".dcb.w"] = DK_DCB_W;
- DirectiveKindMap[".dcb.x"] = DK_DCB_X;
- DirectiveKindMap[".ds"] = DK_DS;
- DirectiveKindMap[".ds.b"] = DK_DS_B;
- DirectiveKindMap[".ds.d"] = DK_DS_D;
- DirectiveKindMap[".ds.l"] = DK_DS_L;
- DirectiveKindMap[".ds.p"] = DK_DS_P;
- DirectiveKindMap[".ds.s"] = DK_DS_S;
- DirectiveKindMap[".ds.w"] = DK_DS_W;
- DirectiveKindMap[".ds.x"] = DK_DS_X;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
AsmToken EndToken, StartToken = getTok();
unsigned NestLevel = 0;
- while (true) {
+ for (;;) {
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof)) {
- printError(DirectiveLoc, "no matching '.endr' in definition");
+ Error(DirectiveLoc, "no matching '.endr' in definition");
return nullptr;
}
if (Lexer.is(AsmToken::Identifier) &&
- (getTok().getIdentifier() == ".rept" ||
- getTok().getIdentifier() == ".irp" ||
- getTok().getIdentifier() == ".irpc")) {
+ (getTok().getIdentifier() == ".rept")) {
++NestLevel;
}
@@ -4981,8 +4435,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
EndToken = getTok();
Lex();
if (Lexer.isNot(AsmToken::EndOfStatement)) {
- printError(getTok().getLoc(),
- "unexpected token in '.endr' directive");
+ TokError("unexpected token in '.endr' directive");
return nullptr;
}
break;
@@ -5032,13 +4485,18 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
int64_t Count;
if (!CountExpr->evaluateAsAbsolute(Count)) {
+ eatToEndOfStatement();
return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
}
- if (check(Count < 0, CountLoc, "Count is negative") ||
- parseToken(AsmToken::EndOfStatement,
- "unexpected token in '" + Dir + "' directive"))
- return true;
+ if (Count < 0)
+ return Error(CountLoc, "Count is negative");
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Dir + "' directive");
+
+ // Eat the end of statement.
+ Lex();
// Lex the rept definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
@@ -5063,14 +4521,22 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
/// ::= .irp symbol,values
bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
MCAsmMacroParameter Parameter;
+
+ if (parseIdentifier(Parameter.Name))
+ return TokError("expected identifier in '.irp' directive");
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("expected comma in '.irp' directive");
+
+ Lex();
+
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"))
+ if (parseMacroArguments(nullptr, A))
return true;
+ // Eat the end of statement.
+ Lex();
+
// Lex the irp definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
@@ -5097,20 +4563,24 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
/// ::= .irpc symbol,values
bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
MCAsmMacroParameter Parameter;
- MCAsmMacroArguments A;
- if (check(parseIdentifier(Parameter.Name),
- "expected identifier in '.irpc' directive") ||
- parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
- parseMacroArguments(nullptr, A))
+ if (parseIdentifier(Parameter.Name))
+ return TokError("expected identifier in '.irpc' directive");
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("expected comma in '.irpc' directive");
+
+ Lex();
+
+ MCAsmMacroArguments A;
+ if (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"))
- return true;
+ Lex();
// Lex the irpc definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
@@ -5229,21 +4699,12 @@ bool AsmParser::parseMSInlineAsm(
unsigned InputIdx = 0;
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
- // Parse curly braces marking block start/end
- if (parseCurlyBlockScope(AsmStrRewrites))
- continue;
-
ParseStatementInfo Info(&AsmStrRewrites);
- bool StatementErr = parseStatement(Info, &SI);
-
- if (StatementErr || Info.ParseError) {
- // Emit pending errors if any exist.
- printPendingErrors();
+ if (parseStatement(Info, &SI))
return true;
- }
- // No pending error should exist here.
- assert(!hasPendingError() && "unexpected error from parseStatement");
+ if (Info.ParseError)
+ return true;
if (Info.Opcode == ~0U)
continue;
@@ -5414,9 +4875,6 @@ bool AsmParser::parseMSInlineAsm(
OS << '.';
OS << AR.Val;
break;
- case AOK_EndOfStatement:
- OS << "\n\t";
- break;
}
// Skip the original expression.
@@ -5464,20 +4922,26 @@ static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
bool parseAssignmentExpression(StringRef Name, bool allow_redef,
MCAsmParser &Parser, MCSymbol *&Sym,
const MCExpr *&Value) {
+ MCAsmLexer &Lexer = Parser.getLexer();
// FIXME: Use better location, we should use proper tokens.
- SMLoc EqualLoc = Parser.getTok().getLoc();
+ SMLoc EqualLoc = Lexer.getLoc();
if (Parser.parseExpression(Value)) {
- return Parser.TokError("missing expression");
+ Parser.TokError("missing expression");
+ Parser.eatToEndOfStatement();
+ return true;
}
// Note: we don't count b as used in "a = b". This is to allow
// a = b
// b = c
- if (Parser.parseToken(AsmToken::EndOfStatement))
- return true;
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return Parser.TokError("unexpected token in assignment");
+
+ // Eat the end of statement marker.
+ Parser.Lex();
// 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).
@@ -5503,7 +4967,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
"invalid reassignment of non-absolute variable '" +
Name + "'");
} else if (Name == ".") {
- Parser.getStreamer().emitValueToOffset(Value, 0, EqualLoc);
+ Parser.getStreamer().emitValueToOffset(Value, 0);
return false;
} else
Sym = Parser.getContext().getOrCreateSymbol(Name);
@@ -5513,8 +4977,8 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
return false;
}
-} // end namespace MCParserUtils
-} // end namespace llvm
+} // namespace MCParserUtils
+} // namespace llvm
/// \brief Create an MCAsmParser instance.
MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,