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