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