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