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