LLVM  8.0.0svn
AsmParser.cpp
Go to the documentation of this file.
1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This class implements the parser for assembly files.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/APFloat.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/None.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/ADT/StringMap.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/Twine.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCCodeView.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCDirectives.h"
30 #include "llvm/MC/MCDwarf.h"
31 #include "llvm/MC/MCExpr.h"
32 #include "llvm/MC/MCInstPrinter.h"
33 #include "llvm/MC/MCInstrDesc.h"
34 #include "llvm/MC/MCInstrInfo.h"
44 #include "llvm/MC/MCRegisterInfo.h"
45 #include "llvm/MC/MCSection.h"
46 #include "llvm/MC/MCStreamer.h"
47 #include "llvm/MC/MCSymbol.h"
49 #include "llvm/MC/MCValue.h"
50 #include "llvm/Support/Casting.h"
53 #include "llvm/Support/MD5.h"
56 #include "llvm/Support/SMLoc.h"
57 #include "llvm/Support/SourceMgr.h"
59 #include <algorithm>
60 #include <cassert>
61 #include <cctype>
62 #include <climits>
63 #include <cstddef>
64 #include <cstdint>
65 #include <deque>
66 #include <memory>
67 #include <sstream>
68 #include <string>
69 #include <tuple>
70 #include <utility>
71 #include <vector>
72 
73 using namespace llvm;
74 
76 
78  "asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
79  cl::desc("The maximum nesting depth allowed for assembly macros."));
80 
81 namespace {
82 
83 /// Helper types for tracking macro definitions.
84 typedef std::vector<AsmToken> MCAsmMacroArgument;
85 typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
86 
87 /// Helper class for storing information about an active macro
88 /// instantiation.
89 struct MacroInstantiation {
90  /// The location of the instantiation.
91  SMLoc InstantiationLoc;
92 
93  /// The buffer where parsing should resume upon instantiation completion.
94  int ExitBuffer;
95 
96  /// The location where parsing should resume upon instantiation completion.
97  SMLoc ExitLoc;
98 
99  /// The depth of TheCondStack at the start of the instantiation.
100  size_t CondStackDepth;
101 
102 public:
103  MacroInstantiation(SMLoc IL, int EB, SMLoc EL, size_t CondStackDepth);
104 };
105 
106 struct ParseStatementInfo {
107  /// The parsed operands from the last parsed statement.
109 
110  /// The opcode from the last parsed instruction.
111  unsigned Opcode = ~0U;
112 
113  /// Was there an error parsing the inline assembly?
114  bool ParseError = false;
115 
116  SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
117 
118  ParseStatementInfo() = delete;
119  ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
120  : AsmRewrites(rewrites) {}
121 };
122 
123 /// The concrete assembly parser instance.
124 class AsmParser : public MCAsmParser {
125 private:
126  AsmLexer Lexer;
127  MCContext &Ctx;
128  MCStreamer &Out;
129  const MCAsmInfo &MAI;
130  SourceMgr &SrcMgr;
131  SourceMgr::DiagHandlerTy SavedDiagHandler;
132  void *SavedDiagContext;
133  std::unique_ptr<MCAsmParserExtension> PlatformParser;
134 
135  /// This is the current buffer index we're lexing from as managed by the
136  /// SourceMgr object.
137  unsigned CurBuffer;
138 
139  AsmCond TheCondState;
140  std::vector<AsmCond> TheCondStack;
141 
142  /// maps directive names to handler methods in parser
143  /// extensions. Extensions register themselves in this map by calling
144  /// addDirectiveHandler.
145  StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
146 
147  /// Stack of active macro instantiations.
148  std::vector<MacroInstantiation*> ActiveMacros;
149 
150  /// List of bodies of anonymous macros.
151  std::deque<MCAsmMacro> MacroLikeBodies;
152 
153  /// Boolean tracking whether macro substitution is enabled.
154  unsigned MacrosEnabledFlag : 1;
155 
156  /// Keeps track of how many .macro's have been instantiated.
157  unsigned NumOfMacroInstantiations;
158 
159  /// The values from the last parsed cpp hash file line comment if any.
160  struct CppHashInfoTy {
161  StringRef Filename;
162  int64_t LineNumber = 0;
163  SMLoc Loc;
164  unsigned Buf = 0;
165  };
166  CppHashInfoTy CppHashInfo;
167 
168  /// List of forward directional labels for diagnosis at the end.
170 
171  /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
172  unsigned AssemblerDialect = ~0U;
173 
174  /// is Darwin compatibility enabled?
175  bool IsDarwin = false;
176 
177  /// Are we parsing ms-style inline assembly?
178  bool ParsingInlineAsm = false;
179 
180  /// Did we already inform the user about inconsistent MD5 usage?
181  bool ReportedInconsistentMD5 = false;
182 
183 public:
184  AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
185  const MCAsmInfo &MAI, unsigned CB);
186  AsmParser(const AsmParser &) = delete;
187  AsmParser &operator=(const AsmParser &) = delete;
188  ~AsmParser() override;
189 
190  bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
191 
192  void addDirectiveHandler(StringRef Directive,
193  ExtensionDirectiveHandler Handler) override {
194  ExtensionDirectiveMap[Directive] = Handler;
195  }
196 
197  void addAliasForDirective(StringRef Directive, StringRef Alias) override {
198  DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
199  }
200 
201  /// @name MCAsmParser Interface
202  /// {
203 
204  SourceMgr &getSourceManager() override { return SrcMgr; }
205  MCAsmLexer &getLexer() override { return Lexer; }
206  MCContext &getContext() override { return Ctx; }
207  MCStreamer &getStreamer() override { return Out; }
208 
209  CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
210 
211  unsigned getAssemblerDialect() override {
212  if (AssemblerDialect == ~0U)
213  return MAI.getAssemblerDialect();
214  else
215  return AssemblerDialect;
216  }
217  void setAssemblerDialect(unsigned i) override {
218  AssemblerDialect = i;
219  }
220 
221  void Note(SMLoc L, const Twine &Msg, SMRange Range = None) override;
222  bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) override;
223  bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) override;
224 
225  const AsmToken &Lex() override;
226 
227  void setParsingInlineAsm(bool V) override {
228  ParsingInlineAsm = V;
229  Lexer.setParsingMSInlineAsm(V);
230  }
231  bool isParsingInlineAsm() override { return ParsingInlineAsm; }
232 
233  bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
234  unsigned &NumOutputs, unsigned &NumInputs,
235  SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
236  SmallVectorImpl<std::string> &Constraints,
238  const MCInstrInfo *MII, const MCInstPrinter *IP,
239  MCAsmParserSemaCallback &SI) override;
240 
241  bool parseExpression(const MCExpr *&Res);
242  bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
243  bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
244  bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
245  bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
246  SMLoc &EndLoc) override;
247  bool parseAbsoluteExpression(int64_t &Res) override;
248 
249  /// Parse a floating point expression using the float \p Semantics
250  /// and set \p Res to the value.
251  bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
252 
253  /// Parse an identifier or string (as a quoted identifier)
254  /// and set \p Res to the identifier contents.
255  bool parseIdentifier(StringRef &Res) override;
256  void eatToEndOfStatement() override;
257 
258  bool checkForValidSection() override;
259 
260  /// }
261 
262 private:
263  bool isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc);
264  void altMacroString(StringRef AltMacroStr, std::string &Res);
265  bool parseStatement(ParseStatementInfo &Info,
267  bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
268  bool parseCppHashLineFilenameComment(SMLoc L);
269 
270  void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
271  ArrayRef<MCAsmMacroParameter> Parameters);
272  bool expandMacro(raw_svector_ostream &OS, StringRef Body,
274  ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable,
275  SMLoc L);
276 
277  /// Are macros enabled in the parser?
278  bool areMacrosEnabled() {return MacrosEnabledFlag;}
279 
280  /// Control a flag in the parser that enables or disables macros.
281  void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
282 
283  /// Are we inside a macro instantiation?
284  bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
285 
286  /// Handle entry to macro instantiation.
287  ///
288  /// \param M The macro.
289  /// \param NameLoc Instantiation location.
290  bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
291 
292  /// Handle exit from macro instantiation.
293  void handleMacroExit();
294 
295  /// Extract AsmTokens for a macro argument.
296  bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg);
297 
298  /// Parse all macro arguments for a given macro.
299  bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
300 
301  void printMacroInstantiations();
302  void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
303  SMRange Range = None) const {
304  ArrayRef<SMRange> Ranges(Range);
305  SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
306  }
307  static void DiagHandler(const SMDiagnostic &Diag, void *Context);
308 
309  /// Should we emit DWARF describing this assembler source? (Returns false if
310  /// the source has .file directives, which means we don't want to generate
311  /// info describing the assembler source itself.)
312  bool enabledGenDwarfForAssembly();
313 
314  /// Enter the specified file. This returns true on failure.
315  bool enterIncludeFile(const std::string &Filename);
316 
317  /// Process the specified file for the .incbin directive.
318  /// This returns true on failure.
319  bool processIncbinFile(const std::string &Filename, int64_t Skip = 0,
320  const MCExpr *Count = nullptr, SMLoc Loc = SMLoc());
321 
322  /// Reset the current lexer position to that given by \p Loc. The
323  /// current token is not set; clients should ensure Lex() is called
324  /// subsequently.
325  ///
326  /// \param InBuffer If not 0, should be the known buffer id that contains the
327  /// location.
328  void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0);
329 
330  /// Parse up to the end of statement and a return the contents from the
331  /// current token until the end of the statement; the current token on exit
332  /// will be either the EndOfStatement or EOF.
333  StringRef parseStringToEndOfStatement() override;
334 
335  /// Parse until the end of a statement or a comma is encountered,
336  /// return the contents from the current token up to the end or comma.
337  StringRef parseStringToComma();
338 
339  bool parseAssignment(StringRef Name, bool allow_redef,
340  bool NoDeadStrip = false);
341 
342  unsigned getBinOpPrecedence(AsmToken::TokenKind K,
343  MCBinaryExpr::Opcode &Kind);
344 
345  bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
346  bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
347  bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
348 
349  bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
350 
351  bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
352  bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
353 
354  // Generic (target and platform independent) directive parsing.
355  enum DirectiveKind {
356  DK_NO_DIRECTIVE, // Placeholder
357  DK_SET,
358  DK_EQU,
359  DK_EQUIV,
360  DK_ASCII,
361  DK_ASCIZ,
362  DK_STRING,
363  DK_BYTE,
364  DK_SHORT,
365  DK_RELOC,
366  DK_VALUE,
367  DK_2BYTE,
368  DK_LONG,
369  DK_INT,
370  DK_4BYTE,
371  DK_QUAD,
372  DK_8BYTE,
373  DK_OCTA,
374  DK_DC,
375  DK_DC_A,
376  DK_DC_B,
377  DK_DC_D,
378  DK_DC_L,
379  DK_DC_S,
380  DK_DC_W,
381  DK_DC_X,
382  DK_DCB,
383  DK_DCB_B,
384  DK_DCB_D,
385  DK_DCB_L,
386  DK_DCB_S,
387  DK_DCB_W,
388  DK_DCB_X,
389  DK_DS,
390  DK_DS_B,
391  DK_DS_D,
392  DK_DS_L,
393  DK_DS_P,
394  DK_DS_S,
395  DK_DS_W,
396  DK_DS_X,
397  DK_SINGLE,
398  DK_FLOAT,
399  DK_DOUBLE,
400  DK_ALIGN,
401  DK_ALIGN32,
402  DK_BALIGN,
403  DK_BALIGNW,
404  DK_BALIGNL,
405  DK_P2ALIGN,
406  DK_P2ALIGNW,
407  DK_P2ALIGNL,
408  DK_ORG,
409  DK_FILL,
410  DK_ENDR,
411  DK_BUNDLE_ALIGN_MODE,
412  DK_BUNDLE_LOCK,
413  DK_BUNDLE_UNLOCK,
414  DK_ZERO,
415  DK_EXTERN,
416  DK_GLOBL,
417  DK_GLOBAL,
418  DK_LAZY_REFERENCE,
419  DK_NO_DEAD_STRIP,
420  DK_SYMBOL_RESOLVER,
421  DK_PRIVATE_EXTERN,
422  DK_REFERENCE,
423  DK_WEAK_DEFINITION,
424  DK_WEAK_REFERENCE,
425  DK_WEAK_DEF_CAN_BE_HIDDEN,
426  DK_COMM,
427  DK_COMMON,
428  DK_LCOMM,
429  DK_ABORT,
430  DK_INCLUDE,
431  DK_INCBIN,
432  DK_CODE16,
433  DK_CODE16GCC,
434  DK_REPT,
435  DK_IRP,
436  DK_IRPC,
437  DK_IF,
438  DK_IFEQ,
439  DK_IFGE,
440  DK_IFGT,
441  DK_IFLE,
442  DK_IFLT,
443  DK_IFNE,
444  DK_IFB,
445  DK_IFNB,
446  DK_IFC,
447  DK_IFEQS,
448  DK_IFNC,
449  DK_IFNES,
450  DK_IFDEF,
451  DK_IFNDEF,
452  DK_IFNOTDEF,
453  DK_ELSEIF,
454  DK_ELSE,
455  DK_ENDIF,
456  DK_SPACE,
457  DK_SKIP,
458  DK_FILE,
459  DK_LINE,
460  DK_LOC,
461  DK_STABS,
462  DK_CV_FILE,
463  DK_CV_FUNC_ID,
464  DK_CV_INLINE_SITE_ID,
465  DK_CV_LOC,
466  DK_CV_LINETABLE,
467  DK_CV_INLINE_LINETABLE,
468  DK_CV_DEF_RANGE,
469  DK_CV_STRINGTABLE,
470  DK_CV_FILECHECKSUMS,
471  DK_CV_FILECHECKSUM_OFFSET,
472  DK_CV_FPO_DATA,
473  DK_CFI_SECTIONS,
474  DK_CFI_STARTPROC,
475  DK_CFI_ENDPROC,
476  DK_CFI_DEF_CFA,
477  DK_CFI_DEF_CFA_OFFSET,
478  DK_CFI_ADJUST_CFA_OFFSET,
479  DK_CFI_DEF_CFA_REGISTER,
480  DK_CFI_OFFSET,
481  DK_CFI_REL_OFFSET,
482  DK_CFI_PERSONALITY,
483  DK_CFI_LSDA,
484  DK_CFI_REMEMBER_STATE,
485  DK_CFI_RESTORE_STATE,
486  DK_CFI_SAME_VALUE,
487  DK_CFI_RESTORE,
488  DK_CFI_ESCAPE,
489  DK_CFI_RETURN_COLUMN,
490  DK_CFI_SIGNAL_FRAME,
491  DK_CFI_UNDEFINED,
492  DK_CFI_REGISTER,
493  DK_CFI_WINDOW_SAVE,
494  DK_MACROS_ON,
495  DK_MACROS_OFF,
496  DK_ALTMACRO,
497  DK_NOALTMACRO,
498  DK_MACRO,
499  DK_EXITM,
500  DK_ENDM,
501  DK_ENDMACRO,
502  DK_PURGEM,
503  DK_SLEB128,
504  DK_ULEB128,
505  DK_ERR,
506  DK_ERROR,
507  DK_WARNING,
508  DK_PRINT,
509  DK_ADDRSIG,
510  DK_ADDRSIG_SYM,
511  DK_END
512  };
513 
514  /// Maps directive name --> DirectiveKind enum, for
515  /// directives parsed by this class.
516  StringMap<DirectiveKind> DirectiveKindMap;
517 
518  // ".ascii", ".asciz", ".string"
519  bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
520  bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc"
521  bool parseDirectiveValue(StringRef IDVal,
522  unsigned Size); // ".byte", ".long", ...
523  bool parseDirectiveOctaValue(StringRef IDVal); // ".octa", ...
524  bool parseDirectiveRealValue(StringRef IDVal,
525  const fltSemantics &); // ".single", ...
526  bool parseDirectiveFill(); // ".fill"
527  bool parseDirectiveZero(); // ".zero"
528  // ".set", ".equ", ".equiv"
529  bool parseDirectiveSet(StringRef IDVal, bool allow_redef);
530  bool parseDirectiveOrg(); // ".org"
531  // ".align{,32}", ".p2align{,w,l}"
532  bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
533 
534  // ".file", ".line", ".loc", ".stabs"
535  bool parseDirectiveFile(SMLoc DirectiveLoc);
536  bool parseDirectiveLine();
537  bool parseDirectiveLoc();
538  bool parseDirectiveStabs();
539 
540  // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
541  // ".cv_inline_linetable", ".cv_def_range"
542  bool parseDirectiveCVFile();
543  bool parseDirectiveCVFuncId();
544  bool parseDirectiveCVInlineSiteId();
545  bool parseDirectiveCVLoc();
546  bool parseDirectiveCVLinetable();
547  bool parseDirectiveCVInlineLinetable();
548  bool parseDirectiveCVDefRange();
549  bool parseDirectiveCVStringTable();
550  bool parseDirectiveCVFileChecksums();
551  bool parseDirectiveCVFileChecksumOffset();
552  bool parseDirectiveCVFPOData();
553 
554  // .cfi directives
555  bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
556  bool parseDirectiveCFIWindowSave();
557  bool parseDirectiveCFISections();
558  bool parseDirectiveCFIStartProc();
559  bool parseDirectiveCFIEndProc();
560  bool parseDirectiveCFIDefCfaOffset();
561  bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
562  bool parseDirectiveCFIAdjustCfaOffset();
563  bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
564  bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
565  bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
566  bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
567  bool parseDirectiveCFIRememberState();
568  bool parseDirectiveCFIRestoreState();
569  bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
570  bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
571  bool parseDirectiveCFIEscape();
572  bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
573  bool parseDirectiveCFISignalFrame();
574  bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
575 
576  // macro directives
577  bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
578  bool parseDirectiveExitMacro(StringRef Directive);
579  bool parseDirectiveEndMacro(StringRef Directive);
580  bool parseDirectiveMacro(SMLoc DirectiveLoc);
581  bool parseDirectiveMacrosOnOff(StringRef Directive);
582  // alternate macro mode directives
583  bool parseDirectiveAltmacro(StringRef Directive);
584  // ".bundle_align_mode"
585  bool parseDirectiveBundleAlignMode();
586  // ".bundle_lock"
587  bool parseDirectiveBundleLock();
588  // ".bundle_unlock"
589  bool parseDirectiveBundleUnlock();
590 
591  // ".space", ".skip"
592  bool parseDirectiveSpace(StringRef IDVal);
593 
594  // ".dcb"
595  bool parseDirectiveDCB(StringRef IDVal, unsigned Size);
596  bool parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &);
597  // ".ds"
598  bool parseDirectiveDS(StringRef IDVal, unsigned Size);
599 
600  // .sleb128 (Signed=true) and .uleb128 (Signed=false)
601  bool parseDirectiveLEB128(bool Signed);
602 
603  /// Parse a directive like ".globl" which
604  /// accepts a single symbol (which should be a label or an external).
605  bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
606 
607  bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
608 
609  bool parseDirectiveAbort(); // ".abort"
610  bool parseDirectiveInclude(); // ".include"
611  bool parseDirectiveIncbin(); // ".incbin"
612 
613  // ".if", ".ifeq", ".ifge", ".ifgt" , ".ifle", ".iflt" or ".ifne"
614  bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
615  // ".ifb" or ".ifnb", depending on ExpectBlank.
616  bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
617  // ".ifc" or ".ifnc", depending on ExpectEqual.
618  bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
619  // ".ifeqs" or ".ifnes", depending on ExpectEqual.
620  bool parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual);
621  // ".ifdef" or ".ifndef", depending on expect_defined
622  bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
623  bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
624  bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else"
625  bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
626  bool parseEscapedString(std::string &Data) override;
627 
628  const MCExpr *applyModifierToExpr(const MCExpr *E,
630 
631  // Macro-like directives
632  MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
633  void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
634  raw_svector_ostream &OS);
635  bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive);
636  bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
637  bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
638  bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
639 
640  // "_emit" or "__emit"
641  bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
642  size_t Len);
643 
644  // "align"
645  bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
646 
647  // "end"
648  bool parseDirectiveEnd(SMLoc DirectiveLoc);
649 
650  // ".err" or ".error"
651  bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
652 
653  // ".warning"
654  bool parseDirectiveWarning(SMLoc DirectiveLoc);
655 
656  // .print <double-quotes-string>
657  bool parseDirectivePrint(SMLoc DirectiveLoc);
658 
659  // Directives to support address-significance tables.
660  bool parseDirectiveAddrsig();
661  bool parseDirectiveAddrsigSym();
662 
663  void initializeDirectiveKindMap();
664 };
665 
666 } // end anonymous namespace
667 
668 namespace llvm {
669 
673 
674 } // end namespace llvm
675 
676 enum { DEFAULT_ADDRSPACE = 0 };
677 
678 AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
679  const MCAsmInfo &MAI, unsigned CB = 0)
680  : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
681  CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
682  HadError = false;
683  // Save the old handler.
684  SavedDiagHandler = SrcMgr.getDiagHandler();
685  SavedDiagContext = SrcMgr.getDiagContext();
686  // Set our own handler which calls the saved handler.
687  SrcMgr.setDiagHandler(DiagHandler, this);
688  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
689 
690  // Initialize the platform / file format parser.
691  switch (Ctx.getObjectFileInfo()->getObjectFileType()) {
693  PlatformParser.reset(createCOFFAsmParser());
694  break;
696  PlatformParser.reset(createDarwinAsmParser());
697  IsDarwin = true;
698  break;
700  PlatformParser.reset(createELFAsmParser());
701  break;
703  // TODO: WASM will need its own MCAsmParserExtension implementation, but
704  // for now we can re-use the ELF one, since the directives can be the
705  // same for now.
706  PlatformParser.reset(createELFAsmParser());
707  break;
708  }
709 
710  PlatformParser->Initialize(*this);
711  initializeDirectiveKindMap();
712 
713  NumOfMacroInstantiations = 0;
714 }
715 
716 AsmParser::~AsmParser() {
717  assert((HadError || ActiveMacros.empty()) &&
718  "Unexpected active macro instantiation!");
719 
720  // Restore the saved diagnostics handler and context for use during
721  // finalization.
722  SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
723 }
724 
725 void AsmParser::printMacroInstantiations() {
726  // Print the active macro instantiation stack.
727  for (std::vector<MacroInstantiation *>::const_reverse_iterator
728  it = ActiveMacros.rbegin(),
729  ie = ActiveMacros.rend();
730  it != ie; ++it)
731  printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
732  "while in macro instantiation");
733 }
734 
735 void AsmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
736  printPendingErrors();
737  printMessage(L, SourceMgr::DK_Note, Msg, Range);
738  printMacroInstantiations();
739 }
740 
741 bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
742  if(getTargetParser().getTargetOptions().MCNoWarn)
743  return false;
744  if (getTargetParser().getTargetOptions().MCFatalWarnings)
745  return Error(L, Msg, Range);
746  printMessage(L, SourceMgr::DK_Warning, Msg, Range);
747  printMacroInstantiations();
748  return false;
749 }
750 
751 bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
752  HadError = true;
753  printMessage(L, SourceMgr::DK_Error, Msg, Range);
754  printMacroInstantiations();
755  return true;
756 }
757 
758 bool AsmParser::enterIncludeFile(const std::string &Filename) {
759  std::string IncludedFile;
760  unsigned NewBuf =
761  SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
762  if (!NewBuf)
763  return true;
764 
765  CurBuffer = NewBuf;
766  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
767  return false;
768 }
769 
770 /// Process the specified .incbin file by searching for it in the include paths
771 /// then just emitting the byte contents of the file to the streamer. This
772 /// returns true on failure.
773 bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
774  const MCExpr *Count, SMLoc Loc) {
775  std::string IncludedFile;
776  unsigned NewBuf =
777  SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
778  if (!NewBuf)
779  return true;
780 
781  // Pick up the bytes from the file and emit them.
782  StringRef Bytes = SrcMgr.getMemoryBuffer(NewBuf)->getBuffer();
783  Bytes = Bytes.drop_front(Skip);
784  if (Count) {
785  int64_t Res;
786  if (!Count->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
787  return Error(Loc, "expected absolute expression");
788  if (Res < 0)
789  return Warning(Loc, "negative count has no effect");
790  Bytes = Bytes.take_front(Res);
791  }
792  getStreamer().EmitBytes(Bytes);
793  return false;
794 }
795 
796 void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) {
797  CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
798  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
799  Loc.getPointer());
800 }
801 
802 const AsmToken &AsmParser::Lex() {
803  if (Lexer.getTok().is(AsmToken::Error))
804  Error(Lexer.getErrLoc(), Lexer.getErr());
805 
806  // if it's a end of statement with a comment in it
807  if (getTok().is(AsmToken::EndOfStatement)) {
808  // if this is a line comment output it.
809  if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
810  getTok().getString().front() != '\r' && MAI.preserveAsmComments())
811  Out.addExplicitComment(Twine(getTok().getString()));
812  }
813 
814  const AsmToken *tok = &Lexer.Lex();
815 
816  // Parse comments here to be deferred until end of next statement.
817  while (tok->is(AsmToken::Comment)) {
818  if (MAI.preserveAsmComments())
819  Out.addExplicitComment(Twine(tok->getString()));
820  tok = &Lexer.Lex();
821  }
822 
823  if (tok->is(AsmToken::Eof)) {
824  // If this is the end of an included file, pop the parent file off the
825  // include stack.
826  SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
827  if (ParentIncludeLoc != SMLoc()) {
828  jumpToLoc(ParentIncludeLoc);
829  return Lex();
830  }
831  }
832 
833  return *tok;
834 }
835 
836 bool AsmParser::enabledGenDwarfForAssembly() {
837  // Check whether the user specified -g.
838  if (!getContext().getGenDwarfForAssembly())
839  return false;
840  // If we haven't encountered any .file directives (which would imply that
841  // the assembler source was produced with debug info already) then emit one
842  // describing the assembler source file itself.
843  if (getContext().getGenDwarfFileNumber() == 0)
844  getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
845  0, StringRef(), getContext().getMainFileName()));
846  return true;
847 }
848 
849 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
850  // Create the initial section, if requested.
851  if (!NoInitialTextSection)
852  Out.InitSections(false);
853 
854  // Prime the lexer.
855  Lex();
856 
857  HadError = false;
858  AsmCond StartingCondState = TheCondState;
859  SmallVector<AsmRewrite, 4> AsmStrRewrites;
860 
861  // If we are generating dwarf for assembly source files save the initial text
862  // section. (Don't use enabledGenDwarfForAssembly() here, as we aren't
863  // emitting any actual debug info yet and haven't had a chance to parse any
864  // embedded .file directives.)
865  if (getContext().getGenDwarfForAssembly()) {
866  MCSection *Sec = getStreamer().getCurrentSectionOnly();
867  if (!Sec->getBeginSymbol()) {
868  MCSymbol *SectionStartSym = getContext().createTempSymbol();
869  getStreamer().EmitLabel(SectionStartSym);
870  Sec->setBeginSymbol(SectionStartSym);
871  }
872  bool InsertResult = getContext().addGenDwarfSection(Sec);
873  assert(InsertResult && ".text section should not have debug info yet");
874  (void)InsertResult;
875  }
876 
877  // While we have input, parse each statement.
878  while (Lexer.isNot(AsmToken::Eof)) {
879  ParseStatementInfo Info(&AsmStrRewrites);
880  if (!parseStatement(Info, nullptr))
881  continue;
882 
883  // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
884  // for printing ErrMsg via Lex() only if no (presumably better) parser error
885  // exists.
886  if (!hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
887  Lex();
888  }
889 
890  // parseStatement returned true so may need to emit an error.
891  printPendingErrors();
892 
893  // Skipping to the next line if needed.
894  if (!getLexer().isAtStartOfStatement())
895  eatToEndOfStatement();
896  }
897 
898  // All errors should have been emitted.
899  assert(!hasPendingError() && "unexpected error from parseStatement");
900 
901  getTargetParser().flushPendingInstructions(getStreamer());
902 
903  if (TheCondState.TheCond != StartingCondState.TheCond ||
904  TheCondState.Ignore != StartingCondState.Ignore)
905  printError(getTok().getLoc(), "unmatched .ifs or .elses");
906  // Check to see there are no empty DwarfFile slots.
907  const auto &LineTables = getContext().getMCDwarfLineTables();
908  if (!LineTables.empty()) {
909  unsigned Index = 0;
910  for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
911  if (File.Name.empty() && Index != 0)
912  printError(getTok().getLoc(), "unassigned file number: " +
913  Twine(Index) +
914  " for .file directives");
915  ++Index;
916  }
917  }
918 
919  // Check to see that all assembler local symbols were actually defined.
920  // Targets that don't do subsections via symbols may not want this, though,
921  // so conservatively exclude them. Only do this if we're finalizing, though,
922  // as otherwise we won't necessarilly have seen everything yet.
923  if (!NoFinalize) {
924  if (MAI.hasSubsectionsViaSymbols()) {
925  for (const auto &TableEntry : getContext().getSymbols()) {
926  MCSymbol *Sym = TableEntry.getValue();
927  // Variable symbols may not be marked as defined, so check those
928  // explicitly. If we know it's a variable, we have a definition for
929  // the purposes of this check.
930  if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
931  // FIXME: We would really like to refer back to where the symbol was
932  // first referenced for a source location. We need to add something
933  // to track that. Currently, we just point to the end of the file.
934  printError(getTok().getLoc(), "assembler local symbol '" +
935  Sym->getName() + "' not defined");
936  }
937  }
938 
939  // Temporary symbols like the ones for directional jumps don't go in the
940  // symbol table. They also need to be diagnosed in all (final) cases.
941  for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
942  if (std::get<2>(LocSym)->isUndefined()) {
943  // Reset the state of any "# line file" directives we've seen to the
944  // context as it was at the diagnostic site.
945  CppHashInfo = std::get<1>(LocSym);
946  printError(std::get<0>(LocSym), "directional label undefined");
947  }
948  }
949  }
950 
951  // Finalize the output stream if there are no errors and if the client wants
952  // us to.
953  if (!HadError && !NoFinalize)
954  Out.Finish();
955 
956  return HadError || getContext().hadError();
957 }
958 
959 bool AsmParser::checkForValidSection() {
960  if (!ParsingInlineAsm && !getStreamer().getCurrentSectionOnly()) {
961  Out.InitSections(false);
962  return Error(getTok().getLoc(),
963  "expected section directive before assembly directive");
964  }
965  return false;
966 }
967 
968 /// Throw away the rest of the line for testing purposes.
969 void AsmParser::eatToEndOfStatement() {
970  while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
971  Lexer.Lex();
972 
973  // Eat EOL.
974  if (Lexer.is(AsmToken::EndOfStatement))
975  Lexer.Lex();
976 }
977 
978 StringRef AsmParser::parseStringToEndOfStatement() {
979  const char *Start = getTok().getLoc().getPointer();
980 
981  while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
982  Lexer.Lex();
983 
984  const char *End = getTok().getLoc().getPointer();
985  return StringRef(Start, End - Start);
986 }
987 
988 StringRef AsmParser::parseStringToComma() {
989  const char *Start = getTok().getLoc().getPointer();
990 
991  while (Lexer.isNot(AsmToken::EndOfStatement) &&
992  Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof))
993  Lexer.Lex();
994 
995  const char *End = getTok().getLoc().getPointer();
996  return StringRef(Start, End - Start);
997 }
998 
999 /// Parse a paren expression and return it.
1000 /// NOTE: This assumes the leading '(' has already been consumed.
1001 ///
1002 /// parenexpr ::= expr)
1003 ///
1004 bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1005  if (parseExpression(Res))
1006  return true;
1007  if (Lexer.isNot(AsmToken::RParen))
1008  return TokError("expected ')' in parentheses expression");
1009  EndLoc = Lexer.getTok().getEndLoc();
1010  Lex();
1011  return false;
1012 }
1013 
1014 /// Parse a bracket expression and return it.
1015 /// NOTE: This assumes the leading '[' has already been consumed.
1016 ///
1017 /// bracketexpr ::= expr]
1018 ///
1019 bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1020  if (parseExpression(Res))
1021  return true;
1022  EndLoc = getTok().getEndLoc();
1023  if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
1024  return true;
1025  return false;
1026 }
1027 
1028 /// Parse a primary expression and return it.
1029 /// primaryexpr ::= (parenexpr
1030 /// primaryexpr ::= symbol
1031 /// primaryexpr ::= number
1032 /// primaryexpr ::= '.'
1033 /// primaryexpr ::= ~,+,- primaryexpr
1034 bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
1035  SMLoc FirstTokenLoc = getLexer().getLoc();
1036  AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
1037  switch (FirstTokenKind) {
1038  default:
1039  return TokError("unknown token in expression");
1040  // If we have an error assume that we've already handled it.
1041  case AsmToken::Error:
1042  return true;
1043  case AsmToken::Exclaim:
1044  Lex(); // Eat the operator.
1045  if (parsePrimaryExpr(Res, EndLoc))
1046  return true;
1047  Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
1048  return false;
1049  case AsmToken::Dollar:
1050  case AsmToken::At:
1051  case AsmToken::String:
1052  case AsmToken::Identifier: {
1054  if (parseIdentifier(Identifier)) {
1055  // We may have failed but $ may be a valid token.
1056  if (getTok().is(AsmToken::Dollar)) {
1057  if (Lexer.getMAI().getDollarIsPC()) {
1058  Lex();
1059  // This is a '$' reference, which references the current PC. Emit a
1060  // temporary label to the streamer and refer to it.
1061  MCSymbol *Sym = Ctx.createTempSymbol();
1062  Out.EmitLabel(Sym);
1064  getContext());
1065  EndLoc = FirstTokenLoc;
1066  return false;
1067  }
1068  return Error(FirstTokenLoc, "invalid token in expression");
1069  }
1070  }
1071  // Parse symbol variant
1072  std::pair<StringRef, StringRef> Split;
1073  if (!MAI.useParensForSymbolVariant()) {
1074  if (FirstTokenKind == AsmToken::String) {
1075  if (Lexer.is(AsmToken::At)) {
1076  Lex(); // eat @
1077  SMLoc AtLoc = getLexer().getLoc();
1078  StringRef VName;
1079  if (parseIdentifier(VName))
1080  return Error(AtLoc, "expected symbol variant after '@'");
1081 
1082  Split = std::make_pair(Identifier, VName);
1083  }
1084  } else {
1085  Split = Identifier.split('@');
1086  }
1087  } else if (Lexer.is(AsmToken::LParen)) {
1088  Lex(); // eat '('.
1089  StringRef VName;
1090  parseIdentifier(VName);
1091  // eat ')'.
1092  if (parseToken(AsmToken::RParen,
1093  "unexpected token in variant, expected ')'"))
1094  return true;
1095  Split = std::make_pair(Identifier, VName);
1096  }
1097 
1098  EndLoc = SMLoc::getFromPointer(Identifier.end());
1099 
1100  // This is a symbol reference.
1102  if (SymbolName.empty())
1103  return true;
1104 
1106 
1107  // Lookup the symbol variant if used.
1108  if (!Split.second.empty()) {
1109  Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1110  if (Variant != MCSymbolRefExpr::VK_Invalid) {
1111  SymbolName = Split.first;
1112  } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
1113  Variant = MCSymbolRefExpr::VK_None;
1114  } else {
1115  return Error(SMLoc::getFromPointer(Split.second.begin()),
1116  "invalid variant '" + Split.second + "'");
1117  }
1118  }
1119 
1120  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
1121 
1122  // If this is an absolute variable reference, substitute it now to preserve
1123  // semantics in the face of reassignment.
1124  if (Sym->isVariable()) {
1125  auto V = Sym->getVariableValue(/*SetUsed*/ false);
1126  bool DoInline = isa<MCConstantExpr>(V);
1127  if (auto TV = dyn_cast<MCTargetExpr>(V))
1128  DoInline = TV->inlineAssignedExpr();
1129  if (DoInline) {
1130  if (Variant)
1131  return Error(EndLoc, "unexpected modifier on variable reference");
1132  Res = Sym->getVariableValue(/*SetUsed*/ false);
1133  return false;
1134  }
1135  }
1136 
1137  // Otherwise create a symbol ref.
1138  Res = MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
1139  return false;
1140  }
1141  case AsmToken::BigNum:
1142  return TokError("literal value out of range for directive");
1143  case AsmToken::Integer: {
1144  SMLoc Loc = getTok().getLoc();
1145  int64_t IntVal = getTok().getIntVal();
1146  Res = MCConstantExpr::create(IntVal, getContext());
1147  EndLoc = Lexer.getTok().getEndLoc();
1148  Lex(); // Eat token.
1149  // Look for 'b' or 'f' following an Integer as a directional label
1150  if (Lexer.getKind() == AsmToken::Identifier) {
1151  StringRef IDVal = getTok().getString();
1152  // Lookup the symbol variant if used.
1153  std::pair<StringRef, StringRef> Split = IDVal.split('@');
1155  if (Split.first.size() != IDVal.size()) {
1156  Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1157  if (Variant == MCSymbolRefExpr::VK_Invalid)
1158  return TokError("invalid variant '" + Split.second + "'");
1159  IDVal = Split.first;
1160  }
1161  if (IDVal == "f" || IDVal == "b") {
1162  MCSymbol *Sym =
1163  Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
1164  Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
1165  if (IDVal == "b" && Sym->isUndefined())
1166  return Error(Loc, "directional label undefined");
1167  DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
1168  EndLoc = Lexer.getTok().getEndLoc();
1169  Lex(); // Eat identifier.
1170  }
1171  }
1172  return false;
1173  }
1174  case AsmToken::Real: {
1175  APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
1176  uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
1177  Res = MCConstantExpr::create(IntVal, getContext());
1178  EndLoc = Lexer.getTok().getEndLoc();
1179  Lex(); // Eat token.
1180  return false;
1181  }
1182  case AsmToken::Dot: {
1183  // This is a '.' reference, which references the current PC. Emit a
1184  // temporary label to the streamer and refer to it.
1185  MCSymbol *Sym = Ctx.createTempSymbol();
1186  Out.EmitLabel(Sym);
1187  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1188  EndLoc = Lexer.getTok().getEndLoc();
1189  Lex(); // Eat identifier.
1190  return false;
1191  }
1192  case AsmToken::LParen:
1193  Lex(); // Eat the '('.
1194  return parseParenExpr(Res, EndLoc);
1195  case AsmToken::LBrac:
1196  if (!PlatformParser->HasBracketExpressions())
1197  return TokError("brackets expression not supported on this target");
1198  Lex(); // Eat the '['.
1199  return parseBracketExpr(Res, EndLoc);
1200  case AsmToken::Minus:
1201  Lex(); // Eat the operator.
1202  if (parsePrimaryExpr(Res, EndLoc))
1203  return true;
1204  Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
1205  return false;
1206  case AsmToken::Plus:
1207  Lex(); // Eat the operator.
1208  if (parsePrimaryExpr(Res, EndLoc))
1209  return true;
1210  Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
1211  return false;
1212  case AsmToken::Tilde:
1213  Lex(); // Eat the operator.
1214  if (parsePrimaryExpr(Res, EndLoc))
1215  return true;
1216  Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
1217  return false;
1218  // MIPS unary expression operators. The lexer won't generate these tokens if
1219  // MCAsmInfo::HasMipsExpressions is false for the target.
1225  case AsmToken::PercentGot:
1233  case AsmToken::PercentHi:
1236  case AsmToken::PercentLo:
1237  case AsmToken::PercentNeg:
1244  Lex(); // Eat the operator.
1245  if (Lexer.isNot(AsmToken::LParen))
1246  return TokError("expected '(' after operator");
1247  Lex(); // Eat the operator.
1248  if (parseExpression(Res, EndLoc))
1249  return true;
1250  if (Lexer.isNot(AsmToken::RParen))
1251  return TokError("expected ')'");
1252  Lex(); // Eat the operator.
1253  Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
1254  return !Res;
1255  }
1256 }
1257 
1258 bool AsmParser::parseExpression(const MCExpr *&Res) {
1259  SMLoc EndLoc;
1260  return parseExpression(Res, EndLoc);
1261 }
1262 
1263 const MCExpr *
1264 AsmParser::applyModifierToExpr(const MCExpr *E,
1265  MCSymbolRefExpr::VariantKind Variant) {
1266  // Ask the target implementation about this expression first.
1267  const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
1268  if (NewE)
1269  return NewE;
1270  // Recurse over the given expression, rebuilding it to apply the given variant
1271  // if there is exactly one symbol.
1272  switch (E->getKind()) {
1273  case MCExpr::Target:
1274  case MCExpr::Constant:
1275  return nullptr;
1276 
1277  case MCExpr::SymbolRef: {
1278  const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1279 
1280  if (SRE->getKind() != MCSymbolRefExpr::VK_None) {
1281  TokError("invalid variant on expression '" + getTok().getIdentifier() +
1282  "' (already modified)");
1283  return E;
1284  }
1285 
1286  return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, getContext());
1287  }
1288 
1289  case MCExpr::Unary: {
1290  const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1291  const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant);
1292  if (!Sub)
1293  return nullptr;
1294  return MCUnaryExpr::create(UE->getOpcode(), Sub, getContext());
1295  }
1296 
1297  case MCExpr::Binary: {
1298  const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1299  const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant);
1300  const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant);
1301 
1302  if (!LHS && !RHS)
1303  return nullptr;
1304 
1305  if (!LHS)
1306  LHS = BE->getLHS();
1307  if (!RHS)
1308  RHS = BE->getRHS();
1309 
1310  return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, getContext());
1311  }
1312  }
1313 
1314  llvm_unreachable("Invalid expression kind!");
1315 }
1316 
1317 /// This function checks if the next token is <string> type or arithmetic.
1318 /// string that begin with character '<' must end with character '>'.
1319 /// otherwise it is arithmetics.
1320 /// If the function returns a 'true' value,
1321 /// the End argument will be filled with the last location pointed to the '>'
1322 /// character.
1323 
1324 /// There is a gap between the AltMacro's documentation and the single quote implementation.
1325 /// GCC does not fully support this feature and so we will not support it.
1326 /// TODO: Adding single quote as a string.
1327 bool AsmParser::isAltmacroString(SMLoc &StrLoc, SMLoc &EndLoc) {
1328  assert((StrLoc.getPointer() != NULL) &&
1329  "Argument to the function cannot be a NULL value");
1330  const char *CharPtr = StrLoc.getPointer();
1331  while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
1332  (*CharPtr != '\0')) {
1333  if (*CharPtr == '!')
1334  CharPtr++;
1335  CharPtr++;
1336  }
1337  if (*CharPtr == '>') {
1338  EndLoc = StrLoc.getFromPointer(CharPtr + 1);
1339  return true;
1340  }
1341  return false;
1342 }
1343 
1344 /// creating a string without the escape characters '!'.
1345 void AsmParser::altMacroString(StringRef AltMacroStr,std::string &Res) {
1346  for (size_t Pos = 0; Pos < AltMacroStr.size(); Pos++) {
1347  if (AltMacroStr[Pos] == '!')
1348  Pos++;
1349  Res += AltMacroStr[Pos];
1350  }
1351 }
1352 
1353 /// Parse an expression and return it.
1354 ///
1355 /// expr ::= expr &&,|| expr -> lowest.
1356 /// expr ::= expr |,^,&,! expr
1357 /// expr ::= expr ==,!=,<>,<,<=,>,>= expr
1358 /// expr ::= expr <<,>> expr
1359 /// expr ::= expr +,- expr
1360 /// expr ::= expr *,/,% expr -> highest.
1361 /// expr ::= primaryexpr
1362 ///
1363 bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1364  // Parse the expression.
1365  Res = nullptr;
1366  if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
1367  parseBinOpRHS(1, Res, EndLoc))
1368  return true;
1369 
1370  // As a special case, we support 'a op b @ modifier' by rewriting the
1371  // expression to include the modifier. This is inefficient, but in general we
1372  // expect users to use 'a@modifier op b'.
1373  if (Lexer.getKind() == AsmToken::At) {
1374  Lex();
1375 
1376  if (Lexer.isNot(AsmToken::Identifier))
1377  return TokError("unexpected symbol modifier following '@'");
1378 
1380  MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
1381  if (Variant == MCSymbolRefExpr::VK_Invalid)
1382  return TokError("invalid variant '" + getTok().getIdentifier() + "'");
1383 
1384  const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
1385  if (!ModifiedRes) {
1386  return TokError("invalid modifier '" + getTok().getIdentifier() +
1387  "' (no symbols present)");
1388  }
1389 
1390  Res = ModifiedRes;
1391  Lex();
1392  }
1393 
1394  // Try to constant fold it up front, if possible. Do not exploit
1395  // assembler here.
1396  int64_t Value;
1397  if (Res->evaluateAsAbsolute(Value))
1398  Res = MCConstantExpr::create(Value, getContext());
1399 
1400  return false;
1401 }
1402 
1403 bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
1404  Res = nullptr;
1405  return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
1406 }
1407 
1408 bool AsmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
1409  SMLoc &EndLoc) {
1410  if (parseParenExpr(Res, EndLoc))
1411  return true;
1412 
1413  for (; ParenDepth > 0; --ParenDepth) {
1414  if (parseBinOpRHS(1, Res, EndLoc))
1415  return true;
1416 
1417  // We don't Lex() the last RParen.
1418  // This is the same behavior as parseParenExpression().
1419  if (ParenDepth - 1 > 0) {
1420  EndLoc = getTok().getEndLoc();
1421  if (parseToken(AsmToken::RParen,
1422  "expected ')' in parentheses expression"))
1423  return true;
1424  }
1425  }
1426  return false;
1427 }
1428 
1429 bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
1430  const MCExpr *Expr;
1431 
1432  SMLoc StartLoc = Lexer.getLoc();
1433  if (parseExpression(Expr))
1434  return true;
1435 
1436  if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
1437  return Error(StartLoc, "expected absolute expression");
1438 
1439  return false;
1440 }
1441 
1444  bool ShouldUseLogicalShr) {
1445  switch (K) {
1446  default:
1447  return 0; // not a binop.
1448 
1449  // Lowest Precedence: &&, ||
1450  case AsmToken::AmpAmp:
1451  Kind = MCBinaryExpr::LAnd;
1452  return 1;
1453  case AsmToken::PipePipe:
1454  Kind = MCBinaryExpr::LOr;
1455  return 1;
1456 
1457  // Low Precedence: |, &, ^
1458  //
1459  // FIXME: gas seems to support '!' as an infix operator?
1460  case AsmToken::Pipe:
1461  Kind = MCBinaryExpr::Or;
1462  return 2;
1463  case AsmToken::Caret:
1464  Kind = MCBinaryExpr::Xor;
1465  return 2;
1466  case AsmToken::Amp:
1467  Kind = MCBinaryExpr::And;
1468  return 2;
1469 
1470  // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
1471  case AsmToken::EqualEqual:
1472  Kind = MCBinaryExpr::EQ;
1473  return 3;
1475  case AsmToken::LessGreater:
1476  Kind = MCBinaryExpr::NE;
1477  return 3;
1478  case AsmToken::Less:
1479  Kind = MCBinaryExpr::LT;
1480  return 3;
1481  case AsmToken::LessEqual:
1482  Kind = MCBinaryExpr::LTE;
1483  return 3;
1484  case AsmToken::Greater:
1485  Kind = MCBinaryExpr::GT;
1486  return 3;
1488  Kind = MCBinaryExpr::GTE;
1489  return 3;
1490 
1491  // Intermediate Precedence: <<, >>
1492  case AsmToken::LessLess:
1493  Kind = MCBinaryExpr::Shl;
1494  return 4;
1496  Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
1497  return 4;
1498 
1499  // High Intermediate Precedence: +, -
1500  case AsmToken::Plus:
1501  Kind = MCBinaryExpr::Add;
1502  return 5;
1503  case AsmToken::Minus:
1504  Kind = MCBinaryExpr::Sub;
1505  return 5;
1506 
1507  // Highest Precedence: *, /, %
1508  case AsmToken::Star:
1509  Kind = MCBinaryExpr::Mul;
1510  return 6;
1511  case AsmToken::Slash:
1512  Kind = MCBinaryExpr::Div;
1513  return 6;
1514  case AsmToken::Percent:
1515  Kind = MCBinaryExpr::Mod;
1516  return 6;
1517  }
1518 }
1519 
1522  bool ShouldUseLogicalShr) {
1523  switch (K) {
1524  default:
1525  return 0; // not a binop.
1526 
1527  // Lowest Precedence: &&, ||
1528  case AsmToken::AmpAmp:
1529  Kind = MCBinaryExpr::LAnd;
1530  return 2;
1531  case AsmToken::PipePipe:
1532  Kind = MCBinaryExpr::LOr;
1533  return 1;
1534 
1535  // Low Precedence: ==, !=, <>, <, <=, >, >=
1536  case AsmToken::EqualEqual:
1537  Kind = MCBinaryExpr::EQ;
1538  return 3;
1540  case AsmToken::LessGreater:
1541  Kind = MCBinaryExpr::NE;
1542  return 3;
1543  case AsmToken::Less:
1544  Kind = MCBinaryExpr::LT;
1545  return 3;
1546  case AsmToken::LessEqual:
1547  Kind = MCBinaryExpr::LTE;
1548  return 3;
1549  case AsmToken::Greater:
1550  Kind = MCBinaryExpr::GT;
1551  return 3;
1553  Kind = MCBinaryExpr::GTE;
1554  return 3;
1555 
1556  // Low Intermediate Precedence: +, -
1557  case AsmToken::Plus:
1558  Kind = MCBinaryExpr::Add;
1559  return 4;
1560  case AsmToken::Minus:
1561  Kind = MCBinaryExpr::Sub;
1562  return 4;
1563 
1564  // High Intermediate Precedence: |, &, ^
1565  //
1566  // FIXME: gas seems to support '!' as an infix operator?
1567  case AsmToken::Pipe:
1568  Kind = MCBinaryExpr::Or;
1569  return 5;
1570  case AsmToken::Caret:
1571  Kind = MCBinaryExpr::Xor;
1572  return 5;
1573  case AsmToken::Amp:
1574  Kind = MCBinaryExpr::And;
1575  return 5;
1576 
1577  // Highest Precedence: *, /, %, <<, >>
1578  case AsmToken::Star:
1579  Kind = MCBinaryExpr::Mul;
1580  return 6;
1581  case AsmToken::Slash:
1582  Kind = MCBinaryExpr::Div;
1583  return 6;
1584  case AsmToken::Percent:
1585  Kind = MCBinaryExpr::Mod;
1586  return 6;
1587  case AsmToken::LessLess:
1588  Kind = MCBinaryExpr::Shl;
1589  return 6;
1591  Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
1592  return 6;
1593  }
1594 }
1595 
1596 unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K,
1598  bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
1599  return IsDarwin ? getDarwinBinOpPrecedence(K, Kind, ShouldUseLogicalShr)
1600  : getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr);
1601 }
1602 
1603 /// Parse all binary operators with precedence >= 'Precedence'.
1604 /// Res contains the LHS of the expression on input.
1605 bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
1606  SMLoc &EndLoc) {
1607  SMLoc StartLoc = Lexer.getLoc();
1608  while (true) {
1610  unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
1611 
1612  // If the next token is lower precedence than we are allowed to eat, return
1613  // successfully with what we ate already.
1614  if (TokPrec < Precedence)
1615  return false;
1616 
1617  Lex();
1618 
1619  // Eat the next primary expression.
1620  const MCExpr *RHS;
1621  if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
1622  return true;
1623 
1624  // If BinOp binds less tightly with RHS than the operator after RHS, let
1625  // the pending operator take RHS as its LHS.
1627  unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
1628  if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
1629  return true;
1630 
1631  // Merge LHS and RHS according to operator.
1632  Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
1633  }
1634 }
1635 
1636 /// ParseStatement:
1637 /// ::= EndOfStatement
1638 /// ::= Label* Directive ...Operands... EndOfStatement
1639 /// ::= Label* Identifier OperandList* EndOfStatement
1640 bool AsmParser::parseStatement(ParseStatementInfo &Info,
1642  assert(!hasPendingError() && "parseStatement started with pending error");
1643  // Eat initial spaces and comments
1644  while (Lexer.is(AsmToken::Space))
1645  Lex();
1646  if (Lexer.is(AsmToken::EndOfStatement)) {
1647  // if this is a line comment we can drop it safely
1648  if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
1649  getTok().getString().front() == '\n')
1650  Out.AddBlankLine();
1651  Lex();
1652  return false;
1653  }
1654  // Statements always start with an identifier.
1655  AsmToken ID = getTok();
1656  SMLoc IDLoc = ID.getLoc();
1657  StringRef IDVal;
1658  int64_t LocalLabelVal = -1;
1659  if (Lexer.is(AsmToken::HashDirective))
1660  return parseCppHashLineFilenameComment(IDLoc);
1661  // Allow an integer followed by a ':' as a directional local label.
1662  if (Lexer.is(AsmToken::Integer)) {
1663  LocalLabelVal = getTok().getIntVal();
1664  if (LocalLabelVal < 0) {
1665  if (!TheCondState.Ignore) {
1666  Lex(); // always eat a token
1667  return Error(IDLoc, "unexpected token at start of statement");
1668  }
1669  IDVal = "";
1670  } else {
1671  IDVal = getTok().getString();
1672  Lex(); // Consume the integer token to be used as an identifier token.
1673  if (Lexer.getKind() != AsmToken::Colon) {
1674  if (!TheCondState.Ignore) {
1675  Lex(); // always eat a token
1676  return Error(IDLoc, "unexpected token at start of statement");
1677  }
1678  }
1679  }
1680  } else if (Lexer.is(AsmToken::Dot)) {
1681  // Treat '.' as a valid identifier in this context.
1682  Lex();
1683  IDVal = ".";
1684  } else if (Lexer.is(AsmToken::LCurly)) {
1685  // Treat '{' as a valid identifier in this context.
1686  Lex();
1687  IDVal = "{";
1688 
1689  } else if (Lexer.is(AsmToken::RCurly)) {
1690  // Treat '}' as a valid identifier in this context.
1691  Lex();
1692  IDVal = "}";
1693  } else if (Lexer.is(AsmToken::Star) &&
1694  getTargetParser().starIsStartOfStatement()) {
1695  // Accept '*' as a valid start of statement.
1696  Lex();
1697  IDVal = "*";
1698  } else if (parseIdentifier(IDVal)) {
1699  if (!TheCondState.Ignore) {
1700  Lex(); // always eat a token
1701  return Error(IDLoc, "unexpected token at start of statement");
1702  }
1703  IDVal = "";
1704  }
1705 
1706  // Handle conditional assembly here before checking for skipping. We
1707  // have to do this so that .endif isn't skipped in a ".if 0" block for
1708  // example.
1710  DirectiveKindMap.find(IDVal);
1711  DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1712  ? DK_NO_DIRECTIVE
1713  : DirKindIt->getValue();
1714  switch (DirKind) {
1715  default:
1716  break;
1717  case DK_IF:
1718  case DK_IFEQ:
1719  case DK_IFGE:
1720  case DK_IFGT:
1721  case DK_IFLE:
1722  case DK_IFLT:
1723  case DK_IFNE:
1724  return parseDirectiveIf(IDLoc, DirKind);
1725  case DK_IFB:
1726  return parseDirectiveIfb(IDLoc, true);
1727  case DK_IFNB:
1728  return parseDirectiveIfb(IDLoc, false);
1729  case DK_IFC:
1730  return parseDirectiveIfc(IDLoc, true);
1731  case DK_IFEQS:
1732  return parseDirectiveIfeqs(IDLoc, true);
1733  case DK_IFNC:
1734  return parseDirectiveIfc(IDLoc, false);
1735  case DK_IFNES:
1736  return parseDirectiveIfeqs(IDLoc, false);
1737  case DK_IFDEF:
1738  return parseDirectiveIfdef(IDLoc, true);
1739  case DK_IFNDEF:
1740  case DK_IFNOTDEF:
1741  return parseDirectiveIfdef(IDLoc, false);
1742  case DK_ELSEIF:
1743  return parseDirectiveElseIf(IDLoc);
1744  case DK_ELSE:
1745  return parseDirectiveElse(IDLoc);
1746  case DK_ENDIF:
1747  return parseDirectiveEndIf(IDLoc);
1748  }
1749 
1750  // Ignore the statement if in the middle of inactive conditional
1751  // (e.g. ".if 0").
1752  if (TheCondState.Ignore) {
1753  eatToEndOfStatement();
1754  return false;
1755  }
1756 
1757  // FIXME: Recurse on local labels?
1758 
1759  // See what kind of statement we have.
1760  switch (Lexer.getKind()) {
1761  case AsmToken::Colon: {
1762  if (!getTargetParser().isLabel(ID))
1763  break;
1764  if (checkForValidSection())
1765  return true;
1766 
1767  // identifier ':' -> Label.
1768  Lex();
1769 
1770  // Diagnose attempt to use '.' as a label.
1771  if (IDVal == ".")
1772  return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
1773 
1774  // Diagnose attempt to use a variable as a label.
1775  //
1776  // FIXME: Diagnostics. Note the location of the definition as a label.
1777  // FIXME: This doesn't diagnose assignment to a symbol which has been
1778  // implicitly marked as external.
1779  MCSymbol *Sym;
1780  if (LocalLabelVal == -1) {
1781  if (ParsingInlineAsm && SI) {
1782  StringRef RewrittenLabel =
1783  SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
1784  assert(!RewrittenLabel.empty() &&
1785  "We should have an internal name here.");
1786  Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
1787  RewrittenLabel);
1788  IDVal = RewrittenLabel;
1789  }
1790  Sym = getContext().getOrCreateSymbol(IDVal);
1791  } else
1792  Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
1793  // End of Labels should be treated as end of line for lexing
1794  // purposes but that information is not available to the Lexer who
1795  // does not understand Labels. This may cause us to see a Hash
1796  // here instead of a preprocessor line comment.
1797  if (getTok().is(AsmToken::Hash)) {
1798  StringRef CommentStr = parseStringToEndOfStatement();
1799  Lexer.Lex();
1800  Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
1801  }
1802 
1803  // Consume any end of statement token, if present, to avoid spurious
1804  // AddBlankLine calls().
1805  if (getTok().is(AsmToken::EndOfStatement)) {
1806  Lex();
1807  }
1808 
1809  // Emit the label.
1810  if (!getTargetParser().isParsingInlineAsm())
1811  Out.EmitLabel(Sym, IDLoc);
1812 
1813  // If we are generating dwarf for assembly source files then gather the
1814  // info to make a dwarf label entry for this label if needed.
1815  if (enabledGenDwarfForAssembly())
1816  MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
1817  IDLoc);
1818 
1819  getTargetParser().onLabelParsed(Sym);
1820 
1821  return false;
1822  }
1823 
1824  case AsmToken::Equal:
1825  if (!getTargetParser().equalIsAsmAssignment())
1826  break;
1827  // identifier '=' ... -> assignment statement
1828  Lex();
1829 
1830  return parseAssignment(IDVal, true);
1831 
1832  default: // Normal instruction or directive.
1833  break;
1834  }
1835 
1836  // If macros are enabled, check to see if this is a macro instantiation.
1837  if (areMacrosEnabled())
1838  if (const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
1839  return handleMacroEntry(M, IDLoc);
1840  }
1841 
1842  // Otherwise, we have a normal instruction or directive.
1843 
1844  // Directives start with "."
1845  if (IDVal[0] == '.' && IDVal != ".") {
1846  // There are several entities interested in parsing directives:
1847  //
1848  // 1. The target-specific assembly parser. Some directives are target
1849  // specific or may potentially behave differently on certain targets.
1850  // 2. Asm parser extensions. For example, platform-specific parsers
1851  // (like the ELF parser) register themselves as extensions.
1852  // 3. The generic directive parser implemented by this class. These are
1853  // all the directives that behave in a target and platform independent
1854  // manner, or at least have a default behavior that's shared between
1855  // all targets and platforms.
1856 
1857  getTargetParser().flushPendingInstructions(getStreamer());
1858 
1859  SMLoc StartTokLoc = getTok().getLoc();
1860  bool TPDirectiveReturn = getTargetParser().ParseDirective(ID);
1861 
1862  if (hasPendingError())
1863  return true;
1864  // Currently the return value should be true if we are
1865  // uninterested but as this is at odds with the standard parsing
1866  // convention (return true = error) we have instances of a parsed
1867  // directive that fails returning true as an error. Catch these
1868  // cases as best as possible errors here.
1869  if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
1870  return true;
1871  // Return if we did some parsing or believe we succeeded.
1872  if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
1873  return false;
1874 
1875  // Next, check the extension directive map to see if any extension has
1876  // registered itself to parse this directive.
1877  std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
1878  ExtensionDirectiveMap.lookup(IDVal);
1879  if (Handler.first)
1880  return (*Handler.second)(Handler.first, IDVal, IDLoc);
1881 
1882  // Finally, if no one else is interested in this directive, it must be
1883  // generic and familiar to this class.
1884  switch (DirKind) {
1885  default:
1886  break;
1887  case DK_SET:
1888  case DK_EQU:
1889  return parseDirectiveSet(IDVal, true);
1890  case DK_EQUIV:
1891  return parseDirectiveSet(IDVal, false);
1892  case DK_ASCII:
1893  return parseDirectiveAscii(IDVal, false);
1894  case DK_ASCIZ:
1895  case DK_STRING:
1896  return parseDirectiveAscii(IDVal, true);
1897  case DK_BYTE:
1898  case DK_DC_B:
1899  return parseDirectiveValue(IDVal, 1);
1900  case DK_DC:
1901  case DK_DC_W:
1902  case DK_SHORT:
1903  case DK_VALUE:
1904  case DK_2BYTE:
1905  return parseDirectiveValue(IDVal, 2);
1906  case DK_LONG:
1907  case DK_INT:
1908  case DK_4BYTE:
1909  case DK_DC_L:
1910  return parseDirectiveValue(IDVal, 4);
1911  case DK_QUAD:
1912  case DK_8BYTE:
1913  return parseDirectiveValue(IDVal, 8);
1914  case DK_DC_A:
1915  return parseDirectiveValue(
1916  IDVal, getContext().getAsmInfo()->getCodePointerSize());
1917  case DK_OCTA:
1918  return parseDirectiveOctaValue(IDVal);
1919  case DK_SINGLE:
1920  case DK_FLOAT:
1921  case DK_DC_S:
1922  return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle());
1923  case DK_DOUBLE:
1924  case DK_DC_D:
1925  return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble());
1926  case DK_ALIGN: {
1927  bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
1928  return parseDirectiveAlign(IsPow2, /*ExprSize=*/1);
1929  }
1930  case DK_ALIGN32: {
1931  bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
1932  return parseDirectiveAlign(IsPow2, /*ExprSize=*/4);
1933  }
1934  case DK_BALIGN:
1935  return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
1936  case DK_BALIGNW:
1937  return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
1938  case DK_BALIGNL:
1939  return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
1940  case DK_P2ALIGN:
1941  return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
1942  case DK_P2ALIGNW:
1943  return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
1944  case DK_P2ALIGNL:
1945  return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
1946  case DK_ORG:
1947  return parseDirectiveOrg();
1948  case DK_FILL:
1949  return parseDirectiveFill();
1950  case DK_ZERO:
1951  return parseDirectiveZero();
1952  case DK_EXTERN:
1953  eatToEndOfStatement(); // .extern is the default, ignore it.
1954  return false;
1955  case DK_GLOBL:
1956  case DK_GLOBAL:
1957  return parseDirectiveSymbolAttribute(MCSA_Global);
1958  case DK_LAZY_REFERENCE:
1959  return parseDirectiveSymbolAttribute(MCSA_LazyReference);
1960  case DK_NO_DEAD_STRIP:
1961  return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
1962  case DK_SYMBOL_RESOLVER:
1963  return parseDirectiveSymbolAttribute(MCSA_SymbolResolver);
1964  case DK_PRIVATE_EXTERN:
1965  return parseDirectiveSymbolAttribute(MCSA_PrivateExtern);
1966  case DK_REFERENCE:
1967  return parseDirectiveSymbolAttribute(MCSA_Reference);
1968  case DK_WEAK_DEFINITION:
1969  return parseDirectiveSymbolAttribute(MCSA_WeakDefinition);
1970  case DK_WEAK_REFERENCE:
1971  return parseDirectiveSymbolAttribute(MCSA_WeakReference);
1972  case DK_WEAK_DEF_CAN_BE_HIDDEN:
1973  return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
1974  case DK_COMM:
1975  case DK_COMMON:
1976  return parseDirectiveComm(/*IsLocal=*/false);
1977  case DK_LCOMM:
1978  return parseDirectiveComm(/*IsLocal=*/true);
1979  case DK_ABORT:
1980  return parseDirectiveAbort();
1981  case DK_INCLUDE:
1982  return parseDirectiveInclude();
1983  case DK_INCBIN:
1984  return parseDirectiveIncbin();
1985  case DK_CODE16:
1986  case DK_CODE16GCC:
1987  return TokError(Twine(IDVal) +
1988  " not currently supported for this target");
1989  case DK_REPT:
1990  return parseDirectiveRept(IDLoc, IDVal);
1991  case DK_IRP:
1992  return parseDirectiveIrp(IDLoc);
1993  case DK_IRPC:
1994  return parseDirectiveIrpc(IDLoc);
1995  case DK_ENDR:
1996  return parseDirectiveEndr(IDLoc);
1997  case DK_BUNDLE_ALIGN_MODE:
1998  return parseDirectiveBundleAlignMode();
1999  case DK_BUNDLE_LOCK:
2000  return parseDirectiveBundleLock();
2001  case DK_BUNDLE_UNLOCK:
2002  return parseDirectiveBundleUnlock();
2003  case DK_SLEB128:
2004  return parseDirectiveLEB128(true);
2005  case DK_ULEB128:
2006  return parseDirectiveLEB128(false);
2007  case DK_SPACE:
2008  case DK_SKIP:
2009  return parseDirectiveSpace(IDVal);
2010  case DK_FILE:
2011  return parseDirectiveFile(IDLoc);
2012  case DK_LINE:
2013  return parseDirectiveLine();
2014  case DK_LOC:
2015  return parseDirectiveLoc();
2016  case DK_STABS:
2017  return parseDirectiveStabs();
2018  case DK_CV_FILE:
2019  return parseDirectiveCVFile();
2020  case DK_CV_FUNC_ID:
2021  return parseDirectiveCVFuncId();
2022  case DK_CV_INLINE_SITE_ID:
2023  return parseDirectiveCVInlineSiteId();
2024  case DK_CV_LOC:
2025  return parseDirectiveCVLoc();
2026  case DK_CV_LINETABLE:
2027  return parseDirectiveCVLinetable();
2028  case DK_CV_INLINE_LINETABLE:
2029  return parseDirectiveCVInlineLinetable();
2030  case DK_CV_DEF_RANGE:
2031  return parseDirectiveCVDefRange();
2032  case DK_CV_STRINGTABLE:
2033  return parseDirectiveCVStringTable();
2034  case DK_CV_FILECHECKSUMS:
2035  return parseDirectiveCVFileChecksums();
2036  case DK_CV_FILECHECKSUM_OFFSET:
2037  return parseDirectiveCVFileChecksumOffset();
2038  case DK_CV_FPO_DATA:
2039  return parseDirectiveCVFPOData();
2040  case DK_CFI_SECTIONS:
2041  return parseDirectiveCFISections();
2042  case DK_CFI_STARTPROC:
2043  return parseDirectiveCFIStartProc();
2044  case DK_CFI_ENDPROC:
2045  return parseDirectiveCFIEndProc();
2046  case DK_CFI_DEF_CFA:
2047  return parseDirectiveCFIDefCfa(IDLoc);
2048  case DK_CFI_DEF_CFA_OFFSET:
2049  return parseDirectiveCFIDefCfaOffset();
2050  case DK_CFI_ADJUST_CFA_OFFSET:
2051  return parseDirectiveCFIAdjustCfaOffset();
2052  case DK_CFI_DEF_CFA_REGISTER:
2053  return parseDirectiveCFIDefCfaRegister(IDLoc);
2054  case DK_CFI_OFFSET:
2055  return parseDirectiveCFIOffset(IDLoc);
2056  case DK_CFI_REL_OFFSET:
2057  return parseDirectiveCFIRelOffset(IDLoc);
2058  case DK_CFI_PERSONALITY:
2059  return parseDirectiveCFIPersonalityOrLsda(true);
2060  case DK_CFI_LSDA:
2061  return parseDirectiveCFIPersonalityOrLsda(false);
2062  case DK_CFI_REMEMBER_STATE:
2063  return parseDirectiveCFIRememberState();
2064  case DK_CFI_RESTORE_STATE:
2065  return parseDirectiveCFIRestoreState();
2066  case DK_CFI_SAME_VALUE:
2067  return parseDirectiveCFISameValue(IDLoc);
2068  case DK_CFI_RESTORE:
2069  return parseDirectiveCFIRestore(IDLoc);
2070  case DK_CFI_ESCAPE:
2071  return parseDirectiveCFIEscape();
2072  case DK_CFI_RETURN_COLUMN:
2073  return parseDirectiveCFIReturnColumn(IDLoc);
2074  case DK_CFI_SIGNAL_FRAME:
2075  return parseDirectiveCFISignalFrame();
2076  case DK_CFI_UNDEFINED:
2077  return parseDirectiveCFIUndefined(IDLoc);
2078  case DK_CFI_REGISTER:
2079  return parseDirectiveCFIRegister(IDLoc);
2080  case DK_CFI_WINDOW_SAVE:
2081  return parseDirectiveCFIWindowSave();
2082  case DK_MACROS_ON:
2083  case DK_MACROS_OFF:
2084  return parseDirectiveMacrosOnOff(IDVal);
2085  case DK_MACRO:
2086  return parseDirectiveMacro(IDLoc);
2087  case DK_ALTMACRO:
2088  case DK_NOALTMACRO:
2089  return parseDirectiveAltmacro(IDVal);
2090  case DK_EXITM:
2091  return parseDirectiveExitMacro(IDVal);
2092  case DK_ENDM:
2093  case DK_ENDMACRO:
2094  return parseDirectiveEndMacro(IDVal);
2095  case DK_PURGEM:
2096  return parseDirectivePurgeMacro(IDLoc);
2097  case DK_END:
2098  return parseDirectiveEnd(IDLoc);
2099  case DK_ERR:
2100  return parseDirectiveError(IDLoc, false);
2101  case DK_ERROR:
2102  return parseDirectiveError(IDLoc, true);
2103  case DK_WARNING:
2104  return parseDirectiveWarning(IDLoc);
2105  case DK_RELOC:
2106  return parseDirectiveReloc(IDLoc);
2107  case DK_DCB:
2108  case DK_DCB_W:
2109  return parseDirectiveDCB(IDVal, 2);
2110  case DK_DCB_B:
2111  return parseDirectiveDCB(IDVal, 1);
2112  case DK_DCB_D:
2113  return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble());
2114  case DK_DCB_L:
2115  return parseDirectiveDCB(IDVal, 4);
2116  case DK_DCB_S:
2117  return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle());
2118  case DK_DC_X:
2119  case DK_DCB_X:
2120  return TokError(Twine(IDVal) +
2121  " not currently supported for this target");
2122  case DK_DS:
2123  case DK_DS_W:
2124  return parseDirectiveDS(IDVal, 2);
2125  case DK_DS_B:
2126  return parseDirectiveDS(IDVal, 1);
2127  case DK_DS_D:
2128  return parseDirectiveDS(IDVal, 8);
2129  case DK_DS_L:
2130  case DK_DS_S:
2131  return parseDirectiveDS(IDVal, 4);
2132  case DK_DS_P:
2133  case DK_DS_X:
2134  return parseDirectiveDS(IDVal, 12);
2135  case DK_PRINT:
2136  return parseDirectivePrint(IDLoc);
2137  case DK_ADDRSIG:
2138  return parseDirectiveAddrsig();
2139  case DK_ADDRSIG_SYM:
2140  return parseDirectiveAddrsigSym();
2141  }
2142 
2143  return Error(IDLoc, "unknown directive");
2144  }
2145 
2146  // __asm _emit or __asm __emit
2147  if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
2148  IDVal == "_EMIT" || IDVal == "__EMIT"))
2149  return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
2150 
2151  // __asm align
2152  if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
2153  return parseDirectiveMSAlign(IDLoc, Info);
2154 
2155  if (ParsingInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
2156  Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
2157  if (checkForValidSection())
2158  return true;
2159 
2160  // Canonicalize the opcode to lower case.
2161  std::string OpcodeStr = IDVal.lower();
2162  ParseInstructionInfo IInfo(Info.AsmRewrites);
2163  bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
2164  Info.ParsedOperands);
2165  Info.ParseError = ParseHadError;
2166 
2167  // Dump the parsed representation, if requested.
2168  if (getShowParsedOperands()) {
2169  SmallString<256> Str;
2170  raw_svector_ostream OS(Str);
2171  OS << "parsed instruction: [";
2172  for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
2173  if (i != 0)
2174  OS << ", ";
2175  Info.ParsedOperands[i]->print(OS);
2176  }
2177  OS << "]";
2178 
2179  printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
2180  }
2181 
2182  // Fail even if ParseInstruction erroneously returns false.
2183  if (hasPendingError() || ParseHadError)
2184  return true;
2185 
2186  // If we are generating dwarf for the current section then generate a .loc
2187  // directive for the instruction.
2188  if (!ParseHadError && enabledGenDwarfForAssembly() &&
2189  getContext().getGenDwarfSectionSyms().count(
2190  getStreamer().getCurrentSectionOnly())) {
2191  unsigned Line;
2192  if (ActiveMacros.empty())
2193  Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
2194  else
2195  Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
2196  ActiveMacros.front()->ExitBuffer);
2197 
2198  // If we previously parsed a cpp hash file line comment then make sure the
2199  // current Dwarf File is for the CppHashFilename if not then emit the
2200  // Dwarf File table for it and adjust the line number for the .loc.
2201  if (!CppHashInfo.Filename.empty()) {
2202  unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
2203  0, StringRef(), CppHashInfo.Filename);
2204  getContext().setGenDwarfFileNumber(FileNumber);
2205 
2206  unsigned CppHashLocLineNo =
2207  SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
2208  Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
2209  }
2210 
2211  getStreamer().EmitDwarfLocDirective(
2212  getContext().getGenDwarfFileNumber(), Line, 0,
2214  StringRef());
2215  }
2216 
2217  // If parsing succeeded, match the instruction.
2218  if (!ParseHadError) {
2219  uint64_t ErrorInfo;
2220  if (getTargetParser().MatchAndEmitInstruction(
2221  IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
2222  getTargetParser().isParsingInlineAsm()))
2223  return true;
2224  }
2225  return false;
2226 }
2227 
2228 // Parse and erase curly braces marking block start/end
2229 bool
2230 AsmParser::parseCurlyBlockScope(SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
2231  // Identify curly brace marking block start/end
2232  if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
2233  return false;
2234 
2235  SMLoc StartLoc = Lexer.getLoc();
2236  Lex(); // Eat the brace
2237  if (Lexer.is(AsmToken::EndOfStatement))
2238  Lex(); // Eat EndOfStatement following the brace
2239 
2240  // Erase the block start/end brace from the output asm string
2241  AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
2242  StartLoc.getPointer());
2243  return true;
2244 }
2245 
2246 /// parseCppHashLineFilenameComment as this:
2247 /// ::= # number "filename"
2248 bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) {
2249  Lex(); // Eat the hash token.
2250  // Lexer only ever emits HashDirective if it fully formed if it's
2251  // done the checking already so this is an internal error.
2252  assert(getTok().is(AsmToken::Integer) &&
2253  "Lexing Cpp line comment: Expected Integer");
2254  int64_t LineNumber = getTok().getIntVal();
2255  Lex();
2256  assert(getTok().is(AsmToken::String) &&
2257  "Lexing Cpp line comment: Expected String");
2258  StringRef Filename = getTok().getString();
2259  Lex();
2260 
2261  // Get rid of the enclosing quotes.
2262  Filename = Filename.substr(1, Filename.size() - 2);
2263 
2264  // Save the SMLoc, Filename and LineNumber for later use by diagnostics.
2265  CppHashInfo.Loc = L;
2266  CppHashInfo.Filename = Filename;
2267  CppHashInfo.LineNumber = LineNumber;
2268  CppHashInfo.Buf = CurBuffer;
2269  return false;
2270 }
2271 
2272 /// will use the last parsed cpp hash line filename comment
2273 /// for the Filename and LineNo if any in the diagnostic.
2274 void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
2275  const AsmParser *Parser = static_cast<const AsmParser *>(Context);
2276  raw_ostream &OS = errs();
2277 
2278  const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
2279  SMLoc DiagLoc = Diag.getLoc();
2280  unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2281  unsigned CppHashBuf =
2282  Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
2283 
2284  // Like SourceMgr::printMessage() we need to print the include stack if any
2285  // before printing the message.
2286  unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
2287  if (!Parser->SavedDiagHandler && DiagCurBuffer &&
2288  DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
2289  SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
2290  DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
2291  }
2292 
2293  // If we have not parsed a cpp hash line filename comment or the source
2294  // manager changed or buffer changed (like in a nested include) then just
2295  // print the normal diagnostic using its Filename and LineNo.
2296  if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
2297  DiagBuf != CppHashBuf) {
2298  if (Parser->SavedDiagHandler)
2299  Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
2300  else
2301  Diag.print(nullptr, OS);
2302  return;
2303  }
2304 
2305  // Use the CppHashFilename and calculate a line number based on the
2306  // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
2307  // for the diagnostic.
2308  const std::string &Filename = Parser->CppHashInfo.Filename;
2309 
2310  int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
2311  int CppHashLocLineNo =
2312  Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
2313  int LineNo =
2314  Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
2315 
2316  SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
2317  Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
2318  Diag.getLineContents(), Diag.getRanges());
2319 
2320  if (Parser->SavedDiagHandler)
2321  Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
2322  else
2323  NewDiag.print(nullptr, OS);
2324 }
2325 
2326 // FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The
2327 // difference being that that function accepts '@' as part of identifiers and
2328 // we can't do that. AsmLexer.cpp should probably be changed to handle
2329 // '@' as a special case when needed.
2330 static bool isIdentifierChar(char c) {
2331  return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
2332  c == '.';
2333 }
2334 
2335 bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
2336  ArrayRef<MCAsmMacroParameter> Parameters,
2338  bool EnableAtPseudoVariable, SMLoc L) {
2339  unsigned NParameters = Parameters.size();
2340  bool HasVararg = NParameters ? Parameters.back().Vararg : false;
2341  if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
2342  return Error(L, "Wrong number of arguments");
2343 
2344  // A macro without parameters is handled differently on Darwin:
2345  // gas accepts no arguments and does no substitutions
2346  while (!Body.empty()) {
2347  // Scan for the next substitution.
2348  std::size_t End = Body.size(), Pos = 0;
2349  for (; Pos != End; ++Pos) {
2350  // Check for a substitution or escape.
2351  if (IsDarwin && !NParameters) {
2352  // This macro has no parameters, look for $0, $1, etc.
2353  if (Body[Pos] != '$' || Pos + 1 == End)
2354  continue;
2355 
2356  char Next = Body[Pos + 1];
2357  if (Next == '$' || Next == 'n' ||
2358  isdigit(static_cast<unsigned char>(Next)))
2359  break;
2360  } else {
2361  // This macro has parameters, look for \foo, \bar, etc.
2362  if (Body[Pos] == '\\' && Pos + 1 != End)
2363  break;
2364  }
2365  }
2366 
2367  // Add the prefix.
2368  OS << Body.slice(0, Pos);
2369 
2370  // Check if we reached the end.
2371  if (Pos == End)
2372  break;
2373 
2374  if (IsDarwin && !NParameters) {
2375  switch (Body[Pos + 1]) {
2376  // $$ => $
2377  case '$':
2378  OS << '$';
2379  break;
2380 
2381  // $n => number of arguments
2382  case 'n':
2383  OS << A.size();
2384  break;
2385 
2386  // $[0-9] => argument
2387  default: {
2388  // Missing arguments are ignored.
2389  unsigned Index = Body[Pos + 1] - '0';
2390  if (Index >= A.size())
2391  break;
2392 
2393  // Otherwise substitute with the token values, with spaces eliminated.
2394  for (const AsmToken &Token : A[Index])
2395  OS << Token.getString();
2396  break;
2397  }
2398  }
2399  Pos += 2;
2400  } else {
2401  unsigned I = Pos + 1;
2402 
2403  // Check for the \@ pseudo-variable.
2404  if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
2405  ++I;
2406  else
2407  while (isIdentifierChar(Body[I]) && I + 1 != End)
2408  ++I;
2409 
2410  const char *Begin = Body.data() + Pos + 1;
2411  StringRef Argument(Begin, I - (Pos + 1));
2412  unsigned Index = 0;
2413 
2414  if (Argument == "@") {
2415  OS << NumOfMacroInstantiations;
2416  Pos += 2;
2417  } else {
2418  for (; Index < NParameters; ++Index)
2419  if (Parameters[Index].Name == Argument)
2420  break;
2421 
2422  if (Index == NParameters) {
2423  if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
2424  Pos += 3;
2425  else {
2426  OS << '\\' << Argument;
2427  Pos = I;
2428  }
2429  } else {
2430  bool VarargParameter = HasVararg && Index == (NParameters - 1);
2431  for (const AsmToken &Token : A[Index])
2432  // For altmacro mode, you can write '%expr'.
2433  // The prefix '%' evaluates the expression 'expr'
2434  // and uses the result as a string (e.g. replace %(1+2) with the string "3").
2435  // Here, we identify the integer token which is the result of the
2436  // absolute expression evaluation and replace it with its string representation.
2437  if ((Lexer.IsaAltMacroMode()) &&
2438  (*(Token.getString().begin()) == '%') && Token.is(AsmToken::Integer))
2439  // Emit an integer value to the buffer.
2440  OS << Token.getIntVal();
2441  // Only Token that was validated as a string and begins with '<'
2442  // is considered altMacroString!!!
2443  else if ((Lexer.IsaAltMacroMode()) &&
2444  (*(Token.getString().begin()) == '<') &&
2445  Token.is(AsmToken::String)) {
2446  std::string Res;
2447  altMacroString(Token.getStringContents(), Res);
2448  OS << Res;
2449  }
2450  // We expect no quotes around the string's contents when
2451  // parsing for varargs.
2452  else if (Token.isNot(AsmToken::String) || VarargParameter)
2453  OS << Token.getString();
2454  else
2455  OS << Token.getStringContents();
2456 
2457  Pos += 1 + Argument.size();
2458  }
2459  }
2460  }
2461  // Update the scan point.
2462  Body = Body.substr(Pos);
2463  }
2464 
2465  return false;
2466 }
2467 
2468 MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
2469  size_t CondStackDepth)
2470  : InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
2471  CondStackDepth(CondStackDepth) {}
2472 
2473 static bool isOperator(AsmToken::TokenKind kind) {
2474  switch (kind) {
2475  default:
2476  return false;
2477  case AsmToken::Plus:
2478  case AsmToken::Minus:
2479  case AsmToken::Tilde:
2480  case AsmToken::Slash:
2481  case AsmToken::Star:
2482  case AsmToken::Dot:
2483  case AsmToken::Equal:
2484  case AsmToken::EqualEqual:
2485  case AsmToken::Pipe:
2486  case AsmToken::PipePipe:
2487  case AsmToken::Caret:
2488  case AsmToken::Amp:
2489  case AsmToken::AmpAmp:
2490  case AsmToken::Exclaim:
2492  case AsmToken::Less:
2493  case AsmToken::LessEqual:
2494  case AsmToken::LessLess:
2495  case AsmToken::LessGreater:
2496  case AsmToken::Greater:
2499  return true;
2500  }
2501 }
2502 
2503 namespace {
2504 
2505 class AsmLexerSkipSpaceRAII {
2506 public:
2507  AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
2508  Lexer.setSkipSpace(SkipSpace);
2509  }
2510 
2511  ~AsmLexerSkipSpaceRAII() {
2512  Lexer.setSkipSpace(true);
2513  }
2514 
2515 private:
2516  AsmLexer &Lexer;
2517 };
2518 
2519 } // end anonymous namespace
2520 
2521 bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) {
2522 
2523  if (Vararg) {
2524  if (Lexer.isNot(AsmToken::EndOfStatement)) {
2525  StringRef Str = parseStringToEndOfStatement();
2526  MA.emplace_back(AsmToken::String, Str);
2527  }
2528  return false;
2529  }
2530 
2531  unsigned ParenLevel = 0;
2532 
2533  // Darwin doesn't use spaces to delmit arguments.
2534  AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
2535 
2536  bool SpaceEaten;
2537 
2538  while (true) {
2539  SpaceEaten = false;
2540  if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
2541  return TokError("unexpected token in macro instantiation");
2542 
2543  if (ParenLevel == 0) {
2544 
2545  if (Lexer.is(AsmToken::Comma))
2546  break;
2547 
2548  if (Lexer.is(AsmToken::Space)) {
2549  SpaceEaten = true;
2550  Lexer.Lex(); // Eat spaces
2551  }
2552 
2553  // Spaces can delimit parameters, but could also be part an expression.
2554  // If the token after a space is an operator, add the token and the next
2555  // one into this argument
2556  if (!IsDarwin) {
2557  if (isOperator(Lexer.getKind())) {
2558  MA.push_back(getTok());
2559  Lexer.Lex();
2560 
2561  // Whitespace after an operator can be ignored.
2562  if (Lexer.is(AsmToken::Space))
2563  Lexer.Lex();
2564 
2565  continue;
2566  }
2567  }
2568  if (SpaceEaten)
2569  break;
2570  }
2571 
2572  // handleMacroEntry relies on not advancing the lexer here
2573  // to be able to fill in the remaining default parameter values
2574  if (Lexer.is(AsmToken::EndOfStatement))
2575  break;
2576 
2577  // Adjust the current parentheses level.
2578  if (Lexer.is(AsmToken::LParen))
2579  ++ParenLevel;
2580  else if (Lexer.is(AsmToken::RParen) && ParenLevel)
2581  --ParenLevel;
2582 
2583  // Append the token to the current argument list.
2584  MA.push_back(getTok());
2585  Lexer.Lex();
2586  }
2587 
2588  if (ParenLevel != 0)
2589  return TokError("unbalanced parentheses in macro argument");
2590  return false;
2591 }
2592 
2593 // Parse the macro instantiation arguments.
2594 bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
2595  MCAsmMacroArguments &A) {
2596  const unsigned NParameters = M ? M->Parameters.size() : 0;
2597  bool NamedParametersFound = false;
2598  SmallVector<SMLoc, 4> FALocs;
2599 
2600  A.resize(NParameters);
2601  FALocs.resize(NParameters);
2602 
2603  // Parse two kinds of macro invocations:
2604  // - macros defined without any parameters accept an arbitrary number of them
2605  // - macros defined with parameters accept at most that many of them
2606  bool HasVararg = NParameters ? M->Parameters.back().Vararg : false;
2607  for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
2608  ++Parameter) {
2609  SMLoc IDLoc = Lexer.getLoc();
2611 
2612  if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) {
2613  if (parseIdentifier(FA.Name))
2614  return Error(IDLoc, "invalid argument identifier for formal argument");
2615 
2616  if (Lexer.isNot(AsmToken::Equal))
2617  return TokError("expected '=' after formal parameter identifier");
2618 
2619  Lex();
2620 
2621  NamedParametersFound = true;
2622  }
2623  bool Vararg = HasVararg && Parameter == (NParameters - 1);
2624 
2625  if (NamedParametersFound && FA.Name.empty())
2626  return Error(IDLoc, "cannot mix positional and keyword arguments");
2627 
2628  SMLoc StrLoc = Lexer.getLoc();
2629  SMLoc EndLoc;
2630  if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Percent)) {
2631  const MCExpr *AbsoluteExp;
2632  int64_t Value;
2633  /// Eat '%'
2634  Lex();
2635  if (parseExpression(AbsoluteExp, EndLoc))
2636  return false;
2637  if (!AbsoluteExp->evaluateAsAbsolute(Value,
2638  getStreamer().getAssemblerPtr()))
2639  return Error(StrLoc, "expected absolute expression");
2640  const char *StrChar = StrLoc.getPointer();
2641  const char *EndChar = EndLoc.getPointer();
2642  AsmToken newToken(AsmToken::Integer, StringRef(StrChar , EndChar - StrChar), Value);
2643  FA.Value.push_back(newToken);
2644  } else if (Lexer.IsaAltMacroMode() && Lexer.is(AsmToken::Less) &&
2645  isAltmacroString(StrLoc, EndLoc)) {
2646  const char *StrChar = StrLoc.getPointer();
2647  const char *EndChar = EndLoc.getPointer();
2648  jumpToLoc(EndLoc, CurBuffer);
2649  /// Eat from '<' to '>'
2650  Lex();
2651  AsmToken newToken(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
2652  FA.Value.push_back(newToken);
2653  } else if(parseMacroArgument(FA.Value, Vararg))
2654  return true;
2655 
2656  unsigned PI = Parameter;
2657  if (!FA.Name.empty()) {
2658  unsigned FAI = 0;
2659  for (FAI = 0; FAI < NParameters; ++FAI)
2660  if (M->Parameters[FAI].Name == FA.Name)
2661  break;
2662 
2663  if (FAI >= NParameters) {
2664  assert(M && "expected macro to be defined");
2665  return Error(IDLoc, "parameter named '" + FA.Name +
2666  "' does not exist for macro '" + M->Name + "'");
2667  }
2668  PI = FAI;
2669  }
2670 
2671  if (!FA.Value.empty()) {
2672  if (A.size() <= PI)
2673  A.resize(PI + 1);
2674  A[PI] = FA.Value;
2675 
2676  if (FALocs.size() <= PI)
2677  FALocs.resize(PI + 1);
2678 
2679  FALocs[PI] = Lexer.getLoc();
2680  }
2681 
2682  // At the end of the statement, fill in remaining arguments that have
2683  // default values. If there aren't any, then the next argument is
2684  // required but missing
2685  if (Lexer.is(AsmToken::EndOfStatement)) {
2686  bool Failure = false;
2687  for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
2688  if (A[FAI].empty()) {
2689  if (M->Parameters[FAI].Required) {
2690  Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
2691  "missing value for required parameter "
2692  "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
2693  Failure = true;
2694  }
2695 
2696  if (!M->Parameters[FAI].Value.empty())
2697  A[FAI] = M->Parameters[FAI].Value;
2698  }
2699  }
2700  return Failure;
2701  }
2702 
2703  if (Lexer.is(AsmToken::Comma))
2704  Lex();
2705  }
2706 
2707  return TokError("too many positional arguments");
2708 }
2709 
2710 bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
2711  // Arbitrarily limit macro nesting depth (default matches 'as'). We can
2712  // eliminate this, although we should protect against infinite loops.
2713  unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
2714  if (ActiveMacros.size() == MaxNestingDepth) {
2715  std::ostringstream MaxNestingDepthError;
2716  MaxNestingDepthError << "macros cannot be nested more than "
2717  << MaxNestingDepth << " levels deep."
2718  << " Use -asm-macro-max-nesting-depth to increase "
2719  "this limit.";
2720  return TokError(MaxNestingDepthError.str());
2721  }
2722 
2723  MCAsmMacroArguments A;
2724  if (parseMacroArguments(M, A))
2725  return true;
2726 
2727  // Macro instantiation is lexical, unfortunately. We construct a new buffer
2728  // to hold the macro body with substitutions.
2729  SmallString<256> Buf;
2730  StringRef Body = M->Body;
2731  raw_svector_ostream OS(Buf);
2732 
2733  if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc()))
2734  return true;
2735 
2736  // We include the .endmacro in the buffer as our cue to exit the macro
2737  // instantiation.
2738  OS << ".endmacro\n";
2739 
2740  std::unique_ptr<MemoryBuffer> Instantiation =
2741  MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
2742 
2743  // Create the macro instantiation object and add to the current macro
2744  // instantiation stack.
2745  MacroInstantiation *MI = new MacroInstantiation(
2746  NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
2747  ActiveMacros.push_back(MI);
2748 
2749  ++NumOfMacroInstantiations;
2750 
2751  // Jump to the macro instantiation and prime the lexer.
2752  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
2753  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
2754  Lex();
2755 
2756  return false;
2757 }
2758 
2759 void AsmParser::handleMacroExit() {
2760  // Jump to the EndOfStatement we should return to, and consume it.
2761  jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
2762  Lex();
2763 
2764  // Pop the instantiation entry.
2765  delete ActiveMacros.back();
2766  ActiveMacros.pop_back();
2767 }
2768 
2769 bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
2770  bool NoDeadStrip) {
2771  MCSymbol *Sym;
2772  const MCExpr *Value;
2773  if (MCParserUtils::parseAssignmentExpression(Name, allow_redef, *this, Sym,
2774  Value))
2775  return true;
2776 
2777  if (!Sym) {
2778  // In the case where we parse an expression starting with a '.', we will
2779  // not generate an error, nor will we create a symbol. In this case we
2780  // should just return out.
2781  return false;
2782  }
2783 
2784  // Do the assignment.
2785  Out.EmitAssignment(Sym, Value);
2786  if (NoDeadStrip)
2788 
2789  return false;
2790 }
2791 
2792 /// parseIdentifier:
2793 /// ::= identifier
2794 /// ::= string
2795 bool AsmParser::parseIdentifier(StringRef &Res) {
2796  // The assembler has relaxed rules for accepting identifiers, in particular we
2797  // allow things like '.globl $foo' and '.def @feat.00', which would normally be
2798  // separate tokens. At this level, we have already lexed so we cannot (currently)
2799  // handle this as a context dependent token, instead we detect adjacent tokens
2800  // and return the combined identifier.
2801  if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
2802  SMLoc PrefixLoc = getLexer().getLoc();
2803 
2804  // Consume the prefix character, and check for a following identifier.
2805 
2806  AsmToken Buf[1];
2807  Lexer.peekTokens(Buf, false);
2808 
2809  if (Buf[0].isNot(AsmToken::Identifier))
2810  return true;
2811 
2812  // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
2813  if (PrefixLoc.getPointer() + 1 != Buf[0].getLoc().getPointer())
2814  return true;
2815 
2816  // eat $ or @
2817  Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
2818  // Construct the joined identifier and consume the token.
2819  Res =
2820  StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
2821  Lex(); // Parser Lex to maintain invariants.
2822  return false;
2823  }
2824 
2825  if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
2826  return true;
2827 
2828  Res = getTok().getIdentifier();
2829 
2830  Lex(); // Consume the identifier token.
2831 
2832  return false;
2833 }
2834 
2835 /// parseDirectiveSet:
2836 /// ::= .equ identifier ',' expression
2837 /// ::= .equiv identifier ',' expression
2838 /// ::= .set identifier ',' expression
2839 bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
2840  StringRef Name;
2841  if (check(parseIdentifier(Name), "expected identifier") ||
2842  parseToken(AsmToken::Comma) || parseAssignment(Name, allow_redef, true))
2843  return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
2844  return false;
2845 }
2846 
2847 bool AsmParser::parseEscapedString(std::string &Data) {
2848  if (check(getTok().isNot(AsmToken::String), "expected string"))
2849  return true;
2850 
2851  Data = "";
2852  StringRef Str = getTok().getStringContents();
2853  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
2854  if (Str[i] != '\\') {
2855  Data += Str[i];
2856  continue;
2857  }
2858 
2859  // Recognize escaped characters. Note that this escape semantics currently
2860  // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
2861  ++i;
2862  if (i == e)
2863  return TokError("unexpected backslash at end of string");
2864 
2865  // Recognize octal sequences.
2866  if ((unsigned)(Str[i] - '0') <= 7) {
2867  // Consume up to three octal characters.
2868  unsigned Value = Str[i] - '0';
2869 
2870  if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
2871  ++i;
2872  Value = Value * 8 + (Str[i] - '0');
2873 
2874  if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
2875  ++i;
2876  Value = Value * 8 + (Str[i] - '0');
2877  }
2878  }
2879 
2880  if (Value > 255)
2881  return TokError("invalid octal escape sequence (out of range)");
2882 
2883  Data += (unsigned char)Value;
2884  continue;
2885  }
2886 
2887  // Otherwise recognize individual escapes.
2888  switch (Str[i]) {
2889  default:
2890  // Just reject invalid escape sequences for now.
2891  return TokError("invalid escape sequence (unrecognized character)");
2892 
2893  case 'b': Data += '\b'; break;
2894  case 'f': Data += '\f'; break;
2895  case 'n': Data += '\n'; break;
2896  case 'r': Data += '\r'; break;
2897  case 't': Data += '\t'; break;
2898  case '"': Data += '"'; break;
2899  case '\\': Data += '\\'; break;
2900  }
2901  }
2902 
2903  Lex();
2904  return false;
2905 }
2906 
2907 /// parseDirectiveAscii:
2908 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
2909 bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
2910  auto parseOp = [&]() -> bool {
2911  std::string Data;
2912  if (checkForValidSection() || parseEscapedString(Data))
2913  return true;
2914  getStreamer().EmitBytes(Data);
2915  if (ZeroTerminated)
2916  getStreamer().EmitBytes(StringRef("\0", 1));
2917  return false;
2918  };
2919 
2920  if (parseMany(parseOp))
2921  return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
2922  return false;
2923 }
2924 
2925 /// parseDirectiveReloc
2926 /// ::= .reloc expression , identifier [ , expression ]
2927 bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
2928  const MCExpr *Offset;
2929  const MCExpr *Expr = nullptr;
2930 
2931  SMLoc OffsetLoc = Lexer.getTok().getLoc();
2932  int64_t OffsetValue;
2933  // We can only deal with constant expressions at the moment.
2934 
2935  if (parseExpression(Offset))
2936  return true;
2937 
2938  if (check(!Offset->evaluateAsAbsolute(OffsetValue,
2939  getStreamer().getAssemblerPtr()),
2940  OffsetLoc, "expression is not a constant value") ||
2941  check(OffsetValue < 0, OffsetLoc, "expression is negative") ||
2942  parseToken(AsmToken::Comma, "expected comma") ||
2943  check(getTok().isNot(AsmToken::Identifier), "expected relocation name"))
2944  return true;
2945 
2946  SMLoc NameLoc = Lexer.getTok().getLoc();
2947  StringRef Name = Lexer.getTok().getIdentifier();
2948  Lex();
2949 
2950  if (Lexer.is(AsmToken::Comma)) {
2951  Lex();
2952  SMLoc ExprLoc = Lexer.getLoc();
2953  if (parseExpression(Expr))
2954  return true;
2955 
2956  MCValue Value;
2957  if (!Expr->evaluateAsRelocatable(Value, nullptr, nullptr))
2958  return Error(ExprLoc, "expression must be relocatable");
2959  }
2960 
2961  if (parseToken(AsmToken::EndOfStatement,
2962  "unexpected token in .reloc directive"))
2963  return true;
2964 
2965  const MCTargetAsmParser &MCT = getTargetParser();
2966  const MCSubtargetInfo &STI = MCT.getSTI();
2967  if (getStreamer().EmitRelocDirective(*Offset, Name, Expr, DirectiveLoc, STI))
2968  return Error(NameLoc, "unknown relocation name");
2969 
2970  return false;
2971 }
2972 
2973 /// parseDirectiveValue
2974 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
2975 bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
2976  auto parseOp = [&]() -> bool {
2977  const MCExpr *Value;
2978  SMLoc ExprLoc = getLexer().getLoc();
2979  if (checkForValidSection() || parseExpression(Value))
2980  return true;
2981  // Special case constant expressions to match code generator.
2982  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
2983  assert(Size <= 8 && "Invalid size");
2984  uint64_t IntValue = MCE->getValue();
2985  if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
2986  return Error(ExprLoc, "out of range literal value");
2987  getStreamer().EmitIntValue(IntValue, Size);
2988  } else
2989  getStreamer().EmitValue(Value, Size, ExprLoc);
2990  return false;
2991  };
2992 
2993  if (parseMany(parseOp))
2994  return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
2995  return false;
2996 }
2997 
2998 static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo) {
2999  if (Asm.getTok().isNot(AsmToken::Integer) &&
3000  Asm.getTok().isNot(AsmToken::BigNum))
3001  return Asm.TokError("unknown token in expression");
3002  SMLoc ExprLoc = Asm.getTok().getLoc();
3003  APInt IntValue = Asm.getTok().getAPIntVal();
3004  Asm.Lex();
3005  if (!IntValue.isIntN(128))
3006  return Asm.Error(ExprLoc, "out of range literal value");
3007  if (!IntValue.isIntN(64)) {
3008  hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
3009  lo = IntValue.getLoBits(64).getZExtValue();
3010  } else {
3011  hi = 0;
3012  lo = IntValue.getZExtValue();
3013  }
3014  return false;
3015 }
3016 
3017 /// ParseDirectiveOctaValue
3018 /// ::= .octa [ hexconstant (, hexconstant)* ]
3019 
3020 bool AsmParser::parseDirectiveOctaValue(StringRef IDVal) {
3021  auto parseOp = [&]() -> bool {
3022  if (checkForValidSection())
3023  return true;
3024  uint64_t hi, lo;
3025  if (parseHexOcta(*this, hi, lo))
3026  return true;
3027  if (MAI.isLittleEndian()) {
3028  getStreamer().EmitIntValue(lo, 8);
3029  getStreamer().EmitIntValue(hi, 8);
3030  } else {
3031  getStreamer().EmitIntValue(hi, 8);
3032  getStreamer().EmitIntValue(lo, 8);
3033  }
3034  return false;
3035  };
3036 
3037  if (parseMany(parseOp))
3038  return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3039  return false;
3040 }
3041 
3042 bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
3043  // We don't truly support arithmetic on floating point expressions, so we
3044  // have to manually parse unary prefixes.
3045  bool IsNeg = false;
3046  if (getLexer().is(AsmToken::Minus)) {
3047  Lexer.Lex();
3048  IsNeg = true;
3049  } else if (getLexer().is(AsmToken::Plus))
3050  Lexer.Lex();
3051 
3052  if (Lexer.is(AsmToken::Error))
3053  return TokError(Lexer.getErr());
3054  if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
3055  Lexer.isNot(AsmToken::Identifier))
3056  return TokError("unexpected token in directive");
3057 
3058  // Convert to an APFloat.
3059  APFloat Value(Semantics);
3060  StringRef IDVal = getTok().getString();
3061  if (getLexer().is(AsmToken::Identifier)) {
3062  if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
3063  Value = APFloat::getInf(Semantics);
3064  else if (!IDVal.compare_lower("nan"))
3065  Value = APFloat::getNaN(Semantics, false, ~0);
3066  else
3067  return TokError("invalid floating point literal");
3068  } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
3070  return TokError("invalid floating point literal");
3071  if (IsNeg)
3072  Value.changeSign();
3073 
3074  // Consume the numeric token.
3075  Lex();
3076 
3077  Res = Value.bitcastToAPInt();
3078 
3079  return false;
3080 }
3081 
3082 /// parseDirectiveRealValue
3083 /// ::= (.single | .double) [ expression (, expression)* ]
3084 bool AsmParser::parseDirectiveRealValue(StringRef IDVal,
3085  const fltSemantics &Semantics) {
3086  auto parseOp = [&]() -> bool {
3087  APInt AsInt;
3088  if (checkForValidSection() || parseRealValue(Semantics, AsInt))
3089  return true;
3090  getStreamer().EmitIntValue(AsInt.getLimitedValue(),
3091  AsInt.getBitWidth() / 8);
3092  return false;
3093  };
3094 
3095  if (parseMany(parseOp))
3096  return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
3097  return false;
3098 }
3099 
3100 /// parseDirectiveZero
3101 /// ::= .zero expression
3102 bool AsmParser::parseDirectiveZero() {
3103  SMLoc NumBytesLoc = Lexer.getLoc();
3104  const MCExpr *NumBytes;
3105  if (checkForValidSection() || parseExpression(NumBytes))
3106  return true;
3107 
3108  int64_t Val = 0;
3109  if (getLexer().is(AsmToken::Comma)) {
3110  Lex();
3111  if (parseAbsoluteExpression(Val))
3112  return true;
3113  }
3114 
3115  if (parseToken(AsmToken::EndOfStatement,
3116  "unexpected token in '.zero' directive"))
3117  return true;
3118  getStreamer().emitFill(*NumBytes, Val, NumBytesLoc);
3119 
3120  return false;
3121 }
3122 
3123 /// parseDirectiveFill
3124 /// ::= .fill expression [ , expression [ , expression ] ]
3125 bool AsmParser::parseDirectiveFill() {
3126  SMLoc NumValuesLoc = Lexer.getLoc();
3127  const MCExpr *NumValues;
3128  if (checkForValidSection() || parseExpression(NumValues))
3129  return true;
3130 
3131  int64_t FillSize = 1;
3132  int64_t FillExpr = 0;
3133 
3134  SMLoc SizeLoc, ExprLoc;
3135 
3136  if (parseOptionalToken(AsmToken::Comma)) {
3137  SizeLoc = getTok().getLoc();
3138  if (parseAbsoluteExpression(FillSize))
3139  return true;
3140  if (parseOptionalToken(AsmToken::Comma)) {
3141  ExprLoc = getTok().getLoc();
3142  if (parseAbsoluteExpression(FillExpr))
3143  return true;
3144  }
3145  }
3146  if (parseToken(AsmToken::EndOfStatement,
3147  "unexpected token in '.fill' directive"))
3148  return true;
3149 
3150  if (FillSize < 0) {
3151  Warning(SizeLoc, "'.fill' directive with negative size has no effect");
3152  return false;
3153  }
3154  if (FillSize > 8) {
3155  Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8");
3156  FillSize = 8;
3157  }
3158 
3159  if (!isUInt<32>(FillExpr) && FillSize > 4)
3160  Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
3161 
3162  getStreamer().emitFill(*NumValues, FillSize, FillExpr, NumValuesLoc);
3163 
3164  return false;
3165 }
3166 
3167 /// parseDirectiveOrg
3168 /// ::= .org expression [ , expression ]
3169 bool AsmParser::parseDirectiveOrg() {
3170  const MCExpr *Offset;
3171  SMLoc OffsetLoc = Lexer.getLoc();
3172  if (checkForValidSection() || parseExpression(Offset))
3173  return true;
3174 
3175  // Parse optional fill expression.
3176  int64_t FillExpr = 0;
3177  if (parseOptionalToken(AsmToken::Comma))
3178  if (parseAbsoluteExpression(FillExpr))
3179  return addErrorSuffix(" in '.org' directive");
3180  if (parseToken(AsmToken::EndOfStatement))
3181  return addErrorSuffix(" in '.org' directive");
3182 
3183  getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc);
3184  return false;
3185 }
3186 
3187 /// parseDirectiveAlign
3188 /// ::= {.align, ...} expression [ , expression [ , expression ]]
3189 bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
3190  SMLoc AlignmentLoc = getLexer().getLoc();
3191  int64_t Alignment;
3192  SMLoc MaxBytesLoc;
3193  bool HasFillExpr = false;
3194  int64_t FillExpr = 0;
3195  int64_t MaxBytesToFill = 0;
3196 
3197  auto parseAlign = [&]() -> bool {
3198  if (parseAbsoluteExpression(Alignment))
3199  return true;
3200  if (parseOptionalToken(AsmToken::Comma)) {
3201  // The fill expression can be omitted while specifying a maximum number of
3202  // alignment bytes, e.g:
3203  // .align 3,,4
3204  if (getTok().isNot(AsmToken::Comma)) {
3205  HasFillExpr = true;
3206  if (parseAbsoluteExpression(FillExpr))
3207  return true;
3208  }
3209  if (parseOptionalToken(AsmToken::Comma))
3210  if (parseTokenLoc(MaxBytesLoc) ||
3211  parseAbsoluteExpression(MaxBytesToFill))
3212  return true;
3213  }
3214  return parseToken(AsmToken::EndOfStatement);
3215  };
3216 
3217  if (checkForValidSection())
3218  return addErrorSuffix(" in directive");
3219  // Ignore empty '.p2align' directives for GNU-as compatibility
3220  if (IsPow2 && (ValueSize == 1) && getTok().is(AsmToken::EndOfStatement)) {
3221  Warning(AlignmentLoc, "p2align directive with no operand(s) is ignored");
3222  return parseToken(AsmToken::EndOfStatement);
3223  }
3224  if (parseAlign())
3225  return addErrorSuffix(" in directive");
3226 
3227  // Always emit an alignment here even if we thrown an error.
3228  bool ReturnVal = false;
3229 
3230  // Compute alignment in bytes.
3231  if (IsPow2) {
3232  // FIXME: Diagnose overflow.
3233  if (Alignment >= 32) {
3234  ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
3235  Alignment = 31;
3236  }
3237 
3238  Alignment = 1ULL << Alignment;
3239  } else {
3240  // Reject alignments that aren't either a power of two or zero,
3241  // for gas compatibility. Alignment of zero is silently rounded
3242  // up to one.
3243  if (Alignment == 0)
3244  Alignment = 1;
3245  if (!isPowerOf2_64(Alignment))
3246  ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2");
3247  }
3248 
3249  // Diagnose non-sensical max bytes to align.
3250  if (MaxBytesLoc.isValid()) {
3251  if (MaxBytesToFill < 1) {
3252  ReturnVal |= Error(MaxBytesLoc,
3253  "alignment directive can never be satisfied in this "
3254  "many bytes, ignoring maximum bytes expression");
3255  MaxBytesToFill = 0;
3256  }
3257 
3258  if (MaxBytesToFill >= Alignment) {
3259  Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
3260  "has no effect");
3261  MaxBytesToFill = 0;
3262  }
3263  }
3264 
3265  // Check whether we should use optimal code alignment for this .align
3266  // directive.
3267  const MCSection *Section = getStreamer().getCurrentSectionOnly();
3268  assert(Section && "must have section to emit alignment");
3269  bool UseCodeAlign = Section->UseCodeAlign();
3270  if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
3271  ValueSize == 1 && UseCodeAlign) {
3272  getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
3273  } else {
3274  // FIXME: Target specific behavior about how the "extra" bytes are filled.
3275  getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize,
3276  MaxBytesToFill);
3277  }
3278 
3279  return ReturnVal;
3280 }
3281 
3282 /// parseDirectiveFile
3283 /// ::= .file filename
3284 /// ::= .file number [directory] filename [md5 checksum] [source source-text]
3285 bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
3286  // FIXME: I'm not sure what this is.
3287  int64_t FileNumber = -1;
3288  if (getLexer().is(AsmToken::Integer)) {
3289  FileNumber = getTok().getIntVal();
3290  Lex();
3291 
3292  if (FileNumber < 0)
3293  return TokError("negative file number");
3294  }
3295 
3296  std::string Path;
3297 
3298  // Usually the directory and filename together, otherwise just the directory.
3299  // Allow the strings to have escaped octal character sequence.
3300  if (check(getTok().isNot(AsmToken::String),
3301  "unexpected token in '.file' directive") ||
3302  parseEscapedString(Path))
3303  return true;
3304 
3305  StringRef Directory;
3306  StringRef Filename;
3307  std::string FilenameData;
3308  if (getLexer().is(AsmToken::String)) {
3309  if (check(FileNumber == -1,
3310  "explicit path specified, but no file number") ||
3311  parseEscapedString(FilenameData))
3312  return true;
3313  Filename = FilenameData;
3314  Directory = Path;
3315  } else {
3316  Filename = Path;
3317  }
3318 
3319  uint64_t MD5Hi, MD5Lo;
3320  bool HasMD5 = false;
3321 
3323  bool HasSource = false;
3324  std::string SourceString;
3325 
3326  while (!parseOptionalToken(AsmToken::EndOfStatement)) {
3327  StringRef Keyword;
3328  if (check(getTok().isNot(AsmToken::Identifier),
3329  "unexpected token in '.file' directive") ||
3330  parseIdentifier(Keyword))
3331  return true;
3332  if (Keyword == "md5") {
3333  HasMD5 = true;
3334  if (check(FileNumber == -1,
3335  "MD5 checksum specified, but no file number") ||
3336  parseHexOcta(*this, MD5Hi, MD5Lo))
3337  return true;
3338  } else if (Keyword == "source") {
3339  HasSource = true;
3340  if (check(FileNumber == -1,
3341  "source specified, but no file number") ||
3342  check(getTok().isNot(AsmToken::String),
3343  "unexpected token in '.file' directive") ||
3344  parseEscapedString(SourceString))
3345  return true;
3346  } else {
3347  return TokError("unexpected token in '.file' directive");
3348  }
3349  }
3350 
3351  // In case there is a -g option as well as debug info from directive .file,
3352  // we turn off the -g option, directly use the existing debug info instead.
3353  // Also reset any implicit ".file 0" for the assembler source.
3354  if (Ctx.getGenDwarfForAssembly()) {
3356  Ctx.setGenDwarfForAssembly(false);
3357  }
3358 
3359  if (FileNumber == -1)
3360  getStreamer().EmitFileDirective(Filename);
3361  else {
3362  MD5::MD5Result *CKMem = nullptr;
3363  if (HasMD5) {
3364  CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1);
3365  for (unsigned i = 0; i != 8; ++i) {
3366  CKMem->Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3367  CKMem->Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3368  }
3369  }
3370  if (HasSource) {
3371  char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
3372  memcpy(SourceBuf, SourceString.data(), SourceString.size());
3373  Source = StringRef(SourceBuf, SourceString.size());
3374  }
3375  if (FileNumber == 0) {
3376  if (Ctx.getDwarfVersion() < 5)
3377  return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
3378  getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3379  } else {
3380  Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3381  FileNumber, Directory, Filename, CKMem, Source);
3382  if (!FileNumOrErr)
3383  return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
3384  FileNumber = FileNumOrErr.get();
3385  }
3386  // Alert the user if there are some .file directives with MD5 and some not.
3387  // But only do that once.
3388  if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
3389  ReportedInconsistentMD5 = true;
3390  return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
3391  }
3392  }
3393 
3394  return false;
3395 }
3396 
3397 /// parseDirectiveLine
3398 /// ::= .line [number]
3399 bool AsmParser::parseDirectiveLine() {
3400  int64_t LineNumber;
3401  if (getLexer().is(AsmToken::Integer)) {
3402  if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
3403  return true;
3404  (void)LineNumber;
3405  // FIXME: Do something with the .line.
3406  }
3407  if (parseToken(AsmToken::EndOfStatement,
3408  "unexpected token in '.line' directive"))
3409  return true;
3410 
3411  return false;
3412 }
3413 
3414 /// parseDirectiveLoc
3415 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
3416 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
3417 /// The first number is a file number, must have been previously assigned with
3418 /// a .file directive, the second number is the line number and optionally the
3419 /// third number is a column position (zero if not specified). The remaining
3420 /// optional items are .loc sub-directives.
3421 bool AsmParser::parseDirectiveLoc() {
3422  int64_t FileNumber = 0, LineNumber = 0;
3423  SMLoc Loc = getTok().getLoc();
3424  if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
3425  check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
3426  "file number less than one in '.loc' directive") ||
3427  check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3428  "unassigned file number in '.loc' directive"))
3429  return true;
3430 
3431  // optional
3432  if (getLexer().is(AsmToken::Integer)) {
3433  LineNumber = getTok().getIntVal();
3434  if (LineNumber < 0)
3435  return TokError("line number less than zero in '.loc' directive");
3436  Lex();
3437  }
3438 
3439  int64_t ColumnPos = 0;
3440  if (getLexer().is(AsmToken::Integer)) {
3441  ColumnPos = getTok().getIntVal();
3442  if (ColumnPos < 0)
3443  return TokError("column position less than zero in '.loc' directive");
3444  Lex();
3445  }
3446 
3447  unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
3448  unsigned Isa = 0;
3449  int64_t Discriminator = 0;
3450 
3451  auto parseLocOp = [&]() -> bool {
3452  StringRef Name;
3453  SMLoc Loc = getTok().getLoc();
3454  if (parseIdentifier(Name))
3455  return TokError("unexpected token in '.loc' directive");
3456 
3457  if (Name == "basic_block")
3458  Flags |= DWARF2_FLAG_BASIC_BLOCK;
3459  else if (Name == "prologue_end")
3460  Flags |= DWARF2_FLAG_PROLOGUE_END;
3461  else if (Name == "epilogue_begin")
3462  Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
3463  else if (Name == "is_stmt") {
3464  Loc = getTok().getLoc();
3465  const MCExpr *Value;
3466  if (parseExpression(Value))
3467  return true;
3468  // The expression must be the constant 0 or 1.
3469  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3470  int Value = MCE->getValue();
3471  if (Value == 0)
3472  Flags &= ~DWARF2_FLAG_IS_STMT;
3473  else if (Value == 1)
3474  Flags |= DWARF2_FLAG_IS_STMT;
3475  else
3476  return Error(Loc, "is_stmt value not 0 or 1");
3477  } else {
3478  return Error(Loc, "is_stmt value not the constant value of 0 or 1");
3479  }
3480  } else if (Name == "isa") {
3481  Loc = getTok().getLoc();
3482  const MCExpr *Value;
3483  if (parseExpression(Value))
3484  return true;
3485  // The expression must be a constant greater or equal to 0.
3486  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3487  int Value = MCE->getValue();
3488  if (Value < 0)
3489  return Error(Loc, "isa number less than zero");
3490  Isa = Value;
3491  } else {
3492  return Error(Loc, "isa number not a constant value");
3493  }
3494  } else if (Name == "discriminator") {
3495  if (parseAbsoluteExpression(Discriminator))
3496  return true;
3497  } else {
3498  return Error(Loc, "unknown sub-directive in '.loc' directive");
3499  }
3500  return false;
3501  };
3502 
3503  if (parseMany(parseLocOp, false /*hasComma*/))
3504  return true;
3505 
3506  getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3507  Isa, Discriminator, StringRef());
3508 
3509  return false;
3510 }
3511 
3512 /// parseDirectiveStabs
3513 /// ::= .stabs string, number, number, number
3514 bool AsmParser::parseDirectiveStabs() {
3515  return TokError("unsupported directive '.stabs'");
3516 }
3517 
3518 /// parseDirectiveCVFile
3519 /// ::= .cv_file number filename [checksum] [checksumkind]
3520 bool AsmParser::parseDirectiveCVFile() {
3521  SMLoc FileNumberLoc = getTok().getLoc();
3522  int64_t FileNumber;
3523  std::string Filename;
3524  std::string Checksum;
3525  int64_t ChecksumKind = 0;
3526 
3527  if (parseIntToken(FileNumber,
3528  "expected file number in '.cv_file' directive") ||
3529  check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
3530  check(getTok().isNot(AsmToken::String),
3531  "unexpected token in '.cv_file' directive") ||
3532  parseEscapedString(Filename))
3533  return true;
3534  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3535  if (check(getTok().isNot(AsmToken::String),
3536  "unexpected token in '.cv_file' directive") ||
3537  parseEscapedString(Checksum) ||
3538  parseIntToken(ChecksumKind,
3539  "expected checksum kind in '.cv_file' directive") ||
3540  parseToken(AsmToken::EndOfStatement,
3541  "unexpected token in '.cv_file' directive"))
3542  return true;
3543  }
3544 
3545  Checksum = fromHex(Checksum);
3546  void *CKMem = Ctx.allocate(Checksum.size(), 1);
3547  memcpy(CKMem, Checksum.data(), Checksum.size());
3548  ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
3549  Checksum.size());
3550 
3551  if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3552  static_cast<uint8_t>(ChecksumKind)))
3553  return Error(FileNumberLoc, "file number already allocated");
3554 
3555  return false;
3556 }
3557 
3558 bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
3559  StringRef DirectiveName) {
3560  SMLoc Loc;
3561  return parseTokenLoc(Loc) ||
3562  parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
3563  "' directive") ||
3564  check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3565  "expected function id within range [0, UINT_MAX)");
3566 }
3567 
3568 bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3569  SMLoc Loc;
3570  return parseTokenLoc(Loc) ||
3571  parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
3572  "' directive") ||
3573  check(FileNumber < 1, Loc, "file number less than one in '" +
3574  DirectiveName + "' directive") ||
3575  check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3576  "unassigned file number in '" + DirectiveName + "' directive");
3577 }
3578 
3579 /// parseDirectiveCVFuncId
3580 /// ::= .cv_func_id FunctionId
3581 ///
3582 /// Introduces a function ID that can be used with .cv_loc.
3583 bool AsmParser::parseDirectiveCVFuncId() {
3584  SMLoc FunctionIdLoc = getTok().getLoc();
3585  int64_t FunctionId;
3586 
3587  if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
3588  parseToken(AsmToken::EndOfStatement,
3589  "unexpected token in '.cv_func_id' directive"))
3590  return true;
3591 
3592  if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
3593  return Error(FunctionIdLoc, "function id already allocated");
3594 
3595  return false;
3596 }
3597 
3598 /// parseDirectiveCVInlineSiteId
3599 /// ::= .cv_inline_site_id FunctionId
3600 /// "within" IAFunc
3601 /// "inlined_at" IAFile IALine [IACol]
3602 ///
3603 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
3604 /// at" source location information for use in the line table of the caller,
3605 /// whether the caller is a real function or another inlined call site.
3606 bool AsmParser::parseDirectiveCVInlineSiteId() {
3607  SMLoc FunctionIdLoc = getTok().getLoc();
3608  int64_t FunctionId;
3609  int64_t IAFunc;
3610  int64_t IAFile;
3611  int64_t IALine;
3612  int64_t IACol = 0;
3613 
3614  // FunctionId
3615  if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
3616  return true;
3617 
3618  // "within"
3619  if (check((getLexer().isNot(AsmToken::Identifier) ||
3620  getTok().getIdentifier() != "within"),
3621  "expected 'within' identifier in '.cv_inline_site_id' directive"))
3622  return true;
3623  Lex();
3624 
3625  // IAFunc
3626  if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
3627  return true;
3628 
3629  // "inlined_at"
3630  if (check((getLexer().isNot(AsmToken::Identifier) ||
3631  getTok().getIdentifier() != "inlined_at"),
3632  "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3633  "directive") )
3634  return true;
3635  Lex();
3636 
3637  // IAFile IALine
3638  if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
3639  parseIntToken(IALine, "expected line number after 'inlined_at'"))
3640  return true;
3641 
3642  // [IACol]
3643  if (getLexer().is(AsmToken::Integer)) {
3644  IACol = getTok().getIntVal();
3645  Lex();
3646  }
3647 
3648  if (parseToken(AsmToken::EndOfStatement,
3649  "unexpected token in '.cv_inline_site_id' directive"))
3650  return true;
3651 
3652  if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3653  IALine, IACol, FunctionIdLoc))
3654  return Error(FunctionIdLoc, "function id already allocated");
3655 
3656  return false;
3657 }
3658 
3659 /// parseDirectiveCVLoc
3660 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
3661 /// [is_stmt VALUE]
3662 /// The first number is a file number, must have been previously assigned with
3663 /// a .file directive, the second number is the line number and optionally the
3664 /// third number is a column position (zero if not specified). The remaining
3665 /// optional items are .loc sub-directives.
3666 bool AsmParser::parseDirectiveCVLoc() {
3667  SMLoc DirectiveLoc = getTok().getLoc();
3668  int64_t FunctionId, FileNumber;
3669  if (parseCVFunctionId(FunctionId, ".cv_loc") ||
3670  parseCVFileId(FileNumber, ".cv_loc"))
3671  return true;
3672 
3673  int64_t LineNumber = 0;
3674  if (getLexer().is(AsmToken::Integer)) {
3675  LineNumber = getTok().getIntVal();
3676  if (LineNumber < 0)
3677  return TokError("line number less than zero in '.cv_loc' directive");
3678  Lex();
3679  }
3680 
3681  int64_t ColumnPos = 0;
3682  if (getLexer().is(AsmToken::Integer)) {
3683  ColumnPos = getTok().getIntVal();
3684  if (ColumnPos < 0)
3685  return TokError("column position less than zero in '.cv_loc' directive");
3686  Lex();
3687  }
3688 
3689  bool PrologueEnd = false;
3690  uint64_t IsStmt = 0;
3691 
3692  auto parseOp = [&]() -> bool {
3693  StringRef Name;
3694  SMLoc Loc = getTok().getLoc();
3695  if (parseIdentifier(Name))
3696  return TokError("unexpected token in '.cv_loc' directive");
3697  if (Name == "prologue_end")
3698  PrologueEnd = true;
3699  else if (Name == "is_stmt") {
3700  Loc = getTok().getLoc();
3701  const MCExpr *Value;
3702  if (parseExpression(Value))
3703  return true;
3704  // The expression must be the constant 0 or 1.
3705  IsStmt = ~0ULL;
3706  if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
3707  IsStmt = MCE->getValue();
3708 
3709  if (IsStmt > 1)
3710  return Error(Loc, "is_stmt value not 0 or 1");
3711  } else {
3712  return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
3713  }
3714  return false;
3715  };
3716 
3717  if (parseMany(parseOp, false /*hasComma*/))
3718  return true;
3719 
3720  getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
3721  ColumnPos, PrologueEnd, IsStmt, StringRef(),
3722  DirectiveLoc);
3723  return false;
3724 }
3725 
3726 /// parseDirectiveCVLinetable
3727 /// ::= .cv_linetable FunctionId, FnStart, FnEnd
3728 bool AsmParser::parseDirectiveCVLinetable() {
3729  int64_t FunctionId;
3730  StringRef FnStartName, FnEndName;
3731  SMLoc Loc = getTok().getLoc();
3732  if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
3733  parseToken(AsmToken::Comma,
3734  "unexpected token in '.cv_linetable' directive") ||
3735  parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3736  "expected identifier in directive") ||
3737  parseToken(AsmToken::Comma,
3738  "unexpected token in '.cv_linetable' directive") ||
3739  parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3740  "expected identifier in directive"))
3741  return true;
3742 
3743  MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3744  MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3745 
3746  getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
3747  return false;
3748 }
3749 
3750 /// parseDirectiveCVInlineLinetable
3751 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
3752 bool AsmParser::parseDirectiveCVInlineLinetable() {
3753  int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3754  StringRef FnStartName, FnEndName;
3755  SMLoc Loc = getTok().getLoc();
3756  if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
3757  parseTokenLoc(Loc) ||
3758  parseIntToken(
3759  SourceFileId,
3760  "expected SourceField in '.cv_inline_linetable' directive") ||
3761  check(SourceFileId <= 0, Loc,
3762  "File id less than zero in '.cv_inline_linetable' directive") ||
3763  parseTokenLoc(Loc) ||
3764  parseIntToken(
3765  SourceLineNum,
3766  "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3767  check(SourceLineNum < 0, Loc,
3768  "Line number less than zero in '.cv_inline_linetable' directive") ||
3769  parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3770  "expected identifier in directive") ||
3771  parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3772  "expected identifier in directive"))
3773  return true;
3774 
3775  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3776  return true;
3777 
3778  MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3779  MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3780  getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
3781  SourceLineNum, FnStartSym,
3782  FnEndSym);
3783  return false;
3784 }
3785 
3786 /// parseDirectiveCVDefRange
3787 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
3788 bool AsmParser::parseDirectiveCVDefRange() {
3789  SMLoc Loc;
3790  std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
3791  while (getLexer().is(AsmToken::Identifier)) {
3792  Loc = getLexer().getLoc();
3793  StringRef GapStartName;
3794  if (parseIdentifier(GapStartName))
3795  return Error(Loc, "expected identifier in directive");
3796  MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
3797 
3798  Loc = getLexer().getLoc();
3799  StringRef GapEndName;
3800  if (parseIdentifier(GapEndName))
3801  return Error(Loc, "expected identifier in directive");
3802  MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
3803 
3804  Ranges.push_back({GapStartSym, GapEndSym});
3805  }
3806 
3807  std::string FixedSizePortion;
3808  if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
3809  parseEscapedString(FixedSizePortion))
3810  return true;
3811 
3812  getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
3813  return false;
3814 }
3815 
3816 /// parseDirectiveCVStringTable
3817 /// ::= .cv_stringtable
3818 bool AsmParser::parseDirectiveCVStringTable() {
3819  getStreamer().EmitCVStringTableDirective();
3820  return false;
3821 }
3822 
3823 /// parseDirectiveCVFileChecksums
3824 /// ::= .cv_filechecksums
3825 bool AsmParser::parseDirectiveCVFileChecksums() {
3826  getStreamer().EmitCVFileChecksumsDirective();
3827  return false;
3828 }
3829 
3830 /// parseDirectiveCVFileChecksumOffset
3831 /// ::= .cv_filechecksumoffset fileno
3832 bool AsmParser::parseDirectiveCVFileChecksumOffset() {
3833  int64_t FileNo;
3834  if (parseIntToken(FileNo, "expected identifier in directive"))
3835  return true;
3836  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3837  return true;
3838  getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
3839  return false;
3840 }
3841 
3842 /// parseDirectiveCVFPOData
3843 /// ::= .cv_fpo_data procsym
3844 bool AsmParser::parseDirectiveCVFPOData() {
3845  SMLoc DirLoc = getLexer().getLoc();
3846  StringRef ProcName;
3847  if (parseIdentifier(ProcName))
3848  return TokError("expected symbol name");
3849  if (parseEOL("unexpected tokens"))
3850  return addErrorSuffix(" in '.cv_fpo_data' directive");
3851  MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3852  getStreamer().EmitCVFPOData(ProcSym, DirLoc);
3853  return false;
3854 }
3855 
3856 /// parseDirectiveCFISections
3857 /// ::= .cfi_sections section [, section]
3858 bool AsmParser::parseDirectiveCFISections() {
3859  StringRef Name;
3860  bool EH = false;
3861  bool Debug = false;
3862 
3863  if (parseIdentifier(Name))
3864  return TokError("Expected an identifier");
3865 
3866  if (Name == ".eh_frame")
3867  EH = true;
3868  else if (Name == ".debug_frame")
3869  Debug = true;
3870 
3871  if (getLexer().is(AsmToken::Comma)) {
3872  Lex();
3873 
3874  if (parseIdentifier(Name))
3875  return TokError("Expected an identifier");
3876 
3877  if (Name == ".eh_frame")
3878  EH = true;
3879  else if (Name == ".debug_frame")
3880  Debug = true;
3881  }
3882 
3883  getStreamer().EmitCFISections(EH, Debug);
3884  return false;
3885 }
3886 
3887 /// parseDirectiveCFIStartProc
3888 /// ::= .cfi_startproc [simple]
3889 bool AsmParser::parseDirectiveCFIStartProc() {
3890  StringRef Simple;
3891  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3892  if (check(parseIdentifier(Simple) || Simple != "simple",
3893  "unexpected token") ||
3894  parseToken(AsmToken::EndOfStatement))
3895  return addErrorSuffix(" in '.cfi_startproc' directive");
3896  }
3897 
3898  getStreamer().EmitCFIStartProc(!Simple.empty());
3899  return false;
3900 }
3901 
3902 /// parseDirectiveCFIEndProc
3903 /// ::= .cfi_endproc
3904 bool AsmParser::parseDirectiveCFIEndProc() {
3905  getStreamer().EmitCFIEndProc();
3906  return false;
3907 }
3908 
3909 /// parse register name or number.
3910 bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
3911  SMLoc DirectiveLoc) {
3912  unsigned RegNo;
3913 
3914  if (getLexer().isNot(AsmToken::Integer)) {
3915  if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
3916  return true;
3917  Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
3918  } else
3919  return parseAbsoluteExpression(Register);
3920 
3921  return false;
3922 }
3923 
3924 /// parseDirectiveCFIDefCfa
3925 /// ::= .cfi_def_cfa register, offset
3926 bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
3927  int64_t Register = 0, Offset = 0;
3928  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3929  parseToken(AsmToken::Comma, "unexpected token in directive") ||
3930  parseAbsoluteExpression(Offset))
3931  return true;
3932 
3933  getStreamer().EmitCFIDefCfa(Register, Offset);
3934  return false;
3935 }
3936 
3937 /// parseDirectiveCFIDefCfaOffset
3938 /// ::= .cfi_def_cfa_offset offset
3939 bool AsmParser::parseDirectiveCFIDefCfaOffset() {
3940  int64_t Offset = 0;
3941  if (parseAbsoluteExpression(Offset))
3942  return true;
3943 
3944  getStreamer().EmitCFIDefCfaOffset(Offset);
3945  return false;
3946 }
3947 
3948 /// parseDirectiveCFIRegister
3949 /// ::= .cfi_register register, register
3950 bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
3951  int64_t Register1 = 0, Register2 = 0;
3952  if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
3953  parseToken(AsmToken::Comma, "unexpected token in directive") ||
3954  parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
3955  return true;
3956 
3957  getStreamer().EmitCFIRegister(Register1, Register2);
3958  return false;
3959 }
3960 
3961 /// parseDirectiveCFIWindowSave
3962 /// ::= .cfi_window_save
3963 bool AsmParser::parseDirectiveCFIWindowSave() {
3964  getStreamer().EmitCFIWindowSave();
3965  return false;
3966 }
3967 
3968 /// parseDirectiveCFIAdjustCfaOffset
3969 /// ::= .cfi_adjust_cfa_offset adjustment
3970 bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
3971  int64_t Adjustment = 0;
3972  if (parseAbsoluteExpression(Adjustment))
3973  return true;
3974 
3975  getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
3976  return false;
3977 }
3978 
3979 /// parseDirectiveCFIDefCfaRegister
3980 /// ::= .cfi_def_cfa_register register
3981 bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
3982  int64_t Register = 0;
3983  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
3984  return true;
3985 
3986  getStreamer().EmitCFIDefCfaRegister(Register);
3987  return false;
3988 }
3989 
3990 /// parseDirectiveCFIOffset
3991 /// ::= .cfi_offset register, offset
3992 bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
3993  int64_t Register = 0;
3994  int64_t Offset = 0;
3995 
3996  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3997  parseToken(AsmToken::Comma, "unexpected token in directive") ||
3998  parseAbsoluteExpression(Offset))
3999  return true;
4000 
4001  getStreamer().EmitCFIOffset(Register, Offset);
4002  return false;
4003 }
4004 
4005 /// parseDirectiveCFIRelOffset
4006 /// ::= .cfi_rel_offset register, offset
4007 bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
4008  int64_t Register = 0, Offset = 0;
4009 
4010  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
4011  parseToken(AsmToken::Comma, "unexpected token in directive") ||
4012  parseAbsoluteExpression(Offset))
4013  return true;
4014 
4015  getStreamer().EmitCFIRelOffset(Register, Offset);
4016  return false;
4017 }
4018 
4019 static bool isValidEncoding(int64_t Encoding) {
4020  if (Encoding & ~0xff)
4021  return false;
4022 
4023  if (Encoding == dwarf::DW_EH_PE_omit)
4024  return true;
4025 
4026  const unsigned Format = Encoding & 0xf;
4027  if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
4028  Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
4029  Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
4030  Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
4031  return false;
4032 
4033  const unsigned Application = Encoding & 0x70;
4034  if (Application != dwarf::DW_EH_PE_absptr &&
4035  Application != dwarf::DW_EH_PE_pcrel)
4036  return false;
4037 
4038  return true;
4039 }
4040 
4041 /// parseDirectiveCFIPersonalityOrLsda
4042 /// IsPersonality true for cfi_personality, false for cfi_lsda
4043 /// ::= .cfi_personality encoding, [symbol_name]
4044 /// ::= .cfi_lsda encoding, [symbol_name]
4045 bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
4046  int64_t Encoding = 0;
4047  if (parseAbsoluteExpression(Encoding))
4048  return true;
4049  if (Encoding == dwarf::DW_EH_PE_omit)
4050  return false;
4051 
4052  StringRef Name;
4053  if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
4054  parseToken(AsmToken::Comma, "unexpected token in directive") ||
4055  check(parseIdentifier(Name), "expected identifier in directive"))
4056  return true;
4057 
4058  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4059 
4060  if (IsPersonality)
4061  getStreamer().EmitCFIPersonality(Sym, Encoding);
4062  else
4063  getStreamer().EmitCFILsda(Sym, Encoding);
4064  return false;
4065 }
4066 
4067 /// parseDirectiveCFIRememberState
4068 /// ::= .cfi_remember_state
4069 bool AsmParser::parseDirectiveCFIRememberState() {
4070  getStreamer().EmitCFIRememberState();
4071  return false;
4072 }
4073 
4074 /// parseDirectiveCFIRestoreState
4075 /// ::= .cfi_remember_state
4076 bool AsmParser::parseDirectiveCFIRestoreState() {
4077  getStreamer().EmitCFIRestoreState();
4078  return false;
4079 }
4080 
4081 /// parseDirectiveCFISameValue
4082 /// ::= .cfi_same_value register
4083 bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
4084  int64_t Register = 0;
4085 
4086  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4087  return true;
4088 
4089  getStreamer().EmitCFISameValue(Register);
4090  return false;
4091 }
4092 
4093 /// parseDirectiveCFIRestore
4094 /// ::= .cfi_restore register
4095 bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
4096  int64_t Register = 0;
4097  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4098  return true;
4099 
4100  getStreamer().EmitCFIRestore(Register);
4101  return false;
4102 }
4103 
4104 /// parseDirectiveCFIEscape
4105 /// ::= .cfi_escape expression[,...]
4106 bool AsmParser::parseDirectiveCFIEscape() {
4107  std::string Values;
4108  int64_t CurrValue;
4109  if (parseAbsoluteExpression(CurrValue))
4110  return true;
4111 
4112  Values.push_back((uint8_t)CurrValue);
4113 
4114  while (getLexer().is(AsmToken::Comma)) {
4115  Lex();
4116 
4117  if (parseAbsoluteExpression(CurrValue))
4118  return true;
4119 
4120  Values.push_back((uint8_t)CurrValue);
4121  }
4122 
4123  getStreamer().EmitCFIEscape(Values);
4124  return false;
4125 }
4126 
4127 /// parseDirectiveCFIReturnColumn
4128 /// ::= .cfi_return_column register
4129 bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4130  int64_t Register = 0;
4131  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4132  return true;
4133  getStreamer().EmitCFIReturnColumn(Register);
4134  return false;
4135 }
4136 
4137 /// parseDirectiveCFISignalFrame
4138 /// ::= .cfi_signal_frame
4139 bool AsmParser::parseDirectiveCFISignalFrame() {
4140  if (parseToken(AsmToken::EndOfStatement,
4141  "unexpected token in '.cfi_signal_frame'"))
4142  return true;
4143 
4144  getStreamer().EmitCFISignalFrame();
4145  return false;
4146 }
4147 
4148 /// parseDirectiveCFIUndefined
4149 /// ::= .cfi_undefined register
4150 bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4151  int64_t Register = 0;
4152 
4153  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4154  return true;
4155 
4156  getStreamer().EmitCFIUndefined(Register);
4157  return false;
4158 }
4159 
4160 /// parseDirectiveAltmacro
4161 /// ::= .altmacro
4162 /// ::= .noaltmacro
4163 bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
4164  if (getLexer().isNot(AsmToken::EndOfStatement))
4165  return TokError("unexpected token in '" + Directive + "' directive");
4166  if (Directive == ".altmacro")
4167  getLexer().SetAltMacroMode(true);
4168  else
4169  getLexer().SetAltMacroMode(false);
4170  return false;
4171 }
4172 
4173 /// parseDirectiveMacrosOnOff
4174 /// ::= .macros_on
4175 /// ::= .macros_off
4176 bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
4177  if (parseToken(AsmToken::EndOfStatement,
4178  "unexpected token in '" + Directive + "' directive"))
4179  return true;
4180 
4181  setMacrosEnabled(Directive == ".macros_on");
4182  return false;
4183 }
4184 
4185 /// parseDirectiveMacro
4186 /// ::= .macro name[,] [parameters]
4187 bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4188  StringRef Name;
4189  if (parseIdentifier(Name))
4190  return TokError("expected identifier in '.macro' directive");
4191 
4192  if (getLexer().is(AsmToken::Comma))
4193  Lex();
4194 
4195  MCAsmMacroParameters Parameters;
4196  while (getLexer().isNot(AsmToken::EndOfStatement)) {
4197 
4198  if (!Parameters.empty() && Parameters.back().Vararg)
4199  return Error(Lexer.getLoc(),
4200  "Vararg parameter '" + Parameters.back().Name +
4201  "' should be last one in the list of parameters.");
4202 
4203  MCAsmMacroParameter Parameter;
4204  if (parseIdentifier(Parameter.Name))
4205  return TokError("expected identifier in '.macro' directive");
4206 
4207  // Emit an error if two (or more) named parameters share the same name
4208  for (const MCAsmMacroParameter& CurrParam : Parameters)
4209  if (CurrParam.Name.equals(Parameter.Name))
4210  return TokError("macro '" + Name + "' has multiple parameters"
4211  " named '" + Parameter.Name + "'");
4212 
4213  if (Lexer.is(AsmToken::Colon)) {
4214  Lex(); // consume ':'
4215 
4216  SMLoc QualLoc;
4217  StringRef Qualifier;
4218 
4219  QualLoc = Lexer.getLoc();
4220  if (parseIdentifier(Qualifier))
4221  return Error(QualLoc, "missing parameter qualifier for "
4222  "'" + Parameter.Name + "' in macro '" + Name + "'");
4223 
4224  if (Qualifier == "req")
4225  Parameter.Required = true;
4226  else if (Qualifier == "vararg")
4227  Parameter.Vararg = true;
4228  else
4229  return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
4230  "for '" + Parameter.Name + "' in macro '" + Name + "'");
4231  }
4232 
4233  if (getLexer().is(AsmToken::Equal)) {
4234  Lex();
4235 
4236  SMLoc ParamLoc;
4237 
4238  ParamLoc = Lexer.getLoc();
4239  if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
4240  return true;
4241 
4242  if (Parameter.Required)
4243  Warning(ParamLoc, "pointless default value for required parameter "
4244  "'" + Parameter.Name + "' in macro '" + Name + "'");
4245  }
4246 
4247  Parameters.push_back(std::move(Parameter));
4248 
4249  if (getLexer().is(AsmToken::Comma))
4250  Lex();
4251  }
4252 
4253  // Eat just the end of statement.
4254  Lexer.Lex();
4255 
4256  // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
4257  AsmToken EndToken, StartToken = getTok();
4258  unsigned MacroDepth = 0;
4259  // Lex the macro definition.
4260  while (true) {
4261  // Ignore Lexing errors in macros.
4262  while (Lexer.is(AsmToken::Error)) {
4263  Lexer.Lex();
4264  }
4265 
4266  // Check whether we have reached the end of the file.
4267  if (getLexer().is(AsmToken::Eof))
4268  return Error(DirectiveLoc, "no matching '.endmacro' in definition");
4269 
4270  // Otherwise, check whether we have reach the .endmacro.
4271  if (getLexer().is(AsmToken::Identifier)) {
4272  if (getTok().getIdentifier() == ".endm" ||
4273  getTok().getIdentifier() == ".endmacro") {
4274  if (MacroDepth == 0) { // Outermost macro.
4275  EndToken = getTok();
4276  Lexer.Lex();
4277  if (getLexer().isNot(AsmToken::EndOfStatement))
4278  return TokError("unexpected token in '" + EndToken.getIdentifier() +
4279  "' directive");
4280  break;
4281  } else {
4282  // Otherwise we just found the end of an inner macro.
4283  --MacroDepth;
4284  }
4285  } else if (getTok().getIdentifier() == ".macro") {
4286  // We allow nested macros. Those aren't instantiated until the outermost
4287  // macro is expanded so just ignore them for now.
4288  ++MacroDepth;
4289  }
4290  }
4291 
4292  // Otherwise, scan til the end of the statement.
4293  eatToEndOfStatement();
4294  }
4295 
4296  if (getContext().lookupMacro(Name)) {
4297  return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
4298  }
4299 
4300  const char *BodyStart = StartToken.getLoc().getPointer();
4301  const char *BodyEnd = EndToken.getLoc().getPointer();
4302  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
4303  checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4304  MCAsmMacro Macro(Name, Body, std::move(Parameters));
4305  DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
4306  Macro.dump());
4307  getContext().defineMacro(Name, std::move(Macro));
4308  return false;
4309 }
4310 
4311 /// checkForBadMacro
4312 ///
4313 /// With the support added for named parameters there may be code out there that
4314 /// is transitioning from positional parameters. In versions of gas that did
4315 /// not support named parameters they would be ignored on the macro definition.
4316 /// But to support both styles of parameters this is not possible so if a macro
4317 /// definition has named parameters but does not use them and has what appears
4318 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a
4319 /// warning that the positional parameter found in body which have no effect.
4320 /// Hoping the developer will either remove the named parameters from the macro
4321 /// definition so the positional parameters get used if that was what was
4322 /// intended or change the macro to use the named parameters. It is possible
4323 /// this warning will trigger when the none of the named parameters are used
4324 /// and the strings like $1 are infact to simply to be passed trough unchanged.
4325 void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
4326  StringRef Body,
4327  ArrayRef<MCAsmMacroParameter> Parameters) {
4328  // If this macro is not defined with named parameters the warning we are
4329  // checking for here doesn't apply.
4330  unsigned NParameters = Parameters.size();
4331  if (NParameters == 0)
4332  return;
4333 
4334  bool NamedParametersFound = false;
4335  bool PositionalParametersFound = false;
4336 
4337  // Look at the body of the macro for use of both the named parameters and what
4338  // are likely to be positional parameters. This is what expandMacro() is
4339  // doing when it finds the parameters in the body.
4340  while (!Body.empty()) {
4341  // Scan for the next possible parameter.
4342  std::size_t End = Body.size(), Pos = 0;
4343  for (; Pos != End; ++Pos) {
4344  // Check for a substitution or escape.
4345  // This macro is defined with parameters, look for \foo, \bar, etc.
4346  if (Body[Pos] == '\\' && Pos + 1 != End)
4347  break;
4348 
4349  // This macro should have parameters, but look for $0, $1, ..., $n too.
4350  if (Body[Pos] != '$' || Pos + 1 == End)
4351  continue;
4352  char Next = Body[Pos + 1];
4353  if (Next == '$' || Next == 'n' ||
4354  isdigit(static_cast<unsigned char>(Next)))
4355  break;
4356  }
4357 
4358  // Check if we reached the end.
4359  if (Pos == End)
4360  break;
4361 
4362  if (Body[Pos] == '$') {
4363  switch (Body[Pos + 1]) {
4364  // $$ => $
4365  case '$':
4366  break;
4367 
4368  // $n => number of arguments
4369  case 'n':
4370  PositionalParametersFound = true;
4371  break;
4372 
4373  // $[0-9] => argument
4374  default: {
4375  PositionalParametersFound = true;
4376  break;
4377  }
4378  }
4379  Pos += 2;
4380  } else {
4381  unsigned I = Pos + 1;
4382  while (isIdentifierChar(Body[I]) && I + 1 != End)
4383  ++I;
4384 
4385  const char *Begin = Body.data() + Pos + 1;
4386  StringRef Argument(Begin, I - (Pos + 1));
4387  unsigned Index = 0;
4388  for (; Index < NParameters; ++Index)
4389  if (Parameters[Index].Name == Argument)
4390  break;
4391 
4392  if (Index == NParameters) {
4393  if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
4394  Pos += 3;
4395  else {
4396  Pos = I;
4397  }
4398  } else {
4399  NamedParametersFound = true;
4400  Pos += 1 + Argument.size();
4401  }
4402  }
4403  // Update the scan point.
4404  Body = Body.substr(Pos);
4405  }
4406 
4407  if (!NamedParametersFound && PositionalParametersFound)
4408  Warning(DirectiveLoc, "macro defined with named parameters which are not "
4409  "used in macro body, possible positional parameter "
4410  "found in body which will have no effect");
4411 }
4412 
4413 /// parseDirectiveExitMacro
4414 /// ::= .exitm
4415 bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
4416  if (parseToken(AsmToken::EndOfStatement,
4417  "unexpected token in '" + Directive + "' directive"))
4418  return true;
4419 
4420  if (!isInsideMacroInstantiation())
4421  return TokError("unexpected '" + Directive + "' in file, "
4422  "no current macro definition");
4423 
4424  // Exit all conditionals that are active in the current macro.
4425  while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4426  TheCondState = TheCondStack.back();
4427  TheCondStack.pop_back();
4428  }
4429 
4430  handleMacroExit();
4431  return false;
4432 }
4433 
4434 /// parseDirectiveEndMacro
4435 /// ::= .endm
4436 /// ::= .endmacro
4437 bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
4438  if (getLexer().isNot(AsmToken::EndOfStatement))
4439  return TokError("unexpected token in '" + Directive + "' directive");
4440 
4441  // If we are inside a macro instantiation, terminate the current
4442  // instantiation.
4443  if (isInsideMacroInstantiation()) {
4444  handleMacroExit();
4445  return false;
4446  }
4447 
4448  // Otherwise, this .endmacro is a stray entry in the file; well formed
4449  // .endmacro directives are handled during the macro definition parsing.
4450  return TokError("unexpected '" + Directive + "' in file, "
4451  "no current macro definition");
4452 }
4453 
4454 /// parseDirectivePurgeMacro
4455 /// ::= .purgem
4456 bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4457  StringRef Name;
4458  SMLoc Loc;
4459  if (parseTokenLoc(Loc) ||
4460  check(parseIdentifier(Name), Loc,
4461  "expected identifier in '.purgem' directive") ||
4462  parseToken(AsmToken::EndOfStatement,
4463  "unexpected token in '.purgem' directive"))
4464  return true;
4465 
4466  if (!getContext().lookupMacro(Name))
4467  return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
4468 
4469  getContext().undefineMacro(Name);
4470  DEBUG_WITH_TYPE("asm-macros", dbgs()
4471  << "Un-defining macro: " << Name << "\n");
4472  return false;
4473 }
4474 
4475 /// parseDirectiveBundleAlignMode
4476 /// ::= {.bundle_align_mode} expression
4477 bool AsmParser::parseDirectiveBundleAlignMode() {
4478  // Expect a single argument: an expression that evaluates to a constant
4479  // in the inclusive range 0-30.
4480  SMLoc ExprLoc = getLexer().getLoc();
4481  int64_t AlignSizePow2;
4482  if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4483  parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
4484  "in '.bundle_align_mode' "
4485  "directive") ||
4486  check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4487  "invalid bundle alignment size (expected between 0 and 30)"))
4488  return true;
4489 
4490  // Because of AlignSizePow2's verified range we can safely truncate it to
4491  // unsigned.
4492  getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
4493  return false;
4494 }
4495 
4496 /// parseDirectiveBundleLock
4497 /// ::= {.bundle_lock} [align_to_end]
4498 bool AsmParser::parseDirectiveBundleLock() {
4499  if (checkForValidSection())
4500  return true;
4501  bool AlignToEnd = false;
4502 
4503  StringRef Option;
4504  SMLoc Loc = getTok().getLoc();
4505  const char *kInvalidOptionError =
4506  "invalid option for '.bundle_lock' directive";
4507 
4508  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4509  if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4510  check(Option != "align_to_end", Loc, kInvalidOptionError) ||
4511  parseToken(AsmToken::EndOfStatement,
4512  "unexpected token after '.bundle_lock' directive option"))
4513  return true;
4514  AlignToEnd = true;
4515  }
4516 
4517  getStreamer().EmitBundleLock(AlignToEnd);
4518  return false;
4519 }
4520 
4521 /// parseDirectiveBundleLock
4522 /// ::= {.bundle_lock}
4523 bool AsmParser::parseDirectiveBundleUnlock() {
4524  if (checkForValidSection() ||
4525  parseToken(AsmToken::EndOfStatement,
4526  "unexpected token in '.bundle_unlock' directive"))
4527  return true;
4528 
4529  getStreamer().EmitBundleUnlock();
4530  return false;
4531 }
4532 
4533 /// parseDirectiveSpace
4534 /// ::= (.skip | .space) expression [ , expression ]
4535 bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
4536  SMLoc NumBytesLoc = Lexer.getLoc();
4537  const MCExpr *NumBytes;
4538  if (checkForValidSection() || parseExpression(NumBytes))
4539  return true;
4540 
4541  int64_t FillExpr = 0;
4542  if (parseOptionalToken(AsmToken::Comma))
4543  if (parseAbsoluteExpression(FillExpr))
4544  return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
4545  if (parseToken(AsmToken::EndOfStatement))
4546  return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
4547 
4548  // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
4549  getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4550 
4551  return false;
4552 }
4553 
4554 /// parseDirectiveDCB
4555 /// ::= .dcb.{b, l, w} expression, expression
4556 bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
4557  SMLoc NumValuesLoc = Lexer.getLoc();
4558  int64_t NumValues;
4559  if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4560  return true;
4561 
4562  if (NumValues < 0) {
4563  Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4564  return false;
4565  }
4566 
4567  if (parseToken(AsmToken::Comma,
4568  "unexpected token in '" + Twine(IDVal) + "' directive"))
4569  return true;
4570 
4571  const MCExpr *Value;
4572  SMLoc ExprLoc = getLexer().getLoc();
4573  if (parseExpression(Value))
4574  return true;
4575 
4576  // Special case constant expressions to match code generator.
4577  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4578  assert(Size <= 8 && "Invalid size");
4579  uint64_t IntValue = MCE->getValue();
4580  if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
4581  return Error(ExprLoc, "literal value out of range for directive");
4582  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4583  getStreamer().EmitIntValue(IntValue, Size);
4584  } else {
4585  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4586  getStreamer().EmitValue(Value, Size, ExprLoc);
4587  }
4588 
4589  if (parseToken(AsmToken::EndOfStatement,
4590  "unexpected token in '" + Twine(IDVal) + "' directive"))
4591  return true;
4592 
4593  return false;
4594 }
4595 
4596 /// parseDirectiveRealDCB
4597 /// ::= .dcb.{d, s} expression, expression
4598 bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
4599  SMLoc NumValuesLoc = Lexer.getLoc();
4600  int64_t NumValues;
4601  if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4602  return true;
4603 
4604  if (NumValues < 0) {
4605  Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4606  return false;
4607  }
4608 
4609  if (parseToken(AsmToken::Comma,
4610  "unexpected token in '" + Twine(IDVal) + "' directive"))
4611  return true;
4612 
4613  APInt AsInt;
4614  if (parseRealValue(Semantics, AsInt))
4615  return true;
4616 
4617  if (parseToken(AsmToken::EndOfStatement,
4618  "unexpected token in '" + Twine(IDVal) + "' directive"))
4619  return true;
4620 
4621  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4622  getStreamer().EmitIntValue(AsInt.getLimitedValue(),
4623  AsInt.getBitWidth() / 8);
4624 
4625  return false;
4626 }
4627 
4628 /// parseDirectiveDS
4629 /// ::= .ds.{b, d, l, p, s, w, x} expression
4630 bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
4631  SMLoc NumValuesLoc = Lexer.getLoc();
4632  int64_t NumValues;
4633  if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4634  return true;
4635 
4636  if (NumValues < 0) {
4637  Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4638  return false;
4639  }
4640 
4641  if (parseToken(AsmToken::EndOfStatement,
4642  "unexpected token in '" + Twine(IDVal) + "' directive"))
4643  return true;
4644 
4645  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4646  getStreamer().emitFill(Size, 0);
4647 
4648  return false;
4649 }
4650 
4651 /// parseDirectiveLEB128
4652 /// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
4653 bool AsmParser::parseDirectiveLEB128(bool Signed) {
4654  if (checkForValidSection())
4655  return true;
4656 
4657  auto parseOp = [&]() -> bool {
4658  const MCExpr *Value;
4659  if (parseExpression(Value))
4660  return true;
4661  if (Signed)
4662  getStreamer().EmitSLEB128Value(Value);
4663  else
4664  getStreamer().EmitULEB128Value(Value);
4665  return false;
4666  };
4667 
4668  if (parseMany(parseOp))
4669  return addErrorSuffix(" in directive");
4670 
4671  return false;
4672 }
4673 
4674 /// parseDirectiveSymbolAttribute
4675 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
4676 bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
4677  auto parseOp = [&]() -> bool {
4678  StringRef Name;
4679  SMLoc Loc = getTok().getLoc();
4680  if (parseIdentifier(Name))
4681  return Error(Loc, "expected identifier");
4682  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4683 
4684  // Assembler local symbols don't make any sense here. Complain loudly.
4685  if (Sym->isTemporary())
4686  return Error(Loc, "non-local symbol required");
4687 
4688  if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
4689  return Error(Loc, "unable to emit symbol attribute");
4690  return false;
4691  };
4692 
4693  if (parseMany(parseOp))
4694  return addErrorSuffix(" in directive");
4695  return false;
4696 }
4697 
4698 /// parseDirectiveComm
4699 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
4700 bool AsmParser::parseDirectiveComm(bool IsLocal) {
4701  if (checkForValidSection())
4702  return true;
4703 
4704  SMLoc IDLoc = getLexer().getLoc();
4705  StringRef Name;
4706  if (parseIdentifier(Name))
4707  return TokError("expected identifier in directive");
4708 
4709  // Handle the identifier as the key symbol.
4710  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4711 
4712  if (getLexer().isNot(AsmToken::Comma))
4713  return TokError("unexpected token in directive");
4714  Lex();
4715 
4716  int64_t Size;
4717  SMLoc SizeLoc = getLexer().getLoc();
4718  if (parseAbsoluteExpression(Size))
4719  return true;
4720 
4721  int64_t Pow2Alignment = 0;
4722  SMLoc Pow2AlignmentLoc;
4723  if (getLexer().is(AsmToken::Comma)) {
4724  Lex();
4725  Pow2AlignmentLoc = getLexer().getLoc();
4726  if (parseAbsoluteExpression(Pow2Alignment))
4727  return true;
4728 
4730  if (IsLocal && LCOMM == LCOMM::NoAlignment)
4731  return Error(Pow2AlignmentLoc, "alignment not supported on this target");
4732 
4733  // If this target takes alignments in bytes (not log) validate and convert.
4734  if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
4735  (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
4736  if (!isPowerOf2_64(Pow2Alignment))
4737  return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
4738  Pow2Alignment = Log2_64(Pow2Alignment);
4739  }
4740  }
4741 
4742  if (parseToken(AsmToken::EndOfStatement,
4743  "unexpected token in '.comm' or '.lcomm' directive"))
4744  return true;
4745 
4746  // NOTE: a size of zero for a .comm should create a undefined symbol
4747  // but a size of .lcomm creates a bss symbol of size zero.
4748  if (Size < 0)
4749  return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
4750  "be less than zero");
4751 
4752  // NOTE: The alignment in the directive is a power of 2 value, the assembler
4753  // may internally end up wanting an alignment in bytes.
4754  // FIXME: Diagnose overflow.
4755  if (Pow2Alignment < 0)
4756  return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
4757  "alignment, can't be less than zero");
4758 
4759  Sym->redefineIfPossible();
4760  if (!Sym->isUndefined())
4761  return Error(IDLoc, "invalid symbol redefinition");
4762 
4763  // Create the Symbol as a common or local common with Size and Pow2Alignment
4764  if (IsLocal) {
4765  getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4766  return false;
4767  }
4768 
4769  getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4770  return false;
4771 }
4772 
4773 /// parseDirectiveAbort
4774 /// ::= .abort [... message ...]
4775 bool AsmParser::parseDirectiveAbort() {
4776  // FIXME: Use loc from directive.
4777  SMLoc Loc = getLexer().getLoc();
4778 
4779  StringRef Str = parseStringToEndOfStatement();
4780  if (parseToken(AsmToken::EndOfStatement,
4781  "unexpected token in '.abort' directive"))
4782  return true;
4783 
4784  if (Str.empty())
4785  return Error(Loc, ".abort detected. Assembly stopping.");
4786  else
4787  return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
4788  // FIXME: Actually abort assembly here.
4789 
4790  return false;
4791 }
4792 
4793 /// parseDirectiveInclude
4794 /// ::= .include "filename"
4795 bool AsmParser::parseDirectiveInclude() {
4796  // Allow the strings to have escaped octal character sequence.
4797  std::string Filename;
4798  SMLoc IncludeLoc = getTok().getLoc();
4799 
4800  if (check(getTok().isNot(AsmToken::String),
4801  "expected string in '.include' directive") ||
4802  parseEscapedString(Filename) ||
4803  check(getTok().isNot(AsmToken::EndOfStatement),
4804  "unexpected token in '.include' directive") ||
4805  // Attempt to switch the lexer to the included file before consuming the
4806  // end of statement to avoid losing it when we switch.
4807  check(enterIncludeFile(Filename), IncludeLoc,
4808  "Could not find include file '" + Filename + "'"))
4809  return true;
4810 
4811  return false;
4812 }
4813 
4814 /// parseDirectiveIncbin
4815 /// ::= .incbin "filename" [ , skip [ , count ] ]
4816 bool AsmParser::parseDirectiveIncbin() {
4817  // Allow the strings to have escaped octal character sequence.
4818  std::string Filename;
4819  SMLoc IncbinLoc = getTok().getLoc();
4820  if (check(getTok().isNot(AsmToken::String),
4821  "expected string in '.incbin' directive") ||
4822  parseEscapedString(Filename))
4823  return true;
4824 
4825  int64_t Skip = 0;
4826  const MCExpr *Count = nullptr;
4827  SMLoc SkipLoc, CountLoc;
4828  if (parseOptionalToken(AsmToken::Comma)) {
4829  // The skip expression can be omitted while specifying the count, e.g:
4830  // .incbin "filename",,4
4831  if (getTok().isNot(AsmToken::Comma)) {
4832  if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
4833  return true;
4834  }
4835  if (parseOptionalToken(AsmToken::Comma)) {
4836  CountLoc = getTok().getLoc();
4837  if (parseExpression(Count))
4838  return true;
4839  }
4840  }
4841 
4842  if (parseToken(AsmToken::EndOfStatement,
4843  "unexpected token in '.incbin' directive"))
4844  return true;
4845 
4846  if (check(Skip < 0, SkipLoc, "skip is negative"))
4847  return true;
4848 
4849  // Attempt to process the included file.
4850  if (processIncbinFile(Filename, Skip, Count, CountLoc))
4851  return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
4852  return false;
4853 }
4854 
4855 /// parseDirectiveIf
4856 /// ::= .if{,eq,ge,gt,le,lt,ne} expression
4857 bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
4858  TheCondStack.push_back(TheCondState);
4859  TheCondState.TheCond = AsmCond::IfCond;
4860  if (TheCondState.Ignore) {
4861  eatToEndOfStatement();
4862  } else {
4863  int64_t ExprValue;
4864  if (parseAbsoluteExpression(ExprValue) ||
4865  parseToken(AsmToken::EndOfStatement,
4866  "unexpected token in '.if' directive"))
4867  return true;
4868 
4869  switch (DirKind) {
4870  default:
4871  llvm_unreachable("unsupported directive");
4872  case DK_IF:
4873  case DK_IFNE:
4874  break;
4875  case DK_IFEQ:
4876  ExprValue = ExprValue == 0;
4877  break;
4878  case DK_IFGE:
4879  ExprValue = ExprValue >= 0;
4880  break;
4881  case DK_IFGT:
4882  ExprValue = ExprValue > 0;
4883  break;
4884  case DK_IFLE:
4885  ExprValue = ExprValue <= 0;
4886  break;
4887  case DK_IFLT:
4888  ExprValue = ExprValue < 0;
4889  break;
4890  }
4891 
4892  TheCondState.CondMet = ExprValue;
4893  TheCondState.Ignore = !TheCondState.CondMet;
4894  }
4895 
4896  return false;
4897 }
4898 
4899 /// parseDirectiveIfb
4900 /// ::= .ifb string
4901 bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
4902  TheCondStack.push_back(TheCondState);
4903  TheCondState.TheCond = AsmCond::IfCond;
4904 
4905  if (TheCondState.Ignore) {
4906  eatToEndOfStatement();
4907  } else {
4908  StringRef Str = parseStringToEndOfStatement();
4909 
4910  if (parseToken(AsmToken::EndOfStatement,
4911  "unexpected token in '.ifb' directive"))
4912  return true;
4913 
4914  TheCondState.CondMet = ExpectBlank == Str.empty();
4915  TheCondState.Ignore = !TheCondState.CondMet;
4916  }
4917 
4918  return false;
4919 }
4920 
4921 /// parseDirectiveIfc
4922 /// ::= .ifc string1, string2
4923 /// ::= .ifnc string1, string2
4924 bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
4925  TheCondStack.push_back(TheCondState);
4926  TheCondState.TheCond = AsmCond::IfCond;
4927 
4928  if (TheCondState.Ignore) {
4929  eatToEndOfStatement();
4930  } else {
4931  StringRef Str1 = parseStringToComma();
4932 
4933  if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
4934  return true;
4935 
4936  StringRef Str2 = parseStringToEndOfStatement();
4937 
4938  if (parseToken(AsmToken::EndOfStatement,
4939  "unexpected token in '.ifc' directive"))
4940  return true;
4941 
4942  TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
4943  TheCondState.Ignore = !TheCondState.CondMet;
4944  }
4945 
4946  return false;
4947 }
4948 
4949 /// parseDirectiveIfeqs
4950 /// ::= .ifeqs string1, string2
4951 bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
4952  if (Lexer.isNot(AsmToken::String)) {
4953  if (ExpectEqual)
4954  return TokError("expected string parameter for '.ifeqs' directive");
4955  return TokError("expected string parameter for '.ifnes' directive");
4956  }
4957 
4958  StringRef String1 = getTok().getStringContents();
4959  Lex();
4960 
4961  if (Lexer.isNot(AsmToken::Comma)) {
4962  if (ExpectEqual)
4963  return TokError(
4964  "expected comma after first string for '.ifeqs' directive");
4965  return TokError("expected comma after first string for '.ifnes' directive");
4966  }
4967 
4968  Lex();
4969 
4970  if (Lexer.isNot(AsmToken::String)) {
4971  if (ExpectEqual)
4972  return TokError("expected string parameter for '.ifeqs' directive");
4973  return TokError("expected string parameter for '.ifnes' directive");
4974  }
4975 
4976  StringRef String2 = getTok().getStringContents();
4977  Lex();
4978 
4979  TheCondStack.push_back(TheCondState);
4980  TheCondState.TheCond = AsmCond::IfCond;
4981  TheCondState.CondMet = ExpectEqual == (String1 == String2);
4982  TheCondState.Ignore = !TheCondState.CondMet;
4983 
4984  return false;
4985 }
4986 
4987 /// parseDirectiveIfdef
4988 /// ::= .ifdef symbol
4989 bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
4990  StringRef Name;
4991  TheCondStack.push_back(TheCondState);
4992  TheCondState.TheCond = AsmCond::IfCond;
4993 
4994  if (TheCondState.Ignore) {
4995  eatToEndOfStatement();
4996  } else {
4997  if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
4998  parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
4999  return true;
5000 
5001  MCSymbol *Sym = getContext().lookupSymbol(Name);
5002 
5003  if (expect_defined)
5004  TheCondState.CondMet = (Sym && !Sym->isUndefined());
5005  else
5006  TheCondState.CondMet = (!Sym || Sym->isUndefined());
5007  TheCondState.Ignore = !TheCondState.CondMet;
5008  }
5009 
5010  return false;
5011 }
5012 
5013 /// parseDirectiveElseIf
5014 /// ::= .elseif expression
5015 bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
5016  if (TheCondState.TheCond != AsmCond::IfCond &&
5017  TheCondState.TheCond != AsmCond::ElseIfCond)
5018  return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5019  " .if or an .elseif");
5020  TheCondState.TheCond = AsmCond::ElseIfCond;
5021 
5022  bool LastIgnoreState = false;
5023  if (!TheCondStack.empty())
5024  LastIgnoreState = TheCondStack.back().Ignore;
5025  if (LastIgnoreState || TheCondState.CondMet) {
5026  TheCondState.Ignore = true;
5027  eatToEndOfStatement();
5028  } else {
5029  int64_t ExprValue;
5030  if (parseAbsoluteExpression(ExprValue))
5031  return true;
5032 
5033  if (parseToken(AsmToken::EndOfStatement,
5034  "unexpected token in '.elseif' directive"))
5035  return true;
5036 
5037  TheCondState.CondMet = ExprValue;
5038  TheCondState.Ignore = !TheCondState.CondMet;
5039  }
5040 
5041  return false;
5042 }
5043 
5044 /// parseDirectiveElse
5045 /// ::= .else
5046 bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5047  if (parseToken(AsmToken::EndOfStatement,
5048  "unexpected token in '.else' directive"))
5049  return true;
5050 
5051  if (TheCondState.TheCond != AsmCond::IfCond &&
5052  TheCondState.TheCond != AsmCond::ElseIfCond)
5053  return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
5054  " an .if or an .elseif");
5055  TheCondState.TheCond = AsmCond::ElseCond;
5056  bool LastIgnoreState = false;
5057  if (!TheCondStack.empty())
5058  LastIgnoreState = TheCondStack.back().Ignore;
5059  if (LastIgnoreState || TheCondState.CondMet)
5060  TheCondState.Ignore = true;
5061  else
5062  TheCondState.Ignore = false;
5063 
5064  return false;
5065 }
5066 
5067 /// parseDirectiveEnd
5068 /// ::= .end
5069 bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5070  if (parseToken(AsmToken::EndOfStatement,
5071  "unexpected token in '.end' directive"))
5072  return true;
5073 
5074  while (Lexer.isNot(AsmToken::Eof))
5075  Lexer.Lex();
5076 
5077  return false;
5078 }
5079 
5080 /// parseDirectiveError
5081 /// ::= .err
5082 /// ::= .error [string]
5083 bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
5084  if (!TheCondStack.empty()) {
5085  if (TheCondStack.back().Ignore) {
5086  eatToEndOfStatement();
5087  return false;
5088  }
5089  }
5090 
5091  if (!WithMessage)
5092  return Error(L, ".err encountered");
5093 
5094  StringRef Message = ".error directive invoked in source file";
5095  if (Lexer.isNot(AsmToken::EndOfStatement)) {
5096  if (Lexer.isNot(AsmToken::String))
5097  return TokError(".error argument must be a string");
5098 
5099  Message = getTok().getStringContents();
5100  Lex();
5101  }
5102 
5103  return Error(L, Message);
5104 }
5105 
5106 /// parseDirectiveWarning
5107 /// ::= .warning [string]
5108 bool AsmParser::parseDirectiveWarning(SMLoc L) {
5109  if (!TheCondStack.empty()) {
5110  if (TheCondStack.back().Ignore) {
5111  eatToEndOfStatement();
5112  return false;
5113  }
5114  }
5115 
5116  StringRef Message = ".warning directive invoked in source file";
5117 
5118  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5119  if (Lexer.isNot(AsmToken::String))
5120  return TokError(".warning argument must be a string");
5121 
5122  Message = getTok().getStringContents();
5123  Lex();
5124  if (parseToken(AsmToken::EndOfStatement,
5125  "expected end of statement in '.warning' directive"))
5126  return true;
5127  }
5128 
5129  return Warning(L, Message);
5130 }
5131 
5132 /// parseDirectiveEndIf
5133 /// ::= .endif
5134 bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5135  if (parseToken(AsmToken::EndOfStatement,
5136  "unexpected token in '.endif' directive"))
5137  return true;
5138 
5139  if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
5140  return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
5141  "an .if or .else");
5142  if (!TheCondStack.empty()) {
5143  TheCondState = TheCondStack.back();
5144  TheCondStack.pop_back();
5145  }
5146 
5147  return false;
5148 }
5149 
5150 void AsmParser::initializeDirectiveKindMap() {
5151  DirectiveKindMap[".set"] = DK_SET;
5152  DirectiveKindMap[".equ"] = DK_EQU;
5153  DirectiveKindMap[".equiv"] = DK_EQUIV;
5154  DirectiveKindMap[".ascii"] = DK_ASCII;
5155  DirectiveKindMap[".asciz"] = DK_ASCIZ;
5156  DirectiveKindMap[".string"] = DK_STRING;
5157  DirectiveKindMap[".byte"] = DK_BYTE;
5158  DirectiveKindMap[".short"] = DK_SHORT;
5159  DirectiveKindMap[".value"] = DK_VALUE;
5160  DirectiveKindMap[".2byte"] = DK_2BYTE;
5161  DirectiveKindMap[".long"] = DK_LONG;
5162  DirectiveKindMap[".int"] = DK_INT;
5163  DirectiveKindMap[".4byte"] = DK_4BYTE;
5164  DirectiveKindMap[".quad"] = DK_QUAD;
5165  DirectiveKindMap[".8byte"] = DK_8BYTE;
5166  DirectiveKindMap[".octa"] = DK_OCTA;
5167  DirectiveKindMap[".single"] = DK_SINGLE;
5168  DirectiveKindMap[".float"] = DK_FLOAT;
5169  DirectiveKindMap[".double"] = DK_DOUBLE;
5170  DirectiveKindMap[".align"] = DK_ALIGN;
5171  DirectiveKindMap[".align32"] = DK_ALIGN32;
5172  DirectiveKindMap[".balign"] = DK_BALIGN;
5173  DirectiveKindMap[".balignw"] = DK_BALIGNW;
5174  DirectiveKindMap[".balignl"] = DK_BALIGNL;
5175  DirectiveKindMap[".p2align"] = DK_P2ALIGN;
5176  DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
5177  DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
5178  DirectiveKindMap[".org"] = DK_ORG;
5179  DirectiveKindMap[".fill"] = DK_FILL;
5180  DirectiveKindMap[".zero"] = DK_ZERO;
5181  DirectiveKindMap[".extern"] = DK_EXTERN;
5182  DirectiveKindMap[".globl"] = DK_GLOBL;
5183  DirectiveKindMap[".global"] = DK_GLOBAL;
5184  DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
5185  DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
5186  DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5187  DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
5188  DirectiveKindMap[".reference"] = DK_REFERENCE;
5189  DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
5190  DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
5191  DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5192  DirectiveKindMap[".comm"] = DK_COMM;
5193  DirectiveKindMap[".common"] = DK_COMMON;
5194  DirectiveKindMap[".lcomm"] = DK_LCOMM;
5195  DirectiveKindMap[".abort"] = DK_ABORT;
5196  DirectiveKindMap[".include"] = DK_INCLUDE;
5197  DirectiveKindMap[".incbin"] = DK_INCBIN;
5198  DirectiveKindMap[".code16"] = DK_CODE16;
5199  DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
5200  DirectiveKindMap[".rept"] = DK_REPT;
5201  DirectiveKindMap[".rep"] = DK_REPT;
5202  DirectiveKindMap[".irp"] = DK_IRP;
5203  DirectiveKindMap[".irpc"] = DK_IRPC;
5204  DirectiveKindMap[".endr"] = DK_ENDR;
5205  DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5206  DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
5207  DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5208  DirectiveKindMap[".if"] = DK_IF;
5209  DirectiveKindMap[".ifeq"] = DK_IFEQ;
5210  DirectiveKindMap[".ifge"] = DK_IFGE;
5211  DirectiveKindMap[".ifgt"] = DK_IFGT;
5212  DirectiveKindMap[".ifle"] = DK_IFLE;
5213  DirectiveKindMap[".iflt"] = DK_IFLT;
5214  DirectiveKindMap[".ifne"] = DK_IFNE;
5215  DirectiveKindMap[".ifb"] = DK_IFB;
5216  DirectiveKindMap[".ifnb"] = DK_IFNB;
5217  DirectiveKindMap[".ifc"] = DK_IFC;
5218  DirectiveKindMap[".ifeqs"] = DK_IFEQS;
5219  DirectiveKindMap[".ifnc"] = DK_IFNC;
5220  DirectiveKindMap[".ifnes"] = DK_IFNES;
5221  DirectiveKindMap[".ifdef"] = DK_IFDEF;
5222  DirectiveKindMap[".ifndef"] = DK_IFNDEF;
5223  DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
5224  DirectiveKindMap[".elseif"] = DK_ELSEIF;
5225  DirectiveKindMap[".else"] = DK_ELSE;
5226  DirectiveKindMap[".end"] = DK_END;
5227  DirectiveKindMap[".endif"] = DK_ENDIF;
5228  DirectiveKindMap[".skip"] = DK_SKIP;
5229  DirectiveKindMap[".space"] = DK_SPACE;
5230  DirectiveKindMap[".file"] = DK_FILE;
5231  DirectiveKindMap[".line"] = DK_LINE;
5232  DirectiveKindMap[".loc"] = DK_LOC;
5233  DirectiveKindMap[".stabs"] = DK_STABS;
5234  DirectiveKindMap[".cv_file"] = DK_CV_FILE;
5235  DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
5236  DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
5237  DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
5238  DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5239  DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5240  DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
5241  DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
5242  DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5243  DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5244  DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
5245  DirectiveKindMap[".sleb128"] = DK_SLEB128;
5246  DirectiveKindMap[".uleb128"] = DK_ULEB128;
5247  DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
5248  DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
5249  DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
5250  DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5251  DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5252  DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5253  DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5254  DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
5255  DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5256  DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
5257  DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
5258  DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5259  DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5260  DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
5261  DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
5262  DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
5263  DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5264  DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5265  DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
5266  DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
5267  DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5268  DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
5269  DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
5270  DirectiveKindMap[".macro"] = DK_MACRO;
5271  DirectiveKindMap[".exitm"] = DK_EXITM;
5272  DirectiveKindMap[".endm"] = DK_ENDM;
5273  DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
5274  DirectiveKindMap[".purgem"] = DK_PURGEM;
5275  DirectiveKindMap[".err"] = DK_ERR;
5276  DirectiveKindMap[".error"] = DK_ERROR;
5277  DirectiveKindMap[".warning"] = DK_WARNING;
5278  DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
5279  DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
5280  DirectiveKindMap[".reloc"] = DK_RELOC;
5281  DirectiveKindMap[".dc"] = DK_DC;
5282  DirectiveKindMap[".dc.a"] = DK_DC_A;
5283  DirectiveKindMap[".dc.b"] = DK_DC_B;
5284  DirectiveKindMap[".dc.d"] = DK_DC_D;
5285  DirectiveKindMap[".dc.l"] = DK_DC_L;
5286  DirectiveKindMap[".dc.s"] = DK_DC_S;
5287  DirectiveKindMap[".dc.w"] = DK_DC_W;
5288  DirectiveKindMap[".dc.x"] = DK_DC_X;
5289  DirectiveKindMap[".dcb"] = DK_DCB;
5290  DirectiveKindMap[".dcb.b"] = DK_DCB_B;
5291  DirectiveKindMap[".dcb.d"] = DK_DCB_D;
5292  DirectiveKindMap[".dcb.l"] = DK_DCB_L;
5293  DirectiveKindMap[".dcb.s"] = DK_DCB_S;
5294  DirectiveKindMap[".dcb.w"] = DK_DCB_W;
5295  DirectiveKindMap[".dcb.x"] = DK_DCB_X;
5296  DirectiveKindMap[".ds"] = DK_DS;
5297  DirectiveKindMap[".ds.b"] = DK_DS_B;
5298  DirectiveKindMap[".ds.d"] = DK_DS_D;
5299  DirectiveKindMap[".ds.l"] = DK_DS_L;
5300  DirectiveKindMap[".ds.p"] = DK_DS_P;
5301  DirectiveKindMap[".ds.s"] = DK_DS_S;
5302  DirectiveKindMap[".ds.w"] = DK_DS_W;
5303  DirectiveKindMap[".ds.x"] = DK_DS_X;
5304  DirectiveKindMap[".print"] = DK_PRINT;
5305  DirectiveKindMap[".addrsig"] = DK_ADDRSIG;
5306  DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM;
5307 }
5308 
5309 MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5310  AsmToken EndToken, StartToken = getTok();
5311 
5312  unsigned NestLevel = 0;
5313  while (true) {
5314  // Check whether we have reached the end of the file.
5315  if (getLexer().is(AsmToken::Eof)) {
5316  printError(DirectiveLoc, "no matching '.endr' in definition");
5317  return nullptr;
5318  }
5319 
5320  if (Lexer.is(AsmToken::Identifier) &&
5321  (getTok().getIdentifier() == ".rep" ||
5322  getTok().getIdentifier() == ".rept" ||
5323  getTok().getIdentifier() == ".irp" ||
5324  getTok().getIdentifier() == ".irpc")) {
5325  ++NestLevel;
5326  }
5327 
5328  // Otherwise, check whether we have reached the .endr.
5329  if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
5330  if (NestLevel == 0) {
5331  EndToken = getTok();
5332  Lex();
5333  if (Lexer.isNot(AsmToken::EndOfStatement)) {
5334  printError(getTok().getLoc(),
5335  "unexpected token in '.endr' directive");
5336  return nullptr;
5337  }
5338  break;
5339  }
5340  --NestLevel;
5341  }
5342 
5343  // Otherwise, scan till the end of the statement.
5344  eatToEndOfStatement();
5345  }
5346 
5347  const char *BodyStart = StartToken.getLoc().getPointer();
5348  const char *BodyEnd = EndToken.getLoc().getPointer();
5349  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5350 
5351  // We Are Anonymous.
5352  MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
5353  return &MacroLikeBodies.back();
5354 }
5355 
5356 void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5357  raw_svector_ostream &OS) {
5358  OS << ".endr\n";
5359 
5360  std::unique_ptr<MemoryBuffer> Instantiation =
5361  MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
5362 
5363  // Create the macro instantiation object and add to the current macro
5364  // instantiation stack.
5365  MacroInstantiation *MI = new MacroInstantiation(
5366  DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
5367  ActiveMacros.push_back(MI);
5368 
5369  // Jump to the macro instantiation and prime the lexer.
5370  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
5371  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
5372  Lex();
5373 }
5374 
5375 /// parseDirectiveRept
5376 /// ::= .rep | .rept count
5377 bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5378  const MCExpr *CountExpr;
5379  SMLoc CountLoc = getTok().getLoc();
5380  if (parseExpression(CountExpr))
5381  return true;
5382 
5383  int64_t Count;
5384  if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5385  return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
5386  }
5387 
5388  if (check(Count < 0, CountLoc, "Count is negative") ||
5389  parseToken(AsmToken::EndOfStatement,
5390  "unexpected token in '" + Dir + "' directive"))
5391  return true;
5392 
5393  // Lex the rept definition.
5394  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5395  if (!M)
5396  return true;
5397 
5398  // Macro instantiation is lexical, unfortunately. We construct a new buffer
5399  // to hold the macro body with substitutions.
5400  SmallString<256> Buf;
5401  raw_svector_ostream OS(Buf);
5402  while (Count--) {
5403  // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
5404  if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
5405  return true;
5406  }
5407  instantiateMacroLikeBody(M, DirectiveLoc, OS);
5408 
5409  return false;
5410 }
5411 
5412 /// parseDirectiveIrp
5413 /// ::= .irp symbol,values
5414 bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5415  MCAsmMacroParameter Parameter;
5416  MCAsmMacroArguments A;
5417  if (check(parseIdentifier(Parameter.Name),
5418  "expected identifier in '.irp' directive") ||
5419  parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
5420  parseMacroArguments(nullptr, A) ||
5421  parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
5422  return true;
5423 
5424  // Lex the irp definition.
5425  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5426  if (!M)
5427  return true;
5428 
5429  // Macro instantiation is lexical, unfortunately. We construct a new buffer
5430  // to hold the macro body with substitutions.
5431  SmallString<256> Buf;
5432  raw_svector_ostream OS(Buf);
5433 
5434  for (const MCAsmMacroArgument &Arg : A) {
5435  // Note that the AtPseudoVariable is enabled for instantiations of .irp.
5436  // This is undocumented, but GAS seems to support it.
5437  if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5438  return true;
5439  }
5440 
5441  instantiateMacroLikeBody(M, DirectiveLoc, OS);
5442 
5443  return false;
5444 }
5445 
5446 /// parseDirectiveIrpc
5447 /// ::= .irpc symbol,values
5448 bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5449  MCAsmMacroParameter Parameter;
5450  MCAsmMacroArguments A;
5451 
5452  if (check(parseIdentifier(Parameter.Name),
5453  "expected identifier in '.irpc' directive") ||
5454  parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
5455  parseMacroArguments(nullptr, A))
5456  return true;
5457 
5458  if (A.size() != 1 || A.front().size() != 1)
5459  return TokError("unexpected token in '.irpc' directive");
5460 
5461  // Eat the end of statement.
5462  if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5463  return true;
5464 
5465  // Lex the irpc definition.
5466  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5467  if (!M)
5468  return true;
5469 
5470  // Macro instantiation is lexical, unfortunately. We construct a new buffer
5471  // to hold the macro body with substitutions.
5472  SmallString<256> Buf;
5473  raw_svector_ostream OS(Buf);
5474 
5475  StringRef Values = A.front().front().getString();
5476  for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
5477  MCAsmMacroArgument Arg;
5478  Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
5479 
5480  // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
5481  // This is undocumented, but GAS seems to support it.
5482  if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5483  return true;
5484  }
5485 
5486  instantiateMacroLikeBody(M, DirectiveLoc, OS);
5487 
5488  return false;
5489 }
5490 
5491 bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5492  if (ActiveMacros.empty())
5493  return TokError("unmatched '.endr' directive");
5494 
5495  // The only .repl that should get here are the ones created by
5496  // instantiateMacroLikeBody.
5497  assert(getLexer().is(AsmToken::EndOfStatement));
5498 
5499  handleMacroExit();
5500  return false;
5501 }
5502 
5503 bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5504  size_t Len) {
5505  const MCExpr *Value;
5506  SMLoc ExprLoc = getLexer().getLoc();
5507  if (parseExpression(Value))
5508  return true;
5509  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5510  if (!MCE)
5511  return Error(ExprLoc, "unexpected expression in _emit");
5512  uint64_t IntValue = MCE->getValue();
5513  if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5514  return Error(ExprLoc, "literal value out of range for directive");
5515 
5516  Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
5517  return false;
5518 }
5519 
5520 bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5521  const MCExpr *Value;
5522  SMLoc ExprLoc = getLexer().getLoc();
5523  if (parseExpression(Value))
5524  return true;
5525  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5526  if (!MCE)
5527  return Error(ExprLoc, "unexpected expression in align");
5528  uint64_t IntValue = MCE->getValue();
5529  if (!isPowerOf2_64(IntValue))
5530  return Error(ExprLoc, "literal value not a power of two greater then zero");
5531 
5532  Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
5533  return false;
5534 }
5535 
5536 bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
5537  const AsmToken StrTok = getTok();
5538  Lex();
5539  if (StrTok.isNot(AsmToken::String) || StrTok.getString().front() != '"')
5540  return Error(DirectiveLoc, "expected double quoted string after .print");
5541  if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5542  return true;
5543  llvm::outs() << StrTok.getStringContents() << '\n';
5544  return false;
5545 }
5546 
5547 bool AsmParser::parseDirectiveAddrsig() {
5548  getStreamer().EmitAddrsig();
5549  return false;
5550 }
5551 
5552 bool AsmParser::parseDirectiveAddrsigSym() {
5553  StringRef Name;
5554  if (check(parseIdentifier(Name),
5555  "expected identifier in '.addrsig_sym' directive"))
5556  return true;
5557  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5558  getStreamer().EmitAddrsigSym(Sym);
5559  return false;
5560 }
5561 
5562 // We are comparing pointers, but the pointers are relative to a single string.
5563 // Thus, this should always be deterministic.
5564 static int rewritesSort(const AsmRewrite *AsmRewriteA,
5565  const AsmRewrite *AsmRewriteB) {
5566  if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
5567  return -1;
5568  if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
5569  return 1;
5570 
5571  // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
5572  // rewrite to the same location. Make sure the SizeDirective rewrite is
5573  // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
5574  // ensures the sort algorithm is stable.
5575  if (AsmRewritePrecedence[AsmRewriteA->Kind] >
5576  AsmRewritePrecedence[AsmRewriteB->Kind])
5577  return -1;
5578 
5579  if (AsmRewritePrecedence[AsmRewriteA->Kind] <
5580  AsmRewritePrecedence[AsmRewriteB->Kind])
5581  return 1;
5582  llvm_unreachable("Unstable rewrite sort.");
5583 }
5584 
5585 bool AsmParser::parseMSInlineAsm(
5586  void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
5587  unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
5588  SmallVectorImpl<std::string> &Constraints,
5589  SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
5590  const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
5591  SmallVector<void *, 4> InputDecls;
5592  SmallVector<void *, 4> OutputDecls;
5593  SmallVector<bool, 4> InputDeclsAddressOf;
5594  SmallVector<bool, 4> OutputDeclsAddressOf;
5595  SmallVector<std::string, 4> InputConstraints;
5596  SmallVector<std::string, 4> OutputConstraints;
5597  SmallVector<unsigned, 4> ClobberRegs;
5598 
5599  SmallVector<AsmRewrite, 4> AsmStrRewrites;
5600 
5601  // Prime the lexer.
5602  Lex();
5603 
5604  // While we have input, parse each statement.
5605  unsigned InputIdx = 0;
5606  unsigned OutputIdx = 0;
5607  while (getLexer().isNot(AsmToken::Eof)) {
5608  // Parse curly braces marking block start/end
5609  if (parseCurlyBlockScope(AsmStrRewrites))
5610  continue;
5611 
5612  ParseStatementInfo Info(&AsmStrRewrites);
5613  bool StatementErr = parseStatement(Info, &SI);
5614 
5615  if (StatementErr || Info.ParseError) {
5616  // Emit pending errors if any exist.
5617  printPendingErrors();
5618  return true;
5619  }
5620 
5621  // No pending error should exist here.
5622  assert(!hasPendingError() && "unexpected error from parseStatement");
5623 
5624  if (Info.Opcode == ~0U)
5625  continue;
5626 
5627  const MCInstrDesc &Desc = MII->get(Info.Opcode);
5628 
5629  // Build the list of clobbers, outputs and inputs.
5630  for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
5631  MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
5632 
5633  // Immediate.
5634  if (Operand.isImm())
5635  continue;
5636 
5637  // Register operand.
5638  if (Operand.isReg() && !Operand.needAddressOf() &&
5639  !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
5640  unsigned NumDefs = Desc.getNumDefs();
5641  // Clobber.
5642  if (NumDefs && Operand.getMCOperandNum() < NumDefs)
5643  ClobberRegs.push_back(Operand.getReg());
5644  continue;
5645  }
5646 
5647  // Expr/Input or Output.
5648  StringRef SymName = Operand.getSymName();
5649  if (SymName.empty())
5650  continue;
5651 
5652  void *OpDecl = Operand.getOpDecl();
5653  if (!OpDecl)
5654  continue;
5655 
5656  bool isOutput = (i == 1) && Desc.mayStore();
5657  SMLoc Start = SMLoc::getFromPointer(SymName.data());
5658  if (isOutput) {
5659  ++InputIdx;
5660  OutputDecls.push_back(OpDecl);
5661  OutputDeclsAddressOf.push_back(Operand.needAddressOf());
5662  OutputConstraints.push_back(("=" + Operand.getConstraint()).str());
5663  AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
5664  } else {
5665  InputDecls.push_back(OpDecl);
5666  InputDeclsAddressOf.push_back(Operand.needAddressOf());
5667  InputConstraints.push_back(Operand.getConstraint().str());
5668  AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
5669  }
5670  }
5671 
5672  // Consider implicit defs to be clobbers. Think of cpuid and push.
5673  ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
5674  Desc.getNumImplicitDefs());
5675  ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
5676  }
5677 
5678  // Set the number of Outputs and Inputs.
5679  NumOutputs = OutputDecls.size();
5680  NumInputs = InputDecls.size();
5681 
5682  // Set the unique clobbers.
5683  array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
5684  ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
5685  ClobberRegs.end());
5686  Clobbers.assign(ClobberRegs.size(), std::string());
5687  for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
5688  raw_string_ostream OS(Clobbers[I]);
5689  IP->printRegName(OS, ClobberRegs[I]);
5690  }
5691 
5692  // Merge the various outputs and inputs. Output are expected first.
5693  if (NumOutputs || NumInputs) {
5694  unsigned NumExprs = NumOutputs + NumInputs;
5695  OpDecls.resize(NumExprs);
5696  Constraints.resize(NumExprs);
5697  for (unsigned i = 0; i < NumOutputs; ++i) {
5698  OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
5699  Constraints[i] = OutputConstraints[i];
5700  }
5701  for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
5702  OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
5703  Constraints[j] = InputConstraints[i];
5704  }
5705  }
5706 
5707  // Build the IR assembly string.
5708  std::string AsmStringIR;
5709  raw_string_ostream OS(AsmStringIR);
5710  StringRef ASMString =
5711  SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
5712  const char *AsmStart = ASMString.begin();
5713  const char *AsmEnd = ASMString.end();
5714  array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
5715  for (const AsmRewrite &AR : AsmStrRewrites) {
5716  AsmRewriteKind Kind = AR.Kind;
5717 
5718  const char *Loc = AR.Loc.getPointer();
5719  assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
5720 
5721  // Emit everything up to the immediate/expression.
5722  if (unsigned Len = Loc - AsmStart)
5723  OS << StringRef(AsmStart, Len);
5724 
5725  // Skip the original expression.
5726  if (Kind == AOK_Skip) {
5727  AsmStart = Loc + AR.Len;
5728  continue;
5729  }
5730 
5731  unsigned AdditionalSkip = 0;
5732  // Rewrite expressions in $N notation.
5733  switch (Kind) {
5734  default:
5735  break;
5736  case AOK_IntelExpr:
5737  assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
5738  if (AR.IntelExp.NeedBracs)
5739  OS << "[";
5740  if (AR.IntelExp.hasBaseReg())
5741  OS << AR.IntelExp.BaseReg;
5742  if (AR.IntelExp.hasIndexReg())
5743  OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
5744  << AR.IntelExp.IndexReg;
5745  if (AR.IntelExp.Scale > 1)
5746  OS << " * $$" << AR.IntelExp.Scale;
5747  if (AR.IntelExp.Imm || !AR.IntelExp.hasRegs())
5748  OS << (AR.IntelExp.hasRegs() ? " + $$" : "$$") << AR.IntelExp.Imm;
5749  if (AR.IntelExp.NeedBracs)
5750  OS << "]";
5751  break;
5752  case AOK_Label:
5753  OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
5754  break;
5755  case AOK_Input:
5756  OS << '$' << InputIdx++;
5757  break;
5758  case AOK_Output:
5759  OS << '$' << OutputIdx++;
5760  break;
5761  case AOK_SizeDirective:
5762  switch (AR.Val) {
5763  default: break;
5764  case 8: OS << "byte ptr "; break;
5765  case 16: OS << "word ptr "; break;
5766  case 32: OS << "dword ptr "; break;
5767  case 64: OS << "qword ptr "; break;
5768  case 80: OS << "xword ptr "; break;
5769  case 128: OS << "xmmword ptr "; break;
5770  case 256: OS << "ymmword ptr "; break;
5771  }
5772  break;
5773  case AOK_Emit:
5774  OS << ".byte";
5775  break;
5776  case AOK_Align: {
5777  // MS alignment directives are measured in bytes. If the native assembler
5778  // measures alignment in bytes, we can pass it straight through.
5779  OS << ".align";
5780  if (getContext().getAsmInfo()->getAlignmentIsInBytes())
5781  break;
5782 
5783  // Alignment is in log2 form, so print that instead and skip the original
5784  // immediate.
5785  unsigned Val = AR.Val;
5786  OS << ' ' << Val;
5787  assert(Val < 10 && "Expected alignment less then 2^10.");
5788  AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
5789  break;
5790  }
5791  case AOK_EVEN:
5792  OS << ".even";
5793  break;
5794  case AOK_EndOfStatement:
5795  OS << "\n\t";
5796  break;
5797  }
5798 
5799  // Skip the original expression.
5800  AsmStart = Loc + AR.Len + AdditionalSkip;
5801  }
5802 
5803  // Emit the remainder of the asm string.
5804  if (AsmStart != AsmEnd)
5805  OS << StringRef(AsmStart, AsmEnd - AsmStart);
5806 
5807  AsmString = OS.str();
5808  return false;
5809 }
5810 
5811 namespace llvm {
5812 namespace MCParserUtils {
5813 
5814 /// Returns whether the given symbol is used anywhere in the given expression,
5815 /// or subexpressions.
5816 static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
5817  switch (Value->getKind()) {
5818  case MCExpr::Binary: {
5819  const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value);
5820  return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
5821  isSymbolUsedInExpression(Sym, BE->getRHS());
5822  }
5823  case MCExpr::Target:
5824  case MCExpr::Constant:
5825  return false;
5826  case MCExpr::SymbolRef: {
5827  const MCSymbol &S =
5828  static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
5829  if (S.isVariable())
5830  return isSymbolUsedInExpression(Sym, S.getVariableValue());
5831  return &S == Sym;
5832  }
5833  case MCExpr::Unary:
5834  return isSymbolUsedInExpression(
5835  Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr());
5836  }
5837 
5838  llvm_unreachable("Unknown expr kind!");
5839 }
5840 
5841 bool parseAssignmentExpression(StringRef Name, bool allow_redef,
5842  MCAsmParser &Parser, MCSymbol *&Sym,
5843  const MCExpr *&Value) {
5844 
5845  // FIXME: Use better location, we should use proper tokens.
5846  SMLoc EqualLoc = Parser.getTok().getLoc();
5847  if (Parser.parseExpression(Value))
5848  return Parser.TokError("missing expression");
5849 
5850  // Note: we don't count b as used in "a = b". This is to allow
5851  // a = b
5852  // b = c
5853 
5855  return true;
5856 
5857  // Validate that the LHS is allowed to be a variable (either it has not been
5858  // used as a symbol, or it is an absolute symbol).
5859  Sym = Parser.getContext().lookupSymbol(Name);
5860  if (Sym) {
5861  // Diagnose assignment to a label.
5862  //
5863  // FIXME: Diagnostics. Note the location of the definition as a label.
5864  // FIXME: Diagnose assignment to protected identifier (e.g., register name).
5865  if (isSymbolUsedInExpression(Sym, Value))
5866  return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
5867  else if (Sym->isUndefined(/*SetUsed*/ false) && !Sym->isUsed() &&
5868  !Sym->isVariable())
5869  ; // Allow redefinitions of undefined symbols only used in directives.
5870  else if (Sym->isVariable() && !Sym->isUsed() && allow_redef)
5871  ; // Allow redefinitions of variables that haven't yet been used.
5872  else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
5873  return Parser.Error(EqualLoc, "redefinition of '" + Name + "'");
5874  else if (!Sym->isVariable())
5875  return Parser.Error(EqualLoc, "invalid assignment to '" + Name + "'");
5876  else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
5877  return Parser.Error(EqualLoc,
5878  "invalid reassignment of non-absolute variable '" +
5879  Name + "'");
5880  } else if (Name == ".") {
5881  Parser.getStreamer().emitValueToOffset(Value, 0, EqualLoc);
5882  return false;
5883  } else
5884  Sym = Parser.getContext().getOrCreateSymbol(Name);
5885 
5886  Sym->setRedefinable(allow_redef);
5887 
5888  return false;
5889 }
5890 
5891 } // end namespace MCParserUtils
5892 } // end namespace llvm
5893 
5894 /// Create an MCAsmParser instance.
5896  MCStreamer &Out, const MCAsmInfo &MAI,
5897  unsigned CB) {
5898  return new AsmParser(SM, C, Out, MAI, CB);
5899 }
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:382
bool getCOMMDirectiveAlignmentIsInBytes() const
Definition: MCAsmInfo.h:530
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:293
uint64_t CallInst * C
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:349
Represents a range in source code.
Definition: SMLoc.h:49
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:39
Signed less than comparison (result is either 0 or some target-specific non-zero value).
Definition: MCExpr.h:429
static bool parseHexOcta(AsmParser &Asm, uint64_t &hi, uint64_t &lo)
Definition: AsmParser.cpp:2998
MCSymbol * getDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before)
Create and return a directional local symbol for numbered label (used for "1b" or 1f" references)...
Definition: MCContext.cpp:248
const AsmToken & getTok() const
Get the current (last) lexed token.
Definition: MCAsmLexer.h:109
const MCAsmInfo & getMAI() const
Definition: AsmLexer.h:54
void setGenDwarfForAssembly(bool Value)
Definition: MCContext.h:595
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
Definition: SourceMgr.cpp:61
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:111
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1557
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
LLVMContext & Context
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:158
#define DWARF2_FLAG_PROLOGUE_END
Definition: MCDwarf.h:82
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:322
StringRef getBuffer() const
Definition: MemoryBuffer.h:64
MCSymbol * lookupSymbol(const Twine &Name) const
Get the symbol for Name, or null.
Definition: MCContext.cpp:256
unsigned getNumImplicitDefs() const
Return the number of implicit defs this instruct has.
Definition: MCInstrDesc.h:542
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
SMLoc getLoc() const
Definition: SourceMgr.h:286
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:294
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
Definition: SourceMgr.cpp:367
Signed less than or equal comparison (result is either 0 or some target-specific non-zero value)...
Definition: MCExpr.h:431
DiagHandlerTy getDiagHandler() const
Definition: SourceMgr.h:123
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
Definition: MCStreamer.cpp:986
This represents an "assembler immediate".
Definition: MCValue.h:40
void setSkipSpace(bool val)
Set whether spaces should be ignored by the lexer.
Definition: MCAsmLexer.h:150
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:144
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
VariantKind getKind() const
Definition: MCExpr.h:337
void redefineIfPossible()
Prepare this symbol to be redefined.
Definition: MCSymbol.h:230
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
Bitwise and.
Definition: MCExpr.h:420
virtual void AddBlankLine()
AddBlankLine - Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:324
MCTargetAsmParser - Generic interface to target specific assembly parsers.
bool parseAssignmentExpression(StringRef