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