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