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