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