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