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