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