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