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