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 
3392  if (HasMD5) {
3393  MD5::MD5Result Sum;
3394  for (unsigned i = 0; i != 8; ++i) {
3395  Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
3396  Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
3397  }
3398  CKMem = Sum;
3399  }
3400  if (HasSource) {
3401  char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
3402  memcpy(SourceBuf, SourceString.data(), SourceString.size());
3403  Source = StringRef(SourceBuf, SourceString.size());
3404  }
3405  if (FileNumber == 0) {
3406  if (Ctx.getDwarfVersion() < 5)
3407  return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
3408  getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
3409  } else {
3410  Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
3411  FileNumber, Directory, Filename, CKMem, Source);
3412  if (!FileNumOrErr)
3413  return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
3414  FileNumber = FileNumOrErr.get();
3415  }
3416  // Alert the user if there are some .file directives with MD5 and some not.
3417  // But only do that once.
3418  if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
3419  ReportedInconsistentMD5 = true;
3420  return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
3421  }
3422  }
3423 
3424  return false;
3425 }
3426 
3427 /// parseDirectiveLine
3428 /// ::= .line [number]
3429 bool AsmParser::parseDirectiveLine() {
3430  int64_t LineNumber;
3431  if (getLexer().is(AsmToken::Integer)) {
3432  if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
3433  return true;
3434  (void)LineNumber;
3435  // FIXME: Do something with the .line.
3436  }
3437  if (parseToken(AsmToken::EndOfStatement,
3438  "unexpected token in '.line' directive"))
3439  return true;
3440 
3441  return false;
3442 }
3443 
3444 /// parseDirectiveLoc
3445 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
3446 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
3447 /// The first number is a file number, must have been previously assigned with
3448 /// a .file directive, the second number is the line number and optionally the
3449 /// third number is a column position (zero if not specified). The remaining
3450 /// optional items are .loc sub-directives.
3451 bool AsmParser::parseDirectiveLoc() {
3452  int64_t FileNumber = 0, LineNumber = 0;
3453  SMLoc Loc = getTok().getLoc();
3454  if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
3455  check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
3456  "file number less than one in '.loc' directive") ||
3457  check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
3458  "unassigned file number in '.loc' directive"))
3459  return true;
3460 
3461  // optional
3462  if (getLexer().is(AsmToken::Integer)) {
3463  LineNumber = getTok().getIntVal();
3464  if (LineNumber < 0)
3465  return TokError("line number less than zero in '.loc' directive");
3466  Lex();
3467  }
3468 
3469  int64_t ColumnPos = 0;
3470  if (getLexer().is(AsmToken::Integer)) {
3471  ColumnPos = getTok().getIntVal();
3472  if (ColumnPos < 0)
3473  return TokError("column position less than zero in '.loc' directive");
3474  Lex();
3475  }
3476 
3477  unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
3478  unsigned Isa = 0;
3479  int64_t Discriminator = 0;
3480 
3481  auto parseLocOp = [&]() -> bool {
3482  StringRef Name;
3483  SMLoc Loc = getTok().getLoc();
3484  if (parseIdentifier(Name))
3485  return TokError("unexpected token in '.loc' directive");
3486 
3487  if (Name == "basic_block")
3488  Flags |= DWARF2_FLAG_BASIC_BLOCK;
3489  else if (Name == "prologue_end")
3490  Flags |= DWARF2_FLAG_PROLOGUE_END;
3491  else if (Name == "epilogue_begin")
3492  Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
3493  else if (Name == "is_stmt") {
3494  Loc = getTok().getLoc();
3495  const MCExpr *Value;
3496  if (parseExpression(Value))
3497  return true;
3498  // The expression must be the constant 0 or 1.
3499  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3500  int Value = MCE->getValue();
3501  if (Value == 0)
3502  Flags &= ~DWARF2_FLAG_IS_STMT;
3503  else if (Value == 1)
3504  Flags |= DWARF2_FLAG_IS_STMT;
3505  else
3506  return Error(Loc, "is_stmt value not 0 or 1");
3507  } else {
3508  return Error(Loc, "is_stmt value not the constant value of 0 or 1");
3509  }
3510  } else if (Name == "isa") {
3511  Loc = getTok().getLoc();
3512  const MCExpr *Value;
3513  if (parseExpression(Value))
3514  return true;
3515  // The expression must be a constant greater or equal to 0.
3516  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
3517  int Value = MCE->getValue();
3518  if (Value < 0)
3519  return Error(Loc, "isa number less than zero");
3520  Isa = Value;
3521  } else {
3522  return Error(Loc, "isa number not a constant value");
3523  }
3524  } else if (Name == "discriminator") {
3525  if (parseAbsoluteExpression(Discriminator))
3526  return true;
3527  } else {
3528  return Error(Loc, "unknown sub-directive in '.loc' directive");
3529  }
3530  return false;
3531  };
3532 
3533  if (parseMany(parseLocOp, false /*hasComma*/))
3534  return true;
3535 
3536  getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
3537  Isa, Discriminator, StringRef());
3538 
3539  return false;
3540 }
3541 
3542 /// parseDirectiveStabs
3543 /// ::= .stabs string, number, number, number
3544 bool AsmParser::parseDirectiveStabs() {
3545  return TokError("unsupported directive '.stabs'");
3546 }
3547 
3548 /// parseDirectiveCVFile
3549 /// ::= .cv_file number filename [checksum] [checksumkind]
3550 bool AsmParser::parseDirectiveCVFile() {
3551  SMLoc FileNumberLoc = getTok().getLoc();
3552  int64_t FileNumber;
3553  std::string Filename;
3554  std::string Checksum;
3555  int64_t ChecksumKind = 0;
3556 
3557  if (parseIntToken(FileNumber,
3558  "expected file number in '.cv_file' directive") ||
3559  check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
3560  check(getTok().isNot(AsmToken::String),
3561  "unexpected token in '.cv_file' directive") ||
3562  parseEscapedString(Filename))
3563  return true;
3564  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3565  if (check(getTok().isNot(AsmToken::String),
3566  "unexpected token in '.cv_file' directive") ||
3567  parseEscapedString(Checksum) ||
3568  parseIntToken(ChecksumKind,
3569  "expected checksum kind in '.cv_file' directive") ||
3570  parseToken(AsmToken::EndOfStatement,
3571  "unexpected token in '.cv_file' directive"))
3572  return true;
3573  }
3574 
3575  Checksum = fromHex(Checksum);
3576  void *CKMem = Ctx.allocate(Checksum.size(), 1);
3577  memcpy(CKMem, Checksum.data(), Checksum.size());
3578  ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
3579  Checksum.size());
3580 
3581  if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
3582  static_cast<uint8_t>(ChecksumKind)))
3583  return Error(FileNumberLoc, "file number already allocated");
3584 
3585  return false;
3586 }
3587 
3588 bool AsmParser::parseCVFunctionId(int64_t &FunctionId,
3589  StringRef DirectiveName) {
3590  SMLoc Loc;
3591  return parseTokenLoc(Loc) ||
3592  parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
3593  "' directive") ||
3594  check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
3595  "expected function id within range [0, UINT_MAX)");
3596 }
3597 
3598 bool AsmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
3599  SMLoc Loc;
3600  return parseTokenLoc(Loc) ||
3601  parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
3602  "' directive") ||
3603  check(FileNumber < 1, Loc, "file number less than one in '" +
3604  DirectiveName + "' directive") ||
3605  check(!getCVContext().isValidFileNumber(FileNumber), Loc,
3606  "unassigned file number in '" + DirectiveName + "' directive");
3607 }
3608 
3609 /// parseDirectiveCVFuncId
3610 /// ::= .cv_func_id FunctionId
3611 ///
3612 /// Introduces a function ID that can be used with .cv_loc.
3613 bool AsmParser::parseDirectiveCVFuncId() {
3614  SMLoc FunctionIdLoc = getTok().getLoc();
3615  int64_t FunctionId;
3616 
3617  if (parseCVFunctionId(FunctionId, ".cv_func_id") ||
3618  parseToken(AsmToken::EndOfStatement,
3619  "unexpected token in '.cv_func_id' directive"))
3620  return true;
3621 
3622  if (!getStreamer().EmitCVFuncIdDirective(FunctionId))
3623  return Error(FunctionIdLoc, "function id already allocated");
3624 
3625  return false;
3626 }
3627 
3628 /// parseDirectiveCVInlineSiteId
3629 /// ::= .cv_inline_site_id FunctionId
3630 /// "within" IAFunc
3631 /// "inlined_at" IAFile IALine [IACol]
3632 ///
3633 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
3634 /// at" source location information for use in the line table of the caller,
3635 /// whether the caller is a real function or another inlined call site.
3636 bool AsmParser::parseDirectiveCVInlineSiteId() {
3637  SMLoc FunctionIdLoc = getTok().getLoc();
3638  int64_t FunctionId;
3639  int64_t IAFunc;
3640  int64_t IAFile;
3641  int64_t IALine;
3642  int64_t IACol = 0;
3643 
3644  // FunctionId
3645  if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
3646  return true;
3647 
3648  // "within"
3649  if (check((getLexer().isNot(AsmToken::Identifier) ||
3650  getTok().getIdentifier() != "within"),
3651  "expected 'within' identifier in '.cv_inline_site_id' directive"))
3652  return true;
3653  Lex();
3654 
3655  // IAFunc
3656  if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
3657  return true;
3658 
3659  // "inlined_at"
3660  if (check((getLexer().isNot(AsmToken::Identifier) ||
3661  getTok().getIdentifier() != "inlined_at"),
3662  "expected 'inlined_at' identifier in '.cv_inline_site_id' "
3663  "directive") )
3664  return true;
3665  Lex();
3666 
3667  // IAFile IALine
3668  if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
3669  parseIntToken(IALine, "expected line number after 'inlined_at'"))
3670  return true;
3671 
3672  // [IACol]
3673  if (getLexer().is(AsmToken::Integer)) {
3674  IACol = getTok().getIntVal();
3675  Lex();
3676  }
3677 
3678  if (parseToken(AsmToken::EndOfStatement,
3679  "unexpected token in '.cv_inline_site_id' directive"))
3680  return true;
3681 
3682  if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
3683  IALine, IACol, FunctionIdLoc))
3684  return Error(FunctionIdLoc, "function id already allocated");
3685 
3686  return false;
3687 }
3688 
3689 /// parseDirectiveCVLoc
3690 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
3691 /// [is_stmt VALUE]
3692 /// The first number is a file number, must have been previously assigned with
3693 /// a .file directive, the second number is the line number and optionally the
3694 /// third number is a column position (zero if not specified). The remaining
3695 /// optional items are .loc sub-directives.
3696 bool AsmParser::parseDirectiveCVLoc() {
3697  SMLoc DirectiveLoc = getTok().getLoc();
3698  int64_t FunctionId, FileNumber;
3699  if (parseCVFunctionId(FunctionId, ".cv_loc") ||
3700  parseCVFileId(FileNumber, ".cv_loc"))
3701  return true;
3702 
3703  int64_t LineNumber = 0;
3704  if (getLexer().is(AsmToken::Integer)) {
3705  LineNumber = getTok().getIntVal();
3706  if (LineNumber < 0)
3707  return TokError("line number less than zero in '.cv_loc' directive");
3708  Lex();
3709  }
3710 
3711  int64_t ColumnPos = 0;
3712  if (getLexer().is(AsmToken::Integer)) {
3713  ColumnPos = getTok().getIntVal();
3714  if (ColumnPos < 0)
3715  return TokError("column position less than zero in '.cv_loc' directive");
3716  Lex();
3717  }
3718 
3719  bool PrologueEnd = false;
3720  uint64_t IsStmt = 0;
3721 
3722  auto parseOp = [&]() -> bool {
3723  StringRef Name;
3724  SMLoc Loc = getTok().getLoc();
3725  if (parseIdentifier(Name))
3726  return TokError("unexpected token in '.cv_loc' directive");
3727  if (Name == "prologue_end")
3728  PrologueEnd = true;
3729  else if (Name == "is_stmt") {
3730  Loc = getTok().getLoc();
3731  const MCExpr *Value;
3732  if (parseExpression(Value))
3733  return true;
3734  // The expression must be the constant 0 or 1.
3735  IsStmt = ~0ULL;
3736  if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
3737  IsStmt = MCE->getValue();
3738 
3739  if (IsStmt > 1)
3740  return Error(Loc, "is_stmt value not 0 or 1");
3741  } else {
3742  return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
3743  }
3744  return false;
3745  };
3746 
3747  if (parseMany(parseOp, false /*hasComma*/))
3748  return true;
3749 
3750  getStreamer().EmitCVLocDirective(FunctionId, FileNumber, LineNumber,
3751  ColumnPos, PrologueEnd, IsStmt, StringRef(),
3752  DirectiveLoc);
3753  return false;
3754 }
3755 
3756 /// parseDirectiveCVLinetable
3757 /// ::= .cv_linetable FunctionId, FnStart, FnEnd
3758 bool AsmParser::parseDirectiveCVLinetable() {
3759  int64_t FunctionId;
3760  StringRef FnStartName, FnEndName;
3761  SMLoc Loc = getTok().getLoc();
3762  if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
3763  parseToken(AsmToken::Comma,
3764  "unexpected token in '.cv_linetable' directive") ||
3765  parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3766  "expected identifier in directive") ||
3767  parseToken(AsmToken::Comma,
3768  "unexpected token in '.cv_linetable' directive") ||
3769  parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3770  "expected identifier in directive"))
3771  return true;
3772 
3773  MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3774  MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3775 
3776  getStreamer().EmitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
3777  return false;
3778 }
3779 
3780 /// parseDirectiveCVInlineLinetable
3781 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
3782 bool AsmParser::parseDirectiveCVInlineLinetable() {
3783  int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
3784  StringRef FnStartName, FnEndName;
3785  SMLoc Loc = getTok().getLoc();
3786  if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
3787  parseTokenLoc(Loc) ||
3788  parseIntToken(
3789  SourceFileId,
3790  "expected SourceField in '.cv_inline_linetable' directive") ||
3791  check(SourceFileId <= 0, Loc,
3792  "File id less than zero in '.cv_inline_linetable' directive") ||
3793  parseTokenLoc(Loc) ||
3794  parseIntToken(
3795  SourceLineNum,
3796  "expected SourceLineNum in '.cv_inline_linetable' directive") ||
3797  check(SourceLineNum < 0, Loc,
3798  "Line number less than zero in '.cv_inline_linetable' directive") ||
3799  parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
3800  "expected identifier in directive") ||
3801  parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
3802  "expected identifier in directive"))
3803  return true;
3804 
3805  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3806  return true;
3807 
3808  MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
3809  MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
3810  getStreamer().EmitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
3811  SourceLineNum, FnStartSym,
3812  FnEndSym);
3813  return false;
3814 }
3815 
3816 /// parseDirectiveCVDefRange
3817 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
3818 bool AsmParser::parseDirectiveCVDefRange() {
3819  SMLoc Loc;
3820  std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
3821  while (getLexer().is(AsmToken::Identifier)) {
3822  Loc = getLexer().getLoc();
3823  StringRef GapStartName;
3824  if (parseIdentifier(GapStartName))
3825  return Error(Loc, "expected identifier in directive");
3826  MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
3827 
3828  Loc = getLexer().getLoc();
3829  StringRef GapEndName;
3830  if (parseIdentifier(GapEndName))
3831  return Error(Loc, "expected identifier in directive");
3832  MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
3833 
3834  Ranges.push_back({GapStartSym, GapEndSym});
3835  }
3836 
3837  std::string FixedSizePortion;
3838  if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
3839  parseEscapedString(FixedSizePortion))
3840  return true;
3841 
3842  getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
3843  return false;
3844 }
3845 
3846 /// parseDirectiveCVString
3847 /// ::= .cv_stringtable "string"
3848 bool AsmParser::parseDirectiveCVString() {
3849  std::string Data;
3850  if (checkForValidSection() || parseEscapedString(Data))
3851  return addErrorSuffix(" in '.cv_string' directive");
3852 
3853  // Put the string in the table and emit the offset.
3854  std::pair<StringRef, unsigned> Insertion =
3855  getCVContext().addToStringTable(Data);
3856  getStreamer().EmitIntValue(Insertion.second, 4);
3857  return false;
3858 }
3859 
3860 /// parseDirectiveCVStringTable
3861 /// ::= .cv_stringtable
3862 bool AsmParser::parseDirectiveCVStringTable() {
3863  getStreamer().EmitCVStringTableDirective();
3864  return false;
3865 }
3866 
3867 /// parseDirectiveCVFileChecksums
3868 /// ::= .cv_filechecksums
3869 bool AsmParser::parseDirectiveCVFileChecksums() {
3870  getStreamer().EmitCVFileChecksumsDirective();
3871  return false;
3872 }
3873 
3874 /// parseDirectiveCVFileChecksumOffset
3875 /// ::= .cv_filechecksumoffset fileno
3876 bool AsmParser::parseDirectiveCVFileChecksumOffset() {
3877  int64_t FileNo;
3878  if (parseIntToken(FileNo, "expected identifier in directive"))
3879  return true;
3880  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
3881  return true;
3882  getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
3883  return false;
3884 }
3885 
3886 /// parseDirectiveCVFPOData
3887 /// ::= .cv_fpo_data procsym
3888 bool AsmParser::parseDirectiveCVFPOData() {
3889  SMLoc DirLoc = getLexer().getLoc();
3890  StringRef ProcName;
3891  if (parseIdentifier(ProcName))
3892  return TokError("expected symbol name");
3893  if (parseEOL("unexpected tokens"))
3894  return addErrorSuffix(" in '.cv_fpo_data' directive");
3895  MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
3896  getStreamer().EmitCVFPOData(ProcSym, DirLoc);
3897  return false;
3898 }
3899 
3900 /// parseDirectiveCFISections
3901 /// ::= .cfi_sections section [, section]
3902 bool AsmParser::parseDirectiveCFISections() {
3903  StringRef Name;
3904  bool EH = false;
3905  bool Debug = false;
3906 
3907  if (parseIdentifier(Name))
3908  return TokError("Expected an identifier");
3909 
3910  if (Name == ".eh_frame")
3911  EH = true;
3912  else if (Name == ".debug_frame")
3913  Debug = true;
3914 
3915  if (getLexer().is(AsmToken::Comma)) {
3916  Lex();
3917 
3918  if (parseIdentifier(Name))
3919  return TokError("Expected an identifier");
3920 
3921  if (Name == ".eh_frame")
3922  EH = true;
3923  else if (Name == ".debug_frame")
3924  Debug = true;
3925  }
3926 
3927  getStreamer().EmitCFISections(EH, Debug);
3928  return false;
3929 }
3930 
3931 /// parseDirectiveCFIStartProc
3932 /// ::= .cfi_startproc [simple]
3933 bool AsmParser::parseDirectiveCFIStartProc() {
3934  StringRef Simple;
3935  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
3936  if (check(parseIdentifier(Simple) || Simple != "simple",
3937  "unexpected token") ||
3938  parseToken(AsmToken::EndOfStatement))
3939  return addErrorSuffix(" in '.cfi_startproc' directive");
3940  }
3941 
3942  // TODO(kristina): Deal with a corner case of incorrect diagnostic context
3943  // being produced if this directive is emitted as part of preprocessor macro
3944  // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
3945  // Tools like llvm-mc on the other hand are not affected by it, and report
3946  // correct context information.
3947  getStreamer().EmitCFIStartProc(!Simple.empty(), Lexer.getLoc());
3948  return false;
3949 }
3950 
3951 /// parseDirectiveCFIEndProc
3952 /// ::= .cfi_endproc
3953 bool AsmParser::parseDirectiveCFIEndProc() {
3954  getStreamer().EmitCFIEndProc();
3955  return false;
3956 }
3957 
3958 /// parse register name or number.
3959 bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
3960  SMLoc DirectiveLoc) {
3961  unsigned RegNo;
3962 
3963  if (getLexer().isNot(AsmToken::Integer)) {
3964  if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
3965  return true;
3966  Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
3967  } else
3968  return parseAbsoluteExpression(Register);
3969 
3970  return false;
3971 }
3972 
3973 /// parseDirectiveCFIDefCfa
3974 /// ::= .cfi_def_cfa register, offset
3975 bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
3976  int64_t Register = 0, Offset = 0;
3977  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
3978  parseToken(AsmToken::Comma, "unexpected token in directive") ||
3979  parseAbsoluteExpression(Offset))
3980  return true;
3981 
3982  getStreamer().EmitCFIDefCfa(Register, Offset);
3983  return false;
3984 }
3985 
3986 /// parseDirectiveCFIDefCfaOffset
3987 /// ::= .cfi_def_cfa_offset offset
3988 bool AsmParser::parseDirectiveCFIDefCfaOffset() {
3989  int64_t Offset = 0;
3990  if (parseAbsoluteExpression(Offset))
3991  return true;
3992 
3993  getStreamer().EmitCFIDefCfaOffset(Offset);
3994  return false;
3995 }
3996 
3997 /// parseDirectiveCFIRegister
3998 /// ::= .cfi_register register, register
3999 bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
4000  int64_t Register1 = 0, Register2 = 0;
4001  if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
4002  parseToken(AsmToken::Comma, "unexpected token in directive") ||
4003  parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
4004  return true;
4005 
4006  getStreamer().EmitCFIRegister(Register1, Register2);
4007  return false;
4008 }
4009 
4010 /// parseDirectiveCFIWindowSave
4011 /// ::= .cfi_window_save
4012 bool AsmParser::parseDirectiveCFIWindowSave() {
4013  getStreamer().EmitCFIWindowSave();
4014  return false;
4015 }
4016 
4017 /// parseDirectiveCFIAdjustCfaOffset
4018 /// ::= .cfi_adjust_cfa_offset adjustment
4019 bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
4020  int64_t Adjustment = 0;
4021  if (parseAbsoluteExpression(Adjustment))
4022  return true;
4023 
4024  getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
4025  return false;
4026 }
4027 
4028 /// parseDirectiveCFIDefCfaRegister
4029 /// ::= .cfi_def_cfa_register register
4030 bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
4031  int64_t Register = 0;
4032  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4033  return true;
4034 
4035  getStreamer().EmitCFIDefCfaRegister(Register);
4036  return false;
4037 }
4038 
4039 /// parseDirectiveCFIOffset
4040 /// ::= .cfi_offset register, offset
4041 bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
4042  int64_t Register = 0;
4043  int64_t Offset = 0;
4044 
4045  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
4046  parseToken(AsmToken::Comma, "unexpected token in directive") ||
4047  parseAbsoluteExpression(Offset))
4048  return true;
4049 
4050  getStreamer().EmitCFIOffset(Register, Offset);
4051  return false;
4052 }
4053 
4054 /// parseDirectiveCFIRelOffset
4055 /// ::= .cfi_rel_offset register, offset
4056 bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
4057  int64_t Register = 0, Offset = 0;
4058 
4059  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
4060  parseToken(AsmToken::Comma, "unexpected token in directive") ||
4061  parseAbsoluteExpression(Offset))
4062  return true;
4063 
4064  getStreamer().EmitCFIRelOffset(Register, Offset);
4065  return false;
4066 }
4067 
4068 static bool isValidEncoding(int64_t Encoding) {
4069  if (Encoding & ~0xff)
4070  return false;
4071 
4072  if (Encoding == dwarf::DW_EH_PE_omit)
4073  return true;
4074 
4075  const unsigned Format = Encoding & 0xf;
4076  if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
4077  Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
4078  Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
4079  Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
4080  return false;
4081 
4082  const unsigned Application = Encoding & 0x70;
4083  if (Application != dwarf::DW_EH_PE_absptr &&
4084  Application != dwarf::DW_EH_PE_pcrel)
4085  return false;
4086 
4087  return true;
4088 }
4089 
4090 /// parseDirectiveCFIPersonalityOrLsda
4091 /// IsPersonality true for cfi_personality, false for cfi_lsda
4092 /// ::= .cfi_personality encoding, [symbol_name]
4093 /// ::= .cfi_lsda encoding, [symbol_name]
4094 bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
4095  int64_t Encoding = 0;
4096  if (parseAbsoluteExpression(Encoding))
4097  return true;
4098  if (Encoding == dwarf::DW_EH_PE_omit)
4099  return false;
4100 
4101  StringRef Name;
4102  if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
4103  parseToken(AsmToken::Comma, "unexpected token in directive") ||
4104  check(parseIdentifier(Name), "expected identifier in directive"))
4105  return true;
4106 
4107  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4108 
4109  if (IsPersonality)
4110  getStreamer().EmitCFIPersonality(Sym, Encoding);
4111  else
4112  getStreamer().EmitCFILsda(Sym, Encoding);
4113  return false;
4114 }
4115 
4116 /// parseDirectiveCFIRememberState
4117 /// ::= .cfi_remember_state
4118 bool AsmParser::parseDirectiveCFIRememberState() {
4119  getStreamer().EmitCFIRememberState();
4120  return false;
4121 }
4122 
4123 /// parseDirectiveCFIRestoreState
4124 /// ::= .cfi_remember_state
4125 bool AsmParser::parseDirectiveCFIRestoreState() {
4126  getStreamer().EmitCFIRestoreState();
4127  return false;
4128 }
4129 
4130 /// parseDirectiveCFISameValue
4131 /// ::= .cfi_same_value register
4132 bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
4133  int64_t Register = 0;
4134 
4135  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4136  return true;
4137 
4138  getStreamer().EmitCFISameValue(Register);
4139  return false;
4140 }
4141 
4142 /// parseDirectiveCFIRestore
4143 /// ::= .cfi_restore register
4144 bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
4145  int64_t Register = 0;
4146  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4147  return true;
4148 
4149  getStreamer().EmitCFIRestore(Register);
4150  return false;
4151 }
4152 
4153 /// parseDirectiveCFIEscape
4154 /// ::= .cfi_escape expression[,...]
4155 bool AsmParser::parseDirectiveCFIEscape() {
4156  std::string Values;
4157  int64_t CurrValue;
4158  if (parseAbsoluteExpression(CurrValue))
4159  return true;
4160 
4161  Values.push_back((uint8_t)CurrValue);
4162 
4163  while (getLexer().is(AsmToken::Comma)) {
4164  Lex();
4165 
4166  if (parseAbsoluteExpression(CurrValue))
4167  return true;
4168 
4169  Values.push_back((uint8_t)CurrValue);
4170  }
4171 
4172  getStreamer().EmitCFIEscape(Values);
4173  return false;
4174 }
4175 
4176 /// parseDirectiveCFIReturnColumn
4177 /// ::= .cfi_return_column register
4178 bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
4179  int64_t Register = 0;
4180  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4181  return true;
4182  getStreamer().EmitCFIReturnColumn(Register);
4183  return false;
4184 }
4185 
4186 /// parseDirectiveCFISignalFrame
4187 /// ::= .cfi_signal_frame
4188 bool AsmParser::parseDirectiveCFISignalFrame() {
4189  if (parseToken(AsmToken::EndOfStatement,
4190  "unexpected token in '.cfi_signal_frame'"))
4191  return true;
4192 
4193  getStreamer().EmitCFISignalFrame();
4194  return false;
4195 }
4196 
4197 /// parseDirectiveCFIUndefined
4198 /// ::= .cfi_undefined register
4199 bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
4200  int64_t Register = 0;
4201 
4202  if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
4203  return true;
4204 
4205  getStreamer().EmitCFIUndefined(Register);
4206  return false;
4207 }
4208 
4209 /// parseDirectiveAltmacro
4210 /// ::= .altmacro
4211 /// ::= .noaltmacro
4212 bool AsmParser::parseDirectiveAltmacro(StringRef Directive) {
4213  if (getLexer().isNot(AsmToken::EndOfStatement))
4214  return TokError("unexpected token in '" + Directive + "' directive");
4215  AltMacroMode = (Directive == ".altmacro");
4216  return false;
4217 }
4218 
4219 /// parseDirectiveMacrosOnOff
4220 /// ::= .macros_on
4221 /// ::= .macros_off
4222 bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
4223  if (parseToken(AsmToken::EndOfStatement,
4224  "unexpected token in '" + Directive + "' directive"))
4225  return true;
4226 
4227  setMacrosEnabled(Directive == ".macros_on");
4228  return false;
4229 }
4230 
4231 /// parseDirectiveMacro
4232 /// ::= .macro name[,] [parameters]
4233 bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
4234  StringRef Name;
4235  if (parseIdentifier(Name))
4236  return TokError("expected identifier in '.macro' directive");
4237 
4238  if (getLexer().is(AsmToken::Comma))
4239  Lex();
4240 
4241  MCAsmMacroParameters Parameters;
4242  while (getLexer().isNot(AsmToken::EndOfStatement)) {
4243 
4244  if (!Parameters.empty() && Parameters.back().Vararg)
4245  return Error(Lexer.getLoc(),
4246  "Vararg parameter '" + Parameters.back().Name +
4247  "' should be last one in the list of parameters.");
4248 
4249  MCAsmMacroParameter Parameter;
4250  if (parseIdentifier(Parameter.Name))
4251  return TokError("expected identifier in '.macro' directive");
4252 
4253  // Emit an error if two (or more) named parameters share the same name
4254  for (const MCAsmMacroParameter& CurrParam : Parameters)
4255  if (CurrParam.Name.equals(Parameter.Name))
4256  return TokError("macro '" + Name + "' has multiple parameters"
4257  " named '" + Parameter.Name + "'");
4258 
4259  if (Lexer.is(AsmToken::Colon)) {
4260  Lex(); // consume ':'
4261 
4262  SMLoc QualLoc;
4263  StringRef Qualifier;
4264 
4265  QualLoc = Lexer.getLoc();
4266  if (parseIdentifier(Qualifier))
4267  return Error(QualLoc, "missing parameter qualifier for "
4268  "'" + Parameter.Name + "' in macro '" + Name + "'");
4269 
4270  if (Qualifier == "req")
4271  Parameter.Required = true;
4272  else if (Qualifier == "vararg")
4273  Parameter.Vararg = true;
4274  else
4275  return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
4276  "for '" + Parameter.Name + "' in macro '" + Name + "'");
4277  }
4278 
4279  if (getLexer().is(AsmToken::Equal)) {
4280  Lex();
4281 
4282  SMLoc ParamLoc;
4283 
4284  ParamLoc = Lexer.getLoc();
4285  if (parseMacroArgument(Parameter.Value, /*Vararg=*/false ))
4286  return true;
4287 
4288  if (Parameter.Required)
4289  Warning(ParamLoc, "pointless default value for required parameter "
4290  "'" + Parameter.Name + "' in macro '" + Name + "'");
4291  }
4292 
4293  Parameters.push_back(std::move(Parameter));
4294 
4295  if (getLexer().is(AsmToken::Comma))
4296  Lex();
4297  }
4298 
4299  // Eat just the end of statement.
4300  Lexer.Lex();
4301 
4302  // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors
4303  AsmToken EndToken, StartToken = getTok();
4304  unsigned MacroDepth = 0;
4305  // Lex the macro definition.
4306  while (true) {
4307  // Ignore Lexing errors in macros.
4308  while (Lexer.is(AsmToken::Error)) {
4309  Lexer.Lex();
4310  }
4311 
4312  // Check whether we have reached the end of the file.
4313  if (getLexer().is(AsmToken::Eof))
4314  return Error(DirectiveLoc, "no matching '.endmacro' in definition");
4315 
4316  // Otherwise, check whether we have reach the .endmacro.
4317  if (getLexer().is(AsmToken::Identifier)) {
4318  if (getTok().getIdentifier() == ".endm" ||
4319  getTok().getIdentifier() == ".endmacro") {
4320  if (MacroDepth == 0) { // Outermost macro.
4321  EndToken = getTok();
4322  Lexer.Lex();
4323  if (getLexer().isNot(AsmToken::EndOfStatement))
4324  return TokError("unexpected token in '" + EndToken.getIdentifier() +
4325  "' directive");
4326  break;
4327  } else {
4328  // Otherwise we just found the end of an inner macro.
4329  --MacroDepth;
4330  }
4331  } else if (getTok().getIdentifier() == ".macro") {
4332  // We allow nested macros. Those aren't instantiated until the outermost
4333  // macro is expanded so just ignore them for now.
4334  ++MacroDepth;
4335  }
4336  }
4337 
4338  // Otherwise, scan til the end of the statement.
4339  eatToEndOfStatement();
4340  }
4341 
4342  if (getContext().lookupMacro(Name)) {
4343  return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
4344  }
4345 
4346  const char *BodyStart = StartToken.getLoc().getPointer();
4347  const char *BodyEnd = EndToken.getLoc().getPointer();
4348  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
4349  checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
4350  MCAsmMacro Macro(Name, Body, std::move(Parameters));
4351  DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
4352  Macro.dump());
4353  getContext().defineMacro(Name, std::move(Macro));
4354  return false;
4355 }
4356 
4357 /// checkForBadMacro
4358 ///
4359 /// With the support added for named parameters there may be code out there that
4360 /// is transitioning from positional parameters. In versions of gas that did
4361 /// not support named parameters they would be ignored on the macro definition.
4362 /// But to support both styles of parameters this is not possible so if a macro
4363 /// definition has named parameters but does not use them and has what appears
4364 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a
4365 /// warning that the positional parameter found in body which have no effect.
4366 /// Hoping the developer will either remove the named parameters from the macro
4367 /// definition so the positional parameters get used if that was what was
4368 /// intended or change the macro to use the named parameters. It is possible
4369 /// this warning will trigger when the none of the named parameters are used
4370 /// and the strings like $1 are infact to simply to be passed trough unchanged.
4371 void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
4372  StringRef Body,
4373  ArrayRef<MCAsmMacroParameter> Parameters) {
4374  // If this macro is not defined with named parameters the warning we are
4375  // checking for here doesn't apply.
4376  unsigned NParameters = Parameters.size();
4377  if (NParameters == 0)
4378  return;
4379 
4380  bool NamedParametersFound = false;
4381  bool PositionalParametersFound = false;
4382 
4383  // Look at the body of the macro for use of both the named parameters and what
4384  // are likely to be positional parameters. This is what expandMacro() is
4385  // doing when it finds the parameters in the body.
4386  while (!Body.empty()) {
4387  // Scan for the next possible parameter.
4388  std::size_t End = Body.size(), Pos = 0;
4389  for (; Pos != End; ++Pos) {
4390  // Check for a substitution or escape.
4391  // This macro is defined with parameters, look for \foo, \bar, etc.
4392  if (Body[Pos] == '\\' && Pos + 1 != End)
4393  break;
4394 
4395  // This macro should have parameters, but look for $0, $1, ..., $n too.
4396  if (Body[Pos] != '$' || Pos + 1 == End)
4397  continue;
4398  char Next = Body[Pos + 1];
4399  if (Next == '$' || Next == 'n' ||
4400  isdigit(static_cast<unsigned char>(Next)))
4401  break;
4402  }
4403 
4404  // Check if we reached the end.
4405  if (Pos == End)
4406  break;
4407 
4408  if (Body[Pos] == '$') {
4409  switch (Body[Pos + 1]) {
4410  // $$ => $
4411  case '$':
4412  break;
4413 
4414  // $n => number of arguments
4415  case 'n':
4416  PositionalParametersFound = true;
4417  break;
4418 
4419  // $[0-9] => argument
4420  default: {
4421  PositionalParametersFound = true;
4422  break;
4423  }
4424  }
4425  Pos += 2;
4426  } else {
4427  unsigned I = Pos + 1;
4428  while (isIdentifierChar(Body[I]) && I + 1 != End)
4429  ++I;
4430 
4431  const char *Begin = Body.data() + Pos + 1;
4432  StringRef Argument(Begin, I - (Pos + 1));
4433  unsigned Index = 0;
4434  for (; Index < NParameters; ++Index)
4435  if (Parameters[Index].Name == Argument)
4436  break;
4437 
4438  if (Index == NParameters) {
4439  if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
4440  Pos += 3;
4441  else {
4442  Pos = I;
4443  }
4444  } else {
4445  NamedParametersFound = true;
4446  Pos += 1 + Argument.size();
4447  }
4448  }
4449  // Update the scan point.
4450  Body = Body.substr(Pos);
4451  }
4452 
4453  if (!NamedParametersFound && PositionalParametersFound)
4454  Warning(DirectiveLoc, "macro defined with named parameters which are not "
4455  "used in macro body, possible positional parameter "
4456  "found in body which will have no effect");
4457 }
4458 
4459 /// parseDirectiveExitMacro
4460 /// ::= .exitm
4461 bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
4462  if (parseToken(AsmToken::EndOfStatement,
4463  "unexpected token in '" + Directive + "' directive"))
4464  return true;
4465 
4466  if (!isInsideMacroInstantiation())
4467  return TokError("unexpected '" + Directive + "' in file, "
4468  "no current macro definition");
4469 
4470  // Exit all conditionals that are active in the current macro.
4471  while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
4472  TheCondState = TheCondStack.back();
4473  TheCondStack.pop_back();
4474  }
4475 
4476  handleMacroExit();
4477  return false;
4478 }
4479 
4480 /// parseDirectiveEndMacro
4481 /// ::= .endm
4482 /// ::= .endmacro
4483 bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
4484  if (getLexer().isNot(AsmToken::EndOfStatement))
4485  return TokError("unexpected token in '" + Directive + "' directive");
4486 
4487  // If we are inside a macro instantiation, terminate the current
4488  // instantiation.
4489  if (isInsideMacroInstantiation()) {
4490  handleMacroExit();
4491  return false;
4492  }
4493 
4494  // Otherwise, this .endmacro is a stray entry in the file; well formed
4495  // .endmacro directives are handled during the macro definition parsing.
4496  return TokError("unexpected '" + Directive + "' in file, "
4497  "no current macro definition");
4498 }
4499 
4500 /// parseDirectivePurgeMacro
4501 /// ::= .purgem
4502 bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
4503  StringRef Name;
4504  SMLoc Loc;
4505  if (parseTokenLoc(Loc) ||
4506  check(parseIdentifier(Name), Loc,
4507  "expected identifier in '.purgem' directive") ||
4508  parseToken(AsmToken::EndOfStatement,
4509  "unexpected token in '.purgem' directive"))
4510  return true;
4511 
4512  if (!getContext().lookupMacro(Name))
4513  return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
4514 
4515  getContext().undefineMacro(Name);
4516  DEBUG_WITH_TYPE("asm-macros", dbgs()
4517  << "Un-defining macro: " << Name << "\n");
4518  return false;
4519 }
4520 
4521 /// parseDirectiveBundleAlignMode
4522 /// ::= {.bundle_align_mode} expression
4523 bool AsmParser::parseDirectiveBundleAlignMode() {
4524  // Expect a single argument: an expression that evaluates to a constant
4525  // in the inclusive range 0-30.
4526  SMLoc ExprLoc = getLexer().getLoc();
4527  int64_t AlignSizePow2;
4528  if (checkForValidSection() || parseAbsoluteExpression(AlignSizePow2) ||
4529  parseToken(AsmToken::EndOfStatement, "unexpected token after expression "
4530  "in '.bundle_align_mode' "
4531  "directive") ||
4532  check(AlignSizePow2 < 0 || AlignSizePow2 > 30, ExprLoc,
4533  "invalid bundle alignment size (expected between 0 and 30)"))
4534  return true;
4535 
4536  // Because of AlignSizePow2's verified range we can safely truncate it to
4537  // unsigned.
4538  getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
4539  return false;
4540 }
4541 
4542 /// parseDirectiveBundleLock
4543 /// ::= {.bundle_lock} [align_to_end]
4544 bool AsmParser::parseDirectiveBundleLock() {
4545  if (checkForValidSection())
4546  return true;
4547  bool AlignToEnd = false;
4548 
4549  StringRef Option;
4550  SMLoc Loc = getTok().getLoc();
4551  const char *kInvalidOptionError =
4552  "invalid option for '.bundle_lock' directive";
4553 
4554  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
4555  if (check(parseIdentifier(Option), Loc, kInvalidOptionError) ||
4556  check(Option != "align_to_end", Loc, kInvalidOptionError) ||
4557  parseToken(AsmToken::EndOfStatement,
4558  "unexpected token after '.bundle_lock' directive option"))
4559  return true;
4560  AlignToEnd = true;
4561  }
4562 
4563  getStreamer().EmitBundleLock(AlignToEnd);
4564  return false;
4565 }
4566 
4567 /// parseDirectiveBundleLock
4568 /// ::= {.bundle_lock}
4569 bool AsmParser::parseDirectiveBundleUnlock() {
4570  if (checkForValidSection() ||
4571  parseToken(AsmToken::EndOfStatement,
4572  "unexpected token in '.bundle_unlock' directive"))
4573  return true;
4574 
4575  getStreamer().EmitBundleUnlock();
4576  return false;
4577 }
4578 
4579 /// parseDirectiveSpace
4580 /// ::= (.skip | .space) expression [ , expression ]
4581 bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
4582  SMLoc NumBytesLoc = Lexer.getLoc();
4583  const MCExpr *NumBytes;
4584  if (checkForValidSection() || parseExpression(NumBytes))
4585  return true;
4586 
4587  int64_t FillExpr = 0;
4588  if (parseOptionalToken(AsmToken::Comma))
4589  if (parseAbsoluteExpression(FillExpr))
4590  return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
4591  if (parseToken(AsmToken::EndOfStatement))
4592  return addErrorSuffix("in '" + Twine(IDVal) + "' directive");
4593 
4594  // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
4595  getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
4596 
4597  return false;
4598 }
4599 
4600 /// parseDirectiveDCB
4601 /// ::= .dcb.{b, l, w} expression, expression
4602 bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
4603  SMLoc NumValuesLoc = Lexer.getLoc();
4604  int64_t NumValues;
4605  if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4606  return true;
4607 
4608  if (NumValues < 0) {
4609  Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4610  return false;
4611  }
4612 
4613  if (parseToken(AsmToken::Comma,
4614  "unexpected token in '" + Twine(IDVal) + "' directive"))
4615  return true;
4616 
4617  const MCExpr *Value;
4618  SMLoc ExprLoc = getLexer().getLoc();
4619  if (parseExpression(Value))
4620  return true;
4621 
4622  // Special case constant expressions to match code generator.
4623  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
4624  assert(Size <= 8 && "Invalid size");
4625  uint64_t IntValue = MCE->getValue();
4626  if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
4627  return Error(ExprLoc, "literal value out of range for directive");
4628  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4629  getStreamer().EmitIntValue(IntValue, Size);
4630  } else {
4631  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4632  getStreamer().EmitValue(Value, Size, ExprLoc);
4633  }
4634 
4635  if (parseToken(AsmToken::EndOfStatement,
4636  "unexpected token in '" + Twine(IDVal) + "' directive"))
4637  return true;
4638 
4639  return false;
4640 }
4641 
4642 /// parseDirectiveRealDCB
4643 /// ::= .dcb.{d, s} expression, expression
4644 bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
4645  SMLoc NumValuesLoc = Lexer.getLoc();
4646  int64_t NumValues;
4647  if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4648  return true;
4649 
4650  if (NumValues < 0) {
4651  Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4652  return false;
4653  }
4654 
4655  if (parseToken(AsmToken::Comma,
4656  "unexpected token in '" + Twine(IDVal) + "' directive"))
4657  return true;
4658 
4659  APInt AsInt;
4660  if (parseRealValue(Semantics, AsInt))
4661  return true;
4662 
4663  if (parseToken(AsmToken::EndOfStatement,
4664  "unexpected token in '" + Twine(IDVal) + "' directive"))
4665  return true;
4666 
4667  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4668  getStreamer().EmitIntValue(AsInt.getLimitedValue(),
4669  AsInt.getBitWidth() / 8);
4670 
4671  return false;
4672 }
4673 
4674 /// parseDirectiveDS
4675 /// ::= .ds.{b, d, l, p, s, w, x} expression
4676 bool AsmParser::parseDirectiveDS(StringRef IDVal, unsigned Size) {
4677  SMLoc NumValuesLoc = Lexer.getLoc();
4678  int64_t NumValues;
4679  if (checkForValidSection() || parseAbsoluteExpression(NumValues))
4680  return true;
4681 
4682  if (NumValues < 0) {
4683  Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
4684  return false;
4685  }
4686 
4687  if (parseToken(AsmToken::EndOfStatement,
4688  "unexpected token in '" + Twine(IDVal) + "' directive"))
4689  return true;
4690 
4691  for (uint64_t i = 0, e = NumValues; i != e; ++i)
4692  getStreamer().emitFill(Size, 0);
4693 
4694  return false;
4695 }
4696 
4697 /// parseDirectiveLEB128
4698 /// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
4699 bool AsmParser::parseDirectiveLEB128(bool Signed) {
4700  if (checkForValidSection())
4701  return true;
4702 
4703  auto parseOp = [&]() -> bool {
4704  const MCExpr *Value;
4705  if (parseExpression(Value))
4706  return true;
4707  if (Signed)
4708  getStreamer().EmitSLEB128Value(Value);
4709  else
4710  getStreamer().EmitULEB128Value(Value);
4711  return false;
4712  };
4713 
4714  if (parseMany(parseOp))
4715  return addErrorSuffix(" in directive");
4716 
4717  return false;
4718 }
4719 
4720 /// parseDirectiveSymbolAttribute
4721 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
4722 bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
4723  auto parseOp = [&]() -> bool {
4724  StringRef Name;
4725  SMLoc Loc = getTok().getLoc();
4726  if (parseIdentifier(Name))
4727  return Error(Loc, "expected identifier");
4728  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4729 
4730  // Assembler local symbols don't make any sense here. Complain loudly.
4731  if (Sym->isTemporary())
4732  return Error(Loc, "non-local symbol required");
4733 
4734  if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
4735  return Error(Loc, "unable to emit symbol attribute");
4736  return false;
4737  };
4738 
4739  if (parseMany(parseOp))
4740  return addErrorSuffix(" in directive");
4741  return false;
4742 }
4743 
4744 /// parseDirectiveComm
4745 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
4746 bool AsmParser::parseDirectiveComm(bool IsLocal) {
4747  if (checkForValidSection())
4748  return true;
4749 
4750  SMLoc IDLoc = getLexer().getLoc();
4751  StringRef Name;
4752  if (parseIdentifier(Name))
4753  return TokError("expected identifier in directive");
4754 
4755  // Handle the identifier as the key symbol.
4756  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4757 
4758  if (getLexer().isNot(AsmToken::Comma))
4759  return TokError("unexpected token in directive");
4760  Lex();
4761 
4762  int64_t Size;
4763  SMLoc SizeLoc = getLexer().getLoc();
4764  if (parseAbsoluteExpression(Size))
4765  return true;
4766 
4767  int64_t Pow2Alignment = 0;
4768  SMLoc Pow2AlignmentLoc;
4769  if (getLexer().is(AsmToken::Comma)) {
4770  Lex();
4771  Pow2AlignmentLoc = getLexer().getLoc();
4772  if (parseAbsoluteExpression(Pow2Alignment))
4773  return true;
4774 
4776  if (IsLocal && LCOMM == LCOMM::NoAlignment)
4777  return Error(Pow2AlignmentLoc, "alignment not supported on this target");
4778 
4779  // If this target takes alignments in bytes (not log) validate and convert.
4780  if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
4781  (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
4782  if (!isPowerOf2_64(Pow2Alignment))
4783  return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
4784  Pow2Alignment = Log2_64(Pow2Alignment);
4785  }
4786  }
4787 
4788  if (parseToken(AsmToken::EndOfStatement,
4789  "unexpected token in '.comm' or '.lcomm' directive"))
4790  return true;
4791 
4792  // NOTE: a size of zero for a .comm should create a undefined symbol
4793  // but a size of .lcomm creates a bss symbol of size zero.
4794  if (Size < 0)
4795  return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
4796  "be less than zero");
4797 
4798  // NOTE: The alignment in the directive is a power of 2 value, the assembler
4799  // may internally end up wanting an alignment in bytes.
4800  // FIXME: Diagnose overflow.
4801  if (Pow2Alignment < 0)
4802  return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
4803  "alignment, can't be less than zero");
4804 
4805  Sym->redefineIfPossible();
4806  if (!Sym->isUndefined())
4807  return Error(IDLoc, "invalid symbol redefinition");
4808 
4809  // Create the Symbol as a common or local common with Size and Pow2Alignment
4810  if (IsLocal) {
4811  getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4812  return false;
4813  }
4814 
4815  getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
4816  return false;
4817 }
4818 
4819 /// parseDirectiveAbort
4820 /// ::= .abort [... message ...]
4821 bool AsmParser::parseDirectiveAbort() {
4822  // FIXME: Use loc from directive.
4823  SMLoc Loc = getLexer().getLoc();
4824 
4825  StringRef Str = parseStringToEndOfStatement();
4826  if (parseToken(AsmToken::EndOfStatement,
4827  "unexpected token in '.abort' directive"))
4828  return true;
4829 
4830  if (Str.empty())
4831  return Error(Loc, ".abort detected. Assembly stopping.");
4832  else
4833  return Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
4834  // FIXME: Actually abort assembly here.
4835 
4836  return false;
4837 }
4838 
4839 /// parseDirectiveInclude
4840 /// ::= .include "filename"
4841 bool AsmParser::parseDirectiveInclude() {
4842  // Allow the strings to have escaped octal character sequence.
4843  std::string Filename;
4844  SMLoc IncludeLoc = getTok().getLoc();
4845 
4846  if (check(getTok().isNot(AsmToken::String),
4847  "expected string in '.include' directive") ||
4848  parseEscapedString(Filename) ||
4849  check(getTok().isNot(AsmToken::EndOfStatement),
4850  "unexpected token in '.include' directive") ||
4851  // Attempt to switch the lexer to the included file before consuming the
4852  // end of statement to avoid losing it when we switch.
4853  check(enterIncludeFile(Filename), IncludeLoc,
4854  "Could not find include file '" + Filename + "'"))
4855  return true;
4856 
4857  return false;
4858 }
4859 
4860 /// parseDirectiveIncbin
4861 /// ::= .incbin "filename" [ , skip [ , count ] ]
4862 bool AsmParser::parseDirectiveIncbin() {
4863  // Allow the strings to have escaped octal character sequence.
4864  std::string Filename;
4865  SMLoc IncbinLoc = getTok().getLoc();
4866  if (check(getTok().isNot(AsmToken::String),
4867  "expected string in '.incbin' directive") ||
4868  parseEscapedString(Filename))
4869  return true;
4870 
4871  int64_t Skip = 0;
4872  const MCExpr *Count = nullptr;
4873  SMLoc SkipLoc, CountLoc;
4874  if (parseOptionalToken(AsmToken::Comma)) {
4875  // The skip expression can be omitted while specifying the count, e.g:
4876  // .incbin "filename",,4
4877  if (getTok().isNot(AsmToken::Comma)) {
4878  if (parseTokenLoc(SkipLoc) || parseAbsoluteExpression(Skip))
4879  return true;
4880  }
4881  if (parseOptionalToken(AsmToken::Comma)) {
4882  CountLoc = getTok().getLoc();
4883  if (parseExpression(Count))
4884  return true;
4885  }
4886  }
4887 
4888  if (parseToken(AsmToken::EndOfStatement,
4889  "unexpected token in '.incbin' directive"))
4890  return true;
4891 
4892  if (check(Skip < 0, SkipLoc, "skip is negative"))
4893  return true;
4894 
4895  // Attempt to process the included file.
4896  if (processIncbinFile(Filename, Skip, Count, CountLoc))
4897  return Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
4898  return false;
4899 }
4900 
4901 /// parseDirectiveIf
4902 /// ::= .if{,eq,ge,gt,le,lt,ne} expression
4903 bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
4904  TheCondStack.push_back(TheCondState);
4905  TheCondState.TheCond = AsmCond::IfCond;
4906  if (TheCondState.Ignore) {
4907  eatToEndOfStatement();
4908  } else {
4909  int64_t ExprValue;
4910  if (parseAbsoluteExpression(ExprValue) ||
4911  parseToken(AsmToken::EndOfStatement,
4912  "unexpected token in '.if' directive"))
4913  return true;
4914 
4915  switch (DirKind) {
4916  default:
4917  llvm_unreachable("unsupported directive");
4918  case DK_IF:
4919  case DK_IFNE:
4920  break;
4921  case DK_IFEQ:
4922  ExprValue = ExprValue == 0;
4923  break;
4924  case DK_IFGE:
4925  ExprValue = ExprValue >= 0;
4926  break;
4927  case DK_IFGT:
4928  ExprValue = ExprValue > 0;
4929  break;
4930  case DK_IFLE:
4931  ExprValue = ExprValue <= 0;
4932  break;
4933  case DK_IFLT:
4934  ExprValue = ExprValue < 0;
4935  break;
4936  }
4937 
4938  TheCondState.CondMet = ExprValue;
4939  TheCondState.Ignore = !TheCondState.CondMet;
4940  }
4941 
4942  return false;
4943 }
4944 
4945 /// parseDirectiveIfb
4946 /// ::= .ifb string
4947 bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
4948  TheCondStack.push_back(TheCondState);
4949  TheCondState.TheCond = AsmCond::IfCond;
4950 
4951  if (TheCondState.Ignore) {
4952  eatToEndOfStatement();
4953  } else {
4954  StringRef Str = parseStringToEndOfStatement();
4955 
4956  if (parseToken(AsmToken::EndOfStatement,
4957  "unexpected token in '.ifb' directive"))
4958  return true;
4959 
4960  TheCondState.CondMet = ExpectBlank == Str.empty();
4961  TheCondState.Ignore = !TheCondState.CondMet;
4962  }
4963 
4964  return false;
4965 }
4966 
4967 /// parseDirectiveIfc
4968 /// ::= .ifc string1, string2
4969 /// ::= .ifnc string1, string2
4970 bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
4971  TheCondStack.push_back(TheCondState);
4972  TheCondState.TheCond = AsmCond::IfCond;
4973 
4974  if (TheCondState.Ignore) {
4975  eatToEndOfStatement();
4976  } else {
4977  StringRef Str1 = parseStringToComma();
4978 
4979  if (parseToken(AsmToken::Comma, "unexpected token in '.ifc' directive"))
4980  return true;
4981 
4982  StringRef Str2 = parseStringToEndOfStatement();
4983 
4984  if (parseToken(AsmToken::EndOfStatement,
4985  "unexpected token in '.ifc' directive"))
4986  return true;
4987 
4988  TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim());
4989  TheCondState.Ignore = !TheCondState.CondMet;
4990  }
4991 
4992  return false;
4993 }
4994 
4995 /// parseDirectiveIfeqs
4996 /// ::= .ifeqs string1, string2
4997 bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) {
4998  if (Lexer.isNot(AsmToken::String)) {
4999  if (ExpectEqual)
5000  return TokError("expected string parameter for '.ifeqs' directive");
5001  return TokError("expected string parameter for '.ifnes' directive");
5002  }
5003 
5004  StringRef String1 = getTok().getStringContents();
5005  Lex();
5006 
5007  if (Lexer.isNot(AsmToken::Comma)) {
5008  if (ExpectEqual)
5009  return TokError(
5010  "expected comma after first string for '.ifeqs' directive");
5011  return TokError("expected comma after first string for '.ifnes' directive");
5012  }
5013 
5014  Lex();
5015 
5016  if (Lexer.isNot(AsmToken::String)) {
5017  if (ExpectEqual)
5018  return TokError("expected string parameter for '.ifeqs' directive");
5019  return TokError("expected string parameter for '.ifnes' directive");
5020  }
5021 
5022  StringRef String2 = getTok().getStringContents();
5023  Lex();
5024 
5025  TheCondStack.push_back(TheCondState);
5026  TheCondState.TheCond = AsmCond::IfCond;
5027  TheCondState.CondMet = ExpectEqual == (String1 == String2);
5028  TheCondState.Ignore = !TheCondState.CondMet;
5029 
5030  return false;
5031 }
5032 
5033 /// parseDirectiveIfdef
5034 /// ::= .ifdef symbol
5035 bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
5036  StringRef Name;
5037  TheCondStack.push_back(TheCondState);
5038  TheCondState.TheCond = AsmCond::IfCond;
5039 
5040  if (TheCondState.Ignore) {
5041  eatToEndOfStatement();
5042  } else {
5043  if (check(parseIdentifier(Name), "expected identifier after '.ifdef'") ||
5044  parseToken(AsmToken::EndOfStatement, "unexpected token in '.ifdef'"))
5045  return true;
5046 
5047  MCSymbol *Sym = getContext().lookupSymbol(Name);
5048 
5049  if (expect_defined)
5050  TheCondState.CondMet = (Sym && !Sym->isUndefined(false));
5051  else
5052  TheCondState.CondMet = (!Sym || Sym->isUndefined(false));
5053  TheCondState.Ignore = !TheCondState.CondMet;
5054  }
5055 
5056  return false;
5057 }
5058 
5059 /// parseDirectiveElseIf
5060 /// ::= .elseif expression
5061 bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
5062  if (TheCondState.TheCond != AsmCond::IfCond &&
5063  TheCondState.TheCond != AsmCond::ElseIfCond)
5064  return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
5065  " .if or an .elseif");
5066  TheCondState.TheCond = AsmCond::ElseIfCond;
5067 
5068  bool LastIgnoreState = false;
5069  if (!TheCondStack.empty())
5070  LastIgnoreState = TheCondStack.back().Ignore;
5071  if (LastIgnoreState || TheCondState.CondMet) {
5072  TheCondState.Ignore = true;
5073  eatToEndOfStatement();
5074  } else {
5075  int64_t ExprValue;
5076  if (parseAbsoluteExpression(ExprValue))
5077  return true;
5078 
5079  if (parseToken(AsmToken::EndOfStatement,
5080  "unexpected token in '.elseif' directive"))
5081  return true;
5082 
5083  TheCondState.CondMet = ExprValue;
5084  TheCondState.Ignore = !TheCondState.CondMet;
5085  }
5086 
5087  return false;
5088 }
5089 
5090 /// parseDirectiveElse
5091 /// ::= .else
5092 bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
5093  if (parseToken(AsmToken::EndOfStatement,
5094  "unexpected token in '.else' directive"))
5095  return true;
5096 
5097  if (TheCondState.TheCond != AsmCond::IfCond &&
5098  TheCondState.TheCond != AsmCond::ElseIfCond)
5099  return Error(DirectiveLoc, "Encountered a .else that doesn't follow "
5100  " an .if or an .elseif");
5101  TheCondState.TheCond = AsmCond::ElseCond;
5102  bool LastIgnoreState = false;
5103  if (!TheCondStack.empty())
5104  LastIgnoreState = TheCondStack.back().Ignore;
5105  if (LastIgnoreState || TheCondState.CondMet)
5106  TheCondState.Ignore = true;
5107  else
5108  TheCondState.Ignore = false;
5109 
5110  return false;
5111 }
5112 
5113 /// parseDirectiveEnd
5114 /// ::= .end
5115 bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
5116  if (parseToken(AsmToken::EndOfStatement,
5117  "unexpected token in '.end' directive"))
5118  return true;
5119 
5120  while (Lexer.isNot(AsmToken::Eof))
5121  Lexer.Lex();
5122 
5123  return false;
5124 }
5125 
5126 /// parseDirectiveError
5127 /// ::= .err
5128 /// ::= .error [string]
5129 bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
5130  if (!TheCondStack.empty()) {
5131  if (TheCondStack.back().Ignore) {
5132  eatToEndOfStatement();
5133  return false;
5134  }
5135  }
5136 
5137  if (!WithMessage)
5138  return Error(L, ".err encountered");
5139 
5140  StringRef Message = ".error directive invoked in source file";
5141  if (Lexer.isNot(AsmToken::EndOfStatement)) {
5142  if (Lexer.isNot(AsmToken::String))
5143  return TokError(".error argument must be a string");
5144 
5145  Message = getTok().getStringContents();
5146  Lex();
5147  }
5148 
5149  return Error(L, Message);
5150 }
5151 
5152 /// parseDirectiveWarning
5153 /// ::= .warning [string]
5154 bool AsmParser::parseDirectiveWarning(SMLoc L) {
5155  if (!TheCondStack.empty()) {
5156  if (TheCondStack.back().Ignore) {
5157  eatToEndOfStatement();
5158  return false;
5159  }
5160  }
5161 
5162  StringRef Message = ".warning directive invoked in source file";
5163 
5164  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
5165  if (Lexer.isNot(AsmToken::String))
5166  return TokError(".warning argument must be a string");
5167 
5168  Message = getTok().getStringContents();
5169  Lex();
5170  if (parseToken(AsmToken::EndOfStatement,
5171  "expected end of statement in '.warning' directive"))
5172  return true;
5173  }
5174 
5175  return Warning(L, Message);
5176 }
5177 
5178 /// parseDirectiveEndIf
5179 /// ::= .endif
5180 bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
5181  if (parseToken(AsmToken::EndOfStatement,
5182  "unexpected token in '.endif' directive"))
5183  return true;
5184 
5185  if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
5186  return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
5187  "an .if or .else");
5188  if (!TheCondStack.empty()) {
5189  TheCondState = TheCondStack.back();
5190  TheCondStack.pop_back();
5191  }
5192 
5193  return false;
5194 }
5195 
5196 void AsmParser::initializeDirectiveKindMap() {
5197  DirectiveKindMap[".set"] = DK_SET;
5198  DirectiveKindMap[".equ"] = DK_EQU;
5199  DirectiveKindMap[".equiv"] = DK_EQUIV;
5200  DirectiveKindMap[".ascii"] = DK_ASCII;
5201  DirectiveKindMap[".asciz"] = DK_ASCIZ;
5202  DirectiveKindMap[".string"] = DK_STRING;
5203  DirectiveKindMap[".byte"] = DK_BYTE;
5204  DirectiveKindMap[".short"] = DK_SHORT;
5205  DirectiveKindMap[".value"] = DK_VALUE;
5206  DirectiveKindMap[".2byte"] = DK_2BYTE;
5207  DirectiveKindMap[".long"] = DK_LONG;
5208  DirectiveKindMap[".int"] = DK_INT;
5209  DirectiveKindMap[".4byte"] = DK_4BYTE;
5210  DirectiveKindMap[".quad"] = DK_QUAD;
5211  DirectiveKindMap[".8byte"] = DK_8BYTE;
5212  DirectiveKindMap[".octa"] = DK_OCTA;
5213  DirectiveKindMap[".single"] = DK_SINGLE;
5214  DirectiveKindMap[".float"] = DK_FLOAT;
5215  DirectiveKindMap[".double"] = DK_DOUBLE;
5216  DirectiveKindMap[".align"] = DK_ALIGN;
5217  DirectiveKindMap[".align32"] = DK_ALIGN32;
5218  DirectiveKindMap[".balign"] = DK_BALIGN;
5219  DirectiveKindMap[".balignw"] = DK_BALIGNW;
5220  DirectiveKindMap[".balignl"] = DK_BALIGNL;
5221  DirectiveKindMap[".p2align"] = DK_P2ALIGN;
5222  DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
5223  DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
5224  DirectiveKindMap[".org"] = DK_ORG;
5225  DirectiveKindMap[".fill"] = DK_FILL;
5226  DirectiveKindMap[".zero"] = DK_ZERO;
5227  DirectiveKindMap[".extern"] = DK_EXTERN;
5228  DirectiveKindMap[".globl"] = DK_GLOBL;
5229  DirectiveKindMap[".global"] = DK_GLOBAL;
5230  DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
5231  DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
5232  DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
5233  DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
5234  DirectiveKindMap[".reference"] = DK_REFERENCE;
5235  DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
5236  DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
5237  DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
5238  DirectiveKindMap[".cold"] = DK_COLD;
5239  DirectiveKindMap[".comm"] = DK_COMM;
5240  DirectiveKindMap[".common"] = DK_COMMON;
5241  DirectiveKindMap[".lcomm"] = DK_LCOMM;
5242  DirectiveKindMap[".abort"] = DK_ABORT;
5243  DirectiveKindMap[".include"] = DK_INCLUDE;
5244  DirectiveKindMap[".incbin"] = DK_INCBIN;
5245  DirectiveKindMap[".code16"] = DK_CODE16;
5246  DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
5247  DirectiveKindMap[".rept"] = DK_REPT;
5248  DirectiveKindMap[".rep"] = DK_REPT;
5249  DirectiveKindMap[".irp"] = DK_IRP;
5250  DirectiveKindMap[".irpc"] = DK_IRPC;
5251  DirectiveKindMap[".endr"] = DK_ENDR;
5252  DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
5253  DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
5254  DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
5255  DirectiveKindMap[".if"] = DK_IF;
5256  DirectiveKindMap[".ifeq"] = DK_IFEQ;
5257  DirectiveKindMap[".ifge"] = DK_IFGE;
5258  DirectiveKindMap[".ifgt"] = DK_IFGT;
5259  DirectiveKindMap[".ifle"] = DK_IFLE;
5260  DirectiveKindMap[".iflt"] = DK_IFLT;
5261  DirectiveKindMap[".ifne"] = DK_IFNE;
5262  DirectiveKindMap[".ifb"] = DK_IFB;
5263  DirectiveKindMap[".ifnb"] = DK_IFNB;
5264  DirectiveKindMap[".ifc"] = DK_IFC;
5265  DirectiveKindMap[".ifeqs"] = DK_IFEQS;
5266  DirectiveKindMap[".ifnc"] = DK_IFNC;
5267  DirectiveKindMap[".ifnes"] = DK_IFNES;
5268  DirectiveKindMap[".ifdef"] = DK_IFDEF;
5269  DirectiveKindMap[".ifndef"] = DK_IFNDEF;
5270  DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
5271  DirectiveKindMap[".elseif"] = DK_ELSEIF;
5272  DirectiveKindMap[".else"] = DK_ELSE;
5273  DirectiveKindMap[".end"] = DK_END;
5274  DirectiveKindMap[".endif"] = DK_ENDIF;
5275  DirectiveKindMap[".skip"] = DK_SKIP;
5276  DirectiveKindMap[".space"] = DK_SPACE;
5277  DirectiveKindMap[".file"] = DK_FILE;
5278  DirectiveKindMap[".line"] = DK_LINE;
5279  DirectiveKindMap[".loc"] = DK_LOC;
5280  DirectiveKindMap[".stabs"] = DK_STABS;
5281  DirectiveKindMap[".cv_file"] = DK_CV_FILE;
5282  DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
5283  DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
5284  DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
5285  DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
5286  DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
5287  DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
5288  DirectiveKindMap[".cv_string"] = DK_CV_STRING;
5289  DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
5290  DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
5291  DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
5292  DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
5293  DirectiveKindMap[".sleb128"] = DK_SLEB128;
5294  DirectiveKindMap[".uleb128"] = DK_ULEB128;
5295  DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
5296  DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
5297  DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
5298  DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
5299  DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
5300  DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
5301  DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
5302  DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
5303  DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
5304  DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
5305  DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
5306  DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
5307  DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
5308  DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
5309  DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
5310  DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
5311  DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
5312  DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
5313  DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
5314  DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
5315  DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
5316  DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
5317  DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
5318  DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
5319  DirectiveKindMap[".macro"] = DK_MACRO;
5320  DirectiveKindMap[".exitm"] = DK_EXITM;
5321  DirectiveKindMap[".endm"] = DK_ENDM;
5322  DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
5323  DirectiveKindMap[".purgem"] = DK_PURGEM;
5324  DirectiveKindMap[".err"] = DK_ERR;
5325  DirectiveKindMap[".error"] = DK_ERROR;
5326  DirectiveKindMap[".warning"] = DK_WARNING;
5327  DirectiveKindMap[".altmacro"] = DK_ALTMACRO;
5328  DirectiveKindMap[".noaltmacro"] = DK_NOALTMACRO;
5329  DirectiveKindMap[".reloc"] = DK_RELOC;
5330  DirectiveKindMap[".dc"] = DK_DC;
5331  DirectiveKindMap[".dc.a"] = DK_DC_A;
5332  DirectiveKindMap[".dc.b"] = DK_DC_B;
5333  DirectiveKindMap[".dc.d"] = DK_DC_D;
5334  DirectiveKindMap[".dc.l"] = DK_DC_L;
5335  DirectiveKindMap[".dc.s"] = DK_DC_S;
5336  DirectiveKindMap[".dc.w"] = DK_DC_W;
5337  DirectiveKindMap[".dc.x"] = DK_DC_X;
5338  DirectiveKindMap[".dcb"] = DK_DCB;
5339  DirectiveKindMap[".dcb.b"] = DK_DCB_B;
5340  DirectiveKindMap[".dcb.d"] = DK_DCB_D;
5341  DirectiveKindMap[".dcb.l"] = DK_DCB_L;
5342  DirectiveKindMap[".dcb.s"] = DK_DCB_S;
5343  DirectiveKindMap[".dcb.w"] = DK_DCB_W;
5344  DirectiveKindMap[".dcb.x"] = DK_DCB_X;
5345  DirectiveKindMap[".ds"] = DK_DS;
5346  DirectiveKindMap[".ds.b"] = DK_DS_B;
5347  DirectiveKindMap[".ds.d"] = DK_DS_D;
5348  DirectiveKindMap[".ds.l"] = DK_DS_L;
5349  DirectiveKindMap[".ds.p"] = DK_DS_P;
5350  DirectiveKindMap[".ds.s"] = DK_DS_S;
5351  DirectiveKindMap[".ds.w"] = DK_DS_W;
5352  DirectiveKindMap[".ds.x"] = DK_DS_X;
5353  DirectiveKindMap[".print"] = DK_PRINT;
5354  DirectiveKindMap[".addrsig"] = DK_ADDRSIG;
5355  DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM;
5356 }
5357 
5358 MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
5359  AsmToken EndToken, StartToken = getTok();
5360 
5361  unsigned NestLevel = 0;
5362  while (true) {
5363  // Check whether we have reached the end of the file.
5364  if (getLexer().is(AsmToken::Eof)) {
5365  printError(DirectiveLoc, "no matching '.endr' in definition");
5366  return nullptr;
5367  }
5368 
5369  if (Lexer.is(AsmToken::Identifier) &&
5370  (getTok().getIdentifier() == ".rep" ||
5371  getTok().getIdentifier() == ".rept" ||
5372  getTok().getIdentifier() == ".irp" ||
5373  getTok().getIdentifier() == ".irpc")) {
5374  ++NestLevel;
5375  }
5376 
5377  // Otherwise, check whether we have reached the .endr.
5378  if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
5379  if (NestLevel == 0) {
5380  EndToken = getTok();
5381  Lex();
5382  if (Lexer.isNot(AsmToken::EndOfStatement)) {
5383  printError(getTok().getLoc(),
5384  "unexpected token in '.endr' directive");
5385  return nullptr;
5386  }
5387  break;
5388  }
5389  --NestLevel;
5390  }
5391 
5392  // Otherwise, scan till the end of the statement.
5393  eatToEndOfStatement();
5394  }
5395 
5396  const char *BodyStart = StartToken.getLoc().getPointer();
5397  const char *BodyEnd = EndToken.getLoc().getPointer();
5398  StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
5399 
5400  // We Are Anonymous.
5401  MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
5402  return &MacroLikeBodies.back();
5403 }
5404 
5405 void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
5406  raw_svector_ostream &OS) {
5407  OS << ".endr\n";
5408 
5409  std::unique_ptr<MemoryBuffer> Instantiation =
5410  MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
5411 
5412  // Create the macro instantiation object and add to the current macro
5413  // instantiation stack.
5414  MacroInstantiation *MI = new MacroInstantiation(
5415  DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
5416  ActiveMacros.push_back(MI);
5417 
5418  // Jump to the macro instantiation and prime the lexer.
5419  CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
5420  Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
5421  Lex();
5422 }
5423 
5424 /// parseDirectiveRept
5425 /// ::= .rep | .rept count
5426 bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
5427  const MCExpr *CountExpr;
5428  SMLoc CountLoc = getTok().getLoc();
5429  if (parseExpression(CountExpr))
5430  return true;
5431 
5432  int64_t Count;
5433  if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
5434  return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
5435  }
5436 
5437  if (check(Count < 0, CountLoc, "Count is negative") ||
5438  parseToken(AsmToken::EndOfStatement,
5439  "unexpected token in '" + Dir + "' directive"))
5440  return true;
5441 
5442  // Lex the rept definition.
5443  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5444  if (!M)
5445  return true;
5446 
5447  // Macro instantiation is lexical, unfortunately. We construct a new buffer
5448  // to hold the macro body with substitutions.
5449  SmallString<256> Buf;
5450  raw_svector_ostream OS(Buf);
5451  while (Count--) {
5452  // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
5453  if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
5454  return true;
5455  }
5456  instantiateMacroLikeBody(M, DirectiveLoc, OS);
5457 
5458  return false;
5459 }
5460 
5461 /// parseDirectiveIrp
5462 /// ::= .irp symbol,values
5463 bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
5464  MCAsmMacroParameter Parameter;
5465  MCAsmMacroArguments A;
5466  if (check(parseIdentifier(Parameter.Name),
5467  "expected identifier in '.irp' directive") ||
5468  parseToken(AsmToken::Comma, "expected comma in '.irp' directive") ||
5469  parseMacroArguments(nullptr, A) ||
5470  parseToken(AsmToken::EndOfStatement, "expected End of Statement"))
5471  return true;
5472 
5473  // Lex the irp definition.
5474  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5475  if (!M)
5476  return true;
5477 
5478  // Macro instantiation is lexical, unfortunately. We construct a new buffer
5479  // to hold the macro body with substitutions.
5480  SmallString<256> Buf;
5481  raw_svector_ostream OS(Buf);
5482 
5483  for (const MCAsmMacroArgument &Arg : A) {
5484  // Note that the AtPseudoVariable is enabled for instantiations of .irp.
5485  // This is undocumented, but GAS seems to support it.
5486  if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5487  return true;
5488  }
5489 
5490  instantiateMacroLikeBody(M, DirectiveLoc, OS);
5491 
5492  return false;
5493 }
5494 
5495 /// parseDirectiveIrpc
5496 /// ::= .irpc symbol,values
5497 bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
5498  MCAsmMacroParameter Parameter;
5499  MCAsmMacroArguments A;
5500 
5501  if (check(parseIdentifier(Parameter.Name),
5502  "expected identifier in '.irpc' directive") ||
5503  parseToken(AsmToken::Comma, "expected comma in '.irpc' directive") ||
5504  parseMacroArguments(nullptr, A))
5505  return true;
5506 
5507  if (A.size() != 1 || A.front().size() != 1)
5508  return TokError("unexpected token in '.irpc' directive");
5509 
5510  // Eat the end of statement.
5511  if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5512  return true;
5513 
5514  // Lex the irpc definition.
5515  MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
5516  if (!M)
5517  return true;
5518 
5519  // Macro instantiation is lexical, unfortunately. We construct a new buffer
5520  // to hold the macro body with substitutions.
5521  SmallString<256> Buf;
5522  raw_svector_ostream OS(Buf);
5523 
5524  StringRef Values = A.front().front().getString();
5525  for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
5526  MCAsmMacroArgument Arg;
5527  Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
5528 
5529  // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
5530  // This is undocumented, but GAS seems to support it.
5531  if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
5532  return true;
5533  }
5534 
5535  instantiateMacroLikeBody(M, DirectiveLoc, OS);
5536 
5537  return false;
5538 }
5539 
5540 bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
5541  if (ActiveMacros.empty())
5542  return TokError("unmatched '.endr' directive");
5543 
5544  // The only .repl that should get here are the ones created by
5545  // instantiateMacroLikeBody.
5546  assert(getLexer().is(AsmToken::EndOfStatement));
5547 
5548  handleMacroExit();
5549  return false;
5550 }
5551 
5552 bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
5553  size_t Len) {
5554  const MCExpr *Value;
5555  SMLoc ExprLoc = getLexer().getLoc();
5556  if (parseExpression(Value))
5557  return true;
5558  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5559  if (!MCE)
5560  return Error(ExprLoc, "unexpected expression in _emit");
5561  uint64_t IntValue = MCE->getValue();
5562  if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
5563  return Error(ExprLoc, "literal value out of range for directive");
5564 
5565  Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
5566  return false;
5567 }
5568 
5569 bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
5570  const MCExpr *Value;
5571  SMLoc ExprLoc = getLexer().getLoc();
5572  if (parseExpression(Value))
5573  return true;
5574  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
5575  if (!MCE)
5576  return Error(ExprLoc, "unexpected expression in align");
5577  uint64_t IntValue = MCE->getValue();
5578  if (!isPowerOf2_64(IntValue))
5579  return Error(ExprLoc, "literal value not a power of two greater then zero");
5580 
5581  Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
5582  return false;
5583 }
5584 
5585 bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) {
5586  const AsmToken StrTok = getTok();
5587  Lex();
5588  if (StrTok.isNot(AsmToken::String) || StrTok.getString().front() != '"')
5589  return Error(DirectiveLoc, "expected double quoted string after .print");
5590  if (parseToken(AsmToken::EndOfStatement, "expected end of statement"))
5591  return true;
5592  llvm::outs() << StrTok.getStringContents() << '\n';
5593  return false;
5594 }
5595 
5596 bool AsmParser::parseDirectiveAddrsig() {
5597  getStreamer().EmitAddrsig();
5598  return false;
5599 }
5600 
5601 bool AsmParser::parseDirectiveAddrsigSym() {
5602  StringRef Name;
5603  if (check(parseIdentifier(Name),
5604  "expected identifier in '.addrsig_sym' directive"))
5605  return true;
5606  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5607  getStreamer().EmitAddrsigSym(Sym);
5608  return false;
5609 }
5610 
5611 // We are comparing pointers, but the pointers are relative to a single string.
5612 // Thus, this should always be deterministic.
5613 static int rewritesSort(const AsmRewrite *AsmRewriteA,
5614  const AsmRewrite *AsmRewriteB) {
5615  if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
5616  return -1;
5617  if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
5618  return 1;
5619 
5620  // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
5621  // rewrite to the same location. Make sure the SizeDirective rewrite is
5622  // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
5623  // ensures the sort algorithm is stable.
5624  if (AsmRewritePrecedence[AsmRewriteA->Kind] >
5625  AsmRewritePrecedence[AsmRewriteB->Kind])
5626  return -1;
5627 
5628  if (AsmRewritePrecedence[AsmRewriteA->Kind] <
5629  AsmRewritePrecedence[AsmRewriteB->Kind])
5630  return 1;
5631  llvm_unreachable("Unstable rewrite sort.");
5632 }
5633 
5634 bool AsmParser::parseMSInlineAsm(
5635  void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
5636  unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
5637  SmallVectorImpl<std::string> &Constraints,
5638  SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
5639  const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
5640  SmallVector<void *, 4> InputDecls;
5641  SmallVector<void *, 4> OutputDecls;
5642  SmallVector<bool, 4> InputDeclsAddressOf;
5643  SmallVector<bool, 4> OutputDeclsAddressOf;
5644  SmallVector<std::string, 4> InputConstraints;
5645  SmallVector<std::string, 4> OutputConstraints;
5646  SmallVector<unsigned, 4> ClobberRegs;
5647 
5648  SmallVector<AsmRewrite, 4> AsmStrRewrites;
5649 
5650  // Prime the lexer.
5651  Lex();
5652 
5653  // While we have input, parse each statement.
5654  unsigned InputIdx = 0;
5655  unsigned OutputIdx = 0;
5656  while (getLexer().isNot(AsmToken::Eof)) {
5657  // Parse curly braces marking block start/end
5658  if (parseCurlyBlockScope(AsmStrRewrites))
5659  continue;
5660 
5661  ParseStatementInfo Info(&AsmStrRewrites);
5662  bool StatementErr = parseStatement(Info, &SI);
5663 
5664  if (StatementErr || Info.ParseError) {
5665  // Emit pending errors if any exist.
5666  printPendingErrors();
5667  return true;
5668  }
5669 
5670  // No pending error should exist here.
5671  assert(!hasPendingError() && "unexpected error from parseStatement");
5672 
5673  if (Info.Opcode == ~0U)
5674  continue;
5675 
5676  const MCInstrDesc &Desc = MII->get(Info.Opcode);
5677 
5678  // Build the list of clobbers, outputs and inputs.
5679  for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
5680  MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
5681 
5682  // Immediate.
5683  if (Operand.isImm())
5684  continue;
5685 
5686  // Register operand.
5687  if (Operand.isReg() && !Operand.needAddressOf() &&
5688  !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
5689  unsigned NumDefs = Desc.getNumDefs();
5690  // Clobber.
5691  if (NumDefs && Operand.getMCOperandNum() < NumDefs)
5692  ClobberRegs.push_back(Operand.getReg());
5693  continue;
5694  }
5695 
5696  // Expr/Input or Output.
5697  StringRef SymName = Operand.getSymName();
5698  if (SymName.empty())
5699  continue;
5700 
5701  void *OpDecl = Operand.getOpDecl();
5702  if (!OpDecl)
5703  continue;
5704 
5705  bool isOutput = (i == 1) && Desc.mayStore();
5706  SMLoc Start = SMLoc::getFromPointer(SymName.data());
5707  if (isOutput) {
5708  ++InputIdx;
5709  OutputDecls.push_back(OpDecl);
5710  OutputDeclsAddressOf.push_back(Operand.needAddressOf());
5711  OutputConstraints.push_back(("=" + Operand.getConstraint()).str());
5712  AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
5713  } else {
5714  InputDecls.push_back(OpDecl);
5715  InputDeclsAddressOf.push_back(Operand.needAddressOf());
5716  InputConstraints.push_back(Operand.getConstraint().str());
5717  AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
5718  }
5719  }
5720 
5721  // Consider implicit defs to be clobbers. Think of cpuid and push.
5722  ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(),
5723  Desc.getNumImplicitDefs());
5724  ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end());
5725  }
5726 
5727  // Set the number of Outputs and Inputs.
5728  NumOutputs = OutputDecls.size();
5729  NumInputs = InputDecls.size();
5730 
5731  // Set the unique clobbers.
5732  array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
5733  ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
5734  ClobberRegs.end());
5735  Clobbers.assign(ClobberRegs.size(), std::string());
5736  for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
5737  raw_string_ostream OS(Clobbers[I]);
5738  IP->printRegName(OS, ClobberRegs[I]);
5739  }
5740 
5741  // Merge the various outputs and inputs. Output are expected first.
5742  if (NumOutputs || NumInputs) {
5743  unsigned NumExprs = NumOutputs + NumInputs;
5744  OpDecls.resize(NumExprs);
5745  Constraints.resize(NumExprs);
5746  for (unsigned i = 0; i < NumOutputs; ++i) {
5747  OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
5748  Constraints[i] = OutputConstraints[i];
5749  }
5750  for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
5751  OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
5752  Constraints[j] = InputConstraints[i];
5753  }
5754  }
5755 
5756  // Build the IR assembly string.
5757  std::string AsmStringIR;
5758  raw_string_ostream OS(AsmStringIR);
5759  StringRef ASMString =
5760  SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
5761  const char *AsmStart = ASMString.begin();
5762  const char *AsmEnd = ASMString.end();
5763  array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
5764  for (const AsmRewrite &AR : AsmStrRewrites) {
5765  AsmRewriteKind Kind = AR.Kind;
5766 
5767  const char *Loc = AR.Loc.getPointer();
5768  assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
5769 
5770  // Emit everything up to the immediate/expression.
5771  if (unsigned Len = Loc - AsmStart)
5772  OS << StringRef(AsmStart, Len);
5773 
5774  // Skip the original expression.
5775  if (Kind == AOK_Skip) {
5776  AsmStart = Loc + AR.Len;
5777  continue;
5778  }
5779 
5780  unsigned AdditionalSkip = 0;
5781  // Rewrite expressions in $N notation.
5782  switch (Kind) {
5783  default:
5784  break;
5785  case AOK_IntelExpr:
5786  assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
5787  if (AR.IntelExp.NeedBracs)
5788  OS << "[";
5789  if (AR.IntelExp.hasBaseReg())
5790  OS << AR.IntelExp.BaseReg;
5791  if (AR.IntelExp.hasIndexReg())
5792  OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
5793  << AR.IntelExp.IndexReg;
5794  if (AR.IntelExp.Scale > 1)
5795  OS << " * $$" << AR.IntelExp.Scale;
5796  if (AR.IntelExp.Imm || !AR.IntelExp.hasRegs())
5797  OS << (AR.IntelExp.hasRegs() ? " + $$" : "$$") << AR.IntelExp.Imm;
5798  if (AR.IntelExp.NeedBracs)
5799  OS << "]";
5800  break;
5801  case AOK_Label:
5802  OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
5803  break;
5804  case AOK_Input:
5805  OS << '$' << InputIdx++;
5806  break;
5807  case AOK_Output:
5808  OS << '$' << OutputIdx++;
5809  break;
5810  case AOK_SizeDirective:
5811  switch (AR.Val) {
5812  default: break;
5813  case 8: OS << "byte ptr "; break;
5814  case 16: OS << "word ptr "; break;
5815  case 32: OS << "dword ptr "; break;
5816  case 64: OS << "qword ptr "; break;
5817  case 80: OS << "xword ptr "; break;
5818  case 128: OS << "xmmword ptr "; break;
5819  case 256: OS << "ymmword ptr "; break;
5820  }
5821  break;
5822  case AOK_Emit:
5823  OS << ".byte";
5824  break;
5825  case AOK_Align: {
5826  // MS alignment directives are measured in bytes. If the native assembler
5827  // measures alignment in bytes, we can pass it straight through.
5828  OS << ".align";
5829  if (getContext().getAsmInfo()->getAlignmentIsInBytes())
5830  break;
5831 
5832  // Alignment is in log2 form, so print that instead and skip the original
5833  // immediate.
5834  unsigned Val = AR.Val;
5835  OS << ' ' << Val;
5836  assert(Val < 10 && "Expected alignment less then 2^10.");
5837  AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
5838  break;
5839  }
5840  case AOK_EVEN:
5841  OS << ".even";
5842  break;
5843  case AOK_EndOfStatement:
5844  OS << "\n\t";
5845  break;
5846  }
5847 
5848  // Skip the original expression.
5849  AsmStart = Loc + AR.Len + AdditionalSkip;
5850  }
5851 
5852  // Emit the remainder of the asm string.
5853  if (AsmStart != AsmEnd)
5854  OS << StringRef(AsmStart, AsmEnd - AsmStart);
5855 
5856  AsmString = OS.str();
5857  return false;
5858 }
5859 
5860 namespace llvm {
5861 namespace MCParserUtils {
5862 
5863 /// Returns whether the given symbol is used anywhere in the given expression,
5864 /// or subexpressions.
5865 static bool isSymbolUsedInExpression(const MCSymbol *Sym, const MCExpr *Value) {
5866  switch (Value->getKind()) {
5867  case MCExpr::Binary: {
5868  const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value);
5869  return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
5870  isSymbolUsedInExpression(Sym, BE->getRHS());
5871  }
5872  case MCExpr::Target:
5873  case MCExpr::Constant:
5874  return false;
5875  case MCExpr::SymbolRef: {
5876  const MCSymbol &S =
5877  static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
5878  if (S.isVariable())
5879  return isSymbolUsedInExpression(Sym, S.getVariableValue());
5880  return &S == Sym;
5881  }
5882  case MCExpr::Unary:
5883  return isSymbolUsedInExpression(
5884  Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr());
5885  }
5886 
5887  llvm_unreachable("Unknown expr kind!");
5888 }
5889 
5890 bool parseAssignmentExpression(StringRef Name, bool allow_redef,
5891  MCAsmParser &Parser, MCSymbol *&Sym,
5892  const MCExpr *&Value) {
5893 
5894  // FIXME: Use better location, we should use proper tokens.
5895  SMLoc EqualLoc = Parser.getTok().getLoc();
5896  if (Parser.parseExpression(Value))
5897  return Parser.TokError("missing expression");
5898 
5899  // Note: we don't count b as used in "a = b". This is to allow
5900  // a = b
5901  // b = c
5902 
5904  return true;
5905 
5906  // Validate that the LHS is allowed to be a variable (either it has not been
5907  // used as a symbol, or it is an absolute symbol).
5908  Sym = Parser.getContext().lookupSymbol(Name);
5909  if (Sym) {
5910  // Diagnose assignment to a label.
5911  //
5912  // FIXME: Diagnostics. Note the location of the definition as a label.
5913  // FIXME: Diagnose assignment to protected identifier (e.g., register name).
5914  if (isSymbolUsedInExpression(Sym, Value))
5915  return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
5916  else if (Sym->isUndefined(/*SetUsed*/ false) && !Sym->isUsed() &&
5917  !Sym->isVariable())
5918  ; // Allow redefinitions of undefined symbols only used in directives.
5919  else if (Sym->isVariable() && !Sym->isUsed() && allow_redef)
5920  ; // Allow redefinitions of variables that haven't yet been used.
5921  else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
5922  return Parser.Error(EqualLoc, "redefinition of '" + Name + "'");
5923  else if (!Sym->isVariable())
5924  return Parser.Error(EqualLoc, "invalid assignment to '" + Name + "'");
5925  else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
5926  return Parser.Error(EqualLoc,
5927  "invalid reassignment of non-absolute variable '" +
5928  Name + "'");
5929  } else if (Name == ".") {
5930  Parser.getStreamer().emitValueToOffset(Value, 0, EqualLoc);
5931  return false;
5932  } else
5933  Sym = Parser.getContext().getOrCreateSymbol(Name);
5934 
5935  Sym->setRedefinable(allow_redef);
5936 
5937  return false;
5938 }
5939 
5940 } // end namespace MCParserUtils
5941 } // end namespace llvm
5942 
5943 /// Create an MCAsmParser instance.
5945  MCStreamer &Out, const MCAsmInfo &MAI,
5946  unsigned CB) {
5947  return new AsmParser(SM, C, Out, MAI, CB);
5948 }
static const MCUnaryExpr * createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:381
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:428
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:591
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:84
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
StringRef getBuffer() const
Definition: MemoryBuffer.h:63
MCSymbol * lookupSymbol(const Twine &Name) const
Get the symbol for Name, or null.