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