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 // Reserve space to ensure Alignment doesn't get invalidated when 4149 // StructInProgress grows. 4150 StructInProgress.reserve(StructInProgress.size() + 1); 4151 StructInProgress.emplace_back(Name, DirKind == DK_UNION, 4152 StructInProgress.back().Alignment); 4153 return false; 4154 } 4155 4156 bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) { 4157 if (StructInProgress.empty()) 4158 return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION"); 4159 if (StructInProgress.size() > 1) 4160 return Error(NameLoc, "unexpected name in nested ENDS directive"); 4161 if (StructInProgress.back().Name.compare_lower(Name)) 4162 return Error(NameLoc, "mismatched name in ENDS directive; expected '" + 4163 StructInProgress.back().Name + "'"); 4164 StructInfo Structure = StructInProgress.pop_back_val(); 4165 // Pad to make the structure's size divisible by the smaller of its alignment 4166 // and the size of its largest field. 4167 Structure.Size = llvm::alignTo( 4168 Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize)); 4169 Structs[Name.lower()] = Structure; 4170 4171 if (parseToken(AsmToken::EndOfStatement)) 4172 return addErrorSuffix(" in ENDS directive"); 4173 4174 return false; 4175 } 4176 4177 bool MasmParser::parseDirectiveNestedEnds() { 4178 if (StructInProgress.empty()) 4179 return TokError("ENDS directive without matching STRUC/STRUCT/UNION"); 4180 if (StructInProgress.size() == 1) 4181 return TokError("missing name in top-level ENDS directive"); 4182 4183 if (parseToken(AsmToken::EndOfStatement)) 4184 return addErrorSuffix(" in nested ENDS directive"); 4185 4186 StructInfo Structure = StructInProgress.pop_back_val(); 4187 // Pad to make the structure's size divisible by its alignment. 4188 Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment); 4189 4190 StructInfo &ParentStruct = StructInProgress.back(); 4191 if (Structure.Name.empty()) { 4192 const size_t OldFields = ParentStruct.Fields.size(); 4193 ParentStruct.Fields.insert( 4194 ParentStruct.Fields.end(), 4195 std::make_move_iterator(Structure.Fields.begin()), 4196 std::make_move_iterator(Structure.Fields.end())); 4197 for (const auto &FieldByName : Structure.FieldsByName) { 4198 ParentStruct.FieldsByName[FieldByName.getKey()] = 4199 FieldByName.getValue() + OldFields; 4200 } 4201 if (!ParentStruct.IsUnion) { 4202 for (auto FieldIter = ParentStruct.Fields.begin() + OldFields; 4203 FieldIter != ParentStruct.Fields.end(); ++FieldIter) { 4204 FieldIter->Offset += ParentStruct.Size; 4205 } 4206 } 4207 4208 if (ParentStruct.IsUnion) 4209 ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size); 4210 else 4211 ParentStruct.Size += Structure.Size; 4212 } else { 4213 FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT, 4214 Structure.AlignmentSize); 4215 StructFieldInfo &StructInfo = Field.Contents.StructInfo; 4216 Field.Type = Structure.Size; 4217 Field.LengthOf = 1; 4218 Field.SizeOf = Structure.Size; 4219 4220 if (ParentStruct.IsUnion) 4221 ParentStruct.Size = std::max(ParentStruct.Size, Field.SizeOf); 4222 else 4223 ParentStruct.Size += Field.SizeOf; 4224 4225 StructInfo.Structure = Structure; 4226 StructInfo.Initializers.emplace_back(); 4227 auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers; 4228 for (const auto &SubField : Structure.Fields) { 4229 FieldInitializers.push_back(SubField.Contents); 4230 } 4231 } 4232 4233 return false; 4234 } 4235 4236 /// parseDirectiveOrg 4237 /// ::= .org expression [ , expression ] 4238 bool MasmParser::parseDirectiveOrg() { 4239 const MCExpr *Offset; 4240 SMLoc OffsetLoc = Lexer.getLoc(); 4241 if (checkForValidSection() || parseExpression(Offset)) 4242 return true; 4243 4244 // Parse optional fill expression. 4245 int64_t FillExpr = 0; 4246 if (parseOptionalToken(AsmToken::Comma)) 4247 if (parseAbsoluteExpression(FillExpr)) 4248 return addErrorSuffix(" in '.org' directive"); 4249 if (parseToken(AsmToken::EndOfStatement)) 4250 return addErrorSuffix(" in '.org' directive"); 4251 4252 getStreamer().emitValueToOffset(Offset, FillExpr, OffsetLoc); 4253 return false; 4254 } 4255 4256 /// parseDirectiveAlign 4257 /// ::= align expression 4258 bool MasmParser::parseDirectiveAlign() { 4259 SMLoc AlignmentLoc = getLexer().getLoc(); 4260 int64_t Alignment; 4261 4262 if (checkForValidSection()) 4263 return addErrorSuffix(" in align directive"); 4264 // Ignore empty 'align' directives. 4265 if (getTok().is(AsmToken::EndOfStatement)) { 4266 Warning(AlignmentLoc, "align directive with no operand is ignored"); 4267 return parseToken(AsmToken::EndOfStatement); 4268 } 4269 if (parseAbsoluteExpression(Alignment) || 4270 parseToken(AsmToken::EndOfStatement)) 4271 return addErrorSuffix(" in align directive"); 4272 4273 // Always emit an alignment here even if we thrown an error. 4274 bool ReturnVal = false; 4275 4276 // Reject alignments that aren't either a power of two or zero, for gas 4277 // compatibility. Alignment of zero is silently rounded up to one. 4278 if (Alignment == 0) 4279 Alignment = 1; 4280 if (!isPowerOf2_64(Alignment)) 4281 ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2"); 4282 4283 // Check whether we should use optimal code alignment for this align 4284 // directive. 4285 const MCSection *Section = getStreamer().getCurrentSectionOnly(); 4286 assert(Section && "must have section to emit alignment"); 4287 if (Section->UseCodeAlign()) { 4288 getStreamer().emitCodeAlignment(Alignment, /*MaxBytesToEmit=*/0); 4289 } else { 4290 // FIXME: Target specific behavior about how the "extra" bytes are filled. 4291 getStreamer().emitValueToAlignment(Alignment, /*Value=*/0, /*ValueSize=*/1, 4292 /*MaxBytesToEmit=*/0); 4293 } 4294 4295 return ReturnVal; 4296 } 4297 4298 /// parseDirectiveFile 4299 /// ::= .file filename 4300 /// ::= .file number [directory] filename [md5 checksum] [source source-text] 4301 bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) { 4302 // FIXME: I'm not sure what this is. 4303 int64_t FileNumber = -1; 4304 if (getLexer().is(AsmToken::Integer)) { 4305 FileNumber = getTok().getIntVal(); 4306 Lex(); 4307 4308 if (FileNumber < 0) 4309 return TokError("negative file number"); 4310 } 4311 4312 std::string Path; 4313 4314 // Usually the directory and filename together, otherwise just the directory. 4315 // Allow the strings to have escaped octal character sequence. 4316 if (check(getTok().isNot(AsmToken::String), 4317 "unexpected token in '.file' directive") || 4318 parseEscapedString(Path)) 4319 return true; 4320 4321 StringRef Directory; 4322 StringRef Filename; 4323 std::string FilenameData; 4324 if (getLexer().is(AsmToken::String)) { 4325 if (check(FileNumber == -1, 4326 "explicit path specified, but no file number") || 4327 parseEscapedString(FilenameData)) 4328 return true; 4329 Filename = FilenameData; 4330 Directory = Path; 4331 } else { 4332 Filename = Path; 4333 } 4334 4335 uint64_t MD5Hi, MD5Lo; 4336 bool HasMD5 = false; 4337 4338 Optional<StringRef> Source; 4339 bool HasSource = false; 4340 std::string SourceString; 4341 4342 while (!parseOptionalToken(AsmToken::EndOfStatement)) { 4343 StringRef Keyword; 4344 if (check(getTok().isNot(AsmToken::Identifier), 4345 "unexpected token in '.file' directive") || 4346 parseIdentifier(Keyword)) 4347 return true; 4348 if (Keyword == "md5") { 4349 HasMD5 = true; 4350 if (check(FileNumber == -1, 4351 "MD5 checksum specified, but no file number") || 4352 parseHexOcta(*this, MD5Hi, MD5Lo)) 4353 return true; 4354 } else if (Keyword == "source") { 4355 HasSource = true; 4356 if (check(FileNumber == -1, 4357 "source specified, but no file number") || 4358 check(getTok().isNot(AsmToken::String), 4359 "unexpected token in '.file' directive") || 4360 parseEscapedString(SourceString)) 4361 return true; 4362 } else { 4363 return TokError("unexpected token in '.file' directive"); 4364 } 4365 } 4366 4367 if (FileNumber == -1) { 4368 // Ignore the directive if there is no number and the target doesn't support 4369 // numberless .file directives. This allows some portability of assembler 4370 // between different object file formats. 4371 if (getContext().getAsmInfo()->hasSingleParameterDotFile()) 4372 getStreamer().emitFileDirective(Filename); 4373 } else { 4374 // In case there is a -g option as well as debug info from directive .file, 4375 // we turn off the -g option, directly use the existing debug info instead. 4376 // Throw away any implicit file table for the assembler source. 4377 if (Ctx.getGenDwarfForAssembly()) { 4378 Ctx.getMCDwarfLineTable(0).resetFileTable(); 4379 Ctx.setGenDwarfForAssembly(false); 4380 } 4381 4382 Optional<MD5::MD5Result> CKMem; 4383 if (HasMD5) { 4384 MD5::MD5Result Sum; 4385 for (unsigned i = 0; i != 8; ++i) { 4386 Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); 4387 Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); 4388 } 4389 CKMem = Sum; 4390 } 4391 if (HasSource) { 4392 char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size())); 4393 memcpy(SourceBuf, SourceString.data(), SourceString.size()); 4394 Source = StringRef(SourceBuf, SourceString.size()); 4395 } 4396 if (FileNumber == 0) { 4397 if (Ctx.getDwarfVersion() < 5) 4398 return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5"); 4399 getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source); 4400 } else { 4401 Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective( 4402 FileNumber, Directory, Filename, CKMem, Source); 4403 if (!FileNumOrErr) 4404 return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); 4405 } 4406 // Alert the user if there are some .file directives with MD5 and some not. 4407 // But only do that once. 4408 if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) { 4409 ReportedInconsistentMD5 = true; 4410 return Warning(DirectiveLoc, "inconsistent use of MD5 checksums"); 4411 } 4412 } 4413 4414 return false; 4415 } 4416 4417 /// parseDirectiveLine 4418 /// ::= .line [number] 4419 bool MasmParser::parseDirectiveLine() { 4420 int64_t LineNumber; 4421 if (getLexer().is(AsmToken::Integer)) { 4422 if (parseIntToken(LineNumber, "unexpected token in '.line' directive")) 4423 return true; 4424 (void)LineNumber; 4425 // FIXME: Do something with the .line. 4426 } 4427 if (parseToken(AsmToken::EndOfStatement, 4428 "unexpected token in '.line' directive")) 4429 return true; 4430 4431 return false; 4432 } 4433 4434 /// parseDirectiveLoc 4435 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 4436 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 4437 /// The first number is a file number, must have been previously assigned with 4438 /// a .file directive, the second number is the line number and optionally the 4439 /// third number is a column position (zero if not specified). The remaining 4440 /// optional items are .loc sub-directives. 4441 bool MasmParser::parseDirectiveLoc() { 4442 int64_t FileNumber = 0, LineNumber = 0; 4443 SMLoc Loc = getTok().getLoc(); 4444 if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") || 4445 check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc, 4446 "file number less than one in '.loc' directive") || 4447 check(!getContext().isValidDwarfFileNumber(FileNumber), Loc, 4448 "unassigned file number in '.loc' directive")) 4449 return true; 4450 4451 // optional 4452 if (getLexer().is(AsmToken::Integer)) { 4453 LineNumber = getTok().getIntVal(); 4454 if (LineNumber < 0) 4455 return TokError("line number less than zero in '.loc' directive"); 4456 Lex(); 4457 } 4458 4459 int64_t ColumnPos = 0; 4460 if (getLexer().is(AsmToken::Integer)) { 4461 ColumnPos = getTok().getIntVal(); 4462 if (ColumnPos < 0) 4463 return TokError("column position less than zero in '.loc' directive"); 4464 Lex(); 4465 } 4466 4467 auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags(); 4468 unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT; 4469 unsigned Isa = 0; 4470 int64_t Discriminator = 0; 4471 4472 auto parseLocOp = [&]() -> bool { 4473 StringRef Name; 4474 SMLoc Loc = getTok().getLoc(); 4475 if (parseIdentifier(Name)) 4476 return TokError("unexpected token in '.loc' directive"); 4477 4478 if (Name == "basic_block") 4479 Flags |= DWARF2_FLAG_BASIC_BLOCK; 4480 else if (Name == "prologue_end") 4481 Flags |= DWARF2_FLAG_PROLOGUE_END; 4482 else if (Name == "epilogue_begin") 4483 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 4484 else if (Name == "is_stmt") { 4485 Loc = getTok().getLoc(); 4486 const MCExpr *Value; 4487 if (parseExpression(Value)) 4488 return true; 4489 // The expression must be the constant 0 or 1. 4490 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 4491 int Value = MCE->getValue(); 4492 if (Value == 0) 4493 Flags &= ~DWARF2_FLAG_IS_STMT; 4494 else if (Value == 1) 4495 Flags |= DWARF2_FLAG_IS_STMT; 4496 else 4497 return Error(Loc, "is_stmt value not 0 or 1"); 4498 } else { 4499 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 4500 } 4501 } else if (Name == "isa") { 4502 Loc = getTok().getLoc(); 4503 const MCExpr *Value; 4504 if (parseExpression(Value)) 4505 return true; 4506 // The expression must be a constant greater or equal to 0. 4507 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 4508 int Value = MCE->getValue(); 4509 if (Value < 0) 4510 return Error(Loc, "isa number less than zero"); 4511 Isa = Value; 4512 } else { 4513 return Error(Loc, "isa number not a constant value"); 4514 } 4515 } else if (Name == "discriminator") { 4516 if (parseAbsoluteExpression(Discriminator)) 4517 return true; 4518 } else { 4519 return Error(Loc, "unknown sub-directive in '.loc' directive"); 4520 } 4521 return false; 4522 }; 4523 4524 if (parseMany(parseLocOp, false /*hasComma*/)) 4525 return true; 4526 4527 getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 4528 Isa, Discriminator, StringRef()); 4529 4530 return false; 4531 } 4532 4533 /// parseDirectiveStabs 4534 /// ::= .stabs string, number, number, number 4535 bool MasmParser::parseDirectiveStabs() { 4536 return TokError("unsupported directive '.stabs'"); 4537 } 4538 4539 /// parseDirectiveCVFile 4540 /// ::= .cv_file number filename [checksum] [checksumkind] 4541 bool MasmParser::parseDirectiveCVFile() { 4542 SMLoc FileNumberLoc = getTok().getLoc(); 4543 int64_t FileNumber; 4544 std::string Filename; 4545 std::string Checksum; 4546 int64_t ChecksumKind = 0; 4547 4548 if (parseIntToken(FileNumber, 4549 "expected file number in '.cv_file' directive") || 4550 check(FileNumber < 1, FileNumberLoc, "file number less than one") || 4551 check(getTok().isNot(AsmToken::String), 4552 "unexpected token in '.cv_file' directive") || 4553 parseEscapedString(Filename)) 4554 return true; 4555 if (!parseOptionalToken(AsmToken::EndOfStatement)) { 4556 if (check(getTok().isNot(AsmToken::String), 4557 "unexpected token in '.cv_file' directive") || 4558 parseEscapedString(Checksum) || 4559 parseIntToken(ChecksumKind, 4560 "expected checksum kind in '.cv_file' directive") || 4561 parseToken(AsmToken::EndOfStatement, 4562 "unexpected token in '.cv_file' directive")) 4563 return true; 4564 } 4565 4566 Checksum = fromHex(Checksum); 4567 void *CKMem = Ctx.allocate(Checksum.size(), 1); 4568 memcpy(CKMem, Checksum.data(), Checksum.size()); 4569 ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem), 4570 Checksum.size()); 4571 4572 if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, ChecksumAsBytes, 4573 static_cast<uint8_t>(ChecksumKind))) 4574 return Error(FileNumberLoc, "file number already allocated"); 4575 4576 return false; 4577 } 4578 4579 bool MasmParser::parseCVFunctionId(int64_t &FunctionId, 4580 StringRef DirectiveName) { 4581 SMLoc Loc; 4582 return parseTokenLoc(Loc) || 4583 parseIntToken(FunctionId, "expected function id in '" + DirectiveName + 4584 "' directive") || 4585 check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc, 4586 "expected function id within range [0, UINT_MAX)"); 4587 } 4588 4589 bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) { 4590 SMLoc Loc; 4591 return parseTokenLoc(Loc) || 4592 parseIntToken(FileNumber, "expected integer in '" + DirectiveName + 4593 "' directive") || 4594 check(FileNumber < 1, Loc, "file number less than one in '" + 4595 DirectiveName + "' directive") || 4596 check(!getCVContext().isValidFileNumber(FileNumber), Loc, 4597 "unassigned file number in '" + DirectiveName + "' directive"); 4598 } 4599 4600 /// parseDirectiveCVFuncId 4601 /// ::= .cv_func_id FunctionId 4602 /// 4603 /// Introduces a function ID that can be used with .cv_loc. 4604 bool MasmParser::parseDirectiveCVFuncId() { 4605 SMLoc FunctionIdLoc = getTok().getLoc(); 4606 int64_t FunctionId; 4607 4608 if (parseCVFunctionId(FunctionId, ".cv_func_id") || 4609 parseToken(AsmToken::EndOfStatement, 4610 "unexpected token in '.cv_func_id' directive")) 4611 return true; 4612 4613 if (!getStreamer().EmitCVFuncIdDirective(FunctionId)) 4614 return Error(FunctionIdLoc, "function id already allocated"); 4615 4616 return false; 4617 } 4618 4619 /// parseDirectiveCVInlineSiteId 4620 /// ::= .cv_inline_site_id FunctionId 4621 /// "within" IAFunc 4622 /// "inlined_at" IAFile IALine [IACol] 4623 /// 4624 /// Introduces a function ID that can be used with .cv_loc. Includes "inlined 4625 /// at" source location information for use in the line table of the caller, 4626 /// whether the caller is a real function or another inlined call site. 4627 bool MasmParser::parseDirectiveCVInlineSiteId() { 4628 SMLoc FunctionIdLoc = getTok().getLoc(); 4629 int64_t FunctionId; 4630 int64_t IAFunc; 4631 int64_t IAFile; 4632 int64_t IALine; 4633 int64_t IACol = 0; 4634 4635 // FunctionId 4636 if (parseCVFunctionId(FunctionId, ".cv_inline_site_id")) 4637 return true; 4638 4639 // "within" 4640 if (check((getLexer().isNot(AsmToken::Identifier) || 4641 getTok().getIdentifier() != "within"), 4642 "expected 'within' identifier in '.cv_inline_site_id' directive")) 4643 return true; 4644 Lex(); 4645 4646 // IAFunc 4647 if (parseCVFunctionId(IAFunc, ".cv_inline_site_id")) 4648 return true; 4649 4650 // "inlined_at" 4651 if (check((getLexer().isNot(AsmToken::Identifier) || 4652 getTok().getIdentifier() != "inlined_at"), 4653 "expected 'inlined_at' identifier in '.cv_inline_site_id' " 4654 "directive") ) 4655 return true; 4656 Lex(); 4657 4658 // IAFile IALine 4659 if (parseCVFileId(IAFile, ".cv_inline_site_id") || 4660 parseIntToken(IALine, "expected line number after 'inlined_at'")) 4661 return true; 4662 4663 // [IACol] 4664 if (getLexer().is(AsmToken::Integer)) { 4665 IACol = getTok().getIntVal(); 4666 Lex(); 4667 } 4668 4669 if (parseToken(AsmToken::EndOfStatement, 4670 "unexpected token in '.cv_inline_site_id' directive")) 4671 return true; 4672 4673 if (!getStreamer().EmitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile, 4674 IALine, IACol, FunctionIdLoc)) 4675 return Error(FunctionIdLoc, "function id already allocated"); 4676 4677 return false; 4678 } 4679 4680 /// parseDirectiveCVLoc 4681 /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end] 4682 /// [is_stmt VALUE] 4683 /// The first number is a file number, must have been previously assigned with 4684 /// a .file directive, the second number is the line number and optionally the 4685 /// third number is a column position (zero if not specified). The remaining 4686 /// optional items are .loc sub-directives. 4687 bool MasmParser::parseDirectiveCVLoc() { 4688 SMLoc DirectiveLoc = getTok().getLoc(); 4689 int64_t FunctionId, FileNumber; 4690 if (parseCVFunctionId(FunctionId, ".cv_loc") || 4691 parseCVFileId(FileNumber, ".cv_loc")) 4692 return true; 4693 4694 int64_t LineNumber = 0; 4695 if (getLexer().is(AsmToken::Integer)) { 4696 LineNumber = getTok().getIntVal(); 4697 if (LineNumber < 0) 4698 return TokError("line number less than zero in '.cv_loc' directive"); 4699 Lex(); 4700 } 4701 4702 int64_t ColumnPos = 0; 4703 if (getLexer().is(AsmToken::Integer)) { 4704 ColumnPos = getTok().getIntVal(); 4705 if (ColumnPos < 0) 4706 return TokError("column position less than zero in '.cv_loc' directive"); 4707 Lex(); 4708 } 4709 4710 bool PrologueEnd = false; 4711 uint64_t IsStmt = 0; 4712 4713 auto parseOp = [&]() -> bool { 4714 StringRef Name; 4715 SMLoc Loc = getTok().getLoc(); 4716 if (parseIdentifier(Name)) 4717 return TokError("unexpected token in '.cv_loc' directive"); 4718 if (Name == "prologue_end") 4719 PrologueEnd = true; 4720 else if (Name == "is_stmt") { 4721 Loc = getTok().getLoc(); 4722 const MCExpr *Value; 4723 if (parseExpression(Value)) 4724 return true; 4725 // The expression must be the constant 0 or 1. 4726 IsStmt = ~0ULL; 4727 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) 4728 IsStmt = MCE->getValue(); 4729 4730 if (IsStmt > 1) 4731 return Error(Loc, "is_stmt value not 0 or 1"); 4732 } else { 4733 return Error(Loc, "unknown sub-directive in '.cv_loc' directive"); 4734 } 4735 return false; 4736 }; 4737 4738 if (parseMany(parseOp, false /*hasComma*/)) 4739 return true; 4740 4741 getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber, 4742 ColumnPos, PrologueEnd, IsStmt, StringRef(), 4743 DirectiveLoc); 4744 return false; 4745 } 4746 4747 /// parseDirectiveCVLinetable 4748 /// ::= .cv_linetable FunctionId, FnStart, FnEnd 4749 bool MasmParser::parseDirectiveCVLinetable() { 4750 int64_t FunctionId; 4751 StringRef FnStartName, FnEndName; 4752 SMLoc Loc = getTok().getLoc(); 4753 if (parseCVFunctionId(FunctionId, ".cv_linetable") || 4754 parseToken(AsmToken::Comma, 4755 "unexpected token in '.cv_linetable' directive") || 4756 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc, 4757 "expected identifier in directive") || 4758 parseToken(AsmToken::Comma, 4759 "unexpected token in '.cv_linetable' directive") || 4760 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc, 4761 "expected identifier in directive")) 4762 return true; 4763 4764 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); 4765 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); 4766 4767 getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym); 4768 return false; 4769 } 4770 4771 /// parseDirectiveCVInlineLinetable 4772 /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd 4773 bool MasmParser::parseDirectiveCVInlineLinetable() { 4774 int64_t PrimaryFunctionId, SourceFileId, SourceLineNum; 4775 StringRef FnStartName, FnEndName; 4776 SMLoc Loc = getTok().getLoc(); 4777 if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") || 4778 parseTokenLoc(Loc) || 4779 parseIntToken( 4780 SourceFileId, 4781 "expected SourceField in '.cv_inline_linetable' directive") || 4782 check(SourceFileId <= 0, Loc, 4783 "File id less than zero in '.cv_inline_linetable' directive") || 4784 parseTokenLoc(Loc) || 4785 parseIntToken( 4786 SourceLineNum, 4787 "expected SourceLineNum in '.cv_inline_linetable' directive") || 4788 check(SourceLineNum < 0, Loc, 4789 "Line number less than zero in '.cv_inline_linetable' directive") || 4790 parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc, 4791 "expected identifier in directive") || 4792 parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc, 4793 "expected identifier in directive")) 4794 return true; 4795 4796 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement")) 4797 return true; 4798 4799 MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName); 4800 MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName); 4801 getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId, 4802 SourceLineNum, FnStartSym, 4803 FnEndSym); 4804 return false; 4805 } 4806 4807 void MasmParser::initializeCVDefRangeTypeMap() { 4808 CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER; 4809 CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL; 4810 CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER; 4811 CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL; 4812 } 4813 4814 /// parseDirectiveCVDefRange 4815 /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes* 4816 bool MasmParser::parseDirectiveCVDefRange() { 4817 SMLoc Loc; 4818 std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges; 4819 while (getLexer().is(AsmToken::Identifier)) { 4820 Loc = getLexer().getLoc(); 4821 StringRef GapStartName; 4822 if (parseIdentifier(GapStartName)) 4823 return Error(Loc, "expected identifier in directive"); 4824 MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName); 4825 4826 Loc = getLexer().getLoc(); 4827 StringRef GapEndName; 4828 if (parseIdentifier(GapEndName)) 4829 return Error(Loc, "expected identifier in directive"); 4830 MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName); 4831 4832 Ranges.push_back({GapStartSym, GapEndSym}); 4833 } 4834 4835 StringRef CVDefRangeTypeStr; 4836 if (parseToken( 4837 AsmToken::Comma, 4838 "expected comma before def_range type in .cv_def_range directive") || 4839 parseIdentifier(CVDefRangeTypeStr)) 4840 return Error(Loc, "expected def_range type in directive"); 4841 4842 StringMap<CVDefRangeType>::const_iterator CVTypeIt = 4843 CVDefRangeTypeMap.find(CVDefRangeTypeStr); 4844 CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end()) 4845 ? CVDR_DEFRANGE 4846 : CVTypeIt->getValue(); 4847 switch (CVDRType) { 4848 case CVDR_DEFRANGE_REGISTER: { 4849 int64_t DRRegister; 4850 if (parseToken(AsmToken::Comma, "expected comma before register number in " 4851 ".cv_def_range directive") || 4852 parseAbsoluteExpression(DRRegister)) 4853 return Error(Loc, "expected register number"); 4854 4855 codeview::DefRangeRegisterHeader DRHdr; 4856 DRHdr.Register = DRRegister; 4857 DRHdr.MayHaveNoName = 0; 4858 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 4859 break; 4860 } 4861 case CVDR_DEFRANGE_FRAMEPOINTER_REL: { 4862 int64_t DROffset; 4863 if (parseToken(AsmToken::Comma, 4864 "expected comma before offset in .cv_def_range directive") || 4865 parseAbsoluteExpression(DROffset)) 4866 return Error(Loc, "expected offset value"); 4867 4868 codeview::DefRangeFramePointerRelHeader DRHdr; 4869 DRHdr.Offset = DROffset; 4870 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 4871 break; 4872 } 4873 case CVDR_DEFRANGE_SUBFIELD_REGISTER: { 4874 int64_t DRRegister; 4875 int64_t DROffsetInParent; 4876 if (parseToken(AsmToken::Comma, "expected comma before register number in " 4877 ".cv_def_range directive") || 4878 parseAbsoluteExpression(DRRegister)) 4879 return Error(Loc, "expected register number"); 4880 if (parseToken(AsmToken::Comma, 4881 "expected comma before offset in .cv_def_range directive") || 4882 parseAbsoluteExpression(DROffsetInParent)) 4883 return Error(Loc, "expected offset value"); 4884 4885 codeview::DefRangeSubfieldRegisterHeader DRHdr; 4886 DRHdr.Register = DRRegister; 4887 DRHdr.MayHaveNoName = 0; 4888 DRHdr.OffsetInParent = DROffsetInParent; 4889 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 4890 break; 4891 } 4892 case CVDR_DEFRANGE_REGISTER_REL: { 4893 int64_t DRRegister; 4894 int64_t DRFlags; 4895 int64_t DRBasePointerOffset; 4896 if (parseToken(AsmToken::Comma, "expected comma before register number in " 4897 ".cv_def_range directive") || 4898 parseAbsoluteExpression(DRRegister)) 4899 return Error(Loc, "expected register value"); 4900 if (parseToken( 4901 AsmToken::Comma, 4902 "expected comma before flag value in .cv_def_range directive") || 4903 parseAbsoluteExpression(DRFlags)) 4904 return Error(Loc, "expected flag value"); 4905 if (parseToken(AsmToken::Comma, "expected comma before base pointer offset " 4906 "in .cv_def_range directive") || 4907 parseAbsoluteExpression(DRBasePointerOffset)) 4908 return Error(Loc, "expected base pointer offset value"); 4909 4910 codeview::DefRangeRegisterRelHeader DRHdr; 4911 DRHdr.Register = DRRegister; 4912 DRHdr.Flags = DRFlags; 4913 DRHdr.BasePointerOffset = DRBasePointerOffset; 4914 getStreamer().emitCVDefRangeDirective(Ranges, DRHdr); 4915 break; 4916 } 4917 default: 4918 return Error(Loc, "unexpected def_range type in .cv_def_range directive"); 4919 } 4920 return true; 4921 } 4922 4923 /// parseDirectiveCVString 4924 /// ::= .cv_stringtable "string" 4925 bool MasmParser::parseDirectiveCVString() { 4926 std::string Data; 4927 if (checkForValidSection() || parseEscapedString(Data)) 4928 return addErrorSuffix(" in '.cv_string' directive"); 4929 4930 // Put the string in the table and emit the offset. 4931 std::pair<StringRef, unsigned> Insertion = 4932 getCVContext().addToStringTable(Data); 4933 getStreamer().emitIntValue(Insertion.second, 4); 4934 return false; 4935 } 4936 4937 /// parseDirectiveCVStringTable 4938 /// ::= .cv_stringtable 4939 bool MasmParser::parseDirectiveCVStringTable() { 4940 getStreamer().emitCVStringTableDirective(); 4941 return false; 4942 } 4943 4944 /// parseDirectiveCVFileChecksums 4945 /// ::= .cv_filechecksums 4946 bool MasmParser::parseDirectiveCVFileChecksums() { 4947 getStreamer().emitCVFileChecksumsDirective(); 4948 return false; 4949 } 4950 4951 /// parseDirectiveCVFileChecksumOffset 4952 /// ::= .cv_filechecksumoffset fileno 4953 bool MasmParser::parseDirectiveCVFileChecksumOffset() { 4954 int64_t FileNo; 4955 if (parseIntToken(FileNo, "expected identifier in directive")) 4956 return true; 4957 if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement")) 4958 return true; 4959 getStreamer().emitCVFileChecksumOffsetDirective(FileNo); 4960 return false; 4961 } 4962 4963 /// parseDirectiveCVFPOData 4964 /// ::= .cv_fpo_data procsym 4965 bool MasmParser::parseDirectiveCVFPOData() { 4966 SMLoc DirLoc = getLexer().getLoc(); 4967 StringRef ProcName; 4968 if (parseIdentifier(ProcName)) 4969 return TokError("expected symbol name"); 4970 if (parseEOL("unexpected tokens")) 4971 return addErrorSuffix(" in '.cv_fpo_data' directive"); 4972 MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName); 4973 getStreamer().EmitCVFPOData(ProcSym, DirLoc); 4974 return false; 4975 } 4976 4977 /// parseDirectiveCFISections 4978 /// ::= .cfi_sections section [, section] 4979 bool MasmParser::parseDirectiveCFISections() { 4980 StringRef Name; 4981 bool EH = false; 4982 bool Debug = false; 4983 4984 if (parseIdentifier(Name)) 4985 return TokError("Expected an identifier"); 4986 4987 if (Name == ".eh_frame") 4988 EH = true; 4989 else if (Name == ".debug_frame") 4990 Debug = true; 4991 4992 if (getLexer().is(AsmToken::Comma)) { 4993 Lex(); 4994 4995 if (parseIdentifier(Name)) 4996 return TokError("Expected an identifier"); 4997 4998 if (Name == ".eh_frame") 4999 EH = true; 5000 else if (Name == ".debug_frame") 5001 Debug = true; 5002 } 5003 5004 getStreamer().emitCFISections(EH, Debug); 5005 return false; 5006 } 5007 5008 /// parseDirectiveCFIStartProc 5009 /// ::= .cfi_startproc [simple] 5010 bool MasmParser::parseDirectiveCFIStartProc() { 5011 StringRef Simple; 5012 if (!parseOptionalToken(AsmToken::EndOfStatement)) { 5013 if (check(parseIdentifier(Simple) || Simple != "simple", 5014 "unexpected token") || 5015 parseToken(AsmToken::EndOfStatement)) 5016 return addErrorSuffix(" in '.cfi_startproc' directive"); 5017 } 5018 5019 // TODO(kristina): Deal with a corner case of incorrect diagnostic context 5020 // being produced if this directive is emitted as part of preprocessor macro 5021 // expansion which can *ONLY* happen if Clang's cc1as is the API consumer. 5022 // Tools like llvm-mc on the other hand are not affected by it, and report 5023 // correct context information. 5024 getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc()); 5025 return false; 5026 } 5027 5028 /// parseDirectiveCFIEndProc 5029 /// ::= .cfi_endproc 5030 bool MasmParser::parseDirectiveCFIEndProc() { 5031 getStreamer().emitCFIEndProc(); 5032 return false; 5033 } 5034 5035 /// parse register name or number. 5036 bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register, 5037 SMLoc DirectiveLoc) { 5038 unsigned RegNo; 5039 5040 if (getLexer().isNot(AsmToken::Integer)) { 5041 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) 5042 return true; 5043 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); 5044 } else 5045 return parseAbsoluteExpression(Register); 5046 5047 return false; 5048 } 5049 5050 /// parseDirectiveCFIDefCfa 5051 /// ::= .cfi_def_cfa register, offset 5052 bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { 5053 int64_t Register = 0, Offset = 0; 5054 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5055 parseToken(AsmToken::Comma, "unexpected token in directive") || 5056 parseAbsoluteExpression(Offset)) 5057 return true; 5058 5059 getStreamer().emitCFIDefCfa(Register, Offset); 5060 return false; 5061 } 5062 5063 /// parseDirectiveCFIDefCfaOffset 5064 /// ::= .cfi_def_cfa_offset offset 5065 bool MasmParser::parseDirectiveCFIDefCfaOffset() { 5066 int64_t Offset = 0; 5067 if (parseAbsoluteExpression(Offset)) 5068 return true; 5069 5070 getStreamer().emitCFIDefCfaOffset(Offset); 5071 return false; 5072 } 5073 5074 /// parseDirectiveCFIRegister 5075 /// ::= .cfi_register register, register 5076 bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) { 5077 int64_t Register1 = 0, Register2 = 0; 5078 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) || 5079 parseToken(AsmToken::Comma, "unexpected token in directive") || 5080 parseRegisterOrRegisterNumber(Register2, DirectiveLoc)) 5081 return true; 5082 5083 getStreamer().emitCFIRegister(Register1, Register2); 5084 return false; 5085 } 5086 5087 /// parseDirectiveCFIWindowSave 5088 /// ::= .cfi_window_save 5089 bool MasmParser::parseDirectiveCFIWindowSave() { 5090 getStreamer().emitCFIWindowSave(); 5091 return false; 5092 } 5093 5094 /// parseDirectiveCFIAdjustCfaOffset 5095 /// ::= .cfi_adjust_cfa_offset adjustment 5096 bool MasmParser::parseDirectiveCFIAdjustCfaOffset() { 5097 int64_t Adjustment = 0; 5098 if (parseAbsoluteExpression(Adjustment)) 5099 return true; 5100 5101 getStreamer().emitCFIAdjustCfaOffset(Adjustment); 5102 return false; 5103 } 5104 5105 /// parseDirectiveCFIDefCfaRegister 5106 /// ::= .cfi_def_cfa_register register 5107 bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { 5108 int64_t Register = 0; 5109 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5110 return true; 5111 5112 getStreamer().emitCFIDefCfaRegister(Register); 5113 return false; 5114 } 5115 5116 /// parseDirectiveCFIOffset 5117 /// ::= .cfi_offset register, offset 5118 bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) { 5119 int64_t Register = 0; 5120 int64_t Offset = 0; 5121 5122 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5123 parseToken(AsmToken::Comma, "unexpected token in directive") || 5124 parseAbsoluteExpression(Offset)) 5125 return true; 5126 5127 getStreamer().emitCFIOffset(Register, Offset); 5128 return false; 5129 } 5130 5131 /// parseDirectiveCFIRelOffset 5132 /// ::= .cfi_rel_offset register, offset 5133 bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { 5134 int64_t Register = 0, Offset = 0; 5135 5136 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) || 5137 parseToken(AsmToken::Comma, "unexpected token in directive") || 5138 parseAbsoluteExpression(Offset)) 5139 return true; 5140 5141 getStreamer().emitCFIRelOffset(Register, Offset); 5142 return false; 5143 } 5144 5145 static bool isValidEncoding(int64_t Encoding) { 5146 if (Encoding & ~0xff) 5147 return false; 5148 5149 if (Encoding == dwarf::DW_EH_PE_omit) 5150 return true; 5151 5152 const unsigned Format = Encoding & 0xf; 5153 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 5154 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 5155 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 5156 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 5157 return false; 5158 5159 const unsigned Application = Encoding & 0x70; 5160 if (Application != dwarf::DW_EH_PE_absptr && 5161 Application != dwarf::DW_EH_PE_pcrel) 5162 return false; 5163 5164 return true; 5165 } 5166 5167 /// parseDirectiveCFIPersonalityOrLsda 5168 /// IsPersonality true for cfi_personality, false for cfi_lsda 5169 /// ::= .cfi_personality encoding, [symbol_name] 5170 /// ::= .cfi_lsda encoding, [symbol_name] 5171 bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { 5172 int64_t Encoding = 0; 5173 if (parseAbsoluteExpression(Encoding)) 5174 return true; 5175 if (Encoding == dwarf::DW_EH_PE_omit) 5176 return false; 5177 5178 StringRef Name; 5179 if (check(!isValidEncoding(Encoding), "unsupported encoding.") || 5180 parseToken(AsmToken::Comma, "unexpected token in directive") || 5181 check(parseIdentifier(Name), "expected identifier in directive")) 5182 return true; 5183 5184 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5185 5186 if (IsPersonality) 5187 getStreamer().emitCFIPersonality(Sym, Encoding); 5188 else 5189 getStreamer().emitCFILsda(Sym, Encoding); 5190 return false; 5191 } 5192 5193 /// parseDirectiveCFIRememberState 5194 /// ::= .cfi_remember_state 5195 bool MasmParser::parseDirectiveCFIRememberState() { 5196 getStreamer().emitCFIRememberState(); 5197 return false; 5198 } 5199 5200 /// parseDirectiveCFIRestoreState 5201 /// ::= .cfi_remember_state 5202 bool MasmParser::parseDirectiveCFIRestoreState() { 5203 getStreamer().emitCFIRestoreState(); 5204 return false; 5205 } 5206 5207 /// parseDirectiveCFISameValue 5208 /// ::= .cfi_same_value register 5209 bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) { 5210 int64_t Register = 0; 5211 5212 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5213 return true; 5214 5215 getStreamer().emitCFISameValue(Register); 5216 return false; 5217 } 5218 5219 /// parseDirectiveCFIRestore 5220 /// ::= .cfi_restore register 5221 bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) { 5222 int64_t Register = 0; 5223 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5224 return true; 5225 5226 getStreamer().emitCFIRestore(Register); 5227 return false; 5228 } 5229 5230 /// parseDirectiveCFIEscape 5231 /// ::= .cfi_escape expression[,...] 5232 bool MasmParser::parseDirectiveCFIEscape() { 5233 std::string Values; 5234 int64_t CurrValue; 5235 if (parseAbsoluteExpression(CurrValue)) 5236 return true; 5237 5238 Values.push_back((uint8_t)CurrValue); 5239 5240 while (getLexer().is(AsmToken::Comma)) { 5241 Lex(); 5242 5243 if (parseAbsoluteExpression(CurrValue)) 5244 return true; 5245 5246 Values.push_back((uint8_t)CurrValue); 5247 } 5248 5249 getStreamer().emitCFIEscape(Values); 5250 return false; 5251 } 5252 5253 /// parseDirectiveCFIReturnColumn 5254 /// ::= .cfi_return_column register 5255 bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) { 5256 int64_t Register = 0; 5257 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5258 return true; 5259 getStreamer().emitCFIReturnColumn(Register); 5260 return false; 5261 } 5262 5263 /// parseDirectiveCFISignalFrame 5264 /// ::= .cfi_signal_frame 5265 bool MasmParser::parseDirectiveCFISignalFrame() { 5266 if (parseToken(AsmToken::EndOfStatement, 5267 "unexpected token in '.cfi_signal_frame'")) 5268 return true; 5269 5270 getStreamer().emitCFISignalFrame(); 5271 return false; 5272 } 5273 5274 /// parseDirectiveCFIUndefined 5275 /// ::= .cfi_undefined register 5276 bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { 5277 int64_t Register = 0; 5278 5279 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 5280 return true; 5281 5282 getStreamer().emitCFIUndefined(Register); 5283 return false; 5284 } 5285 5286 /// parseDirectiveMacro 5287 /// ::= name macro [parameters] 5288 /// ["LOCAL" identifiers] 5289 /// parameters ::= parameter [, parameter]* 5290 /// parameter ::= name ":" qualifier 5291 /// qualifier ::= "req" | "vararg" | "=" macro_argument 5292 bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) { 5293 MCAsmMacroParameters Parameters; 5294 while (getLexer().isNot(AsmToken::EndOfStatement)) { 5295 if (!Parameters.empty() && Parameters.back().Vararg) 5296 return Error(Lexer.getLoc(), 5297 "Vararg parameter '" + Parameters.back().Name + 5298 "' should be last in the list of parameters"); 5299 5300 MCAsmMacroParameter Parameter; 5301 if (parseIdentifier(Parameter.Name)) 5302 return TokError("expected identifier in 'macro' directive"); 5303 5304 // Emit an error if two (or more) named parameters share the same name. 5305 for (const MCAsmMacroParameter& CurrParam : Parameters) 5306 if (CurrParam.Name.equals_lower(Parameter.Name)) 5307 return TokError("macro '" + Name + "' has multiple parameters" 5308 " named '" + Parameter.Name + "'"); 5309 5310 if (Lexer.is(AsmToken::Colon)) { 5311 Lex(); // consume ':' 5312 5313 if (parseOptionalToken(AsmToken::Equal)) { 5314 // Default value 5315 SMLoc ParamLoc; 5316 5317 ParamLoc = Lexer.getLoc(); 5318 if (parseMacroArgument(nullptr, Parameter.Value)) 5319 return true; 5320 } else { 5321 SMLoc QualLoc; 5322 StringRef Qualifier; 5323 5324 QualLoc = Lexer.getLoc(); 5325 if (parseIdentifier(Qualifier)) 5326 return Error(QualLoc, "missing parameter qualifier for " 5327 "'" + 5328 Parameter.Name + "' in macro '" + Name + 5329 "'"); 5330 5331 if (Qualifier.equals_lower("req")) 5332 Parameter.Required = true; 5333 else if (Qualifier.equals_lower("vararg")) 5334 Parameter.Vararg = true; 5335 else 5336 return Error(QualLoc, 5337 Qualifier + " is not a valid parameter qualifier for '" + 5338 Parameter.Name + "' in macro '" + Name + "'"); 5339 } 5340 } 5341 5342 Parameters.push_back(std::move(Parameter)); 5343 5344 if (getLexer().is(AsmToken::Comma)) 5345 Lex(); 5346 } 5347 5348 // Eat just the end of statement. 5349 Lexer.Lex(); 5350 5351 std::vector<std::string> Locals; 5352 if (getTok().is(AsmToken::Identifier) && 5353 getTok().getIdentifier().equals_lower("local")) { 5354 Lex(); // Eat the LOCAL directive. 5355 5356 StringRef ID; 5357 while (true) { 5358 if (parseIdentifier(ID)) 5359 return true; 5360 Locals.push_back(ID.lower()); 5361 5362 // If we see a comma, continue (and allow line continuation). 5363 if (!parseOptionalToken(AsmToken::Comma)) 5364 break; 5365 parseOptionalToken(AsmToken::EndOfStatement); 5366 } 5367 } 5368 5369 // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors. 5370 AsmToken EndToken, StartToken = getTok(); 5371 unsigned MacroDepth = 0; 5372 // Lex the macro definition. 5373 while (true) { 5374 // Ignore Lexing errors in macros. 5375 while (Lexer.is(AsmToken::Error)) { 5376 Lexer.Lex(); 5377 } 5378 5379 // Check whether we have reached the end of the file. 5380 if (getLexer().is(AsmToken::Eof)) 5381 return Error(NameLoc, "no matching 'endm' in definition"); 5382 5383 // Otherwise, check whether we have reach the 'endm'. 5384 if (getLexer().is(AsmToken::Identifier)) { 5385 if (getTok().getIdentifier().equals_lower("endm")) { 5386 if (MacroDepth == 0) { // Outermost macro. 5387 EndToken = getTok(); 5388 Lexer.Lex(); 5389 if (getLexer().isNot(AsmToken::EndOfStatement)) 5390 return TokError("unexpected token in '" + EndToken.getIdentifier() + 5391 "' directive"); 5392 break; 5393 } else { 5394 // Otherwise we just found the end of an inner macro. 5395 --MacroDepth; 5396 } 5397 } else if (isMacroLikeDirective()) { 5398 // We allow nested macros. Those aren't instantiated until the 5399 // outermost macro is expanded so just ignore them for now. 5400 ++MacroDepth; 5401 } 5402 } 5403 5404 // Otherwise, scan til the end of the statement. 5405 eatToEndOfStatement(); 5406 } 5407 5408 if (getContext().lookupMacro(Name)) { 5409 return Error(NameLoc, "macro '" + Name + "' is already defined"); 5410 } 5411 5412 const char *BodyStart = StartToken.getLoc().getPointer(); 5413 const char *BodyEnd = EndToken.getLoc().getPointer(); 5414 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 5415 checkForBadMacro(NameLoc, Name, Body, Parameters); 5416 MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals)); 5417 DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n"; 5418 Macro.dump()); 5419 getContext().defineMacro(Name, std::move(Macro)); 5420 return false; 5421 } 5422 5423 /// checkForBadMacro 5424 /// 5425 /// With the support added for named parameters there may be code out there that 5426 /// is transitioning from positional parameters. In versions of gas that did 5427 /// not support named parameters they would be ignored on the macro definition. 5428 /// But to support both styles of parameters this is not possible so if a macro 5429 /// definition has named parameters but does not use them and has what appears 5430 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a 5431 /// warning that the positional parameter found in body which have no effect. 5432 /// Hoping the developer will either remove the named parameters from the macro 5433 /// definition so the positional parameters get used if that was what was 5434 /// intended or change the macro to use the named parameters. It is possible 5435 /// this warning will trigger when the none of the named parameters are used 5436 /// and the strings like $1 are infact to simply to be passed trough unchanged. 5437 void MasmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, 5438 StringRef Body, 5439 ArrayRef<MCAsmMacroParameter> Parameters) { 5440 // If this macro is not defined with named parameters the warning we are 5441 // checking for here doesn't apply. 5442 unsigned NParameters = Parameters.size(); 5443 if (NParameters == 0) 5444 return; 5445 5446 bool NamedParametersFound = false; 5447 bool PositionalParametersFound = false; 5448 5449 // Look at the body of the macro for use of both the named parameters and what 5450 // are likely to be positional parameters. This is what expandMacro() is 5451 // doing when it finds the parameters in the body. 5452 while (!Body.empty()) { 5453 // Scan for the next possible parameter. 5454 std::size_t End = Body.size(), Pos = 0; 5455 for (; Pos != End; ++Pos) { 5456 // Check for a substitution or escape. 5457 // This macro is defined with parameters, look for \foo, \bar, etc. 5458 if (Body[Pos] == '\\' && Pos + 1 != End) 5459 break; 5460 5461 // This macro should have parameters, but look for $0, $1, ..., $n too. 5462 if (Body[Pos] != '$' || Pos + 1 == End) 5463 continue; 5464 char Next = Body[Pos + 1]; 5465 if (Next == '$' || Next == 'n' || 5466 isdigit(static_cast<unsigned char>(Next))) 5467 break; 5468 } 5469 5470 // Check if we reached the end. 5471 if (Pos == End) 5472 break; 5473 5474 if (Body[Pos] == '$') { 5475 switch (Body[Pos + 1]) { 5476 // $$ => $ 5477 case '$': 5478 break; 5479 5480 // $n => number of arguments 5481 case 'n': 5482 PositionalParametersFound = true; 5483 break; 5484 5485 // $[0-9] => argument 5486 default: { 5487 PositionalParametersFound = true; 5488 break; 5489 } 5490 } 5491 Pos += 2; 5492 } else { 5493 unsigned I = Pos + 1; 5494 while (isIdentifierChar(Body[I]) && I + 1 != End) 5495 ++I; 5496 5497 const char *Begin = Body.data() + Pos + 1; 5498 StringRef Argument(Begin, I - (Pos + 1)); 5499 unsigned Index = 0; 5500 for (; Index < NParameters; ++Index) 5501 if (Parameters[Index].Name == Argument) 5502 break; 5503 5504 if (Index == NParameters) { 5505 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') 5506 Pos += 3; 5507 else { 5508 Pos = I; 5509 } 5510 } else { 5511 NamedParametersFound = true; 5512 Pos += 1 + Argument.size(); 5513 } 5514 } 5515 // Update the scan point. 5516 Body = Body.substr(Pos); 5517 } 5518 5519 if (!NamedParametersFound && PositionalParametersFound) 5520 Warning(DirectiveLoc, "macro defined with named parameters which are not " 5521 "used in macro body, possible positional parameter " 5522 "found in body which will have no effect"); 5523 } 5524 5525 /// parseDirectiveExitMacro 5526 /// ::= exitm 5527 bool MasmParser::parseDirectiveExitMacro(StringRef Directive) { 5528 if (parseToken(AsmToken::EndOfStatement, 5529 "unexpected token in '" + Directive + "' directive")) 5530 return true; 5531 5532 if (!isInsideMacroInstantiation()) 5533 return TokError("unexpected '" + Directive + "' in file, " 5534 "no current macro definition"); 5535 5536 // Exit all conditionals that are active in the current macro. 5537 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) { 5538 TheCondState = TheCondStack.back(); 5539 TheCondStack.pop_back(); 5540 } 5541 5542 handleMacroExit(); 5543 return false; 5544 } 5545 5546 /// parseDirectiveEndMacro 5547 /// ::= endm 5548 bool MasmParser::parseDirectiveEndMacro(StringRef Directive) { 5549 if (getLexer().isNot(AsmToken::EndOfStatement)) 5550 return TokError("unexpected token in '" + Directive + "' directive"); 5551 5552 // If we are inside a macro instantiation, terminate the current 5553 // instantiation. 5554 if (isInsideMacroInstantiation()) { 5555 handleMacroExit(); 5556 return false; 5557 } 5558 5559 // Otherwise, this .endmacro is a stray entry in the file; well formed 5560 // .endmacro directives are handled during the macro definition parsing. 5561 return TokError("unexpected '" + Directive + "' in file, " 5562 "no current macro definition"); 5563 } 5564 5565 /// parseDirectivePurgeMacro 5566 /// ::= .purgem 5567 bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { 5568 StringRef Name; 5569 SMLoc Loc; 5570 if (parseTokenLoc(Loc) || 5571 check(parseIdentifier(Name), Loc, 5572 "expected identifier in '.purgem' directive") || 5573 parseToken(AsmToken::EndOfStatement, 5574 "unexpected token in '.purgem' directive")) 5575 return true; 5576 5577 if (!getContext().lookupMacro(Name)) 5578 return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); 5579 5580 getContext().undefineMacro(Name); 5581 DEBUG_WITH_TYPE("asm-macros", dbgs() 5582 << "Un-defining macro: " << Name << "\n"); 5583 return false; 5584 } 5585 5586 /// parseDirectiveSymbolAttribute 5587 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 5588 bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 5589 auto parseOp = [&]() -> bool { 5590 StringRef Name; 5591 SMLoc Loc = getTok().getLoc(); 5592 if (parseIdentifier(Name)) 5593 return Error(Loc, "expected identifier"); 5594 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5595 5596 // Assembler local symbols don't make any sense here. Complain loudly. 5597 if (Sym->isTemporary()) 5598 return Error(Loc, "non-local symbol required"); 5599 5600 if (!getStreamer().emitSymbolAttribute(Sym, Attr)) 5601 return Error(Loc, "unable to emit symbol attribute"); 5602 return false; 5603 }; 5604 5605 if (parseMany(parseOp)) 5606 return addErrorSuffix(" in directive"); 5607 return false; 5608 } 5609 5610 /// parseDirectiveComm 5611 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 5612 bool MasmParser::parseDirectiveComm(bool IsLocal) { 5613 if (checkForValidSection()) 5614 return true; 5615 5616 SMLoc IDLoc = getLexer().getLoc(); 5617 StringRef Name; 5618 if (parseIdentifier(Name)) 5619 return TokError("expected identifier in directive"); 5620 5621 // Handle the identifier as the key symbol. 5622 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5623 5624 if (getLexer().isNot(AsmToken::Comma)) 5625 return TokError("unexpected token in directive"); 5626 Lex(); 5627 5628 int64_t Size; 5629 SMLoc SizeLoc = getLexer().getLoc(); 5630 if (parseAbsoluteExpression(Size)) 5631 return true; 5632 5633 int64_t Pow2Alignment = 0; 5634 SMLoc Pow2AlignmentLoc; 5635 if (getLexer().is(AsmToken::Comma)) { 5636 Lex(); 5637 Pow2AlignmentLoc = getLexer().getLoc(); 5638 if (parseAbsoluteExpression(Pow2Alignment)) 5639 return true; 5640 5641 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 5642 if (IsLocal && LCOMM == LCOMM::NoAlignment) 5643 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 5644 5645 // If this target takes alignments in bytes (not log) validate and convert. 5646 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 5647 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 5648 if (!isPowerOf2_64(Pow2Alignment)) 5649 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 5650 Pow2Alignment = Log2_64(Pow2Alignment); 5651 } 5652 } 5653 5654 if (parseToken(AsmToken::EndOfStatement, 5655 "unexpected token in '.comm' or '.lcomm' directive")) 5656 return true; 5657 5658 // NOTE: a size of zero for a .comm should create a undefined symbol 5659 // but a size of .lcomm creates a bss symbol of size zero. 5660 if (Size < 0) 5661 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 5662 "be less than zero"); 5663 5664 // NOTE: The alignment in the directive is a power of 2 value, the assembler 5665 // may internally end up wanting an alignment in bytes. 5666 // FIXME: Diagnose overflow. 5667 if (Pow2Alignment < 0) 5668 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 5669 "alignment, can't be less than zero"); 5670 5671 Sym->redefineIfPossible(); 5672 if (!Sym->isUndefined()) 5673 return Error(IDLoc, "invalid symbol redefinition"); 5674 5675 // Create the Symbol as a common or local common with Size and Pow2Alignment. 5676 if (IsLocal) { 5677 getStreamer().emitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 5678 return false; 5679 } 5680 5681 getStreamer().emitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 5682 return false; 5683 } 5684 5685 /// parseDirectiveComment 5686 /// ::= comment delimiter [[text]] 5687 /// [[text]] 5688 /// [[text]] delimiter [[text]] 5689 bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) { 5690 StringRef FirstLine = parseStringToEndOfStatement(); 5691 size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A "); 5692 StringRef Delimiter = FirstLine.take_front(DelimiterEnd); 5693 if (Delimiter.empty()) 5694 return Error(DirectiveLoc, "no delimiter in 'comment' directive"); 5695 do { 5696 if (getTok().is(AsmToken::Eof)) 5697 return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive"); 5698 Lex(); // eat end of statement 5699 } while (!parseStringToEndOfStatement().contains(Delimiter)); 5700 return parseToken(AsmToken::EndOfStatement, 5701 "unexpected token in 'comment' directive"); 5702 } 5703 5704 /// parseDirectiveInclude 5705 /// ::= include <filename> 5706 /// | include filename 5707 bool MasmParser::parseDirectiveInclude() { 5708 // Allow the strings to have escaped octal character sequence. 5709 std::string Filename; 5710 SMLoc IncludeLoc = getTok().getLoc(); 5711 5712 if (!parseAngleBracketString(Filename)) 5713 Filename = parseStringToEndOfStatement().str(); 5714 if (check(!Filename.empty(), "missing filename in 'include' directive") || 5715 check(getTok().isNot(AsmToken::EndOfStatement), 5716 "unexpected token in 'include' directive") || 5717 // Attempt to switch the lexer to the included file before consuming the 5718 // end of statement to avoid losing it when we switch. 5719 check(enterIncludeFile(Filename), IncludeLoc, 5720 "Could not find include file '" + Filename + "'")) 5721 return true; 5722 5723 return false; 5724 } 5725 5726 /// parseDirectiveIf 5727 /// ::= .if{,eq,ge,gt,le,lt,ne} expression 5728 bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) { 5729 TheCondStack.push_back(TheCondState); 5730 TheCondState.TheCond = AsmCond::IfCond; 5731 if (TheCondState.Ignore) { 5732 eatToEndOfStatement(); 5733 } else { 5734 int64_t ExprValue; 5735 if (parseAbsoluteExpression(ExprValue) || 5736 parseToken(AsmToken::EndOfStatement, 5737 "unexpected token in '.if' directive")) 5738 return true; 5739 5740 switch (DirKind) { 5741 default: 5742 llvm_unreachable("unsupported directive"); 5743 case DK_IF: 5744 break; 5745 case DK_IFE: 5746 ExprValue = ExprValue == 0; 5747 break; 5748 } 5749 5750 TheCondState.CondMet = ExprValue; 5751 TheCondState.Ignore = !TheCondState.CondMet; 5752 } 5753 5754 return false; 5755 } 5756 5757 /// parseDirectiveIfb 5758 /// ::= .ifb string 5759 bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 5760 TheCondStack.push_back(TheCondState); 5761 TheCondState.TheCond = AsmCond::IfCond; 5762 5763 if (TheCondState.Ignore) { 5764 eatToEndOfStatement(); 5765 } else { 5766 std::string Str; 5767 if (parseTextItem(Str)) 5768 return TokError("expected string parameter for 'ifb' directive"); 5769 5770 if (parseToken(AsmToken::EndOfStatement, 5771 "unexpected token in 'ifb' directive")) 5772 return true; 5773 5774 TheCondState.CondMet = ExpectBlank == Str.empty(); 5775 TheCondState.Ignore = !TheCondState.CondMet; 5776 } 5777 5778 return false; 5779 } 5780 5781 /// parseDirectiveIfidn 5782 /// ::= ifidn string1, string2 5783 bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual, bool CaseInsensitive) { 5784 std::string String1, String2; 5785 5786 if (parseTextItem(String1)) { 5787 if (ExpectEqual) 5788 return TokError("expected string parameter for 'ifidn' directive"); 5789 return TokError("expected string parameter for 'ifdif' directive"); 5790 } 5791 5792 if (Lexer.isNot(AsmToken::Comma)) { 5793 if (ExpectEqual) 5794 return TokError( 5795 "expected comma after first string for 'ifidn' directive"); 5796 return TokError("expected comma after first string for 'ifdif' directive"); 5797 } 5798 Lex(); 5799 5800 if (parseTextItem(String2)) { 5801 if (ExpectEqual) 5802 return TokError("expected string parameter for 'ifidn' directive"); 5803 return TokError("expected string parameter for 'ifdif' directive"); 5804 } 5805 5806 TheCondStack.push_back(TheCondState); 5807 TheCondState.TheCond = AsmCond::IfCond; 5808 if (CaseInsensitive) 5809 TheCondState.CondMet = 5810 ExpectEqual == (StringRef(String1).equals_lower(String2)); 5811 else 5812 TheCondState.CondMet = ExpectEqual == (String1 == String2); 5813 TheCondState.Ignore = !TheCondState.CondMet; 5814 5815 return false; 5816 } 5817 5818 /// parseDirectiveIfdef 5819 /// ::= ifdef symbol 5820 /// | ifdef variable 5821 bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 5822 TheCondStack.push_back(TheCondState); 5823 TheCondState.TheCond = AsmCond::IfCond; 5824 5825 if (TheCondState.Ignore) { 5826 eatToEndOfStatement(); 5827 } else { 5828 bool is_defined = false; 5829 unsigned RegNo; 5830 SMLoc StartLoc, EndLoc; 5831 is_defined = (getTargetParser().tryParseRegister( 5832 RegNo, StartLoc, EndLoc) == MatchOperand_Success); 5833 if (!is_defined) { 5834 StringRef Name; 5835 if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") || 5836 parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'")) 5837 return true; 5838 5839 if (Variables.find(Name) != Variables.end()) { 5840 is_defined = true; 5841 } else { 5842 MCSymbol *Sym = getContext().lookupSymbol(Name); 5843 is_defined = (Sym && !Sym->isUndefined(false)); 5844 } 5845 } 5846 5847 TheCondState.CondMet = (is_defined == expect_defined); 5848 TheCondState.Ignore = !TheCondState.CondMet; 5849 } 5850 5851 return false; 5852 } 5853 5854 /// parseDirectiveElseIf 5855 /// ::= elseif expression 5856 bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc, 5857 DirectiveKind DirKind) { 5858 if (TheCondState.TheCond != AsmCond::IfCond && 5859 TheCondState.TheCond != AsmCond::ElseIfCond) 5860 return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an" 5861 " .if or an .elseif"); 5862 TheCondState.TheCond = AsmCond::ElseIfCond; 5863 5864 bool LastIgnoreState = false; 5865 if (!TheCondStack.empty()) 5866 LastIgnoreState = TheCondStack.back().Ignore; 5867 if (LastIgnoreState || TheCondState.CondMet) { 5868 TheCondState.Ignore = true; 5869 eatToEndOfStatement(); 5870 } else { 5871 int64_t ExprValue; 5872 if (parseAbsoluteExpression(ExprValue)) 5873 return true; 5874 5875 if (parseToken(AsmToken::EndOfStatement, 5876 "unexpected token in '.elseif' directive")) 5877 return true; 5878 5879 switch (DirKind) { 5880 default: 5881 llvm_unreachable("unsupported directive"); 5882 case DK_ELSEIF: 5883 break; 5884 case DK_ELSEIFE: 5885 ExprValue = ExprValue == 0; 5886 break; 5887 } 5888 5889 TheCondState.CondMet = ExprValue; 5890 TheCondState.Ignore = !TheCondState.CondMet; 5891 } 5892 5893 return false; 5894 } 5895 5896 /// parseDirectiveElseIfb 5897 /// ::= elseifb expression 5898 bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 5899 if (TheCondState.TheCond != AsmCond::IfCond && 5900 TheCondState.TheCond != AsmCond::ElseIfCond) 5901 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 5902 " if or an elseif"); 5903 TheCondState.TheCond = AsmCond::ElseIfCond; 5904 5905 bool LastIgnoreState = false; 5906 if (!TheCondStack.empty()) 5907 LastIgnoreState = TheCondStack.back().Ignore; 5908 if (LastIgnoreState || TheCondState.CondMet) { 5909 TheCondState.Ignore = true; 5910 eatToEndOfStatement(); 5911 } else { 5912 std::string Str; 5913 if (parseTextItem(Str)) 5914 return TokError("expected string parameter for 'elseifb' directive"); 5915 5916 if (parseToken(AsmToken::EndOfStatement, 5917 "unexpected token in 'elseifb' directive")) 5918 return true; 5919 5920 TheCondState.CondMet = ExpectBlank == Str.empty(); 5921 TheCondState.Ignore = !TheCondState.CondMet; 5922 } 5923 5924 return false; 5925 } 5926 5927 /// parseDirectiveElseIfdef 5928 /// ::= elseifdef symbol 5929 /// | elseifdef variable 5930 bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc, 5931 bool expect_defined) { 5932 if (TheCondState.TheCond != AsmCond::IfCond && 5933 TheCondState.TheCond != AsmCond::ElseIfCond) 5934 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 5935 " if or an elseif"); 5936 TheCondState.TheCond = AsmCond::ElseIfCond; 5937 5938 bool LastIgnoreState = false; 5939 if (!TheCondStack.empty()) 5940 LastIgnoreState = TheCondStack.back().Ignore; 5941 if (LastIgnoreState || TheCondState.CondMet) { 5942 TheCondState.Ignore = true; 5943 eatToEndOfStatement(); 5944 } else { 5945 bool is_defined = false; 5946 unsigned RegNo; 5947 SMLoc StartLoc, EndLoc; 5948 is_defined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) == 5949 MatchOperand_Success); 5950 if (!is_defined) { 5951 StringRef Name; 5952 if (check(parseIdentifier(Name), 5953 "expected identifier after 'elseifdef'") || 5954 parseToken(AsmToken::EndOfStatement, 5955 "unexpected token in 'elseifdef'")) 5956 return true; 5957 5958 if (Variables.find(Name) != Variables.end()) { 5959 is_defined = true; 5960 } else { 5961 MCSymbol *Sym = getContext().lookupSymbol(Name); 5962 is_defined = (Sym && !Sym->isUndefined(false)); 5963 } 5964 } 5965 5966 TheCondState.CondMet = (is_defined == expect_defined); 5967 TheCondState.Ignore = !TheCondState.CondMet; 5968 } 5969 5970 return false; 5971 } 5972 5973 /// parseDirectiveElseIfidn 5974 /// ::= elseifidn string1, string2 5975 bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 5976 bool CaseInsensitive) { 5977 if (TheCondState.TheCond != AsmCond::IfCond && 5978 TheCondState.TheCond != AsmCond::ElseIfCond) 5979 return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an" 5980 " if or an elseif"); 5981 TheCondState.TheCond = AsmCond::ElseIfCond; 5982 5983 bool LastIgnoreState = false; 5984 if (!TheCondStack.empty()) 5985 LastIgnoreState = TheCondStack.back().Ignore; 5986 if (LastIgnoreState || TheCondState.CondMet) { 5987 TheCondState.Ignore = true; 5988 eatToEndOfStatement(); 5989 } else { 5990 std::string String1, String2; 5991 5992 if (parseTextItem(String1)) { 5993 if (ExpectEqual) 5994 return TokError("expected string parameter for 'elseifidn' directive"); 5995 return TokError("expected string parameter for 'elseifdif' directive"); 5996 } 5997 5998 if (Lexer.isNot(AsmToken::Comma)) { 5999 if (ExpectEqual) 6000 return TokError( 6001 "expected comma after first string for 'elseifidn' directive"); 6002 return TokError( 6003 "expected comma after first string for 'elseifdif' directive"); 6004 } 6005 Lex(); 6006 6007 if (parseTextItem(String2)) { 6008 if (ExpectEqual) 6009 return TokError("expected string parameter for 'elseifidn' directive"); 6010 return TokError("expected string parameter for 'elseifdif' directive"); 6011 } 6012 6013 if (CaseInsensitive) 6014 TheCondState.CondMet = 6015 ExpectEqual == (StringRef(String1).equals_lower(String2)); 6016 else 6017 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6018 TheCondState.Ignore = !TheCondState.CondMet; 6019 } 6020 6021 return false; 6022 } 6023 6024 /// parseDirectiveElse 6025 /// ::= else 6026 bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) { 6027 if (parseToken(AsmToken::EndOfStatement, 6028 "unexpected token in 'else' directive")) 6029 return true; 6030 6031 if (TheCondState.TheCond != AsmCond::IfCond && 6032 TheCondState.TheCond != AsmCond::ElseIfCond) 6033 return Error(DirectiveLoc, "Encountered an else that doesn't follow an if" 6034 " or an elseif"); 6035 TheCondState.TheCond = AsmCond::ElseCond; 6036 bool LastIgnoreState = false; 6037 if (!TheCondStack.empty()) 6038 LastIgnoreState = TheCondStack.back().Ignore; 6039 if (LastIgnoreState || TheCondState.CondMet) 6040 TheCondState.Ignore = true; 6041 else 6042 TheCondState.Ignore = false; 6043 6044 return false; 6045 } 6046 6047 /// parseDirectiveEnd 6048 /// ::= end 6049 bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { 6050 if (parseToken(AsmToken::EndOfStatement, 6051 "unexpected token in 'end' directive")) 6052 return true; 6053 6054 while (Lexer.isNot(AsmToken::Eof)) 6055 Lexer.Lex(); 6056 6057 return false; 6058 } 6059 6060 /// parseDirectiveError 6061 /// ::= .err [message] 6062 bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) { 6063 if (!TheCondStack.empty()) { 6064 if (TheCondStack.back().Ignore) { 6065 eatToEndOfStatement(); 6066 return false; 6067 } 6068 } 6069 6070 StringRef Message = ".err directive invoked in source file"; 6071 if (Lexer.isNot(AsmToken::EndOfStatement)) 6072 Message = parseStringToEndOfStatement(); 6073 Lex(); 6074 6075 return Error(DirectiveLoc, Message); 6076 } 6077 6078 /// parseDirectiveErrorIfb 6079 /// ::= .errb textitem[, message] 6080 bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 6081 if (!TheCondStack.empty()) { 6082 if (TheCondStack.back().Ignore) { 6083 eatToEndOfStatement(); 6084 return false; 6085 } 6086 } 6087 6088 std::string Text; 6089 if (parseTextItem(Text)) 6090 return Error(getTok().getLoc(), "missing text item in '.errb' directive"); 6091 6092 StringRef Message = ".errb directive invoked in source file"; 6093 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6094 if (parseToken(AsmToken::Comma)) 6095 return addErrorSuffix(" in '.errb' directive"); 6096 Message = parseStringToEndOfStatement(); 6097 } 6098 Lex(); 6099 6100 if (Text.empty() == ExpectBlank) 6101 return Error(DirectiveLoc, Message); 6102 return false; 6103 } 6104 6105 /// parseDirectiveErrorIfdef 6106 /// ::= .errdef name[, message] 6107 bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc, 6108 bool ExpectDefined) { 6109 if (!TheCondStack.empty()) { 6110 if (TheCondStack.back().Ignore) { 6111 eatToEndOfStatement(); 6112 return false; 6113 } 6114 } 6115 6116 bool IsDefined = false; 6117 unsigned RegNo; 6118 SMLoc StartLoc, EndLoc; 6119 IsDefined = (getTargetParser().tryParseRegister(RegNo, StartLoc, EndLoc) == 6120 MatchOperand_Success); 6121 if (!IsDefined) { 6122 StringRef Name; 6123 if (check(parseIdentifier(Name), "expected identifier after '.errdef'")) 6124 return true; 6125 6126 if (Variables.find(Name) != Variables.end()) { 6127 IsDefined = true; 6128 } else { 6129 MCSymbol *Sym = getContext().lookupSymbol(Name); 6130 IsDefined = (Sym && !Sym->isUndefined(false)); 6131 } 6132 } 6133 6134 StringRef Message = ".errdef directive invoked in source file"; 6135 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6136 if (parseToken(AsmToken::Comma)) 6137 return addErrorSuffix(" in '.errdef' directive"); 6138 Message = parseStringToEndOfStatement(); 6139 } 6140 Lex(); 6141 6142 if (IsDefined == ExpectDefined) 6143 return Error(DirectiveLoc, Message); 6144 return false; 6145 } 6146 6147 /// parseDirectiveErrorIfidn 6148 /// ::= .erridn textitem1, textitem2[, message] 6149 bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual, 6150 bool CaseInsensitive) { 6151 if (!TheCondStack.empty()) { 6152 if (TheCondStack.back().Ignore) { 6153 eatToEndOfStatement(); 6154 return false; 6155 } 6156 } 6157 6158 std::string String1, String2; 6159 6160 if (parseTextItem(String1)) { 6161 if (ExpectEqual) 6162 return TokError("expected string parameter for '.erridn' directive"); 6163 return TokError("expected string parameter for '.errdif' directive"); 6164 } 6165 6166 if (Lexer.isNot(AsmToken::Comma)) { 6167 if (ExpectEqual) 6168 return TokError( 6169 "expected comma after first string for '.erridn' directive"); 6170 return TokError( 6171 "expected comma after first string for '.errdif' directive"); 6172 } 6173 Lex(); 6174 6175 if (parseTextItem(String2)) { 6176 if (ExpectEqual) 6177 return TokError("expected string parameter for '.erridn' directive"); 6178 return TokError("expected string parameter for '.errdif' directive"); 6179 } 6180 6181 StringRef Message; 6182 if (ExpectEqual) 6183 Message = ".erridn directive invoked in source file"; 6184 else 6185 Message = ".errdif directive invoked in source file"; 6186 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6187 if (parseToken(AsmToken::Comma)) 6188 return addErrorSuffix(" in '.erridn' directive"); 6189 Message = parseStringToEndOfStatement(); 6190 } 6191 Lex(); 6192 6193 if (CaseInsensitive) 6194 TheCondState.CondMet = 6195 ExpectEqual == (StringRef(String1).equals_lower(String2)); 6196 else 6197 TheCondState.CondMet = ExpectEqual == (String1 == String2); 6198 TheCondState.Ignore = !TheCondState.CondMet; 6199 6200 if ((CaseInsensitive && 6201 ExpectEqual == StringRef(String1).equals_lower(String2)) || 6202 (ExpectEqual == (String1 == String2))) 6203 return Error(DirectiveLoc, Message); 6204 return false; 6205 } 6206 6207 /// parseDirectiveErrorIfe 6208 /// ::= .erre expression[, message] 6209 bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) { 6210 if (!TheCondStack.empty()) { 6211 if (TheCondStack.back().Ignore) { 6212 eatToEndOfStatement(); 6213 return false; 6214 } 6215 } 6216 6217 int64_t ExprValue; 6218 if (parseAbsoluteExpression(ExprValue)) 6219 return addErrorSuffix(" in '.erre' directive"); 6220 6221 StringRef Message = ".erre directive invoked in source file"; 6222 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6223 if (parseToken(AsmToken::Comma)) 6224 return addErrorSuffix(" in '.erre' directive"); 6225 Message = parseStringToEndOfStatement(); 6226 } 6227 Lex(); 6228 6229 if ((ExprValue == 0) == ExpectZero) 6230 return Error(DirectiveLoc, Message); 6231 return false; 6232 } 6233 6234 /// parseDirectiveEndIf 6235 /// ::= .endif 6236 bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { 6237 if (parseToken(AsmToken::EndOfStatement, 6238 "unexpected token in '.endif' directive")) 6239 return true; 6240 6241 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty()) 6242 return Error(DirectiveLoc, "Encountered a .endif that doesn't follow " 6243 "an .if or .else"); 6244 if (!TheCondStack.empty()) { 6245 TheCondState = TheCondStack.back(); 6246 TheCondStack.pop_back(); 6247 } 6248 6249 return false; 6250 } 6251 6252 void MasmParser::initializeDirectiveKindMap() { 6253 DirectiveKindMap["="] = DK_ASSIGN; 6254 DirectiveKindMap["equ"] = DK_EQU; 6255 DirectiveKindMap["textequ"] = DK_TEXTEQU; 6256 // DirectiveKindMap[".ascii"] = DK_ASCII; 6257 // DirectiveKindMap[".asciz"] = DK_ASCIZ; 6258 // DirectiveKindMap[".string"] = DK_STRING; 6259 DirectiveKindMap["byte"] = DK_BYTE; 6260 DirectiveKindMap["sbyte"] = DK_SBYTE; 6261 DirectiveKindMap["word"] = DK_WORD; 6262 DirectiveKindMap["sword"] = DK_SWORD; 6263 DirectiveKindMap["dword"] = DK_DWORD; 6264 DirectiveKindMap["sdword"] = DK_SDWORD; 6265 DirectiveKindMap["fword"] = DK_FWORD; 6266 DirectiveKindMap["qword"] = DK_QWORD; 6267 DirectiveKindMap["sqword"] = DK_SQWORD; 6268 DirectiveKindMap["real4"] = DK_REAL4; 6269 DirectiveKindMap["real8"] = DK_REAL8; 6270 DirectiveKindMap["real10"] = DK_REAL10; 6271 DirectiveKindMap["align"] = DK_ALIGN; 6272 // DirectiveKindMap[".org"] = DK_ORG; 6273 DirectiveKindMap["extern"] = DK_EXTERN; 6274 DirectiveKindMap["public"] = DK_PUBLIC; 6275 // DirectiveKindMap[".comm"] = DK_COMM; 6276 DirectiveKindMap["comment"] = DK_COMMENT; 6277 DirectiveKindMap["include"] = DK_INCLUDE; 6278 DirectiveKindMap["repeat"] = DK_REPEAT; 6279 DirectiveKindMap["rept"] = DK_REPEAT; 6280 DirectiveKindMap["while"] = DK_WHILE; 6281 DirectiveKindMap["for"] = DK_FOR; 6282 DirectiveKindMap["irp"] = DK_FOR; 6283 DirectiveKindMap["forc"] = DK_FORC; 6284 DirectiveKindMap["irpc"] = DK_FORC; 6285 DirectiveKindMap["if"] = DK_IF; 6286 DirectiveKindMap["ife"] = DK_IFE; 6287 DirectiveKindMap["ifb"] = DK_IFB; 6288 DirectiveKindMap["ifnb"] = DK_IFNB; 6289 DirectiveKindMap["ifdef"] = DK_IFDEF; 6290 DirectiveKindMap["ifndef"] = DK_IFNDEF; 6291 DirectiveKindMap["ifdif"] = DK_IFDIF; 6292 DirectiveKindMap["ifdifi"] = DK_IFDIFI; 6293 DirectiveKindMap["ifidn"] = DK_IFIDN; 6294 DirectiveKindMap["ifidni"] = DK_IFIDNI; 6295 DirectiveKindMap["elseif"] = DK_ELSEIF; 6296 DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF; 6297 DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF; 6298 DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF; 6299 DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN; 6300 DirectiveKindMap["else"] = DK_ELSE; 6301 DirectiveKindMap["end"] = DK_END; 6302 DirectiveKindMap["endif"] = DK_ENDIF; 6303 // DirectiveKindMap[".file"] = DK_FILE; 6304 // DirectiveKindMap[".line"] = DK_LINE; 6305 // DirectiveKindMap[".loc"] = DK_LOC; 6306 // DirectiveKindMap[".stabs"] = DK_STABS; 6307 // DirectiveKindMap[".cv_file"] = DK_CV_FILE; 6308 // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID; 6309 // DirectiveKindMap[".cv_loc"] = DK_CV_LOC; 6310 // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE; 6311 // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE; 6312 // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID; 6313 // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE; 6314 // DirectiveKindMap[".cv_string"] = DK_CV_STRING; 6315 // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE; 6316 // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS; 6317 // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET; 6318 // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA; 6319 // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS; 6320 // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC; 6321 // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC; 6322 // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA; 6323 // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET; 6324 // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET; 6325 // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER; 6326 // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET; 6327 // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET; 6328 // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY; 6329 // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA; 6330 // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE; 6331 // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE; 6332 // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE; 6333 // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE; 6334 // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE; 6335 // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN; 6336 // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; 6337 // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; 6338 // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; 6339 // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; 6340 // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME; 6341 DirectiveKindMap["macro"] = DK_MACRO; 6342 DirectiveKindMap["exitm"] = DK_EXITM; 6343 DirectiveKindMap["endm"] = DK_ENDM; 6344 // DirectiveKindMap[".purgem"] = DK_PURGEM; 6345 DirectiveKindMap[".err"] = DK_ERR; 6346 DirectiveKindMap[".errb"] = DK_ERRB; 6347 DirectiveKindMap[".errnb"] = DK_ERRNB; 6348 DirectiveKindMap[".errdef"] = DK_ERRDEF; 6349 DirectiveKindMap[".errndef"] = DK_ERRNDEF; 6350 DirectiveKindMap[".errdif"] = DK_ERRDIF; 6351 DirectiveKindMap[".errdifi"] = DK_ERRDIFI; 6352 DirectiveKindMap[".erridn"] = DK_ERRIDN; 6353 DirectiveKindMap[".erridni"] = DK_ERRIDNI; 6354 DirectiveKindMap[".erre"] = DK_ERRE; 6355 DirectiveKindMap[".errnz"] = DK_ERRNZ; 6356 DirectiveKindMap[".pushframe"] = DK_PUSHFRAME; 6357 DirectiveKindMap[".pushreg"] = DK_PUSHREG; 6358 DirectiveKindMap[".savereg"] = DK_SAVEREG; 6359 DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128; 6360 DirectiveKindMap[".setframe"] = DK_SETFRAME; 6361 DirectiveKindMap[".radix"] = DK_RADIX; 6362 DirectiveKindMap["db"] = DK_DB; 6363 DirectiveKindMap["dd"] = DK_DD; 6364 DirectiveKindMap["df"] = DK_DF; 6365 DirectiveKindMap["dq"] = DK_DQ; 6366 DirectiveKindMap["dw"] = DK_DW; 6367 DirectiveKindMap["echo"] = DK_ECHO; 6368 DirectiveKindMap["struc"] = DK_STRUCT; 6369 DirectiveKindMap["struct"] = DK_STRUCT; 6370 DirectiveKindMap["union"] = DK_UNION; 6371 DirectiveKindMap["ends"] = DK_ENDS; 6372 } 6373 6374 bool MasmParser::isMacroLikeDirective() { 6375 if (getLexer().is(AsmToken::Identifier)) { 6376 bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier()) 6377 .CasesLower("repeat", "rept", true) 6378 .CaseLower("while", true) 6379 .CasesLower("for", "irp", true) 6380 .CasesLower("forc", "irpc", true) 6381 .Default(false); 6382 if (IsMacroLike) 6383 return true; 6384 } 6385 if (getLexer().peekTok().is(AsmToken::Identifier) && 6386 getLexer().peekTok().getIdentifier().equals_lower("macro")) 6387 return true; 6388 6389 return false; 6390 } 6391 6392 MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { 6393 AsmToken EndToken, StartToken = getTok(); 6394 6395 unsigned NestLevel = 0; 6396 while (true) { 6397 // Check whether we have reached the end of the file. 6398 if (getLexer().is(AsmToken::Eof)) { 6399 printError(DirectiveLoc, "no matching 'endm' in definition"); 6400 return nullptr; 6401 } 6402 6403 if (isMacroLikeDirective()) 6404 ++NestLevel; 6405 6406 // Otherwise, check whether we have reached the endm. 6407 if (Lexer.is(AsmToken::Identifier) && 6408 getTok().getIdentifier().equals_lower("endm")) { 6409 if (NestLevel == 0) { 6410 EndToken = getTok(); 6411 Lex(); 6412 if (Lexer.isNot(AsmToken::EndOfStatement)) { 6413 printError(getTok().getLoc(), "unexpected token in 'endm' directive"); 6414 return nullptr; 6415 } 6416 break; 6417 } 6418 --NestLevel; 6419 } 6420 6421 // Otherwise, scan till the end of the statement. 6422 eatToEndOfStatement(); 6423 } 6424 6425 const char *BodyStart = StartToken.getLoc().getPointer(); 6426 const char *BodyEnd = EndToken.getLoc().getPointer(); 6427 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 6428 6429 // We Are Anonymous. 6430 MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters()); 6431 return &MacroLikeBodies.back(); 6432 } 6433 6434 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 6435 raw_svector_ostream &OS) { 6436 instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS); 6437 } 6438 void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 6439 SMLoc ExitLoc, 6440 raw_svector_ostream &OS) { 6441 OS << "endm\n"; 6442 6443 std::unique_ptr<MemoryBuffer> Instantiation = 6444 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 6445 6446 // Create the macro instantiation object and add to the current macro 6447 // instantiation stack. 6448 MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer, 6449 ExitLoc, TheCondStack.size()}; 6450 ActiveMacros.push_back(MI); 6451 6452 // Jump to the macro instantiation and prime the lexer. 6453 CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); 6454 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 6455 Lex(); 6456 } 6457 6458 /// parseDirectiveRepeat 6459 /// ::= ("repeat" | "rept") count 6460 /// body 6461 /// endm 6462 bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) { 6463 const MCExpr *CountExpr; 6464 SMLoc CountLoc = getTok().getLoc(); 6465 if (parseExpression(CountExpr)) 6466 return true; 6467 6468 int64_t Count; 6469 if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) { 6470 return Error(CountLoc, "unexpected token in '" + Dir + "' directive"); 6471 } 6472 6473 if (check(Count < 0, CountLoc, "Count is negative") || 6474 parseToken(AsmToken::EndOfStatement, 6475 "unexpected token in '" + Dir + "' directive")) 6476 return true; 6477 6478 // Lex the repeat definition. 6479 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6480 if (!M) 6481 return true; 6482 6483 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6484 // to hold the macro body with substitutions. 6485 SmallString<256> Buf; 6486 raw_svector_ostream OS(Buf); 6487 while (Count--) { 6488 if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc())) 6489 return true; 6490 } 6491 instantiateMacroLikeBody(M, DirectiveLoc, OS); 6492 6493 return false; 6494 } 6495 6496 /// parseDirectiveWhile 6497 /// ::= "while" expression 6498 /// body 6499 /// endm 6500 bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) { 6501 const MCExpr *CondExpr; 6502 SMLoc CondLoc = getTok().getLoc(); 6503 if (parseExpression(CondExpr)) 6504 return true; 6505 6506 // Lex the repeat definition. 6507 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6508 if (!M) 6509 return true; 6510 6511 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6512 // to hold the macro body with substitutions. 6513 SmallString<256> Buf; 6514 raw_svector_ostream OS(Buf); 6515 int64_t Condition; 6516 if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr())) 6517 return Error(CondLoc, "expected absolute expression in 'while' directive"); 6518 if (Condition) { 6519 // Instantiate the macro, then resume at this directive to recheck the 6520 // condition. 6521 if (expandMacro(OS, M->Body, None, None, M->Locals, getTok().getLoc())) 6522 return true; 6523 instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS); 6524 } 6525 6526 return false; 6527 } 6528 6529 /// parseDirectiveFor 6530 /// ::= ("for" | "irp") symbol [":" qualifier], <values> 6531 /// body 6532 /// endm 6533 bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) { 6534 MCAsmMacroParameter Parameter; 6535 MCAsmMacroArguments A; 6536 if (check(parseIdentifier(Parameter.Name), 6537 "expected identifier in '" + Dir + "' directive")) 6538 return true; 6539 6540 // Parse optional qualifier (default value, or "req") 6541 if (parseOptionalToken(AsmToken::Colon)) { 6542 if (parseOptionalToken(AsmToken::Equal)) { 6543 // Default value 6544 SMLoc ParamLoc; 6545 6546 ParamLoc = Lexer.getLoc(); 6547 if (parseMacroArgument(nullptr, Parameter.Value)) 6548 return true; 6549 } else { 6550 SMLoc QualLoc; 6551 StringRef Qualifier; 6552 6553 QualLoc = Lexer.getLoc(); 6554 if (parseIdentifier(Qualifier)) 6555 return Error(QualLoc, "missing parameter qualifier for " 6556 "'" + 6557 Parameter.Name + "' in '" + Dir + 6558 "' directive"); 6559 6560 if (Qualifier.equals_lower("req")) 6561 Parameter.Required = true; 6562 else 6563 return Error(QualLoc, 6564 Qualifier + " is not a valid parameter qualifier for '" + 6565 Parameter.Name + "' in '" + Dir + "' directive"); 6566 } 6567 } 6568 6569 if (parseToken(AsmToken::Comma, 6570 "expected comma in '" + Dir + "' directive") || 6571 parseToken(AsmToken::Less, 6572 "values in '" + Dir + 6573 "' directive must be enclosed in angle brackets")) 6574 return true; 6575 6576 while (true) { 6577 A.emplace_back(); 6578 if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater)) 6579 return addErrorSuffix(" in arguments for '" + Dir + "' directive"); 6580 6581 // If we see a comma, continue, and allow line continuation. 6582 if (!parseOptionalToken(AsmToken::Comma)) 6583 break; 6584 parseOptionalToken(AsmToken::EndOfStatement); 6585 } 6586 6587 if (parseToken(AsmToken::Greater, 6588 "values in '" + Dir + 6589 "' directive must be enclosed in angle brackets") || 6590 parseToken(AsmToken::EndOfStatement, "expected End of Statement")) 6591 return true; 6592 6593 // Lex the for definition. 6594 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6595 if (!M) 6596 return true; 6597 6598 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6599 // to hold the macro body with substitutions. 6600 SmallString<256> Buf; 6601 raw_svector_ostream OS(Buf); 6602 6603 for (const MCAsmMacroArgument &Arg : A) { 6604 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc())) 6605 return true; 6606 } 6607 6608 instantiateMacroLikeBody(M, DirectiveLoc, OS); 6609 6610 return false; 6611 } 6612 6613 /// parseDirectiveForc 6614 /// ::= ("forc" | "irpc") symbol, <string> 6615 /// body 6616 /// endm 6617 bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) { 6618 MCAsmMacroParameter Parameter; 6619 6620 std::string Argument; 6621 if (check(parseIdentifier(Parameter.Name), 6622 "expected identifier in '" + Directive + "' directive") || 6623 parseToken(AsmToken::Comma, 6624 "expected comma in '" + Directive + "' directive")) 6625 return true; 6626 if (parseAngleBracketString(Argument)) { 6627 // Match ml64.exe; treat all characters to end of statement as a string, 6628 // ignoring comment markers, then discard anything following a space (using 6629 // the C locale). 6630 Argument = parseStringToEndOfStatement().str(); 6631 if (getTok().is(AsmToken::EndOfStatement)) 6632 Argument += getTok().getString(); 6633 size_t End = 0; 6634 for (; End < Argument.size(); ++End) { 6635 if (isSpace(Argument[End])) 6636 break; 6637 } 6638 Argument.resize(End); 6639 } 6640 if (parseToken(AsmToken::EndOfStatement, "expected end of statement")) 6641 return true; 6642 6643 // Lex the irpc definition. 6644 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 6645 if (!M) 6646 return true; 6647 6648 // Macro instantiation is lexical, unfortunately. We construct a new buffer 6649 // to hold the macro body with substitutions. 6650 SmallString<256> Buf; 6651 raw_svector_ostream OS(Buf); 6652 6653 StringRef Values(Argument); 6654 for (std::size_t I = 0, End = Values.size(); I != End; ++I) { 6655 MCAsmMacroArgument Arg; 6656 Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1)); 6657 6658 if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc())) 6659 return true; 6660 } 6661 6662 instantiateMacroLikeBody(M, DirectiveLoc, OS); 6663 6664 return false; 6665 } 6666 6667 bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, 6668 size_t Len) { 6669 const MCExpr *Value; 6670 SMLoc ExprLoc = getLexer().getLoc(); 6671 if (parseExpression(Value)) 6672 return true; 6673 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 6674 if (!MCE) 6675 return Error(ExprLoc, "unexpected expression in _emit"); 6676 uint64_t IntValue = MCE->getValue(); 6677 if (!isUInt<8>(IntValue) && !isInt<8>(IntValue)) 6678 return Error(ExprLoc, "literal value out of range for directive"); 6679 6680 Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len); 6681 return false; 6682 } 6683 6684 bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { 6685 const MCExpr *Value; 6686 SMLoc ExprLoc = getLexer().getLoc(); 6687 if (parseExpression(Value)) 6688 return true; 6689 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 6690 if (!MCE) 6691 return Error(ExprLoc, "unexpected expression in align"); 6692 uint64_t IntValue = MCE->getValue(); 6693 if (!isPowerOf2_64(IntValue)) 6694 return Error(ExprLoc, "literal value not a power of two greater then zero"); 6695 6696 Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue)); 6697 return false; 6698 } 6699 6700 bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) { 6701 const SMLoc Loc = getLexer().getLoc(); 6702 StringRef RadixString = parseStringToEndOfStatement().trim(); 6703 unsigned Radix; 6704 if (RadixString.getAsInteger(10, Radix)) { 6705 return Error(Loc, 6706 "radix must be a decimal number in the range 2 to 16; was " + 6707 RadixString); 6708 } 6709 if (Radix < 2 || Radix > 16) 6710 return Error(Loc, "radix must be in the range 2 to 16; was " + 6711 std::to_string(Radix)); 6712 getLexer().setMasmDefaultRadix(Radix); 6713 return false; 6714 } 6715 6716 bool MasmParser::parseDirectiveEcho() { 6717 StringRef Message = parseStringToEndOfStatement(); 6718 Lex(); // eat end of statement 6719 llvm::outs() << Message << '\n'; 6720 return false; 6721 } 6722 6723 // We are comparing pointers, but the pointers are relative to a single string. 6724 // Thus, this should always be deterministic. 6725 static int rewritesSort(const AsmRewrite *AsmRewriteA, 6726 const AsmRewrite *AsmRewriteB) { 6727 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) 6728 return -1; 6729 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) 6730 return 1; 6731 6732 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output 6733 // rewrite to the same location. Make sure the SizeDirective rewrite is 6734 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This 6735 // ensures the sort algorithm is stable. 6736 if (AsmRewritePrecedence[AsmRewriteA->Kind] > 6737 AsmRewritePrecedence[AsmRewriteB->Kind]) 6738 return -1; 6739 6740 if (AsmRewritePrecedence[AsmRewriteA->Kind] < 6741 AsmRewritePrecedence[AsmRewriteB->Kind]) 6742 return 1; 6743 llvm_unreachable("Unstable rewrite sort."); 6744 } 6745 6746 bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const { 6747 const std::pair<StringRef, StringRef> BaseMember = Name.split('.'); 6748 const StringRef Base = BaseMember.first, Member = BaseMember.second; 6749 return lookUpField(Base, Member, Info); 6750 } 6751 6752 bool MasmParser::lookUpField(StringRef Base, StringRef Member, 6753 AsmFieldInfo &Info) const { 6754 if (Base.empty()) 6755 return true; 6756 6757 AsmFieldInfo BaseInfo; 6758 if (Base.contains('.') && !lookUpField(Base, BaseInfo)) 6759 Base = BaseInfo.Type.Name; 6760 6761 auto StructIt = Structs.find(Base.lower()); 6762 auto TypeIt = KnownType.find(Base.lower()); 6763 if (TypeIt != KnownType.end()) { 6764 StructIt = Structs.find(TypeIt->second.Name.lower()); 6765 } 6766 if (StructIt != Structs.end()) 6767 return lookUpField(StructIt->second, Member, Info); 6768 6769 return true; 6770 } 6771 6772 bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member, 6773 AsmFieldInfo &Info) const { 6774 if (Member.empty()) { 6775 Info.Type.Name = Structure.Name; 6776 Info.Type.Size = Structure.Size; 6777 Info.Type.ElementSize = Structure.Size; 6778 Info.Type.Length = 1; 6779 return false; 6780 } 6781 6782 std::pair<StringRef, StringRef> Split = Member.split('.'); 6783 const StringRef FieldName = Split.first, FieldMember = Split.second; 6784 6785 auto StructIt = Structs.find(FieldName.lower()); 6786 if (StructIt != Structs.end()) 6787 return lookUpField(StructIt->second, FieldMember, Info); 6788 6789 auto FieldIt = Structure.FieldsByName.find(FieldName.lower()); 6790 if (FieldIt == Structure.FieldsByName.end()) 6791 return true; 6792 6793 const FieldInfo &Field = Structure.Fields[FieldIt->second]; 6794 if (FieldMember.empty()) { 6795 Info.Offset += Field.Offset; 6796 Info.Type.Size = Field.SizeOf; 6797 Info.Type.ElementSize = Field.Type; 6798 Info.Type.Length = Field.LengthOf; 6799 if (Field.Contents.FT == FT_STRUCT) 6800 Info.Type.Name = Field.Contents.StructInfo.Structure.Name; 6801 else 6802 Info.Type.Name = ""; 6803 return false; 6804 } 6805 6806 if (Field.Contents.FT != FT_STRUCT) 6807 return true; 6808 const StructFieldInfo &StructInfo = Field.Contents.StructInfo; 6809 6810 if (lookUpField(StructInfo.Structure, FieldMember, Info)) 6811 return true; 6812 6813 Info.Offset += Field.Offset; 6814 return false; 6815 } 6816 6817 bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const { 6818 unsigned Size = StringSwitch<unsigned>(Name) 6819 .CasesLower("byte", "db", "sbyte", 1) 6820 .CasesLower("word", "dw", "sword", 2) 6821 .CasesLower("dword", "dd", "sdword", 4) 6822 .CasesLower("fword", "df", 6) 6823 .CasesLower("qword", "dq", "sqword", 8) 6824 .CaseLower("real4", 4) 6825 .CaseLower("real8", 8) 6826 .CaseLower("real10", 10) 6827 .Default(0); 6828 if (Size) { 6829 Info.Name = Name; 6830 Info.ElementSize = Size; 6831 Info.Length = 1; 6832 Info.Size = Size; 6833 return false; 6834 } 6835 6836 auto StructIt = Structs.find(Name.lower()); 6837 if (StructIt != Structs.end()) { 6838 const StructInfo &Structure = StructIt->second; 6839 Info.Name = Name; 6840 Info.ElementSize = Structure.Size; 6841 Info.Length = 1; 6842 Info.Size = Structure.Size; 6843 return false; 6844 } 6845 6846 return true; 6847 } 6848 6849 bool MasmParser::parseMSInlineAsm( 6850 void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, 6851 unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls, 6852 SmallVectorImpl<std::string> &Constraints, 6853 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII, 6854 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) { 6855 SmallVector<void *, 4> InputDecls; 6856 SmallVector<void *, 4> OutputDecls; 6857 SmallVector<bool, 4> InputDeclsAddressOf; 6858 SmallVector<bool, 4> OutputDeclsAddressOf; 6859 SmallVector<std::string, 4> InputConstraints; 6860 SmallVector<std::string, 4> OutputConstraints; 6861 SmallVector<unsigned, 4> ClobberRegs; 6862 6863 SmallVector<AsmRewrite, 4> AsmStrRewrites; 6864 6865 // Prime the lexer. 6866 Lex(); 6867 6868 // While we have input, parse each statement. 6869 unsigned InputIdx = 0; 6870 unsigned OutputIdx = 0; 6871 while (getLexer().isNot(AsmToken::Eof)) { 6872 // Parse curly braces marking block start/end. 6873 if (parseCurlyBlockScope(AsmStrRewrites)) 6874 continue; 6875 6876 ParseStatementInfo Info(&AsmStrRewrites); 6877 bool StatementErr = parseStatement(Info, &SI); 6878 6879 if (StatementErr || Info.ParseError) { 6880 // Emit pending errors if any exist. 6881 printPendingErrors(); 6882 return true; 6883 } 6884 6885 // No pending error should exist here. 6886 assert(!hasPendingError() && "unexpected error from parseStatement"); 6887 6888 if (Info.Opcode == ~0U) 6889 continue; 6890 6891 const MCInstrDesc &Desc = MII->get(Info.Opcode); 6892 6893 // Build the list of clobbers, outputs and inputs. 6894 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { 6895 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i]; 6896 6897 // Register operand. 6898 if (Operand.isReg() && !Operand.needAddressOf() && 6899 !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) { 6900 unsigned NumDefs = Desc.getNumDefs(); 6901 // Clobber. 6902 if (NumDefs && Operand.getMCOperandNum() < NumDefs) 6903 ClobberRegs.push_back(Operand.getReg()); 6904 continue; 6905 } 6906 6907 // Expr/Input or Output. 6908 StringRef SymName = Operand.getSymName(); 6909 if (SymName.empty()) 6910 continue; 6911 6912 void *OpDecl = Operand.getOpDecl(); 6913 if (!OpDecl) 6914 continue; 6915 6916 StringRef Constraint = Operand.getConstraint(); 6917 if (Operand.isImm()) { 6918 // Offset as immediate. 6919 if (Operand.isOffsetOfLocal()) 6920 Constraint = "r"; 6921 else 6922 Constraint = "i"; 6923 } 6924 6925 bool isOutput = (i == 1) && Desc.mayStore(); 6926 SMLoc Start = SMLoc::getFromPointer(SymName.data()); 6927 if (isOutput) { 6928 ++InputIdx; 6929 OutputDecls.push_back(OpDecl); 6930 OutputDeclsAddressOf.push_back(Operand.needAddressOf()); 6931 OutputConstraints.push_back(("=" + Constraint).str()); 6932 AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size()); 6933 } else { 6934 InputDecls.push_back(OpDecl); 6935 InputDeclsAddressOf.push_back(Operand.needAddressOf()); 6936 InputConstraints.push_back(Constraint.str()); 6937 if (Desc.OpInfo[i - 1].isBranchTarget()) 6938 AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size()); 6939 else 6940 AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size()); 6941 } 6942 } 6943 6944 // Consider implicit defs to be clobbers. Think of cpuid and push. 6945 ArrayRef<MCPhysReg> ImpDefs(Desc.getImplicitDefs(), 6946 Desc.getNumImplicitDefs()); 6947 ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end()); 6948 } 6949 6950 // Set the number of Outputs and Inputs. 6951 NumOutputs = OutputDecls.size(); 6952 NumInputs = InputDecls.size(); 6953 6954 // Set the unique clobbers. 6955 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end()); 6956 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()), 6957 ClobberRegs.end()); 6958 Clobbers.assign(ClobberRegs.size(), std::string()); 6959 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) { 6960 raw_string_ostream OS(Clobbers[I]); 6961 IP->printRegName(OS, ClobberRegs[I]); 6962 } 6963 6964 // Merge the various outputs and inputs. Output are expected first. 6965 if (NumOutputs || NumInputs) { 6966 unsigned NumExprs = NumOutputs + NumInputs; 6967 OpDecls.resize(NumExprs); 6968 Constraints.resize(NumExprs); 6969 for (unsigned i = 0; i < NumOutputs; ++i) { 6970 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]); 6971 Constraints[i] = OutputConstraints[i]; 6972 } 6973 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { 6974 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]); 6975 Constraints[j] = InputConstraints[i]; 6976 } 6977 } 6978 6979 // Build the IR assembly string. 6980 std::string AsmStringIR; 6981 raw_string_ostream OS(AsmStringIR); 6982 StringRef ASMString = 6983 SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer(); 6984 const char *AsmStart = ASMString.begin(); 6985 const char *AsmEnd = ASMString.end(); 6986 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); 6987 for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) { 6988 const AsmRewrite &AR = *it; 6989 // Check if this has already been covered by another rewrite... 6990 if (AR.Done) 6991 continue; 6992 AsmRewriteKind Kind = AR.Kind; 6993 6994 const char *Loc = AR.Loc.getPointer(); 6995 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); 6996 6997 // Emit everything up to the immediate/expression. 6998 if (unsigned Len = Loc - AsmStart) 6999 OS << StringRef(AsmStart, Len); 7000 7001 // Skip the original expression. 7002 if (Kind == AOK_Skip) { 7003 AsmStart = Loc + AR.Len; 7004 continue; 7005 } 7006 7007 unsigned AdditionalSkip = 0; 7008 // Rewrite expressions in $N notation. 7009 switch (Kind) { 7010 default: 7011 break; 7012 case AOK_IntelExpr: 7013 assert(AR.IntelExp.isValid() && "cannot write invalid intel expression"); 7014 if (AR.IntelExp.NeedBracs) 7015 OS << "["; 7016 if (AR.IntelExp.hasBaseReg()) 7017 OS << AR.IntelExp.BaseReg; 7018 if (AR.IntelExp.hasIndexReg()) 7019 OS << (AR.IntelExp.hasBaseReg() ? " + " : "") 7020 << AR.IntelExp.IndexReg; 7021 if (AR.IntelExp.Scale > 1) 7022 OS << " * $$" << AR.IntelExp.Scale; 7023 if (AR.IntelExp.hasOffset()) { 7024 if (AR.IntelExp.hasRegs()) 7025 OS << " + "; 7026 // Fuse this rewrite with a rewrite of the offset name, if present. 7027 StringRef OffsetName = AR.IntelExp.OffsetName; 7028 SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data()); 7029 size_t OffsetLen = OffsetName.size(); 7030 auto rewrite_it = std::find_if( 7031 it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) { 7032 return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen && 7033 (FusingAR.Kind == AOK_Input || 7034 FusingAR.Kind == AOK_CallInput); 7035 }); 7036 if (rewrite_it == AsmStrRewrites.end()) { 7037 OS << "offset " << OffsetName; 7038 } else if (rewrite_it->Kind == AOK_CallInput) { 7039 OS << "${" << InputIdx++ << ":P}"; 7040 rewrite_it->Done = true; 7041 } else { 7042 OS << '$' << InputIdx++; 7043 rewrite_it->Done = true; 7044 } 7045 } 7046 if (AR.IntelExp.Imm || AR.IntelExp.emitImm()) 7047 OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm; 7048 if (AR.IntelExp.NeedBracs) 7049 OS << "]"; 7050 break; 7051 case AOK_Label: 7052 OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label; 7053 break; 7054 case AOK_Input: 7055 OS << '$' << InputIdx++; 7056 break; 7057 case AOK_CallInput: 7058 OS << "${" << InputIdx++ << ":P}"; 7059 break; 7060 case AOK_Output: 7061 OS << '$' << OutputIdx++; 7062 break; 7063 case AOK_SizeDirective: 7064 switch (AR.Val) { 7065 default: break; 7066 case 8: OS << "byte ptr "; break; 7067 case 16: OS << "word ptr "; break; 7068 case 32: OS << "dword ptr "; break; 7069 case 64: OS << "qword ptr "; break; 7070 case 80: OS << "xword ptr "; break; 7071 case 128: OS << "xmmword ptr "; break; 7072 case 256: OS << "ymmword ptr "; break; 7073 } 7074 break; 7075 case AOK_Emit: 7076 OS << ".byte"; 7077 break; 7078 case AOK_Align: { 7079 // MS alignment directives are measured in bytes. If the native assembler 7080 // measures alignment in bytes, we can pass it straight through. 7081 OS << ".align"; 7082 if (getContext().getAsmInfo()->getAlignmentIsInBytes()) 7083 break; 7084 7085 // Alignment is in log2 form, so print that instead and skip the original 7086 // immediate. 7087 unsigned Val = AR.Val; 7088 OS << ' ' << Val; 7089 assert(Val < 10 && "Expected alignment less then 2^10."); 7090 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; 7091 break; 7092 } 7093 case AOK_EVEN: 7094 OS << ".even"; 7095 break; 7096 case AOK_EndOfStatement: 7097 OS << "\n\t"; 7098 break; 7099 } 7100 7101 // Skip the original expression. 7102 AsmStart = Loc + AR.Len + AdditionalSkip; 7103 } 7104 7105 // Emit the remainder of the asm string. 7106 if (AsmStart != AsmEnd) 7107 OS << StringRef(AsmStart, AsmEnd - AsmStart); 7108 7109 AsmString = OS.str(); 7110 return false; 7111 } 7112 7113 /// Create an MCAsmParser instance. 7114 MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C, 7115 MCStreamer &Out, const MCAsmInfo &MAI, 7116 unsigned CB) { 7117 return new MasmParser(SM, C, Out, MAI, CB); 7118 } 7119