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