summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp206
-rw-r--r--lib/MC/MCParser/AsmParser.cpp1206
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp2
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp35
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp30
-rw-r--r--lib/MC/MCParser/MCAsmLexer.cpp2
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp4
-rw-r--r--lib/MC/MCParser/MCTargetAsmParser.cpp2
-rw-r--r--lib/MC/MCParser/Makefile15
9 files changed, 896 insertions, 606 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index 36c192026856a..d56071aea4df0 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -23,7 +23,8 @@ using namespace llvm;
AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) {
CurPtr = nullptr;
- isAtStartOfLine = true;
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
}
@@ -46,24 +47,13 @@ void AsmLexer::setBuffer(StringRef Buf, const char *ptr) {
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
SetError(SMLoc::getFromPointer(Loc), Msg);
- return AsmToken(AsmToken::Error, StringRef(Loc, 0));
+ return AsmToken(AsmToken::Error, StringRef(Loc, CurPtr - Loc));
}
int AsmLexer::getNextChar() {
- char CurChar = *CurPtr++;
- switch (CurChar) {
- default:
- return (unsigned char)CurChar;
- case 0:
- // A nul character in the stream is either the end of the current buffer or
- // a random nul in the file. Disambiguate that here.
- if (CurPtr - 1 != CurBuf.end())
- return 0; // Just whitespace.
-
- // Otherwise, return end of file.
- --CurPtr; // Another call to lex will return EOF again.
+ if (CurPtr == CurBuf.end())
return EOF;
- }
+ return (unsigned char)*CurPtr++;
}
/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)?
@@ -168,40 +158,53 @@ AsmToken AsmLexer::LexIdentifier() {
/// C-Style Comment: /* ... */
AsmToken AsmLexer::LexSlash() {
switch (*CurPtr) {
- case '*': break; // C style comment.
- case '/': return ++CurPtr, LexLineComment();
- default: return AsmToken(AsmToken::Slash, StringRef(CurPtr-1, 1));
+ case '*':
+ IsAtStartOfStatement = false;
+ break; // C style comment.
+ case '/':
+ ++CurPtr;
+ return LexLineComment();
+ default:
+ IsAtStartOfStatement = false;
+ return AsmToken(AsmToken::Slash, StringRef(TokStart, 1));
}
// C Style comment.
++CurPtr; // skip the star.
- while (1) {
- int CurChar = getNextChar();
- switch (CurChar) {
- case EOF:
- return ReturnError(TokStart, "unterminated comment");
+ while (CurPtr != CurBuf.end()) {
+ switch (*CurPtr++) {
case '*':
// End of the comment?
- if (CurPtr[0] != '/') break;
-
+ if (*CurPtr != '/')
+ break;
++CurPtr; // End the */.
- return LexToken();
+ return AsmToken(AsmToken::Comment,
+ StringRef(TokStart, CurPtr - TokStart));
}
}
+ return ReturnError(TokStart, "unterminated comment");
}
/// LexLineComment: Comment: #[^\n]*
/// : //[^\n]*
AsmToken AsmLexer::LexLineComment() {
- // FIXME: This is broken if we happen to a comment at the end of a file, which
- // was .included, and which doesn't end with a newline.
+ // Mark This as an end of statement with a body of the
+ // comment. While it would be nicer to leave this two tokens,
+ // backwards compatability with TargetParsers makes keeping this in this form
+ // better.
int CurChar = getNextChar();
while (CurChar != '\n' && CurChar != '\r' && CurChar != EOF)
CurChar = getNextChar();
- if (CurChar == EOF)
- return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
- return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0));
+ IsAtStartOfLine = true;
+ // Whis is a whole line comment. leave newline
+ if (IsAtStartOfStatement)
+ return AsmToken(AsmToken::EndOfStatement,
+ StringRef(TokStart, CurPtr - TokStart));
+ IsAtStartOfStatement = true;
+
+ return AsmToken(AsmToken::EndOfStatement,
+ StringRef(TokStart, CurPtr - 1 - TokStart));
}
static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
@@ -280,7 +283,7 @@ AsmToken AsmLexer::LexDigit() {
return intToken(Result, Value);
}
- if (*CurPtr == 'b') {
+ if ((*CurPtr == 'b') || (*CurPtr == 'B')) {
++CurPtr;
// See if we actually have "0b" as part of something like "jmp 0b\n"
if (!isdigit(CurPtr[0])) {
@@ -309,7 +312,7 @@ AsmToken AsmLexer::LexDigit() {
return intToken(Result, Value);
}
- if (*CurPtr == 'x') {
+ if ((*CurPtr == 'x') || (*CurPtr == 'X')) {
++CurPtr;
const char *NumStart = CurPtr;
while (isxdigit(CurPtr[0]))
@@ -419,8 +422,7 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
while (!isAtStartOfComment(CurPtr) && // Start of line comment.
!isAtStatementSeparator(CurPtr) && // End of statement marker.
- *CurPtr != '\n' && *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf.end())) {
+ *CurPtr != '\n' && *CurPtr != '\r' && CurPtr != CurBuf.end()) {
++CurPtr;
}
return StringRef(TokStart, CurPtr-TokStart);
@@ -429,8 +431,7 @@ StringRef AsmLexer::LexUntilEndOfStatement() {
StringRef AsmLexer::LexUntilEndOfLine() {
TokStart = CurPtr;
- while (*CurPtr != '\n' && *CurPtr != '\r' &&
- (*CurPtr != 0 || CurPtr != CurBuf.end())) {
+ while (*CurPtr != '\n' && *CurPtr != '\r' && CurPtr != CurBuf.end()) {
++CurPtr;
}
return StringRef(TokStart, CurPtr-TokStart);
@@ -440,7 +441,8 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
bool ShouldSkipSpace) {
const char *SavedTokStart = TokStart;
const char *SavedCurPtr = CurPtr;
- bool SavedAtStartOfLine = isAtStartOfLine;
+ bool SavedAtStartOfLine = IsAtStartOfLine;
+ bool SavedAtStartOfStatement = IsAtStartOfStatement;
bool SavedSkipSpace = SkipSpace;
std::string SavedErr = getErr();
@@ -461,7 +463,8 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
SetError(SavedErrLoc, SavedErr);
SkipSpace = SavedSkipSpace;
- isAtStartOfLine = SavedAtStartOfLine;
+ IsAtStartOfLine = SavedAtStartOfLine;
+ IsAtStartOfStatement = SavedAtStartOfStatement;
CurPtr = SavedCurPtr;
TokStart = SavedTokStart;
@@ -491,29 +494,45 @@ AsmToken AsmLexer::LexToken() {
// This always consumes at least one character.
int CurChar = getNextChar();
- if (isAtStartOfComment(TokStart)) {
- // If this comment starts with a '#', then return the Hash token and let
- // the assembler parser see if it can be parsed as a cpp line filename
- // comment. We do this only if we are at the start of a line.
- if (CurChar == '#' && isAtStartOfLine)
- return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
- isAtStartOfLine = true;
+ if (CurChar == '#' && IsAtStartOfStatement) {
+ // If this starts with a '#', this may be a cpp
+ // hash directive and otherwise a line comment.
+ AsmToken TokenBuf[2];
+ MutableArrayRef<AsmToken> Buf(TokenBuf, 2);
+ size_t num = peekTokens(Buf, true);
+ // There cannot be a space preceeding this
+ if (IsAtStartOfLine && num == 2 && TokenBuf[0].is(AsmToken::Integer) &&
+ TokenBuf[1].is(AsmToken::String)) {
+ CurPtr = TokStart; // reset curPtr;
+ StringRef s = LexUntilEndOfLine();
+ UnLex(TokenBuf[1]);
+ UnLex(TokenBuf[0]);
+ return AsmToken(AsmToken::HashDirective, s);
+ }
return LexLineComment();
}
+
+ if (isAtStartOfComment(TokStart))
+ return LexLineComment();
+
if (isAtStatementSeparator(TokStart)) {
CurPtr += strlen(MAI.getSeparatorString()) - 1;
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
return AsmToken(AsmToken::EndOfStatement,
StringRef(TokStart, strlen(MAI.getSeparatorString())));
}
// If we're missing a newline at EOF, make sure we still get an
// EndOfStatement token before the Eof token.
- if (CurChar == EOF && !isAtStartOfLine) {
- isAtStartOfLine = true;
+ if (CurChar == EOF && !IsAtStartOfStatement) {
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
}
-
- isAtStartOfLine = false;
+ IsAtStartOfLine = false;
+ bool OldIsAtStartOfStatement = IsAtStartOfStatement;
+ IsAtStartOfStatement = false;
switch (CurChar) {
default:
// Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
@@ -522,24 +541,24 @@ AsmToken AsmLexer::LexToken() {
// Unknown character, emit an error.
return ReturnError(TokStart, "invalid character in input");
- case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
+ case EOF:
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
+ return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
case 0:
case ' ':
case '\t':
- if (SkipSpace) {
- // Ignore whitespace.
- return LexToken();
- } else {
- int len = 1;
- while (*CurPtr==' ' || *CurPtr=='\t') {
- CurPtr++;
- len++;
- }
- return AsmToken(AsmToken::Space, StringRef(TokStart, len));
- }
- case '\n': // FALL THROUGH.
+ IsAtStartOfStatement = OldIsAtStartOfStatement;
+ while (*CurPtr == ' ' || *CurPtr == '\t')
+ CurPtr++;
+ if (SkipSpace)
+ return LexToken(); // Ignore whitespace.
+ else
+ return AsmToken(AsmToken::Space, StringRef(TokStart, CurPtr - TokStart));
+ case '\n':
case '\r':
- isAtStartOfLine = true;
+ IsAtStartOfLine = true;
+ IsAtStartOfStatement = true;
return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
@@ -557,24 +576,34 @@ AsmToken AsmLexer::LexToken() {
case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1));
case '\\': return AsmToken(AsmToken::BackSlash, StringRef(TokStart, 1));
case '=':
- if (*CurPtr == '=')
- return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
+ if (*CurPtr == '=') {
+ ++CurPtr;
+ return AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
case '|':
- if (*CurPtr == '|')
- return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
+ if (*CurPtr == '|') {
+ ++CurPtr;
+ return AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
case '&':
- if (*CurPtr == '&')
- return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
+ if (*CurPtr == '&') {
+ ++CurPtr;
+ return AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
case '!':
- if (*CurPtr == '=')
- return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
+ if (*CurPtr == '=') {
+ ++CurPtr;
+ return AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
+ }
return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
- case '/': return LexSlash();
+ case '/':
+ IsAtStartOfStatement = OldIsAtStartOfStatement;
+ return LexSlash();
case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
case '\'': return LexSingleQuote();
case '"': return LexQuote();
@@ -583,21 +612,28 @@ AsmToken AsmLexer::LexToken() {
return LexDigit();
case '<':
switch (*CurPtr) {
- case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
- StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
- StringRef(TokStart, 2));
- case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
- StringRef(TokStart, 2));
- default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
+ case '<':
+ ++CurPtr;
+ return AsmToken(AsmToken::LessLess, StringRef(TokStart, 2));
+ case '=':
+ ++CurPtr;
+ return AsmToken(AsmToken::LessEqual, StringRef(TokStart, 2));
+ case '>':
+ ++CurPtr;
+ return AsmToken(AsmToken::LessGreater, StringRef(TokStart, 2));
+ default:
+ return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
}
case '>':
switch (*CurPtr) {
- case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
- StringRef(TokStart, 2));
- case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
- StringRef(TokStart, 2));
- default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
+ case '>':
+ ++CurPtr;
+ return AsmToken(AsmToken::GreaterGreater, StringRef(TokStart, 2));
+ case '=':
+ ++CurPtr;
+ return AsmToken(AsmToken::GreaterEqual, StringRef(TokStart, 2));
+ default:
+ return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
}
// TODO: Quoted identifiers (objc methods etc)
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 646cbb43cae8a..1548aee84227a 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -28,13 +28,12 @@
#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/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/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -42,7 +41,6 @@
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <deque>
-#include <set>
#include <string>
#include <vector>
using namespace llvm;
@@ -156,10 +154,17 @@ private:
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;
+ 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;
+
/// 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
@@ -245,13 +250,36 @@ public:
void eatToEndOfStatement() override;
void checkForValidSection() override;
+
+ bool getTokenLoc(SMLoc &Loc) {
+ Loc = getTok().getLoc();
+ return false;
+ }
+
+ /// parseToken - If current token has the specified kind, eat it and
+ /// return success. Otherwise, emit the specified error and return failure.
+ bool parseToken(AsmToken::TokenKind T, const Twine &ErrMsg) {
+ if (getTok().getKind() != T)
+ return TokError(ErrMsg);
+ Lex();
+ return false;
+ }
+
+ bool parseIntToken(int64_t &V, const Twine &ErrMsg) {
+ if (getTok().getKind() != AsmToken::Integer)
+ return TokError(ErrMsg);
+ V = getTok().getIntVal();
+ Lex();
+ return false;
+ }
+
/// }
private:
bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
- void eatToEndOfLine();
+ bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
bool parseCppHashLineFilenameComment(SMLoc L);
void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
@@ -303,6 +331,18 @@ private:
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
+ bool check(bool P, SMLoc Loc, const Twine &Msg) {
+ if (P)
+ return Error(Loc, Msg);
+ return false;
+ }
+
+ bool check(bool P, const Twine &Msg) {
+ if (P)
+ return TokError(Msg);
+ return false;
+ }
+
/// \brief Enter the specified file. This returns true on failure.
bool enterIncludeFile(const std::string &Filename);
@@ -349,14 +389,16 @@ private:
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_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,
@@ -394,6 +436,16 @@ private:
bool parseDirectiveLoc();
bool parseDirectiveStabs();
+ // ".cv_file", ".cv_loc", ".cv_linetable", "cv_inline_linetable",
+ // ".cv_def_range"
+ bool parseDirectiveCVFile();
+ bool parseDirectiveCVLoc();
+ bool parseDirectiveCVLinetable();
+ bool parseDirectiveCVInlineLinetable();
+ bool parseDirectiveCVDefRange();
+ bool parseDirectiveCVStringTable();
+ bool parseDirectiveCVFileChecksums();
+
// .cfi directives
bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
bool parseDirectiveCFIWindowSave();
@@ -506,7 +558,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI)
: Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
PlatformParser(nullptr), CurBuffer(SM.getMainFileID()),
- MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0),
+ MacrosEnabledFlag(true), HadError(false), CppHashInfo(),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
@@ -606,20 +658,36 @@ 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);
- tok = &Lexer.Lex();
+ return Lex();
}
}
- if (tok->is(AsmToken::Error))
- Error(Lexer.getErrLoc(), Lexer.getErr());
return *tok;
}
@@ -657,6 +725,12 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
if (!parseStatement(Info, nullptr))
continue;
+ // If we've failed, but on a Error Token, but did not consume it in
+ // favor of a better message, emit it now.
+ if (Lexer.getTok().is(AsmToken::Error)) {
+ Lex();
+ }
+
// 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!");
@@ -683,18 +757,32 @@ 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 && 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");
+ 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.
+ HadError |=
+ Error(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);
+ HadError |= Error(std::get<0>(LocSym), "directional label undefined");
+ }
}
}
@@ -716,18 +804,18 @@ void AsmParser::checkForValidSection() {
/// \brief Throw away the rest of the line for testing purposes.
void AsmParser::eatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
- Lex();
+ Lexer.Lex();
// Eat EOL.
if (Lexer.is(AsmToken::EndOfStatement))
- Lex();
+ Lexer.Lex();
}
StringRef AsmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
- Lex();
+ Lexer.Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
@@ -738,7 +826,7 @@ StringRef AsmParser::parseStringToComma() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof))
- Lex();
+ Lexer.Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
@@ -767,10 +855,9 @@ bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (parseExpression(Res))
return true;
- if (Lexer.isNot(AsmToken::RBrac))
- return TokError("expected ']' in brackets expression");
- EndLoc = Lexer.getTok().getEndLoc();
- Lex();
+ EndLoc = getTok().getEndLoc();
+ if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
+ return true;
return false;
}
@@ -820,7 +907,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (!MAI.useParensForSymbolVariant()) {
if (FirstTokenKind == AsmToken::String) {
if (Lexer.is(AsmToken::At)) {
- Lexer.Lex(); // eat @
+ Lex(); // eat @
SMLoc AtLoc = getLexer().getLoc();
StringRef VName;
if (parseIdentifier(VName))
@@ -832,14 +919,13 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Split = Identifier.split('@');
}
} else if (Lexer.is(AsmToken::LParen)) {
- Lexer.Lex(); // eat (
+ Lex(); // eat '('.
StringRef VName;
parseIdentifier(VName);
- if (Lexer.isNot(AsmToken::RParen)) {
- return Error(Lexer.getTok().getLoc(),
- "unexpected token in variant, expected ')'");
- }
- Lexer.Lex(); // eat )
+ // eat ')'.
+ if (parseToken(AsmToken::RParen,
+ "unexpected token in variant, expected ')'"))
+ return true;
Split = std::make_pair(Identifier, VName);
}
@@ -904,7 +990,8 @@ 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, "invalid reference to undefined symbol");
+ return Error(Loc, "directional label undefined");
+ DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat identifier.
}
@@ -1082,10 +1169,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) {
- if (Lexer.isNot(AsmToken::RParen))
- return TokError("expected ')' in parentheses expression");
- EndLoc = Lexer.getTok().getEndLoc();
- Lex();
+ EndLoc = getTok().getEndLoc();
+ if (parseToken(AsmToken::RParen,
+ "expected ')' in parentheses expression"))
+ return true;
}
}
return false;
@@ -1303,21 +1390,24 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
/// ::= Label* Identifier OperandList* EndOfStatement
bool AsmParser::parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI) {
+ // Eat initial spaces and comments
+ while (Lexer.is(AsmToken::Space))
+ Lex();
if (Lexer.is(AsmToken::EndOfStatement)) {
- Out.AddBlankLine();
+ // if this is a line comment we can drop it safely
+ if (getTok().getString().front() == '\r' ||
+ getTok().getString().front() == '\n')
+ Out.AddBlankLine();
Lex();
return false;
}
-
- // Statements always start with an identifier or are a full line comment.
+ // Statements always start with an identifier.
AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
int64_t LocalLabelVal = -1;
- // A full line comment is a '#' as the first token.
- if (Lexer.is(AsmToken::Hash))
+ if (Lexer.is(AsmToken::HashDirective))
return parseCppHashLineFilenameComment(IDLoc);
-
// Allow an integer followed by a ':' as a directional local label.
if (Lexer.is(AsmToken::Integer)) {
LocalLabelVal = getTok().getIntVal();
@@ -1444,6 +1534,12 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
if (!Sym->isUndefined() || Sym->isVariable())
return Error(IDLoc, "invalid symbol redefinition");
+ // 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);
@@ -1456,13 +1552,7 @@ 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;
}
@@ -1608,7 +1698,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveIncbin();
case DK_CODE16:
case DK_CODE16GCC:
- return TokError(Twine(IDVal) + " not supported yet");
+ return TokError(Twine(IDVal) +
+ " not currently supported for this target");
case DK_REPT:
return parseDirectiveRept(IDLoc, IDVal);
case DK_IRP:
@@ -1638,6 +1729,20 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return parseDirectiveLoc();
case DK_STABS:
return parseDirectiveStabs();
+ case DK_CV_FILE:
+ return parseDirectiveCVFile();
+ 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:
@@ -1755,24 +1860,26 @@ 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 (CppHashFilename.size()) {
+ if (CppHashInfo.Filename.size()) {
unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
- 0, StringRef(), CppHashFilename);
+ 0, StringRef(), CppHashInfo.Filename);
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 == CppHashLoc && LastQueryBuffer == CppHashBuf)
+ if (LastQueryIDLoc == CppHashInfo.Loc &&
+ LastQueryBuffer == CppHashInfo.Buf)
CppHashLocLineNo = LastQueryLine;
else {
- CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf);
+ CppHashLocLineNo =
+ SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
LastQueryLine = CppHashLocLineNo;
- LastQueryIDLoc = CppHashLoc;
- LastQueryBuffer = CppHashBuf;
+ LastQueryIDLoc = CppHashInfo.Loc;
+ LastQueryBuffer = CppHashInfo.Buf;
}
- Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
+ Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
}
getStreamer().EmitDwarfLocDirective(
@@ -1794,48 +1901,46 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
return false;
}
-/// 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();
+// 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;
}
/// 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.
-
- 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;
- }
-
+ // 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");
int64_t LineNumber = getTok().getIntVal();
Lex();
-
- if (getLexer().isNot(AsmToken::String)) {
- eatToEndOfLine();
- return false;
- }
-
+ assert(getTok().is(AsmToken::String) &&
+ "Lexing Cpp line comment: Expected String");
StringRef Filename = getTok().getString();
+ Lex();
// Get rid of the enclosing quotes.
Filename = Filename.substr(1, Filename.size() - 2);
// Save the SMLoc, Filename and LineNumber for later use by diagnostics.
- CppHashLoc = L;
- CppHashFilename = Filename;
- CppHashLineNumber = LineNumber;
- CppHashBuf = CurBuffer;
-
- // Ignore any trailing characters, they're just comment.
- eatToEndOfLine();
+ CppHashInfo.Loc = L;
+ CppHashInfo.Filename = Filename;
+ CppHashInfo.LineNumber = LineNumber;
+ CppHashInfo.Buf = CurBuffer;
return false;
}
@@ -1849,7 +1954,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
SMLoc DiagLoc = Diag.getLoc();
unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
unsigned CppHashBuf =
- Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
+ Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
// Like SourceMgr::printMessage() we need to print the include stack if any
// before printing the message.
@@ -1863,7 +1968,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->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
+ if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
DiagBuf != CppHashBuf) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
@@ -1873,15 +1978,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
}
// Use the CppHashFilename and calculate a line number based on the
- // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
- // the diagnostic.
- const std::string &Filename = Parser->CppHashFilename;
+ // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
+ // for the diagnostic.
+ const std::string &Filename = Parser->CppHashInfo.Filename;
int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
int CppHashLocLineNo =
- Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
+ Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
int LineNo =
- Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
+ Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
@@ -2041,7 +2146,6 @@ 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:
@@ -2080,37 +2184,44 @@ 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;
+
for (;;) {
+ SpaceEaten = false;
if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
return TokError("unexpected token in macro instantiation");
- if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
- break;
+ if (ParenLevel == 0) {
+
+ if (Lexer.is(AsmToken::Comma))
+ break;
- if (Lexer.is(AsmToken::Space)) {
- Lex(); // Eat spaces
+ if (Lexer.is(AsmToken::Space)) {
+ SpaceEaten = true;
+ Lexer.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())) {
- // 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;
- }
+ MA.push_back(getTok());
+ Lexer.Lex();
- if (!AddTokens && ParenLevel == 0) {
- break;
+ // Whitespace after an operator can be ignored.
+ if (Lexer.is(AsmToken::Space))
+ Lexer.Lex();
+
+ continue;
}
}
+ if (SpaceEaten)
+ break;
}
// handleMacroEntry relies on not advancing the lexer here
@@ -2126,9 +2237,7 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
// Append the token to the current argument list.
MA.push_back(getTok());
- if (AddTokens)
- AddTokens--;
- Lex();
+ Lexer.Lex();
}
if (ParenLevel != 0)
@@ -2162,7 +2271,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
return true;
}
- if (!Lexer.is(AsmToken::Equal)) {
+ if (Lexer.isNot(AsmToken::Equal)) {
TokError("expected '=' after formal parameter identifier");
eatToEndOfStatement();
return true;
@@ -2190,7 +2299,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
break;
if (FAI >= NParameters) {
- assert(M && "expected macro to be defined");
+ assert(M && "expected macro to be defined");
Error(IDLoc,
"parameter named '" + FA.Name + "' does not exist for macro '" +
M->Name + "'");
@@ -2337,7 +2446,7 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
SMLoc PrefixLoc = getLexer().getLoc();
// Consume the prefix character, and check for a following identifier.
- Lex();
+ Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
if (Lexer.isNot(AsmToken::Identifier))
return true;
@@ -2348,7 +2457,7 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
// Construct the joined identifier and consume the token.
Res =
StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
- Lex();
+ Lex(); // Parser Lex to maintain invariants.
return false;
}
@@ -2369,12 +2478,10 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
- if (parseIdentifier(Name))
- return TokError("expected identifier after '" + Twine(IDVal) + "'");
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '" + Twine(IDVal) + "'");
- Lex();
+ if (check(parseIdentifier(Name),
+ "expected identifier after '" + Twine(IDVal) + "'") ||
+ parseToken(AsmToken::Comma, "unexpected token in '" + Twine(IDVal) + "'"))
+ return true;
return parseAssignment(Name, allow_redef, true);
}
@@ -2434,6 +2541,7 @@ bool AsmParser::parseEscapedString(std::string &Data) {
}
}
+ Lex();
return false;
}
@@ -2444,25 +2552,22 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
checkForValidSection();
for (;;) {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '" + Twine(IDVal) + "' directive");
-
std::string Data;
- if (parseEscapedString(Data))
+ if (check(getTok().isNot(AsmToken::String),
+ "expected string in '" + Twine(IDVal) + "' directive") ||
+ parseEscapedString(Data))
return true;
getStreamer().EmitBytes(Data);
if (ZeroTerminated)
getStreamer().EmitBytes(StringRef("\0", 1));
- Lex();
-
if (getLexer().is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
- Lex();
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
}
}
@@ -2482,21 +2587,19 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
// 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 (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;
- if (Lexer.isNot(AsmToken::Identifier))
- return TokError("expected relocation name");
SMLoc NameLoc = Lexer.getTok().getLoc();
StringRef Name = Lexer.getTok().getIdentifier();
- Lexer.Lex();
+ Lex();
if (Lexer.is(AsmToken::Comma)) {
- Lexer.Lex();
+ Lex();
SMLoc ExprLoc = Lexer.getLoc();
if (parseExpression(Expr))
return true;
@@ -2506,12 +2609,11 @@ bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
return Error(ExprLoc, "expression must be relocatable");
}
- 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");
-
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in .reloc directive") ||
+ check(getStreamer().EmitRelocDirective(*Offset, Name, Expr, DirectiveLoc),
+ NameLoc, "unknown relocation name"))
+ return true;
return false;
}
@@ -2541,9 +2643,8 @@ bool AsmParser::parseDirectiveValue(unsigned Size) {
break;
// FIXME: Improve diagnostic.
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -2558,10 +2659,9 @@ bool AsmParser::parseDirectiveOctaValue() {
checkForValidSection();
for (;;) {
- if (Lexer.getKind() == AsmToken::Error)
+ if (getTok().is(AsmToken::Error))
return true;
- if (Lexer.getKind() != AsmToken::Integer &&
- Lexer.getKind() != AsmToken::BigNum)
+ if (getTok().isNot(AsmToken::Integer) && getTok().isNot(AsmToken::BigNum))
return TokError("unknown token in expression");
SMLoc ExprLoc = getLexer().getLoc();
@@ -2591,9 +2691,8 @@ bool AsmParser::parseDirectiveOctaValue() {
break;
// FIXME: Improve diagnostic.
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -2612,14 +2711,15 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
// have to manually parse unary prefixes.
bool IsNeg = false;
if (getLexer().is(AsmToken::Minus)) {
- Lex();
+ Lexer.Lex();
IsNeg = true;
} else if (getLexer().is(AsmToken::Plus))
- Lex();
+ Lexer.Lex();
- if (getLexer().isNot(AsmToken::Integer) &&
- getLexer().isNot(AsmToken::Real) &&
- getLexer().isNot(AsmToken::Identifier))
+ 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");
// Convert to an APFloat.
@@ -2646,12 +2746,11 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
getStreamer().EmitIntValue(AsInt.getLimitedValue(),
AsInt.getBitWidth() / 8);
- if (getLexer().is(AsmToken::EndOfStatement))
+ if (Lexer.is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -2664,8 +2763,9 @@ bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
bool AsmParser::parseDirectiveZero() {
checkForValidSection();
- int64_t NumBytes;
- if (parseAbsoluteExpression(NumBytes))
+ SMLoc NumBytesLoc = Lexer.getLoc();
+ const MCExpr *NumBytes;
+ if (parseExpression(NumBytes))
return true;
int64_t Val = 0;
@@ -2675,12 +2775,10 @@ bool AsmParser::parseDirectiveZero() {
return true;
}
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.zero' directive");
-
- Lex();
-
- getStreamer().EmitFill(NumBytes, Val);
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.zero' directive"))
+ return true;
+ getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
return false;
}
@@ -2690,49 +2788,34 @@ bool AsmParser::parseDirectiveZero() {
bool AsmParser::parseDirectiveFill() {
checkForValidSection();
- SMLoc RepeatLoc = getLexer().getLoc();
- int64_t NumValues;
- if (parseAbsoluteExpression(NumValues))
+ SMLoc NumValuesLoc = Lexer.getLoc();
+ const MCExpr *NumValues;
+ if (parseExpression(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();
- SizeLoc = getLexer().getLoc();
- if (parseAbsoluteExpression(FillSize))
+ if (parseToken(AsmToken::Comma, "unexpected token in '.fill' directive") ||
+ getTokenLoc(SizeLoc) || parseAbsoluteExpression(FillSize))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
-
- ExprLoc = getLexer().getLoc();
- if (parseAbsoluteExpression(FillExpr))
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '.fill' directive") ||
+ getTokenLoc(ExprLoc) || parseAbsoluteExpression(FillExpr) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.fill' directive"))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.fill' directive");
-
- Lex();
}
}
if (FillSize < 0) {
Warning(SizeLoc, "'.fill' directive with negative size has no effect");
- NumValues = 0;
+ return false;
}
if (FillSize > 8) {
Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
@@ -2742,15 +2825,7 @@ bool AsmParser::parseDirectiveFill() {
if (!isUInt<32>(FillExpr) && FillSize > 4)
Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
- 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);
- }
- }
+ getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
return false;
}
@@ -2767,18 +2842,15 @@ bool AsmParser::parseDirectiveOrg() {
// Parse optional fill expression.
int64_t FillExpr = 0;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.org' directive");
- Lex();
-
- if (parseAbsoluteExpression(FillExpr))
+ if (parseToken(AsmToken::Comma, "unexpected token in '.org' directive") ||
+ parseAbsoluteExpression(FillExpr))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.org' directive");
}
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.org' directive"))
+ return true;
+
getStreamer().emitValueToOffset(Offset, FillExpr);
return false;
}
@@ -2798,34 +2870,27 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
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();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ 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)) {
+ if (getTok().isNot(AsmToken::Comma)) {
HasFillExpr = true;
if (parseAbsoluteExpression(FillExpr))
return true;
}
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- MaxBytesLoc = getLexer().getLoc();
- if (parseAbsoluteExpression(MaxBytesToFill))
+ if (getTok().isNot(AsmToken::EndOfStatement)) {
+ if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ getTokenLoc(MaxBytesLoc) || parseAbsoluteExpression(MaxBytesToFill))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
}
}
- Lex();
+ if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
+ return true;
if (!HasFillExpr)
FillExpr = 0;
@@ -2896,43 +2961,41 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
return TokError("file number less than one");
}
- if (getLexer().isNot(AsmToken::String))
- return TokError("unexpected token in '.file' directive");
+ std::string Path = getTok().getString();
// Usually the directory and filename together, otherwise just the directory.
// Allow the strings to have escaped octal character sequence.
- std::string Path = getTok().getString();
- if (parseEscapedString(Path))
+ if (check(getTok().isNot(AsmToken::String),
+ "unexpected token in '.file' directive") ||
+ parseEscapedString(Path))
return true;
- Lex();
StringRef Directory;
StringRef Filename;
std::string FilenameData;
if (getLexer().is(AsmToken::String)) {
- if (FileNumber == -1)
- return TokError("explicit path specified, but no file number");
- if (parseEscapedString(FilenameData))
+ if (check(FileNumber == -1,
+ "explicit path specified, but no file number") ||
+ parseEscapedString(FilenameData))
return true;
Filename = FilenameData;
Directory = Path;
- Lex();
} else {
Filename = Path;
}
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.file' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.file' directive"))
+ return true;
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())
- 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) ==
+ getContext().setGenDwarfForAssembly(false);
+ else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
0)
Error(FileNumberLoc, "file number already allocated");
}
@@ -2943,19 +3006,16 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
/// parseDirectiveLine
/// ::= .line [number]
bool AsmParser::parseDirectiveLine() {
+ int64_t LineNumber;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Integer))
- return TokError("unexpected token in '.line' directive");
-
- int64_t LineNumber = getTok().getIntVal();
+ if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
+ return true;
(void)LineNumber;
- Lex();
-
// FIXME: Do something with the .line.
}
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.line' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.line' directive"))
+ return true;
return false;
}
@@ -2968,16 +3028,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() {
- 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();
+ 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;
- int64_t LineNumber = 0;
+ // optional
if (getLexer().is(AsmToken::Integer)) {
LineNumber = getTok().getIntVal();
if (LineNumber < 0)
@@ -3054,6 +3114,7 @@ bool AsmParser::parseDirectiveLoc() {
break;
}
}
+ Lex();
getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
Isa, Discriminator, StringRef());
@@ -3067,6 +3128,231 @@ 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") ||
+ check(getStreamer().EmitCVFileDirective(FileNumber, Filename) == 0,
+ FileNumberLoc, "file number already allocated"))
+ return true;
+
+ 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 Loc;
+ int64_t FunctionId, FileNumber;
+ if (getTokenLoc(Loc) ||
+ parseIntToken(FunctionId, "unexpected token in '.cv_loc' directive") ||
+ check(FunctionId < 0, Loc,
+ "function id less than zero in '.cv_loc' directive") ||
+ getTokenLoc(Loc) ||
+ parseIntToken(FileNumber, "expected integer in '.cv_loc' directive") ||
+ check(FileNumber < 1, Loc,
+ "file number less than one in '.cv_loc' directive") ||
+ check(!getContext().isValidCVFileNumber(FileNumber), Loc,
+ "unassigned file number in '.cv_loc' directive"))
+ 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;
+ while (getLexer().isNot(AsmToken::EndOfStatement)) {
+ 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");
+ }
+ }
+ Lex();
+
+ getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
+ ColumnPos, PrologueEnd, IsStmt, StringRef());
+ return false;
+}
+
+/// parseDirectiveCVLinetable
+/// ::= .cv_linetable FunctionId, FnStart, FnEnd
+bool AsmParser::parseDirectiveCVLinetable() {
+ int64_t FunctionId;
+ StringRef FnStartName, FnEndName;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIntToken(FunctionId,
+ "expected Integer in '.cv_linetable' directive") ||
+ check(FunctionId < 0, Loc,
+ "function id less than zero in '.cv_linetable' directive") ||
+ parseToken(AsmToken::Comma,
+ "unexpected token in '.cv_linetable' directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
+ "expected identifier in directive") ||
+ parseToken(AsmToken::Comma,
+ "unexpected token in '.cv_linetable' directive") ||
+ getTokenLoc(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
+/// ("contains" SecondaryFunctionId+)?
+bool AsmParser::parseDirectiveCVInlineLinetable() {
+ int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
+ StringRef FnStartName, FnEndName;
+ SMLoc Loc = getTok().getLoc();
+ if (parseIntToken(
+ PrimaryFunctionId,
+ "expected PrimaryFunctionId in '.cv_inline_linetable' directive") ||
+ check(PrimaryFunctionId < 0, Loc,
+ "function id less than zero in '.cv_inline_linetable' directive") ||
+ getTokenLoc(Loc) ||
+ parseIntToken(
+ SourceFileId,
+ "expected SourceField in '.cv_inline_linetable' directive") ||
+ check(SourceFileId <= 0, Loc,
+ "File id less than zero in '.cv_inline_linetable' directive") ||
+ getTokenLoc(Loc) ||
+ parseIntToken(
+ SourceLineNum,
+ "expected SourceLineNum in '.cv_inline_linetable' directive") ||
+ check(SourceLineNum < 0, Loc,
+ "Line number less than zero in '.cv_inline_linetable' directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
+ "expected identifier in directive") ||
+ getTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
+ "expected identifier in directive"))
+ return true;
+
+ SmallVector<unsigned, 8> SecondaryFunctionIds;
+ if (getLexer().is(AsmToken::Identifier)) {
+ if (getTok().getIdentifier() != "contains")
+ return TokError(
+ "unexpected identifier in '.cv_inline_linetable' directive");
+ Lex();
+
+ while (getLexer().isNot(AsmToken::EndOfStatement)) {
+ int64_t SecondaryFunctionId = getTok().getIntVal();
+ if (SecondaryFunctionId < 0)
+ return TokError(
+ "function id less than zero in '.cv_inline_linetable' directive");
+ Lex();
+
+ SecondaryFunctionIds.push_back(SecondaryFunctionId);
+ }
+ }
+
+ 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, SecondaryFunctionIds);
+ 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() {
@@ -3106,6 +3392,9 @@ bool AsmParser::parseDirectiveCFIStartProc() {
if (parseIdentifier(Simple) || Simple != "simple")
return TokError("unexpected token in .cfi_startproc directive");
+ if (parseToken(AsmToken::EndOfStatement, "Expected end of statement"))
+ return true;
+
getStreamer().EmitCFIStartProc(!Simple.empty());
return false;
}
@@ -3135,16 +3424,10 @@ bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
/// parseDirectiveCFIDefCfa
/// ::= .cfi_def_cfa register, offset
bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
- 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))
+ int64_t Register = 0, Offset = 0;
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfa(Register, Offset);
@@ -3165,16 +3448,10 @@ bool AsmParser::parseDirectiveCFIDefCfaOffset() {
/// parseDirectiveCFIRegister
/// ::= .cfi_register register, register
bool AsmParser::parseDirectiveCFIRegister(SMLoc 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))
+ int64_t Register1 = 0, Register2 = 0;
+ if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
return true;
getStreamer().EmitCFIRegister(Register1, Register2);
@@ -3216,14 +3493,9 @@ bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
int64_t Offset = 0;
- if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
- return true;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- if (parseAbsoluteExpression(Offset))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIOffset(Register, Offset);
@@ -3233,17 +3505,11 @@ bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
/// parseDirectiveCFIRelOffset
/// ::= .cfi_rel_offset register, offset
bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
- int64_t Register = 0;
+ int64_t Register = 0, Offset = 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))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIRelOffset(Register, Offset);
@@ -3283,16 +3549,11 @@ 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 (parseIdentifier(Name))
- return TokError("expected identifier in directive");
+ if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
+ parseToken(AsmToken::Comma, "unexpected token in directive") ||
+ check(parseIdentifier(Name), "expected identifier in directive"))
+ return true;
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
@@ -3366,9 +3627,9 @@ bool AsmParser::parseDirectiveCFIEscape() {
/// parseDirectiveCFISignalFrame
/// ::= .cfi_signal_frame
bool AsmParser::parseDirectiveCFISignalFrame() {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getLoc(),
- "unexpected token in '.cfi_signal_frame'");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.cfi_signal_frame'"))
+ return true;
getStreamer().EmitCFISignalFrame();
return false;
@@ -3390,9 +3651,9 @@ bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
/// ::= .macros_on
/// ::= .macros_off
bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getLoc(),
- "unexpected token in '" + Directive + "' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Directive + "' directive"))
+ return true;
setMacrosEnabled(Directive == ".macros_on");
return false;
@@ -3460,14 +3721,19 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
Lex();
}
- // Eat the end of statement.
- Lex();
+ // Eat just the end of statement.
+ Lexer.Lex();
+ // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
AsmToken EndToken, StartToken = getTok();
unsigned MacroDepth = 0;
-
// Lex the macro definition.
for (;;) {
+ // Ignore Lexing errors in macros.
+ while (Lexer.is(AsmToken::Error)) {
+ Lexer.Lex();
+ }
+
// Check whether we have reached the end of the file.
if (getLexer().is(AsmToken::Eof))
return Error(DirectiveLoc, "no matching '.endmacro' in definition");
@@ -3478,7 +3744,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
getTok().getIdentifier() == ".endmacro") {
if (MacroDepth == 0) { // Outermost macro.
EndToken = getTok();
- Lex();
+ Lexer.Lex();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + EndToken.getIdentifier() +
"' directive");
@@ -3615,8 +3881,9 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
/// parseDirectiveExitMacro
/// ::= .exitm
bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + Directive + "' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Directive + "' directive"))
+ return true;
if (!isInsideMacroInstantiation())
return TokError("unexpected '" + Directive + "' in file, "
@@ -3656,14 +3923,14 @@ bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
/// ::= .purgem
bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
- 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");
+ SMLoc Loc;
+ if (getTokenLoc(Loc) || check(parseIdentifier(Name), Loc,
+ "expected identifier in '.purgem' directive") ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.purgem' directive") ||
+ check(!lookupMacro(Name), DirectiveLoc,
+ "macro '" + Name + "' is not defined"))
+ return true;
undefineMacro(Name);
return false;
@@ -3678,16 +3945,13 @@ bool AsmParser::parseDirectiveBundleAlignMode() {
// in the inclusive range 0-30.
SMLoc ExprLoc = getLexer().getLoc();
int64_t AlignSizePow2;
- if (parseAbsoluteExpression(AlignSizePow2))
+ if (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)"))
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.
@@ -3707,14 +3971,11 @@ bool AsmParser::parseDirectiveBundleLock() {
const char *kInvalidOptionError =
"invalid option for '.bundle_lock' directive";
- if (parseIdentifier(Option))
- return Error(Loc, kInvalidOptionError);
-
- 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");
+ if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
+ check(Option != "align_to_end", Loc, kInvalidOptionError) ||
+ check(getTok().isNot(AsmToken::EndOfStatement), Loc,
+ "unexpected token after '.bundle_lock' directive option"))
+ return true;
AlignToEnd = true;
}
@@ -3729,9 +3990,9 @@ bool AsmParser::parseDirectiveBundleLock() {
bool AsmParser::parseDirectiveBundleUnlock() {
checkForValidSection();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.bundle_unlock' directive");
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.bundle_unlock' directive"))
+ return true;
getStreamer().EmitBundleUnlock();
return false;
@@ -3742,31 +4003,26 @@ bool AsmParser::parseDirectiveBundleUnlock() {
bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
checkForValidSection();
- int64_t NumBytes;
- if (parseAbsoluteExpression(NumBytes))
+ SMLoc NumBytesLoc = Lexer.getLoc();
+ const MCExpr *NumBytes;
+ if (parseExpression(NumBytes))
return true;
int64_t FillExpr = 0;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
- Lex();
- if (parseAbsoluteExpression(FillExpr))
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '" + Twine(IDVal) + "' directive") ||
+ parseAbsoluteExpression(FillExpr))
return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
}
- Lex();
-
- if (NumBytes <= 0)
- return TokError("invalid number of bytes in '" + Twine(IDVal) +
- "' directive");
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().EmitFill(NumBytes, FillExpr);
+ getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
return false;
}
@@ -3789,10 +4045,10 @@ bool AsmParser::parseDirectiveLEB128(bool Signed) {
if (getLexer().is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
+ Lex();
return false;
}
@@ -3820,9 +4076,8 @@ bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
if (getLexer().is(AsmToken::EndOfStatement))
break;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in directive"))
+ return true;
}
}
@@ -3911,10 +4166,9 @@ bool AsmParser::parseDirectiveAbort() {
SMLoc Loc = getLexer().getLoc();
StringRef Str = parseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.abort' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.abort' directive"))
+ return true;
if (Str.empty())
Error(Loc, ".abort detected. Assembly stopping.");
@@ -3928,25 +4182,20 @@ 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;
- 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 + "'");
+ 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 + "'"))
return true;
- }
return false;
}
@@ -3954,25 +4203,18 @@ bool AsmParser::parseDirectiveInclude() {
/// parseDirectiveIncbin
/// ::= .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;
- if (parseEscapedString(Filename))
- return true;
- SMLoc IncbinLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.incbin' directive");
-
- // Attempt to process the included file.
- if (processIncbinFile(Filename)) {
- Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
+ SMLoc IncbinLoc = getTok().getLoc();
+ if (check(getTok().isNot(AsmToken::String),
+ "expected string in '.incbin' directive") ||
+ parseEscapedString(Filename) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.incbin' directive") ||
+ // Attempt to process the included file.
+ check(processIncbinFile(Filename), IncbinLoc,
+ "Could not find incbin file '" + Filename + "'"))
return true;
- }
-
return false;
}
@@ -3985,14 +4227,11 @@ bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
eatToEndOfStatement();
} else {
int64_t ExprValue;
- if (parseAbsoluteExpression(ExprValue))
+ if (parseAbsoluteExpression(ExprValue) ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.if' directive"))
return true;
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.if' directive");
-
- Lex();
-
switch (DirKind) {
default:
llvm_unreachable("unsupported directive");
@@ -4034,10 +4273,9 @@ bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
} else {
StringRef Str = parseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifb' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.ifb' directive"))
+ return true;
TheCondState.CondMet = ExpectBlank == Str.empty();
TheCondState.Ignore = !TheCondState.CondMet;
@@ -4058,17 +4296,14 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
} else {
StringRef Str1 = parseStringToComma();
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
+ if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
+ return true;
StringRef Str2 = parseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.ifc' directive"))
+ return true;
TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
TheCondState.Ignore = !TheCondState.CondMet;
@@ -4133,10 +4368,9 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
if (TheCondState.Ignore) {
eatToEndOfStatement();
} else {
- if (parseIdentifier(Name))
- return TokError("expected identifier after '.ifdef'");
-
- Lex();
+ if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
+ parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
+ return true;
MCSymbol *Sym = getContext().lookupSymbol(Name);
@@ -4184,10 +4418,9 @@ bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
/// parseDirectiveElse
/// ::= .else
bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.else' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.else' directive"))
+ return true;
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
@@ -4208,10 +4441,9 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
/// parseDirectiveEnd
/// ::= .end
bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.end' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.end' directive"))
+ return true;
while (Lexer.isNot(AsmToken::Eof))
Lex();
@@ -4278,10 +4510,9 @@ bool AsmParser::parseDirectiveWarning(SMLoc L) {
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.endif' directive");
-
- Lex();
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.endif' directive"))
+ return true;
if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
@@ -4378,6 +4609,13 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".line"] = DK_LINE;
DirectiveKindMap[".loc"] = DK_LOC;
DirectiveKindMap[".stabs"] = DK_STABS;
+ DirectiveKindMap[".cv_file"] = DK_CV_FILE;
+ DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
+ DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
+ DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
+ 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;
@@ -4425,7 +4663,9 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
}
if (Lexer.is(AsmToken::Identifier) &&
- (getTok().getIdentifier() == ".rept")) {
+ (getTok().getIdentifier() == ".rept" ||
+ getTok().getIdentifier() == ".irp" ||
+ getTok().getIdentifier() == ".irpc")) {
++NestLevel;
}
@@ -4489,14 +4729,10 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
}
- 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();
+ if (check(Count < 0, CountLoc, "Count is negative") ||
+ parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Dir + "' directive"))
+ return true;
// Lex the rept definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
@@ -4521,22 +4757,14 @@ 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 (parseMacroArguments(nullptr, 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"))
return true;
- // Eat the end of statement.
- Lex();
-
// Lex the irp definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
@@ -4563,24 +4791,20 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
/// ::= .irpc symbol,values
bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
MCAsmMacroParameter Parameter;
-
- 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))
+
+ if (check(parseIdentifier(Parameter.Name),
+ "expected identifier in '.irpc' directive") ||
+ parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
+ 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.
- Lex();
+ if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
+ return true;
// Lex the irpc definition.
MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
@@ -4699,6 +4923,10 @@ 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);
if (parseStatement(Info, &SI))
return true;
@@ -4875,6 +5103,9 @@ bool AsmParser::parseMSInlineAsm(
OS << '.';
OS << AR.Val;
break;
+ case AOK_EndOfStatement:
+ OS << "\n\t";
+ break;
}
// Skip the original expression.
@@ -4922,10 +5153,9 @@ 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 = Lexer.getLoc();
+ SMLoc EqualLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(Value)) {
Parser.TokError("missing expression");
@@ -4937,7 +5167,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
// a = b
// b = c
- if (Lexer.isNot(AsmToken::EndOfStatement))
+ if (Parser.getTok().isNot(AsmToken::EndOfStatement))
return Parser.TokError("unexpected token in assignment");
// Eat the end of statement marker.
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index a4b2b195f7100..653627ad8dca8 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -15,10 +15,10 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/COFF.h"
using namespace llvm;
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 73e068a343911..37515d9c074d4 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -50,6 +50,7 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
+ addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
".indirect_symbol");
@@ -111,6 +112,9 @@ public:
addDirectiveHandler<
&DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
".non_lazy_symbol_pointer");
+ addDirectiveHandler<
+ &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
+ ".thread_local_variable_pointer");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
".objc_cat_cls_meth");
addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
@@ -179,6 +183,7 @@ public:
LastVersionMinDirective = SMLoc();
}
+ bool parseDirectiveAltEntry(StringRef, SMLoc);
bool parseDirectiveDesc(StringRef, SMLoc);
bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
@@ -261,6 +266,10 @@ public:
return parseSectionSwitch("__DATA", "__la_symbol_ptr",
MachO::S_LAZY_SYMBOL_POINTERS, 4);
}
+ bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
+ return parseSectionSwitch("__DATA", "__thread_ptr",
+ MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
+ }
bool parseSectionDirectiveDyld(StringRef, SMLoc) {
return parseSectionSwitch("__DATA", "__dyld");
}
@@ -408,6 +417,26 @@ bool DarwinAsmParser::parseSectionSwitch(const char *Segment,
return false;
}
+/// parseDirectiveAltEntry
+/// ::= .alt_entry identifier
+bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {
+ StringRef Name;
+ if (getParser().parseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Look up symbol.
+ MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
+
+ if (Sym->isDefined())
+ return TokError(".alt_entry must preceed symbol definition");
+
+ if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_AltEntry))
+ return TokError("unable to emit symbol attribute");
+
+ Lex();
+ return false;
+}
+
/// parseDirectiveDesc
/// ::= .desc identifier , expression
bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
@@ -445,6 +474,7 @@ bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
MachO::SectionType SectionType = Current->getType();
if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
+ SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
SectionType != MachO::S_SYMBOL_STUBS)
return Error(Loc, "indirect symbol not in a symbol pointer or stub "
"section");
@@ -507,7 +537,6 @@ bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
Args.push_back(Data);
- Lex();
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -929,8 +958,8 @@ bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) {
if (getLexer().isNot(AsmToken::Integer))
return TokError("invalid OS update number");
Update = getLexer().getTok().getIntVal();
- if (Update > 255 || Update < 0)
- return TokError("invalid OS update number");
+ if (Update > 255 || Update < 0)
+ return TokError("invalid OS update number");
Lex();
}
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index 6cbcdec5e275f..47d19a824d196 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -188,6 +188,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
if (getParser().parseExpression(Subsection))
return true;
}
+ Lex();
getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
Subsection);
@@ -211,6 +212,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
+ Lex();
getStreamer().emitELFSize(Sym, Expr);
return false;
@@ -229,22 +231,23 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
}
for (;;) {
- unsigned CurSize;
-
+
SMLoc PrevLoc = getLexer().getLoc();
- if (getLexer().is(AsmToken::Minus)) {
- CurSize = 1;
- Lex(); // Consume the "-".
- } else if (getLexer().is(AsmToken::String)) {
+ if (getLexer().is(AsmToken::Comma) ||
+ getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ unsigned CurSize;
+ if (getLexer().is(AsmToken::String)) {
CurSize = getTok().getIdentifier().size() + 2;
Lex();
} else if (getLexer().is(AsmToken::Identifier)) {
CurSize = getTok().getIdentifier().size();
Lex();
} else {
- break;
+ CurSize = getTok().getString().size();
+ Lex();
}
-
Size += CurSize;
SectionName = StringRef(FirstLoc.getPointer(), Size);
@@ -261,8 +264,8 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
unsigned flags = 0;
- for (unsigned i = 0; i < flagsStr.size(); i++) {
- switch (flagsStr[i]) {
+ for (char i : flagsStr) {
+ switch (i) {
case 'a':
flags |= ELF::SHF_ALLOC;
break;
@@ -476,6 +479,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
EndStmt:
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
+ Lex();
unsigned Type = ELF::SHT_PROGBITS;
@@ -627,6 +631,10 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ident' directive");
+ Lex();
+
getStreamer().EmitIdent(Data);
return false;
}
@@ -725,6 +733,8 @@ bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
+ Lex();
+
getStreamer().SubSection(Subsection);
return false;
}
diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp
index e891bd2c6240a..d95cd12accbc1 100644
--- a/lib/MC/MCParser/MCAsmLexer.cpp
+++ b/lib/MC/MCParser/MCAsmLexer.cpp
@@ -13,7 +13,7 @@
using namespace llvm;
MCAsmLexer::MCAsmLexer() : TokStart(nullptr), SkipSpace(true) {
- CurTok.emplace_back(AsmToken::Error, StringRef());
+ CurTok.emplace_back(AsmToken::Space, StringRef());
}
MCAsmLexer::~MCAsmLexer() {
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
index 290dcb2977428..dc7a3f00840f8 100644
--- a/lib/MC/MCParser/MCAsmParser.cpp
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -11,7 +11,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
-#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
@@ -43,7 +43,7 @@ bool MCAsmParser::parseExpression(const MCExpr *&Res) {
return parseExpression(Res, L);
}
-void MCParsedAsmOperand::dump() const {
+LLVM_DUMP_METHOD void MCParsedAsmOperand::dump() const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dbgs() << " " << *this;
#endif
diff --git a/lib/MC/MCParser/MCTargetAsmParser.cpp b/lib/MC/MCParser/MCTargetAsmParser.cpp
index 4e4b47805cd8e..14a22c6b8a2fc 100644
--- a/lib/MC/MCParser/MCTargetAsmParser.cpp
+++ b/lib/MC/MCParser/MCTargetAsmParser.cpp
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCTargetAsmParser.h"
using namespace llvm;
MCTargetAsmParser::MCTargetAsmParser(MCTargetOptions const &MCOptions,
diff --git a/lib/MC/MCParser/Makefile b/lib/MC/MCParser/Makefile
deleted file mode 100644
index 4477757657c7f..0000000000000
--- a/lib/MC/MCParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/MC/MCParser/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMCParser
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
-