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