1//===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This class implements the parser for assembly files.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/ADT/APFloat.h"
14#include "llvm/ADT/APInt.h"
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/None.h"
17#include "llvm/ADT/Optional.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallString.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/StringExtras.h"
22#include "llvm/ADT/StringMap.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/ADT/Twine.h"
26#include "llvm/BinaryFormat/Dwarf.h"
27#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
28#include "llvm/MC/MCAsmInfo.h"
29#include "llvm/MC/MCCodeView.h"
30#include "llvm/MC/MCContext.h"
31#include "llvm/MC/MCDirectives.h"
32#include "llvm/MC/MCDwarf.h"
33#include "llvm/MC/MCExpr.h"
34#include "llvm/MC/MCInstPrinter.h"
35#include "llvm/MC/MCInstrDesc.h"
36#include "llvm/MC/MCInstrInfo.h"
37#include "llvm/MC/MCObjectFileInfo.h"
38#include "llvm/MC/MCParser/AsmCond.h"
39#include "llvm/MC/MCParser/AsmLexer.h"
40#include "llvm/MC/MCParser/MCAsmLexer.h"
41#include "llvm/MC/MCParser/MCAsmParser.h"
42#include "llvm/MC/MCParser/MCAsmParserExtension.h"
43#include "llvm/MC/MCParser/MCAsmParserUtils.h"
44#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
45#include "llvm/MC/MCParser/MCTargetAsmParser.h"
46#include "llvm/MC/MCRegisterInfo.h"
47#include "llvm/MC/MCSection.h"
48#include "llvm/MC/MCStreamer.h"
49#include "llvm/MC/MCSymbol.h"
50#include "llvm/MC/MCTargetOptions.h"
51#include "llvm/MC/MCValue.h"
52#include "llvm/Support/Casting.h"
53#include "llvm/Support/CommandLine.h"
54#include "llvm/Support/ErrorHandling.h"
55#include "llvm/Support/Format.h"
56#include "llvm/Support/MD5.h"
57#include "llvm/Support/MathExtras.h"
58#include "llvm/Support/MemoryBuffer.h"
59#include "llvm/Support/SMLoc.h"
60#include "llvm/Support/SourceMgr.h"
61#include "llvm/Support/raw_ostream.h"
62#include <algorithm>
63#include <cassert>
64#include <cctype>
65#include <climits>
66#include <cstddef>
67#include <cstdint>
68#include <deque>
69#include <memory>
70#include <sstream>
71#include <string>
72#include <tuple>
73#include <utility>
74#include <vector>
75
76using namespace llvm;
77
78extern cl::opt<unsigned> AsmMacroMaxNestingDepth;
79
80namespace {
81
82/// Helper types for tracking macro definitions.
83typedef std::vector<AsmToken> MCAsmMacroArgument;
84typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
85
86/// Helper class for storing information about an active macro instantiation.
87struct MacroInstantiation {
88  /// The location of the instantiation.
89  SMLoc InstantiationLoc;
90
91  /// The buffer where parsing should resume upon instantiation completion.
92  unsigned ExitBuffer;
93
94  /// The location where parsing should resume upon instantiation completion.
95  SMLoc ExitLoc;
96
97  /// The depth of TheCondStack at the start of the instantiation.
98  size_t CondStackDepth;
99};
100
101struct ParseStatementInfo {
102  /// The parsed operands from the last parsed statement.
103  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
104
105  /// The opcode from the last parsed instruction.
106  unsigned Opcode = ~0U;
107
108  /// Was there an error parsing the inline assembly?
109  bool ParseError = false;
110
111  /// The value associated with a macro exit.
112  Optional<std::string> ExitValue;
113
114  SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
115
116  ParseStatementInfo() = delete;
117  ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
118      : AsmRewrites(rewrites) {}
119};
120
121enum FieldType {
122  FT_INTEGRAL, // Initializer: integer expression, stored as an MCExpr.
123  FT_REAL,     // Initializer: real number, stored as an APInt.
124  FT_STRUCT    // Initializer: struct initializer, stored recursively.
125};
126
127struct FieldInfo;
128struct StructInfo {
129  StringRef Name;
130  bool IsUnion = false;
131  unsigned Alignment = 0;
132  unsigned Size = 0;
133  unsigned AlignmentSize = 0;
134  std::vector<FieldInfo> Fields;
135  StringMap<size_t> FieldsByName;
136
137  FieldInfo &addField(StringRef FieldName, FieldType FT,
138                      unsigned FieldAlignmentSize);
139
140  StructInfo() = default;
141
142  StructInfo(StringRef StructName, bool Union, unsigned AlignmentValue)
143      : Name(StructName), IsUnion(Union), Alignment(AlignmentValue) {}
144};
145
146// FIXME: This should probably use a class hierarchy, raw pointers between the
147// objects, and dynamic type resolution instead of a union. On the other hand,
148// ownership then becomes much more complicated; the obvious thing would be to
149// use BumpPtrAllocator, but the lack of a destructor makes that messy.
150
151struct StructInitializer;
152struct IntFieldInfo {
153  SmallVector<const MCExpr *, 1> Values;
154
155  IntFieldInfo() = default;
156  IntFieldInfo(const SmallVector<const MCExpr *, 1> &V) { Values = V; }
157  IntFieldInfo(SmallVector<const MCExpr *, 1> &&V) { Values = V; }
158};
159struct RealFieldInfo {
160  SmallVector<APInt, 1> AsIntValues;
161
162  RealFieldInfo() = default;
163  RealFieldInfo(const SmallVector<APInt, 1> &V) { AsIntValues = V; }
164  RealFieldInfo(SmallVector<APInt, 1> &&V) { AsIntValues = V; }
165};
166struct StructFieldInfo {
167  std::vector<StructInitializer> Initializers;
168  StructInfo Structure;
169
170  StructFieldInfo() = default;
171  StructFieldInfo(const std::vector<StructInitializer> &V, StructInfo S) {
172    Initializers = V;
173    Structure = S;
174  }
175  StructFieldInfo(std::vector<StructInitializer> &&V, StructInfo S) {
176    Initializers = V;
177    Structure = S;
178  }
179};
180
181class FieldInitializer {
182public:
183  FieldType FT;
184  union {
185    IntFieldInfo IntInfo;
186    RealFieldInfo RealInfo;
187    StructFieldInfo StructInfo;
188  };
189
190  ~FieldInitializer() {
191    switch (FT) {
192    case FT_INTEGRAL:
193      IntInfo.~IntFieldInfo();
194      break;
195    case FT_REAL:
196      RealInfo.~RealFieldInfo();
197      break;
198    case FT_STRUCT:
199      StructInfo.~StructFieldInfo();
200      break;
201    }
202  }
203
204  FieldInitializer(FieldType FT) : FT(FT) {
205    switch (FT) {
206    case FT_INTEGRAL:
207      new (&IntInfo) IntFieldInfo();
208      break;
209    case FT_REAL:
210      new (&RealInfo) RealFieldInfo();
211      break;
212    case FT_STRUCT:
213      new (&StructInfo) StructFieldInfo();
214      break;
215    }
216  }
217
218  FieldInitializer(SmallVector<const MCExpr *, 1> &&Values) : FT(FT_INTEGRAL) {
219    new (&IntInfo) IntFieldInfo(Values);
220  }
221
222  FieldInitializer(SmallVector<APInt, 1> &&AsIntValues) : FT(FT_REAL) {
223    new (&RealInfo) RealFieldInfo(AsIntValues);
224  }
225
226  FieldInitializer(std::vector<StructInitializer> &&Initializers,
227                   struct StructInfo Structure)
228      : FT(FT_STRUCT) {
229    new (&StructInfo) StructFieldInfo(Initializers, Structure);
230  }
231
232  FieldInitializer(const FieldInitializer &Initializer) : FT(Initializer.FT) {
233    switch (FT) {
234    case FT_INTEGRAL:
235      new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
236      break;
237    case FT_REAL:
238      new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
239      break;
240    case FT_STRUCT:
241      new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
242      break;
243    }
244  }
245
246  FieldInitializer(FieldInitializer &&Initializer) : FT(Initializer.FT) {
247    switch (FT) {
248    case FT_INTEGRAL:
249      new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
250      break;
251    case FT_REAL:
252      new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
253      break;
254    case FT_STRUCT:
255      new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
256      break;
257    }
258  }
259
260  FieldInitializer &operator=(const FieldInitializer &Initializer) {
261    if (FT != Initializer.FT) {
262      switch (FT) {
263      case FT_INTEGRAL:
264        IntInfo.~IntFieldInfo();
265        break;
266      case FT_REAL:
267        RealInfo.~RealFieldInfo();
268        break;
269      case FT_STRUCT:
270        StructInfo.~StructFieldInfo();
271        break;
272      }
273    }
274    FT = Initializer.FT;
275    switch (FT) {
276    case FT_INTEGRAL:
277      IntInfo = Initializer.IntInfo;
278      break;
279    case FT_REAL:
280      RealInfo = Initializer.RealInfo;
281      break;
282    case FT_STRUCT:
283      StructInfo = Initializer.StructInfo;
284      break;
285    }
286    return *this;
287  }
288
289  FieldInitializer &operator=(FieldInitializer &&Initializer) {
290    if (FT != Initializer.FT) {
291      switch (FT) {
292      case FT_INTEGRAL:
293        IntInfo.~IntFieldInfo();
294        break;
295      case FT_REAL:
296        RealInfo.~RealFieldInfo();
297        break;
298      case FT_STRUCT:
299        StructInfo.~StructFieldInfo();
300        break;
301      }
302    }
303    FT = Initializer.FT;
304    switch (FT) {
305    case FT_INTEGRAL:
306      IntInfo = Initializer.IntInfo;
307      break;
308    case FT_REAL:
309      RealInfo = Initializer.RealInfo;
310      break;
311    case FT_STRUCT:
312      StructInfo = Initializer.StructInfo;
313      break;
314    }
315    return *this;
316  }
317};
318
319struct StructInitializer {
320  std::vector<FieldInitializer> FieldInitializers;
321};
322
323struct FieldInfo {
324  // Offset of the field within the containing STRUCT.
325  size_t Offset = 0;
326
327  // Total size of the field (= LengthOf * Type).
328  unsigned SizeOf = 0;
329
330  // Number of elements in the field (1 if scalar, >1 if an array).
331  unsigned LengthOf = 0;
332
333  // Size of a single entry in this field, in bytes ("type" in MASM standards).
334  unsigned Type = 0;
335
336  FieldInitializer Contents;
337
338  FieldInfo(FieldType FT) : Contents(FT) {}
339};
340
341FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT,
342                                unsigned FieldAlignmentSize) {
343  if (!FieldName.empty())
344    FieldsByName[FieldName.lower()] = Fields.size();
345  Fields.emplace_back(FT);
346  FieldInfo &Field = Fields.back();
347  if (IsUnion) {
348    Field.Offset = 0;
349  } else {
350    Size = llvm::alignTo(Size, std::min(Alignment, FieldAlignmentSize));
351    Field.Offset = Size;
352  }
353  AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
354  return Field;
355}
356
357/// The concrete assembly parser instance.
358// Note that this is a full MCAsmParser, not an MCAsmParserExtension!
359// It's a peer of AsmParser, not of COFFAsmParser, WasmAsmParser, etc.
360class MasmParser : public MCAsmParser {
361private:
362  AsmLexer Lexer;
363  MCContext &Ctx;
364  MCStreamer &Out;
365  const MCAsmInfo &MAI;
366  SourceMgr &SrcMgr;
367  SourceMgr::DiagHandlerTy SavedDiagHandler;
368  void *SavedDiagContext;
369  std::unique_ptr<MCAsmParserExtension> PlatformParser;
370
371  /// This is the current buffer index we're lexing from as managed by the
372  /// SourceMgr object.
373  unsigned CurBuffer;
374  std::vector<bool> EndStatementAtEOFStack;
375
376  AsmCond TheCondState;
377  std::vector<AsmCond> TheCondStack;
378
379  /// maps directive names to handler methods in parser
380  /// extensions. Extensions register themselves in this map by calling
381  /// addDirectiveHandler.
382  StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
383
384  /// maps assembly-time variable names to variables.
385  struct Variable {
386    StringRef Name;
387    bool Redefinable = true;
388    bool IsText = false;
389    int64_t NumericValue = 0;
390    std::string TextValue;
391  };
392  StringMap<Variable> Variables;
393
394  /// Stack of active struct definitions.
395  SmallVector<StructInfo, 1> StructInProgress;
396
397  /// Maps struct tags to struct definitions.
398  StringMap<StructInfo> Structs;
399
400  /// Maps data location names to types.
401  StringMap<AsmTypeInfo> KnownType;
402
403  /// Stack of active macro instantiations.
404  std::vector<MacroInstantiation*> ActiveMacros;
405
406  /// List of bodies of anonymous macros.
407  std::deque<MCAsmMacro> MacroLikeBodies;
408
409  /// Keeps track of how many .macro's have been instantiated.
410  unsigned NumOfMacroInstantiations;
411
412  /// The values from the last parsed cpp hash file line comment if any.
413  struct CppHashInfoTy {
414    StringRef Filename;
415    int64_t LineNumber;
416    SMLoc Loc;
417    unsigned Buf;
418    CppHashInfoTy() : Filename(), LineNumber(0), Loc(), Buf(0) {}
419  };
420  CppHashInfoTy CppHashInfo;
421
422  /// The filename from the first cpp hash file line comment, if any.
423  StringRef FirstCppHashFilename;
424
425  /// List of forward directional labels for diagnosis at the end.
426  SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
427
428  /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
429  /// Defaults to 1U, meaning Intel.
430  unsigned AssemblerDialect = 1U;
431
432  /// is Darwin compatibility enabled?
433  bool IsDarwin = false;
434
435  /// Are we parsing ms-style inline assembly?
436  bool ParsingMSInlineAsm = false;
437
438  /// Did we already inform the user about inconsistent MD5 usage?
439  bool ReportedInconsistentMD5 = false;
440
441  // Current <...> expression depth.
442  unsigned AngleBracketDepth = 0U;
443
444  // Number of locals defined.
445  uint16_t LocalCounter = 0;
446
447public:
448  MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
449             const MCAsmInfo &MAI, unsigned CB);
450  MasmParser(const MasmParser &) = delete;
451  MasmParser &operator=(const MasmParser &) = delete;
452  ~MasmParser() override;
453
454  bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
455
456  void addDirectiveHandler(StringRef Directive,
457                           ExtensionDirectiveHandler Handler) override {
458    ExtensionDirectiveMap[Directive] = Handler;
459    if (DirectiveKindMap.find(Directive) == DirectiveKindMap.end()) {
460      DirectiveKindMap[Directive] = DK_HANDLER_DIRECTIVE;
461    }
462  }
463
464  void addAliasForDirective(StringRef Directive, StringRef Alias) override {
465    DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
466  }
467
468  /// @name MCAsmParser Interface
469  /// {
470
471  SourceMgr &getSourceManager() override { return SrcMgr; }
472  MCAsmLexer &getLexer() override { return Lexer; }
473  MCContext &getContext() override { return Ctx; }
474  MCStreamer &getStreamer() override { return Out; }
475
476  CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
477
478  unsigned getAssemblerDialect() override {
479    if (AssemblerDialect == ~0U)
480      return MAI.getAssemblerDialect();
481    else
482      return AssemblerDialect;
483  }
484  void setAssemblerDialect(unsigned i) override {
485    AssemblerDialect = i;
486  }
487
488  void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override;
489  bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override;
490  bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override;
491
492  const AsmToken &Lex() override;
493
494  void setParsingMSInlineAsm(bool V) override {
495    ParsingMSInlineAsm = V;
496    // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and
497    // hex integer literals.
498    Lexer.setLexMasmIntegers(V);
499  }
500  bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
501
502  bool isParsingMasm() const override { return true; }
503
504  bool defineMacro(StringRef Name, StringRef Value) override;
505
506  bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override;
507  bool lookUpField(StringRef Base, StringRef Member,
508                   AsmFieldInfo &Info) const override;
509
510  bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override;
511
512  bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
513                        unsigned &NumOutputs, unsigned &NumInputs,
514                        SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
515                        SmallVectorImpl<std::string> &Constraints,
516                        SmallVectorImpl<std::string> &Clobbers,
517                        const MCInstrInfo *MII, const MCInstPrinter *IP,
518                        MCAsmParserSemaCallback &SI) override;
519
520  bool parseExpression(const MCExpr *&Res);
521  bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
522  bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
523                        AsmTypeInfo *TypeInfo) override;
524  bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
525  bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
526                             SMLoc &EndLoc) override;
527  bool parseAbsoluteExpression(int64_t &Res) override;
528
529  /// Parse a floating point expression using the float \p Semantics
530  /// and set \p Res to the value.
531  bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
532
533  /// Parse an identifier or string (as a quoted identifier)
534  /// and set \p Res to the identifier contents.
535  bool parseIdentifier(StringRef &Res) override;
536  void eatToEndOfStatement() override;
537
538  bool checkForValidSection() override;
539
540  /// }
541
542private:
543  bool parseStatement(ParseStatementInfo &Info,
544                      MCAsmParserSemaCallback *SI);
545  bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
546  bool parseCppHashLineFilenameComment(SMLoc L);
547
548  bool expandMacro(raw_svector_ostream &OS, StringRef Body,
549                   ArrayRef<MCAsmMacroParameter> Parameters,
550                   ArrayRef<MCAsmMacroArgument> A,
551                   const std::vector<std::string> &Locals, SMLoc L);
552
553  /// Are we inside a macro instantiation?
554  bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
555
556  /// Handle entry to macro instantiation.
557  ///
558  /// \param M The macro.
559  /// \param NameLoc Instantiation location.
560  bool handleMacroEntry(
561      const MCAsmMacro *M, SMLoc NameLoc,
562      AsmToken::TokenKind ArgumentEndTok = AsmToken::EndOfStatement);
563
564  /// Handle invocation of macro function.
565  ///
566  /// \param M The macro.
567  /// \param NameLoc Invocation location.
568  bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc);
569
570  /// Handle exit from macro instantiation.
571  void handleMacroExit();
572
573  /// Extract AsmTokens for a macro argument.
574  bool
575  parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA,
576                     AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
577
578  /// Parse all macro arguments for a given macro.
579  bool
580  parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A,
581                      AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
582
583  void printMacroInstantiations();
584
585  bool expandStatement(SMLoc Loc);
586
587  void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
588                    SMRange Range = None) const {
589    ArrayRef<SMRange> Ranges(Range);
590    SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
591  }
592  static void DiagHandler(const SMDiagnostic &Diag, void *Context);
593
594  bool lookUpField(const StructInfo &Structure, StringRef Member,
595                   AsmFieldInfo &Info) const;
596
597  /// Should we emit DWARF describing this assembler source?  (Returns false if
598  /// the source has .file directives, which means we don't want to generate
599  /// info describing the assembler source itself.)
600  bool enabledGenDwarfForAssembly();
601
602  /// Enter the specified file. This returns true on failure.
603  bool enterIncludeFile(const std::string &Filename);
604
605  /// Reset the current lexer position to that given by \p Loc. The
606  /// current token is not set; clients should ensure Lex() is called
607  /// subsequently.
608  ///
609  /// \param InBuffer If not 0, should be the known buffer id that contains the
610  /// location.
611  void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0,
612                 bool EndStatementAtEOF = true);
613
614  /// Parse up to a token of kind \p EndTok and return the contents from the
615  /// current token up to (but not including) this token; the current token on
616  /// exit will be either this kind or EOF. Reads through instantiated macro
617  /// functions and text macros.
618  SmallVector<StringRef, 1> parseStringRefsTo(AsmToken::TokenKind EndTok);
619  std::string parseStringTo(AsmToken::TokenKind EndTok);
620
621  /// Parse up to the end of statement and return the contents from the current
622  /// token until the end of the statement; the current token on exit will be
623  /// either the EndOfStatement or EOF.
624  StringRef parseStringToEndOfStatement() override;
625
626  bool parseTextItem(std::string &Data);
627
628  unsigned getBinOpPrecedence(AsmToken::TokenKind K,
629                              MCBinaryExpr::Opcode &Kind);
630
631  bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
632  bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
633  bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
634
635  bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
636
637  bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
638  bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
639
640  // Generic (target and platform independent) directive parsing.
641  enum DirectiveKind {
642    DK_NO_DIRECTIVE, // Placeholder
643    DK_HANDLER_DIRECTIVE,
644    DK_ASSIGN,
645    DK_EQU,
646    DK_TEXTEQU,
647    DK_ASCII,
648    DK_ASCIZ,
649    DK_STRING,
650    DK_BYTE,
651    DK_SBYTE,
652    DK_WORD,
653    DK_SWORD,
654    DK_DWORD,
655    DK_SDWORD,
656    DK_FWORD,
657    DK_QWORD,
658    DK_SQWORD,
659    DK_DB,
660    DK_DD,
661    DK_DF,
662    DK_DQ,
663    DK_DW,
664    DK_REAL4,
665    DK_REAL8,
666    DK_REAL10,
667    DK_ALIGN,
668    DK_ORG,
669    DK_ENDR,
670    DK_EXTERN,
671    DK_PUBLIC,
672    DK_COMM,
673    DK_COMMENT,
674    DK_INCLUDE,
675    DK_REPEAT,
676    DK_WHILE,
677    DK_FOR,
678    DK_FORC,
679    DK_IF,
680    DK_IFE,
681    DK_IFB,
682    DK_IFNB,
683    DK_IFDEF,
684    DK_IFNDEF,
685    DK_IFDIF,
686    DK_IFDIFI,
687    DK_IFIDN,
688    DK_IFIDNI,
689    DK_ELSEIF,
690    DK_ELSEIFE,
691    DK_ELSEIFB,
692    DK_ELSEIFNB,
693    DK_ELSEIFDEF,
694    DK_ELSEIFNDEF,
695    DK_ELSEIFDIF,
696    DK_ELSEIFDIFI,
697    DK_ELSEIFIDN,
698    DK_ELSEIFIDNI,
699    DK_ELSE,
700    DK_ENDIF,
701    DK_FILE,
702    DK_LINE,
703    DK_LOC,
704    DK_STABS,
705    DK_CV_FILE,
706    DK_CV_FUNC_ID,
707    DK_CV_INLINE_SITE_ID,
708    DK_CV_LOC,
709    DK_CV_LINETABLE,
710    DK_CV_INLINE_LINETABLE,
711    DK_CV_DEF_RANGE,
712    DK_CV_STRINGTABLE,
713    DK_CV_STRING,
714    DK_CV_FILECHECKSUMS,
715    DK_CV_FILECHECKSUM_OFFSET,
716    DK_CV_FPO_DATA,
717    DK_CFI_SECTIONS,
718    DK_CFI_STARTPROC,
719    DK_CFI_ENDPROC,
720    DK_CFI_DEF_CFA,
721    DK_CFI_DEF_CFA_OFFSET,
722    DK_CFI_ADJUST_CFA_OFFSET,
723    DK_CFI_DEF_CFA_REGISTER,
724    DK_CFI_OFFSET,
725    DK_CFI_REL_OFFSET,
726    DK_CFI_PERSONALITY,
727    DK_CFI_LSDA,
728    DK_CFI_REMEMBER_STATE,
729    DK_CFI_RESTORE_STATE,
730    DK_CFI_SAME_VALUE,
731    DK_CFI_RESTORE,
732    DK_CFI_ESCAPE,
733    DK_CFI_RETURN_COLUMN,
734    DK_CFI_SIGNAL_FRAME,
735    DK_CFI_UNDEFINED,
736    DK_CFI_REGISTER,
737    DK_CFI_WINDOW_SAVE,
738    DK_CFI_B_KEY_FRAME,
739    DK_MACRO,
740    DK_EXITM,
741    DK_ENDM,
742    DK_PURGE,
743    DK_ERR,
744    DK_ERRB,
745    DK_ERRNB,
746    DK_ERRDEF,
747    DK_ERRNDEF,
748    DK_ERRDIF,
749    DK_ERRDIFI,
750    DK_ERRIDN,
751    DK_ERRIDNI,
752    DK_ERRE,
753    DK_ERRNZ,
754    DK_ECHO,
755    DK_STRUCT,
756    DK_UNION,
757    DK_ENDS,
758    DK_END,
759    DK_PUSHFRAME,
760    DK_PUSHREG,
761    DK_SAVEREG,
762    DK_SAVEXMM128,
763    DK_SETFRAME,
764    DK_RADIX,
765  };
766
767  /// Maps directive name --> DirectiveKind enum, for directives parsed by this
768  /// class.
769  StringMap<DirectiveKind> DirectiveKindMap;
770
771  bool isMacroLikeDirective();
772
773  // Codeview def_range type parsing.
774  enum CVDefRangeType {
775    CVDR_DEFRANGE = 0, // Placeholder
776    CVDR_DEFRANGE_REGISTER,
777    CVDR_DEFRANGE_FRAMEPOINTER_REL,
778    CVDR_DEFRANGE_SUBFIELD_REGISTER,
779    CVDR_DEFRANGE_REGISTER_REL
780  };
781
782  /// Maps Codeview def_range types --> CVDefRangeType enum, for Codeview
783  /// def_range types parsed by this class.
784  StringMap<CVDefRangeType> CVDefRangeTypeMap;
785
786  // ".ascii", ".asciz", ".string"
787  bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
788
789  // "byte", "word", ...
790  bool emitIntValue(const MCExpr *Value, unsigned Size);
791  bool parseScalarInitializer(unsigned Size,
792                              SmallVectorImpl<const MCExpr *> &Values,
793                              unsigned StringPadLength = 0);
794  bool parseScalarInstList(
795      unsigned Size, SmallVectorImpl<const MCExpr *> &Values,
796      const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
797  bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr);
798  bool addIntegralField(StringRef Name, unsigned Size);
799  bool parseDirectiveValue(StringRef IDVal, unsigned Size);
800  bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
801                                StringRef Name, SMLoc NameLoc);
802
803  // "real4", "real8", "real10"
804  bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);
805  bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);
806  bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,
807                               size_t Size);
808  bool parseRealInstList(
809      const fltSemantics &Semantics, SmallVectorImpl<APInt> &Values,
810      const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
811  bool parseDirectiveNamedRealValue(StringRef TypeName,
812                                    const fltSemantics &Semantics,
813                                    unsigned Size, StringRef Name,
814                                    SMLoc NameLoc);
815
816  bool parseOptionalAngleBracketOpen();
817  bool parseAngleBracketClose(const Twine &Msg = "expected '>'");
818
819  bool parseFieldInitializer(const FieldInfo &Field,
820                             FieldInitializer &Initializer);
821  bool parseFieldInitializer(const FieldInfo &Field,
822                             const IntFieldInfo &Contents,
823                             FieldInitializer &Initializer);
824  bool parseFieldInitializer(const FieldInfo &Field,
825                             const RealFieldInfo &Contents,
826                             FieldInitializer &Initializer);
827  bool parseFieldInitializer(const FieldInfo &Field,
828                             const StructFieldInfo &Contents,
829                             FieldInitializer &Initializer);
830
831  bool parseStructInitializer(const StructInfo &Structure,
832                              StructInitializer &Initializer);
833  bool parseStructInstList(
834      const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
835      const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
836
837  bool emitFieldValue(const FieldInfo &Field);
838  bool emitFieldValue(const FieldInfo &Field, const IntFieldInfo &Contents);
839  bool emitFieldValue(const FieldInfo &Field, const RealFieldInfo &Contents);
840  bool emitFieldValue(const FieldInfo &Field, const StructFieldInfo &Contents);
841
842  bool emitFieldInitializer(const FieldInfo &Field,
843                            const FieldInitializer &Initializer);
844  bool emitFieldInitializer(const FieldInfo &Field,
845                            const IntFieldInfo &Contents,
846                            const IntFieldInfo &Initializer);
847  bool emitFieldInitializer(const FieldInfo &Field,
848                            const RealFieldInfo &Contents,
849                            const RealFieldInfo &Initializer);
850  bool emitFieldInitializer(const FieldInfo &Field,
851                            const StructFieldInfo &Contents,
852                            const StructFieldInfo &Initializer);
853
854  bool emitStructInitializer(const StructInfo &Structure,
855                             const StructInitializer &Initializer);
856
857  // User-defined types (structs, unions):
858  bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr);
859  bool addStructField(StringRef Name, const StructInfo &Structure);
860  bool parseDirectiveStructValue(const StructInfo &Structure,
861                                 StringRef Directive, SMLoc DirLoc);
862  bool parseDirectiveNamedStructValue(const StructInfo &Structure,
863                                      StringRef Directive, SMLoc DirLoc,
864                                      StringRef Name);
865
866  // "=", "equ", "textequ"
867  bool parseDirectiveEquate(StringRef IDVal, StringRef Name,
868                            DirectiveKind DirKind);
869
870  bool parseDirectiveOrg(); // ".org"
871  bool parseDirectiveAlign();  // "align"
872
873  // ".file", ".line", ".loc", ".stabs"
874  bool parseDirectiveFile(SMLoc DirectiveLoc);
875  bool parseDirectiveLine();
876  bool parseDirectiveLoc();
877  bool parseDirectiveStabs();
878
879  // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
880  // ".cv_inline_linetable", ".cv_def_range", ".cv_string"
881  bool parseDirectiveCVFile();
882  bool parseDirectiveCVFuncId();
883  bool parseDirectiveCVInlineSiteId();
884  bool parseDirectiveCVLoc();
885  bool parseDirectiveCVLinetable();
886  bool parseDirectiveCVInlineLinetable();
887  bool parseDirectiveCVDefRange();
888  bool parseDirectiveCVString();
889  bool parseDirectiveCVStringTable();
890  bool parseDirectiveCVFileChecksums();
891  bool parseDirectiveCVFileChecksumOffset();
892  bool parseDirectiveCVFPOData();
893
894  // .cfi directives
895  bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
896  bool parseDirectiveCFIWindowSave();
897  bool parseDirectiveCFISections();
898  bool parseDirectiveCFIStartProc();
899  bool parseDirectiveCFIEndProc();
900  bool parseDirectiveCFIDefCfaOffset();
901  bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
902  bool parseDirectiveCFIAdjustCfaOffset();
903  bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
904  bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
905  bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
906  bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
907  bool parseDirectiveCFIRememberState();
908  bool parseDirectiveCFIRestoreState();
909  bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
910  bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
911  bool parseDirectiveCFIEscape();
912  bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
913  bool parseDirectiveCFISignalFrame();
914  bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
915
916  // macro directives
917  bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
918  bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,
919                               std::string &Value);
920  bool parseDirectiveEndMacro(StringRef Directive);
921  bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);
922
923  bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind,
924                            StringRef Name, SMLoc NameLoc);
925  bool parseDirectiveNestedStruct(StringRef Directive, DirectiveKind DirKind);
926  bool parseDirectiveEnds(StringRef Name, SMLoc NameLoc);
927  bool parseDirectiveNestedEnds();
928
929  /// Parse a directive like ".globl" which accepts a single symbol (which
930  /// should be a label or an external).
931  bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
932
933  bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
934
935  bool parseDirectiveComment(SMLoc DirectiveLoc); // "comment"
936
937  bool parseDirectiveInclude(); // "include"
938
939  // "if" or "ife"
940  bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
941  // "ifb" or "ifnb", depending on ExpectBlank.
942  bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
943  // "ifidn", "ifdif", "ifidni", or "ifdifi", depending on ExpectEqual and
944  // CaseInsensitive.
945  bool parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
946                           bool CaseInsensitive);
947  // "ifdef" or "ifndef", depending on expect_defined
948  bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
949  // "elseif" or "elseife"
950  bool parseDirectiveElseIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
951  // "elseifb" or "elseifnb", depending on ExpectBlank.
952  bool parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank);
953  // ".elseifdef" or ".elseifndef", depending on expect_defined
954  bool parseDirectiveElseIfdef(SMLoc DirectiveLoc, bool expect_defined);
955  // "elseifidn", "elseifdif", "elseifidni", or "elseifdifi", depending on
956  // ExpectEqual and CaseInsensitive.
957  bool parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
958                               bool CaseInsensitive);
959  bool parseDirectiveElse(SMLoc DirectiveLoc);   // "else"
960  bool parseDirectiveEndIf(SMLoc DirectiveLoc);  // "endif"
961  bool parseEscapedString(std::string &Data) override;
962  bool parseAngleBracketString(std::string &Data) override;
963
964  // Macro-like directives
965  MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
966  void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
967                                raw_svector_ostream &OS);
968  void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
969                                SMLoc ExitLoc, raw_svector_ostream &OS);
970  bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive);
971  bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive);
972  bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive);
973  bool parseDirectiveWhile(SMLoc DirectiveLoc);
974
975  // "_emit" or "__emit"
976  bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
977                            size_t Len);
978
979  // "align"
980  bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
981
982  // "end"
983  bool parseDirectiveEnd(SMLoc DirectiveLoc);
984
985  // ".err"
986  bool parseDirectiveError(SMLoc DirectiveLoc);
987  // ".errb" or ".errnb", depending on ExpectBlank.
988  bool parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank);
989  // ".errdef" or ".errndef", depending on ExpectBlank.
990  bool parseDirectiveErrorIfdef(SMLoc DirectiveLoc, bool ExpectDefined);
991  // ".erridn", ".errdif", ".erridni", or ".errdifi", depending on ExpectEqual
992  // and CaseInsensitive.
993  bool parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
994                                bool CaseInsensitive);
995  // ".erre" or ".errnz", depending on ExpectZero.
996  bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero);
997
998  // ".radix"
999  bool parseDirectiveRadix(SMLoc DirectiveLoc);
1000
1001  // "echo"
1002  bool parseDirectiveEcho();
1003
1004  void initializeDirectiveKindMap();
1005  void initializeCVDefRangeTypeMap();
1006};
1007
1008} // end anonymous namespace
1009
1010namespace llvm {
1011
1012extern MCAsmParserExtension *createCOFFMasmParser();
1013
1014} // end namespace llvm
1015
1016enum { DEFAULT_ADDRSPACE = 0 };
1017
1018MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
1019                       const MCAsmInfo &MAI, unsigned CB = 0)
1020    : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
1021      CurBuffer(CB ? CB : SM.getMainFileID()) {
1022  HadError = false;
1023  // Save the old handler.
1024  SavedDiagHandler = SrcMgr.getDiagHandler();
1025  SavedDiagContext = SrcMgr.getDiagContext();
1026  // Set our own handler which calls the saved handler.
1027  SrcMgr.setDiagHandler(DiagHandler, this);
1028  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
1029  EndStatementAtEOFStack.push_back(true);
1030
1031  // Initialize the platform / file format parser.
1032  switch (Ctx.getObjectFileType()) {
1033  case MCContext::IsCOFF:
1034    PlatformParser.reset(createCOFFMasmParser());
1035    break;
1036  default:
1037    report_fatal_error("llvm-ml currently supports only COFF output.");
1038    break;
1039  }
1040
1041  initializeDirectiveKindMap();
1042  PlatformParser->Initialize(*this);
1043  initializeCVDefRangeTypeMap();
1044
1045  NumOfMacroInstantiations = 0;
1046}
1047
1048MasmParser::~MasmParser() {
1049  assert((HadError || ActiveMacros.empty()) &&
1050         "Unexpected active macro instantiation!");
1051
1052  // Restore the saved diagnostics handler and context for use during
1053  // finalization.
1054  SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
1055}
1056
1057void MasmParser::printMacroInstantiations() {
1058  // Print the active macro instantiation stack.
1059  for (std::vector<MacroInstantiation *>::const_reverse_iterator
1060           it = ActiveMacros.rbegin(),
1061           ie = ActiveMacros.rend();
1062       it != ie; ++it)
1063    printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
1064                 "while in macro instantiation");
1065}
1066
1067void MasmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
1068  printPendingErrors();
1069  printMessage(L, SourceMgr::DK_Note, Msg, Range);
1070  printMacroInstantiations();
1071}
1072
1073bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
1074  if (getTargetParser().getTargetOptions().MCNoWarn)
1075    return false;
1076  if (getTargetParser().getTargetOptions().MCFatalWarnings)
1077    return Error(L, Msg, Range);
1078  printMessage(L, SourceMgr::DK_Warning, Msg, Range);
1079  printMacroInstantiations();
1080  return false;
1081}
1082
1083bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
1084  HadError = true;
1085  printMessage(L, SourceMgr::DK_Error, Msg, Range);
1086  printMacroInstantiations();
1087  return true;
1088}
1089
1090bool MasmParser::enterIncludeFile(const std::string &Filename) {
1091  std::string IncludedFile;
1092  unsigned NewBuf =
1093      SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
1094  if (!NewBuf)
1095    return true;
1096
1097  CurBuffer = NewBuf;
1098  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
1099  EndStatementAtEOFStack.push_back(true);
1100  return false;
1101}
1102
1103void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer,
1104                           bool EndStatementAtEOF) {
1105  CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
1106  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
1107                  Loc.getPointer(), EndStatementAtEOF);
1108}
1109
1110const AsmToken &MasmParser::Lex() {
1111  if (Lexer.getTok().is(AsmToken::Error))
1112    Error(Lexer.getErrLoc(), Lexer.getErr());
1113
1114  // if it's a end of statement with a comment in it
1115  if (getTok().is(AsmToken::EndOfStatement)) {
1116    // if this is a line comment output it.
1117    if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
1118        getTok().getString().front() != '\r' && MAI.preserveAsmComments())
1119      Out.addExplicitComment(Twine(getTok().getString()));
1120  }
1121
1122  const AsmToken *tok = &Lexer.Lex();
1123
1124  while (tok->is(AsmToken::Identifier)) {
1125    auto it = Variables.find(tok->getIdentifier().lower());
1126    const llvm::MCAsmMacro *M =
1127        getContext().lookupMacro(tok->getIdentifier().lower());
1128    if (it != Variables.end() && it->second.IsText) {
1129      // This is a textmacro; expand it in place.
1130      std::unique_ptr<MemoryBuffer> Instantiation =
1131          MemoryBuffer::getMemBufferCopy(it->second.TextValue,
1132                                         "<instantiation>");
1133
1134      // Jump to the macro instantiation and prime the lexer.
1135      CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation),
1136                                            getTok().getEndLoc());
1137      Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
1138                      /*EndStatementAtEOF=*/false);
1139      EndStatementAtEOFStack.push_back(false);
1140      tok = &Lexer.Lex();
1141    } else if (M && M->IsFunction && Lexer.peekTok().is(AsmToken::LParen)) {
1142      // This is a macro function invocation; expand it in place.
1143      const AsmToken MacroTok = *tok;
1144      tok = &Lexer.Lex();
1145      if (handleMacroInvocation(M, MacroTok.getLoc())) {
1146        Lexer.UnLex(AsmToken(AsmToken::Error, MacroTok.getIdentifier()));
1147        tok = &Lexer.Lex();
1148      }
1149      continue;
1150    } else {
1151      break;
1152    }
1153  }
1154
1155  // Parse comments here to be deferred until end of next statement.
1156  while (tok->is(AsmToken::Comment)) {
1157    if (MAI.preserveAsmComments())
1158      Out.addExplicitComment(Twine(tok->getString()));
1159    tok = &Lexer.Lex();
1160  }
1161
1162  // Recognize and bypass line continuations.
1163  while (tok->is(AsmToken::BackSlash) &&
1164         Lexer.peekTok().is(AsmToken::EndOfStatement)) {
1165    // Eat both the backslash and the end of statement.
1166    Lexer.Lex();
1167    tok = &Lexer.Lex();
1168  }
1169
1170  if (tok->is(AsmToken::Eof)) {
1171    // If this is the end of an included file, pop the parent file off the
1172    // include stack.
1173    SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1174    if (ParentIncludeLoc != SMLoc()) {
1175      EndStatementAtEOFStack.pop_back();
1176      jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1177      return Lex();
1178    }
1179    EndStatementAtEOFStack.pop_back();
1180    assert(EndStatementAtEOFStack.empty());
1181  }
1182
1183  return *tok;
1184}
1185
1186bool MasmParser::enabledGenDwarfForAssembly() {
1187  // Check whether the user specified -g.
1188  if (!getContext().getGenDwarfForAssembly())
1189    return false;
1190  // If we haven't encountered any .file directives (which would imply that
1191  // the assembler source was produced with debug info already) then emit one
1192  // describing the assembler source file itself.
1193  if (getContext().getGenDwarfFileNumber() == 0) {
1194    // Use the first #line directive for this, if any. It's preprocessed, so
1195    // there is no checksum, and of course no source directive.
1196    if (!FirstCppHashFilename.empty())
1197      getContext().setMCLineTableRootFile(/*CUID=*/0,
1198                                          getContext().getCompilationDir(),
1199                                          FirstCppHashFilename,
1200                                          /*Cksum=*/None, /*Source=*/None);
1201    const MCDwarfFile &RootFile =
1202        getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
1203    getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
1204        /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name,
1205        RootFile.Checksum, RootFile.Source));
1206  }
1207  return true;
1208}
1209
1210bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
1211  // Create the initial section, if requested.
1212  if (!NoInitialTextSection)
1213    Out.InitSections(false);
1214
1215  // Prime the lexer.
1216  Lex();
1217
1218  HadError = false;
1219  AsmCond StartingCondState = TheCondState;
1220  SmallVector<AsmRewrite, 4> AsmStrRewrites;
1221
1222  // If we are generating dwarf for assembly source files save the initial text
1223  // section.  (Don't use enabledGenDwarfForAssembly() here, as we aren't
1224  // emitting any actual debug info yet and haven't had a chance to parse any
1225  // embedded .file directives.)
1226  if (getContext().getGenDwarfForAssembly()) {
1227    MCSection *Sec = getStreamer().getCurrentSectionOnly();
1228    if (!Sec->getBeginSymbol()) {
1229      MCSymbol *SectionStartSym = getContext().createTempSymbol();
1230      getStreamer().emitLabel(SectionStartSym);
1231      Sec->setBeginSymbol(SectionStartSym);
1232    }
1233    bool InsertResult = getContext().addGenDwarfSection(Sec);
1234    assert(InsertResult && ".text section should not have debug info yet");
1235    (void)InsertResult;
1236  }
1237
1238  getTargetParser().onBeginOfFile();
1239
1240  // While we have input, parse each statement.
1241  while (Lexer.isNot(AsmToken::Eof) ||
1242         SrcMgr.getParentIncludeLoc(CurBuffer) != SMLoc()) {
1243    // Skip through the EOF at the end of an inclusion.
1244    if (Lexer.is(AsmToken::Eof))
1245      Lex();
1246
1247    ParseStatementInfo Info(&AsmStrRewrites);
1248    bool Parsed = parseStatement(Info, nullptr);
1249
1250    // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
1251    // for printing ErrMsg via Lex() only if no (presumably better) parser error
1252    // exists.
1253    if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
1254      Lex();
1255    }
1256
1257    // parseStatement returned true so may need to emit an error.
1258    printPendingErrors();
1259
1260    // Skipping to the next line if needed.
1261    if (Parsed && !getLexer().isAtStartOfStatement())
1262      eatToEndOfStatement();
1263  }
1264
1265  getTargetParser().onEndOfFile();
1266  printPendingErrors();
1267
1268  // All errors should have been emitted.
1269  assert(!hasPendingError() && "unexpected error from parseStatement");
1270
1271  getTargetParser().flushPendingInstructions(getStreamer());
1272
1273  if (TheCondState.TheCond != StartingCondState.TheCond ||
1274      TheCondState.Ignore != StartingCondState.Ignore)
1275    printError(getTok().getLoc(), "unmatched .ifs or .elses");
1276  // Check to see there are no empty DwarfFile slots.
1277  const auto &LineTables = getContext().getMCDwarfLineTables();
1278  if (!LineTables.empty()) {
1279    unsigned Index = 0;
1280    for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
1281      if (File.Name.empty() && Index != 0)
1282        printError(getTok().getLoc(), "unassigned file number: " +
1283                                          Twine(Index) +
1284                                          " for .file directives");
1285      ++Index;
1286    }
1287  }
1288
1289  // Check to see that all assembler local symbols were actually defined.
1290  // Targets that don't do subsections via symbols may not want this, though,
1291  // so conservatively exclude them. Only do this if we're finalizing, though,
1292  // as otherwise we won't necessarilly have seen everything yet.
1293  if (!NoFinalize) {
1294    if (MAI.hasSubsectionsViaSymbols()) {
1295      for (const auto &TableEntry : getContext().getSymbols()) {
1296        MCSymbol *Sym = TableEntry.getValue();
1297        // Variable symbols may not be marked as defined, so check those
1298        // explicitly. If we know it's a variable, we have a definition for
1299        // the purposes of this check.
1300        if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
1301          // FIXME: We would really like to refer back to where the symbol was
1302          // first referenced for a source location. We need to add something
1303          // to track that. Currently, we just point to the end of the file.
1304          printError(getTok().getLoc(), "assembler local symbol '" +
1305                                            Sym->getName() + "' not defined");
1306      }
1307    }
1308
1309    // Temporary symbols like the ones for directional jumps don't go in the
1310    // symbol table. They also need to be diagnosed in all (final) cases.
1311    for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
1312      if (std::get<2>(LocSym)->isUndefined()) {
1313        // Reset the state of any "# line file" directives we've seen to the
1314        // context as it was at the diagnostic site.
1315        CppHashInfo = std::get<1>(LocSym);
1316        printError(std::get<0>(LocSym), "directional label undefined");
1317      }
1318    }
1319  }
1320
1321  // Finalize the output stream if there are no errors and if the client wants
1322  // us to.
1323  if (!HadError && !NoFinalize)
1324    Out.Finish(Lexer.getLoc());
1325
1326  return HadError || getContext().hadError();
1327}
1328
1329bool MasmParser::checkForValidSection() {
1330  if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
1331    Out.InitSections(false);
1332    return Error(getTok().getLoc(),
1333                 "expected section directive before assembly directive");
1334  }
1335  return false;
1336}
1337
1338/// Throw away the rest of the line for testing purposes.
1339void MasmParser::eatToEndOfStatement() {
1340  while (Lexer.isNot(AsmToken::EndOfStatement)) {
1341    if (Lexer.is(AsmToken::Eof)) {
1342      SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1343      if (ParentIncludeLoc == SMLoc()) {
1344        break;
1345      }
1346
1347      EndStatementAtEOFStack.pop_back();
1348      jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1349    }
1350
1351    Lexer.Lex();
1352  }
1353
1354  // Eat EOL.
1355  if (Lexer.is(AsmToken::EndOfStatement))
1356    Lexer.Lex();
1357}
1358
1359SmallVector<StringRef, 1>
1360MasmParser::parseStringRefsTo(AsmToken::TokenKind EndTok) {
1361  SmallVector<StringRef, 1> Refs;
1362  const char *Start = getTok().getLoc().getPointer();
1363  while (Lexer.isNot(EndTok)) {
1364    if (Lexer.is(AsmToken::Eof)) {
1365      SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
1366      if (ParentIncludeLoc == SMLoc()) {
1367        break;
1368      }
1369      Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
1370
1371      EndStatementAtEOFStack.pop_back();
1372      jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
1373      Lexer.Lex();
1374      Start = getTok().getLoc().getPointer();
1375    } else {
1376      Lexer.Lex();
1377    }
1378  }
1379  Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
1380  return Refs;
1381}
1382
1383std::string MasmParser::parseStringTo(AsmToken::TokenKind EndTok) {
1384  SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok);
1385  std::string Str;
1386  for (StringRef S : Refs) {
1387    Str.append(S.str());
1388  }
1389  return Str;
1390}
1391
1392StringRef MasmParser::parseStringToEndOfStatement() {
1393  const char *Start = getTok().getLoc().getPointer();
1394
1395  while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
1396    Lexer.Lex();
1397
1398  const char *End = getTok().getLoc().getPointer();
1399  return StringRef(Start, End - Start);
1400}
1401
1402/// Parse a paren expression and return it.
1403/// NOTE: This assumes the leading '(' has already been consumed.
1404///
1405/// parenexpr ::= expr)
1406///
1407bool MasmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1408  if (parseExpression(Res))
1409    return true;
1410  if (Lexer.isNot(AsmToken::RParen))
1411    return TokError("expected ')' in parentheses expression");
1412  EndLoc = Lexer.getTok().getEndLoc();
1413  Lex();
1414  return false;
1415}
1416
1417/// Parse a bracket expression and return it.
1418/// NOTE: This assumes the leading '[' has already been consumed.
1419///
1420/// bracketexpr ::= expr]
1421///
1422bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1423  if (parseExpression(Res))
1424    return true;
1425  EndLoc = getTok().getEndLoc();
1426  if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1427    return true;
1428  return false;
1429}
1430
1431/// Parse a primary expression and return it.
1432///  primaryexpr ::= (parenexpr
1433///  primaryexpr ::= symbol
1434///  primaryexpr ::= number
1435///  primaryexpr ::= '.'
1436///  primaryexpr ::= ~,+,-,'not' primaryexpr
1437///  primaryexpr ::= string
1438///          (a string is interpreted as a 64-bit number in big-endian base-256)
1439bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
1440                                  AsmTypeInfo *TypeInfo) {
1441  SMLoc FirstTokenLoc = getLexer().getLoc();
1442  AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
1443  switch (FirstTokenKind) {
1444  default:
1445    return TokError("unknown token in expression");
1446  // If we have an error assume that we've already handled it.
1447  case AsmToken::Error:
1448    return true;
1449  case AsmToken::Exclaim:
1450    Lex(); // Eat the operator.
1451    if (parsePrimaryExpr(Res, EndLoc, nullptr))
1452      return true;
1453    Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
1454    return false;
1455  case AsmToken::Dollar:
1456  case AsmToken::At:
1457  case AsmToken::Identifier: {
1458    StringRef Identifier;
1459    if (parseIdentifier(Identifier)) {
1460      // We may have failed but $ may be a valid token.
1461      if (getTok().is(AsmToken::Dollar)) {
1462        if (Lexer.getMAI().getDollarIsPC()) {
1463          Lex();
1464          // This is a '$' reference, which references the current PC.  Emit a
1465          // temporary label to the streamer and refer to it.
1466          MCSymbol *Sym = Ctx.createTempSymbol();
1467          Out.emitLabel(Sym);
1468          Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
1469                                        getContext());
1470          EndLoc = FirstTokenLoc;
1471          return false;
1472        }
1473        return Error(FirstTokenLoc, "invalid token in expression");
1474      }
1475    }
1476    // Parse named bitwise negation.
1477    if (Identifier.equals_lower("not")) {
1478      if (parsePrimaryExpr(Res, EndLoc, nullptr))
1479        return true;
1480      Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1481      return false;
1482    }
1483    // Parse symbol variant.
1484    std::pair<StringRef, StringRef> Split;
1485    if (!MAI.useParensForSymbolVariant()) {
1486      if (FirstTokenKind == AsmToken::String) {
1487        if (Lexer.is(AsmToken::At)) {
1488          Lex(); // eat @
1489          SMLoc AtLoc = getLexer().getLoc();
1490          StringRef VName;
1491          if (parseIdentifier(VName))
1492            return Error(AtLoc, "expected symbol variant after '@'");
1493
1494          Split = std::make_pair(Identifier, VName);
1495        }
1496      } else {
1497        Split = Identifier.split('@');
1498      }
1499    } else if (Lexer.is(AsmToken::LParen)) {
1500      Lex(); // eat '('.
1501      StringRef VName;
1502      parseIdentifier(VName);
1503      // eat ')'.
1504      if (parseToken(AsmToken::RParen,
1505                     "unexpected token in variant, expected ')'"))
1506        return true;
1507      Split = std::make_pair(Identifier, VName);
1508    }
1509
1510    EndLoc = SMLoc::getFromPointer(Identifier.end());
1511
1512    // This is a symbol reference.
1513    StringRef SymbolName = Identifier;
1514    if (SymbolName.empty())
1515      return Error(getLexer().getLoc(), "expected a symbol reference");
1516
1517    MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1518
1519    // Look up the symbol variant if used.
1520    if (!Split.second.empty()) {
1521      Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1522      if (Variant != MCSymbolRefExpr::VK_Invalid) {
1523        SymbolName = Split.first;
1524      } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
1525        Variant = MCSymbolRefExpr::VK_None;
1526      } else {
1527        return Error(SMLoc::getFromPointer(Split.second.begin()),
1528                     "invalid variant '" + Split.second + "'");
1529      }
1530    }
1531
1532    // Find the field offset if used.
1533    AsmFieldInfo Info;
1534    Split = SymbolName.split('.');
1535    if (Split.second.empty()) {
1536    } else {
1537      SymbolName = Split.first;
1538      if (lookUpField(SymbolName, Split.second, Info)) {
1539        std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');
1540        StringRef Base = BaseMember.first, Member = BaseMember.second;
1541        lookUpField(Base, Member, Info);
1542      } else if (Structs.count(SymbolName.lower())) {
1543        // This is actually a reference to a field offset.
1544        Res = MCConstantExpr::create(Info.Offset, getContext());
1545        return false;
1546      }
1547    }
1548
1549    MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
1550    if (!Sym) {
1551      // Variables use case-insensitive symbol names; if this is a variable, we
1552      // find the symbol using its canonical name.
1553      auto VarIt = Variables.find(SymbolName.lower());
1554      if (VarIt != Variables.end())
1555        SymbolName = VarIt->second.Name;
1556      Sym = getContext().getOrCreateSymbol(SymbolName);
1557    }
1558
1559    // If this is an absolute variable reference, substitute it now to preserve
1560    // semantics in the face of reassignment.
1561    if (Sym->isVariable()) {
1562      auto V = Sym->getVariableValue(/*SetUsed*/ false);
1563      bool DoInline = isa<MCConstantExpr>(V) && !Variant;
1564      if (auto TV = dyn_cast<MCTargetExpr>(V))
1565        DoInline = TV->inlineAssignedExpr();
1566      if (DoInline) {
1567        if (Variant)
1568          return Error(EndLoc, "unexpected modifier on variable reference");
1569        Res = Sym->getVariableValue(/*SetUsed*/ false);
1570        return false;
1571      }
1572    }
1573
1574    // Otherwise create a symbol ref.
1575    const MCExpr *SymRef =
1576        MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
1577    if (Info.Offset) {
1578      Res = MCBinaryExpr::create(
1579          MCBinaryExpr::Add, SymRef,
1580          MCConstantExpr::create(Info.Offset, getContext()), getContext());
1581    } else {
1582      Res = SymRef;
1583    }
1584    if (TypeInfo) {
1585      if (Info.Type.Name.empty()) {
1586        auto TypeIt = KnownType.find(Identifier.lower());
1587        if (TypeIt != KnownType.end()) {
1588          Info.Type = TypeIt->second;
1589        }
1590      }
1591
1592      *TypeInfo = Info.Type;
1593    }
1594    return false;
1595  }
1596  case AsmToken::BigNum:
1597    return TokError("literal value out of range for directive");
1598  case AsmToken::Integer: {
1599    SMLoc Loc = getTok().getLoc();
1600    int64_t IntVal = getTok().getIntVal();
1601    Res = MCConstantExpr::create(IntVal, getContext());
1602    EndLoc = Lexer.getTok().getEndLoc();
1603    Lex(); // Eat token.
1604    // Look for 'b' or 'f' following an Integer as a directional label.
1605    if (Lexer.getKind() == AsmToken::Identifier) {
1606      StringRef IDVal = getTok().getString();
1607      // Look up the symbol variant if used.
1608      std::pair<StringRef, StringRef> Split = IDVal.split('@');
1609      MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1610      if (Split.first.size() != IDVal.size()) {
1611        Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1612        if (Variant == MCSymbolRefExpr::VK_Invalid)
1613          return TokError("invalid variant '" + Split.second + "'");
1614        IDVal = Split.first;
1615      }
1616      if (IDVal == "f" || IDVal == "b") {
1617        MCSymbol *Sym =
1618            Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
1619        Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
1620        if (IDVal == "b" && Sym->isUndefined())
1621          return Error(Loc, "directional label undefined");
1622        DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1623        EndLoc = Lexer.getTok().getEndLoc();
1624        Lex(); // Eat identifier.
1625      }
1626    }
1627    return false;
1628  }
1629  case AsmToken::String: {
1630    // MASM strings (used as constants) are interpreted as big-endian base-256.
1631    SMLoc ValueLoc = getTok().getLoc();
1632    std::string Value;
1633    if (parseEscapedString(Value))
1634      return true;
1635    if (Value.size() > 8)
1636      return Error(ValueLoc, "literal value out of range");
1637    uint64_t IntValue = 0;
1638    for (const unsigned char CharVal : Value)
1639      IntValue = (IntValue << 8) | CharVal;
1640    Res = MCConstantExpr::create(IntValue, getContext());
1641    return false;
1642  }
1643  case AsmToken::Real: {
1644    APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1645    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1646    Res = MCConstantExpr::create(IntVal, getContext());
1647    EndLoc = Lexer.getTok().getEndLoc();
1648    Lex(); // Eat token.
1649    return false;
1650  }
1651  case AsmToken::Dot: {
1652    // This is a '.' reference, which references the current PC.  Emit a
1653    // temporary label to the streamer and refer to it.
1654    MCSymbol *Sym = Ctx.createTempSymbol();
1655    Out.emitLabel(Sym);
1656    Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1657    EndLoc = Lexer.getTok().getEndLoc();
1658    Lex(); // Eat identifier.
1659    return false;
1660  }
1661  case AsmToken::LParen:
1662    Lex(); // Eat the '('.
1663    return parseParenExpr(Res, EndLoc);
1664  case AsmToken::LBrac:
1665    if (!PlatformParser->HasBracketExpressions())
1666      return TokError("brackets expression not supported on this target");
1667    Lex(); // Eat the '['.
1668    return parseBracketExpr(Res, EndLoc);
1669  case AsmToken::Minus:
1670    Lex(); // Eat the operator.
1671    if (parsePrimaryExpr(Res, EndLoc, nullptr))
1672      return true;
1673    Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
1674    return false;
1675  case AsmToken::Plus:
1676    Lex(); // Eat the operator.
1677    if (parsePrimaryExpr(Res, EndLoc, nullptr))
1678      return true;
1679    Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
1680    return false;
1681  case AsmToken::Tilde:
1682    Lex(); // Eat the operator.
1683    if (parsePrimaryExpr(Res, EndLoc, nullptr))
1684      return true;
1685    Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1686    return false;
1687  // MIPS unary expression operators. The lexer won't generate these tokens if
1688  // MCAsmInfo::HasMipsExpressions is false for the target.
1689  case AsmToken::PercentCall16:
1690  case AsmToken::PercentCall_Hi:
1691  case AsmToken::PercentCall_Lo:
1692  case AsmToken::PercentDtprel_Hi:
1693  case AsmToken::PercentDtprel_Lo:
1694  case AsmToken::PercentGot:
1695  case AsmToken::PercentGot_Disp:
1696  case AsmToken::PercentGot_Hi:
1697  case AsmToken::PercentGot_Lo:
1698  case AsmToken::PercentGot_Ofst:
1699  case AsmToken::PercentGot_Page:
1700  case AsmToken::PercentGottprel:
1701  case AsmToken::PercentGp_Rel:
1702  case AsmToken::PercentHi:
1703  case AsmToken::PercentHigher:
1704  case AsmToken::PercentHighest:
1705  case AsmToken::PercentLo:
1706  case AsmToken::PercentNeg:
1707  case AsmToken::PercentPcrel_Hi:
1708  case AsmToken::PercentPcrel_Lo:
1709  case AsmToken::PercentTlsgd:
1710  case AsmToken::PercentTlsldm:
1711  case AsmToken::PercentTprel_Hi:
1712  case AsmToken::PercentTprel_Lo:
1713    Lex(); // Eat the operator.
1714    if (Lexer.isNot(AsmToken::LParen))
1715      return TokError("expected '(' after operator");
1716    Lex(); // Eat the operator.
1717    if (parseExpression(Res, EndLoc))
1718      return true;
1719    if (Lexer.isNot(AsmToken::RParen))
1720      return TokError("expected ')'");
1721    Lex(); // Eat the operator.
1722    Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1723    return !Res;
1724  }
1725}
1726
1727bool MasmParser::parseExpression(const MCExpr *&Res) {
1728  SMLoc EndLoc;
1729  return parseExpression(Res, EndLoc);
1730}
1731
1732/// This function checks if the next token is <string> type or arithmetic.
1733/// string that begin with character '<' must end with character '>'.
1734/// otherwise it is arithmetics.
1735/// If the function returns a 'true' value,
1736/// the End argument will be filled with the last location pointed to the '>'
1737/// character.
1738static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc) {
1739  assert((StrLoc.getPointer() != nullptr) &&
1740         "Argument to the function cannot be a NULL value");
1741  const char *CharPtr = StrLoc.getPointer();
1742  while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1743         (*CharPtr != '\0')) {
1744    if (*CharPtr == '!')
1745      CharPtr++;
1746    CharPtr++;
1747  }
1748  if (*CharPtr == '>') {
1749    EndLoc = StrLoc.getFromPointer(CharPtr + 1);
1750    return true;
1751  }
1752  return false;
1753}
1754
1755/// creating a string without the escape characters '!'.
1756static std::string angleBracketString(StringRef BracketContents) {
1757  std::string Res;
1758  for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) {
1759    if (BracketContents[Pos] == '!')
1760      Pos++;
1761    Res += BracketContents[Pos];
1762  }
1763  return Res;
1764}
1765
1766/// Parse an expression and return it.
1767///
1768///  expr ::= expr &&,|| expr               -> lowest.
1769///  expr ::= expr |,^,&,! expr
1770///  expr ::= expr ==,!=,<>,<,<=,>,>= expr
1771///  expr ::= expr <<,>> expr
1772///  expr ::= expr +,- expr
1773///  expr ::= expr *,/,% expr               -> highest.
1774///  expr ::= primaryexpr
1775///
1776bool MasmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1777  // Parse the expression.
1778  Res = nullptr;
1779  if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1780      parseBinOpRHS(1, Res, EndLoc))
1781    return true;
1782
1783  // Try to constant fold it up front, if possible. Do not exploit
1784  // assembler here.
1785  int64_t Value;
1786  if (Res->evaluateAsAbsolute(Value))
1787    Res = MCConstantExpr::create(Value, getContext());
1788
1789  return false;
1790}
1791
1792bool MasmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1793  Res = nullptr;
1794  return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1795}
1796
1797bool MasmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
1798                                       SMLoc &EndLoc) {
1799  if (parseParenExpr(Res, EndLoc))
1800    return true;
1801
1802  for (; ParenDepth > 0; --ParenDepth) {
1803    if (parseBinOpRHS(1, Res, EndLoc))
1804      return true;
1805
1806    // We don't Lex() the last RParen.
1807    // This is the same behavior as parseParenExpression().
1808    if (ParenDepth - 1 > 0) {
1809      EndLoc = getTok().getEndLoc();
1810      if (parseToken(AsmToken::RParen,
1811                     "expected ')' in parentheses expression"))
1812        return true;
1813    }
1814  }
1815  return false;
1816}
1817
1818bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
1819  const MCExpr *Expr;
1820
1821  SMLoc StartLoc = Lexer.getLoc();
1822  if (parseExpression(Expr))
1823    return true;
1824
1825  if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1826    return Error(StartLoc, "expected absolute expression");
1827
1828  return false;
1829}
1830
1831static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K,
1832                                      MCBinaryExpr::Opcode &Kind,
1833                                      bool ShouldUseLogicalShr,
1834                                      bool EndExpressionAtGreater) {
1835  switch (K) {
1836  default:
1837    return 0; // not a binop.
1838
1839  // Lowest Precedence: &&, ||
1840  case AsmToken::AmpAmp:
1841    Kind = MCBinaryExpr::LAnd;
1842    return 2;
1843  case AsmToken::PipePipe:
1844    Kind = MCBinaryExpr::LOr;
1845    return 1;
1846
1847  // Low Precedence: ==, !=, <>, <, <=, >, >=
1848  case AsmToken::EqualEqual:
1849    Kind = MCBinaryExpr::EQ;
1850    return 3;
1851  case AsmToken::ExclaimEqual:
1852  case AsmToken::LessGreater:
1853    Kind = MCBinaryExpr::NE;
1854    return 3;
1855  case AsmToken::Less:
1856    Kind = MCBinaryExpr::LT;
1857    return 3;
1858  case AsmToken::LessEqual:
1859    Kind = MCBinaryExpr::LTE;
1860    return 3;
1861  case AsmToken::Greater:
1862    if (EndExpressionAtGreater)
1863      return 0;
1864    Kind = MCBinaryExpr::GT;
1865    return 3;
1866  case AsmToken::GreaterEqual:
1867    Kind = MCBinaryExpr::GTE;
1868    return 3;
1869
1870  // Low Intermediate Precedence: +, -
1871  case AsmToken::Plus:
1872    Kind = MCBinaryExpr::Add;
1873    return 4;
1874  case AsmToken::Minus:
1875    Kind = MCBinaryExpr::Sub;
1876    return 4;
1877
1878  // High Intermediate Precedence: |, &, ^
1879  case AsmToken::Pipe:
1880    Kind = MCBinaryExpr::Or;
1881    return 5;
1882  case AsmToken::Caret:
1883    Kind = MCBinaryExpr::Xor;
1884    return 5;
1885  case AsmToken::Amp:
1886    Kind = MCBinaryExpr::And;
1887    return 5;
1888
1889  // Highest Precedence: *, /, %, <<, >>
1890  case AsmToken::Star:
1891    Kind = MCBinaryExpr::Mul;
1892    return 6;
1893  case AsmToken::Slash:
1894    Kind = MCBinaryExpr::Div;
1895    return 6;
1896  case AsmToken::Percent:
1897    Kind = MCBinaryExpr::Mod;
1898    return 6;
1899  case AsmToken::LessLess:
1900    Kind = MCBinaryExpr::Shl;
1901    return 6;
1902  case AsmToken::GreaterGreater:
1903    if (EndExpressionAtGreater)
1904      return 0;
1905    Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
1906    return 6;
1907  }
1908}
1909
1910unsigned MasmParser::getBinOpPrecedence(AsmToken::TokenKind K,
1911                                        MCBinaryExpr::Opcode &Kind) {
1912  bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
1913  return getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr,
1914                               AngleBracketDepth > 0);
1915}
1916
1917/// Parse all binary operators with precedence >= 'Precedence'.
1918/// Res contains the LHS of the expression on input.
1919bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
1920                               SMLoc &EndLoc) {
1921  SMLoc StartLoc = Lexer.getLoc();
1922  while (true) {
1923    AsmToken::TokenKind TokKind = Lexer.getKind();
1924    if (Lexer.getKind() == AsmToken::Identifier) {
1925      TokKind = StringSwitch<AsmToken::TokenKind>(Lexer.getTok().getString())
1926                    .CaseLower("and", AsmToken::Amp)
1927                    .CaseLower("not", AsmToken::Exclaim)
1928                    .CaseLower("or", AsmToken::Pipe)
1929                    .CaseLower("eq", AsmToken::EqualEqual)
1930                    .CaseLower("ne", AsmToken::ExclaimEqual)
1931                    .CaseLower("lt", AsmToken::Less)
1932                    .CaseLower("le", AsmToken::LessEqual)
1933                    .CaseLower("gt", AsmToken::Greater)
1934                    .CaseLower("ge", AsmToken::GreaterEqual)
1935                    .Default(TokKind);
1936    }
1937    MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
1938    unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
1939
1940    // If the next token is lower precedence than we are allowed to eat, return
1941    // successfully with what we ate already.
1942    if (TokPrec < Precedence)
1943      return false;
1944
1945    Lex();
1946
1947    // Eat the next primary expression.
1948    const MCExpr *RHS;
1949    if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1950      return true;
1951
1952    // If BinOp binds less tightly with RHS than the operator after RHS, let
1953    // the pending operator take RHS as its LHS.
1954    MCBinaryExpr::Opcode Dummy;
1955    unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1956    if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1957      return true;
1958
1959    // Merge LHS and RHS according to operator.
1960    Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
1961  }
1962}
1963
1964/// ParseStatement:
1965///   ::= % statement
1966///   ::= EndOfStatement
1967///   ::= Label* Directive ...Operands... EndOfStatement
1968///   ::= Label* Identifier OperandList* EndOfStatement
1969bool MasmParser::parseStatement(ParseStatementInfo &Info,
1970                                MCAsmParserSemaCallback *SI) {
1971  assert(!hasPendingError() && "parseStatement started with pending error");
1972  // Eat initial spaces and comments.
1973  while (Lexer.is(AsmToken::Space))
1974    Lex();
1975  if (Lexer.is(AsmToken::EndOfStatement)) {
1976    // If this is a line comment we can drop it safely.
1977    if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
1978        getTok().getString().front() == '\n')
1979      Out.AddBlankLine();
1980    Lex();
1981    return false;
1982  }
1983
1984  // If preceded by an expansion operator, first expand all text macros and
1985  // macro functions.
1986  if (getTok().is(AsmToken::Percent)) {
1987    SMLoc ExpansionLoc = getTok().getLoc();
1988    if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc))
1989      return true;
1990  }
1991
1992  // Statements always start with an identifier, unless we're dealing with a
1993  // processor directive (.386, .686, etc.) that lexes as a real.
1994  AsmToken ID = getTok();
1995  SMLoc IDLoc = ID.getLoc();
1996  StringRef IDVal;
1997  int64_t LocalLabelVal = -1;
1998  if (Lexer.is(AsmToken::HashDirective))
1999    return parseCppHashLineFilenameComment(IDLoc);
2000  // Allow an integer followed by a ':' as a directional local label.
2001  if (Lexer.is(AsmToken::Integer)) {
2002    LocalLabelVal = getTok().getIntVal();
2003    if (LocalLabelVal < 0) {
2004      if (!TheCondState.Ignore) {
2005        Lex(); // always eat a token
2006        return Error(IDLoc, "unexpected token at start of statement");
2007      }
2008      IDVal = "";
2009    } else {
2010      IDVal = getTok().getString();
2011      Lex(); // Consume the integer token to be used as an identifier token.
2012      if (Lexer.getKind() != AsmToken::Colon) {
2013        if (!TheCondState.Ignore) {
2014          Lex(); // always eat a token
2015          return Error(IDLoc, "unexpected token at start of statement");
2016        }
2017      }
2018    }
2019  } else if (Lexer.is(AsmToken::Dot)) {
2020    // Treat '.' as a valid identifier in this context.
2021    Lex();
2022    IDVal = ".";
2023  } else if (Lexer.is(AsmToken::LCurly)) {
2024    // Treat '{' as a valid identifier in this context.
2025    Lex();
2026    IDVal = "{";
2027
2028  } else if (Lexer.is(AsmToken::RCurly)) {
2029    // Treat '}' as a valid identifier in this context.
2030    Lex();
2031    IDVal = "}";
2032  } else if (Lexer.is(AsmToken::Star) &&
2033             getTargetParser().starIsStartOfStatement()) {
2034    // Accept '*' as a valid start of statement.
2035    Lex();
2036    IDVal = "*";
2037  } else if (Lexer.is(AsmToken::Real)) {
2038    // Treat ".<number>" as a valid identifier in this context.
2039    IDVal = getTok().getString();
2040    Lex(); // always eat a token
2041    if (!IDVal.startswith("."))
2042      return Error(IDLoc, "unexpected token at start of statement");
2043  } else if (Lexer.is(AsmToken::Identifier) &&
2044             getTok().getString().equals_lower("echo")) {
2045    // Intercept echo early to avoid lexical substitution in its message, and
2046    // delegate all handling to the appropriate function.
2047    return parseDirectiveEcho();
2048  } else if (parseIdentifier(IDVal)) {
2049    if (!TheCondState.Ignore) {
2050      Lex(); // always eat a token
2051      return Error(IDLoc, "unexpected token at start of statement");
2052    }
2053    IDVal = "";
2054  }
2055
2056  // Handle conditional assembly here before checking for skipping.  We
2057  // have to do this so that .endif isn't skipped in a ".if 0" block for
2058  // example.
2059  StringMap<DirectiveKind>::const_iterator DirKindIt =
2060      DirectiveKindMap.find(IDVal.lower());
2061  DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
2062                              ? DK_NO_DIRECTIVE
2063                              : DirKindIt->getValue();
2064  switch (DirKind) {
2065  default:
2066    break;
2067  case DK_IF:
2068  case DK_IFE:
2069    return parseDirectiveIf(IDLoc, DirKind);
2070  case DK_IFB:
2071    return parseDirectiveIfb(IDLoc, true);
2072  case DK_IFNB:
2073    return parseDirectiveIfb(IDLoc, false);
2074  case DK_IFDEF:
2075    return parseDirectiveIfdef(IDLoc, true);
2076  case DK_IFNDEF:
2077    return parseDirectiveIfdef(IDLoc, false);
2078  case DK_IFDIF:
2079    return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
2080                               /*CaseInsensitive=*/false);
2081  case DK_IFDIFI:
2082    return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
2083                               /*CaseInsensitive=*/true);
2084  case DK_IFIDN:
2085    return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
2086                               /*CaseInsensitive=*/false);
2087  case DK_IFIDNI:
2088    return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
2089                               /*CaseInsensitive=*/true);
2090  case DK_ELSEIF:
2091  case DK_ELSEIFE:
2092    return parseDirectiveElseIf(IDLoc, DirKind);
2093  case DK_ELSEIFB:
2094    return parseDirectiveElseIfb(IDLoc, true);
2095  case DK_ELSEIFNB:
2096    return parseDirectiveElseIfb(IDLoc, false);
2097  case DK_ELSEIFDEF:
2098    return parseDirectiveElseIfdef(IDLoc, true);
2099  case DK_ELSEIFNDEF:
2100    return parseDirectiveElseIfdef(IDLoc, false);
2101  case DK_ELSEIFDIF:
2102    return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
2103                                   /*CaseInsensitive=*/false);
2104  case DK_ELSEIFDIFI:
2105    return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
2106                                   /*CaseInsensitive=*/true);
2107  case DK_ELSEIFIDN:
2108    return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
2109                                   /*CaseInsensitive=*/false);
2110  case DK_ELSEIFIDNI:
2111    return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
2112                                   /*CaseInsensitive=*/true);
2113  case DK_ELSE:
2114    return parseDirectiveElse(IDLoc);
2115  case DK_ENDIF:
2116    return parseDirectiveEndIf(IDLoc);
2117  }
2118
2119  // Ignore the statement if in the middle of inactive conditional
2120  // (e.g. ".if 0").
2121  if (TheCondState.Ignore) {
2122    eatToEndOfStatement();
2123    return false;
2124  }
2125
2126  // FIXME: Recurse on local labels?
2127
2128  // See what kind of statement we have.
2129  switch (Lexer.getKind()) {
2130  case AsmToken::Colon: {
2131    if (!getTargetParser().isLabel(ID))
2132      break;
2133    if (checkForValidSection())
2134      return true;
2135
2136    // identifier ':'   -> Label.
2137    Lex();
2138
2139    // Diagnose attempt to use '.' as a label.
2140    if (IDVal == ".")
2141      return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
2142
2143    // Diagnose attempt to use a variable as a label.
2144    //
2145    // FIXME: Diagnostics. Note the location of the definition as a label.
2146    // FIXME: This doesn't diagnose assignment to a symbol which has been
2147    // implicitly marked as external.
2148    MCSymbol *Sym;
2149    if (LocalLabelVal == -1) {
2150      if (ParsingMSInlineAsm && SI) {
2151        StringRef RewrittenLabel =
2152            SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
2153        assert(!RewrittenLabel.empty() &&
2154               "We should have an internal name here.");
2155        Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
2156                                       RewrittenLabel);
2157        IDVal = RewrittenLabel;
2158      }
2159      Sym = getContext().getOrCreateSymbol(IDVal);
2160    } else
2161      Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
2162    // End of Labels should be treated as end of line for lexing
2163    // purposes but that information is not available to the Lexer who
2164    // does not understand Labels. This may cause us to see a Hash
2165    // here instead of a preprocessor line comment.
2166    if (getTok().is(AsmToken::Hash)) {
2167      std::string CommentStr = parseStringTo(AsmToken::EndOfStatement);
2168      Lexer.Lex();
2169      Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
2170    }
2171
2172    // Consume any end of statement token, if present, to avoid spurious
2173    // AddBlankLine calls().
2174    if (getTok().is(AsmToken::EndOfStatement)) {
2175      Lex();
2176    }
2177
2178    getTargetParser().doBeforeLabelEmit(Sym);
2179
2180    // Emit the label.
2181    if (!getTargetParser().isParsingMSInlineAsm())
2182      Out.emitLabel(Sym, IDLoc);
2183
2184    // If we are generating dwarf for assembly source files then gather the
2185    // info to make a dwarf label entry for this label if needed.
2186    if (enabledGenDwarfForAssembly())
2187      MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
2188                                 IDLoc);
2189
2190    getTargetParser().onLabelParsed(Sym);
2191
2192    return false;
2193  }
2194
2195  default: // Normal instruction or directive.
2196    break;
2197  }
2198
2199  // If macros are enabled, check to see if this is a macro instantiation.
2200  if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) {
2201    return handleMacroEntry(M, IDLoc);
2202  }
2203
2204  // Otherwise, we have a normal instruction or directive.
2205
2206  if (DirKind != DK_NO_DIRECTIVE) {
2207    // There are several entities interested in parsing directives:
2208    //
2209    // 1. Asm parser extensions. For example, platform-specific parsers
2210    //    (like the ELF parser) register themselves as extensions.
2211    // 2. The target-specific assembly parser. Some directives are target
2212    //    specific or may potentially behave differently on certain targets.
2213    // 3. The generic directive parser implemented by this class. These are
2214    //    all the directives that behave in a target and platform independent
2215    //    manner, or at least have a default behavior that's shared between
2216    //    all targets and platforms.
2217
2218    getTargetParser().flushPendingInstructions(getStreamer());
2219
2220    // Special-case handling of structure-end directives at higher priority,
2221    // since ENDS is overloaded as a segment-end directive.
2222    if (IDVal.equals_lower("ends") && StructInProgress.size() > 1 &&
2223        getTok().is(AsmToken::EndOfStatement)) {
2224      return parseDirectiveNestedEnds();
2225    }
2226
2227    // First, check the extension directive map to see if any extension has
2228    // registered itself to parse this directive.
2229    std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2230        ExtensionDirectiveMap.lookup(IDVal.lower());
2231    if (Handler.first)
2232      return (*Handler.second)(Handler.first, IDVal, IDLoc);
2233
2234    // Next, let the target-specific assembly parser try.
2235    SMLoc StartTokLoc = getTok().getLoc();
2236    bool TPDirectiveReturn =
2237        ID.is(AsmToken::Identifier) && getTargetParser().ParseDirective(ID);
2238
2239    if (hasPendingError())
2240      return true;
2241    // Currently the return value should be true if we are
2242    // uninterested but as this is at odds with the standard parsing
2243    // convention (return true = error) we have instances of a parsed
2244    // directive that fails returning true as an error. Catch these
2245    // cases as best as possible errors here.
2246    if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
2247      return true;
2248    // Return if we did some parsing or believe we succeeded.
2249    if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
2250      return false;
2251
2252    // Finally, if no one else is interested in this directive, it must be
2253    // generic and familiar to this class.
2254    switch (DirKind) {
2255    default:
2256      break;
2257    case DK_ASCII:
2258      return parseDirectiveAscii(IDVal, false);
2259    case DK_ASCIZ:
2260    case DK_STRING:
2261      return parseDirectiveAscii(IDVal, true);
2262    case DK_BYTE:
2263    case DK_SBYTE:
2264    case DK_DB:
2265      return parseDirectiveValue(IDVal, 1);
2266    case DK_WORD:
2267    case DK_SWORD:
2268    case DK_DW:
2269      return parseDirectiveValue(IDVal, 2);
2270    case DK_DWORD:
2271    case DK_SDWORD:
2272    case DK_DD:
2273      return parseDirectiveValue(IDVal, 4);
2274    case DK_FWORD:
2275    case DK_DF:
2276      return parseDirectiveValue(IDVal, 6);
2277    case DK_QWORD:
2278    case DK_SQWORD:
2279    case DK_DQ:
2280      return parseDirectiveValue(IDVal, 8);
2281    case DK_REAL4:
2282      return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
2283    case DK_REAL8:
2284      return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
2285    case DK_REAL10:
2286      return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
2287    case DK_STRUCT:
2288    case DK_UNION:
2289      return parseDirectiveNestedStruct(IDVal, DirKind);
2290    case DK_ENDS:
2291      return parseDirectiveNestedEnds();
2292    case DK_ALIGN:
2293      return parseDirectiveAlign();
2294    case DK_ORG:
2295      return parseDirectiveOrg();
2296    case DK_EXTERN:
2297      eatToEndOfStatement(); // .extern is the default, ignore it.
2298      return false;
2299    case DK_PUBLIC:
2300      return parseDirectiveSymbolAttribute(MCSA_Global);
2301    case DK_COMM:
2302      return parseDirectiveComm(/*IsLocal=*/false);
2303    case DK_COMMENT:
2304      return parseDirectiveComment(IDLoc);
2305    case DK_INCLUDE:
2306      return parseDirectiveInclude();
2307    case DK_REPEAT:
2308      return parseDirectiveRepeat(IDLoc, IDVal);
2309    case DK_WHILE:
2310      return parseDirectiveWhile(IDLoc);
2311    case DK_FOR:
2312      return parseDirectiveFor(IDLoc, IDVal);
2313    case DK_FORC:
2314      return parseDirectiveForc(IDLoc, IDVal);
2315    case DK_FILE:
2316      return parseDirectiveFile(IDLoc);
2317    case DK_LINE:
2318      return parseDirectiveLine();
2319    case DK_LOC:
2320      return parseDirectiveLoc();
2321    case DK_STABS:
2322      return parseDirectiveStabs();
2323    case DK_CV_FILE:
2324      return parseDirectiveCVFile();
2325    case DK_CV_FUNC_ID:
2326      return parseDirectiveCVFuncId();
2327    case DK_CV_INLINE_SITE_ID:
2328      return parseDirectiveCVInlineSiteId();
2329    case DK_CV_LOC:
2330      return parseDirectiveCVLoc();
2331    case DK_CV_LINETABLE:
2332      return parseDirectiveCVLinetable();
2333    case DK_CV_INLINE_LINETABLE:
2334      return parseDirectiveCVInlineLinetable();
2335    case DK_CV_DEF_RANGE:
2336      return parseDirectiveCVDefRange();
2337    case DK_CV_STRING:
2338      return parseDirectiveCVString();
2339    case DK_CV_STRINGTABLE:
2340      return parseDirectiveCVStringTable();
2341    case DK_CV_FILECHECKSUMS:
2342      return parseDirectiveCVFileChecksums();
2343    case DK_CV_FILECHECKSUM_OFFSET:
2344      return parseDirectiveCVFileChecksumOffset();
2345    case DK_CV_FPO_DATA:
2346      return parseDirectiveCVFPOData();
2347    case DK_CFI_SECTIONS:
2348      return parseDirectiveCFISections();
2349    case DK_CFI_STARTPROC:
2350      return parseDirectiveCFIStartProc();
2351    case DK_CFI_ENDPROC:
2352      return parseDirectiveCFIEndProc();
2353    case DK_CFI_DEF_CFA:
2354      return parseDirectiveCFIDefCfa(IDLoc);
2355    case DK_CFI_DEF_CFA_OFFSET:
2356      return parseDirectiveCFIDefCfaOffset();
2357    case DK_CFI_ADJUST_CFA_OFFSET:
2358      return parseDirectiveCFIAdjustCfaOffset();
2359    case DK_CFI_DEF_CFA_REGISTER:
2360      return parseDirectiveCFIDefCfaRegister(IDLoc);
2361    case DK_CFI_OFFSET:
2362      return parseDirectiveCFIOffset(IDLoc);
2363    case DK_CFI_REL_OFFSET:
2364      return parseDirectiveCFIRelOffset(IDLoc);
2365    case DK_CFI_PERSONALITY:
2366      return parseDirectiveCFIPersonalityOrLsda(true);
2367    case DK_CFI_LSDA:
2368      return parseDirectiveCFIPersonalityOrLsda(false);
2369    case DK_CFI_REMEMBER_STATE:
2370      return parseDirectiveCFIRememberState();
2371    case DK_CFI_RESTORE_STATE:
2372      return parseDirectiveCFIRestoreState();
2373    case DK_CFI_SAME_VALUE:
2374      return parseDirectiveCFISameValue(IDLoc);
2375    case DK_CFI_RESTORE:
2376      return parseDirectiveCFIRestore(IDLoc);
2377    case DK_CFI_ESCAPE:
2378      return parseDirectiveCFIEscape();
2379    case DK_CFI_RETURN_COLUMN:
2380      return parseDirectiveCFIReturnColumn(IDLoc);
2381    case DK_CFI_SIGNAL_FRAME:
2382      return parseDirectiveCFISignalFrame();
2383    case DK_CFI_UNDEFINED:
2384      return parseDirectiveCFIUndefined(IDLoc);
2385    case DK_CFI_REGISTER:
2386      return parseDirectiveCFIRegister(IDLoc);
2387    case DK_CFI_WINDOW_SAVE:
2388      return parseDirectiveCFIWindowSave();
2389    case DK_EXITM:
2390      Info.ExitValue = "";
2391      return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);
2392    case DK_ENDM:
2393      Info.ExitValue = "";
2394      return parseDirectiveEndMacro(IDVal);
2395    case DK_PURGE:
2396      return parseDirectivePurgeMacro(IDLoc);
2397    case DK_END:
2398      return parseDirectiveEnd(IDLoc);
2399    case DK_ERR:
2400      return parseDirectiveError(IDLoc);
2401    case DK_ERRB:
2402      return parseDirectiveErrorIfb(IDLoc, true);
2403    case DK_ERRNB:
2404      return parseDirectiveErrorIfb(IDLoc, false);
2405    case DK_ERRDEF:
2406      return parseDirectiveErrorIfdef(IDLoc, true);
2407    case DK_ERRNDEF:
2408      return parseDirectiveErrorIfdef(IDLoc, false);
2409    case DK_ERRDIF:
2410      return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
2411                                      /*CaseInsensitive=*/false);
2412    case DK_ERRDIFI:
2413      return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
2414                                      /*CaseInsensitive=*/true);
2415    case DK_ERRIDN:
2416      return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
2417                                      /*CaseInsensitive=*/false);
2418    case DK_ERRIDNI:
2419      return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
2420                                      /*CaseInsensitive=*/true);
2421    case DK_ERRE:
2422      return parseDirectiveErrorIfe(IDLoc, true);
2423    case DK_ERRNZ:
2424      return parseDirectiveErrorIfe(IDLoc, false);
2425    case DK_RADIX:
2426      return parseDirectiveRadix(IDLoc);
2427    }
2428
2429    return Error(IDLoc, "unknown directive");
2430  }
2431
2432  // We also check if this is allocating memory with user-defined type.
2433  auto IDIt = Structs.find(IDVal.lower());
2434  if (IDIt != Structs.end())
2435    return parseDirectiveStructValue(/*Structure=*/IDIt->getValue(), IDVal,
2436                                     IDLoc);
2437
2438  // Non-conditional Microsoft directives sometimes follow their first argument.
2439  const AsmToken nextTok = getTok();
2440  const StringRef nextVal = nextTok.getString();
2441  const SMLoc nextLoc = nextTok.getLoc();
2442
2443  // There are several entities interested in parsing infix directives:
2444  //
2445  // 1. Asm parser extensions. For example, platform-specific parsers
2446  //    (like the ELF parser) register themselves as extensions.
2447  // 2. The generic directive parser implemented by this class. These are
2448  //    all the directives that behave in a target and platform independent
2449  //    manner, or at least have a default behavior that's shared between
2450  //    all targets and platforms.
2451
2452  getTargetParser().flushPendingInstructions(getStreamer());
2453
2454  // Special-case handling of structure-end directives at higher priority, since
2455  // ENDS is overloaded as a segment-end directive.
2456  if (nextVal.equals_lower("ends") && StructInProgress.size() == 1) {
2457    Lex();
2458    return parseDirectiveEnds(IDVal, IDLoc);
2459  }
2460
2461  // First, check the extension directive map to see if any extension has
2462  // registered itself to parse this directive.
2463  std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
2464      ExtensionDirectiveMap.lookup(nextVal.lower());
2465  if (Handler.first) {
2466    Lex();
2467    Lexer.UnLex(ID);
2468    return (*Handler.second)(Handler.first, nextVal, nextLoc);
2469  }
2470
2471  // If no one else is interested in this directive, it must be
2472  // generic and familiar to this class.
2473  DirKindIt = DirectiveKindMap.find(nextVal.lower());
2474  DirKind = (DirKindIt == DirectiveKindMap.end())
2475                ? DK_NO_DIRECTIVE
2476                : DirKindIt->getValue();
2477  switch (DirKind) {
2478  default:
2479    break;
2480  case DK_ASSIGN:
2481  case DK_EQU:
2482  case DK_TEXTEQU:
2483    Lex();
2484    return parseDirectiveEquate(nextVal, IDVal, DirKind);
2485  case DK_BYTE:
2486  case DK_SBYTE:
2487  case DK_DB:
2488    Lex();
2489    return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
2490  case DK_WORD:
2491  case DK_SWORD:
2492  case DK_DW:
2493    Lex();
2494    return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
2495  case DK_DWORD:
2496  case DK_SDWORD:
2497  case DK_DD:
2498    Lex();
2499    return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
2500  case DK_FWORD:
2501  case DK_DF:
2502    Lex();
2503    return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
2504  case DK_QWORD:
2505  case DK_SQWORD:
2506  case DK_DQ:
2507    Lex();
2508    return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
2509  case DK_REAL4:
2510    Lex();
2511    return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
2512                                        IDVal, IDLoc);
2513  case DK_REAL8:
2514    Lex();
2515    return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
2516                                        IDVal, IDLoc);
2517  case DK_REAL10:
2518    Lex();
2519    return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
2520                                        10, IDVal, IDLoc);
2521  case DK_STRUCT:
2522  case DK_UNION:
2523    Lex();
2524    return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
2525  case DK_ENDS:
2526    Lex();
2527    return parseDirectiveEnds(IDVal, IDLoc);
2528  case DK_MACRO:
2529    Lex();
2530    return parseDirectiveMacro(IDVal, IDLoc);
2531  }
2532
2533  // Finally, we check if this is allocating a variable with user-defined type.
2534  auto NextIt = Structs.find(nextVal.lower());
2535  if (NextIt != Structs.end()) {
2536    Lex();
2537    return parseDirectiveNamedStructValue(/*Structure=*/NextIt->getValue(),
2538                                          nextVal, nextLoc, IDVal);
2539  }
2540
2541  // __asm _emit or __asm __emit
2542  if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2543                             IDVal == "_EMIT" || IDVal == "__EMIT"))
2544    return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2545
2546  // __asm align
2547  if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2548    return parseDirectiveMSAlign(IDLoc, Info);
2549
2550  if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2551    Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2552  if (checkForValidSection())
2553    return true;
2554
2555  // Canonicalize the opcode to lower case.
2556  std::string OpcodeStr = IDVal.lower();
2557  ParseInstructionInfo IInfo(Info.AsmRewrites);
2558  bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
2559                                                          Info.ParsedOperands);
2560  Info.ParseError = ParseHadError;
2561
2562  // Dump the parsed representation, if requested.
2563  if (getShowParsedOperands()) {
2564    SmallString<256> Str;
2565    raw_svector_ostream OS(Str);
2566    OS << "parsed instruction: [";
2567    for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2568      if (i != 0)
2569        OS << ", ";
2570      Info.ParsedOperands[i]->print(OS);
2571    }
2572    OS << "]";
2573
2574    printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
2575  }
2576
2577  // Fail even if ParseInstruction erroneously returns false.
2578  if (hasPendingError() || ParseHadError)
2579    return true;
2580
2581  // If we are generating dwarf for the current section then generate a .loc
2582  // directive for the instruction.
2583  if (!ParseHadError && enabledGenDwarfForAssembly() &&
2584      getContext().getGenDwarfSectionSyms().count(
2585          getStreamer().getCurrentSectionOnly())) {
2586    unsigned Line;
2587    if (ActiveMacros.empty())
2588      Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
2589    else
2590      Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
2591                                   ActiveMacros.front()->ExitBuffer);
2592
2593    // If we previously parsed a cpp hash file line comment then make sure the
2594    // current Dwarf File is for the CppHashFilename if not then emit the
2595    // Dwarf File table for it and adjust the line number for the .loc.
2596    if (!CppHashInfo.Filename.empty()) {
2597      unsigned FileNumber = getStreamer().emitDwarfFileDirective(
2598          0, StringRef(), CppHashInfo.Filename);
2599      getContext().setGenDwarfFileNumber(FileNumber);
2600
2601      unsigned CppHashLocLineNo =
2602        SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
2603      Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2604    }
2605
2606    getStreamer().emitDwarfLocDirective(
2607        getContext().getGenDwarfFileNumber(), Line, 0,
2608        DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0,
2609        StringRef());
2610  }
2611
2612  // If parsing succeeded, match the instruction.
2613  if (!ParseHadError) {
2614    uint64_t ErrorInfo;
2615    if (getTargetParser().MatchAndEmitInstruction(
2616            IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
2617            getTargetParser().isParsingMSInlineAsm()))
2618      return true;
2619  }
2620  return false;
2621}
2622
2623// Parse and erase curly braces marking block start/end.
2624bool MasmParser::parseCurlyBlockScope(
2625    SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
2626  // Identify curly brace marking block start/end.
2627  if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
2628    return false;
2629
2630  SMLoc StartLoc = Lexer.getLoc();
2631  Lex(); // Eat the brace.
2632  if (Lexer.is(AsmToken::EndOfStatement))
2633    Lex(); // Eat EndOfStatement following the brace.
2634
2635  // Erase the block start/end brace from the output asm string.
2636  AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
2637                                                  StartLoc.getPointer());
2638  return true;
2639}
2640
2641/// parseCppHashLineFilenameComment as this:
2642///   ::= # number "filename"
2643bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) {
2644  Lex(); // Eat the hash token.
2645  // Lexer only ever emits HashDirective if it fully formed if it's
2646  // done the checking already so this is an internal error.
2647  assert(getTok().is(AsmToken::Integer) &&
2648         "Lexing Cpp line comment: Expected Integer");
2649  int64_t LineNumber = getTok().getIntVal();
2650  Lex();
2651  assert(getTok().is(AsmToken::String) &&
2652         "Lexing Cpp line comment: Expected String");
2653  StringRef Filename = getTok().getString();
2654  Lex();
2655
2656  // Get rid of the enclosing quotes.
2657  Filename = Filename.substr(1, Filename.size() - 2);
2658
2659  // Save the SMLoc, Filename and LineNumber for later use by diagnostics
2660  // and possibly DWARF file info.
2661  CppHashInfo.Loc = L;
2662  CppHashInfo.Filename = Filename;
2663  CppHashInfo.LineNumber = LineNumber;
2664  CppHashInfo.Buf = CurBuffer;
2665  if (FirstCppHashFilename.empty())
2666    FirstCppHashFilename = Filename;
2667  return false;
2668}
2669
2670/// will use the last parsed cpp hash line filename comment
2671/// for the Filename and LineNo if any in the diagnostic.
2672void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2673  const MasmParser *Parser = static_cast<const MasmParser *>(Context);
2674  raw_ostream &OS = errs();
2675
2676  const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
2677  SMLoc DiagLoc = Diag.getLoc();
2678  unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2679  unsigned CppHashBuf =
2680      Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2681
2682  // Like SourceMgr::printMessage() we need to print the include stack if any
2683  // before printing the message.
2684  unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2685  if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2686      DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
2687    SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
2688    DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
2689  }
2690
2691  // If we have not parsed a cpp hash line filename comment or the source
2692  // manager changed or buffer changed (like in a nested include) then just
2693  // print the normal diagnostic using its Filename and LineNo.
2694  if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2695      DiagBuf != CppHashBuf) {
2696    if (Parser->SavedDiagHandler)
2697      Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2698    else
2699      Diag.print(nullptr, OS);
2700    return;
2701  }
2702
2703  // Use the CppHashFilename and calculate a line number based on the
2704  // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
2705  // for the diagnostic.
2706  const std::string &Filename = std::string(Parser->CppHashInfo.Filename);
2707
2708  int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2709  int CppHashLocLineNo =
2710      Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2711  int LineNo =
2712      Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2713
2714  SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
2715                       Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
2716                       Diag.getLineContents(), Diag.getRanges());
2717
2718  if (Parser->SavedDiagHandler)
2719    Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2720  else
2721    NewDiag.print(nullptr, OS);
2722}
2723
2724// This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does
2725// not accept '.'.
2726static bool isMacroParameterChar(char C) {
2727  return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?';
2728}
2729
2730bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
2731                             ArrayRef<MCAsmMacroParameter> Parameters,
2732                             ArrayRef<MCAsmMacroArgument> A,
2733                             const std::vector<std::string> &Locals, SMLoc L) {
2734  unsigned NParameters = Parameters.size();
2735  if (NParameters != A.size())
2736    return Error(L, "Wrong number of arguments");
2737  StringMap<std::string> LocalSymbols;
2738  std::string Name;
2739  Name.reserve(6);
2740  for (StringRef Local : Locals) {
2741    raw_string_ostream LocalName(Name);
2742    LocalName << "??"
2743              << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true);
2744    LocalSymbols.insert({Local, LocalName.str()});
2745    Name.clear();
2746  }
2747
2748  Optional<char> CurrentQuote;
2749  while (!Body.empty()) {
2750    // Scan for the next substitution.
2751    std::size_t End = Body.size(), Pos = 0;
2752    std::size_t IdentifierPos = End;
2753    for (; Pos != End; ++Pos) {
2754      // Find the next possible macro parameter, including preceding a '&'
2755      // inside quotes.
2756      if (Body[Pos] == '&')
2757        break;
2758      if (isMacroParameterChar(Body[Pos])) {
2759        if (!CurrentQuote.hasValue())
2760          break;
2761        if (IdentifierPos == End)
2762          IdentifierPos = Pos;
2763      } else {
2764        IdentifierPos = End;
2765      }
2766
2767      // Track quotation status
2768      if (!CurrentQuote.hasValue()) {
2769        if (Body[Pos] == '\'' || Body[Pos] == '"')
2770          CurrentQuote = Body[Pos];
2771      } else if (Body[Pos] == CurrentQuote) {
2772        if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {
2773          // Escaped quote, and quotes aren't identifier chars; skip
2774          ++Pos;
2775          continue;
2776        } else {
2777          CurrentQuote.reset();
2778        }
2779      }
2780    }
2781    if (IdentifierPos != End) {
2782      // We've recognized an identifier before an apostrophe inside quotes;
2783      // check once to see if we can expand it.
2784      Pos = IdentifierPos;
2785      IdentifierPos = End;
2786    }
2787
2788    // Add the prefix.
2789    OS << Body.slice(0, Pos);
2790
2791    // Check if we reached the end.
2792    if (Pos == End)
2793      break;
2794
2795    unsigned I = Pos;
2796    bool InitialAmpersand = (Body[I] == '&');
2797    if (InitialAmpersand) {
2798      ++I;
2799      ++Pos;
2800    }
2801    while (I < End && isMacroParameterChar(Body[I]))
2802      ++I;
2803
2804    const char *Begin = Body.data() + Pos;
2805    StringRef Argument(Begin, I - Pos);
2806    unsigned Index = 0;
2807
2808    for (; Index < NParameters; ++Index)
2809      if (Parameters[Index].Name == Argument)
2810        break;
2811
2812    if (Index == NParameters) {
2813      if (InitialAmpersand)
2814        OS << '&';
2815      auto it = LocalSymbols.find(Argument.lower());
2816      if (it != LocalSymbols.end())
2817        OS << it->second;
2818      else
2819        OS << Argument;
2820      Pos = I;
2821    } else {
2822      for (const AsmToken &Token : A[Index]) {
2823        // In MASM, you can write '%expr'.
2824        // The prefix '%' evaluates the expression 'expr'
2825        // and uses the result as a string (e.g. replace %(1+2) with the
2826        // string "3").
2827        // Here, we identify the integer token which is the result of the
2828        // absolute expression evaluation and replace it with its string
2829        // representation.
2830        if (Token.getString().front() == '%' && Token.is(AsmToken::Integer))
2831          // Emit an integer value to the buffer.
2832          OS << Token.getIntVal();
2833        else
2834          OS << Token.getString();
2835      }
2836
2837      Pos += Argument.size();
2838      if (Pos < End && Body[Pos] == '&') {
2839        ++Pos;
2840      }
2841    }
2842    // Update the scan point.
2843    Body = Body.substr(Pos);
2844  }
2845
2846  return false;
2847}
2848
2849static bool isOperator(AsmToken::TokenKind kind) {
2850  switch (kind) {
2851  default:
2852    return false;
2853  case AsmToken::Plus:
2854  case AsmToken::Minus:
2855  case AsmToken::Tilde:
2856  case AsmToken::Slash:
2857  case AsmToken::Star:
2858  case AsmToken::Dot:
2859  case AsmToken::Equal:
2860  case AsmToken::EqualEqual:
2861  case AsmToken::Pipe:
2862  case AsmToken::PipePipe:
2863  case AsmToken::Caret:
2864  case AsmToken::Amp:
2865  case AsmToken::AmpAmp:
2866  case AsmToken::Exclaim:
2867  case AsmToken::ExclaimEqual:
2868  case AsmToken::Less:
2869  case AsmToken::LessEqual:
2870  case AsmToken::LessLess:
2871  case AsmToken::LessGreater:
2872  case AsmToken::Greater:
2873  case AsmToken::GreaterEqual:
2874  case AsmToken::GreaterGreater:
2875    return true;
2876  }
2877}
2878
2879namespace {
2880
2881class AsmLexerSkipSpaceRAII {
2882public:
2883  AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2884    Lexer.setSkipSpace(SkipSpace);
2885  }
2886
2887  ~AsmLexerSkipSpaceRAII() {
2888    Lexer.setSkipSpace(true);
2889  }
2890
2891private:
2892  AsmLexer &Lexer;
2893};
2894
2895} // end anonymous namespace
2896
2897bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
2898                                    MCAsmMacroArgument &MA,
2899                                    AsmToken::TokenKind EndTok) {
2900  if (MP && MP->Vararg) {
2901    if (Lexer.isNot(EndTok)) {
2902      SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok);
2903      for (StringRef S : Str) {
2904        MA.emplace_back(AsmToken::String, S);
2905      }
2906    }
2907    return false;
2908  }
2909
2910  SMLoc StrLoc = Lexer.getLoc(), EndLoc;
2911  if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) {
2912    const char *StrChar = StrLoc.getPointer() + 1;
2913    const char *EndChar = EndLoc.getPointer() - 1;
2914    jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
2915    /// Eat from '<' to '>'.
2916    Lex();
2917    MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
2918    return false;
2919  }
2920
2921  unsigned ParenLevel = 0;
2922
2923  // Darwin doesn't use spaces to delmit arguments.
2924  AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2925
2926  bool SpaceEaten;
2927
2928  while (true) {
2929    SpaceEaten = false;
2930    if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
2931      return TokError("unexpected token");
2932
2933    if (ParenLevel == 0) {
2934      if (Lexer.is(AsmToken::Comma))
2935        break;
2936
2937      if (Lexer.is(AsmToken::Space)) {
2938        SpaceEaten = true;
2939        Lex(); // Eat spaces.
2940      }
2941
2942      // Spaces can delimit parameters, but could also be part an expression.
2943      // If the token after a space is an operator, add the token and the next
2944      // one into this argument
2945      if (!IsDarwin) {
2946        if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) {
2947          MA.push_back(getTok());
2948          Lex();
2949
2950          // Whitespace after an operator can be ignored.
2951          if (Lexer.is(AsmToken::Space))
2952            Lex();
2953
2954          continue;
2955        }
2956      }
2957      if (SpaceEaten)
2958        break;
2959    }
2960
2961    // handleMacroEntry relies on not advancing the lexer here
2962    // to be able to fill in the remaining default parameter values
2963    if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0))
2964      break;
2965
2966    // Adjust the current parentheses level.
2967    if (Lexer.is(AsmToken::LParen))
2968      ++ParenLevel;
2969    else if (Lexer.is(AsmToken::RParen) && ParenLevel)
2970      --ParenLevel;
2971
2972    // Append the token to the current argument list.
2973    MA.push_back(getTok());
2974    Lex();
2975  }
2976
2977  if (ParenLevel != 0)
2978    return TokError("unbalanced parentheses in argument");
2979
2980  if (MA.empty() && MP) {
2981    if (MP->Required) {
2982      return TokError("missing value for required parameter '" + MP->Name +
2983                      "'");
2984    } else {
2985      MA = MP->Value;
2986    }
2987  }
2988  return false;
2989}
2990
2991// Parse the macro instantiation arguments.
2992bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
2993                                     MCAsmMacroArguments &A,
2994                                     AsmToken::TokenKind EndTok) {
2995  const unsigned NParameters = M ? M->Parameters.size() : 0;
2996  bool NamedParametersFound = false;
2997  SmallVector<SMLoc, 4> FALocs;
2998
2999  A.resize(NParameters);
3000  FALocs.resize(NParameters);
3001
3002  // Parse two kinds of macro invocations:
3003  // - macros defined without any parameters accept an arbitrary number of them
3004  // - macros defined with parameters accept at most that many of them
3005  for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
3006       ++Parameter) {
3007    SMLoc IDLoc = Lexer.getLoc();
3008    MCAsmMacroParameter FA;
3009
3010    if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
3011      if (parseIdentifier(FA.Name))
3012        return Error(IDLoc, "invalid argument identifier for formal argument");
3013
3014      if (Lexer.isNot(AsmToken::Equal))
3015        return TokError("expected '=' after formal parameter identifier");
3016
3017      Lex();
3018
3019      NamedParametersFound = true;
3020    }
3021
3022    if (NamedParametersFound && FA.Name.empty())
3023      return Error(IDLoc, "cannot mix positional and keyword arguments");
3024
3025    unsigned PI = Parameter;
3026    if (!FA.Name.empty()) {
3027      assert(M && "expected macro to be defined");
3028      unsigned FAI = 0;
3029      for (FAI = 0; FAI < NParameters; ++FAI)
3030        if (M->Parameters[FAI].Name == FA.Name)
3031          break;
3032
3033      if (FAI >= NParameters) {
3034        return Error(IDLoc, "parameter named '" + FA.Name +
3035                                "' does not exist for macro '" + M->Name + "'");
3036      }
3037      PI = FAI;
3038    }
3039    const MCAsmMacroParameter *MP = nullptr;
3040    if (M && PI < NParameters)
3041      MP = &M->Parameters[PI];
3042
3043    SMLoc StrLoc = Lexer.getLoc();
3044    SMLoc EndLoc;
3045    if (Lexer.is(AsmToken::Percent)) {
3046      const MCExpr *AbsoluteExp;
3047      int64_t Value;
3048      /// Eat '%'.
3049      Lex();
3050      if (parseExpression(AbsoluteExp, EndLoc))
3051        return false;
3052      if (!AbsoluteExp->evaluateAsAbsolute(Value,
3053                                           getStreamer().getAssemblerPtr()))
3054        return Error(StrLoc, "expected absolute expression");
3055      const char *StrChar = StrLoc.getPointer();
3056      const char *EndChar = EndLoc.getPointer();
3057      AsmToken newToken(AsmToken::Integer,
3058                        StringRef(StrChar, EndChar - StrChar), Value);
3059      FA.Value.push_back(newToken);
3060    } else if (parseMacroArgument(MP, FA.Value, EndTok)) {
3061      if (M)
3062        return addErrorSuffix(" in '" + M->Name + "' macro");
3063      else
3064        return true;
3065    }
3066
3067    if (!FA.Value.empty()) {
3068      if (A.size() <= PI)
3069        A.resize(PI + 1);
3070      A[PI] = FA.Value;
3071
3072      if (FALocs.size() <= PI)
3073        FALocs.resize(PI + 1);
3074
3075      FALocs[PI] = Lexer.getLoc();
3076    }
3077
3078    // At the end of the statement, fill in remaining arguments that have
3079    // default values. If there aren't any, then the next argument is
3080    // required but missing
3081    if (Lexer.is(EndTok)) {
3082      bool Failure = false;
3083      for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
3084        if (A[FAI].empty()) {
3085          if (M->Parameters[FAI].Required) {
3086            Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
3087                  "missing value for required parameter "
3088                  "'" +
3089                      M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
3090            Failure = true;
3091          }
3092
3093          if (!M->Parameters[FAI].Value.empty())
3094            A[FAI] = M->Parameters[FAI].Value;
3095        }
3096      }
3097      return Failure;
3098    }
3099
3100    if (Lexer.is(AsmToken::Comma))
3101      Lex();
3102  }
3103
3104  return TokError("too many positional arguments");
3105}
3106
3107bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
3108                                  AsmToken::TokenKind ArgumentEndTok) {
3109  // Arbitrarily limit macro nesting depth (default matches 'as'). We can
3110  // eliminate this, although we should protect against infinite loops.
3111  unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
3112  if (ActiveMacros.size() == MaxNestingDepth) {
3113    std::ostringstream MaxNestingDepthError;
3114    MaxNestingDepthError << "macros cannot be nested more than "
3115                         << MaxNestingDepth << " levels deep."
3116                         << " Use -asm-macro-max-nesting-depth to increase "
3117                            "this limit.";
3118    return TokError(MaxNestingDepthError.str());
3119  }
3120
3121  MCAsmMacroArguments A;
3122  if (parseMacroArguments(M, A, ArgumentEndTok))
3123    return true;
3124
3125  // Macro instantiation is lexical, unfortunately. We construct a new buffer
3126  // to hold the macro body with substitutions.
3127  SmallString<256> Buf;
3128  StringRef Body = M->Body;
3129  raw_svector_ostream OS(Buf);
3130
3131  if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc()))
3132    return true;
3133
3134  // We include the endm in the buffer as our cue to exit the macro
3135  // instantiation.
3136  OS << "endm\n";
3137
3138  std::unique_ptr<MemoryBuffer> Instantiation =
3139      MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
3140
3141  // Create the macro instantiation object and add to the current macro
3142  // instantiation stack.
3143  MacroInstantiation *MI = new MacroInstantiation{
3144      NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
3145  ActiveMacros.push_back(MI);
3146
3147  ++NumOfMacroInstantiations;
3148
3149  // Jump to the macro instantiation and prime the lexer.
3150  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
3151  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
3152  EndStatementAtEOFStack.push_back(true);
3153  Lex();
3154
3155  return false;
3156}
3157
3158void MasmParser::handleMacroExit() {
3159  // Jump to the token we should return to, and consume it.
3160  EndStatementAtEOFStack.pop_back();
3161  jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
3162            EndStatementAtEOFStack.back());
3163  Lex();
3164
3165  // Pop the instantiation entry.
3166  delete ActiveMacros.back();
3167  ActiveMacros.pop_back();
3168}
3169
3170bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) {
3171  if (!M->IsFunction)
3172    return Error(NameLoc, "cannot invoke macro procedure as function");
3173
3174  if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name +
3175                                       "' requires arguments in parentheses") ||
3176      handleMacroEntry(M, NameLoc, AsmToken::RParen))
3177    return true;
3178
3179  // Parse all statements in the macro, retrieving the exit value when it ends.
3180  std::string ExitValue;
3181  SmallVector<AsmRewrite, 4> AsmStrRewrites;
3182  while (Lexer.isNot(AsmToken::Eof)) {
3183    ParseStatementInfo Info(&AsmStrRewrites);
3184    bool Parsed = parseStatement(Info, nullptr);
3185
3186    if (!Parsed && Info.ExitValue.hasValue()) {
3187      ExitValue = std::move(*Info.ExitValue);
3188      break;
3189    }
3190
3191    // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
3192    // for printing ErrMsg via Lex() only if no (presumably better) parser error
3193    // exists.
3194    if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
3195      Lex();
3196    }
3197
3198    // parseStatement returned true so may need to emit an error.
3199    printPendingErrors();
3200
3201    // Skipping to the next line if needed.
3202    if (Parsed && !getLexer().isAtStartOfStatement())
3203      eatToEndOfStatement();
3204  }
3205
3206  // Consume the right-parenthesis on the other side of the arguments.
3207  if (parseToken(AsmToken::RParen, "invoking macro function '" + M->Name +
3208                                       "' requires arguments in parentheses"))
3209    return true;
3210
3211  // Exit values may require lexing, unfortunately. We construct a new buffer to
3212  // hold the exit value.
3213  std::unique_ptr<MemoryBuffer> MacroValue =
3214      MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>");
3215
3216  // Jump from this location to the instantiated exit value, and prime the
3217  // lexer.
3218  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc());
3219  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
3220                  /*EndStatementAtEOF=*/false);
3221  EndStatementAtEOFStack.push_back(false);
3222  Lex();
3223
3224  return false;
3225}
3226
3227/// parseIdentifier:
3228///   ::= identifier
3229///   ::= string
3230bool MasmParser::parseIdentifier(StringRef &Res) {
3231  // The assembler has relaxed rules for accepting identifiers, in particular we
3232  // allow things like '.globl $foo' and '.def @feat.00', which would normally
3233  // be separate tokens. At this level, we have already lexed so we cannot
3234  // (currently) handle this as a context dependent token, instead we detect
3235  // adjacent tokens and return the combined identifier.
3236  if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
3237    SMLoc PrefixLoc = getLexer().getLoc();
3238
3239    // Consume the prefix character, and check for a following identifier.
3240
3241    AsmToken Buf[1];
3242    Lexer.peekTokens(Buf, false);
3243
3244    if (Buf[0].isNot(AsmToken::Identifier))
3245      return true;
3246
3247    // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
3248    if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
3249      return true;
3250
3251    // eat $ or @
3252    Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
3253    // Construct the joined identifier and consume the token.
3254    Res =
3255        StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
3256    Lex(); // Parser Lex to maintain invariants.
3257    return false;
3258  }
3259
3260  if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
3261    return true;
3262
3263  Res = getTok().getIdentifier();
3264
3265  Lex(); // Consume the identifier token.
3266
3267  return false;
3268}
3269
3270/// parseDirectiveEquate:
3271///  ::= name "=" expression
3272///    | name "equ" expression    (not redefinable)
3273///    | name "equ" text-list
3274///    | name "textequ" text-list
3275bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
3276                                      DirectiveKind DirKind) {
3277  Variable &Var = Variables[Name.lower()];
3278  if (Var.Name.empty()) {
3279    Var.Name = Name;
3280  } else if (!Var.Redefinable) {
3281    return TokError("invalid variable redefinition");
3282  }
3283  Var.Redefinable = (DirKind != DK_EQU);
3284
3285  SMLoc StartLoc = Lexer.getLoc();
3286  if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
3287    // "equ" and "textequ" both allow text expressions.
3288    std::string Value;
3289    if (!parseTextItem(Value)) {
3290      Var.IsText = true;
3291      Var.TextValue = Value;
3292
3293      // Accept a text-list, not just one text-item.
3294      auto parseItem = [&]() -> bool {
3295        if (parseTextItem(Value))
3296          return TokError("expected text item");
3297        Var.TextValue += Value;
3298        return false;
3299      };
3300      if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem))
3301        return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3302
3303      return false;
3304    }
3305  }
3306  if (DirKind == DK_TEXTEQU)
3307    return TokError("expected <text> in '" + Twine(IDVal) + "' directive");
3308
3309  // Parse as expression assignment.
3310  const MCExpr *Expr;
3311  SMLoc EndLoc;
3312  if (parseExpression(Expr, EndLoc))
3313    return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3314  MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
3315  Sym->setRedefinable(Var.Redefinable);
3316  Sym->setVariableValue(Expr);
3317  Sym->setExternal(false);
3318
3319  if (Expr->evaluateAsAbsolute(Var.NumericValue,
3320                               getStreamer().getAssemblerPtr()))
3321    return false;
3322
3323  // Not an absolute expression; define as a text replacement.
3324  Var.IsText = true;
3325  Var.TextValue = StringRef(StartLoc.getPointer(),
3326                            EndLoc.getPointer() - StartLoc.getPointer()).str();
3327  return false;
3328}
3329
3330bool MasmParser::parseEscapedString(std::string &Data) {
3331  if (check(getTok().isNot(AsmToken::String), "expected string"))
3332    return true;
3333
3334  Data = "";
3335  char Quote = getTok().getString().front();
3336  StringRef Str = getTok().getStringContents();
3337  Data.reserve(Str.size());
3338  for (size_t i = 0, e = Str.size(); i != e; ++i) {
3339    Data.push_back(Str[i]);
3340    if (Str[i] == Quote) {
3341      // MASM treats doubled delimiting quotes as an escaped delimiting quote.
3342      // If we're escaping the string's trailing delimiter, we're definitely
3343      // missing a quotation mark.
3344      if (i + 1 == Str.size())
3345        return Error(getTok().getLoc(), "missing quotation mark in string");
3346      if (Str[i + 1] == Quote)
3347        ++i;
3348    }
3349  }
3350
3351  Lex();
3352  return false;
3353}
3354
3355bool MasmParser::parseAngleBracketString(std::string &Data) {
3356  SMLoc EndLoc, StartLoc = getTok().getLoc();
3357  if (isAngleBracketString(StartLoc, EndLoc)) {
3358    const char *StartChar = StartLoc.getPointer() + 1;
3359    const char *EndChar = EndLoc.getPointer() - 1;
3360    jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
3361    // Eat from '<' to '>'.
3362    Lex();
3363
3364    Data = angleBracketString(StringRef(StartChar, EndChar - StartChar));
3365    return false;
3366  }
3367  return true;
3368}
3369
3370/// textItem ::= textLiteral | textMacroID | % constExpr
3371bool MasmParser::parseTextItem(std::string &Data) {
3372  switch (getTok().getKind()) {
3373  default:
3374    return true;
3375  case AsmToken::Percent: {
3376    int64_t Res;
3377    if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))
3378      return true;
3379    Data = std::to_string(Res);
3380    return false;
3381  }
3382  case AsmToken::Less:
3383  case AsmToken::LessEqual:
3384  case AsmToken::LessLess:
3385  case AsmToken::LessGreater:
3386    return parseAngleBracketString(Data);
3387  case AsmToken::Identifier: {
3388    // This must be a text macro; we need to expand it accordingly.
3389    StringRef ID;
3390    if (parseIdentifier(ID))
3391      return true;
3392    Data = ID.str();
3393
3394    auto it = Variables.find(ID.lower());
3395    if (it == Variables.end()) {
3396      // Not a variable; since we haven't used the token, put it back for better
3397      // error recovery.
3398      getLexer().UnLex(AsmToken(AsmToken::Identifier, ID));
3399      return true;
3400    }
3401
3402    while (it != Variables.end()) {
3403      const Variable &Var = it->second;
3404      if (!Var.IsText) {
3405        // Not a text macro; not usable in TextItem context. Since we haven't
3406        // used the token, put it back for better error recovery.
3407        getLexer().UnLex(AsmToken(AsmToken::Identifier, ID));
3408        return true;
3409      }
3410      Data = Var.TextValue;
3411      it = Variables.find(StringRef(Data).lower());
3412    }
3413    return false;
3414  }
3415  }
3416  llvm_unreachable("unhandled token kind");
3417}
3418
3419/// parseDirectiveAscii:
3420///   ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
3421bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
3422  auto parseOp = [&]() -> bool {
3423    std::string Data;
3424    if (checkForValidSection() || parseEscapedString(Data))
3425      return true;
3426    getStreamer().emitBytes(Data);
3427    if (ZeroTerminated)
3428      getStreamer().emitBytes(StringRef("\0", 1));
3429    return false;
3430  };
3431
3432  if (parseMany(parseOp))
3433    return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3434  return false;
3435}
3436
3437bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) {
3438  // Special case constant expressions to match code generator.
3439  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3440    assert(Size <= 8 && "Invalid size");
3441    int64_t IntValue = MCE->getValue();
3442    if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
3443      return Error(MCE->getLoc(), "out of range literal value");
3444    getStreamer().emitIntValue(IntValue, Size);
3445  } else {
3446    const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value);
3447    if (MSE && MSE->getSymbol().getName() == "?") {
3448      // ? initializer; treat as 0.
3449      getStreamer().emitIntValue(0, Size);
3450    } else {
3451      getStreamer().emitValue(Value, Size, Value->getLoc());
3452    }
3453  }
3454  return false;
3455}
3456
3457bool MasmParser::parseScalarInitializer(unsigned Size,
3458                                        SmallVectorImpl<const MCExpr *> &Values,
3459                                        unsigned StringPadLength) {
3460  if (Size == 1 && getTok().is(AsmToken::String)) {
3461    std::string Value;
3462    if (parseEscapedString(Value))
3463      return true;
3464    // Treat each character as an initializer.
3465    for (const unsigned char CharVal : Value)
3466      Values.push_back(MCConstantExpr::create(CharVal, getContext()));
3467
3468    // Pad the string with spaces to the specified length.
3469    for (size_t i = Value.size(); i < StringPadLength; ++i)
3470      Values.push_back(MCConstantExpr::create(' ', getContext()));
3471  } else {
3472    const MCExpr *Value;
3473    if (parseExpression(Value))
3474      return true;
3475    if (getTok().is(AsmToken::Identifier) &&
3476        getTok().getString().equals_lower("dup")) {
3477      Lex(); // Eat 'dup'.
3478      const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3479      if (!MCE)
3480        return Error(Value->getLoc(),
3481                     "cannot repeat value a non-constant number of times");
3482      const int64_t Repetitions = MCE->getValue();
3483      if (Repetitions < 0)
3484        return Error(Value->getLoc(),
3485                     "cannot repeat value a negative number of times");
3486
3487      SmallVector<const MCExpr *, 1> DuplicatedValues;
3488      if (parseToken(AsmToken::LParen,
3489                     "parentheses required for 'dup' contents") ||
3490          parseScalarInstList(Size, DuplicatedValues) ||
3491          parseToken(AsmToken::RParen, "unmatched parentheses"))
3492        return true;
3493
3494      for (int i = 0; i < Repetitions; ++i)
3495        Values.append(DuplicatedValues.begin(), DuplicatedValues.end());
3496    } else {
3497      Values.push_back(Value);
3498    }
3499  }
3500  return false;
3501}
3502
3503bool MasmParser::parseScalarInstList(unsigned Size,
3504                                     SmallVectorImpl<const MCExpr *> &Values,
3505                                     const AsmToken::TokenKind EndToken) {
3506  while (getTok().isNot(EndToken) &&
3507         (EndToken != AsmToken::Greater ||
3508          getTok().isNot(AsmToken::GreaterGreater))) {
3509    parseScalarInitializer(Size, Values);
3510
3511    // If we see a comma, continue, and allow line continuation.
3512    if (!parseOptionalToken(AsmToken::Comma))
3513      break;
3514    parseOptionalToken(AsmToken::EndOfStatement);
3515  }
3516  return false;
3517}
3518
3519bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {
3520  SmallVector<const MCExpr *, 1> Values;
3521  if (checkForValidSection() || parseScalarInstList(Size, Values))
3522    return true;
3523
3524  for (auto Value : Values) {
3525    emitIntValue(Value, Size);
3526  }
3527  if (Count)
3528    *Count = Values.size();
3529  return false;
3530}
3531
3532// Add a field to the current structure.
3533bool MasmParser::addIntegralField(StringRef Name, unsigned Size) {
3534  StructInfo &Struct = StructInProgress.back();
3535  FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size);
3536  IntFieldInfo &IntInfo = Field.Contents.IntInfo;
3537
3538  Field.Type = Size;
3539
3540  if (parseScalarInstList(Size, IntInfo.Values))
3541    return true;
3542
3543  Field.SizeOf = Field.Type * IntInfo.Values.size();
3544  Field.LengthOf = IntInfo.Values.size();
3545  if (Struct.IsUnion)
3546    Struct.Size = std::max(Struct.Size, Field.SizeOf);
3547  else
3548    Struct.Size += Field.SizeOf;
3549  return false;
3550}
3551
3552/// parseDirectiveValue
3553///  ::= (byte | word | ... ) [ expression (, expression)* ]
3554bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
3555  if (StructInProgress.empty()) {
3556    // Initialize data value.
3557    if (emitIntegralValues(Size))
3558      return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3559  } else if (addIntegralField("", Size)) {
3560    return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3561  }
3562
3563  return false;
3564}
3565
3566/// parseDirectiveNamedValue
3567///  ::= name (byte | word | ... ) [ expression (, expression)* ]
3568bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
3569                                          StringRef Name, SMLoc NameLoc) {
3570  if (StructInProgress.empty()) {
3571    // Initialize named data value.
3572    MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3573    getStreamer().emitLabel(Sym);
3574    unsigned Count;
3575    if (emitIntegralValues(Size, &Count))
3576      return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
3577
3578    AsmTypeInfo Type;
3579    Type.Name = TypeName;
3580    Type.Size = Size * Count;
3581    Type.ElementSize = Size;
3582    Type.Length = Count;
3583    KnownType[Name.lower()] = Type;
3584  } else if (addIntegralField(Name, Size)) {
3585    return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
3586  }
3587
3588  return false;
3589}
3590
3591static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo) {
3592  if (Asm.getTok().isNot(AsmToken::Integer) &&
3593      Asm.getTok().isNot(AsmToken::BigNum))
3594    return Asm.TokError("unknown token in expression");
3595  SMLoc ExprLoc = Asm.getTok().getLoc();
3596  APInt IntValue = Asm.getTok().getAPIntVal();
3597  Asm.Lex();
3598  if (!IntValue.isIntN(128))
3599    return Asm.Error(ExprLoc, "out of range literal value");
3600  if (!IntValue.isIntN(64)) {
3601    hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
3602    lo = IntValue.getLoBits(64).getZExtValue();
3603  } else {
3604    hi = 0;
3605    lo = IntValue.getZExtValue();
3606  }
3607  return false;
3608}
3609
3610bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3611  // We don't truly support arithmetic on floating point expressions, so we
3612  // have to manually parse unary prefixes.
3613  bool IsNeg = false;
3614  SMLoc SignLoc;
3615  if (getLexer().is(AsmToken::Minus)) {
3616    SignLoc = getLexer().getLoc();
3617    Lexer.Lex();
3618    IsNeg = true;
3619  } else if (getLexer().is(AsmToken::Plus)) {
3620    SignLoc = getLexer().getLoc();
3621    Lexer.Lex();
3622  }
3623
3624  if (Lexer.is(AsmToken::Error))
3625    return TokError(Lexer.getErr());
3626  if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
3627      Lexer.isNot(AsmToken::Identifier))
3628    return TokError("unexpected token in directive");
3629
3630  // Convert to an APFloat.
3631  APFloat Value(Semantics);
3632  StringRef IDVal = getTok().getString();
3633  if (getLexer().is(AsmToken::Identifier)) {
3634    if (IDVal.equals_lower("infinity") || IDVal.equals_lower("inf"))
3635      Value = APFloat::getInf(Semantics);
3636    else if (IDVal.equals_lower("nan"))
3637      Value = APFloat::getNaN(Semantics, false, ~0);
3638    else if (IDVal.equals_lower("?"))
3639      Value = APFloat::getZero(Semantics);
3640    else
3641      return TokError("invalid floating point literal");
3642  } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) {
3643    // MASM hexadecimal floating-point literal; no APFloat conversion needed.
3644    // To match ML64.exe, ignore the initial sign.
3645    unsigned SizeInBits = Value.getSizeInBits(Semantics);
3646    if (SizeInBits != (IDVal.size() << 2))
3647      return TokError("invalid floating point literal");
3648
3649    // Consume the numeric token.
3650    Lex();
3651
3652    Res = APInt(SizeInBits, IDVal, 16);
3653    if (SignLoc.isValid())
3654      return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");
3655    return false;
3656  } else if (errorToBool(
3657                 Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
3658                     .takeError())) {
3659    return TokError("invalid floating point literal");
3660  }
3661  if (IsNeg)
3662    Value.changeSign();
3663
3664  // Consume the numeric token.
3665  Lex();
3666
3667  Res = Value.bitcastToAPInt();
3668
3669  return false;
3670}
3671
3672bool MasmParser::parseRealInstList(const fltSemantics &Semantics,
3673                                   SmallVectorImpl<APInt> &ValuesAsInt,
3674                                   const AsmToken::TokenKind EndToken) {
3675  while (getTok().isNot(EndToken) ||
3676         (EndToken == AsmToken::Greater &&
3677          getTok().isNot(AsmToken::GreaterGreater))) {
3678    const AsmToken NextTok = Lexer.peekTok();
3679    if (NextTok.is(AsmToken::Identifier) &&
3680        NextTok.getString().equals_lower("dup")) {
3681      const MCExpr *Value;
3682      if (parseExpression(Value) || parseToken(AsmToken::Identifier))
3683        return true;
3684      const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
3685      if (!MCE)
3686        return Error(Value->getLoc(),
3687                     "cannot repeat value a non-constant number of times");
3688      const int64_t Repetitions = MCE->getValue();
3689      if (Repetitions < 0)
3690        return Error(Value->getLoc(),
3691                     "cannot repeat value a negative number of times");
3692
3693      SmallVector<APInt, 1> DuplicatedValues;
3694      if (parseToken(AsmToken::LParen,
3695                     "parentheses required for 'dup' contents") ||
3696          parseRealInstList(Semantics, DuplicatedValues) ||
3697          parseToken(AsmToken::RParen, "unmatched parentheses"))
3698        return true;
3699
3700      for (int i = 0; i < Repetitions; ++i)
3701        ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end());
3702    } else {
3703      APInt AsInt;
3704      if (parseRealValue(Semantics, AsInt))
3705        return true;
3706      ValuesAsInt.push_back(AsInt);
3707    }
3708
3709    // Continue if we see a comma. (Also, allow line continuation.)
3710    if (!parseOptionalToken(AsmToken::Comma))
3711      break;
3712    parseOptionalToken(AsmToken::EndOfStatement);
3713  }
3714
3715  return false;
3716}
3717
3718// Initialize real data values.
3719bool MasmParser::emitRealValues(const fltSemantics &Semantics,
3720                                unsigned *Count) {
3721  if (checkForValidSection())
3722    return true;
3723
3724  SmallVector<APInt, 1> ValuesAsInt;
3725  if (parseRealInstList(Semantics, ValuesAsInt))
3726    return true;
3727
3728  for (const APInt &AsInt : ValuesAsInt) {
3729    getStreamer().emitIntValue(AsInt);
3730  }
3731  if (Count)
3732    *Count = ValuesAsInt.size();
3733  return false;
3734}
3735
3736// Add a real field to the current struct.
3737bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
3738                              size_t Size) {
3739  StructInfo &Struct = StructInProgress.back();
3740  FieldInfo &Field = Struct.addField(Name, FT_REAL, Size);
3741  RealFieldInfo &RealInfo = Field.Contents.RealInfo;
3742
3743  Field.SizeOf = 0;
3744
3745  if (parseRealInstList(Semantics, RealInfo.AsIntValues))
3746    return true;
3747
3748  Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
3749  Field.LengthOf = RealInfo.AsIntValues.size();
3750  Field.SizeOf = Field.Type * Field.LengthOf;
3751  if (Struct.IsUnion)
3752    Struct.Size = std::max(Struct.Size, Field.SizeOf);
3753  else
3754    Struct.Size += Field.SizeOf;
3755  return false;
3756}
3757
3758/// parseDirectiveRealValue
3759///  ::= (real4 | real8 | real10) [ expression (, expression)* ]
3760bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
3761                                         const fltSemantics &Semantics,
3762                                         size_t Size) {
3763  if (StructInProgress.empty()) {
3764    // Initialize data value.
3765    if (emitRealValues(Semantics))
3766      return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3767  } else if (addRealField("", Semantics, Size)) {
3768    return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3769  }
3770  return false;
3771}
3772
3773/// parseDirectiveNamedRealValue
3774///  ::= name (real4 | real8 | real10) [ expression (, expression)* ]
3775bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,
3776                                              const fltSemantics &Semantics,
3777                                              unsigned Size, StringRef Name,
3778                                              SMLoc NameLoc) {
3779  if (StructInProgress.empty()) {
3780    // Initialize named data value.
3781    MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3782    getStreamer().emitLabel(Sym);
3783    unsigned Count;
3784    if (emitRealValues(Semantics, &Count))
3785      return addErrorSuffix(" in '" + TypeName + "' directive");
3786
3787    AsmTypeInfo Type;
3788    Type.Name = TypeName;
3789    Type.Size = Size * Count;
3790    Type.ElementSize = Size;
3791    Type.Length = Count;
3792    KnownType[Name.lower()] = Type;
3793  } else if (addRealField(Name, Semantics, Size)) {
3794    return addErrorSuffix(" in '" + TypeName + "' directive");
3795  }
3796  return false;
3797}
3798
3799bool MasmParser::parseOptionalAngleBracketOpen() {
3800  const AsmToken Tok = getTok();
3801  if (parseOptionalToken(AsmToken::LessLess)) {
3802    AngleBracketDepth++;
3803    Lexer.UnLex(AsmToken(AsmToken::Less, Tok.getString().substr(1)));
3804    return true;
3805  } else if (parseOptionalToken(AsmToken::LessGreater)) {
3806    AngleBracketDepth++;
3807    Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
3808    return true;
3809  } else if (parseOptionalToken(AsmToken::Less)) {
3810    AngleBracketDepth++;
3811    return true;
3812  }
3813
3814  return false;
3815}
3816
3817bool MasmParser::parseAngleBracketClose(const Twine &Msg) {
3818  const AsmToken Tok = getTok();
3819  if (parseOptionalToken(AsmToken::GreaterGreater)) {
3820    Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
3821  } else if (parseToken(AsmToken::Greater, Msg)) {
3822    return true;
3823  }
3824  AngleBracketDepth--;
3825  return false;
3826}
3827
3828bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3829                                       const IntFieldInfo &Contents,
3830                                       FieldInitializer &Initializer) {
3831  SMLoc Loc = getTok().getLoc();
3832
3833  SmallVector<const MCExpr *, 1> Values;
3834  if (parseOptionalToken(AsmToken::LCurly)) {
3835    if (Field.LengthOf == 1 && Field.Type > 1)
3836      return Error(Loc, "Cannot initialize scalar field with array value");
3837    if (parseScalarInstList(Field.Type, Values, AsmToken::RCurly) ||
3838        parseToken(AsmToken::RCurly))
3839      return true;
3840  } else if (parseOptionalAngleBracketOpen()) {
3841    if (Field.LengthOf == 1 && Field.Type > 1)
3842      return Error(Loc, "Cannot initialize scalar field with array value");
3843    if (parseScalarInstList(Field.Type, Values, AsmToken::Greater) ||
3844        parseAngleBracketClose())
3845      return true;
3846  } else if (Field.LengthOf > 1 && Field.Type > 1) {
3847    return Error(Loc, "Cannot initialize array field with scalar value");
3848  } else if (parseScalarInitializer(Field.Type, Values,
3849                                    /*StringPadLength=*/Field.LengthOf)) {
3850    return true;
3851  }
3852
3853  if (Values.size() > Field.LengthOf) {
3854    return Error(Loc, "Initializer too long for field; expected at most " +
3855                          std::to_string(Field.LengthOf) + " elements, got " +
3856                          std::to_string(Values.size()));
3857  }
3858  // Default-initialize all remaining values.
3859  Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end());
3860
3861  Initializer = FieldInitializer(std::move(Values));
3862  return false;
3863}
3864
3865bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3866                                       const RealFieldInfo &Contents,
3867                                       FieldInitializer &Initializer) {
3868  const fltSemantics *Semantics;
3869  switch (Field.Type) {
3870  case 4:
3871    Semantics = &APFloat::IEEEsingle();
3872    break;
3873  case 8:
3874    Semantics = &APFloat::IEEEdouble();
3875    break;
3876  case 10:
3877    Semantics = &APFloat::x87DoubleExtended();
3878    break;
3879  default:
3880    llvm_unreachable("unknown real field type");
3881  }
3882
3883  SMLoc Loc = getTok().getLoc();
3884
3885  SmallVector<APInt, 1> AsIntValues;
3886  if (parseOptionalToken(AsmToken::LCurly)) {
3887    if (Field.LengthOf == 1)
3888      return Error(Loc, "Cannot initialize scalar field with array value");
3889    if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||
3890        parseToken(AsmToken::RCurly))
3891      return true;
3892  } else if (parseOptionalAngleBracketOpen()) {
3893    if (Field.LengthOf == 1)
3894      return Error(Loc, "Cannot initialize scalar field with array value");
3895    if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||
3896        parseAngleBracketClose())
3897      return true;
3898  } else if (Field.LengthOf > 1) {
3899    return Error(Loc, "Cannot initialize array field with scalar value");
3900  } else {
3901    AsIntValues.emplace_back();
3902    if (parseRealValue(*Semantics, AsIntValues.back()))
3903      return true;
3904  }
3905
3906  if (AsIntValues.size() > Field.LengthOf) {
3907    return Error(Loc, "Initializer too long for field; expected at most " +
3908                          std::to_string(Field.LengthOf) + " elements, got " +
3909                          std::to_string(AsIntValues.size()));
3910  }
3911  // Default-initialize all remaining values.
3912  AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(),
3913                     Contents.AsIntValues.end());
3914
3915  Initializer = FieldInitializer(std::move(AsIntValues));
3916  return false;
3917}
3918
3919bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3920                                       const StructFieldInfo &Contents,
3921                                       FieldInitializer &Initializer) {
3922  SMLoc Loc = getTok().getLoc();
3923
3924  std::vector<StructInitializer> Initializers;
3925  if (Field.LengthOf > 1) {
3926    if (parseOptionalToken(AsmToken::LCurly)) {
3927      if (parseStructInstList(Contents.Structure, Initializers,
3928                              AsmToken::RCurly) ||
3929          parseToken(AsmToken::RCurly))
3930        return true;
3931    } else if (parseOptionalAngleBracketOpen()) {
3932      if (parseStructInstList(Contents.Structure, Initializers,
3933                              AsmToken::Greater) ||
3934          parseAngleBracketClose())
3935        return true;
3936    } else {
3937      return Error(Loc, "Cannot initialize array field with scalar value");
3938    }
3939  } else {
3940    Initializers.emplace_back();
3941    if (parseStructInitializer(Contents.Structure, Initializers.back()))
3942      return true;
3943  }
3944
3945  if (Initializers.size() > Field.LengthOf) {
3946    return Error(Loc, "Initializer too long for field; expected at most " +
3947                          std::to_string(Field.LengthOf) + " elements, got " +
3948                          std::to_string(Initializers.size()));
3949  }
3950  // Default-initialize all remaining values.
3951  Initializers.insert(Initializers.end(),
3952                      Contents.Initializers.begin() + Initializers.size(),
3953                      Contents.Initializers.end());
3954
3955  Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
3956  return false;
3957}
3958
3959bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
3960                                       FieldInitializer &Initializer) {
3961  switch (Field.Contents.FT) {
3962  case FT_INTEGRAL:
3963    return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer);
3964  case FT_REAL:
3965    return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer);
3966  case FT_STRUCT:
3967    return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer);
3968  }
3969  llvm_unreachable("Unhandled FieldType enum");
3970}
3971
3972bool MasmParser::parseStructInitializer(const StructInfo &Structure,
3973                                        StructInitializer &Initializer) {
3974  const AsmToken FirstToken = getTok();
3975
3976  Optional<AsmToken::TokenKind> EndToken;
3977  if (parseOptionalToken(AsmToken::LCurly)) {
3978    EndToken = AsmToken::RCurly;
3979  } else if (parseOptionalAngleBracketOpen()) {
3980    EndToken = AsmToken::Greater;
3981    AngleBracketDepth++;
3982  } else if (FirstToken.is(AsmToken::Identifier) &&
3983             FirstToken.getString() == "?") {
3984    // ? initializer; leave EndToken uninitialized to treat as empty.
3985    if (parseToken(AsmToken::Identifier))
3986      return true;
3987  } else {
3988    return Error(FirstToken.getLoc(), "Expected struct initializer");
3989  }
3990
3991  auto &FieldInitializers = Initializer.FieldInitializers;
3992  size_t FieldIndex = 0;
3993  if (EndToken.hasValue()) {
3994    // Initialize all fields with given initializers.
3995    while (getTok().isNot(EndToken.getValue()) &&
3996           FieldIndex < Structure.Fields.size()) {
3997      const FieldInfo &Field = Structure.Fields[FieldIndex++];
3998      if (parseOptionalToken(AsmToken::Comma)) {
3999        // Empty initializer; use the default and continue. (Also, allow line
4000        // continuation.)
4001        FieldInitializers.push_back(Field.Contents);
4002        parseOptionalToken(AsmToken::EndOfStatement);
4003        continue;
4004      }
4005      FieldInitializers.emplace_back(Field.Contents.FT);
4006      if (parseFieldInitializer(Field, FieldInitializers.back()))
4007        return true;
4008
4009      // Continue if we see a comma. (Also, allow line continuation.)
4010      SMLoc CommaLoc = getTok().getLoc();
4011      if (!parseOptionalToken(AsmToken::Comma))
4012        break;
4013      if (FieldIndex == Structure.Fields.size())
4014        return Error(CommaLoc, "'" + Structure.Name +
4015                                   "' initializer initializes too many fields");
4016      parseOptionalToken(AsmToken::EndOfStatement);
4017    }
4018  }
4019  // Default-initialize all remaining fields.
4020  for (auto It = Structure.Fields.begin() + FieldIndex;
4021       It != Structure.Fields.end(); ++It) {
4022    const FieldInfo &Field = *It;
4023    FieldInitializers.push_back(Field.Contents);
4024  }
4025
4026  if (EndToken.hasValue()) {
4027    if (EndToken.getValue() == AsmToken::Greater)
4028      return parseAngleBracketClose();
4029
4030    return parseToken(EndToken.getValue());
4031  }
4032
4033  return false;
4034}
4035
4036bool MasmParser::parseStructInstList(
4037    const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
4038    const AsmToken::TokenKind EndToken) {
4039  while (getTok().isNot(EndToken) ||
4040         (EndToken == AsmToken::Greater &&
4041          getTok().isNot(AsmToken::GreaterGreater))) {
4042    const AsmToken NextTok = Lexer.peekTok();
4043    if (NextTok.is(AsmToken::Identifier) &&
4044        NextTok.getString().equals_lower("dup")) {
4045      const MCExpr *Value;
4046      if (parseExpression(Value) || parseToken(AsmToken::Identifier))
4047        return true;
4048      const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
4049      if (!MCE)
4050        return Error(Value->getLoc(),
4051                     "cannot repeat value a non-constant number of times");
4052      const int64_t Repetitions = MCE->getValue();
4053      if (Repetitions < 0)
4054        return Error(Value->getLoc(),
4055                     "cannot repeat value a negative number of times");
4056
4057      std::vector<StructInitializer> DuplicatedValues;
4058      if (parseToken(AsmToken::LParen,
4059                     "parentheses required for 'dup' contents") ||
4060          parseStructInstList(Structure, DuplicatedValues) ||
4061          parseToken(AsmToken::RParen, "unmatched parentheses"))
4062        return true;
4063
4064      for (int i = 0; i < Repetitions; ++i)
4065        llvm::append_range(Initializers, DuplicatedValues);
4066    } else {
4067      Initializers.emplace_back();
4068      if (parseStructInitializer(Structure, Initializers.back()))
4069        return true;
4070    }
4071
4072    // Continue if we see a comma. (Also, allow line continuation.)
4073    if (!parseOptionalToken(AsmToken::Comma))
4074      break;
4075    parseOptionalToken(AsmToken::EndOfStatement);
4076  }
4077
4078  return false;
4079}
4080
4081bool MasmParser::emitFieldValue(const FieldInfo &Field,
4082                                const IntFieldInfo &Contents) {
4083  // Default-initialize all values.
4084  for (const MCExpr *Value : Contents.Values) {
4085    if (emitIntValue(Value, Field.Type))
4086      return true;
4087  }
4088  return false;
4089}
4090
4091bool MasmParser::emitFieldValue(const FieldInfo &Field,
4092                                const RealFieldInfo &Contents) {
4093  for (const APInt &AsInt : Contents.AsIntValues) {
4094    getStreamer().emitIntValue(AsInt.getLimitedValue(),
4095                               AsInt.getBitWidth() / 8);
4096  }
4097  return false;
4098}
4099
4100bool MasmParser::emitFieldValue(const FieldInfo &Field,
4101                                const StructFieldInfo &Contents) {
4102  for (const auto &Initializer : Contents.Initializers) {
4103    size_t Index = 0, Offset = 0;
4104    for (const auto &SubField : Contents.Structure.Fields) {
4105      getStreamer().emitZeros(SubField.Offset - Offset);
4106      Offset = SubField.Offset + SubField.SizeOf;
4107      emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);
4108    }
4109  }
4110  return false;
4111}
4112
4113bool MasmParser::emitFieldValue(const FieldInfo &Field) {
4114  switch (Field.Contents.FT) {
4115  case FT_INTEGRAL:
4116    return emitFieldValue(Field, Field.Contents.IntInfo);
4117  case FT_REAL:
4118    return emitFieldValue(Field, Field.Contents.RealInfo);
4119  case FT_STRUCT:
4120    return emitFieldValue(Field, Field.Contents.StructInfo);
4121  }
4122  llvm_unreachable("Unhandled FieldType enum");
4123}
4124
4125bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4126                                      const IntFieldInfo &Contents,
4127                                      const IntFieldInfo &Initializer) {
4128  for (const auto &Value : Initializer.Values) {
4129    if (emitIntValue(Value, Field.Type))
4130      return true;
4131  }
4132  // Default-initialize all remaining values.
4133  for (auto it = Contents.Values.begin() + Initializer.Values.size();
4134       it != Contents.Values.end(); ++it) {
4135    const auto &Value = *it;
4136    if (emitIntValue(Value, Field.Type))
4137      return true;
4138  }
4139  return false;
4140}
4141
4142bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4143                                      const RealFieldInfo &Contents,
4144                                      const RealFieldInfo &Initializer) {
4145  for (const auto &AsInt : Initializer.AsIntValues) {
4146    getStreamer().emitIntValue(AsInt.getLimitedValue(),
4147                               AsInt.getBitWidth() / 8);
4148  }
4149  // Default-initialize all remaining values.
4150  for (auto It = Contents.AsIntValues.begin() + Initializer.AsIntValues.size();
4151       It != Contents.AsIntValues.end(); ++It) {
4152    const auto &AsInt = *It;
4153    getStreamer().emitIntValue(AsInt.getLimitedValue(),
4154                               AsInt.getBitWidth() / 8);
4155  }
4156  return false;
4157}
4158
4159bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4160                                      const StructFieldInfo &Contents,
4161                                      const StructFieldInfo &Initializer) {
4162  for (const auto &Init : Initializer.Initializers) {
4163    emitStructInitializer(Contents.Structure, Init);
4164  }
4165  // Default-initialize all remaining values.
4166  for (auto It =
4167           Contents.Initializers.begin() + Initializer.Initializers.size();
4168       It != Contents.Initializers.end(); ++It) {
4169    const auto &Init = *It;
4170    emitStructInitializer(Contents.Structure, Init);
4171  }
4172  return false;
4173}
4174
4175bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
4176                                      const FieldInitializer &Initializer) {
4177  switch (Field.Contents.FT) {
4178  case FT_INTEGRAL:
4179    return emitFieldInitializer(Field, Field.Contents.IntInfo,
4180                                Initializer.IntInfo);
4181  case FT_REAL:
4182    return emitFieldInitializer(Field, Field.Contents.RealInfo,
4183                                Initializer.RealInfo);
4184  case FT_STRUCT:
4185    return emitFieldInitializer(Field, Field.Contents.StructInfo,
4186                                Initializer.StructInfo);
4187  }
4188  llvm_unreachable("Unhandled FieldType enum");
4189}
4190
4191bool MasmParser::emitStructInitializer(const StructInfo &Structure,
4192                                       const StructInitializer &Initializer) {
4193  size_t Index = 0, Offset = 0;
4194  for (const auto &Init : Initializer.FieldInitializers) {
4195    const auto &Field = Structure.Fields[Index++];
4196    getStreamer().emitZeros(Field.Offset - Offset);
4197    Offset = Field.Offset + Field.SizeOf;
4198    if (emitFieldInitializer(Field, Init))
4199      return true;
4200  }
4201  // Default-initialize all remaining fields.
4202  for (auto It =
4203           Structure.Fields.begin() + Initializer.FieldInitializers.size();
4204       It != Structure.Fields.end(); ++It) {
4205    const auto &Field = *It;
4206    getStreamer().emitZeros(Field.Offset - Offset);
4207    Offset = Field.Offset + Field.SizeOf;
4208    if (emitFieldValue(Field))
4209      return true;
4210  }
4211  // Add final padding.
4212  if (Offset != Structure.Size)
4213    getStreamer().emitZeros(Structure.Size - Offset);
4214  return false;
4215}
4216
4217// Set data values from initializers.
4218bool MasmParser::emitStructValues(const StructInfo &Structure,
4219                                  unsigned *Count) {
4220  std::vector<StructInitializer> Initializers;
4221  if (parseStructInstList(Structure, Initializers))
4222    return true;
4223
4224  for (const auto &Initializer : Initializers) {
4225    if (emitStructInitializer(Structure, Initializer))
4226      return true;
4227  }
4228
4229  if (Count)
4230    *Count = Initializers.size();
4231  return false;
4232}
4233
4234// Declare a field in the current struct.
4235bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) {
4236  StructInfo &OwningStruct = StructInProgress.back();
4237  FieldInfo &Field =
4238      OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize);
4239  StructFieldInfo &StructInfo = Field.Contents.StructInfo;
4240
4241  StructInfo.Structure = Structure;
4242  Field.Type = Structure.Size;
4243
4244  if (parseStructInstList(Structure, StructInfo.Initializers))
4245    return true;
4246
4247  Field.LengthOf = StructInfo.Initializers.size();
4248  Field.SizeOf = Field.Type * Field.LengthOf;
4249  if (OwningStruct.IsUnion)
4250    OwningStruct.Size = std::max(OwningStruct.Size, Field.SizeOf);
4251  else
4252    OwningStruct.Size += Field.SizeOf;
4253
4254  return false;
4255}
4256
4257/// parseDirectiveStructValue
4258///  ::= struct-id (<struct-initializer> | {struct-initializer})
4259///                [, (<struct-initializer> | {struct-initializer})]*
4260bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure,
4261                                           StringRef Directive, SMLoc DirLoc) {
4262  if (StructInProgress.empty()) {
4263    if (emitStructValues(Structure))
4264      return true;
4265  } else if (addStructField("", Structure)) {
4266    return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4267  }
4268
4269  return false;
4270}
4271
4272/// parseDirectiveNamedValue
4273///  ::= name (byte | word | ... ) [ expression (, expression)* ]
4274bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure,
4275                                                StringRef Directive,
4276                                                SMLoc DirLoc, StringRef Name) {
4277  if (StructInProgress.empty()) {
4278    // Initialize named data value.
4279    MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4280    getStreamer().emitLabel(Sym);
4281    unsigned Count;
4282    if (emitStructValues(Structure, &Count))
4283      return true;
4284    AsmTypeInfo Type;
4285    Type.Name = Structure.Name;
4286    Type.Size = Structure.Size * Count;
4287    Type.ElementSize = Structure.Size;
4288    Type.Length = Count;
4289    KnownType[Name.lower()] = Type;
4290  } else if (addStructField(Name, Structure)) {
4291    return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4292  }
4293
4294  return false;
4295}
4296
4297/// parseDirectiveStruct
4298///  ::= <name> (STRUC | STRUCT | UNION) [fieldAlign] [, NONUNIQUE]
4299///      (dataDir | generalDir | offsetDir | nestedStruct)+
4300///      <name> ENDS
4301////// dataDir = data declaration
4302////// offsetDir = EVEN, ORG, ALIGN
4303bool MasmParser::parseDirectiveStruct(StringRef Directive,
4304                                      DirectiveKind DirKind, StringRef Name,
4305                                      SMLoc NameLoc) {
4306  // We ignore NONUNIQUE; we do not support OPTION M510 or OPTION OLDSTRUCTS
4307  // anyway, so all field accesses must be qualified.
4308  AsmToken NextTok = getTok();
4309  int64_t AlignmentValue = 1;
4310  if (NextTok.isNot(AsmToken::Comma) &&
4311      NextTok.isNot(AsmToken::EndOfStatement) &&
4312      parseAbsoluteExpression(AlignmentValue)) {
4313    return addErrorSuffix(" in alignment value for '" + Twine(Directive) +
4314                          "' directive");
4315  }
4316  if (!isPowerOf2_64(AlignmentValue)) {
4317    return Error(NextTok.getLoc(), "alignment must be a power of two; was " +
4318                                       std::to_string(AlignmentValue));
4319  }
4320
4321  StringRef Qualifier;
4322  SMLoc QualifierLoc;
4323  if (parseOptionalToken(AsmToken::Comma)) {
4324    QualifierLoc = getTok().getLoc();
4325    if (parseIdentifier(Qualifier))
4326      return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4327    if (!Qualifier.equals_lower("nonunique"))
4328      return Error(QualifierLoc, "Unrecognized qualifier for '" +
4329                                     Twine(Directive) +
4330                                     "' directive; expected none or NONUNIQUE");
4331  }
4332
4333  if (parseToken(AsmToken::EndOfStatement))
4334    return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4335
4336  StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue);
4337  return false;
4338}
4339
4340/// parseDirectiveNestedStruct
4341///  ::= (STRUC | STRUCT | UNION) [name]
4342///      (dataDir | generalDir | offsetDir | nestedStruct)+
4343///      ENDS
4344bool MasmParser::parseDirectiveNestedStruct(StringRef Directive,
4345                                            DirectiveKind DirKind) {
4346  if (StructInProgress.empty())
4347    return TokError("missing name in top-level '" + Twine(Directive) +
4348                    "' directive");
4349
4350  StringRef Name;
4351  if (getTok().is(AsmToken::Identifier)) {
4352    Name = getTok().getIdentifier();
4353    parseToken(AsmToken::Identifier);
4354  }
4355  if (parseToken(AsmToken::EndOfStatement))
4356    return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
4357
4358  // Reserve space to ensure Alignment doesn't get invalidated when
4359  // StructInProgress grows.
4360  StructInProgress.reserve(StructInProgress.size() + 1);
4361  StructInProgress.emplace_back(Name, DirKind == DK_UNION,
4362                                StructInProgress.back().Alignment);
4363  return false;
4364}
4365
4366bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
4367  if (StructInProgress.empty())
4368    return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION");
4369  if (StructInProgress.size() > 1)
4370    return Error(NameLoc, "unexpected name in nested ENDS directive");
4371  if (StructInProgress.back().Name.compare_lower(Name))
4372    return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
4373                              StructInProgress.back().Name + "'");
4374  StructInfo Structure = StructInProgress.pop_back_val();
4375  // Pad to make the structure's size divisible by the smaller of its alignment
4376  // and the size of its largest field.
4377  Structure.Size = llvm::alignTo(
4378      Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
4379  Structs[Name.lower()] = Structure;
4380
4381  if (parseToken(AsmToken::EndOfStatement))
4382    return addErrorSuffix(" in ENDS directive");
4383
4384  return false;
4385}
4386
4387bool MasmParser::parseDirectiveNestedEnds() {
4388  if (StructInProgress.empty())
4389    return TokError("ENDS directive without matching STRUC/STRUCT/UNION");
4390  if (StructInProgress.size() == 1)
4391    return TokError("missing name in top-level ENDS directive");
4392
4393  if (parseToken(AsmToken::EndOfStatement))
4394    return addErrorSuffix(" in nested ENDS directive");
4395
4396  StructInfo Structure = StructInProgress.pop_back_val();
4397  // Pad to make the structure's size divisible by its alignment.
4398  Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
4399
4400  StructInfo &ParentStruct = StructInProgress.back();
4401  if (Structure.Name.empty()) {
4402    const size_t OldFields = ParentStruct.Fields.size();
4403    ParentStruct.Fields.insert(
4404        ParentStruct.Fields.end(),
4405        std::make_move_iterator(Structure.Fields.begin()),
4406        std::make_move_iterator(Structure.Fields.end()));
4407    for (const auto &FieldByName : Structure.FieldsByName) {
4408      ParentStruct.FieldsByName[FieldByName.getKey()] =
4409          FieldByName.getValue() + OldFields;
4410    }
4411    if (!ParentStruct.IsUnion) {
4412      for (auto FieldIter = ParentStruct.Fields.begin() + OldFields;
4413           FieldIter != ParentStruct.Fields.end(); ++FieldIter) {
4414        FieldIter->Offset += ParentStruct.Size;
4415      }
4416    }
4417
4418    if (ParentStruct.IsUnion)
4419      ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
4420    else
4421      ParentStruct.Size += Structure.Size;
4422  } else {
4423    FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
4424                                             Structure.AlignmentSize);
4425    StructFieldInfo &StructInfo = Field.Contents.StructInfo;
4426    Field.Type = Structure.Size;
4427    Field.LengthOf = 1;
4428    Field.SizeOf = Structure.Size;
4429
4430    if (ParentStruct.IsUnion)
4431      ParentStruct.Size = std::max(ParentStruct.Size, Field.SizeOf);
4432    else
4433      ParentStruct.Size += Field.SizeOf;
4434
4435    StructInfo.Structure = Structure;
4436    StructInfo.Initializers.emplace_back();
4437    auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
4438    for (const auto &SubField : Structure.Fields) {
4439      FieldInitializers.push_back(SubField.Contents);
4440    }
4441  }
4442
4443  return false;
4444}
4445
4446/// parseDirectiveOrg
4447///  ::= .org expression [ , expression ]
4448bool MasmParser::parseDirectiveOrg() {
4449  const MCExpr *Offset;
4450  SMLoc OffsetLoc = Lexer.getLoc();
4451  if (checkForValidSection() || parseExpression(Offset))
4452    return true;
4453
4454  // Parse optional fill expression.
4455  int64_t FillExpr = 0;
4456  if (parseOptionalToken(AsmToken::Comma))
4457    if (parseAbsoluteExpression(FillExpr))
4458      return addErrorSuffix(" in '.org' directive");
4459  if (parseToken(AsmToken::EndOfStatement))
4460    return addErrorSuffix(" in '.org' directive");
4461
4462  getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
4463  return false;
4464}
4465
4466/// parseDirectiveAlign
4467///  ::= align expression
4468bool MasmParser::parseDirectiveAlign() {
4469  SMLoc AlignmentLoc = getLexer().getLoc();
4470  int64_t Alignment;
4471
4472  if (checkForValidSection())
4473    return addErrorSuffix(" in align directive");
4474  // Ignore empty 'align' directives.
4475  if (getTok().is(AsmToken::EndOfStatement)) {
4476    return Warning(AlignmentLoc,
4477                   "align directive with no operand is ignored") &&
4478           parseToken(AsmToken::EndOfStatement);
4479  }
4480  if (parseAbsoluteExpression(Alignment) ||
4481      parseToken(AsmToken::EndOfStatement))
4482    return addErrorSuffix(" in align directive");
4483
4484  // Always emit an alignment here even if we thrown an error.
4485  bool ReturnVal = false;
4486
4487  // Reject alignments that aren't either a power of two or zero, for gas
4488  // compatibility. Alignment of zero is silently rounded up to one.
4489  if (Alignment == 0)
4490    Alignment = 1;
4491  if (!isPowerOf2_64(Alignment))
4492    ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
4493
4494  // Check whether we should use optimal code alignment for this align
4495  // directive.
4496  const MCSection *Section = getStreamer().getCurrentSectionOnly();
4497  assert(Section && "must have section to emit alignment");
4498  if (Section->UseCodeAlign()) {
4499    getStreamer().emitCodeAlignment(Alignment, /*MaxBytesToEmit=*/0);
4500  } else {
4501    // FIXME: Target specific behavior about how the "extra" bytes are filled.
4502    getStreamer().emitValueToAlignment(Alignment, /*Value=*/0, /*ValueSize=*/1,
4503                                       /*MaxBytesToEmit=*/0);
4504  }
4505
4506  return ReturnVal;
4507}
4508
4509/// parseDirectiveFile
4510/// ::= .file filename
4511/// ::= .file number [directory] filename [md5 checksum] [source source-text]
4512bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
4513  // FIXME: I'm not sure what this is.
4514  int64_t FileNumber = -1;
4515  if (getLexer().is(AsmToken::Integer)) {
4516    FileNumber = getTok().getIntVal();
4517    Lex();
4518
4519    if (FileNumber < 0)
4520      return TokError("negative file number");
4521  }
4522
4523  std::string Path;
4524
4525  // Usually the directory and filename together, otherwise just the directory.
4526  // Allow the strings to have escaped octal character sequence.
4527  if (check(getTok().isNot(AsmToken::String),
4528            "unexpected token in '.file' directive") ||
4529      parseEscapedString(Path))
4530    return true;
4531
4532  StringRef Directory;
4533  StringRef Filename;
4534  std::string FilenameData;
4535  if (getLexer().is(AsmToken::String)) {
4536    if (check(FileNumber == -1,
4537              "explicit path specified, but no file number") ||
4538        parseEscapedString(FilenameData))
4539      return true;
4540    Filename = FilenameData;
4541    Directory = Path;
4542  } else {
4543    Filename = Path;
4544  }
4545
4546  uint64_t MD5Hi, MD5Lo;
4547  bool HasMD5 = false;
4548
4549  Optional<StringRef> Source;
4550  bool HasSource = false;
4551  std::string SourceString;
4552
4553  while (!parseOptionalToken(AsmToken::EndOfStatement)) {
4554    StringRef Keyword;
4555    if (check(getTok().isNot(AsmToken::Identifier),
4556              "unexpected token in '.file' directive") ||
4557        parseIdentifier(Keyword))
4558      return true;
4559    if (Keyword == "md5") {
4560      HasMD5 = true;
4561      if (check(FileNumber == -1,
4562                "MD5 checksum specified, but no file number") ||
4563          parseHexOcta(*this, MD5Hi, MD5Lo))
4564        return true;
4565    } else if (Keyword == "source") {
4566      HasSource = true;
4567      if (check(FileNumber == -1,
4568                "source specified, but no file number") ||
4569          check(getTok().isNot(AsmToken::String),
4570                "unexpected token in '.file' directive") ||
4571          parseEscapedString(SourceString))
4572        return true;
4573    } else {
4574      return TokError("unexpected token in '.file' directive");
4575    }
4576  }
4577
4578  if (FileNumber == -1) {
4579    // Ignore the directive if there is no number and the target doesn't support
4580    // numberless .file directives. This allows some portability of assembler
4581    // between different object file formats.
4582    if (getContext().getAsmInfo()->hasSingleParameterDotFile())
4583      getStreamer().emitFileDirective(Filename);
4584  } else {
4585    // In case there is a -g option as well as debug info from directive .file,
4586    // we turn off the -g option, directly use the existing debug info instead.
4587    // Throw away any implicit file table for the assembler source.
4588    if (Ctx.getGenDwarfForAssembly()) {
4589      Ctx.getMCDwarfLineTable(0).resetFileTable();
4590      Ctx.setGenDwarfForAssembly(false);
4591    }
4592
4593    Optional<MD5::MD5Result> CKMem;
4594    if (HasMD5) {
4595      MD5::MD5Result Sum;
4596      for (unsigned i = 0; i != 8; ++i) {
4597        Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
4598        Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
4599      }
4600      CKMem = Sum;
4601    }
4602    if (HasSource) {
4603      char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
4604      memcpy(SourceBuf, SourceString.data(), SourceString.size());
4605      Source = StringRef(SourceBuf, SourceString.size());
4606    }
4607    if (FileNumber == 0) {
4608      if (Ctx.getDwarfVersion() < 5)
4609        return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
4610      getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
4611    } else {
4612      Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
4613          FileNumber, Directory, Filename, CKMem, Source);
4614      if (!FileNumOrErr)
4615        return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
4616    }
4617    // Alert the user if there are some .file directives with MD5 and some not.
4618    // But only do that once.
4619    if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
4620      ReportedInconsistentMD5 = true;
4621      return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
4622    }
4623  }
4624
4625  return false;
4626}
4627
4628/// parseDirectiveLine
4629/// ::= .line [number]
4630bool MasmParser::parseDirectiveLine() {
4631  int64_t LineNumber;
4632  if (getLexer().is(AsmToken::Integer)) {
4633    if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
4634      return true;
4635    (void)LineNumber;
4636    // FIXME: Do something with the .line.
4637  }
4638  if (parseToken(AsmToken::EndOfStatement,
4639                 "unexpected token in '.line' directive"))
4640    return true;
4641
4642  return false;
4643}
4644
4645/// parseDirectiveLoc
4646/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
4647///                                [epilogue_begin] [is_stmt VALUE] [isa VALUE]
4648/// The first number is a file number, must have been previously assigned with
4649/// a .file directive, the second number is the line number and optionally the
4650/// third number is a column position (zero if not specified).  The remaining
4651/// optional items are .loc sub-directives.
4652bool MasmParser::parseDirectiveLoc() {
4653  int64_t FileNumber = 0, LineNumber = 0;
4654  SMLoc Loc = getTok().getLoc();
4655  if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
4656      check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
4657            "file number less than one in '.loc' directive") ||
4658      check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
4659            "unassigned file number in '.loc' directive"))
4660    return true;
4661
4662  // optional
4663  if (getLexer().is(AsmToken::Integer)) {
4664    LineNumber = getTok().getIntVal();
4665    if (LineNumber < 0)
4666      return TokError("line number less than zero in '.loc' directive");
4667    Lex();
4668  }
4669
4670  int64_t ColumnPos = 0;
4671  if (getLexer().is(AsmToken::Integer)) {
4672    ColumnPos = getTok().getIntVal();
4673    if (ColumnPos < 0)
4674      return TokError("column position less than zero in '.loc' directive");
4675    Lex();
4676  }
4677
4678  auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
4679  unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT;
4680  unsigned Isa = 0;
4681  int64_t Discriminator = 0;
4682
4683  auto parseLocOp = [&]() -> bool {
4684    StringRef Name;
4685    SMLoc Loc = getTok().getLoc();
4686    if (parseIdentifier(Name))
4687      return TokError("unexpected token in '.loc' directive");
4688
4689    if (Name == "basic_block")
4690      Flags |= DWARF2_FLAG_BASIC_BLOCK;
4691    else if (Name == "prologue_end")
4692      Flags |= DWARF2_FLAG_PROLOGUE_END;
4693    else if (Name == "epilogue_begin")
4694      Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
4695    else if (Name == "is_stmt") {
4696      Loc = getTok().getLoc();
4697      const MCExpr *Value;
4698      if (parseExpression(Value))
4699        return true;
4700      // The expression must be the constant 0 or 1.
4701      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4702        int Value = MCE->getValue();
4703        if (Value == 0)
4704          Flags &= ~DWARF2_FLAG_IS_STMT;
4705        else if (Value == 1)
4706          Flags |= DWARF2_FLAG_IS_STMT;
4707        else
4708          return Error(Loc, "is_stmt value not 0 or 1");
4709      } else {
4710        return Error(Loc, "is_stmt value not the constant value of 0 or 1");
4711      }
4712    } else if (Name == "isa") {
4713      Loc = getTok().getLoc();
4714      const MCExpr *Value;
4715      if (parseExpression(Value))
4716        return true;
4717      // The expression must be a constant greater or equal to 0.
4718      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4719        int Value = MCE->getValue();
4720        if (Value < 0)
4721          return Error(Loc, "isa number less than zero");
4722        Isa = Value;
4723      } else {
4724        return Error(Loc, "isa number not a constant value");
4725      }
4726    } else if (Name == "discriminator") {
4727      if (parseAbsoluteExpression(Discriminator))
4728        return true;
4729    } else {
4730      return Error(Loc, "unknown sub-directive in '.loc' directive");
4731    }
4732    return false;
4733  };
4734
4735  if (parseMany(parseLocOp, false /*hasComma*/))
4736    return true;
4737
4738  getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
4739                                      Isa, Discriminator, StringRef());
4740
4741  return false;
4742}
4743
4744/// parseDirectiveStabs
4745/// ::= .stabs string, number, number, number
4746bool MasmParser::parseDirectiveStabs() {
4747  return TokError("unsupported directive '.stabs'");
4748}
4749
4750/// parseDirectiveCVFile
4751/// ::= .cv_file number filename [checksum] [checksumkind]
4752bool MasmParser::parseDirectiveCVFile() {
4753  SMLoc FileNumberLoc = getTok().getLoc();
4754  int64_t FileNumber;
4755  std::string Filename;
4756  std::string Checksum;
4757  int64_t ChecksumKind = 0;
4758
4759  if (parseIntToken(FileNumber,
4760                    "expected file number in '.cv_file' directive") ||
4761      check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
4762      check(getTok().isNot(AsmToken::String),
4763            "unexpected token in '.cv_file' directive") ||
4764      parseEscapedString(Filename))
4765    return true;
4766  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4767    if (check(getTok().isNot(AsmToken::String),
4768              "unexpected token in '.cv_file' directive") ||
4769        parseEscapedString(Checksum) ||
4770        parseIntToken(ChecksumKind,
4771                      "expected checksum kind in '.cv_file' directive") ||
4772        parseToken(AsmToken::EndOfStatement,
4773                   "unexpected token in '.cv_file' directive"))
4774      return true;
4775  }
4776
4777  Checksum = fromHex(Checksum);
4778  void *CKMem = Ctx.allocate(Checksum.size(), 1);
4779  memcpy(CKMem, Checksum.data(), Checksum.size());
4780  ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
4781                                    Checksum.size());
4782
4783  if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
4784                                         static_cast<uint8_t>(ChecksumKind)))
4785    return Error(FileNumberLoc, "file number already allocated");
4786
4787  return false;
4788}
4789
4790bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
4791                                   StringRef DirectiveName) {
4792  SMLoc Loc;
4793  return parseTokenLoc(Loc) ||
4794         parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
4795                                       "' directive") ||
4796         check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
4797               "expected function id within range [0, UINT_MAX)");
4798}
4799
4800bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
4801  SMLoc Loc;
4802  return parseTokenLoc(Loc) ||
4803         parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
4804                                       "' directive") ||
4805         check(FileNumber < 1, Loc, "file number less than one in '" +
4806                                        DirectiveName + "' directive") ||
4807         check(!getCVContext().isValidFileNumber(FileNumber), Loc,
4808               "unassigned file number in '" + DirectiveName + "' directive");
4809}
4810
4811/// parseDirectiveCVFuncId
4812/// ::= .cv_func_id FunctionId
4813///
4814/// Introduces a function ID that can be used with .cv_loc.
4815bool MasmParser::parseDirectiveCVFuncId() {
4816  SMLoc FunctionIdLoc = getTok().getLoc();
4817  int64_t FunctionId;
4818
4819  if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
4820      parseToken(AsmToken::EndOfStatement,
4821                 "unexpected token in '.cv_func_id' directive"))
4822    return true;
4823
4824  if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
4825    return Error(FunctionIdLoc, "function id already allocated");
4826
4827  return false;
4828}
4829
4830/// parseDirectiveCVInlineSiteId
4831/// ::= .cv_inline_site_id FunctionId
4832///         "within" IAFunc
4833///         "inlined_at" IAFile IALine [IACol]
4834///
4835/// Introduces a function ID that can be used with .cv_loc. Includes "inlined
4836/// at" source location information for use in the line table of the caller,
4837/// whether the caller is a real function or another inlined call site.
4838bool MasmParser::parseDirectiveCVInlineSiteId() {
4839  SMLoc FunctionIdLoc = getTok().getLoc();
4840  int64_t FunctionId;
4841  int64_t IAFunc;
4842  int64_t IAFile;
4843  int64_t IALine;
4844  int64_t IACol = 0;
4845
4846  // FunctionId
4847  if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
4848    return true;
4849
4850  // "within"
4851  if (check((getLexer().isNot(AsmToken::Identifier) ||
4852             getTok().getIdentifier() != "within"),
4853            "expected 'within' identifier in '.cv_inline_site_id' directive"))
4854    return true;
4855  Lex();
4856
4857  // IAFunc
4858  if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
4859    return true;
4860
4861  // "inlined_at"
4862  if (check((getLexer().isNot(AsmToken::Identifier) ||
4863             getTok().getIdentifier() != "inlined_at"),
4864            "expected 'inlined_at' identifier in '.cv_inline_site_id' "
4865            "directive") )
4866    return true;
4867  Lex();
4868
4869  // IAFile IALine
4870  if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
4871      parseIntToken(IALine, "expected line number after 'inlined_at'"))
4872    return true;
4873
4874  // [IACol]
4875  if (getLexer().is(AsmToken::Integer)) {
4876    IACol = getTok().getIntVal();
4877    Lex();
4878  }
4879
4880  if (parseToken(AsmToken::EndOfStatement,
4881                 "unexpected token in '.cv_inline_site_id' directive"))
4882    return true;
4883
4884  if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
4885                                                 IALine, IACol, FunctionIdLoc))
4886    return Error(FunctionIdLoc, "function id already allocated");
4887
4888  return false;
4889}
4890
4891/// parseDirectiveCVLoc
4892/// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
4893///                                [is_stmt VALUE]
4894/// The first number is a file number, must have been previously assigned with
4895/// a .file directive, the second number is the line number and optionally the
4896/// third number is a column position (zero if not specified).  The remaining
4897/// optional items are .loc sub-directives.
4898bool MasmParser::parseDirectiveCVLoc() {
4899  SMLoc DirectiveLoc = getTok().getLoc();
4900  int64_t FunctionId, FileNumber;
4901  if (parseCVFunctionId(FunctionId, ".cv_loc") ||
4902      parseCVFileId(FileNumber, ".cv_loc"))
4903    return true;
4904
4905  int64_t LineNumber = 0;
4906  if (getLexer().is(AsmToken::Integer)) {
4907    LineNumber = getTok().getIntVal();
4908    if (LineNumber < 0)
4909      return TokError("line number less than zero in '.cv_loc' directive");
4910    Lex();
4911  }
4912
4913  int64_t ColumnPos = 0;
4914  if (getLexer().is(AsmToken::Integer)) {
4915    ColumnPos = getTok().getIntVal();
4916    if (ColumnPos < 0)
4917      return TokError("column position less than zero in '.cv_loc' directive");
4918    Lex();
4919  }
4920
4921  bool PrologueEnd = false;
4922  uint64_t IsStmt = 0;
4923
4924  auto parseOp = [&]() -> bool {
4925    StringRef Name;
4926    SMLoc Loc = getTok().getLoc();
4927    if (parseIdentifier(Name))
4928      return TokError("unexpected token in '.cv_loc' directive");
4929    if (Name == "prologue_end")
4930      PrologueEnd = true;
4931    else if (Name == "is_stmt") {
4932      Loc = getTok().getLoc();
4933      const MCExpr *Value;
4934      if (parseExpression(Value))
4935        return true;
4936      // The expression must be the constant 0 or 1.
4937      IsStmt = ~0ULL;
4938      if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
4939        IsStmt = MCE->getValue();
4940
4941      if (IsStmt > 1)
4942        return Error(Loc, "is_stmt value not 0 or 1");
4943    } else {
4944      return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
4945    }
4946    return false;
4947  };
4948
4949  if (parseMany(parseOp, false /*hasComma*/))
4950    return true;
4951
4952  getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
4953                                   ColumnPos, PrologueEnd, IsStmt, StringRef(),
4954                                   DirectiveLoc);
4955  return false;
4956}
4957
4958/// parseDirectiveCVLinetable
4959/// ::= .cv_linetable FunctionId, FnStart, FnEnd
4960bool MasmParser::parseDirectiveCVLinetable() {
4961  int64_t FunctionId;
4962  StringRef FnStartName, FnEndName;
4963  SMLoc Loc = getTok().getLoc();
4964  if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
4965      parseToken(AsmToken::Comma,
4966                 "unexpected token in '.cv_linetable' directive") ||
4967      parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
4968                                  "expected identifier in directive") ||
4969      parseToken(AsmToken::Comma,
4970                 "unexpected token in '.cv_linetable' directive") ||
4971      parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
4972                                  "expected identifier in directive"))
4973    return true;
4974
4975  MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
4976  MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
4977
4978  getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
4979  return false;
4980}
4981
4982/// parseDirectiveCVInlineLinetable
4983/// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
4984bool MasmParser::parseDirectiveCVInlineLinetable() {
4985  int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
4986  StringRef FnStartName, FnEndName;
4987  SMLoc Loc = getTok().getLoc();
4988  if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
4989      parseTokenLoc(Loc) ||
4990      parseIntToken(
4991          SourceFileId,
4992          "expected SourceField in '.cv_inline_linetable' directive") ||
4993      check(SourceFileId <= 0, Loc,
4994            "File id less than zero in '.cv_inline_linetable' directive") ||
4995      parseTokenLoc(Loc) ||
4996      parseIntToken(
4997          SourceLineNum,
4998          "expected SourceLineNum in '.cv_inline_linetable' directive") ||
4999      check(SourceLineNum < 0, Loc,
5000            "Line number less than zero in '.cv_inline_linetable' directive") ||
5001      parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
5002                                  "expected identifier in directive") ||
5003      parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
5004                                  "expected identifier in directive"))
5005    return true;
5006
5007  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
5008    return true;
5009
5010  MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
5011  MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
5012  getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
5013                                               SourceLineNum, FnStartSym,
5014                                               FnEndSym);
5015  return false;
5016}
5017
5018void MasmParser::initializeCVDefRangeTypeMap() {
5019  CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
5020  CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
5021  CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
5022  CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
5023}
5024
5025/// parseDirectiveCVDefRange
5026/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
5027bool MasmParser::parseDirectiveCVDefRange() {
5028  SMLoc Loc;
5029  std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
5030  while (getLexer().is(AsmToken::Identifier)) {
5031    Loc = getLexer().getLoc();
5032    StringRef GapStartName;
5033    if (parseIdentifier(GapStartName))
5034      return Error(Loc, "expected identifier in directive");
5035    MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
5036
5037    Loc = getLexer().getLoc();
5038    StringRef GapEndName;
5039    if (parseIdentifier(GapEndName))
5040      return Error(Loc, "expected identifier in directive");
5041    MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
5042
5043    Ranges.push_back({GapStartSym, GapEndSym});
5044  }
5045
5046  StringRef CVDefRangeTypeStr;
5047  if (parseToken(
5048          AsmToken::Comma,
5049          "expected comma before def_range type in .cv_def_range directive") ||
5050      parseIdentifier(CVDefRangeTypeStr))
5051    return Error(Loc, "expected def_range type in directive");
5052
5053  StringMap<CVDefRangeType>::const_iterator CVTypeIt =
5054      CVDefRangeTypeMap.find(CVDefRangeTypeStr);
5055  CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
5056                                ? CVDR_DEFRANGE
5057                                : CVTypeIt->getValue();
5058  switch (CVDRType) {
5059  case CVDR_DEFRANGE_REGISTER: {
5060    int64_t DRRegister;
5061    if (parseToken(AsmToken::Comma, "expected comma before register number in "
5062                                    ".cv_def_range directive") ||
5063        parseAbsoluteExpression(DRRegister))
5064      return Error(Loc, "expected register number");
5065
5066    codeview::DefRangeRegisterHeader DRHdr;
5067    DRHdr.Register = DRRegister;
5068    DRHdr.MayHaveNoName = 0;
5069    getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5070    break;
5071  }
5072  case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
5073    int64_t DROffset;
5074    if (parseToken(AsmToken::Comma,
5075                   "expected comma before offset in .cv_def_range directive") ||
5076        parseAbsoluteExpression(DROffset))
5077      return Error(Loc, "expected offset value");
5078
5079    codeview::DefRangeFramePointerRelHeader DRHdr;
5080    DRHdr.Offset = DROffset;
5081    getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5082    break;
5083  }
5084  case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
5085    int64_t DRRegister;
5086    int64_t DROffsetInParent;
5087    if (parseToken(AsmToken::Comma, "expected comma before register number in "
5088                                    ".cv_def_range directive") ||
5089        parseAbsoluteExpression(DRRegister))
5090      return Error(Loc, "expected register number");
5091    if (parseToken(AsmToken::Comma,
5092                   "expected comma before offset in .cv_def_range directive") ||
5093        parseAbsoluteExpression(DROffsetInParent))
5094      return Error(Loc, "expected offset value");
5095
5096    codeview::DefRangeSubfieldRegisterHeader DRHdr;
5097    DRHdr.Register = DRRegister;
5098    DRHdr.MayHaveNoName = 0;
5099    DRHdr.OffsetInParent = DROffsetInParent;
5100    getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5101    break;
5102  }
5103  case CVDR_DEFRANGE_REGISTER_REL: {
5104    int64_t DRRegister;
5105    int64_t DRFlags;
5106    int64_t DRBasePointerOffset;
5107    if (parseToken(AsmToken::Comma, "expected comma before register number in "
5108                                    ".cv_def_range directive") ||
5109        parseAbsoluteExpression(DRRegister))
5110      return Error(Loc, "expected register value");
5111    if (parseToken(
5112            AsmToken::Comma,
5113            "expected comma before flag value in .cv_def_range directive") ||
5114        parseAbsoluteExpression(DRFlags))
5115      return Error(Loc, "expected flag value");
5116    if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
5117                                    "in .cv_def_range directive") ||
5118        parseAbsoluteExpression(DRBasePointerOffset))
5119      return Error(Loc, "expected base pointer offset value");
5120
5121    codeview::DefRangeRegisterRelHeader DRHdr;
5122    DRHdr.Register = DRRegister;
5123    DRHdr.Flags = DRFlags;
5124    DRHdr.BasePointerOffset = DRBasePointerOffset;
5125    getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
5126    break;
5127  }
5128  default:
5129    return Error(Loc, "unexpected def_range type in .cv_def_range directive");
5130  }
5131  return true;
5132}
5133
5134/// parseDirectiveCVString
5135/// ::= .cv_stringtable "string"
5136bool MasmParser::parseDirectiveCVString() {
5137  std::string Data;
5138  if (checkForValidSection() || parseEscapedString(Data))
5139    return addErrorSuffix(" in '.cv_string' directive");
5140
5141  // Put the string in the table and emit the offset.
5142  std::pair<StringRef, unsigned> Insertion =
5143      getCVContext().addToStringTable(Data);
5144  getStreamer().emitIntValue(Insertion.second, 4);
5145  return false;
5146}
5147
5148/// parseDirectiveCVStringTable
5149/// ::= .cv_stringtable
5150bool MasmParser::parseDirectiveCVStringTable() {
5151  getStreamer().emitCVStringTableDirective();
5152  return false;
5153}
5154
5155/// parseDirectiveCVFileChecksums
5156/// ::= .cv_filechecksums
5157bool MasmParser::parseDirectiveCVFileChecksums() {
5158  getStreamer().emitCVFileChecksumsDirective();
5159  return false;
5160}
5161
5162/// parseDirectiveCVFileChecksumOffset
5163/// ::= .cv_filechecksumoffset fileno
5164bool MasmParser::parseDirectiveCVFileChecksumOffset() {
5165  int64_t FileNo;
5166  if (parseIntToken(FileNo, "expected identifier in directive"))
5167    return true;
5168  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
5169    return true;
5170  getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
5171  return false;
5172}
5173
5174/// parseDirectiveCVFPOData
5175/// ::= .cv_fpo_data procsym
5176bool MasmParser::parseDirectiveCVFPOData() {
5177  SMLoc DirLoc = getLexer().getLoc();
5178  StringRef ProcName;
5179  if (parseIdentifier(ProcName))
5180    return TokError("expected symbol name");
5181  if (parseEOL("unexpected tokens"))
5182    return addErrorSuffix(" in '.cv_fpo_data' directive");
5183  MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
5184  getStreamer().EmitCVFPOData(ProcSym, DirLoc);
5185  return false;
5186}
5187
5188/// parseDirectiveCFISections
5189/// ::= .cfi_sections section [, section]
5190bool MasmParser::parseDirectiveCFISections() {
5191  StringRef Name;
5192  bool EH = false;
5193  bool Debug = false;
5194
5195  if (parseIdentifier(Name))
5196    return TokError("Expected an identifier");
5197
5198  if (Name == ".eh_frame")
5199    EH = true;
5200  else if (Name == ".debug_frame")
5201    Debug = true;
5202
5203  if (getLexer().is(AsmToken::Comma)) {
5204    Lex();
5205
5206    if (parseIdentifier(Name))
5207      return TokError("Expected an identifier");
5208
5209    if (Name == ".eh_frame")
5210      EH = true;
5211    else if (Name == ".debug_frame")
5212      Debug = true;
5213  }
5214
5215  getStreamer().emitCFISections(EH, Debug);
5216  return false;
5217}
5218
5219/// parseDirectiveCFIStartProc
5220/// ::= .cfi_startproc [simple]
5221bool MasmParser::parseDirectiveCFIStartProc() {
5222  StringRef Simple;
5223  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5224    if (check(parseIdentifier(Simple) || Simple != "simple",
5225              "unexpected token") ||
5226        parseToken(AsmToken::EndOfStatement))
5227      return addErrorSuffix(" in '.cfi_startproc' directive");
5228  }
5229
5230  // TODO(kristina): Deal with a corner case of incorrect diagnostic context
5231  // being produced if this directive is emitted as part of preprocessor macro
5232  // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
5233  // Tools like llvm-mc on the other hand are not affected by it, and report
5234  // correct context information.
5235  getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc());
5236  return false;
5237}
5238
5239/// parseDirectiveCFIEndProc
5240/// ::= .cfi_endproc
5241bool MasmParser::parseDirectiveCFIEndProc() {
5242  getStreamer().emitCFIEndProc();
5243  return false;
5244}
5245
5246/// parse register name or number.
5247bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register,
5248                                               SMLoc DirectiveLoc) {
5249  unsigned RegNo;
5250
5251  if (getLexer().isNot(AsmToken::Integer)) {
5252    if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
5253      return true;
5254    Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
5255  } else
5256    return parseAbsoluteExpression(Register);
5257
5258  return false;
5259}
5260
5261/// parseDirectiveCFIDefCfa
5262/// ::= .cfi_def_cfa register,  offset
5263bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
5264  int64_t Register = 0, Offset = 0;
5265  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5266      parseToken(AsmToken::Comma, "unexpected token in directive") ||
5267      parseAbsoluteExpression(Offset))
5268    return true;
5269
5270  getStreamer().emitCFIDefCfa(Register, Offset);
5271  return false;
5272}
5273
5274/// parseDirectiveCFIDefCfaOffset
5275/// ::= .cfi_def_cfa_offset offset
5276bool MasmParser::parseDirectiveCFIDefCfaOffset() {
5277  int64_t Offset = 0;
5278  if (parseAbsoluteExpression(Offset))
5279    return true;
5280
5281  getStreamer().emitCFIDefCfaOffset(Offset);
5282  return false;
5283}
5284
5285/// parseDirectiveCFIRegister
5286/// ::= .cfi_register register, register
5287bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
5288  int64_t Register1 = 0, Register2 = 0;
5289  if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
5290      parseToken(AsmToken::Comma, "unexpected token in directive") ||
5291      parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
5292    return true;
5293
5294  getStreamer().emitCFIRegister(Register1, Register2);
5295  return false;
5296}
5297
5298/// parseDirectiveCFIWindowSave
5299/// ::= .cfi_window_save
5300bool MasmParser::parseDirectiveCFIWindowSave() {
5301  getStreamer().emitCFIWindowSave();
5302  return false;
5303}
5304
5305/// parseDirectiveCFIAdjustCfaOffset
5306/// ::= .cfi_adjust_cfa_offset adjustment
5307bool MasmParser::parseDirectiveCFIAdjustCfaOffset() {
5308  int64_t Adjustment = 0;
5309  if (parseAbsoluteExpression(Adjustment))
5310    return true;
5311
5312  getStreamer().emitCFIAdjustCfaOffset(Adjustment);
5313  return false;
5314}
5315
5316/// parseDirectiveCFIDefCfaRegister
5317/// ::= .cfi_def_cfa_register register
5318bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
5319  int64_t Register = 0;
5320  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5321    return true;
5322
5323  getStreamer().emitCFIDefCfaRegister(Register);
5324  return false;
5325}
5326
5327/// parseDirectiveCFIOffset
5328/// ::= .cfi_offset register, offset
5329bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
5330  int64_t Register = 0;
5331  int64_t Offset = 0;
5332
5333  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5334      parseToken(AsmToken::Comma, "unexpected token in directive") ||
5335      parseAbsoluteExpression(Offset))
5336    return true;
5337
5338  getStreamer().emitCFIOffset(Register, Offset);
5339  return false;
5340}
5341
5342/// parseDirectiveCFIRelOffset
5343/// ::= .cfi_rel_offset register, offset
5344bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
5345  int64_t Register = 0, Offset = 0;
5346
5347  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
5348      parseToken(AsmToken::Comma, "unexpected token in directive") ||
5349      parseAbsoluteExpression(Offset))
5350    return true;
5351
5352  getStreamer().emitCFIRelOffset(Register, Offset);
5353  return false;
5354}
5355
5356static bool isValidEncoding(int64_t Encoding) {
5357  if (Encoding & ~0xff)
5358    return false;
5359
5360  if (Encoding == dwarf::DW_EH_PE_omit)
5361    return true;
5362
5363  const unsigned Format = Encoding & 0xf;
5364  if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
5365      Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
5366      Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
5367      Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
5368    return false;
5369
5370  const unsigned Application = Encoding & 0x70;
5371  if (Application != dwarf::DW_EH_PE_absptr &&
5372      Application != dwarf::DW_EH_PE_pcrel)
5373    return false;
5374
5375  return true;
5376}
5377
5378/// parseDirectiveCFIPersonalityOrLsda
5379/// IsPersonality true for cfi_personality, false for cfi_lsda
5380/// ::= .cfi_personality encoding, [symbol_name]
5381/// ::= .cfi_lsda encoding, [symbol_name]
5382bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
5383  int64_t Encoding = 0;
5384  if (parseAbsoluteExpression(Encoding))
5385    return true;
5386  if (Encoding == dwarf::DW_EH_PE_omit)
5387    return false;
5388
5389  StringRef Name;
5390  if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
5391      parseToken(AsmToken::Comma, "unexpected token in directive") ||
5392      check(parseIdentifier(Name), "expected identifier in directive"))
5393    return true;
5394
5395  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5396
5397  if (IsPersonality)
5398    getStreamer().emitCFIPersonality(Sym, Encoding);
5399  else
5400    getStreamer().emitCFILsda(Sym, Encoding);
5401  return false;
5402}
5403
5404/// parseDirectiveCFIRememberState
5405/// ::= .cfi_remember_state
5406bool MasmParser::parseDirectiveCFIRememberState() {
5407  getStreamer().emitCFIRememberState();
5408  return false;
5409}
5410
5411/// parseDirectiveCFIRestoreState
5412/// ::= .cfi_remember_state
5413bool MasmParser::parseDirectiveCFIRestoreState() {
5414  getStreamer().emitCFIRestoreState();
5415  return false;
5416}
5417
5418/// parseDirectiveCFISameValue
5419/// ::= .cfi_same_value register
5420bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
5421  int64_t Register = 0;
5422
5423  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5424    return true;
5425
5426  getStreamer().emitCFISameValue(Register);
5427  return false;
5428}
5429
5430/// parseDirectiveCFIRestore
5431/// ::= .cfi_restore register
5432bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
5433  int64_t Register = 0;
5434  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5435    return true;
5436
5437  getStreamer().emitCFIRestore(Register);
5438  return false;
5439}
5440
5441/// parseDirectiveCFIEscape
5442/// ::= .cfi_escape expression[,...]
5443bool MasmParser::parseDirectiveCFIEscape() {
5444  std::string Values;
5445  int64_t CurrValue;
5446  if (parseAbsoluteExpression(CurrValue))
5447    return true;
5448
5449  Values.push_back((uint8_t)CurrValue);
5450
5451  while (getLexer().is(AsmToken::Comma)) {
5452    Lex();
5453
5454    if (parseAbsoluteExpression(CurrValue))
5455      return true;
5456
5457    Values.push_back((uint8_t)CurrValue);
5458  }
5459
5460  getStreamer().emitCFIEscape(Values);
5461  return false;
5462}
5463
5464/// parseDirectiveCFIReturnColumn
5465/// ::= .cfi_return_column register
5466bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
5467  int64_t Register = 0;
5468  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5469    return true;
5470  getStreamer().emitCFIReturnColumn(Register);
5471  return false;
5472}
5473
5474/// parseDirectiveCFISignalFrame
5475/// ::= .cfi_signal_frame
5476bool MasmParser::parseDirectiveCFISignalFrame() {
5477  if (parseToken(AsmToken::EndOfStatement,
5478                 "unexpected token in '.cfi_signal_frame'"))
5479    return true;
5480
5481  getStreamer().emitCFISignalFrame();
5482  return false;
5483}
5484
5485/// parseDirectiveCFIUndefined
5486/// ::= .cfi_undefined register
5487bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
5488  int64_t Register = 0;
5489
5490  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
5491    return true;
5492
5493  getStreamer().emitCFIUndefined(Register);
5494  return false;
5495}
5496
5497/// parseDirectiveMacro
5498/// ::= name macro [parameters]
5499///     ["LOCAL" identifiers]
5500///   parameters ::= parameter [, parameter]*
5501///   parameter ::= name ":" qualifier
5502///   qualifier ::= "req" | "vararg" | "=" macro_argument
5503bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
5504  MCAsmMacroParameters Parameters;
5505  while (getLexer().isNot(AsmToken::EndOfStatement)) {
5506    if (!Parameters.empty() && Parameters.back().Vararg)
5507      return Error(Lexer.getLoc(),
5508                   "Vararg parameter '" + Parameters.back().Name +
5509                       "' should be last in the list of parameters");
5510
5511    MCAsmMacroParameter Parameter;
5512    if (parseIdentifier(Parameter.Name))
5513      return TokError("expected identifier in 'macro' directive");
5514
5515    // Emit an error if two (or more) named parameters share the same name.
5516    for (const MCAsmMacroParameter& CurrParam : Parameters)
5517      if (CurrParam.Name.equals_lower(Parameter.Name))
5518        return TokError("macro '" + Name + "' has multiple parameters"
5519                        " named '" + Parameter.Name + "'");
5520
5521    if (Lexer.is(AsmToken::Colon)) {
5522      Lex();  // consume ':'
5523
5524      if (parseOptionalToken(AsmToken::Equal)) {
5525        // Default value
5526        SMLoc ParamLoc;
5527
5528        ParamLoc = Lexer.getLoc();
5529        if (parseMacroArgument(nullptr, Parameter.Value))
5530          return true;
5531      } else {
5532        SMLoc QualLoc;
5533        StringRef Qualifier;
5534
5535        QualLoc = Lexer.getLoc();
5536        if (parseIdentifier(Qualifier))
5537          return Error(QualLoc, "missing parameter qualifier for "
5538                                "'" +
5539                                    Parameter.Name + "' in macro '" + Name +
5540                                    "'");
5541
5542        if (Qualifier.equals_lower("req"))
5543          Parameter.Required = true;
5544        else if (Qualifier.equals_lower("vararg"))
5545          Parameter.Vararg = true;
5546        else
5547          return Error(QualLoc,
5548                       Qualifier + " is not a valid parameter qualifier for '" +
5549                           Parameter.Name + "' in macro '" + Name + "'");
5550      }
5551    }
5552
5553    Parameters.push_back(std::move(Parameter));
5554
5555    if (getLexer().is(AsmToken::Comma))
5556      Lex();
5557  }
5558
5559  // Eat just the end of statement.
5560  Lexer.Lex();
5561
5562  std::vector<std::string> Locals;
5563  if (getTok().is(AsmToken::Identifier) &&
5564      getTok().getIdentifier().equals_lower("local")) {
5565    Lex(); // Eat the LOCAL directive.
5566
5567    StringRef ID;
5568    while (true) {
5569      if (parseIdentifier(ID))
5570        return true;
5571      Locals.push_back(ID.lower());
5572
5573      // If we see a comma, continue (and allow line continuation).
5574      if (!parseOptionalToken(AsmToken::Comma))
5575        break;
5576      parseOptionalToken(AsmToken::EndOfStatement);
5577    }
5578  }
5579
5580  // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors.
5581  AsmToken EndToken, StartToken = getTok();
5582  unsigned MacroDepth = 0;
5583  bool IsMacroFunction = false;
5584  // Lex the macro definition.
5585  while (true) {
5586    // Ignore Lexing errors in macros.
5587    while (Lexer.is(AsmToken::Error)) {
5588      Lexer.Lex();
5589    }
5590
5591    // Check whether we have reached the end of the file.
5592    if (getLexer().is(AsmToken::Eof))
5593      return Error(NameLoc, "no matching 'endm' in definition");
5594
5595    // Otherwise, check whether we have reached the 'endm'... and determine if
5596    // this is a macro function.
5597    if (getLexer().is(AsmToken::Identifier)) {
5598      if (getTok().getIdentifier().equals_lower("endm")) {
5599        if (MacroDepth == 0) { // Outermost macro.
5600          EndToken = getTok();
5601          Lexer.Lex();
5602          if (getLexer().isNot(AsmToken::EndOfStatement))
5603            return TokError("unexpected token in '" + EndToken.getIdentifier() +
5604                            "' directive");
5605          break;
5606        } else {
5607          // Otherwise we just found the end of an inner macro.
5608          --MacroDepth;
5609        }
5610      } else if (getTok().getIdentifier().equals_lower("exitm")) {
5611        if (MacroDepth == 0 &&
5612            getLexer().peekTok().isNot(AsmToken::EndOfStatement)) {
5613          IsMacroFunction = true;
5614        }
5615      } else if (isMacroLikeDirective()) {
5616        // We allow nested macros. Those aren't instantiated until the
5617        // outermost macro is expanded so just ignore them for now.
5618        ++MacroDepth;
5619      }
5620    }
5621
5622    // Otherwise, scan til the end of the statement.
5623    eatToEndOfStatement();
5624  }
5625
5626  if (getContext().lookupMacro(Name.lower())) {
5627    return Error(NameLoc, "macro '" + Name + "' is already defined");
5628  }
5629
5630  const char *BodyStart = StartToken.getLoc().getPointer();
5631  const char *BodyEnd = EndToken.getLoc().getPointer();
5632  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5633  MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals),
5634                   IsMacroFunction);
5635  DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
5636                  Macro.dump());
5637  getContext().defineMacro(Name, std::move(Macro));
5638  return false;
5639}
5640
5641/// parseDirectiveExitMacro
5642/// ::= "exitm" [textitem]
5643bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
5644                                         StringRef Directive,
5645                                         std::string &Value) {
5646  SMLoc EndLoc = getTok().getLoc();
5647  if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value))
5648    return Error(EndLoc,
5649                 "unable to parse text item in '" + Directive + "' directive");
5650  eatToEndOfStatement();
5651
5652  if (!isInsideMacroInstantiation())
5653    return TokError("unexpected '" + Directive + "' in file, "
5654                                                 "no current macro definition");
5655
5656  // Exit all conditionals that are active in the current macro.
5657  while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
5658    TheCondState = TheCondStack.back();
5659    TheCondStack.pop_back();
5660  }
5661
5662  handleMacroExit();
5663  return false;
5664}
5665
5666/// parseDirectiveEndMacro
5667/// ::= endm
5668bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
5669  if (getLexer().isNot(AsmToken::EndOfStatement))
5670    return TokError("unexpected token in '" + Directive + "' directive");
5671
5672  // If we are inside a macro instantiation, terminate the current
5673  // instantiation.
5674  if (isInsideMacroInstantiation()) {
5675    handleMacroExit();
5676    return false;
5677  }
5678
5679  // Otherwise, this .endmacro is a stray entry in the file; well formed
5680  // .endmacro directives are handled during the macro definition parsing.
5681  return TokError("unexpected '" + Directive + "' in file, "
5682                                               "no current macro definition");
5683}
5684
5685/// parseDirectivePurgeMacro
5686/// ::= purge identifier ( , identifier )*
5687bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
5688  StringRef Name;
5689  while (true) {
5690    SMLoc NameLoc;
5691    if (parseTokenLoc(NameLoc) ||
5692        check(parseIdentifier(Name), NameLoc,
5693              "expected identifier in 'purge' directive"))
5694      return true;
5695
5696    DEBUG_WITH_TYPE("asm-macros", dbgs()
5697                                      << "Un-defining macro: " << Name << "\n");
5698    if (!getContext().lookupMacro(Name.lower()))
5699      return Error(NameLoc, "macro '" + Name + "' is not defined");
5700    getContext().undefineMacro(Name.lower());
5701
5702    if (!parseOptionalToken(AsmToken::Comma))
5703      break;
5704    parseOptionalToken(AsmToken::EndOfStatement);
5705  }
5706
5707  return false;
5708}
5709
5710/// parseDirectiveSymbolAttribute
5711///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
5712bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
5713  auto parseOp = [&]() -> bool {
5714    StringRef Name;
5715    SMLoc Loc = getTok().getLoc();
5716    if (parseIdentifier(Name))
5717      return Error(Loc, "expected identifier");
5718    MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5719
5720    // Assembler local symbols don't make any sense here. Complain loudly.
5721    if (Sym->isTemporary())
5722      return Error(Loc, "non-local symbol required");
5723
5724    if (!getStreamer().emitSymbolAttribute(Sym, Attr))
5725      return Error(Loc, "unable to emit symbol attribute");
5726    return false;
5727  };
5728
5729  if (parseMany(parseOp))
5730    return addErrorSuffix(" in directive");
5731  return false;
5732}
5733
5734/// parseDirectiveComm
5735///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
5736bool MasmParser::parseDirectiveComm(bool IsLocal) {
5737  if (checkForValidSection())
5738    return true;
5739
5740  SMLoc IDLoc = getLexer().getLoc();
5741  StringRef Name;
5742  if (parseIdentifier(Name))
5743    return TokError("expected identifier in directive");
5744
5745  // Handle the identifier as the key symbol.
5746  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5747
5748  if (getLexer().isNot(AsmToken::Comma))
5749    return TokError("unexpected token in directive");
5750  Lex();
5751
5752  int64_t Size;
5753  SMLoc SizeLoc = getLexer().getLoc();
5754  if (parseAbsoluteExpression(Size))
5755    return true;
5756
5757  int64_t Pow2Alignment = 0;
5758  SMLoc Pow2AlignmentLoc;
5759  if (getLexer().is(AsmToken::Comma)) {
5760    Lex();
5761    Pow2AlignmentLoc = getLexer().getLoc();
5762    if (parseAbsoluteExpression(Pow2Alignment))
5763      return true;
5764
5765    LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
5766    if (IsLocal && LCOMM == LCOMM::NoAlignment)
5767      return Error(Pow2AlignmentLoc, "alignment not supported on this target");
5768
5769    // If this target takes alignments in bytes (not log) validate and convert.
5770    if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
5771        (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
5772      if (!isPowerOf2_64(Pow2Alignment))
5773        return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
5774      Pow2Alignment = Log2_64(Pow2Alignment);
5775    }
5776  }
5777
5778  if (parseToken(AsmToken::EndOfStatement,
5779                 "unexpected token in '.comm' or '.lcomm' directive"))
5780    return true;
5781
5782  // NOTE: a size of zero for a .comm should create a undefined symbol
5783  // but a size of .lcomm creates a bss symbol of size zero.
5784  if (Size < 0)
5785    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
5786                          "be less than zero");
5787
5788  // NOTE: The alignment in the directive is a power of 2 value, the assembler
5789  // may internally end up wanting an alignment in bytes.
5790  // FIXME: Diagnose overflow.
5791  if (Pow2Alignment < 0)
5792    return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
5793                                   "alignment, can't be less than zero");
5794
5795  Sym->redefineIfPossible();
5796  if (!Sym->isUndefined())
5797    return Error(IDLoc, "invalid symbol redefinition");
5798
5799  // Create the Symbol as a common or local common with Size and Pow2Alignment.
5800  if (IsLocal) {
5801    getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
5802    return false;
5803  }
5804
5805  getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
5806  return false;
5807}
5808
5809/// parseDirectiveComment
5810///  ::= comment delimiter [[text]]
5811///              [[text]]
5812///              [[text]] delimiter [[text]]
5813bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
5814  std::string FirstLine = parseStringTo(AsmToken::EndOfStatement);
5815  size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
5816  StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd);
5817  if (Delimiter.empty())
5818    return Error(DirectiveLoc, "no delimiter in 'comment' directive");
5819  do {
5820    if (getTok().is(AsmToken::Eof))
5821      return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
5822    Lex();  // eat end of statement
5823  } while (
5824      !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter));
5825  return parseToken(AsmToken::EndOfStatement,
5826                    "unexpected token in 'comment' directive");
5827}
5828
5829/// parseDirectiveInclude
5830///  ::= include <filename>
5831///    | include filename
5832bool MasmParser::parseDirectiveInclude() {
5833  // Allow the strings to have escaped octal character sequence.
5834  std::string Filename;
5835  SMLoc IncludeLoc = getTok().getLoc();
5836
5837  if (!parseAngleBracketString(Filename))
5838    Filename = parseStringTo(AsmToken::EndOfStatement);
5839  if (check(!Filename.empty(), "missing filename in 'include' directive") ||
5840      check(getTok().isNot(AsmToken::EndOfStatement),
5841            "unexpected token in 'include' directive") ||
5842      // Attempt to switch the lexer to the included file before consuming the
5843      // end of statement to avoid losing it when we switch.
5844      check(enterIncludeFile(Filename), IncludeLoc,
5845            "Could not find include file '" + Filename + "'"))
5846    return true;
5847
5848  return false;
5849}
5850
5851/// parseDirectiveIf
5852/// ::= .if{,eq,ge,gt,le,lt,ne} expression
5853bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
5854  TheCondStack.push_back(TheCondState);
5855  TheCondState.TheCond = AsmCond::IfCond;
5856  if (TheCondState.Ignore) {
5857    eatToEndOfStatement();
5858  } else {
5859    int64_t ExprValue;
5860    if (parseAbsoluteExpression(ExprValue) ||
5861        parseToken(AsmToken::EndOfStatement,
5862                   "unexpected token in '.if' directive"))
5863      return true;
5864
5865    switch (DirKind) {
5866    default:
5867      llvm_unreachable("unsupported directive");
5868    case DK_IF:
5869      break;
5870    case DK_IFE:
5871      ExprValue = ExprValue == 0;
5872      break;
5873    }
5874
5875    TheCondState.CondMet = ExprValue;
5876    TheCondState.Ignore = !TheCondState.CondMet;
5877  }
5878
5879  return false;
5880}
5881
5882/// parseDirectiveIfb
5883/// ::= .ifb textitem
5884bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
5885  TheCondStack.push_back(TheCondState);
5886  TheCondState.TheCond = AsmCond::IfCond;
5887
5888  if (TheCondState.Ignore) {
5889    eatToEndOfStatement();
5890  } else {
5891    std::string Str;
5892    if (parseTextItem(Str))
5893      return TokError("expected text item parameter for 'ifb' directive");
5894
5895    if (parseToken(AsmToken::EndOfStatement,
5896                   "unexpected token in 'ifb' directive"))
5897      return true;
5898
5899    TheCondState.CondMet = ExpectBlank == Str.empty();
5900    TheCondState.Ignore = !TheCondState.CondMet;
5901  }
5902
5903  return false;
5904}
5905
5906/// parseDirectiveIfidn
5907///   ::= ifidn textitem, textitem
5908bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
5909                                     bool CaseInsensitive) {
5910  std::string String1, String2;
5911
5912  if (parseTextItem(String1)) {
5913    if (ExpectEqual)
5914      return TokError("expected text item parameter for 'ifidn' directive");
5915    return TokError("expected text item parameter for 'ifdif' directive");
5916  }
5917
5918  if (Lexer.isNot(AsmToken::Comma)) {
5919    if (ExpectEqual)
5920      return TokError(
5921          "expected comma after first string for 'ifidn' directive");
5922    return TokError("expected comma after first string for 'ifdif' directive");
5923  }
5924  Lex();
5925
5926  if (parseTextItem(String2)) {
5927    if (ExpectEqual)
5928      return TokError("expected text item parameter for 'ifidn' directive");
5929    return TokError("expected text item parameter for 'ifdif' directive");
5930  }
5931
5932  TheCondStack.push_back(TheCondState);
5933  TheCondState.TheCond = AsmCond::IfCond;
5934  if (CaseInsensitive)
5935    TheCondState.CondMet =
5936        ExpectEqual == (StringRef(String1).equals_lower(String2));
5937  else
5938    TheCondState.CondMet = ExpectEqual == (String1 == String2);
5939  TheCondState.Ignore = !TheCondState.CondMet;
5940
5941  return false;
5942}
5943
5944/// parseDirectiveIfdef
5945/// ::= ifdef symbol
5946///   | ifdef variable
5947bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
5948  TheCondStack.push_back(TheCondState);
5949  TheCondState.TheCond = AsmCond::IfCond;
5950
5951  if (TheCondState.Ignore) {
5952    eatToEndOfStatement();
5953  } else {
5954    bool is_defined = false;
5955    unsigned RegNo;
5956    SMLoc StartLoc, EndLoc;
5957    is_defined = (getTargetParser().tryParseRegister(
5958                      RegNo, StartLoc, EndLoc) == MatchOperand_Success);
5959    if (!is_defined) {
5960      StringRef Name;
5961      if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||
5962          parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'"))
5963        return true;
5964
5965      if (Variables.find(Name.lower()) != Variables.end()) {
5966        is_defined = true;
5967      } else {
5968        MCSymbol *Sym = getContext().lookupSymbol(Name.lower());
5969        is_defined = (Sym && !Sym->isUndefined(false));
5970      }
5971    }
5972
5973    TheCondState.CondMet = (is_defined == expect_defined);
5974    TheCondState.Ignore = !TheCondState.CondMet;
5975  }
5976
5977  return false;
5978}
5979
5980/// parseDirectiveElseIf
5981/// ::= elseif expression
5982bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
5983                                      DirectiveKind DirKind) {
5984  if (TheCondState.TheCond != AsmCond::IfCond &&
5985      TheCondState.TheCond != AsmCond::ElseIfCond)
5986    return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5987                               " .if or  an .elseif");
5988  TheCondState.TheCond = AsmCond::ElseIfCond;
5989
5990  bool LastIgnoreState = false;
5991  if (!TheCondStack.empty())
5992    LastIgnoreState = TheCondStack.back().Ignore;
5993  if (LastIgnoreState || TheCondState.CondMet) {
5994    TheCondState.Ignore = true;
5995    eatToEndOfStatement();
5996  } else {
5997    int64_t ExprValue;
5998    if (parseAbsoluteExpression(ExprValue))
5999      return true;
6000
6001    if (parseToken(AsmToken::EndOfStatement,
6002                   "unexpected token in '.elseif' directive"))
6003      return true;
6004
6005    switch (DirKind) {
6006    default:
6007      llvm_unreachable("unsupported directive");
6008    case DK_ELSEIF:
6009      break;
6010    case DK_ELSEIFE:
6011      ExprValue = ExprValue == 0;
6012      break;
6013    }
6014
6015    TheCondState.CondMet = ExprValue;
6016    TheCondState.Ignore = !TheCondState.CondMet;
6017  }
6018
6019  return false;
6020}
6021
6022/// parseDirectiveElseIfb
6023/// ::= elseifb textitem
6024bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
6025  if (TheCondState.TheCond != AsmCond::IfCond &&
6026      TheCondState.TheCond != AsmCond::ElseIfCond)
6027    return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
6028                               " if or an elseif");
6029  TheCondState.TheCond = AsmCond::ElseIfCond;
6030
6031  bool LastIgnoreState = false;
6032  if (!TheCondStack.empty())
6033    LastIgnoreState = TheCondStack.back().Ignore;
6034  if (LastIgnoreState || TheCondState.CondMet) {
6035    TheCondState.Ignore = true;
6036    eatToEndOfStatement();
6037  } else {
6038    std::string Str;
6039    if (parseTextItem(Str)) {
6040      if (ExpectBlank)
6041        return TokError("expected text item parameter for 'elseifb' directive");
6042      return TokError("expected text item parameter for 'elseifnb' directive");
6043    }
6044
6045    if (parseToken(AsmToken::EndOfStatement,
6046                   "unexpected token in 'elseifb' directive"))
6047      return true;
6048
6049    TheCondState.CondMet = ExpectBlank == Str.empty();
6050    TheCondState.Ignore = !TheCondState.CondMet;
6051  }
6052
6053  return false;
6054}
6055
6056/// parseDirectiveElseIfdef
6057/// ::= elseifdef symbol
6058///   | elseifdef variable
6059bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
6060                                         bool expect_defined) {
6061  if (TheCondState.TheCond != AsmCond::IfCond &&
6062      TheCondState.TheCond != AsmCond::ElseIfCond)
6063    return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
6064                               " if or an elseif");
6065  TheCondState.TheCond = AsmCond::ElseIfCond;
6066
6067  bool LastIgnoreState = false;
6068  if (!TheCondStack.empty())
6069    LastIgnoreState = TheCondStack.back().Ignore;
6070  if (LastIgnoreState || TheCondState.CondMet) {
6071    TheCondState.Ignore = true;
6072    eatToEndOfStatement();
6073  } else {
6074    bool is_defined = false;
6075    unsigned RegNo;
6076    SMLoc StartLoc, EndLoc;
6077    is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
6078                  MatchOperand_Success);
6079    if (!is_defined) {
6080      StringRef Name;
6081      if (check(parseIdentifier(Name),
6082                "expected identifier after 'elseifdef'") ||
6083          parseToken(AsmToken::EndOfStatement,
6084                     "unexpected token in 'elseifdef'"))
6085        return true;
6086
6087      if (Variables.find(Name.lower()) != Variables.end()) {
6088        is_defined = true;
6089      } else {
6090        MCSymbol *Sym = getContext().lookupSymbol(Name);
6091        is_defined = (Sym && !Sym->isUndefined(false));
6092      }
6093    }
6094
6095    TheCondState.CondMet = (is_defined == expect_defined);
6096    TheCondState.Ignore = !TheCondState.CondMet;
6097  }
6098
6099  return false;
6100}
6101
6102/// parseDirectiveElseIfidn
6103/// ::= elseifidn textitem, textitem
6104bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6105                                         bool CaseInsensitive) {
6106  if (TheCondState.TheCond != AsmCond::IfCond &&
6107      TheCondState.TheCond != AsmCond::ElseIfCond)
6108    return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
6109                               " if or an elseif");
6110  TheCondState.TheCond = AsmCond::ElseIfCond;
6111
6112  bool LastIgnoreState = false;
6113  if (!TheCondStack.empty())
6114    LastIgnoreState = TheCondStack.back().Ignore;
6115  if (LastIgnoreState || TheCondState.CondMet) {
6116    TheCondState.Ignore = true;
6117    eatToEndOfStatement();
6118  } else {
6119    std::string String1, String2;
6120
6121    if (parseTextItem(String1)) {
6122      if (ExpectEqual)
6123        return TokError(
6124            "expected text item parameter for 'elseifidn' directive");
6125      return TokError("expected text item parameter for 'elseifdif' directive");
6126    }
6127
6128    if (Lexer.isNot(AsmToken::Comma)) {
6129      if (ExpectEqual)
6130        return TokError(
6131            "expected comma after first string for 'elseifidn' directive");
6132      return TokError(
6133          "expected comma after first string for 'elseifdif' directive");
6134    }
6135    Lex();
6136
6137    if (parseTextItem(String2)) {
6138      if (ExpectEqual)
6139        return TokError(
6140            "expected text item parameter for 'elseifidn' directive");
6141      return TokError("expected text item parameter for 'elseifdif' directive");
6142    }
6143
6144    if (CaseInsensitive)
6145      TheCondState.CondMet =
6146          ExpectEqual == (StringRef(String1).equals_lower(String2));
6147    else
6148      TheCondState.CondMet = ExpectEqual == (String1 == String2);
6149    TheCondState.Ignore = !TheCondState.CondMet;
6150  }
6151
6152  return false;
6153}
6154
6155/// parseDirectiveElse
6156/// ::= else
6157bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
6158  if (parseToken(AsmToken::EndOfStatement,
6159                 "unexpected token in 'else' directive"))
6160    return true;
6161
6162  if (TheCondState.TheCond != AsmCond::IfCond &&
6163      TheCondState.TheCond != AsmCond::ElseIfCond)
6164    return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"
6165                               " or an elseif");
6166  TheCondState.TheCond = AsmCond::ElseCond;
6167  bool LastIgnoreState = false;
6168  if (!TheCondStack.empty())
6169    LastIgnoreState = TheCondStack.back().Ignore;
6170  if (LastIgnoreState || TheCondState.CondMet)
6171    TheCondState.Ignore = true;
6172  else
6173    TheCondState.Ignore = false;
6174
6175  return false;
6176}
6177
6178/// parseDirectiveEnd
6179/// ::= end
6180bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
6181  if (parseToken(AsmToken::EndOfStatement,
6182                 "unexpected token in 'end' directive"))
6183    return true;
6184
6185  while (Lexer.isNot(AsmToken::Eof))
6186    Lexer.Lex();
6187
6188  return false;
6189}
6190
6191/// parseDirectiveError
6192///   ::= .err [message]
6193bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
6194  if (!TheCondStack.empty()) {
6195    if (TheCondStack.back().Ignore) {
6196      eatToEndOfStatement();
6197      return false;
6198    }
6199  }
6200
6201  std::string Message = ".err directive invoked in source file";
6202  if (Lexer.isNot(AsmToken::EndOfStatement))
6203    Message = parseStringTo(AsmToken::EndOfStatement);
6204  Lex();
6205
6206  return Error(DirectiveLoc, Message);
6207}
6208
6209/// parseDirectiveErrorIfb
6210///   ::= .errb textitem[, message]
6211bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
6212  if (!TheCondStack.empty()) {
6213    if (TheCondStack.back().Ignore) {
6214      eatToEndOfStatement();
6215      return false;
6216    }
6217  }
6218
6219  std::string Text;
6220  if (parseTextItem(Text))
6221    return Error(getTok().getLoc(), "missing text item in '.errb' directive");
6222
6223  std::string Message = ".errb directive invoked in source file";
6224  if (Lexer.isNot(AsmToken::EndOfStatement)) {
6225    if (parseToken(AsmToken::Comma))
6226      return addErrorSuffix(" in '.errb' directive");
6227    Message = parseStringTo(AsmToken::EndOfStatement);
6228  }
6229  Lex();
6230
6231  if (Text.empty() == ExpectBlank)
6232    return Error(DirectiveLoc, Message);
6233  return false;
6234}
6235
6236/// parseDirectiveErrorIfdef
6237///   ::= .errdef name[, message]
6238bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
6239                                          bool ExpectDefined) {
6240  if (!TheCondStack.empty()) {
6241    if (TheCondStack.back().Ignore) {
6242      eatToEndOfStatement();
6243      return false;
6244    }
6245  }
6246
6247  bool IsDefined = false;
6248  unsigned RegNo;
6249  SMLoc StartLoc, EndLoc;
6250  IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) ==
6251               MatchOperand_Success);
6252  if (!IsDefined) {
6253    StringRef Name;
6254    if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))
6255      return true;
6256
6257    if (Variables.find(Name.lower()) != Variables.end()) {
6258      IsDefined = true;
6259    } else {
6260      MCSymbol *Sym = getContext().lookupSymbol(Name);
6261      IsDefined = (Sym && !Sym->isUndefined(false));
6262    }
6263  }
6264
6265  std::string Message = ".errdef directive invoked in source file";
6266  if (Lexer.isNot(AsmToken::EndOfStatement)) {
6267    if (parseToken(AsmToken::Comma))
6268      return addErrorSuffix(" in '.errdef' directive");
6269    Message = parseStringTo(AsmToken::EndOfStatement);
6270  }
6271  Lex();
6272
6273  if (IsDefined == ExpectDefined)
6274    return Error(DirectiveLoc, Message);
6275  return false;
6276}
6277
6278/// parseDirectiveErrorIfidn
6279///   ::= .erridn textitem, textitem[, message]
6280bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
6281                                          bool CaseInsensitive) {
6282  if (!TheCondStack.empty()) {
6283    if (TheCondStack.back().Ignore) {
6284      eatToEndOfStatement();
6285      return false;
6286    }
6287  }
6288
6289  std::string String1, String2;
6290
6291  if (parseTextItem(String1)) {
6292    if (ExpectEqual)
6293      return TokError("expected string parameter for '.erridn' directive");
6294    return TokError("expected string parameter for '.errdif' directive");
6295  }
6296
6297  if (Lexer.isNot(AsmToken::Comma)) {
6298    if (ExpectEqual)
6299      return TokError(
6300          "expected comma after first string for '.erridn' directive");
6301    return TokError(
6302        "expected comma after first string for '.errdif' directive");
6303  }
6304  Lex();
6305
6306  if (parseTextItem(String2)) {
6307    if (ExpectEqual)
6308      return TokError("expected string parameter for '.erridn' directive");
6309    return TokError("expected string parameter for '.errdif' directive");
6310  }
6311
6312  std::string Message;
6313  if (ExpectEqual)
6314    Message = ".erridn directive invoked in source file";
6315  else
6316    Message = ".errdif directive invoked in source file";
6317  if (Lexer.isNot(AsmToken::EndOfStatement)) {
6318    if (parseToken(AsmToken::Comma))
6319      return addErrorSuffix(" in '.erridn' directive");
6320    Message = parseStringTo(AsmToken::EndOfStatement);
6321  }
6322  Lex();
6323
6324  if (CaseInsensitive)
6325    TheCondState.CondMet =
6326        ExpectEqual == (StringRef(String1).equals_lower(String2));
6327  else
6328    TheCondState.CondMet = ExpectEqual == (String1 == String2);
6329  TheCondState.Ignore = !TheCondState.CondMet;
6330
6331  if ((CaseInsensitive &&
6332       ExpectEqual == StringRef(String1).equals_lower(String2)) ||
6333      (ExpectEqual == (String1 == String2)))
6334    return Error(DirectiveLoc, Message);
6335  return false;
6336}
6337
6338/// parseDirectiveErrorIfe
6339///   ::= .erre expression[, message]
6340bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
6341  if (!TheCondStack.empty()) {
6342    if (TheCondStack.back().Ignore) {
6343      eatToEndOfStatement();
6344      return false;
6345    }
6346  }
6347
6348  int64_t ExprValue;
6349  if (parseAbsoluteExpression(ExprValue))
6350    return addErrorSuffix(" in '.erre' directive");
6351
6352  std::string Message = ".erre directive invoked in source file";
6353  if (Lexer.isNot(AsmToken::EndOfStatement)) {
6354    if (parseToken(AsmToken::Comma))
6355      return addErrorSuffix(" in '.erre' directive");
6356    Message = parseStringTo(AsmToken::EndOfStatement);
6357  }
6358  Lex();
6359
6360  if ((ExprValue == 0) == ExpectZero)
6361    return Error(DirectiveLoc, Message);
6362  return false;
6363}
6364
6365/// parseDirectiveEndIf
6366/// ::= .endif
6367bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
6368  if (parseToken(AsmToken::EndOfStatement,
6369                 "unexpected token in '.endif' directive"))
6370    return true;
6371
6372  if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
6373    return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
6374                               "an .if or .else");
6375  if (!TheCondStack.empty()) {
6376    TheCondState = TheCondStack.back();
6377    TheCondStack.pop_back();
6378  }
6379
6380  return false;
6381}
6382
6383void MasmParser::initializeDirectiveKindMap() {
6384  DirectiveKindMap["="] = DK_ASSIGN;
6385  DirectiveKindMap["equ"] = DK_EQU;
6386  DirectiveKindMap["textequ"] = DK_TEXTEQU;
6387  // DirectiveKindMap[".ascii"] = DK_ASCII;
6388  // DirectiveKindMap[".asciz"] = DK_ASCIZ;
6389  // DirectiveKindMap[".string"] = DK_STRING;
6390  DirectiveKindMap["byte"] = DK_BYTE;
6391  DirectiveKindMap["sbyte"] = DK_SBYTE;
6392  DirectiveKindMap["word"] = DK_WORD;
6393  DirectiveKindMap["sword"] = DK_SWORD;
6394  DirectiveKindMap["dword"] = DK_DWORD;
6395  DirectiveKindMap["sdword"] = DK_SDWORD;
6396  DirectiveKindMap["fword"] = DK_FWORD;
6397  DirectiveKindMap["qword"] = DK_QWORD;
6398  DirectiveKindMap["sqword"] = DK_SQWORD;
6399  DirectiveKindMap["real4"] = DK_REAL4;
6400  DirectiveKindMap["real8"] = DK_REAL8;
6401  DirectiveKindMap["real10"] = DK_REAL10;
6402  DirectiveKindMap["align"] = DK_ALIGN;
6403  // DirectiveKindMap[".org"] = DK_ORG;
6404  DirectiveKindMap["extern"] = DK_EXTERN;
6405  DirectiveKindMap["public"] = DK_PUBLIC;
6406  // DirectiveKindMap[".comm"] = DK_COMM;
6407  DirectiveKindMap["comment"] = DK_COMMENT;
6408  DirectiveKindMap["include"] = DK_INCLUDE;
6409  DirectiveKindMap["repeat"] = DK_REPEAT;
6410  DirectiveKindMap["rept"] = DK_REPEAT;
6411  DirectiveKindMap["while"] = DK_WHILE;
6412  DirectiveKindMap["for"] = DK_FOR;
6413  DirectiveKindMap["irp"] = DK_FOR;
6414  DirectiveKindMap["forc"] = DK_FORC;
6415  DirectiveKindMap["irpc"] = DK_FORC;
6416  DirectiveKindMap["if"] = DK_IF;
6417  DirectiveKindMap["ife"] = DK_IFE;
6418  DirectiveKindMap["ifb"] = DK_IFB;
6419  DirectiveKindMap["ifnb"] = DK_IFNB;
6420  DirectiveKindMap["ifdef"] = DK_IFDEF;
6421  DirectiveKindMap["ifndef"] = DK_IFNDEF;
6422  DirectiveKindMap["ifdif"] = DK_IFDIF;
6423  DirectiveKindMap["ifdifi"] = DK_IFDIFI;
6424  DirectiveKindMap["ifidn"] = DK_IFIDN;
6425  DirectiveKindMap["ifidni"] = DK_IFIDNI;
6426  DirectiveKindMap["elseif"] = DK_ELSEIF;
6427  DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;
6428  DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;
6429  DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;
6430  DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;
6431  DirectiveKindMap["else"] = DK_ELSE;
6432  DirectiveKindMap["end"] = DK_END;
6433  DirectiveKindMap["endif"] = DK_ENDIF;
6434  // DirectiveKindMap[".file"] = DK_FILE;
6435  // DirectiveKindMap[".line"] = DK_LINE;
6436  // DirectiveKindMap[".loc"] = DK_LOC;
6437  // DirectiveKindMap[".stabs"] = DK_STABS;
6438  // DirectiveKindMap[".cv_file"] = DK_CV_FILE;
6439  // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
6440  // DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
6441  // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
6442  // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
6443  // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
6444  // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
6445  // DirectiveKindMap[".cv_string"] = DK_CV_STRING;
6446  // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
6447  // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
6448  // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
6449  // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
6450  // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
6451  // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
6452  // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
6453  // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
6454  // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
6455  // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
6456  // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
6457  // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
6458  // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
6459  // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
6460  // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
6461  // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
6462  // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
6463  // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
6464  // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
6465  // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
6466  // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
6467  // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
6468  // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
6469  // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
6470  // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
6471  // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
6472  DirectiveKindMap["macro"] = DK_MACRO;
6473  DirectiveKindMap["exitm"] = DK_EXITM;
6474  DirectiveKindMap["endm"] = DK_ENDM;
6475  DirectiveKindMap["purge"] = DK_PURGE;
6476  DirectiveKindMap[".err"] = DK_ERR;
6477  DirectiveKindMap[".errb"] = DK_ERRB;
6478  DirectiveKindMap[".errnb"] = DK_ERRNB;
6479  DirectiveKindMap[".errdef"] = DK_ERRDEF;
6480  DirectiveKindMap[".errndef"] = DK_ERRNDEF;
6481  DirectiveKindMap[".errdif"] = DK_ERRDIF;
6482  DirectiveKindMap[".errdifi"] = DK_ERRDIFI;
6483  DirectiveKindMap[".erridn"] = DK_ERRIDN;
6484  DirectiveKindMap[".erridni"] = DK_ERRIDNI;
6485  DirectiveKindMap[".erre"] = DK_ERRE;
6486  DirectiveKindMap[".errnz"] = DK_ERRNZ;
6487  DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
6488  DirectiveKindMap[".pushreg"] = DK_PUSHREG;
6489  DirectiveKindMap[".savereg"] = DK_SAVEREG;
6490  DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
6491  DirectiveKindMap[".setframe"] = DK_SETFRAME;
6492  DirectiveKindMap[".radix"] = DK_RADIX;
6493  DirectiveKindMap["db"] = DK_DB;
6494  DirectiveKindMap["dd"] = DK_DD;
6495  DirectiveKindMap["df"] = DK_DF;
6496  DirectiveKindMap["dq"] = DK_DQ;
6497  DirectiveKindMap["dw"] = DK_DW;
6498  DirectiveKindMap["echo"] = DK_ECHO;
6499  DirectiveKindMap["struc"] = DK_STRUCT;
6500  DirectiveKindMap["struct"] = DK_STRUCT;
6501  DirectiveKindMap["union"] = DK_UNION;
6502  DirectiveKindMap["ends"] = DK_ENDS;
6503}
6504
6505bool MasmParser::isMacroLikeDirective() {
6506  if (getLexer().is(AsmToken::Identifier)) {
6507    bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier())
6508                           .CasesLower("repeat", "rept", true)
6509                           .CaseLower("while", true)
6510                           .CasesLower("for", "irp", true)
6511                           .CasesLower("forc", "irpc", true)
6512                           .Default(false);
6513    if (IsMacroLike)
6514      return true;
6515  }
6516  if (getLexer().peekTok().is(AsmToken::Identifier) &&
6517      getLexer().peekTok().getIdentifier().equals_lower("macro"))
6518    return true;
6519
6520  return false;
6521}
6522
6523MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
6524  AsmToken EndToken, StartToken = getTok();
6525
6526  unsigned NestLevel = 0;
6527  while (true) {
6528    // Check whether we have reached the end of the file.
6529    if (getLexer().is(AsmToken::Eof)) {
6530      printError(DirectiveLoc, "no matching 'endm' in definition");
6531      return nullptr;
6532    }
6533
6534    if (isMacroLikeDirective())
6535      ++NestLevel;
6536
6537    // Otherwise, check whether we have reached the endm.
6538    if (Lexer.is(AsmToken::Identifier) &&
6539        getTok().getIdentifier().equals_lower("endm")) {
6540      if (NestLevel == 0) {
6541        EndToken = getTok();
6542        Lex();
6543        if (Lexer.isNot(AsmToken::EndOfStatement)) {
6544          printError(getTok().getLoc(), "unexpected token in 'endm' directive");
6545          return nullptr;
6546        }
6547        break;
6548      }
6549      --NestLevel;
6550    }
6551
6552    // Otherwise, scan till the end of the statement.
6553    eatToEndOfStatement();
6554  }
6555
6556  const char *BodyStart = StartToken.getLoc().getPointer();
6557  const char *BodyEnd = EndToken.getLoc().getPointer();
6558  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
6559
6560  // We Are Anonymous.
6561  MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
6562  return &MacroLikeBodies.back();
6563}
6564
6565bool MasmParser::expandStatement(SMLoc Loc) {
6566  std::string Body = parseStringTo(AsmToken::EndOfStatement);
6567  SMLoc EndLoc = getTok().getLoc();
6568
6569  MCAsmMacroParameters Parameters;
6570  MCAsmMacroArguments Arguments;
6571  for (const auto &V : Variables) {
6572    const Variable &Var = V.getValue();
6573    if (Var.IsText) {
6574      Parameters.emplace_back();
6575      Arguments.emplace_back();
6576      MCAsmMacroParameter &P = Parameters.back();
6577      MCAsmMacroArgument &A = Arguments.back();
6578      P.Name = Var.Name;
6579      P.Required = true;
6580      A.push_back(AsmToken(AsmToken::String, Var.TextValue));
6581    }
6582  }
6583  MacroLikeBodies.emplace_back(StringRef(), Body, Parameters);
6584  MCAsmMacro M = MacroLikeBodies.back();
6585
6586  // Expand the statement in a new buffer.
6587  SmallString<80> Buf;
6588  raw_svector_ostream OS(Buf);
6589  if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc))
6590    return true;
6591  std::unique_ptr<MemoryBuffer> Expansion =
6592      MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>");
6593
6594  // Jump to the expanded statement and prime the lexer.
6595  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc);
6596  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
6597  EndStatementAtEOFStack.push_back(false);
6598  Lex();
6599  return false;
6600}
6601
6602void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6603                                          raw_svector_ostream &OS) {
6604  instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS);
6605}
6606void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
6607                                          SMLoc ExitLoc,
6608                                          raw_svector_ostream &OS) {
6609  OS << "endm\n";
6610
6611  std::unique_ptr<MemoryBuffer> Instantiation =
6612      MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
6613
6614  // Create the macro instantiation object and add to the current macro
6615  // instantiation stack.
6616  MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,
6617                                                  ExitLoc, TheCondStack.size()};
6618  ActiveMacros.push_back(MI);
6619
6620  // Jump to the macro instantiation and prime the lexer.
6621  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
6622  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
6623  EndStatementAtEOFStack.push_back(true);
6624  Lex();
6625}
6626
6627/// parseDirectiveRepeat
6628///   ::= ("repeat" | "rept") count
6629///       body
6630///     endm
6631bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
6632  const MCExpr *CountExpr;
6633  SMLoc CountLoc = getTok().getLoc();
6634  if (parseExpression(CountExpr))
6635    return true;
6636
6637  int64_t Count;
6638  if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
6639    return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
6640  }
6641
6642  if (check(Count < 0, CountLoc, "Count is negative") ||
6643      parseToken(AsmToken::EndOfStatement,
6644                 "unexpected token in '" + Dir + "' directive"))
6645    return true;
6646
6647  // Lex the repeat definition.
6648  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6649  if (!M)
6650    return true;
6651
6652  // Macro instantiation is lexical, unfortunately. We construct a new buffer
6653  // to hold the macro body with substitutions.
6654  SmallString<256> Buf;
6655  raw_svector_ostream OS(Buf);
6656  while (Count--) {
6657    if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
6658      return true;
6659  }
6660  instantiateMacroLikeBody(M, DirectiveLoc, OS);
6661
6662  return false;
6663}
6664
6665/// parseDirectiveWhile
6666/// ::= "while" expression
6667///       body
6668///     endm
6669bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
6670  const MCExpr *CondExpr;
6671  SMLoc CondLoc = getTok().getLoc();
6672  if (parseExpression(CondExpr))
6673    return true;
6674
6675  // Lex the repeat definition.
6676  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6677  if (!M)
6678    return true;
6679
6680  // Macro instantiation is lexical, unfortunately. We construct a new buffer
6681  // to hold the macro body with substitutions.
6682  SmallString<256> Buf;
6683  raw_svector_ostream OS(Buf);
6684  int64_t Condition;
6685  if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
6686    return Error(CondLoc, "expected absolute expression in 'while' directive");
6687  if (Condition) {
6688    // Instantiate the macro, then resume at this directive to recheck the
6689    // condition.
6690    if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc()))
6691      return true;
6692    instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
6693  }
6694
6695  return false;
6696}
6697
6698/// parseDirectiveFor
6699/// ::= ("for" | "irp") symbol [":" qualifier], <values>
6700///       body
6701///     endm
6702bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
6703  MCAsmMacroParameter Parameter;
6704  MCAsmMacroArguments A;
6705  if (check(parseIdentifier(Parameter.Name),
6706            "expected identifier in '" + Dir + "' directive"))
6707    return true;
6708
6709  // Parse optional qualifier (default value, or "req")
6710  if (parseOptionalToken(AsmToken::Colon)) {
6711    if (parseOptionalToken(AsmToken::Equal)) {
6712      // Default value
6713      SMLoc ParamLoc;
6714
6715      ParamLoc = Lexer.getLoc();
6716      if (parseMacroArgument(nullptr, Parameter.Value))
6717        return true;
6718    } else {
6719      SMLoc QualLoc;
6720      StringRef Qualifier;
6721
6722      QualLoc = Lexer.getLoc();
6723      if (parseIdentifier(Qualifier))
6724        return Error(QualLoc, "missing parameter qualifier for "
6725                              "'" +
6726                                  Parameter.Name + "' in '" + Dir +
6727                                  "' directive");
6728
6729      if (Qualifier.equals_lower("req"))
6730        Parameter.Required = true;
6731      else
6732        return Error(QualLoc,
6733                     Qualifier + " is not a valid parameter qualifier for '" +
6734                         Parameter.Name + "' in '" + Dir + "' directive");
6735    }
6736  }
6737
6738  if (parseToken(AsmToken::Comma,
6739                 "expected comma in '" + Dir + "' directive") ||
6740      parseToken(AsmToken::Less,
6741                 "values in '" + Dir +
6742                     "' directive must be enclosed in angle brackets"))
6743    return true;
6744
6745  while (true) {
6746    A.emplace_back();
6747    if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater))
6748      return addErrorSuffix(" in arguments for '" + Dir + "' directive");
6749
6750    // If we see a comma, continue, and allow line continuation.
6751    if (!parseOptionalToken(AsmToken::Comma))
6752      break;
6753    parseOptionalToken(AsmToken::EndOfStatement);
6754  }
6755
6756  if (parseToken(AsmToken::Greater,
6757                 "values in '" + Dir +
6758                     "' directive must be enclosed in angle brackets") ||
6759      parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
6760    return true;
6761
6762  // Lex the for definition.
6763  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6764  if (!M)
6765    return true;
6766
6767  // Macro instantiation is lexical, unfortunately. We construct a new buffer
6768  // to hold the macro body with substitutions.
6769  SmallString<256> Buf;
6770  raw_svector_ostream OS(Buf);
6771
6772  for (const MCAsmMacroArgument &Arg : A) {
6773    if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
6774      return true;
6775  }
6776
6777  instantiateMacroLikeBody(M, DirectiveLoc, OS);
6778
6779  return false;
6780}
6781
6782/// parseDirectiveForc
6783/// ::= ("forc" | "irpc") symbol, <string>
6784///       body
6785///     endm
6786bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
6787  MCAsmMacroParameter Parameter;
6788
6789  std::string Argument;
6790  if (check(parseIdentifier(Parameter.Name),
6791            "expected identifier in '" + Directive + "' directive") ||
6792      parseToken(AsmToken::Comma,
6793                 "expected comma in '" + Directive + "' directive"))
6794    return true;
6795  if (parseAngleBracketString(Argument)) {
6796    // Match ml64.exe; treat all characters to end of statement as a string,
6797    // ignoring comment markers, then discard anything following a space (using
6798    // the C locale).
6799    Argument = parseStringTo(AsmToken::EndOfStatement);
6800    if (getTok().is(AsmToken::EndOfStatement))
6801      Argument += getTok().getString();
6802    size_t End = 0;
6803    for (; End < Argument.size(); ++End) {
6804      if (isSpace(Argument[End]))
6805        break;
6806    }
6807    Argument.resize(End);
6808  }
6809  if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
6810    return true;
6811
6812  // Lex the irpc definition.
6813  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
6814  if (!M)
6815    return true;
6816
6817  // Macro instantiation is lexical, unfortunately. We construct a new buffer
6818  // to hold the macro body with substitutions.
6819  SmallString<256> Buf;
6820  raw_svector_ostream OS(Buf);
6821
6822  StringRef Values(Argument);
6823  for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
6824    MCAsmMacroArgument Arg;
6825    Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
6826
6827    if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
6828      return true;
6829  }
6830
6831  instantiateMacroLikeBody(M, DirectiveLoc, OS);
6832
6833  return false;
6834}
6835
6836bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
6837                                      size_t Len) {
6838  const MCExpr *Value;
6839  SMLoc ExprLoc = getLexer().getLoc();
6840  if (parseExpression(Value))
6841    return true;
6842  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
6843  if (!MCE)
6844    return Error(ExprLoc, "unexpected expression in _emit");
6845  uint64_t IntValue = MCE->getValue();
6846  if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
6847    return Error(ExprLoc, "literal value out of range for directive");
6848
6849  Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
6850  return false;
6851}
6852
6853bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
6854  const MCExpr *Value;
6855  SMLoc ExprLoc = getLexer().getLoc();
6856  if (parseExpression(Value))
6857    return true;
6858  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
6859  if (!MCE)
6860    return Error(ExprLoc, "unexpected expression in align");
6861  uint64_t IntValue = MCE->getValue();
6862  if (!isPowerOf2_64(IntValue))
6863    return Error(ExprLoc, "literal value not a power of two greater then zero");
6864
6865  Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
6866  return false;
6867}
6868
6869bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {
6870  const SMLoc Loc = getLexer().getLoc();
6871  std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement);
6872  StringRef RadixString = StringRef(RadixStringRaw).trim();
6873  unsigned Radix;
6874  if (RadixString.getAsInteger(10, Radix)) {
6875    return Error(Loc,
6876                 "radix must be a decimal number in the range 2 to 16; was " +
6877                     RadixString);
6878  }
6879  if (Radix < 2 || Radix > 16)
6880    return Error(Loc, "radix must be in the range 2 to 16; was " +
6881                          std::to_string(Radix));
6882  getLexer().setMasmDefaultRadix(Radix);
6883  return false;
6884}
6885
6886/// parseDirectiveEcho
6887///   ::= "echo" message
6888bool MasmParser::parseDirectiveEcho() {
6889  // We're called before the directive is parsed, to avoid triggering lexical
6890  // substitutions in the message. Assert that the next token is the directive,
6891  // then eat it without using the Parser's Lex method.
6892  assert(getTok().is(AsmToken::Identifier) &&
6893         getTok().getString().equals_lower("echo"));
6894  Lexer.Lex();
6895
6896  std::string Message = parseStringTo(AsmToken::EndOfStatement);
6897  llvm::outs() << Message;
6898  if (!StringRef(Message).endswith("\n"))
6899    llvm::outs() << '\n';
6900  return false;
6901}
6902
6903// We are comparing pointers, but the pointers are relative to a single string.
6904// Thus, this should always be deterministic.
6905static int rewritesSort(const AsmRewrite *AsmRewriteA,
6906                        const AsmRewrite *AsmRewriteB) {
6907  if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
6908    return -1;
6909  if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
6910    return 1;
6911
6912  // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
6913  // rewrite to the same location.  Make sure the SizeDirective rewrite is
6914  // performed first, then the Imm/ImmPrefix and finally the Input/Output.  This
6915  // ensures the sort algorithm is stable.
6916  if (AsmRewritePrecedence[AsmRewriteA->Kind] >
6917      AsmRewritePrecedence[AsmRewriteB->Kind])
6918    return -1;
6919
6920  if (AsmRewritePrecedence[AsmRewriteA->Kind] <
6921      AsmRewritePrecedence[AsmRewriteB->Kind])
6922    return 1;
6923  llvm_unreachable("Unstable rewrite sort.");
6924}
6925
6926bool MasmParser::defineMacro(StringRef Name, StringRef Value) {
6927  Variable &Var = Variables[Name.lower()];
6928  if (Var.Name.empty()) {
6929    Var.Name = Name;
6930  } else if (!Var.Redefinable) {
6931    return TokError("invalid variable redefinition");
6932  }
6933  Var.Redefinable = true;
6934  Var.IsText = true;
6935  Var.TextValue = Value.str();
6936  return false;
6937}
6938
6939bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {
6940  const std::pair<StringRef, StringRef> BaseMember = Name.split('.');
6941  const StringRef Base = BaseMember.first, Member = BaseMember.second;
6942  return lookUpField(Base, Member, Info);
6943}
6944
6945bool MasmParser::lookUpField(StringRef Base, StringRef Member,
6946                             AsmFieldInfo &Info) const {
6947  if (Base.empty())
6948    return true;
6949
6950  AsmFieldInfo BaseInfo;
6951  if (Base.contains('.') && !lookUpField(Base, BaseInfo))
6952    Base = BaseInfo.Type.Name;
6953
6954  auto StructIt = Structs.find(Base.lower());
6955  auto TypeIt = KnownType.find(Base.lower());
6956  if (TypeIt != KnownType.end()) {
6957    StructIt = Structs.find(TypeIt->second.Name.lower());
6958  }
6959  if (StructIt != Structs.end())
6960    return lookUpField(StructIt->second, Member, Info);
6961
6962  return true;
6963}
6964
6965bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
6966                             AsmFieldInfo &Info) const {
6967  if (Member.empty()) {
6968    Info.Type.Name = Structure.Name;
6969    Info.Type.Size = Structure.Size;
6970    Info.Type.ElementSize = Structure.Size;
6971    Info.Type.Length = 1;
6972    return false;
6973  }
6974
6975  std::pair<StringRef, StringRef> Split = Member.split('.');
6976  const StringRef FieldName = Split.first, FieldMember = Split.second;
6977
6978  auto StructIt = Structs.find(FieldName.lower());
6979  if (StructIt != Structs.end())
6980    return lookUpField(StructIt->second, FieldMember, Info);
6981
6982  auto FieldIt = Structure.FieldsByName.find(FieldName.lower());
6983  if (FieldIt == Structure.FieldsByName.end())
6984    return true;
6985
6986  const FieldInfo &Field = Structure.Fields[FieldIt->second];
6987  if (FieldMember.empty()) {
6988    Info.Offset += Field.Offset;
6989    Info.Type.Size = Field.SizeOf;
6990    Info.Type.ElementSize = Field.Type;
6991    Info.Type.Length = Field.LengthOf;
6992    if (Field.Contents.FT == FT_STRUCT)
6993      Info.Type.Name = Field.Contents.StructInfo.Structure.Name;
6994    else
6995      Info.Type.Name = "";
6996    return false;
6997  }
6998
6999  if (Field.Contents.FT != FT_STRUCT)
7000    return true;
7001  const StructFieldInfo &StructInfo = Field.Contents.StructInfo;
7002
7003  if (lookUpField(StructInfo.Structure, FieldMember, Info))
7004    return true;
7005
7006  Info.Offset += Field.Offset;
7007  return false;
7008}
7009
7010bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
7011  unsigned Size = StringSwitch<unsigned>(Name)
7012                      .CasesLower("byte", "db", "sbyte", 1)
7013                      .CasesLower("word", "dw", "sword", 2)
7014                      .CasesLower("dword", "dd", "sdword", 4)
7015                      .CasesLower("fword", "df", 6)
7016                      .CasesLower("qword", "dq", "sqword", 8)
7017                      .CaseLower("real4", 4)
7018                      .CaseLower("real8", 8)
7019                      .CaseLower("real10", 10)
7020                      .Default(0);
7021  if (Size) {
7022    Info.Name = Name;
7023    Info.ElementSize = Size;
7024    Info.Length = 1;
7025    Info.Size = Size;
7026    return false;
7027  }
7028
7029  auto StructIt = Structs.find(Name.lower());
7030  if (StructIt != Structs.end()) {
7031    const StructInfo &Structure = StructIt->second;
7032    Info.Name = Name;
7033    Info.ElementSize = Structure.Size;
7034    Info.Length = 1;
7035    Info.Size = Structure.Size;
7036    return false;
7037  }
7038
7039  return true;
7040}
7041
7042bool MasmParser::parseMSInlineAsm(
7043    void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
7044    unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
7045    SmallVectorImpl<std::string> &Constraints,
7046    SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
7047    const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
7048  SmallVector<void *, 4> InputDecls;
7049  SmallVector<void *, 4> OutputDecls;
7050  SmallVector<bool, 4> InputDeclsAddressOf;
7051  SmallVector<bool, 4> OutputDeclsAddressOf;
7052  SmallVector<std::string, 4> InputConstraints;
7053  SmallVector<std::string, 4> OutputConstraints;
7054  SmallVector<unsigned, 4> ClobberRegs;
7055
7056  SmallVector<AsmRewrite, 4> AsmStrRewrites;
7057
7058  // Prime the lexer.
7059  Lex();
7060
7061  // While we have input, parse each statement.
7062  unsigned InputIdx = 0;
7063  unsigned OutputIdx = 0;
7064  while (getLexer().isNot(AsmToken::Eof)) {
7065    // Parse curly braces marking block start/end.
7066    if (parseCurlyBlockScope(AsmStrRewrites))
7067      continue;
7068
7069    ParseStatementInfo Info(&AsmStrRewrites);
7070    bool StatementErr = parseStatement(Info, &SI);
7071
7072    if (StatementErr || Info.ParseError) {
7073      // Emit pending errors if any exist.
7074      printPendingErrors();
7075      return true;
7076    }
7077
7078    // No pending error should exist here.
7079    assert(!hasPendingError() && "unexpected error from parseStatement");
7080
7081    if (Info.Opcode == ~0U)
7082      continue;
7083
7084    const MCInstrDesc &Desc = MII->get(Info.Opcode);
7085
7086    // Build the list of clobbers, outputs and inputs.
7087    for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
7088      MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
7089
7090      // Register operand.
7091      if (Operand.isReg() && !Operand.needAddressOf() &&
7092          !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
7093        unsigned NumDefs = Desc.getNumDefs();
7094        // Clobber.
7095        if (NumDefs && Operand.getMCOperandNum() < NumDefs)
7096          ClobberRegs.push_back(Operand.getReg());
7097        continue;
7098      }
7099
7100      // Expr/Input or Output.
7101      StringRef SymName = Operand.getSymName();
7102      if (SymName.empty())
7103        continue;
7104
7105      void *OpDecl = Operand.getOpDecl();
7106      if (!OpDecl)
7107        continue;
7108
7109      StringRef Constraint = Operand.getConstraint();
7110      if (Operand.isImm()) {
7111        // Offset as immediate.
7112        if (Operand.isOffsetOfLocal())
7113          Constraint = "r";
7114        else
7115          Constraint = "i";
7116      }
7117
7118      bool isOutput = (i == 1) && Desc.mayStore();
7119      SMLoc Start = SMLoc::getFromPointer(SymName.data());
7120      if (isOutput) {
7121        ++InputIdx;
7122        OutputDecls.push_back(OpDecl);
7123        OutputDeclsAddressOf.push_back(Operand.needAddressOf());
7124        OutputConstraints.push_back(("=" + Constraint).str());
7125        AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
7126      } else {
7127        InputDecls.push_back(OpDecl);
7128        InputDeclsAddressOf.push_back(Operand.needAddressOf());
7129        InputConstraints.push_back(Constraint.str());
7130        if (Desc.OpInfo[i - 1].isBranchTarget())
7131          AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size());
7132        else
7133          AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
7134      }
7135    }
7136
7137    // Consider implicit defs to be clobbers.  Think of cpuid and push.
7138    ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
7139                                Desc.getNumImplicitDefs());
7140    llvm::append_range(ClobberRegs, ImpDefs);
7141  }
7142
7143  // Set the number of Outputs and Inputs.
7144  NumOutputs = OutputDecls.size();
7145  NumInputs = InputDecls.size();
7146
7147  // Set the unique clobbers.
7148  array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
7149  ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
7150                    ClobberRegs.end());
7151  Clobbers.assign(ClobberRegs.size(), std::string());
7152  for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
7153    raw_string_ostream OS(Clobbers[I]);
7154    IP->printRegName(OS, ClobberRegs[I]);
7155  }
7156
7157  // Merge the various outputs and inputs.  Output are expected first.
7158  if (NumOutputs || NumInputs) {
7159    unsigned NumExprs = NumOutputs + NumInputs;
7160    OpDecls.resize(NumExprs);
7161    Constraints.resize(NumExprs);
7162    for (unsigned i = 0; i < NumOutputs; ++i) {
7163      OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
7164      Constraints[i] = OutputConstraints[i];
7165    }
7166    for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
7167      OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
7168      Constraints[j] = InputConstraints[i];
7169    }
7170  }
7171
7172  // Build the IR assembly string.
7173  std::string AsmStringIR;
7174  raw_string_ostream OS(AsmStringIR);
7175  StringRef ASMString =
7176      SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
7177  const char *AsmStart = ASMString.begin();
7178  const char *AsmEnd = ASMString.end();
7179  array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
7180  for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) {
7181    const AsmRewrite &AR = *it;
7182    // Check if this has already been covered by another rewrite...
7183    if (AR.Done)
7184      continue;
7185    AsmRewriteKind Kind = AR.Kind;
7186
7187    const char *Loc = AR.Loc.getPointer();
7188    assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
7189
7190    // Emit everything up to the immediate/expression.
7191    if (unsigned Len = Loc - AsmStart)
7192      OS << StringRef(AsmStart, Len);
7193
7194    // Skip the original expression.
7195    if (Kind == AOK_Skip) {
7196      AsmStart = Loc + AR.Len;
7197      continue;
7198    }
7199
7200    unsigned AdditionalSkip = 0;
7201    // Rewrite expressions in $N notation.
7202    switch (Kind) {
7203    default:
7204      break;
7205    case AOK_IntelExpr:
7206      assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
7207      if (AR.IntelExp.NeedBracs)
7208        OS << "[";
7209      if (AR.IntelExp.hasBaseReg())
7210        OS << AR.IntelExp.BaseReg;
7211      if (AR.IntelExp.hasIndexReg())
7212        OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
7213           << AR.IntelExp.IndexReg;
7214      if (AR.IntelExp.Scale > 1)
7215        OS << " * $$" << AR.IntelExp.Scale;
7216      if (AR.IntelExp.hasOffset()) {
7217        if (AR.IntelExp.hasRegs())
7218          OS << " + ";
7219        // Fuse this rewrite with a rewrite of the offset name, if present.
7220        StringRef OffsetName = AR.IntelExp.OffsetName;
7221        SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data());
7222        size_t OffsetLen = OffsetName.size();
7223        auto rewrite_it = std::find_if(
7224            it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
7225              return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
7226                     (FusingAR.Kind == AOK_Input ||
7227                      FusingAR.Kind == AOK_CallInput);
7228            });
7229        if (rewrite_it == AsmStrRewrites.end()) {
7230          OS << "offset " << OffsetName;
7231        } else if (rewrite_it->Kind == AOK_CallInput) {
7232          OS << "${" << InputIdx++ << ":P}";
7233          rewrite_it->Done = true;
7234        } else {
7235          OS << '$' << InputIdx++;
7236          rewrite_it->Done = true;
7237        }
7238      }
7239      if (AR.IntelExp.Imm || AR.IntelExp.emitImm())
7240        OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm;
7241      if (AR.IntelExp.NeedBracs)
7242        OS << "]";
7243      break;
7244    case AOK_Label:
7245      OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
7246      break;
7247    case AOK_Input:
7248      OS << '$' << InputIdx++;
7249      break;
7250    case AOK_CallInput:
7251      OS << "${" << InputIdx++ << ":P}";
7252      break;
7253    case AOK_Output:
7254      OS << '$' << OutputIdx++;
7255      break;
7256    case AOK_SizeDirective:
7257      switch (AR.Val) {
7258      default: break;
7259      case 8:  OS << "byte ptr "; break;
7260      case 16: OS << "word ptr "; break;
7261      case 32: OS << "dword ptr "; break;
7262      case 64: OS << "qword ptr "; break;
7263      case 80: OS << "xword ptr "; break;
7264      case 128: OS << "xmmword ptr "; break;
7265      case 256: OS << "ymmword ptr "; break;
7266      }
7267      break;
7268    case AOK_Emit:
7269      OS << ".byte";
7270      break;
7271    case AOK_Align: {
7272      // MS alignment directives are measured in bytes. If the native assembler
7273      // measures alignment in bytes, we can pass it straight through.
7274      OS << ".align";
7275      if (getContext().getAsmInfo()->getAlignmentIsInBytes())
7276        break;
7277
7278      // Alignment is in log2 form, so print that instead and skip the original
7279      // immediate.
7280      unsigned Val = AR.Val;
7281      OS << ' ' << Val;
7282      assert(Val < 10 && "Expected alignment less then 2^10.");
7283      AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
7284      break;
7285    }
7286    case AOK_EVEN:
7287      OS << ".even";
7288      break;
7289    case AOK_EndOfStatement:
7290      OS << "\n\t";
7291      break;
7292    }
7293
7294    // Skip the original expression.
7295    AsmStart = Loc + AR.Len + AdditionalSkip;
7296  }
7297
7298  // Emit the remainder of the asm string.
7299  if (AsmStart != AsmEnd)
7300    OS << StringRef(AsmStart, AsmEnd - AsmStart);
7301
7302  AsmString = OS.str();
7303  return false;
7304}
7305
7306/// Create an MCAsmParser instance.
7307MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
7308                                      MCStreamer &Out, const MCAsmInfo &MAI,
7309                                      unsigned CB) {
7310  return new MasmParser(SM, C, Out, MAI, CB);
7311}
7312