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