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