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