1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class implements the parser for assembly files. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ADT/APFloat.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/Twine.h" 19 #include "llvm/MC/MCAsmInfo.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCDwarf.h" 22 #include "llvm/MC/MCExpr.h" 23 #include "llvm/MC/MCInstPrinter.h" 24 #include "llvm/MC/MCInstrInfo.h" 25 #include "llvm/MC/MCObjectFileInfo.h" 26 #include "llvm/MC/MCParser/AsmCond.h" 27 #include "llvm/MC/MCParser/AsmLexer.h" 28 #include "llvm/MC/MCParser/MCAsmParser.h" 29 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 30 #include "llvm/MC/MCRegisterInfo.h" 31 #include "llvm/MC/MCSectionMachO.h" 32 #include "llvm/MC/MCStreamer.h" 33 #include "llvm/MC/MCSymbol.h" 34 #include "llvm/MC/MCTargetAsmParser.h" 35 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/ErrorHandling.h" 37 #include "llvm/Support/MathExtras.h" 38 #include "llvm/Support/MemoryBuffer.h" 39 #include "llvm/Support/SourceMgr.h" 40 #include "llvm/Support/raw_ostream.h" 41 #include <cctype> 42 #include <deque> 43 #include <set> 44 #include <string> 45 #include <vector> 46 using namespace llvm; 47 48 static cl::opt<bool> 49 FatalAssemblerWarnings("fatal-assembler-warnings", 50 cl::desc("Consider warnings as error")); 51 52 MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {} 53 54 namespace { 55 /// \brief Helper types for tracking macro definitions. 56 typedef std::vector<AsmToken> MCAsmMacroArgument; 57 typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments; 58 59 struct MCAsmMacroParameter { 60 StringRef Name; 61 MCAsmMacroArgument Value; 62 bool Required; 63 bool Vararg; 64 65 MCAsmMacroParameter() : Required(false), Vararg(false) {} 66 }; 67 68 typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters; 69 70 struct MCAsmMacro { 71 StringRef Name; 72 StringRef Body; 73 MCAsmMacroParameters Parameters; 74 75 public: 76 MCAsmMacro(StringRef N, StringRef B, ArrayRef<MCAsmMacroParameter> P) : 77 Name(N), Body(B), Parameters(P) {} 78 }; 79 80 /// \brief Helper class for storing information about an active macro 81 /// instantiation. 82 struct MacroInstantiation { 83 /// The macro instantiation with substitutions. 84 MemoryBuffer *Instantiation; 85 86 /// The location of the instantiation. 87 SMLoc InstantiationLoc; 88 89 /// The buffer where parsing should resume upon instantiation completion. 90 int ExitBuffer; 91 92 /// The location where parsing should resume upon instantiation completion. 93 SMLoc ExitLoc; 94 95 /// The depth of TheCondStack at the start of the instantiation. 96 size_t CondStackDepth; 97 98 public: 99 MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I, 100 size_t CondStackDepth); 101 }; 102 103 struct ParseStatementInfo { 104 /// \brief The parsed operands from the last parsed statement. 105 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands; 106 107 /// \brief The opcode from the last parsed instruction. 108 unsigned Opcode; 109 110 /// \brief Was there an error parsing the inline assembly? 111 bool ParseError; 112 113 SmallVectorImpl<AsmRewrite> *AsmRewrites; 114 115 ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {} 116 ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) 117 : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {} 118 }; 119 120 /// \brief The concrete assembly parser instance. 121 class AsmParser : public MCAsmParser { 122 AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION; 123 void operator=(const AsmParser &) LLVM_DELETED_FUNCTION; 124 private: 125 AsmLexer Lexer; 126 MCContext &Ctx; 127 MCStreamer &Out; 128 const MCAsmInfo &MAI; 129 SourceMgr &SrcMgr; 130 SourceMgr::DiagHandlerTy SavedDiagHandler; 131 void *SavedDiagContext; 132 MCAsmParserExtension *PlatformParser; 133 134 /// This is the current buffer index we're lexing from as managed by the 135 /// SourceMgr object. 136 unsigned CurBuffer; 137 138 AsmCond TheCondState; 139 std::vector<AsmCond> TheCondStack; 140 141 /// \brief maps directive names to handler methods in parser 142 /// extensions. Extensions register themselves in this map by calling 143 /// addDirectiveHandler. 144 StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap; 145 146 /// \brief Map of currently defined macros. 147 StringMap<MCAsmMacro*> MacroMap; 148 149 /// \brief Stack of active macro instantiations. 150 std::vector<MacroInstantiation*> ActiveMacros; 151 152 /// \brief List of bodies of anonymous macros. 153 std::deque<MCAsmMacro> MacroLikeBodies; 154 155 /// Boolean tracking whether macro substitution is enabled. 156 unsigned MacrosEnabledFlag : 1; 157 158 /// Flag tracking whether any errors have been encountered. 159 unsigned HadError : 1; 160 161 /// The values from the last parsed cpp hash file line comment if any. 162 StringRef CppHashFilename; 163 int64_t CppHashLineNumber; 164 SMLoc CppHashLoc; 165 unsigned CppHashBuf; 166 /// When generating dwarf for assembly source files we need to calculate the 167 /// logical line number based on the last parsed cpp hash file line comment 168 /// and current line. Since this is slow and messes up the SourceMgr's 169 /// cache we save the last info we queried with SrcMgr.FindLineNumber(). 170 SMLoc LastQueryIDLoc; 171 unsigned LastQueryBuffer; 172 unsigned LastQueryLine; 173 174 /// AssemblerDialect. ~OU means unset value and use value provided by MAI. 175 unsigned AssemblerDialect; 176 177 /// \brief is Darwin compatibility enabled? 178 bool IsDarwin; 179 180 /// \brief Are we parsing ms-style inline assembly? 181 bool ParsingInlineAsm; 182 183 public: 184 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 185 const MCAsmInfo &MAI); 186 virtual ~AsmParser(); 187 188 bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; 189 190 void addDirectiveHandler(StringRef Directive, 191 ExtensionDirectiveHandler Handler) override { 192 ExtensionDirectiveMap[Directive] = Handler; 193 } 194 195 public: 196 /// @name MCAsmParser Interface 197 /// { 198 199 SourceMgr &getSourceManager() override { return SrcMgr; } 200 MCAsmLexer &getLexer() override { return Lexer; } 201 MCContext &getContext() override { return Ctx; } 202 MCStreamer &getStreamer() override { return Out; } 203 unsigned getAssemblerDialect() override { 204 if (AssemblerDialect == ~0U) 205 return MAI.getAssemblerDialect(); 206 else 207 return AssemblerDialect; 208 } 209 void setAssemblerDialect(unsigned i) override { 210 AssemblerDialect = i; 211 } 212 213 void Note(SMLoc L, const Twine &Msg, 214 ArrayRef<SMRange> Ranges = None) override; 215 bool Warning(SMLoc L, const Twine &Msg, 216 ArrayRef<SMRange> Ranges = None) override; 217 bool Error(SMLoc L, const Twine &Msg, 218 ArrayRef<SMRange> Ranges = None) override; 219 220 const AsmToken &Lex() override; 221 222 void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; } 223 bool isParsingInlineAsm() override { return ParsingInlineAsm; } 224 225 bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, 226 unsigned &NumOutputs, unsigned &NumInputs, 227 SmallVectorImpl<std::pair<void *,bool> > &OpDecls, 228 SmallVectorImpl<std::string> &Constraints, 229 SmallVectorImpl<std::string> &Clobbers, 230 const MCInstrInfo *MII, const MCInstPrinter *IP, 231 MCAsmParserSemaCallback &SI) override; 232 233 bool parseExpression(const MCExpr *&Res); 234 bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override; 235 bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; 236 bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override; 237 bool parseAbsoluteExpression(int64_t &Res) override; 238 239 /// \brief Parse an identifier or string (as a quoted identifier) 240 /// and set \p Res to the identifier contents. 241 bool parseIdentifier(StringRef &Res) override; 242 void eatToEndOfStatement() override; 243 244 void checkForValidSection() override; 245 /// } 246 247 private: 248 249 bool parseStatement(ParseStatementInfo &Info); 250 void eatToEndOfLine(); 251 bool parseCppHashLineFilenameComment(const SMLoc &L); 252 253 void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, 254 ArrayRef<MCAsmMacroParameter> Parameters); 255 bool expandMacro(raw_svector_ostream &OS, StringRef Body, 256 ArrayRef<MCAsmMacroParameter> Parameters, 257 ArrayRef<MCAsmMacroArgument> A, 258 const SMLoc &L); 259 260 /// \brief Are macros enabled in the parser? 261 bool areMacrosEnabled() {return MacrosEnabledFlag;} 262 263 /// \brief Control a flag in the parser that enables or disables macros. 264 void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;} 265 266 /// \brief Lookup a previously defined macro. 267 /// \param Name Macro name. 268 /// \returns Pointer to macro. NULL if no such macro was defined. 269 const MCAsmMacro* lookupMacro(StringRef Name); 270 271 /// \brief Define a new macro with the given name and information. 272 void defineMacro(StringRef Name, const MCAsmMacro& Macro); 273 274 /// \brief Undefine a macro. If no such macro was defined, it's a no-op. 275 void undefineMacro(StringRef Name); 276 277 /// \brief Are we inside a macro instantiation? 278 bool isInsideMacroInstantiation() {return !ActiveMacros.empty();} 279 280 /// \brief Handle entry to macro instantiation. 281 /// 282 /// \param M The macro. 283 /// \param NameLoc Instantiation location. 284 bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc); 285 286 /// \brief Handle exit from macro instantiation. 287 void handleMacroExit(); 288 289 /// \brief Extract AsmTokens for a macro argument. 290 bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg); 291 292 /// \brief Parse all macro arguments for a given macro. 293 bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); 294 295 void printMacroInstantiations(); 296 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, 297 ArrayRef<SMRange> Ranges = None) const { 298 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); 299 } 300 static void DiagHandler(const SMDiagnostic &Diag, void *Context); 301 302 /// \brief Enter the specified file. This returns true on failure. 303 bool enterIncludeFile(const std::string &Filename); 304 305 /// \brief Process the specified file for the .incbin directive. 306 /// This returns true on failure. 307 bool processIncbinFile(const std::string &Filename); 308 309 /// \brief Reset the current lexer position to that given by \p Loc. The 310 /// current token is not set; clients should ensure Lex() is called 311 /// subsequently. 312 /// 313 /// \param InBuffer If not 0, should be the known buffer id that contains the 314 /// location. 315 void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0); 316 317 /// \brief Parse up to the end of statement and a return the contents from the 318 /// current token until the end of the statement; the current token on exit 319 /// will be either the EndOfStatement or EOF. 320 StringRef parseStringToEndOfStatement() override; 321 322 /// \brief Parse until the end of a statement or a comma is encountered, 323 /// return the contents from the current token up to the end or comma. 324 StringRef parseStringToComma(); 325 326 bool parseAssignment(StringRef Name, bool allow_redef, 327 bool NoDeadStrip = false); 328 329 bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); 330 bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); 331 bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); 332 333 bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); 334 335 // Generic (target and platform independent) directive parsing. 336 enum DirectiveKind { 337 DK_NO_DIRECTIVE, // Placeholder 338 DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT, 339 DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA, 340 DK_SINGLE, DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW, 341 DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR, 342 DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK, 343 DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, 344 DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN, 345 DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, 346 DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, 347 DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, 348 DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB, 349 DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, 350 DK_ELSEIF, DK_ELSE, DK_ENDIF, 351 DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, 352 DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, 353 DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, 354 DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA, 355 DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE, 356 DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, 357 DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, 358 DK_MACROS_ON, DK_MACROS_OFF, 359 DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM, 360 DK_SLEB128, DK_ULEB128, 361 DK_ERR, DK_ERROR, DK_WARNING, 362 DK_END 363 }; 364 365 /// \brief Maps directive name --> DirectiveKind enum, for 366 /// directives parsed by this class. 367 StringMap<DirectiveKind> DirectiveKindMap; 368 369 // ".ascii", ".asciz", ".string" 370 bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); 371 bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ... 372 bool parseDirectiveOctaValue(); // ".octa" 373 bool parseDirectiveRealValue(const fltSemantics &); // ".single", ... 374 bool parseDirectiveFill(); // ".fill" 375 bool parseDirectiveZero(); // ".zero" 376 // ".set", ".equ", ".equiv" 377 bool parseDirectiveSet(StringRef IDVal, bool allow_redef); 378 bool parseDirectiveOrg(); // ".org" 379 // ".align{,32}", ".p2align{,w,l}" 380 bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize); 381 382 // ".file", ".line", ".loc", ".stabs" 383 bool parseDirectiveFile(SMLoc DirectiveLoc); 384 bool parseDirectiveLine(); 385 bool parseDirectiveLoc(); 386 bool parseDirectiveStabs(); 387 388 // .cfi directives 389 bool parseDirectiveCFIRegister(SMLoc DirectiveLoc); 390 bool parseDirectiveCFIWindowSave(); 391 bool parseDirectiveCFISections(); 392 bool parseDirectiveCFIStartProc(); 393 bool parseDirectiveCFIEndProc(); 394 bool parseDirectiveCFIDefCfaOffset(); 395 bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc); 396 bool parseDirectiveCFIAdjustCfaOffset(); 397 bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc); 398 bool parseDirectiveCFIOffset(SMLoc DirectiveLoc); 399 bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc); 400 bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality); 401 bool parseDirectiveCFIRememberState(); 402 bool parseDirectiveCFIRestoreState(); 403 bool parseDirectiveCFISameValue(SMLoc DirectiveLoc); 404 bool parseDirectiveCFIRestore(SMLoc DirectiveLoc); 405 bool parseDirectiveCFIEscape(); 406 bool parseDirectiveCFISignalFrame(); 407 bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc); 408 409 // macro directives 410 bool parseDirectivePurgeMacro(SMLoc DirectiveLoc); 411 bool parseDirectiveExitMacro(StringRef Directive); 412 bool parseDirectiveEndMacro(StringRef Directive); 413 bool parseDirectiveMacro(SMLoc DirectiveLoc); 414 bool parseDirectiveMacrosOnOff(StringRef Directive); 415 416 // ".bundle_align_mode" 417 bool parseDirectiveBundleAlignMode(); 418 // ".bundle_lock" 419 bool parseDirectiveBundleLock(); 420 // ".bundle_unlock" 421 bool parseDirectiveBundleUnlock(); 422 423 // ".space", ".skip" 424 bool parseDirectiveSpace(StringRef IDVal); 425 426 // .sleb128 (Signed=true) and .uleb128 (Signed=false) 427 bool parseDirectiveLEB128(bool Signed); 428 429 /// \brief Parse a directive like ".globl" which 430 /// accepts a single symbol (which should be a label or an external). 431 bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr); 432 433 bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" 434 435 bool parseDirectiveAbort(); // ".abort" 436 bool parseDirectiveInclude(); // ".include" 437 bool parseDirectiveIncbin(); // ".incbin" 438 439 // ".if", ".ifeq", ".ifge", ".ifgt" , ".ifle", ".iflt" or ".ifne" 440 bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind); 441 // ".ifb" or ".ifnb", depending on ExpectBlank. 442 bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); 443 // ".ifc" or ".ifnc", depending on ExpectEqual. 444 bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); 445 // ".ifeqs" 446 bool parseDirectiveIfeqs(SMLoc DirectiveLoc); 447 // ".ifdef" or ".ifndef", depending on expect_defined 448 bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); 449 bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" 450 bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else" 451 bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif 452 bool parseEscapedString(std::string &Data) override; 453 454 const MCExpr *applyModifierToExpr(const MCExpr *E, 455 MCSymbolRefExpr::VariantKind Variant); 456 457 // Macro-like directives 458 MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc); 459 void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 460 raw_svector_ostream &OS); 461 bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive); 462 bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" 463 bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" 464 bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" 465 466 // "_emit" or "__emit" 467 bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, 468 size_t Len); 469 470 // "align" 471 bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); 472 473 // "end" 474 bool parseDirectiveEnd(SMLoc DirectiveLoc); 475 476 // ".err" or ".error" 477 bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage); 478 479 // ".warning" 480 bool parseDirectiveWarning(SMLoc DirectiveLoc); 481 482 void initializeDirectiveKindMap(); 483 }; 484 } 485 486 namespace llvm { 487 488 extern MCAsmParserExtension *createDarwinAsmParser(); 489 extern MCAsmParserExtension *createELFAsmParser(); 490 extern MCAsmParserExtension *createCOFFAsmParser(); 491 492 } 493 494 enum { DEFAULT_ADDRSPACE = 0 }; 495 496 AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, 497 const MCAsmInfo &_MAI) 498 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), 499 PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()), 500 MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0), 501 AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { 502 // Save the old handler. 503 SavedDiagHandler = SrcMgr.getDiagHandler(); 504 SavedDiagContext = SrcMgr.getDiagContext(); 505 // Set our own handler which calls the saved handler. 506 SrcMgr.setDiagHandler(DiagHandler, this); 507 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 508 509 // Initialize the platform / file format parser. 510 switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { 511 case MCObjectFileInfo::IsCOFF: 512 PlatformParser = createCOFFAsmParser(); 513 PlatformParser->Initialize(*this); 514 break; 515 case MCObjectFileInfo::IsMachO: 516 PlatformParser = createDarwinAsmParser(); 517 PlatformParser->Initialize(*this); 518 IsDarwin = true; 519 break; 520 case MCObjectFileInfo::IsELF: 521 PlatformParser = createELFAsmParser(); 522 PlatformParser->Initialize(*this); 523 break; 524 } 525 526 initializeDirectiveKindMap(); 527 } 528 529 AsmParser::~AsmParser() { 530 assert((HadError || ActiveMacros.empty()) && 531 "Unexpected active macro instantiation!"); 532 533 // Destroy any macros. 534 for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(), 535 ie = MacroMap.end(); 536 it != ie; ++it) 537 delete it->getValue(); 538 539 delete PlatformParser; 540 } 541 542 void AsmParser::printMacroInstantiations() { 543 // Print the active macro instantiation stack. 544 for (std::vector<MacroInstantiation *>::const_reverse_iterator 545 it = ActiveMacros.rbegin(), 546 ie = ActiveMacros.rend(); 547 it != ie; ++it) 548 printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, 549 "while in macro instantiation"); 550 } 551 552 void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 553 printMessage(L, SourceMgr::DK_Note, Msg, Ranges); 554 printMacroInstantiations(); 555 } 556 557 bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 558 if (FatalAssemblerWarnings) 559 return Error(L, Msg, Ranges); 560 printMessage(L, SourceMgr::DK_Warning, Msg, Ranges); 561 printMacroInstantiations(); 562 return false; 563 } 564 565 bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 566 HadError = true; 567 printMessage(L, SourceMgr::DK_Error, Msg, Ranges); 568 printMacroInstantiations(); 569 return true; 570 } 571 572 bool AsmParser::enterIncludeFile(const std::string &Filename) { 573 std::string IncludedFile; 574 unsigned NewBuf = 575 SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 576 if (!NewBuf) 577 return true; 578 579 CurBuffer = NewBuf; 580 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 581 return false; 582 } 583 584 /// Process the specified .incbin file by searching for it in the include paths 585 /// then just emitting the byte contents of the file to the streamer. This 586 /// returns true on failure. 587 bool AsmParser::processIncbinFile(const std::string &Filename) { 588 std::string IncludedFile; 589 unsigned NewBuf = 590 SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 591 if (!NewBuf) 592 return true; 593 594 // Pick up the bytes from the file and emit them. 595 getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer()); 596 return false; 597 } 598 599 void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) { 600 CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc); 601 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), 602 Loc.getPointer()); 603 } 604 605 const AsmToken &AsmParser::Lex() { 606 const AsmToken *tok = &Lexer.Lex(); 607 608 if (tok->is(AsmToken::Eof)) { 609 // If this is the end of an included file, pop the parent file off the 610 // include stack. 611 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 612 if (ParentIncludeLoc != SMLoc()) { 613 jumpToLoc(ParentIncludeLoc); 614 tok = &Lexer.Lex(); 615 } 616 } 617 618 if (tok->is(AsmToken::Error)) 619 Error(Lexer.getErrLoc(), Lexer.getErr()); 620 621 return *tok; 622 } 623 624 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 625 // Create the initial section, if requested. 626 if (!NoInitialTextSection) 627 Out.InitSections(); 628 629 // Prime the lexer. 630 Lex(); 631 632 HadError = false; 633 AsmCond StartingCondState = TheCondState; 634 635 // If we are generating dwarf for assembly source files save the initial text 636 // section and generate a .file directive. 637 if (getContext().getGenDwarfForAssembly()) { 638 MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); 639 getStreamer().EmitLabel(SectionStartSym); 640 auto InsertResult = getContext().addGenDwarfSection( 641 getStreamer().getCurrentSection().first); 642 assert(InsertResult.second && ".text section should not have debug info yet"); 643 InsertResult.first->second.first = SectionStartSym; 644 getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( 645 0, StringRef(), getContext().getMainFileName())); 646 } 647 648 // While we have input, parse each statement. 649 while (Lexer.isNot(AsmToken::Eof)) { 650 ParseStatementInfo Info; 651 if (!parseStatement(Info)) 652 continue; 653 654 // We had an error, validate that one was emitted and recover by skipping to 655 // the next line. 656 assert(HadError && "Parse statement returned an error, but none emitted!"); 657 eatToEndOfStatement(); 658 } 659 660 if (TheCondState.TheCond != StartingCondState.TheCond || 661 TheCondState.Ignore != StartingCondState.Ignore) 662 return TokError("unmatched .ifs or .elses"); 663 664 // Check to see there are no empty DwarfFile slots. 665 const auto &LineTables = getContext().getMCDwarfLineTables(); 666 if (!LineTables.empty()) { 667 unsigned Index = 0; 668 for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) { 669 if (File.Name.empty() && Index != 0) 670 TokError("unassigned file number: " + Twine(Index) + 671 " for .file directives"); 672 ++Index; 673 } 674 } 675 676 // Check to see that all assembler local symbols were actually defined. 677 // Targets that don't do subsections via symbols may not want this, though, 678 // so conservatively exclude them. Only do this if we're finalizing, though, 679 // as otherwise we won't necessarilly have seen everything yet. 680 if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) { 681 const MCContext::SymbolTable &Symbols = getContext().getSymbols(); 682 for (MCContext::SymbolTable::const_iterator i = Symbols.begin(), 683 e = Symbols.end(); 684 i != e; ++i) { 685 MCSymbol *Sym = i->getValue(); 686 // Variable symbols may not be marked as defined, so check those 687 // explicitly. If we know it's a variable, we have a definition for 688 // the purposes of this check. 689 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) 690 // FIXME: We would really like to refer back to where the symbol was 691 // first referenced for a source location. We need to add something 692 // to track that. Currently, we just point to the end of the file. 693 printMessage( 694 getLexer().getLoc(), SourceMgr::DK_Error, 695 "assembler local symbol '" + Sym->getName() + "' not defined"); 696 } 697 } 698 699 // Finalize the output stream if there are no errors and if the client wants 700 // us to. 701 if (!HadError && !NoFinalize) 702 Out.Finish(); 703 704 return HadError; 705 } 706 707 void AsmParser::checkForValidSection() { 708 if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) { 709 TokError("expected section directive before assembly directive"); 710 Out.InitSections(); 711 } 712 } 713 714 /// \brief Throw away the rest of the line for testing purposes. 715 void AsmParser::eatToEndOfStatement() { 716 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) 717 Lex(); 718 719 // Eat EOL. 720 if (Lexer.is(AsmToken::EndOfStatement)) 721 Lex(); 722 } 723 724 StringRef AsmParser::parseStringToEndOfStatement() { 725 const char *Start = getTok().getLoc().getPointer(); 726 727 while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) 728 Lex(); 729 730 const char *End = getTok().getLoc().getPointer(); 731 return StringRef(Start, End - Start); 732 } 733 734 StringRef AsmParser::parseStringToComma() { 735 const char *Start = getTok().getLoc().getPointer(); 736 737 while (Lexer.isNot(AsmToken::EndOfStatement) && 738 Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof)) 739 Lex(); 740 741 const char *End = getTok().getLoc().getPointer(); 742 return StringRef(Start, End - Start); 743 } 744 745 /// \brief Parse a paren expression and return it. 746 /// NOTE: This assumes the leading '(' has already been consumed. 747 /// 748 /// parenexpr ::= expr) 749 /// 750 bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 751 if (parseExpression(Res)) 752 return true; 753 if (Lexer.isNot(AsmToken::RParen)) 754 return TokError("expected ')' in parentheses expression"); 755 EndLoc = Lexer.getTok().getEndLoc(); 756 Lex(); 757 return false; 758 } 759 760 /// \brief Parse a bracket expression and return it. 761 /// NOTE: This assumes the leading '[' has already been consumed. 762 /// 763 /// bracketexpr ::= expr] 764 /// 765 bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { 766 if (parseExpression(Res)) 767 return true; 768 if (Lexer.isNot(AsmToken::RBrac)) 769 return TokError("expected ']' in brackets expression"); 770 EndLoc = Lexer.getTok().getEndLoc(); 771 Lex(); 772 return false; 773 } 774 775 /// \brief Parse a primary expression and return it. 776 /// primaryexpr ::= (parenexpr 777 /// primaryexpr ::= symbol 778 /// primaryexpr ::= number 779 /// primaryexpr ::= '.' 780 /// primaryexpr ::= ~,+,- primaryexpr 781 bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 782 SMLoc FirstTokenLoc = getLexer().getLoc(); 783 AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); 784 switch (FirstTokenKind) { 785 default: 786 return TokError("unknown token in expression"); 787 // If we have an error assume that we've already handled it. 788 case AsmToken::Error: 789 return true; 790 case AsmToken::Exclaim: 791 Lex(); // Eat the operator. 792 if (parsePrimaryExpr(Res, EndLoc)) 793 return true; 794 Res = MCUnaryExpr::CreateLNot(Res, getContext()); 795 return false; 796 case AsmToken::Dollar: 797 case AsmToken::At: 798 case AsmToken::String: 799 case AsmToken::Identifier: { 800 StringRef Identifier; 801 if (parseIdentifier(Identifier)) { 802 if (FirstTokenKind == AsmToken::Dollar) { 803 if (Lexer.getMAI().getDollarIsPC()) { 804 // This is a '$' reference, which references the current PC. Emit a 805 // temporary label to the streamer and refer to it. 806 MCSymbol *Sym = Ctx.CreateTempSymbol(); 807 Out.EmitLabel(Sym); 808 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 809 getContext()); 810 EndLoc = FirstTokenLoc; 811 return false; 812 } 813 return Error(FirstTokenLoc, "invalid token in expression"); 814 } 815 } 816 // Parse symbol variant 817 std::pair<StringRef, StringRef> Split; 818 if (!MAI.useParensForSymbolVariant()) { 819 if (FirstTokenKind == AsmToken::String) { 820 if (Lexer.is(AsmToken::At)) { 821 Lexer.Lex(); // eat @ 822 SMLoc AtLoc = getLexer().getLoc(); 823 StringRef VName; 824 if (parseIdentifier(VName)) 825 return Error(AtLoc, "expected symbol variant after '@'"); 826 827 Split = std::make_pair(Identifier, VName); 828 } 829 } else { 830 Split = Identifier.split('@'); 831 } 832 } else if (Lexer.is(AsmToken::LParen)) { 833 Lexer.Lex(); // eat ( 834 StringRef VName; 835 parseIdentifier(VName); 836 if (Lexer.isNot(AsmToken::RParen)) { 837 return Error(Lexer.getTok().getLoc(), 838 "unexpected token in variant, expected ')'"); 839 } 840 Lexer.Lex(); // eat ) 841 Split = std::make_pair(Identifier, VName); 842 } 843 844 EndLoc = SMLoc::getFromPointer(Identifier.end()); 845 846 // This is a symbol reference. 847 StringRef SymbolName = Identifier; 848 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 849 850 // Lookup the symbol variant if used. 851 if (Split.second.size()) { 852 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 853 if (Variant != MCSymbolRefExpr::VK_Invalid) { 854 SymbolName = Split.first; 855 } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) { 856 Variant = MCSymbolRefExpr::VK_None; 857 } else { 858 return Error(SMLoc::getFromPointer(Split.second.begin()), 859 "invalid variant '" + Split.second + "'"); 860 } 861 } 862 863 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); 864 865 // If this is an absolute variable reference, substitute it now to preserve 866 // semantics in the face of reassignment. 867 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) { 868 if (Variant) 869 return Error(EndLoc, "unexpected modifier on variable reference"); 870 871 Res = Sym->getVariableValue(); 872 return false; 873 } 874 875 // Otherwise create a symbol ref. 876 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 877 return false; 878 } 879 case AsmToken::BigNum: 880 return TokError("literal value out of range for directive"); 881 case AsmToken::Integer: { 882 SMLoc Loc = getTok().getLoc(); 883 int64_t IntVal = getTok().getIntVal(); 884 Res = MCConstantExpr::Create(IntVal, getContext()); 885 EndLoc = Lexer.getTok().getEndLoc(); 886 Lex(); // Eat token. 887 // Look for 'b' or 'f' following an Integer as a directional label 888 if (Lexer.getKind() == AsmToken::Identifier) { 889 StringRef IDVal = getTok().getString(); 890 // Lookup the symbol variant if used. 891 std::pair<StringRef, StringRef> Split = IDVal.split('@'); 892 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 893 if (Split.first.size() != IDVal.size()) { 894 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 895 if (Variant == MCSymbolRefExpr::VK_Invalid) 896 return TokError("invalid variant '" + Split.second + "'"); 897 IDVal = Split.first; 898 } 899 if (IDVal == "f" || IDVal == "b") { 900 MCSymbol *Sym = 901 Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "b"); 902 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 903 if (IDVal == "b" && Sym->isUndefined()) 904 return Error(Loc, "invalid reference to undefined symbol"); 905 EndLoc = Lexer.getTok().getEndLoc(); 906 Lex(); // Eat identifier. 907 } 908 } 909 return false; 910 } 911 case AsmToken::Real: { 912 APFloat RealVal(APFloat::IEEEdouble, getTok().getString()); 913 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 914 Res = MCConstantExpr::Create(IntVal, getContext()); 915 EndLoc = Lexer.getTok().getEndLoc(); 916 Lex(); // Eat token. 917 return false; 918 } 919 case AsmToken::Dot: { 920 // This is a '.' reference, which references the current PC. Emit a 921 // temporary label to the streamer and refer to it. 922 MCSymbol *Sym = Ctx.CreateTempSymbol(); 923 Out.EmitLabel(Sym); 924 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 925 EndLoc = Lexer.getTok().getEndLoc(); 926 Lex(); // Eat identifier. 927 return false; 928 } 929 case AsmToken::LParen: 930 Lex(); // Eat the '('. 931 return parseParenExpr(Res, EndLoc); 932 case AsmToken::LBrac: 933 if (!PlatformParser->HasBracketExpressions()) 934 return TokError("brackets expression not supported on this target"); 935 Lex(); // Eat the '['. 936 return parseBracketExpr(Res, EndLoc); 937 case AsmToken::Minus: 938 Lex(); // Eat the operator. 939 if (parsePrimaryExpr(Res, EndLoc)) 940 return true; 941 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 942 return false; 943 case AsmToken::Plus: 944 Lex(); // Eat the operator. 945 if (parsePrimaryExpr(Res, EndLoc)) 946 return true; 947 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 948 return false; 949 case AsmToken::Tilde: 950 Lex(); // Eat the operator. 951 if (parsePrimaryExpr(Res, EndLoc)) 952 return true; 953 Res = MCUnaryExpr::CreateNot(Res, getContext()); 954 return false; 955 } 956 } 957 958 bool AsmParser::parseExpression(const MCExpr *&Res) { 959 SMLoc EndLoc; 960 return parseExpression(Res, EndLoc); 961 } 962 963 const MCExpr * 964 AsmParser::applyModifierToExpr(const MCExpr *E, 965 MCSymbolRefExpr::VariantKind Variant) { 966 // Ask the target implementation about this expression first. 967 const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx); 968 if (NewE) 969 return NewE; 970 // Recurse over the given expression, rebuilding it to apply the given variant 971 // if there is exactly one symbol. 972 switch (E->getKind()) { 973 case MCExpr::Target: 974 case MCExpr::Constant: 975 return nullptr; 976 977 case MCExpr::SymbolRef: { 978 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 979 980 if (SRE->getKind() != MCSymbolRefExpr::VK_None) { 981 TokError("invalid variant on expression '" + getTok().getIdentifier() + 982 "' (already modified)"); 983 return E; 984 } 985 986 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 987 } 988 989 case MCExpr::Unary: { 990 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 991 const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant); 992 if (!Sub) 993 return nullptr; 994 return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); 995 } 996 997 case MCExpr::Binary: { 998 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 999 const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant); 1000 const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant); 1001 1002 if (!LHS && !RHS) 1003 return nullptr; 1004 1005 if (!LHS) 1006 LHS = BE->getLHS(); 1007 if (!RHS) 1008 RHS = BE->getRHS(); 1009 1010 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 1011 } 1012 } 1013 1014 llvm_unreachable("Invalid expression kind!"); 1015 } 1016 1017 /// \brief Parse an expression and return it. 1018 /// 1019 /// expr ::= expr &&,|| expr -> lowest. 1020 /// expr ::= expr |,^,&,! expr 1021 /// expr ::= expr ==,!=,<>,<,<=,>,>= expr 1022 /// expr ::= expr <<,>> expr 1023 /// expr ::= expr +,- expr 1024 /// expr ::= expr *,/,% expr -> highest. 1025 /// expr ::= primaryexpr 1026 /// 1027 bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 1028 // Parse the expression. 1029 Res = nullptr; 1030 if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc)) 1031 return true; 1032 1033 // As a special case, we support 'a op b @ modifier' by rewriting the 1034 // expression to include the modifier. This is inefficient, but in general we 1035 // expect users to use 'a@modifier op b'. 1036 if (Lexer.getKind() == AsmToken::At) { 1037 Lex(); 1038 1039 if (Lexer.isNot(AsmToken::Identifier)) 1040 return TokError("unexpected symbol modifier following '@'"); 1041 1042 MCSymbolRefExpr::VariantKind Variant = 1043 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); 1044 if (Variant == MCSymbolRefExpr::VK_Invalid) 1045 return TokError("invalid variant '" + getTok().getIdentifier() + "'"); 1046 1047 const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant); 1048 if (!ModifiedRes) { 1049 return TokError("invalid modifier '" + getTok().getIdentifier() + 1050 "' (no symbols present)"); 1051 } 1052 1053 Res = ModifiedRes; 1054 Lex(); 1055 } 1056 1057 // Try to constant fold it up front, if possible. 1058 int64_t Value; 1059 if (Res->EvaluateAsAbsolute(Value)) 1060 Res = MCConstantExpr::Create(Value, getContext()); 1061 1062 return false; 1063 } 1064 1065 bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 1066 Res = nullptr; 1067 return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc); 1068 } 1069 1070 bool AsmParser::parseAbsoluteExpression(int64_t &Res) { 1071 const MCExpr *Expr; 1072 1073 SMLoc StartLoc = Lexer.getLoc(); 1074 if (parseExpression(Expr)) 1075 return true; 1076 1077 if (!Expr->EvaluateAsAbsolute(Res)) 1078 return Error(StartLoc, "expected absolute expression"); 1079 1080 return false; 1081 } 1082 1083 static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 1084 MCBinaryExpr::Opcode &Kind) { 1085 switch (K) { 1086 default: 1087 return 0; // not a binop. 1088 1089 // Lowest Precedence: &&, || 1090 case AsmToken::AmpAmp: 1091 Kind = MCBinaryExpr::LAnd; 1092 return 1; 1093 case AsmToken::PipePipe: 1094 Kind = MCBinaryExpr::LOr; 1095 return 1; 1096 1097 // Low Precedence: |, &, ^ 1098 // 1099 // FIXME: gas seems to support '!' as an infix operator? 1100 case AsmToken::Pipe: 1101 Kind = MCBinaryExpr::Or; 1102 return 2; 1103 case AsmToken::Caret: 1104 Kind = MCBinaryExpr::Xor; 1105 return 2; 1106 case AsmToken::Amp: 1107 Kind = MCBinaryExpr::And; 1108 return 2; 1109 1110 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= 1111 case AsmToken::EqualEqual: 1112 Kind = MCBinaryExpr::EQ; 1113 return 3; 1114 case AsmToken::ExclaimEqual: 1115 case AsmToken::LessGreater: 1116 Kind = MCBinaryExpr::NE; 1117 return 3; 1118 case AsmToken::Less: 1119 Kind = MCBinaryExpr::LT; 1120 return 3; 1121 case AsmToken::LessEqual: 1122 Kind = MCBinaryExpr::LTE; 1123 return 3; 1124 case AsmToken::Greater: 1125 Kind = MCBinaryExpr::GT; 1126 return 3; 1127 case AsmToken::GreaterEqual: 1128 Kind = MCBinaryExpr::GTE; 1129 return 3; 1130 1131 // Intermediate Precedence: <<, >> 1132 case AsmToken::LessLess: 1133 Kind = MCBinaryExpr::Shl; 1134 return 4; 1135 case AsmToken::GreaterGreater: 1136 Kind = MCBinaryExpr::Shr; 1137 return 4; 1138 1139 // High Intermediate Precedence: +, - 1140 case AsmToken::Plus: 1141 Kind = MCBinaryExpr::Add; 1142 return 5; 1143 case AsmToken::Minus: 1144 Kind = MCBinaryExpr::Sub; 1145 return 5; 1146 1147 // Highest Precedence: *, /, % 1148 case AsmToken::Star: 1149 Kind = MCBinaryExpr::Mul; 1150 return 6; 1151 case AsmToken::Slash: 1152 Kind = MCBinaryExpr::Div; 1153 return 6; 1154 case AsmToken::Percent: 1155 Kind = MCBinaryExpr::Mod; 1156 return 6; 1157 } 1158 } 1159 1160 /// \brief Parse all binary operators with precedence >= 'Precedence'. 1161 /// Res contains the LHS of the expression on input. 1162 bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 1163 SMLoc &EndLoc) { 1164 while (1) { 1165 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 1166 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 1167 1168 // If the next token is lower precedence than we are allowed to eat, return 1169 // successfully with what we ate already. 1170 if (TokPrec < Precedence) 1171 return false; 1172 1173 Lex(); 1174 1175 // Eat the next primary expression. 1176 const MCExpr *RHS; 1177 if (parsePrimaryExpr(RHS, EndLoc)) 1178 return true; 1179 1180 // If BinOp binds less tightly with RHS than the operator after RHS, let 1181 // the pending operator take RHS as its LHS. 1182 MCBinaryExpr::Opcode Dummy; 1183 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 1184 if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc)) 1185 return true; 1186 1187 // Merge LHS and RHS according to operator. 1188 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 1189 } 1190 } 1191 1192 /// ParseStatement: 1193 /// ::= EndOfStatement 1194 /// ::= Label* Directive ...Operands... EndOfStatement 1195 /// ::= Label* Identifier OperandList* EndOfStatement 1196 bool AsmParser::parseStatement(ParseStatementInfo &Info) { 1197 if (Lexer.is(AsmToken::EndOfStatement)) { 1198 Out.AddBlankLine(); 1199 Lex(); 1200 return false; 1201 } 1202 1203 // Statements always start with an identifier or are a full line comment. 1204 AsmToken ID = getTok(); 1205 SMLoc IDLoc = ID.getLoc(); 1206 StringRef IDVal; 1207 int64_t LocalLabelVal = -1; 1208 // A full line comment is a '#' as the first token. 1209 if (Lexer.is(AsmToken::Hash)) 1210 return parseCppHashLineFilenameComment(IDLoc); 1211 1212 // Allow an integer followed by a ':' as a directional local label. 1213 if (Lexer.is(AsmToken::Integer)) { 1214 LocalLabelVal = getTok().getIntVal(); 1215 if (LocalLabelVal < 0) { 1216 if (!TheCondState.Ignore) 1217 return TokError("unexpected token at start of statement"); 1218 IDVal = ""; 1219 } else { 1220 IDVal = getTok().getString(); 1221 Lex(); // Consume the integer token to be used as an identifier token. 1222 if (Lexer.getKind() != AsmToken::Colon) { 1223 if (!TheCondState.Ignore) 1224 return TokError("unexpected token at start of statement"); 1225 } 1226 } 1227 } else if (Lexer.is(AsmToken::Dot)) { 1228 // Treat '.' as a valid identifier in this context. 1229 Lex(); 1230 IDVal = "."; 1231 } else if (parseIdentifier(IDVal)) { 1232 if (!TheCondState.Ignore) 1233 return TokError("unexpected token at start of statement"); 1234 IDVal = ""; 1235 } 1236 1237 // Handle conditional assembly here before checking for skipping. We 1238 // have to do this so that .endif isn't skipped in a ".if 0" block for 1239 // example. 1240 StringMap<DirectiveKind>::const_iterator DirKindIt = 1241 DirectiveKindMap.find(IDVal); 1242 DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end()) 1243 ? DK_NO_DIRECTIVE 1244 : DirKindIt->getValue(); 1245 switch (DirKind) { 1246 default: 1247 break; 1248 case DK_IF: 1249 case DK_IFEQ: 1250 case DK_IFGE: 1251 case DK_IFGT: 1252 case DK_IFLE: 1253 case DK_IFLT: 1254 case DK_IFNE: 1255 return parseDirectiveIf(IDLoc, DirKind); 1256 case DK_IFB: 1257 return parseDirectiveIfb(IDLoc, true); 1258 case DK_IFNB: 1259 return parseDirectiveIfb(IDLoc, false); 1260 case DK_IFC: 1261 return parseDirectiveIfc(IDLoc, true); 1262 case DK_IFEQS: 1263 return parseDirectiveIfeqs(IDLoc); 1264 case DK_IFNC: 1265 return parseDirectiveIfc(IDLoc, false); 1266 case DK_IFDEF: 1267 return parseDirectiveIfdef(IDLoc, true); 1268 case DK_IFNDEF: 1269 case DK_IFNOTDEF: 1270 return parseDirectiveIfdef(IDLoc, false); 1271 case DK_ELSEIF: 1272 return parseDirectiveElseIf(IDLoc); 1273 case DK_ELSE: 1274 return parseDirectiveElse(IDLoc); 1275 case DK_ENDIF: 1276 return parseDirectiveEndIf(IDLoc); 1277 } 1278 1279 // Ignore the statement if in the middle of inactive conditional 1280 // (e.g. ".if 0"). 1281 if (TheCondState.Ignore) { 1282 eatToEndOfStatement(); 1283 return false; 1284 } 1285 1286 // FIXME: Recurse on local labels? 1287 1288 // See what kind of statement we have. 1289 switch (Lexer.getKind()) { 1290 case AsmToken::Colon: { 1291 checkForValidSection(); 1292 1293 // identifier ':' -> Label. 1294 Lex(); 1295 1296 // Diagnose attempt to use '.' as a label. 1297 if (IDVal == ".") 1298 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 1299 1300 // Diagnose attempt to use a variable as a label. 1301 // 1302 // FIXME: Diagnostics. Note the location of the definition as a label. 1303 // FIXME: This doesn't diagnose assignment to a symbol which has been 1304 // implicitly marked as external. 1305 MCSymbol *Sym; 1306 if (LocalLabelVal == -1) 1307 Sym = getContext().GetOrCreateSymbol(IDVal); 1308 else 1309 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); 1310 if (!Sym->isUndefined() || Sym->isVariable()) 1311 return Error(IDLoc, "invalid symbol redefinition"); 1312 1313 // Emit the label. 1314 if (!ParsingInlineAsm) 1315 Out.EmitLabel(Sym); 1316 1317 // If we are generating dwarf for assembly source files then gather the 1318 // info to make a dwarf label entry for this label if needed. 1319 if (getContext().getGenDwarfForAssembly()) 1320 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 1321 IDLoc); 1322 1323 getTargetParser().onLabelParsed(Sym); 1324 1325 // Consume any end of statement token, if present, to avoid spurious 1326 // AddBlankLine calls(). 1327 if (Lexer.is(AsmToken::EndOfStatement)) { 1328 Lex(); 1329 if (Lexer.is(AsmToken::Eof)) 1330 return false; 1331 } 1332 1333 return false; 1334 } 1335 1336 case AsmToken::Equal: 1337 // identifier '=' ... -> assignment statement 1338 Lex(); 1339 1340 return parseAssignment(IDVal, true); 1341 1342 default: // Normal instruction or directive. 1343 break; 1344 } 1345 1346 // If macros are enabled, check to see if this is a macro instantiation. 1347 if (areMacrosEnabled()) 1348 if (const MCAsmMacro *M = lookupMacro(IDVal)) { 1349 return handleMacroEntry(M, IDLoc); 1350 } 1351 1352 // Otherwise, we have a normal instruction or directive. 1353 1354 // Directives start with "." 1355 if (IDVal[0] == '.' && IDVal != ".") { 1356 // There are several entities interested in parsing directives: 1357 // 1358 // 1. The target-specific assembly parser. Some directives are target 1359 // specific or may potentially behave differently on certain targets. 1360 // 2. Asm parser extensions. For example, platform-specific parsers 1361 // (like the ELF parser) register themselves as extensions. 1362 // 3. The generic directive parser implemented by this class. These are 1363 // all the directives that behave in a target and platform independent 1364 // manner, or at least have a default behavior that's shared between 1365 // all targets and platforms. 1366 1367 // First query the target-specific parser. It will return 'true' if it 1368 // isn't interested in this directive. 1369 if (!getTargetParser().ParseDirective(ID)) 1370 return false; 1371 1372 // Next, check the extension directive map to see if any extension has 1373 // registered itself to parse this directive. 1374 std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = 1375 ExtensionDirectiveMap.lookup(IDVal); 1376 if (Handler.first) 1377 return (*Handler.second)(Handler.first, IDVal, IDLoc); 1378 1379 // Finally, if no one else is interested in this directive, it must be 1380 // generic and familiar to this class. 1381 switch (DirKind) { 1382 default: 1383 break; 1384 case DK_SET: 1385 case DK_EQU: 1386 return parseDirectiveSet(IDVal, true); 1387 case DK_EQUIV: 1388 return parseDirectiveSet(IDVal, false); 1389 case DK_ASCII: 1390 return parseDirectiveAscii(IDVal, false); 1391 case DK_ASCIZ: 1392 case DK_STRING: 1393 return parseDirectiveAscii(IDVal, true); 1394 case DK_BYTE: 1395 return parseDirectiveValue(1); 1396 case DK_SHORT: 1397 case DK_VALUE: 1398 case DK_2BYTE: 1399 return parseDirectiveValue(2); 1400 case DK_LONG: 1401 case DK_INT: 1402 case DK_4BYTE: 1403 return parseDirectiveValue(4); 1404 case DK_QUAD: 1405 case DK_8BYTE: 1406 return parseDirectiveValue(8); 1407 case DK_OCTA: 1408 return parseDirectiveOctaValue(); 1409 case DK_SINGLE: 1410 case DK_FLOAT: 1411 return parseDirectiveRealValue(APFloat::IEEEsingle); 1412 case DK_DOUBLE: 1413 return parseDirectiveRealValue(APFloat::IEEEdouble); 1414 case DK_ALIGN: { 1415 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); 1416 return parseDirectiveAlign(IsPow2, /*ExprSize=*/1); 1417 } 1418 case DK_ALIGN32: { 1419 bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); 1420 return parseDirectiveAlign(IsPow2, /*ExprSize=*/4); 1421 } 1422 case DK_BALIGN: 1423 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 1424 case DK_BALIGNW: 1425 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 1426 case DK_BALIGNL: 1427 return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 1428 case DK_P2ALIGN: 1429 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 1430 case DK_P2ALIGNW: 1431 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 1432 case DK_P2ALIGNL: 1433 return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 1434 case DK_ORG: 1435 return parseDirectiveOrg(); 1436 case DK_FILL: 1437 return parseDirectiveFill(); 1438 case DK_ZERO: 1439 return parseDirectiveZero(); 1440 case DK_EXTERN: 1441 eatToEndOfStatement(); // .extern is the default, ignore it. 1442 return false; 1443 case DK_GLOBL: 1444 case DK_GLOBAL: 1445 return parseDirectiveSymbolAttribute(MCSA_Global); 1446 case DK_LAZY_REFERENCE: 1447 return parseDirectiveSymbolAttribute(MCSA_LazyReference); 1448 case DK_NO_DEAD_STRIP: 1449 return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 1450 case DK_SYMBOL_RESOLVER: 1451 return parseDirectiveSymbolAttribute(MCSA_SymbolResolver); 1452 case DK_PRIVATE_EXTERN: 1453 return parseDirectiveSymbolAttribute(MCSA_PrivateExtern); 1454 case DK_REFERENCE: 1455 return parseDirectiveSymbolAttribute(MCSA_Reference); 1456 case DK_WEAK_DEFINITION: 1457 return parseDirectiveSymbolAttribute(MCSA_WeakDefinition); 1458 case DK_WEAK_REFERENCE: 1459 return parseDirectiveSymbolAttribute(MCSA_WeakReference); 1460 case DK_WEAK_DEF_CAN_BE_HIDDEN: 1461 return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); 1462 case DK_COMM: 1463 case DK_COMMON: 1464 return parseDirectiveComm(/*IsLocal=*/false); 1465 case DK_LCOMM: 1466 return parseDirectiveComm(/*IsLocal=*/true); 1467 case DK_ABORT: 1468 return parseDirectiveAbort(); 1469 case DK_INCLUDE: 1470 return parseDirectiveInclude(); 1471 case DK_INCBIN: 1472 return parseDirectiveIncbin(); 1473 case DK_CODE16: 1474 case DK_CODE16GCC: 1475 return TokError(Twine(IDVal) + " not supported yet"); 1476 case DK_REPT: 1477 return parseDirectiveRept(IDLoc, IDVal); 1478 case DK_IRP: 1479 return parseDirectiveIrp(IDLoc); 1480 case DK_IRPC: 1481 return parseDirectiveIrpc(IDLoc); 1482 case DK_ENDR: 1483 return parseDirectiveEndr(IDLoc); 1484 case DK_BUNDLE_ALIGN_MODE: 1485 return parseDirectiveBundleAlignMode(); 1486 case DK_BUNDLE_LOCK: 1487 return parseDirectiveBundleLock(); 1488 case DK_BUNDLE_UNLOCK: 1489 return parseDirectiveBundleUnlock(); 1490 case DK_SLEB128: 1491 return parseDirectiveLEB128(true); 1492 case DK_ULEB128: 1493 return parseDirectiveLEB128(false); 1494 case DK_SPACE: 1495 case DK_SKIP: 1496 return parseDirectiveSpace(IDVal); 1497 case DK_FILE: 1498 return parseDirectiveFile(IDLoc); 1499 case DK_LINE: 1500 return parseDirectiveLine(); 1501 case DK_LOC: 1502 return parseDirectiveLoc(); 1503 case DK_STABS: 1504 return parseDirectiveStabs(); 1505 case DK_CFI_SECTIONS: 1506 return parseDirectiveCFISections(); 1507 case DK_CFI_STARTPROC: 1508 return parseDirectiveCFIStartProc(); 1509 case DK_CFI_ENDPROC: 1510 return parseDirectiveCFIEndProc(); 1511 case DK_CFI_DEF_CFA: 1512 return parseDirectiveCFIDefCfa(IDLoc); 1513 case DK_CFI_DEF_CFA_OFFSET: 1514 return parseDirectiveCFIDefCfaOffset(); 1515 case DK_CFI_ADJUST_CFA_OFFSET: 1516 return parseDirectiveCFIAdjustCfaOffset(); 1517 case DK_CFI_DEF_CFA_REGISTER: 1518 return parseDirectiveCFIDefCfaRegister(IDLoc); 1519 case DK_CFI_OFFSET: 1520 return parseDirectiveCFIOffset(IDLoc); 1521 case DK_CFI_REL_OFFSET: 1522 return parseDirectiveCFIRelOffset(IDLoc); 1523 case DK_CFI_PERSONALITY: 1524 return parseDirectiveCFIPersonalityOrLsda(true); 1525 case DK_CFI_LSDA: 1526 return parseDirectiveCFIPersonalityOrLsda(false); 1527 case DK_CFI_REMEMBER_STATE: 1528 return parseDirectiveCFIRememberState(); 1529 case DK_CFI_RESTORE_STATE: 1530 return parseDirectiveCFIRestoreState(); 1531 case DK_CFI_SAME_VALUE: 1532 return parseDirectiveCFISameValue(IDLoc); 1533 case DK_CFI_RESTORE: 1534 return parseDirectiveCFIRestore(IDLoc); 1535 case DK_CFI_ESCAPE: 1536 return parseDirectiveCFIEscape(); 1537 case DK_CFI_SIGNAL_FRAME: 1538 return parseDirectiveCFISignalFrame(); 1539 case DK_CFI_UNDEFINED: 1540 return parseDirectiveCFIUndefined(IDLoc); 1541 case DK_CFI_REGISTER: 1542 return parseDirectiveCFIRegister(IDLoc); 1543 case DK_CFI_WINDOW_SAVE: 1544 return parseDirectiveCFIWindowSave(); 1545 case DK_MACROS_ON: 1546 case DK_MACROS_OFF: 1547 return parseDirectiveMacrosOnOff(IDVal); 1548 case DK_MACRO: 1549 return parseDirectiveMacro(IDLoc); 1550 case DK_EXITM: 1551 return parseDirectiveExitMacro(IDVal); 1552 case DK_ENDM: 1553 case DK_ENDMACRO: 1554 return parseDirectiveEndMacro(IDVal); 1555 case DK_PURGEM: 1556 return parseDirectivePurgeMacro(IDLoc); 1557 case DK_END: 1558 return parseDirectiveEnd(IDLoc); 1559 case DK_ERR: 1560 return parseDirectiveError(IDLoc, false); 1561 case DK_ERROR: 1562 return parseDirectiveError(IDLoc, true); 1563 case DK_WARNING: 1564 return parseDirectiveWarning(IDLoc); 1565 } 1566 1567 return Error(IDLoc, "unknown directive"); 1568 } 1569 1570 // __asm _emit or __asm __emit 1571 if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || 1572 IDVal == "_EMIT" || IDVal == "__EMIT")) 1573 return parseDirectiveMSEmit(IDLoc, Info, IDVal.size()); 1574 1575 // __asm align 1576 if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) 1577 return parseDirectiveMSAlign(IDLoc, Info); 1578 1579 checkForValidSection(); 1580 1581 // Canonicalize the opcode to lower case. 1582 std::string OpcodeStr = IDVal.lower(); 1583 ParseInstructionInfo IInfo(Info.AsmRewrites); 1584 bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, IDLoc, 1585 Info.ParsedOperands); 1586 Info.ParseError = HadError; 1587 1588 // Dump the parsed representation, if requested. 1589 if (getShowParsedOperands()) { 1590 SmallString<256> Str; 1591 raw_svector_ostream OS(Str); 1592 OS << "parsed instruction: ["; 1593 for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) { 1594 if (i != 0) 1595 OS << ", "; 1596 Info.ParsedOperands[i]->print(OS); 1597 } 1598 OS << "]"; 1599 1600 printMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 1601 } 1602 1603 // If we are generating dwarf for the current section then generate a .loc 1604 // directive for the instruction. 1605 if (!HadError && getContext().getGenDwarfForAssembly() && 1606 getContext().getGenDwarfSectionSyms().count( 1607 getStreamer().getCurrentSection().first)) { 1608 1609 unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); 1610 1611 // If we previously parsed a cpp hash file line comment then make sure the 1612 // current Dwarf File is for the CppHashFilename if not then emit the 1613 // Dwarf File table for it and adjust the line number for the .loc. 1614 if (CppHashFilename.size() != 0) { 1615 unsigned FileNumber = getStreamer().EmitDwarfFileDirective( 1616 0, StringRef(), CppHashFilename); 1617 getContext().setGenDwarfFileNumber(FileNumber); 1618 1619 // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's 1620 // cache with the different Loc from the call above we save the last 1621 // info we queried here with SrcMgr.FindLineNumber(). 1622 unsigned CppHashLocLineNo; 1623 if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf) 1624 CppHashLocLineNo = LastQueryLine; 1625 else { 1626 CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf); 1627 LastQueryLine = CppHashLocLineNo; 1628 LastQueryIDLoc = CppHashLoc; 1629 LastQueryBuffer = CppHashBuf; 1630 } 1631 Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); 1632 } 1633 1634 getStreamer().EmitDwarfLocDirective( 1635 getContext().getGenDwarfFileNumber(), Line, 0, 1636 DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0, 1637 StringRef()); 1638 } 1639 1640 // If parsing succeeded, match the instruction. 1641 if (!HadError) { 1642 unsigned ErrorInfo; 1643 getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, 1644 Info.ParsedOperands, Out, 1645 ErrorInfo, ParsingInlineAsm); 1646 } 1647 1648 // Don't skip the rest of the line, the instruction parser is responsible for 1649 // that. 1650 return false; 1651 } 1652 1653 /// eatToEndOfLine uses the Lexer to eat the characters to the end of the line 1654 /// since they may not be able to be tokenized to get to the end of line token. 1655 void AsmParser::eatToEndOfLine() { 1656 if (!Lexer.is(AsmToken::EndOfStatement)) 1657 Lexer.LexUntilEndOfLine(); 1658 // Eat EOL. 1659 Lex(); 1660 } 1661 1662 /// parseCppHashLineFilenameComment as this: 1663 /// ::= # number "filename" 1664 /// or just as a full line comment if it doesn't have a number and a string. 1665 bool AsmParser::parseCppHashLineFilenameComment(const SMLoc &L) { 1666 Lex(); // Eat the hash token. 1667 1668 if (getLexer().isNot(AsmToken::Integer)) { 1669 // Consume the line since in cases it is not a well-formed line directive, 1670 // as if were simply a full line comment. 1671 eatToEndOfLine(); 1672 return false; 1673 } 1674 1675 int64_t LineNumber = getTok().getIntVal(); 1676 Lex(); 1677 1678 if (getLexer().isNot(AsmToken::String)) { 1679 eatToEndOfLine(); 1680 return false; 1681 } 1682 1683 StringRef Filename = getTok().getString(); 1684 // Get rid of the enclosing quotes. 1685 Filename = Filename.substr(1, Filename.size() - 2); 1686 1687 // Save the SMLoc, Filename and LineNumber for later use by diagnostics. 1688 CppHashLoc = L; 1689 CppHashFilename = Filename; 1690 CppHashLineNumber = LineNumber; 1691 CppHashBuf = CurBuffer; 1692 1693 // Ignore any trailing characters, they're just comment. 1694 eatToEndOfLine(); 1695 return false; 1696 } 1697 1698 /// \brief will use the last parsed cpp hash line filename comment 1699 /// for the Filename and LineNo if any in the diagnostic. 1700 void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 1701 const AsmParser *Parser = static_cast<const AsmParser *>(Context); 1702 raw_ostream &OS = errs(); 1703 1704 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 1705 const SMLoc &DiagLoc = Diag.getLoc(); 1706 unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1707 unsigned CppHashBuf = 1708 Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); 1709 1710 // Like SourceMgr::printMessage() we need to print the include stack if any 1711 // before printing the message. 1712 unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1713 if (!Parser->SavedDiagHandler && DiagCurBuffer && 1714 DiagCurBuffer != DiagSrcMgr.getMainFileID()) { 1715 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 1716 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 1717 } 1718 1719 // If we have not parsed a cpp hash line filename comment or the source 1720 // manager changed or buffer changed (like in a nested include) then just 1721 // print the normal diagnostic using its Filename and LineNo. 1722 if (!Parser->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr || 1723 DiagBuf != CppHashBuf) { 1724 if (Parser->SavedDiagHandler) 1725 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 1726 else 1727 Diag.print(nullptr, OS); 1728 return; 1729 } 1730 1731 // Use the CppHashFilename and calculate a line number based on the 1732 // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for 1733 // the diagnostic. 1734 const std::string &Filename = Parser->CppHashFilename; 1735 1736 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 1737 int CppHashLocLineNo = 1738 Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); 1739 int LineNo = 1740 Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); 1741 1742 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo, 1743 Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(), 1744 Diag.getLineContents(), Diag.getRanges()); 1745 1746 if (Parser->SavedDiagHandler) 1747 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 1748 else 1749 NewDiag.print(nullptr, OS); 1750 } 1751 1752 // FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The 1753 // difference being that that function accepts '@' as part of identifiers and 1754 // we can't do that. AsmLexer.cpp should probably be changed to handle 1755 // '@' as a special case when needed. 1756 static bool isIdentifierChar(char c) { 1757 return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' || 1758 c == '.'; 1759 } 1760 1761 bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 1762 ArrayRef<MCAsmMacroParameter> Parameters, 1763 ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) { 1764 unsigned NParameters = Parameters.size(); 1765 bool HasVararg = NParameters ? Parameters.back().Vararg : false; 1766 if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) 1767 return Error(L, "Wrong number of arguments"); 1768 1769 // A macro without parameters is handled differently on Darwin: 1770 // gas accepts no arguments and does no substitutions 1771 while (!Body.empty()) { 1772 // Scan for the next substitution. 1773 std::size_t End = Body.size(), Pos = 0; 1774 for (; Pos != End; ++Pos) { 1775 // Check for a substitution or escape. 1776 if (IsDarwin && !NParameters) { 1777 // This macro has no parameters, look for $0, $1, etc. 1778 if (Body[Pos] != '$' || Pos + 1 == End) 1779 continue; 1780 1781 char Next = Body[Pos + 1]; 1782 if (Next == '$' || Next == 'n' || 1783 isdigit(static_cast<unsigned char>(Next))) 1784 break; 1785 } else { 1786 // This macro has parameters, look for \foo, \bar, etc. 1787 if (Body[Pos] == '\\' && Pos + 1 != End) 1788 break; 1789 } 1790 } 1791 1792 // Add the prefix. 1793 OS << Body.slice(0, Pos); 1794 1795 // Check if we reached the end. 1796 if (Pos == End) 1797 break; 1798 1799 if (IsDarwin && !NParameters) { 1800 switch (Body[Pos + 1]) { 1801 // $$ => $ 1802 case '$': 1803 OS << '$'; 1804 break; 1805 1806 // $n => number of arguments 1807 case 'n': 1808 OS << A.size(); 1809 break; 1810 1811 // $[0-9] => argument 1812 default: { 1813 // Missing arguments are ignored. 1814 unsigned Index = Body[Pos + 1] - '0'; 1815 if (Index >= A.size()) 1816 break; 1817 1818 // Otherwise substitute with the token values, with spaces eliminated. 1819 for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), 1820 ie = A[Index].end(); 1821 it != ie; ++it) 1822 OS << it->getString(); 1823 break; 1824 } 1825 } 1826 Pos += 2; 1827 } else { 1828 unsigned I = Pos + 1; 1829 while (isIdentifierChar(Body[I]) && I + 1 != End) 1830 ++I; 1831 1832 const char *Begin = Body.data() + Pos + 1; 1833 StringRef Argument(Begin, I - (Pos + 1)); 1834 unsigned Index = 0; 1835 for (; Index < NParameters; ++Index) 1836 if (Parameters[Index].Name == Argument) 1837 break; 1838 1839 if (Index == NParameters) { 1840 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') 1841 Pos += 3; 1842 else { 1843 OS << '\\' << Argument; 1844 Pos = I; 1845 } 1846 } else { 1847 bool VarargParameter = HasVararg && Index == (NParameters - 1); 1848 for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), 1849 ie = A[Index].end(); 1850 it != ie; ++it) 1851 // We expect no quotes around the string's contents when 1852 // parsing for varargs. 1853 if (it->getKind() != AsmToken::String || VarargParameter) 1854 OS << it->getString(); 1855 else 1856 OS << it->getStringContents(); 1857 1858 Pos += 1 + Argument.size(); 1859 } 1860 } 1861 // Update the scan point. 1862 Body = Body.substr(Pos); 1863 } 1864 1865 return false; 1866 } 1867 1868 MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL, 1869 MemoryBuffer *I, size_t CondStackDepth) 1870 : Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL), 1871 CondStackDepth(CondStackDepth) {} 1872 1873 static bool isOperator(AsmToken::TokenKind kind) { 1874 switch (kind) { 1875 default: 1876 return false; 1877 case AsmToken::Plus: 1878 case AsmToken::Minus: 1879 case AsmToken::Tilde: 1880 case AsmToken::Slash: 1881 case AsmToken::Star: 1882 case AsmToken::Dot: 1883 case AsmToken::Equal: 1884 case AsmToken::EqualEqual: 1885 case AsmToken::Pipe: 1886 case AsmToken::PipePipe: 1887 case AsmToken::Caret: 1888 case AsmToken::Amp: 1889 case AsmToken::AmpAmp: 1890 case AsmToken::Exclaim: 1891 case AsmToken::ExclaimEqual: 1892 case AsmToken::Percent: 1893 case AsmToken::Less: 1894 case AsmToken::LessEqual: 1895 case AsmToken::LessLess: 1896 case AsmToken::LessGreater: 1897 case AsmToken::Greater: 1898 case AsmToken::GreaterEqual: 1899 case AsmToken::GreaterGreater: 1900 return true; 1901 } 1902 } 1903 1904 namespace { 1905 class AsmLexerSkipSpaceRAII { 1906 public: 1907 AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) { 1908 Lexer.setSkipSpace(SkipSpace); 1909 } 1910 1911 ~AsmLexerSkipSpaceRAII() { 1912 Lexer.setSkipSpace(true); 1913 } 1914 1915 private: 1916 AsmLexer &Lexer; 1917 }; 1918 } 1919 1920 bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) { 1921 1922 if (Vararg) { 1923 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1924 StringRef Str = parseStringToEndOfStatement(); 1925 MA.push_back(AsmToken(AsmToken::String, Str)); 1926 } 1927 return false; 1928 } 1929 1930 unsigned ParenLevel = 0; 1931 unsigned AddTokens = 0; 1932 1933 // Darwin doesn't use spaces to delmit arguments. 1934 AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin); 1935 1936 for (;;) { 1937 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) 1938 return TokError("unexpected token in macro instantiation"); 1939 1940 if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) 1941 break; 1942 1943 if (Lexer.is(AsmToken::Space)) { 1944 Lex(); // Eat spaces 1945 1946 // Spaces can delimit parameters, but could also be part an expression. 1947 // If the token after a space is an operator, add the token and the next 1948 // one into this argument 1949 if (!IsDarwin) { 1950 if (isOperator(Lexer.getKind())) { 1951 // Check to see whether the token is used as an operator, 1952 // or part of an identifier 1953 const char *NextChar = getTok().getEndLoc().getPointer(); 1954 if (*NextChar == ' ') 1955 AddTokens = 2; 1956 } 1957 1958 if (!AddTokens && ParenLevel == 0) { 1959 break; 1960 } 1961 } 1962 } 1963 1964 // handleMacroEntry relies on not advancing the lexer here 1965 // to be able to fill in the remaining default parameter values 1966 if (Lexer.is(AsmToken::EndOfStatement)) 1967 break; 1968 1969 // Adjust the current parentheses level. 1970 if (Lexer.is(AsmToken::LParen)) 1971 ++ParenLevel; 1972 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 1973 --ParenLevel; 1974 1975 // Append the token to the current argument list. 1976 MA.push_back(getTok()); 1977 if (AddTokens) 1978 AddTokens--; 1979 Lex(); 1980 } 1981 1982 if (ParenLevel != 0) 1983 return TokError("unbalanced parentheses in macro argument"); 1984 return false; 1985 } 1986 1987 // Parse the macro instantiation arguments. 1988 bool AsmParser::parseMacroArguments(const MCAsmMacro *M, 1989 MCAsmMacroArguments &A) { 1990 const unsigned NParameters = M ? M->Parameters.size() : 0; 1991 bool NamedParametersFound = false; 1992 SmallVector<SMLoc, 4> FALocs; 1993 1994 A.resize(NParameters); 1995 FALocs.resize(NParameters); 1996 1997 // Parse two kinds of macro invocations: 1998 // - macros defined without any parameters accept an arbitrary number of them 1999 // - macros defined with parameters accept at most that many of them 2000 bool HasVararg = NParameters ? M->Parameters.back().Vararg : false; 2001 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 2002 ++Parameter) { 2003 SMLoc IDLoc = Lexer.getLoc(); 2004 MCAsmMacroParameter FA; 2005 2006 if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) { 2007 if (parseIdentifier(FA.Name)) { 2008 Error(IDLoc, "invalid argument identifier for formal argument"); 2009 eatToEndOfStatement(); 2010 return true; 2011 } 2012 2013 if (!Lexer.is(AsmToken::Equal)) { 2014 TokError("expected '=' after formal parameter identifier"); 2015 eatToEndOfStatement(); 2016 return true; 2017 } 2018 Lex(); 2019 2020 NamedParametersFound = true; 2021 } 2022 2023 if (NamedParametersFound && FA.Name.empty()) { 2024 Error(IDLoc, "cannot mix positional and keyword arguments"); 2025 eatToEndOfStatement(); 2026 return true; 2027 } 2028 2029 bool Vararg = HasVararg && Parameter == (NParameters - 1); 2030 if (parseMacroArgument(FA.Value, Vararg)) 2031 return true; 2032 2033 unsigned PI = Parameter; 2034 if (!FA.Name.empty()) { 2035 unsigned FAI = 0; 2036 for (FAI = 0; FAI < NParameters; ++FAI) 2037 if (M->Parameters[FAI].Name == FA.Name) 2038 break; 2039 2040 if (FAI >= NParameters) { 2041 assert(M && "expected macro to be defined"); 2042 Error(IDLoc, 2043 "parameter named '" + FA.Name + "' does not exist for macro '" + 2044 M->Name + "'"); 2045 return true; 2046 } 2047 PI = FAI; 2048 } 2049 2050 if (!FA.Value.empty()) { 2051 if (A.size() <= PI) 2052 A.resize(PI + 1); 2053 A[PI] = FA.Value; 2054 2055 if (FALocs.size() <= PI) 2056 FALocs.resize(PI + 1); 2057 2058 FALocs[PI] = Lexer.getLoc(); 2059 } 2060 2061 // At the end of the statement, fill in remaining arguments that have 2062 // default values. If there aren't any, then the next argument is 2063 // required but missing 2064 if (Lexer.is(AsmToken::EndOfStatement)) { 2065 bool Failure = false; 2066 for (unsigned FAI = 0; FAI < NParameters; ++FAI) { 2067 if (A[FAI].empty()) { 2068 if (M->Parameters[FAI].Required) { 2069 Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(), 2070 "missing value for required parameter " 2071 "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'"); 2072 Failure = true; 2073 } 2074 2075 if (!M->Parameters[FAI].Value.empty()) 2076 A[FAI] = M->Parameters[FAI].Value; 2077 } 2078 } 2079 return Failure; 2080 } 2081 2082 if (Lexer.is(AsmToken::Comma)) 2083 Lex(); 2084 } 2085 2086 return TokError("too many positional arguments"); 2087 } 2088 2089 const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) { 2090 StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); 2091 return (I == MacroMap.end()) ? nullptr : I->getValue(); 2092 } 2093 2094 void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) { 2095 MacroMap[Name] = new MCAsmMacro(Macro); 2096 } 2097 2098 void AsmParser::undefineMacro(StringRef Name) { 2099 StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); 2100 if (I != MacroMap.end()) { 2101 delete I->getValue(); 2102 MacroMap.erase(I); 2103 } 2104 } 2105 2106 bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { 2107 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate 2108 // this, although we should protect against infinite loops. 2109 if (ActiveMacros.size() == 20) 2110 return TokError("macros cannot be nested more than 20 levels deep"); 2111 2112 MCAsmMacroArguments A; 2113 if (parseMacroArguments(M, A)) 2114 return true; 2115 2116 // Macro instantiation is lexical, unfortunately. We construct a new buffer 2117 // to hold the macro body with substitutions. 2118 SmallString<256> Buf; 2119 StringRef Body = M->Body; 2120 raw_svector_ostream OS(Buf); 2121 2122 if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) 2123 return true; 2124 2125 // We include the .endmacro in the buffer as our cue to exit the macro 2126 // instantiation. 2127 OS << ".endmacro\n"; 2128 2129 MemoryBuffer *Instantiation = 2130 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 2131 2132 // Create the macro instantiation object and add to the current macro 2133 // instantiation stack. 2134 MacroInstantiation *MI = 2135 new MacroInstantiation(NameLoc, CurBuffer, getTok().getLoc(), 2136 Instantiation, TheCondStack.size()); 2137 ActiveMacros.push_back(MI); 2138 2139 // Jump to the macro instantiation and prime the lexer. 2140 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 2141 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 2142 Lex(); 2143 2144 return false; 2145 } 2146 2147 void AsmParser::handleMacroExit() { 2148 // Jump to the EndOfStatement we should return to, and consume it. 2149 jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer); 2150 Lex(); 2151 2152 // Pop the instantiation entry. 2153 delete ActiveMacros.back(); 2154 ActiveMacros.pop_back(); 2155 } 2156 2157 static bool isUsedIn(const MCSymbol *Sym, const MCExpr *Value) { 2158 switch (Value->getKind()) { 2159 case MCExpr::Binary: { 2160 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value); 2161 return isUsedIn(Sym, BE->getLHS()) || isUsedIn(Sym, BE->getRHS()); 2162 } 2163 case MCExpr::Target: 2164 case MCExpr::Constant: 2165 return false; 2166 case MCExpr::SymbolRef: { 2167 const MCSymbol &S = 2168 static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); 2169 if (S.isVariable()) 2170 return isUsedIn(Sym, S.getVariableValue()); 2171 return &S == Sym; 2172 } 2173 case MCExpr::Unary: 2174 return isUsedIn(Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr()); 2175 } 2176 2177 llvm_unreachable("Unknown expr kind!"); 2178 } 2179 2180 bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, 2181 bool NoDeadStrip) { 2182 // FIXME: Use better location, we should use proper tokens. 2183 SMLoc EqualLoc = Lexer.getLoc(); 2184 2185 const MCExpr *Value; 2186 if (parseExpression(Value)) 2187 return true; 2188 2189 // Note: we don't count b as used in "a = b". This is to allow 2190 // a = b 2191 // b = c 2192 2193 if (Lexer.isNot(AsmToken::EndOfStatement)) 2194 return TokError("unexpected token in assignment"); 2195 2196 // Eat the end of statement marker. 2197 Lex(); 2198 2199 // Validate that the LHS is allowed to be a variable (either it has not been 2200 // used as a symbol, or it is an absolute symbol). 2201 MCSymbol *Sym = getContext().LookupSymbol(Name); 2202 if (Sym) { 2203 // Diagnose assignment to a label. 2204 // 2205 // FIXME: Diagnostics. Note the location of the definition as a label. 2206 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 2207 if (isUsedIn(Sym, Value)) 2208 return Error(EqualLoc, "Recursive use of '" + Name + "'"); 2209 else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable()) 2210 ; // Allow redefinitions of undefined symbols only used in directives. 2211 else if (Sym->isVariable() && !Sym->isUsed() && allow_redef) 2212 ; // Allow redefinitions of variables that haven't yet been used. 2213 else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef)) 2214 return Error(EqualLoc, "redefinition of '" + Name + "'"); 2215 else if (!Sym->isVariable()) 2216 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 2217 else if (!isa<MCConstantExpr>(Sym->getVariableValue())) 2218 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 2219 Name + "'"); 2220 2221 // Don't count these checks as uses. 2222 Sym->setUsed(false); 2223 } else if (Name == ".") { 2224 if (Out.EmitValueToOffset(Value, 0)) { 2225 Error(EqualLoc, "expected absolute expression"); 2226 eatToEndOfStatement(); 2227 } 2228 return false; 2229 } else 2230 Sym = getContext().GetOrCreateSymbol(Name); 2231 2232 // Do the assignment. 2233 Out.EmitAssignment(Sym, Value); 2234 if (NoDeadStrip) 2235 Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip); 2236 2237 return false; 2238 } 2239 2240 /// parseIdentifier: 2241 /// ::= identifier 2242 /// ::= string 2243 bool AsmParser::parseIdentifier(StringRef &Res) { 2244 // The assembler has relaxed rules for accepting identifiers, in particular we 2245 // allow things like '.globl $foo' and '.def @feat.00', which would normally be 2246 // separate tokens. At this level, we have already lexed so we cannot (currently) 2247 // handle this as a context dependent token, instead we detect adjacent tokens 2248 // and return the combined identifier. 2249 if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) { 2250 SMLoc PrefixLoc = getLexer().getLoc(); 2251 2252 // Consume the prefix character, and check for a following identifier. 2253 Lex(); 2254 if (Lexer.isNot(AsmToken::Identifier)) 2255 return true; 2256 2257 // We have a '$' or '@' followed by an identifier, make sure they are adjacent. 2258 if (PrefixLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 2259 return true; 2260 2261 // Construct the joined identifier and consume the token. 2262 Res = 2263 StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1); 2264 Lex(); 2265 return false; 2266 } 2267 2268 if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String)) 2269 return true; 2270 2271 Res = getTok().getIdentifier(); 2272 2273 Lex(); // Consume the identifier token. 2274 2275 return false; 2276 } 2277 2278 /// parseDirectiveSet: 2279 /// ::= .equ identifier ',' expression 2280 /// ::= .equiv identifier ',' expression 2281 /// ::= .set identifier ',' expression 2282 bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) { 2283 StringRef Name; 2284 2285 if (parseIdentifier(Name)) 2286 return TokError("expected identifier after '" + Twine(IDVal) + "'"); 2287 2288 if (getLexer().isNot(AsmToken::Comma)) 2289 return TokError("unexpected token in '" + Twine(IDVal) + "'"); 2290 Lex(); 2291 2292 return parseAssignment(Name, allow_redef, true); 2293 } 2294 2295 bool AsmParser::parseEscapedString(std::string &Data) { 2296 assert(getLexer().is(AsmToken::String) && "Unexpected current token!"); 2297 2298 Data = ""; 2299 StringRef Str = getTok().getStringContents(); 2300 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 2301 if (Str[i] != '\\') { 2302 Data += Str[i]; 2303 continue; 2304 } 2305 2306 // Recognize escaped characters. Note that this escape semantics currently 2307 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 2308 ++i; 2309 if (i == e) 2310 return TokError("unexpected backslash at end of string"); 2311 2312 // Recognize octal sequences. 2313 if ((unsigned)(Str[i] - '0') <= 7) { 2314 // Consume up to three octal characters. 2315 unsigned Value = Str[i] - '0'; 2316 2317 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) { 2318 ++i; 2319 Value = Value * 8 + (Str[i] - '0'); 2320 2321 if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) { 2322 ++i; 2323 Value = Value * 8 + (Str[i] - '0'); 2324 } 2325 } 2326 2327 if (Value > 255) 2328 return TokError("invalid octal escape sequence (out of range)"); 2329 2330 Data += (unsigned char)Value; 2331 continue; 2332 } 2333 2334 // Otherwise recognize individual escapes. 2335 switch (Str[i]) { 2336 default: 2337 // Just reject invalid escape sequences for now. 2338 return TokError("invalid escape sequence (unrecognized character)"); 2339 2340 case 'b': Data += '\b'; break; 2341 case 'f': Data += '\f'; break; 2342 case 'n': Data += '\n'; break; 2343 case 'r': Data += '\r'; break; 2344 case 't': Data += '\t'; break; 2345 case '"': Data += '"'; break; 2346 case '\\': Data += '\\'; break; 2347 } 2348 } 2349 2350 return false; 2351 } 2352 2353 /// parseDirectiveAscii: 2354 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 2355 bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 2356 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2357 checkForValidSection(); 2358 2359 for (;;) { 2360 if (getLexer().isNot(AsmToken::String)) 2361 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 2362 2363 std::string Data; 2364 if (parseEscapedString(Data)) 2365 return true; 2366 2367 getStreamer().EmitBytes(Data); 2368 if (ZeroTerminated) 2369 getStreamer().EmitBytes(StringRef("\0", 1)); 2370 2371 Lex(); 2372 2373 if (getLexer().is(AsmToken::EndOfStatement)) 2374 break; 2375 2376 if (getLexer().isNot(AsmToken::Comma)) 2377 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 2378 Lex(); 2379 } 2380 } 2381 2382 Lex(); 2383 return false; 2384 } 2385 2386 /// parseDirectiveValue 2387 /// ::= (.byte | .short | ... ) [ expression (, expression)* ] 2388 bool AsmParser::parseDirectiveValue(unsigned Size) { 2389 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2390 checkForValidSection(); 2391 2392 for (;;) { 2393 const MCExpr *Value; 2394 SMLoc ExprLoc = getLexer().getLoc(); 2395 if (parseExpression(Value)) 2396 return true; 2397 2398 // Special case constant expressions to match code generator. 2399 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2400 assert(Size <= 8 && "Invalid size"); 2401 uint64_t IntValue = MCE->getValue(); 2402 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 2403 return Error(ExprLoc, "literal value out of range for directive"); 2404 getStreamer().EmitIntValue(IntValue, Size); 2405 } else 2406 getStreamer().EmitValue(Value, Size, ExprLoc); 2407 2408 if (getLexer().is(AsmToken::EndOfStatement)) 2409 break; 2410 2411 // FIXME: Improve diagnostic. 2412 if (getLexer().isNot(AsmToken::Comma)) 2413 return TokError("unexpected token in directive"); 2414 Lex(); 2415 } 2416 } 2417 2418 Lex(); 2419 return false; 2420 } 2421 2422 /// ParseDirectiveOctaValue 2423 /// ::= .octa [ hexconstant (, hexconstant)* ] 2424 bool AsmParser::parseDirectiveOctaValue() { 2425 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2426 checkForValidSection(); 2427 2428 for (;;) { 2429 if (Lexer.getKind() == AsmToken::Error) 2430 return true; 2431 if (Lexer.getKind() != AsmToken::Integer && 2432 Lexer.getKind() != AsmToken::BigNum) 2433 return TokError("unknown token in expression"); 2434 2435 SMLoc ExprLoc = getLexer().getLoc(); 2436 APInt IntValue = getTok().getAPIntVal(); 2437 Lex(); 2438 2439 uint64_t hi, lo; 2440 if (IntValue.isIntN(64)) { 2441 hi = 0; 2442 lo = IntValue.getZExtValue(); 2443 } else if (IntValue.isIntN(128)) { 2444 // It might actually have more than 128 bits, but the top ones are zero. 2445 hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue(); 2446 lo = IntValue.getLoBits(64).getZExtValue(); 2447 } else 2448 return Error(ExprLoc, "literal value out of range for directive"); 2449 2450 if (MAI.isLittleEndian()) { 2451 getStreamer().EmitIntValue(lo, 8); 2452 getStreamer().EmitIntValue(hi, 8); 2453 } else { 2454 getStreamer().EmitIntValue(hi, 8); 2455 getStreamer().EmitIntValue(lo, 8); 2456 } 2457 2458 if (getLexer().is(AsmToken::EndOfStatement)) 2459 break; 2460 2461 // FIXME: Improve diagnostic. 2462 if (getLexer().isNot(AsmToken::Comma)) 2463 return TokError("unexpected token in directive"); 2464 Lex(); 2465 } 2466 } 2467 2468 Lex(); 2469 return false; 2470 } 2471 2472 /// parseDirectiveRealValue 2473 /// ::= (.single | .double) [ expression (, expression)* ] 2474 bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) { 2475 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2476 checkForValidSection(); 2477 2478 for (;;) { 2479 // We don't truly support arithmetic on floating point expressions, so we 2480 // have to manually parse unary prefixes. 2481 bool IsNeg = false; 2482 if (getLexer().is(AsmToken::Minus)) { 2483 Lex(); 2484 IsNeg = true; 2485 } else if (getLexer().is(AsmToken::Plus)) 2486 Lex(); 2487 2488 if (getLexer().isNot(AsmToken::Integer) && 2489 getLexer().isNot(AsmToken::Real) && 2490 getLexer().isNot(AsmToken::Identifier)) 2491 return TokError("unexpected token in directive"); 2492 2493 // Convert to an APFloat. 2494 APFloat Value(Semantics); 2495 StringRef IDVal = getTok().getString(); 2496 if (getLexer().is(AsmToken::Identifier)) { 2497 if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) 2498 Value = APFloat::getInf(Semantics); 2499 else if (!IDVal.compare_lower("nan")) 2500 Value = APFloat::getNaN(Semantics, false, ~0); 2501 else 2502 return TokError("invalid floating point literal"); 2503 } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == 2504 APFloat::opInvalidOp) 2505 return TokError("invalid floating point literal"); 2506 if (IsNeg) 2507 Value.changeSign(); 2508 2509 // Consume the numeric token. 2510 Lex(); 2511 2512 // Emit the value as an integer. 2513 APInt AsInt = Value.bitcastToAPInt(); 2514 getStreamer().EmitIntValue(AsInt.getLimitedValue(), 2515 AsInt.getBitWidth() / 8); 2516 2517 if (getLexer().is(AsmToken::EndOfStatement)) 2518 break; 2519 2520 if (getLexer().isNot(AsmToken::Comma)) 2521 return TokError("unexpected token in directive"); 2522 Lex(); 2523 } 2524 } 2525 2526 Lex(); 2527 return false; 2528 } 2529 2530 /// parseDirectiveZero 2531 /// ::= .zero expression 2532 bool AsmParser::parseDirectiveZero() { 2533 checkForValidSection(); 2534 2535 int64_t NumBytes; 2536 if (parseAbsoluteExpression(NumBytes)) 2537 return true; 2538 2539 int64_t Val = 0; 2540 if (getLexer().is(AsmToken::Comma)) { 2541 Lex(); 2542 if (parseAbsoluteExpression(Val)) 2543 return true; 2544 } 2545 2546 if (getLexer().isNot(AsmToken::EndOfStatement)) 2547 return TokError("unexpected token in '.zero' directive"); 2548 2549 Lex(); 2550 2551 getStreamer().EmitFill(NumBytes, Val); 2552 2553 return false; 2554 } 2555 2556 /// parseDirectiveFill 2557 /// ::= .fill expression [ , expression [ , expression ] ] 2558 bool AsmParser::parseDirectiveFill() { 2559 checkForValidSection(); 2560 2561 SMLoc RepeatLoc = getLexer().getLoc(); 2562 int64_t NumValues; 2563 if (parseAbsoluteExpression(NumValues)) 2564 return true; 2565 2566 if (NumValues < 0) { 2567 Warning(RepeatLoc, 2568 "'.fill' directive with negative repeat count has no effect"); 2569 NumValues = 0; 2570 } 2571 2572 int64_t FillSize = 1; 2573 int64_t FillExpr = 0; 2574 2575 SMLoc SizeLoc, ExprLoc; 2576 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2577 if (getLexer().isNot(AsmToken::Comma)) 2578 return TokError("unexpected token in '.fill' directive"); 2579 Lex(); 2580 2581 SizeLoc = getLexer().getLoc(); 2582 if (parseAbsoluteExpression(FillSize)) 2583 return true; 2584 2585 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2586 if (getLexer().isNot(AsmToken::Comma)) 2587 return TokError("unexpected token in '.fill' directive"); 2588 Lex(); 2589 2590 ExprLoc = getLexer().getLoc(); 2591 if (parseAbsoluteExpression(FillExpr)) 2592 return true; 2593 2594 if (getLexer().isNot(AsmToken::EndOfStatement)) 2595 return TokError("unexpected token in '.fill' directive"); 2596 2597 Lex(); 2598 } 2599 } 2600 2601 if (FillSize < 0) { 2602 Warning(SizeLoc, "'.fill' directive with negative size has no effect"); 2603 NumValues = 0; 2604 } 2605 if (FillSize > 8) { 2606 Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8"); 2607 FillSize = 8; 2608 } 2609 2610 if (!isUInt<32>(FillExpr) && FillSize > 4) 2611 Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits"); 2612 2613 int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize; 2614 FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8); 2615 2616 for (uint64_t i = 0, e = NumValues; i != e; ++i) { 2617 getStreamer().EmitIntValue(FillExpr, NonZeroFillSize); 2618 getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize); 2619 } 2620 2621 return false; 2622 } 2623 2624 /// parseDirectiveOrg 2625 /// ::= .org expression [ , expression ] 2626 bool AsmParser::parseDirectiveOrg() { 2627 checkForValidSection(); 2628 2629 const MCExpr *Offset; 2630 SMLoc Loc = getTok().getLoc(); 2631 if (parseExpression(Offset)) 2632 return true; 2633 2634 // Parse optional fill expression. 2635 int64_t FillExpr = 0; 2636 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2637 if (getLexer().isNot(AsmToken::Comma)) 2638 return TokError("unexpected token in '.org' directive"); 2639 Lex(); 2640 2641 if (parseAbsoluteExpression(FillExpr)) 2642 return true; 2643 2644 if (getLexer().isNot(AsmToken::EndOfStatement)) 2645 return TokError("unexpected token in '.org' directive"); 2646 } 2647 2648 Lex(); 2649 2650 // Only limited forms of relocatable expressions are accepted here, it 2651 // has to be relative to the current section. The streamer will return 2652 // 'true' if the expression wasn't evaluatable. 2653 if (getStreamer().EmitValueToOffset(Offset, FillExpr)) 2654 return Error(Loc, "expected assembly-time absolute expression"); 2655 2656 return false; 2657 } 2658 2659 /// parseDirectiveAlign 2660 /// ::= {.align, ...} expression [ , expression [ , expression ]] 2661 bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 2662 checkForValidSection(); 2663 2664 SMLoc AlignmentLoc = getLexer().getLoc(); 2665 int64_t Alignment; 2666 if (parseAbsoluteExpression(Alignment)) 2667 return true; 2668 2669 SMLoc MaxBytesLoc; 2670 bool HasFillExpr = false; 2671 int64_t FillExpr = 0; 2672 int64_t MaxBytesToFill = 0; 2673 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2674 if (getLexer().isNot(AsmToken::Comma)) 2675 return TokError("unexpected token in directive"); 2676 Lex(); 2677 2678 // The fill expression can be omitted while specifying a maximum number of 2679 // alignment bytes, e.g: 2680 // .align 3,,4 2681 if (getLexer().isNot(AsmToken::Comma)) { 2682 HasFillExpr = true; 2683 if (parseAbsoluteExpression(FillExpr)) 2684 return true; 2685 } 2686 2687 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2688 if (getLexer().isNot(AsmToken::Comma)) 2689 return TokError("unexpected token in directive"); 2690 Lex(); 2691 2692 MaxBytesLoc = getLexer().getLoc(); 2693 if (parseAbsoluteExpression(MaxBytesToFill)) 2694 return true; 2695 2696 if (getLexer().isNot(AsmToken::EndOfStatement)) 2697 return TokError("unexpected token in directive"); 2698 } 2699 } 2700 2701 Lex(); 2702 2703 if (!HasFillExpr) 2704 FillExpr = 0; 2705 2706 // Compute alignment in bytes. 2707 if (IsPow2) { 2708 // FIXME: Diagnose overflow. 2709 if (Alignment >= 32) { 2710 Error(AlignmentLoc, "invalid alignment value"); 2711 Alignment = 31; 2712 } 2713 2714 Alignment = 1ULL << Alignment; 2715 } else { 2716 // Reject alignments that aren't a power of two, for gas compatibility. 2717 if (!isPowerOf2_64(Alignment)) 2718 Error(AlignmentLoc, "alignment must be a power of 2"); 2719 } 2720 2721 // Diagnose non-sensical max bytes to align. 2722 if (MaxBytesLoc.isValid()) { 2723 if (MaxBytesToFill < 1) { 2724 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 2725 "many bytes, ignoring maximum bytes expression"); 2726 MaxBytesToFill = 0; 2727 } 2728 2729 if (MaxBytesToFill >= Alignment) { 2730 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 2731 "has no effect"); 2732 MaxBytesToFill = 0; 2733 } 2734 } 2735 2736 // Check whether we should use optimal code alignment for this .align 2737 // directive. 2738 const MCSection *Section = getStreamer().getCurrentSection().first; 2739 assert(Section && "must have section to emit alignment"); 2740 bool UseCodeAlign = Section->UseCodeAlign(); 2741 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && 2742 ValueSize == 1 && UseCodeAlign) { 2743 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); 2744 } else { 2745 // FIXME: Target specific behavior about how the "extra" bytes are filled. 2746 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, 2747 MaxBytesToFill); 2748 } 2749 2750 return false; 2751 } 2752 2753 /// parseDirectiveFile 2754 /// ::= .file [number] filename 2755 /// ::= .file number directory filename 2756 bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { 2757 // FIXME: I'm not sure what this is. 2758 int64_t FileNumber = -1; 2759 SMLoc FileNumberLoc = getLexer().getLoc(); 2760 if (getLexer().is(AsmToken::Integer)) { 2761 FileNumber = getTok().getIntVal(); 2762 Lex(); 2763 2764 if (FileNumber < 1) 2765 return TokError("file number less than one"); 2766 } 2767 2768 if (getLexer().isNot(AsmToken::String)) 2769 return TokError("unexpected token in '.file' directive"); 2770 2771 // Usually the directory and filename together, otherwise just the directory. 2772 // Allow the strings to have escaped octal character sequence. 2773 std::string Path = getTok().getString(); 2774 if (parseEscapedString(Path)) 2775 return true; 2776 Lex(); 2777 2778 StringRef Directory; 2779 StringRef Filename; 2780 std::string FilenameData; 2781 if (getLexer().is(AsmToken::String)) { 2782 if (FileNumber == -1) 2783 return TokError("explicit path specified, but no file number"); 2784 if (parseEscapedString(FilenameData)) 2785 return true; 2786 Filename = FilenameData; 2787 Directory = Path; 2788 Lex(); 2789 } else { 2790 Filename = Path; 2791 } 2792 2793 if (getLexer().isNot(AsmToken::EndOfStatement)) 2794 return TokError("unexpected token in '.file' directive"); 2795 2796 if (FileNumber == -1) 2797 getStreamer().EmitFileDirective(Filename); 2798 else { 2799 if (getContext().getGenDwarfForAssembly() == true) 2800 Error(DirectiveLoc, 2801 "input can't have .file dwarf directives when -g is " 2802 "used to generate dwarf debug info for assembly code"); 2803 2804 if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) == 2805 0) 2806 Error(FileNumberLoc, "file number already allocated"); 2807 } 2808 2809 return false; 2810 } 2811 2812 /// parseDirectiveLine 2813 /// ::= .line [number] 2814 bool AsmParser::parseDirectiveLine() { 2815 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2816 if (getLexer().isNot(AsmToken::Integer)) 2817 return TokError("unexpected token in '.line' directive"); 2818 2819 int64_t LineNumber = getTok().getIntVal(); 2820 (void)LineNumber; 2821 Lex(); 2822 2823 // FIXME: Do something with the .line. 2824 } 2825 2826 if (getLexer().isNot(AsmToken::EndOfStatement)) 2827 return TokError("unexpected token in '.line' directive"); 2828 2829 return false; 2830 } 2831 2832 /// parseDirectiveLoc 2833 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 2834 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 2835 /// The first number is a file number, must have been previously assigned with 2836 /// a .file directive, the second number is the line number and optionally the 2837 /// third number is a column position (zero if not specified). The remaining 2838 /// optional items are .loc sub-directives. 2839 bool AsmParser::parseDirectiveLoc() { 2840 if (getLexer().isNot(AsmToken::Integer)) 2841 return TokError("unexpected token in '.loc' directive"); 2842 int64_t FileNumber = getTok().getIntVal(); 2843 if (FileNumber < 1) 2844 return TokError("file number less than one in '.loc' directive"); 2845 if (!getContext().isValidDwarfFileNumber(FileNumber)) 2846 return TokError("unassigned file number in '.loc' directive"); 2847 Lex(); 2848 2849 int64_t LineNumber = 0; 2850 if (getLexer().is(AsmToken::Integer)) { 2851 LineNumber = getTok().getIntVal(); 2852 if (LineNumber < 0) 2853 return TokError("line number less than zero in '.loc' directive"); 2854 Lex(); 2855 } 2856 2857 int64_t ColumnPos = 0; 2858 if (getLexer().is(AsmToken::Integer)) { 2859 ColumnPos = getTok().getIntVal(); 2860 if (ColumnPos < 0) 2861 return TokError("column position less than zero in '.loc' directive"); 2862 Lex(); 2863 } 2864 2865 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 2866 unsigned Isa = 0; 2867 int64_t Discriminator = 0; 2868 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2869 for (;;) { 2870 if (getLexer().is(AsmToken::EndOfStatement)) 2871 break; 2872 2873 StringRef Name; 2874 SMLoc Loc = getTok().getLoc(); 2875 if (parseIdentifier(Name)) 2876 return TokError("unexpected token in '.loc' directive"); 2877 2878 if (Name == "basic_block") 2879 Flags |= DWARF2_FLAG_BASIC_BLOCK; 2880 else if (Name == "prologue_end") 2881 Flags |= DWARF2_FLAG_PROLOGUE_END; 2882 else if (Name == "epilogue_begin") 2883 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 2884 else if (Name == "is_stmt") { 2885 Loc = getTok().getLoc(); 2886 const MCExpr *Value; 2887 if (parseExpression(Value)) 2888 return true; 2889 // The expression must be the constant 0 or 1. 2890 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2891 int Value = MCE->getValue(); 2892 if (Value == 0) 2893 Flags &= ~DWARF2_FLAG_IS_STMT; 2894 else if (Value == 1) 2895 Flags |= DWARF2_FLAG_IS_STMT; 2896 else 2897 return Error(Loc, "is_stmt value not 0 or 1"); 2898 } else { 2899 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 2900 } 2901 } else if (Name == "isa") { 2902 Loc = getTok().getLoc(); 2903 const MCExpr *Value; 2904 if (parseExpression(Value)) 2905 return true; 2906 // The expression must be a constant greater or equal to 0. 2907 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2908 int Value = MCE->getValue(); 2909 if (Value < 0) 2910 return Error(Loc, "isa number less than zero"); 2911 Isa = Value; 2912 } else { 2913 return Error(Loc, "isa number not a constant value"); 2914 } 2915 } else if (Name == "discriminator") { 2916 if (parseAbsoluteExpression(Discriminator)) 2917 return true; 2918 } else { 2919 return Error(Loc, "unknown sub-directive in '.loc' directive"); 2920 } 2921 2922 if (getLexer().is(AsmToken::EndOfStatement)) 2923 break; 2924 } 2925 } 2926 2927 getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 2928 Isa, Discriminator, StringRef()); 2929 2930 return false; 2931 } 2932 2933 /// parseDirectiveStabs 2934 /// ::= .stabs string, number, number, number 2935 bool AsmParser::parseDirectiveStabs() { 2936 return TokError("unsupported directive '.stabs'"); 2937 } 2938 2939 /// parseDirectiveCFISections 2940 /// ::= .cfi_sections section [, section] 2941 bool AsmParser::parseDirectiveCFISections() { 2942 StringRef Name; 2943 bool EH = false; 2944 bool Debug = false; 2945 2946 if (parseIdentifier(Name)) 2947 return TokError("Expected an identifier"); 2948 2949 if (Name == ".eh_frame") 2950 EH = true; 2951 else if (Name == ".debug_frame") 2952 Debug = true; 2953 2954 if (getLexer().is(AsmToken::Comma)) { 2955 Lex(); 2956 2957 if (parseIdentifier(Name)) 2958 return TokError("Expected an identifier"); 2959 2960 if (Name == ".eh_frame") 2961 EH = true; 2962 else if (Name == ".debug_frame") 2963 Debug = true; 2964 } 2965 2966 getStreamer().EmitCFISections(EH, Debug); 2967 return false; 2968 } 2969 2970 /// parseDirectiveCFIStartProc 2971 /// ::= .cfi_startproc [simple] 2972 bool AsmParser::parseDirectiveCFIStartProc() { 2973 StringRef Simple; 2974 if (getLexer().isNot(AsmToken::EndOfStatement)) 2975 if (parseIdentifier(Simple) || Simple != "simple") 2976 return TokError("unexpected token in .cfi_startproc directive"); 2977 2978 getStreamer().EmitCFIStartProc(!Simple.empty()); 2979 return false; 2980 } 2981 2982 /// parseDirectiveCFIEndProc 2983 /// ::= .cfi_endproc 2984 bool AsmParser::parseDirectiveCFIEndProc() { 2985 getStreamer().EmitCFIEndProc(); 2986 return false; 2987 } 2988 2989 /// \brief parse register name or number. 2990 bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register, 2991 SMLoc DirectiveLoc) { 2992 unsigned RegNo; 2993 2994 if (getLexer().isNot(AsmToken::Integer)) { 2995 if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) 2996 return true; 2997 Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); 2998 } else 2999 return parseAbsoluteExpression(Register); 3000 3001 return false; 3002 } 3003 3004 /// parseDirectiveCFIDefCfa 3005 /// ::= .cfi_def_cfa register, offset 3006 bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { 3007 int64_t Register = 0; 3008 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3009 return true; 3010 3011 if (getLexer().isNot(AsmToken::Comma)) 3012 return TokError("unexpected token in directive"); 3013 Lex(); 3014 3015 int64_t Offset = 0; 3016 if (parseAbsoluteExpression(Offset)) 3017 return true; 3018 3019 getStreamer().EmitCFIDefCfa(Register, Offset); 3020 return false; 3021 } 3022 3023 /// parseDirectiveCFIDefCfaOffset 3024 /// ::= .cfi_def_cfa_offset offset 3025 bool AsmParser::parseDirectiveCFIDefCfaOffset() { 3026 int64_t Offset = 0; 3027 if (parseAbsoluteExpression(Offset)) 3028 return true; 3029 3030 getStreamer().EmitCFIDefCfaOffset(Offset); 3031 return false; 3032 } 3033 3034 /// parseDirectiveCFIRegister 3035 /// ::= .cfi_register register, register 3036 bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) { 3037 int64_t Register1 = 0; 3038 if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc)) 3039 return true; 3040 3041 if (getLexer().isNot(AsmToken::Comma)) 3042 return TokError("unexpected token in directive"); 3043 Lex(); 3044 3045 int64_t Register2 = 0; 3046 if (parseRegisterOrRegisterNumber(Register2, DirectiveLoc)) 3047 return true; 3048 3049 getStreamer().EmitCFIRegister(Register1, Register2); 3050 return false; 3051 } 3052 3053 /// parseDirectiveCFIWindowSave 3054 /// ::= .cfi_window_save 3055 bool AsmParser::parseDirectiveCFIWindowSave() { 3056 getStreamer().EmitCFIWindowSave(); 3057 return false; 3058 } 3059 3060 /// parseDirectiveCFIAdjustCfaOffset 3061 /// ::= .cfi_adjust_cfa_offset adjustment 3062 bool AsmParser::parseDirectiveCFIAdjustCfaOffset() { 3063 int64_t Adjustment = 0; 3064 if (parseAbsoluteExpression(Adjustment)) 3065 return true; 3066 3067 getStreamer().EmitCFIAdjustCfaOffset(Adjustment); 3068 return false; 3069 } 3070 3071 /// parseDirectiveCFIDefCfaRegister 3072 /// ::= .cfi_def_cfa_register register 3073 bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { 3074 int64_t Register = 0; 3075 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3076 return true; 3077 3078 getStreamer().EmitCFIDefCfaRegister(Register); 3079 return false; 3080 } 3081 3082 /// parseDirectiveCFIOffset 3083 /// ::= .cfi_offset register, offset 3084 bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) { 3085 int64_t Register = 0; 3086 int64_t Offset = 0; 3087 3088 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3089 return true; 3090 3091 if (getLexer().isNot(AsmToken::Comma)) 3092 return TokError("unexpected token in directive"); 3093 Lex(); 3094 3095 if (parseAbsoluteExpression(Offset)) 3096 return true; 3097 3098 getStreamer().EmitCFIOffset(Register, Offset); 3099 return false; 3100 } 3101 3102 /// parseDirectiveCFIRelOffset 3103 /// ::= .cfi_rel_offset register, offset 3104 bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { 3105 int64_t Register = 0; 3106 3107 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3108 return true; 3109 3110 if (getLexer().isNot(AsmToken::Comma)) 3111 return TokError("unexpected token in directive"); 3112 Lex(); 3113 3114 int64_t Offset = 0; 3115 if (parseAbsoluteExpression(Offset)) 3116 return true; 3117 3118 getStreamer().EmitCFIRelOffset(Register, Offset); 3119 return false; 3120 } 3121 3122 static bool isValidEncoding(int64_t Encoding) { 3123 if (Encoding & ~0xff) 3124 return false; 3125 3126 if (Encoding == dwarf::DW_EH_PE_omit) 3127 return true; 3128 3129 const unsigned Format = Encoding & 0xf; 3130 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 3131 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 3132 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 3133 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 3134 return false; 3135 3136 const unsigned Application = Encoding & 0x70; 3137 if (Application != dwarf::DW_EH_PE_absptr && 3138 Application != dwarf::DW_EH_PE_pcrel) 3139 return false; 3140 3141 return true; 3142 } 3143 3144 /// parseDirectiveCFIPersonalityOrLsda 3145 /// IsPersonality true for cfi_personality, false for cfi_lsda 3146 /// ::= .cfi_personality encoding, [symbol_name] 3147 /// ::= .cfi_lsda encoding, [symbol_name] 3148 bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { 3149 int64_t Encoding = 0; 3150 if (parseAbsoluteExpression(Encoding)) 3151 return true; 3152 if (Encoding == dwarf::DW_EH_PE_omit) 3153 return false; 3154 3155 if (!isValidEncoding(Encoding)) 3156 return TokError("unsupported encoding."); 3157 3158 if (getLexer().isNot(AsmToken::Comma)) 3159 return TokError("unexpected token in directive"); 3160 Lex(); 3161 3162 StringRef Name; 3163 if (parseIdentifier(Name)) 3164 return TokError("expected identifier in directive"); 3165 3166 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3167 3168 if (IsPersonality) 3169 getStreamer().EmitCFIPersonality(Sym, Encoding); 3170 else 3171 getStreamer().EmitCFILsda(Sym, Encoding); 3172 return false; 3173 } 3174 3175 /// parseDirectiveCFIRememberState 3176 /// ::= .cfi_remember_state 3177 bool AsmParser::parseDirectiveCFIRememberState() { 3178 getStreamer().EmitCFIRememberState(); 3179 return false; 3180 } 3181 3182 /// parseDirectiveCFIRestoreState 3183 /// ::= .cfi_remember_state 3184 bool AsmParser::parseDirectiveCFIRestoreState() { 3185 getStreamer().EmitCFIRestoreState(); 3186 return false; 3187 } 3188 3189 /// parseDirectiveCFISameValue 3190 /// ::= .cfi_same_value register 3191 bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) { 3192 int64_t Register = 0; 3193 3194 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3195 return true; 3196 3197 getStreamer().EmitCFISameValue(Register); 3198 return false; 3199 } 3200 3201 /// parseDirectiveCFIRestore 3202 /// ::= .cfi_restore register 3203 bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) { 3204 int64_t Register = 0; 3205 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3206 return true; 3207 3208 getStreamer().EmitCFIRestore(Register); 3209 return false; 3210 } 3211 3212 /// parseDirectiveCFIEscape 3213 /// ::= .cfi_escape expression[,...] 3214 bool AsmParser::parseDirectiveCFIEscape() { 3215 std::string Values; 3216 int64_t CurrValue; 3217 if (parseAbsoluteExpression(CurrValue)) 3218 return true; 3219 3220 Values.push_back((uint8_t)CurrValue); 3221 3222 while (getLexer().is(AsmToken::Comma)) { 3223 Lex(); 3224 3225 if (parseAbsoluteExpression(CurrValue)) 3226 return true; 3227 3228 Values.push_back((uint8_t)CurrValue); 3229 } 3230 3231 getStreamer().EmitCFIEscape(Values); 3232 return false; 3233 } 3234 3235 /// parseDirectiveCFISignalFrame 3236 /// ::= .cfi_signal_frame 3237 bool AsmParser::parseDirectiveCFISignalFrame() { 3238 if (getLexer().isNot(AsmToken::EndOfStatement)) 3239 return Error(getLexer().getLoc(), 3240 "unexpected token in '.cfi_signal_frame'"); 3241 3242 getStreamer().EmitCFISignalFrame(); 3243 return false; 3244 } 3245 3246 /// parseDirectiveCFIUndefined 3247 /// ::= .cfi_undefined register 3248 bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { 3249 int64_t Register = 0; 3250 3251 if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3252 return true; 3253 3254 getStreamer().EmitCFIUndefined(Register); 3255 return false; 3256 } 3257 3258 /// parseDirectiveMacrosOnOff 3259 /// ::= .macros_on 3260 /// ::= .macros_off 3261 bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) { 3262 if (getLexer().isNot(AsmToken::EndOfStatement)) 3263 return Error(getLexer().getLoc(), 3264 "unexpected token in '" + Directive + "' directive"); 3265 3266 setMacrosEnabled(Directive == ".macros_on"); 3267 return false; 3268 } 3269 3270 /// parseDirectiveMacro 3271 /// ::= .macro name[,] [parameters] 3272 bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { 3273 StringRef Name; 3274 if (parseIdentifier(Name)) 3275 return TokError("expected identifier in '.macro' directive"); 3276 3277 if (getLexer().is(AsmToken::Comma)) 3278 Lex(); 3279 3280 MCAsmMacroParameters Parameters; 3281 while (getLexer().isNot(AsmToken::EndOfStatement)) { 3282 3283 if (Parameters.size() && Parameters.back().Vararg) 3284 return Error(Lexer.getLoc(), 3285 "Vararg parameter '" + Parameters.back().Name + 3286 "' should be last one in the list of parameters."); 3287 3288 MCAsmMacroParameter Parameter; 3289 if (parseIdentifier(Parameter.Name)) 3290 return TokError("expected identifier in '.macro' directive"); 3291 3292 if (Lexer.is(AsmToken::Colon)) { 3293 Lex(); // consume ':' 3294 3295 SMLoc QualLoc; 3296 StringRef Qualifier; 3297 3298 QualLoc = Lexer.getLoc(); 3299 if (parseIdentifier(Qualifier)) 3300 return Error(QualLoc, "missing parameter qualifier for " 3301 "'" + Parameter.Name + "' in macro '" + Name + "'"); 3302 3303 if (Qualifier == "req") 3304 Parameter.Required = true; 3305 else if (Qualifier == "vararg") 3306 Parameter.Vararg = true; 3307 else 3308 return Error(QualLoc, Qualifier + " is not a valid parameter qualifier " 3309 "for '" + Parameter.Name + "' in macro '" + Name + "'"); 3310 } 3311 3312 if (getLexer().is(AsmToken::Equal)) { 3313 Lex(); 3314 3315 SMLoc ParamLoc; 3316 3317 ParamLoc = Lexer.getLoc(); 3318 if (parseMacroArgument(Parameter.Value, /*Vararg=*/false )) 3319 return true; 3320 3321 if (Parameter.Required) 3322 Warning(ParamLoc, "pointless default value for required parameter " 3323 "'" + Parameter.Name + "' in macro '" + Name + "'"); 3324 } 3325 3326 Parameters.push_back(Parameter); 3327 3328 if (getLexer().is(AsmToken::Comma)) 3329 Lex(); 3330 } 3331 3332 // Eat the end of statement. 3333 Lex(); 3334 3335 AsmToken EndToken, StartToken = getTok(); 3336 unsigned MacroDepth = 0; 3337 3338 // Lex the macro definition. 3339 for (;;) { 3340 // Check whether we have reached the end of the file. 3341 if (getLexer().is(AsmToken::Eof)) 3342 return Error(DirectiveLoc, "no matching '.endmacro' in definition"); 3343 3344 // Otherwise, check whether we have reach the .endmacro. 3345 if (getLexer().is(AsmToken::Identifier)) { 3346 if (getTok().getIdentifier() == ".endm" || 3347 getTok().getIdentifier() == ".endmacro") { 3348 if (MacroDepth == 0) { // Outermost macro. 3349 EndToken = getTok(); 3350 Lex(); 3351 if (getLexer().isNot(AsmToken::EndOfStatement)) 3352 return TokError("unexpected token in '" + EndToken.getIdentifier() + 3353 "' directive"); 3354 break; 3355 } else { 3356 // Otherwise we just found the end of an inner macro. 3357 --MacroDepth; 3358 } 3359 } else if (getTok().getIdentifier() == ".macro") { 3360 // We allow nested macros. Those aren't instantiated until the outermost 3361 // macro is expanded so just ignore them for now. 3362 ++MacroDepth; 3363 } 3364 } 3365 3366 // Otherwise, scan til the end of the statement. 3367 eatToEndOfStatement(); 3368 } 3369 3370 if (lookupMacro(Name)) { 3371 return Error(DirectiveLoc, "macro '" + Name + "' is already defined"); 3372 } 3373 3374 const char *BodyStart = StartToken.getLoc().getPointer(); 3375 const char *BodyEnd = EndToken.getLoc().getPointer(); 3376 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3377 checkForBadMacro(DirectiveLoc, Name, Body, Parameters); 3378 defineMacro(Name, MCAsmMacro(Name, Body, Parameters)); 3379 return false; 3380 } 3381 3382 /// checkForBadMacro 3383 /// 3384 /// With the support added for named parameters there may be code out there that 3385 /// is transitioning from positional parameters. In versions of gas that did 3386 /// not support named parameters they would be ignored on the macro definition. 3387 /// But to support both styles of parameters this is not possible so if a macro 3388 /// definition has named parameters but does not use them and has what appears 3389 /// to be positional parameters, strings like $1, $2, ... and $n, then issue a 3390 /// warning that the positional parameter found in body which have no effect. 3391 /// Hoping the developer will either remove the named parameters from the macro 3392 /// definition so the positional parameters get used if that was what was 3393 /// intended or change the macro to use the named parameters. It is possible 3394 /// this warning will trigger when the none of the named parameters are used 3395 /// and the strings like $1 are infact to simply to be passed trough unchanged. 3396 void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, 3397 StringRef Body, 3398 ArrayRef<MCAsmMacroParameter> Parameters) { 3399 // If this macro is not defined with named parameters the warning we are 3400 // checking for here doesn't apply. 3401 unsigned NParameters = Parameters.size(); 3402 if (NParameters == 0) 3403 return; 3404 3405 bool NamedParametersFound = false; 3406 bool PositionalParametersFound = false; 3407 3408 // Look at the body of the macro for use of both the named parameters and what 3409 // are likely to be positional parameters. This is what expandMacro() is 3410 // doing when it finds the parameters in the body. 3411 while (!Body.empty()) { 3412 // Scan for the next possible parameter. 3413 std::size_t End = Body.size(), Pos = 0; 3414 for (; Pos != End; ++Pos) { 3415 // Check for a substitution or escape. 3416 // This macro is defined with parameters, look for \foo, \bar, etc. 3417 if (Body[Pos] == '\\' && Pos + 1 != End) 3418 break; 3419 3420 // This macro should have parameters, but look for $0, $1, ..., $n too. 3421 if (Body[Pos] != '$' || Pos + 1 == End) 3422 continue; 3423 char Next = Body[Pos + 1]; 3424 if (Next == '$' || Next == 'n' || 3425 isdigit(static_cast<unsigned char>(Next))) 3426 break; 3427 } 3428 3429 // Check if we reached the end. 3430 if (Pos == End) 3431 break; 3432 3433 if (Body[Pos] == '$') { 3434 switch (Body[Pos + 1]) { 3435 // $$ => $ 3436 case '$': 3437 break; 3438 3439 // $n => number of arguments 3440 case 'n': 3441 PositionalParametersFound = true; 3442 break; 3443 3444 // $[0-9] => argument 3445 default: { 3446 PositionalParametersFound = true; 3447 break; 3448 } 3449 } 3450 Pos += 2; 3451 } else { 3452 unsigned I = Pos + 1; 3453 while (isIdentifierChar(Body[I]) && I + 1 != End) 3454 ++I; 3455 3456 const char *Begin = Body.data() + Pos + 1; 3457 StringRef Argument(Begin, I - (Pos + 1)); 3458 unsigned Index = 0; 3459 for (; Index < NParameters; ++Index) 3460 if (Parameters[Index].Name == Argument) 3461 break; 3462 3463 if (Index == NParameters) { 3464 if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') 3465 Pos += 3; 3466 else { 3467 Pos = I; 3468 } 3469 } else { 3470 NamedParametersFound = true; 3471 Pos += 1 + Argument.size(); 3472 } 3473 } 3474 // Update the scan point. 3475 Body = Body.substr(Pos); 3476 } 3477 3478 if (!NamedParametersFound && PositionalParametersFound) 3479 Warning(DirectiveLoc, "macro defined with named parameters which are not " 3480 "used in macro body, possible positional parameter " 3481 "found in body which will have no effect"); 3482 } 3483 3484 /// parseDirectiveExitMacro 3485 /// ::= .exitm 3486 bool AsmParser::parseDirectiveExitMacro(StringRef Directive) { 3487 if (getLexer().isNot(AsmToken::EndOfStatement)) 3488 return TokError("unexpected token in '" + Directive + "' directive"); 3489 3490 if (!isInsideMacroInstantiation()) 3491 return TokError("unexpected '" + Directive + "' in file, " 3492 "no current macro definition"); 3493 3494 // Exit all conditionals that are active in the current macro. 3495 while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) { 3496 TheCondState = TheCondStack.back(); 3497 TheCondStack.pop_back(); 3498 } 3499 3500 handleMacroExit(); 3501 return false; 3502 } 3503 3504 /// parseDirectiveEndMacro 3505 /// ::= .endm 3506 /// ::= .endmacro 3507 bool AsmParser::parseDirectiveEndMacro(StringRef Directive) { 3508 if (getLexer().isNot(AsmToken::EndOfStatement)) 3509 return TokError("unexpected token in '" + Directive + "' directive"); 3510 3511 // If we are inside a macro instantiation, terminate the current 3512 // instantiation. 3513 if (isInsideMacroInstantiation()) { 3514 handleMacroExit(); 3515 return false; 3516 } 3517 3518 // Otherwise, this .endmacro is a stray entry in the file; well formed 3519 // .endmacro directives are handled during the macro definition parsing. 3520 return TokError("unexpected '" + Directive + "' in file, " 3521 "no current macro definition"); 3522 } 3523 3524 /// parseDirectivePurgeMacro 3525 /// ::= .purgem 3526 bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { 3527 StringRef Name; 3528 if (parseIdentifier(Name)) 3529 return TokError("expected identifier in '.purgem' directive"); 3530 3531 if (getLexer().isNot(AsmToken::EndOfStatement)) 3532 return TokError("unexpected token in '.purgem' directive"); 3533 3534 if (!lookupMacro(Name)) 3535 return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); 3536 3537 undefineMacro(Name); 3538 return false; 3539 } 3540 3541 /// parseDirectiveBundleAlignMode 3542 /// ::= {.bundle_align_mode} expression 3543 bool AsmParser::parseDirectiveBundleAlignMode() { 3544 checkForValidSection(); 3545 3546 // Expect a single argument: an expression that evaluates to a constant 3547 // in the inclusive range 0-30. 3548 SMLoc ExprLoc = getLexer().getLoc(); 3549 int64_t AlignSizePow2; 3550 if (parseAbsoluteExpression(AlignSizePow2)) 3551 return true; 3552 else if (getLexer().isNot(AsmToken::EndOfStatement)) 3553 return TokError("unexpected token after expression in" 3554 " '.bundle_align_mode' directive"); 3555 else if (AlignSizePow2 < 0 || AlignSizePow2 > 30) 3556 return Error(ExprLoc, 3557 "invalid bundle alignment size (expected between 0 and 30)"); 3558 3559 Lex(); 3560 3561 // Because of AlignSizePow2's verified range we can safely truncate it to 3562 // unsigned. 3563 getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2)); 3564 return false; 3565 } 3566 3567 /// parseDirectiveBundleLock 3568 /// ::= {.bundle_lock} [align_to_end] 3569 bool AsmParser::parseDirectiveBundleLock() { 3570 checkForValidSection(); 3571 bool AlignToEnd = false; 3572 3573 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3574 StringRef Option; 3575 SMLoc Loc = getTok().getLoc(); 3576 const char *kInvalidOptionError = 3577 "invalid option for '.bundle_lock' directive"; 3578 3579 if (parseIdentifier(Option)) 3580 return Error(Loc, kInvalidOptionError); 3581 3582 if (Option != "align_to_end") 3583 return Error(Loc, kInvalidOptionError); 3584 else if (getLexer().isNot(AsmToken::EndOfStatement)) 3585 return Error(Loc, 3586 "unexpected token after '.bundle_lock' directive option"); 3587 AlignToEnd = true; 3588 } 3589 3590 Lex(); 3591 3592 getStreamer().EmitBundleLock(AlignToEnd); 3593 return false; 3594 } 3595 3596 /// parseDirectiveBundleLock 3597 /// ::= {.bundle_lock} 3598 bool AsmParser::parseDirectiveBundleUnlock() { 3599 checkForValidSection(); 3600 3601 if (getLexer().isNot(AsmToken::EndOfStatement)) 3602 return TokError("unexpected token in '.bundle_unlock' directive"); 3603 Lex(); 3604 3605 getStreamer().EmitBundleUnlock(); 3606 return false; 3607 } 3608 3609 /// parseDirectiveSpace 3610 /// ::= (.skip | .space) expression [ , expression ] 3611 bool AsmParser::parseDirectiveSpace(StringRef IDVal) { 3612 checkForValidSection(); 3613 3614 int64_t NumBytes; 3615 if (parseAbsoluteExpression(NumBytes)) 3616 return true; 3617 3618 int64_t FillExpr = 0; 3619 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3620 if (getLexer().isNot(AsmToken::Comma)) 3621 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 3622 Lex(); 3623 3624 if (parseAbsoluteExpression(FillExpr)) 3625 return true; 3626 3627 if (getLexer().isNot(AsmToken::EndOfStatement)) 3628 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 3629 } 3630 3631 Lex(); 3632 3633 if (NumBytes <= 0) 3634 return TokError("invalid number of bytes in '" + Twine(IDVal) + 3635 "' directive"); 3636 3637 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 3638 getStreamer().EmitFill(NumBytes, FillExpr); 3639 3640 return false; 3641 } 3642 3643 /// parseDirectiveLEB128 3644 /// ::= (.sleb128 | .uleb128) expression 3645 bool AsmParser::parseDirectiveLEB128(bool Signed) { 3646 checkForValidSection(); 3647 const MCExpr *Value; 3648 3649 if (parseExpression(Value)) 3650 return true; 3651 3652 if (getLexer().isNot(AsmToken::EndOfStatement)) 3653 return TokError("unexpected token in directive"); 3654 3655 if (Signed) 3656 getStreamer().EmitSLEB128Value(Value); 3657 else 3658 getStreamer().EmitULEB128Value(Value); 3659 3660 return false; 3661 } 3662 3663 /// parseDirectiveSymbolAttribute 3664 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 3665 bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 3666 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3667 for (;;) { 3668 StringRef Name; 3669 SMLoc Loc = getTok().getLoc(); 3670 3671 if (parseIdentifier(Name)) 3672 return Error(Loc, "expected identifier in directive"); 3673 3674 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3675 3676 // Assembler local symbols don't make any sense here. Complain loudly. 3677 if (Sym->isTemporary()) 3678 return Error(Loc, "non-local symbol required in directive"); 3679 3680 if (!getStreamer().EmitSymbolAttribute(Sym, Attr)) 3681 return Error(Loc, "unable to emit symbol attribute"); 3682 3683 if (getLexer().is(AsmToken::EndOfStatement)) 3684 break; 3685 3686 if (getLexer().isNot(AsmToken::Comma)) 3687 return TokError("unexpected token in directive"); 3688 Lex(); 3689 } 3690 } 3691 3692 Lex(); 3693 return false; 3694 } 3695 3696 /// parseDirectiveComm 3697 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 3698 bool AsmParser::parseDirectiveComm(bool IsLocal) { 3699 checkForValidSection(); 3700 3701 SMLoc IDLoc = getLexer().getLoc(); 3702 StringRef Name; 3703 if (parseIdentifier(Name)) 3704 return TokError("expected identifier in directive"); 3705 3706 // Handle the identifier as the key symbol. 3707 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 3708 3709 if (getLexer().isNot(AsmToken::Comma)) 3710 return TokError("unexpected token in directive"); 3711 Lex(); 3712 3713 int64_t Size; 3714 SMLoc SizeLoc = getLexer().getLoc(); 3715 if (parseAbsoluteExpression(Size)) 3716 return true; 3717 3718 int64_t Pow2Alignment = 0; 3719 SMLoc Pow2AlignmentLoc; 3720 if (getLexer().is(AsmToken::Comma)) { 3721 Lex(); 3722 Pow2AlignmentLoc = getLexer().getLoc(); 3723 if (parseAbsoluteExpression(Pow2Alignment)) 3724 return true; 3725 3726 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 3727 if (IsLocal && LCOMM == LCOMM::NoAlignment) 3728 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 3729 3730 // If this target takes alignments in bytes (not log) validate and convert. 3731 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 3732 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 3733 if (!isPowerOf2_64(Pow2Alignment)) 3734 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 3735 Pow2Alignment = Log2_64(Pow2Alignment); 3736 } 3737 } 3738 3739 if (getLexer().isNot(AsmToken::EndOfStatement)) 3740 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 3741 3742 Lex(); 3743 3744 // NOTE: a size of zero for a .comm should create a undefined symbol 3745 // but a size of .lcomm creates a bss symbol of size zero. 3746 if (Size < 0) 3747 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 3748 "be less than zero"); 3749 3750 // NOTE: The alignment in the directive is a power of 2 value, the assembler 3751 // may internally end up wanting an alignment in bytes. 3752 // FIXME: Diagnose overflow. 3753 if (Pow2Alignment < 0) 3754 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 3755 "alignment, can't be less than zero"); 3756 3757 if (!Sym->isUndefined()) 3758 return Error(IDLoc, "invalid symbol redefinition"); 3759 3760 // Create the Symbol as a common or local common with Size and Pow2Alignment 3761 if (IsLocal) { 3762 getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 3763 return false; 3764 } 3765 3766 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 3767 return false; 3768 } 3769 3770 /// parseDirectiveAbort 3771 /// ::= .abort [... message ...] 3772 bool AsmParser::parseDirectiveAbort() { 3773 // FIXME: Use loc from directive. 3774 SMLoc Loc = getLexer().getLoc(); 3775 3776 StringRef Str = parseStringToEndOfStatement(); 3777 if (getLexer().isNot(AsmToken::EndOfStatement)) 3778 return TokError("unexpected token in '.abort' directive"); 3779 3780 Lex(); 3781 3782 if (Str.empty()) 3783 Error(Loc, ".abort detected. Assembly stopping."); 3784 else 3785 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 3786 // FIXME: Actually abort assembly here. 3787 3788 return false; 3789 } 3790 3791 /// parseDirectiveInclude 3792 /// ::= .include "filename" 3793 bool AsmParser::parseDirectiveInclude() { 3794 if (getLexer().isNot(AsmToken::String)) 3795 return TokError("expected string in '.include' directive"); 3796 3797 // Allow the strings to have escaped octal character sequence. 3798 std::string Filename; 3799 if (parseEscapedString(Filename)) 3800 return true; 3801 SMLoc IncludeLoc = getLexer().getLoc(); 3802 Lex(); 3803 3804 if (getLexer().isNot(AsmToken::EndOfStatement)) 3805 return TokError("unexpected token in '.include' directive"); 3806 3807 // Attempt to switch the lexer to the included file before consuming the end 3808 // of statement to avoid losing it when we switch. 3809 if (enterIncludeFile(Filename)) { 3810 Error(IncludeLoc, "Could not find include file '" + Filename + "'"); 3811 return true; 3812 } 3813 3814 return false; 3815 } 3816 3817 /// parseDirectiveIncbin 3818 /// ::= .incbin "filename" 3819 bool AsmParser::parseDirectiveIncbin() { 3820 if (getLexer().isNot(AsmToken::String)) 3821 return TokError("expected string in '.incbin' directive"); 3822 3823 // Allow the strings to have escaped octal character sequence. 3824 std::string Filename; 3825 if (parseEscapedString(Filename)) 3826 return true; 3827 SMLoc IncbinLoc = getLexer().getLoc(); 3828 Lex(); 3829 3830 if (getLexer().isNot(AsmToken::EndOfStatement)) 3831 return TokError("unexpected token in '.incbin' directive"); 3832 3833 // Attempt to process the included file. 3834 if (processIncbinFile(Filename)) { 3835 Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); 3836 return true; 3837 } 3838 3839 return false; 3840 } 3841 3842 /// parseDirectiveIf 3843 /// ::= .if{,eq,ge,gt,le,lt,ne} expression 3844 bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) { 3845 TheCondStack.push_back(TheCondState); 3846 TheCondState.TheCond = AsmCond::IfCond; 3847 if (TheCondState.Ignore) { 3848 eatToEndOfStatement(); 3849 } else { 3850 int64_t ExprValue; 3851 if (parseAbsoluteExpression(ExprValue)) 3852 return true; 3853 3854 if (getLexer().isNot(AsmToken::EndOfStatement)) 3855 return TokError("unexpected token in '.if' directive"); 3856 3857 Lex(); 3858 3859 switch (DirKind) { 3860 default: 3861 llvm_unreachable("unsupported directive"); 3862 case DK_IF: 3863 case DK_IFNE: 3864 break; 3865 case DK_IFEQ: 3866 ExprValue = ExprValue == 0; 3867 break; 3868 case DK_IFGE: 3869 ExprValue = ExprValue >= 0; 3870 break; 3871 case DK_IFGT: 3872 ExprValue = ExprValue > 0; 3873 break; 3874 case DK_IFLE: 3875 ExprValue = ExprValue <= 0; 3876 break; 3877 case DK_IFLT: 3878 ExprValue = ExprValue < 0; 3879 break; 3880 } 3881 3882 TheCondState.CondMet = ExprValue; 3883 TheCondState.Ignore = !TheCondState.CondMet; 3884 } 3885 3886 return false; 3887 } 3888 3889 /// parseDirectiveIfb 3890 /// ::= .ifb string 3891 bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 3892 TheCondStack.push_back(TheCondState); 3893 TheCondState.TheCond = AsmCond::IfCond; 3894 3895 if (TheCondState.Ignore) { 3896 eatToEndOfStatement(); 3897 } else { 3898 StringRef Str = parseStringToEndOfStatement(); 3899 3900 if (getLexer().isNot(AsmToken::EndOfStatement)) 3901 return TokError("unexpected token in '.ifb' directive"); 3902 3903 Lex(); 3904 3905 TheCondState.CondMet = ExpectBlank == Str.empty(); 3906 TheCondState.Ignore = !TheCondState.CondMet; 3907 } 3908 3909 return false; 3910 } 3911 3912 /// parseDirectiveIfc 3913 /// ::= .ifc string1, string2 3914 /// ::= .ifnc string1, string2 3915 bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { 3916 TheCondStack.push_back(TheCondState); 3917 TheCondState.TheCond = AsmCond::IfCond; 3918 3919 if (TheCondState.Ignore) { 3920 eatToEndOfStatement(); 3921 } else { 3922 StringRef Str1 = parseStringToComma(); 3923 3924 if (getLexer().isNot(AsmToken::Comma)) 3925 return TokError("unexpected token in '.ifc' directive"); 3926 3927 Lex(); 3928 3929 StringRef Str2 = parseStringToEndOfStatement(); 3930 3931 if (getLexer().isNot(AsmToken::EndOfStatement)) 3932 return TokError("unexpected token in '.ifc' directive"); 3933 3934 Lex(); 3935 3936 TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim()); 3937 TheCondState.Ignore = !TheCondState.CondMet; 3938 } 3939 3940 return false; 3941 } 3942 3943 /// parseDirectiveIfeqs 3944 /// ::= .ifeqs string1, string2 3945 bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { 3946 if (Lexer.isNot(AsmToken::String)) { 3947 TokError("expected string parameter for '.ifeqs' directive"); 3948 eatToEndOfStatement(); 3949 return true; 3950 } 3951 3952 StringRef String1 = getTok().getStringContents(); 3953 Lex(); 3954 3955 if (Lexer.isNot(AsmToken::Comma)) { 3956 TokError("expected comma after first string for '.ifeqs' directive"); 3957 eatToEndOfStatement(); 3958 return true; 3959 } 3960 3961 Lex(); 3962 3963 if (Lexer.isNot(AsmToken::String)) { 3964 TokError("expected string parameter for '.ifeqs' directive"); 3965 eatToEndOfStatement(); 3966 return true; 3967 } 3968 3969 StringRef String2 = getTok().getStringContents(); 3970 Lex(); 3971 3972 TheCondStack.push_back(TheCondState); 3973 TheCondState.TheCond = AsmCond::IfCond; 3974 TheCondState.CondMet = String1 == String2; 3975 TheCondState.Ignore = !TheCondState.CondMet; 3976 3977 return false; 3978 } 3979 3980 /// parseDirectiveIfdef 3981 /// ::= .ifdef symbol 3982 bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 3983 StringRef Name; 3984 TheCondStack.push_back(TheCondState); 3985 TheCondState.TheCond = AsmCond::IfCond; 3986 3987 if (TheCondState.Ignore) { 3988 eatToEndOfStatement(); 3989 } else { 3990 if (parseIdentifier(Name)) 3991 return TokError("expected identifier after '.ifdef'"); 3992 3993 Lex(); 3994 3995 MCSymbol *Sym = getContext().LookupSymbol(Name); 3996 3997 if (expect_defined) 3998 TheCondState.CondMet = (Sym && !Sym->isUndefined()); 3999 else 4000 TheCondState.CondMet = (!Sym || Sym->isUndefined()); 4001 TheCondState.Ignore = !TheCondState.CondMet; 4002 } 4003 4004 return false; 4005 } 4006 4007 /// parseDirectiveElseIf 4008 /// ::= .elseif expression 4009 bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) { 4010 if (TheCondState.TheCond != AsmCond::IfCond && 4011 TheCondState.TheCond != AsmCond::ElseIfCond) 4012 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 4013 " an .elseif"); 4014 TheCondState.TheCond = AsmCond::ElseIfCond; 4015 4016 bool LastIgnoreState = false; 4017 if (!TheCondStack.empty()) 4018 LastIgnoreState = TheCondStack.back().Ignore; 4019 if (LastIgnoreState || TheCondState.CondMet) { 4020 TheCondState.Ignore = true; 4021 eatToEndOfStatement(); 4022 } else { 4023 int64_t ExprValue; 4024 if (parseAbsoluteExpression(ExprValue)) 4025 return true; 4026 4027 if (getLexer().isNot(AsmToken::EndOfStatement)) 4028 return TokError("unexpected token in '.elseif' directive"); 4029 4030 Lex(); 4031 TheCondState.CondMet = ExprValue; 4032 TheCondState.Ignore = !TheCondState.CondMet; 4033 } 4034 4035 return false; 4036 } 4037 4038 /// parseDirectiveElse 4039 /// ::= .else 4040 bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) { 4041 if (getLexer().isNot(AsmToken::EndOfStatement)) 4042 return TokError("unexpected token in '.else' directive"); 4043 4044 Lex(); 4045 4046 if (TheCondState.TheCond != AsmCond::IfCond && 4047 TheCondState.TheCond != AsmCond::ElseIfCond) 4048 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 4049 ".elseif"); 4050 TheCondState.TheCond = AsmCond::ElseCond; 4051 bool LastIgnoreState = false; 4052 if (!TheCondStack.empty()) 4053 LastIgnoreState = TheCondStack.back().Ignore; 4054 if (LastIgnoreState || TheCondState.CondMet) 4055 TheCondState.Ignore = true; 4056 else 4057 TheCondState.Ignore = false; 4058 4059 return false; 4060 } 4061 4062 /// parseDirectiveEnd 4063 /// ::= .end 4064 bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { 4065 if (getLexer().isNot(AsmToken::EndOfStatement)) 4066 return TokError("unexpected token in '.end' directive"); 4067 4068 Lex(); 4069 4070 while (Lexer.isNot(AsmToken::Eof)) 4071 Lex(); 4072 4073 return false; 4074 } 4075 4076 /// parseDirectiveError 4077 /// ::= .err 4078 /// ::= .error [string] 4079 bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) { 4080 if (!TheCondStack.empty()) { 4081 if (TheCondStack.back().Ignore) { 4082 eatToEndOfStatement(); 4083 return false; 4084 } 4085 } 4086 4087 if (!WithMessage) 4088 return Error(L, ".err encountered"); 4089 4090 StringRef Message = ".error directive invoked in source file"; 4091 if (Lexer.isNot(AsmToken::EndOfStatement)) { 4092 if (Lexer.isNot(AsmToken::String)) { 4093 TokError(".error argument must be a string"); 4094 eatToEndOfStatement(); 4095 return true; 4096 } 4097 4098 Message = getTok().getStringContents(); 4099 Lex(); 4100 } 4101 4102 Error(L, Message); 4103 return true; 4104 } 4105 4106 /// parseDirectiveWarning 4107 /// ::= .warning [string] 4108 bool AsmParser::parseDirectiveWarning(SMLoc L) { 4109 if (!TheCondStack.empty()) { 4110 if (TheCondStack.back().Ignore) { 4111 eatToEndOfStatement(); 4112 return false; 4113 } 4114 } 4115 4116 StringRef Message = ".warning directive invoked in source file"; 4117 if (Lexer.isNot(AsmToken::EndOfStatement)) { 4118 if (Lexer.isNot(AsmToken::String)) { 4119 TokError(".warning argument must be a string"); 4120 eatToEndOfStatement(); 4121 return true; 4122 } 4123 4124 Message = getTok().getStringContents(); 4125 Lex(); 4126 } 4127 4128 Warning(L, Message); 4129 return false; 4130 } 4131 4132 /// parseDirectiveEndIf 4133 /// ::= .endif 4134 bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { 4135 if (getLexer().isNot(AsmToken::EndOfStatement)) 4136 return TokError("unexpected token in '.endif' directive"); 4137 4138 Lex(); 4139 4140 if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty()) 4141 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 4142 ".else"); 4143 if (!TheCondStack.empty()) { 4144 TheCondState = TheCondStack.back(); 4145 TheCondStack.pop_back(); 4146 } 4147 4148 return false; 4149 } 4150 4151 void AsmParser::initializeDirectiveKindMap() { 4152 DirectiveKindMap[".set"] = DK_SET; 4153 DirectiveKindMap[".equ"] = DK_EQU; 4154 DirectiveKindMap[".equiv"] = DK_EQUIV; 4155 DirectiveKindMap[".ascii"] = DK_ASCII; 4156 DirectiveKindMap[".asciz"] = DK_ASCIZ; 4157 DirectiveKindMap[".string"] = DK_STRING; 4158 DirectiveKindMap[".byte"] = DK_BYTE; 4159 DirectiveKindMap[".short"] = DK_SHORT; 4160 DirectiveKindMap[".value"] = DK_VALUE; 4161 DirectiveKindMap[".2byte"] = DK_2BYTE; 4162 DirectiveKindMap[".long"] = DK_LONG; 4163 DirectiveKindMap[".int"] = DK_INT; 4164 DirectiveKindMap[".4byte"] = DK_4BYTE; 4165 DirectiveKindMap[".quad"] = DK_QUAD; 4166 DirectiveKindMap[".8byte"] = DK_8BYTE; 4167 DirectiveKindMap[".octa"] = DK_OCTA; 4168 DirectiveKindMap[".single"] = DK_SINGLE; 4169 DirectiveKindMap[".float"] = DK_FLOAT; 4170 DirectiveKindMap[".double"] = DK_DOUBLE; 4171 DirectiveKindMap[".align"] = DK_ALIGN; 4172 DirectiveKindMap[".align32"] = DK_ALIGN32; 4173 DirectiveKindMap[".balign"] = DK_BALIGN; 4174 DirectiveKindMap[".balignw"] = DK_BALIGNW; 4175 DirectiveKindMap[".balignl"] = DK_BALIGNL; 4176 DirectiveKindMap[".p2align"] = DK_P2ALIGN; 4177 DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW; 4178 DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL; 4179 DirectiveKindMap[".org"] = DK_ORG; 4180 DirectiveKindMap[".fill"] = DK_FILL; 4181 DirectiveKindMap[".zero"] = DK_ZERO; 4182 DirectiveKindMap[".extern"] = DK_EXTERN; 4183 DirectiveKindMap[".globl"] = DK_GLOBL; 4184 DirectiveKindMap[".global"] = DK_GLOBAL; 4185 DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE; 4186 DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP; 4187 DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER; 4188 DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN; 4189 DirectiveKindMap[".reference"] = DK_REFERENCE; 4190 DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION; 4191 DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE; 4192 DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN; 4193 DirectiveKindMap[".comm"] = DK_COMM; 4194 DirectiveKindMap[".common"] = DK_COMMON; 4195 DirectiveKindMap[".lcomm"] = DK_LCOMM; 4196 DirectiveKindMap[".abort"] = DK_ABORT; 4197 DirectiveKindMap[".include"] = DK_INCLUDE; 4198 DirectiveKindMap[".incbin"] = DK_INCBIN; 4199 DirectiveKindMap[".code16"] = DK_CODE16; 4200 DirectiveKindMap[".code16gcc"] = DK_CODE16GCC; 4201 DirectiveKindMap[".rept"] = DK_REPT; 4202 DirectiveKindMap[".rep"] = DK_REPT; 4203 DirectiveKindMap[".irp"] = DK_IRP; 4204 DirectiveKindMap[".irpc"] = DK_IRPC; 4205 DirectiveKindMap[".endr"] = DK_ENDR; 4206 DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE; 4207 DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; 4208 DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; 4209 DirectiveKindMap[".if"] = DK_IF; 4210 DirectiveKindMap[".ifeq"] = DK_IFEQ; 4211 DirectiveKindMap[".ifge"] = DK_IFGE; 4212 DirectiveKindMap[".ifgt"] = DK_IFGT; 4213 DirectiveKindMap[".ifle"] = DK_IFLE; 4214 DirectiveKindMap[".iflt"] = DK_IFLT; 4215 DirectiveKindMap[".ifne"] = DK_IFNE; 4216 DirectiveKindMap[".ifb"] = DK_IFB; 4217 DirectiveKindMap[".ifnb"] = DK_IFNB; 4218 DirectiveKindMap[".ifc"] = DK_IFC; 4219 DirectiveKindMap[".ifeqs"] = DK_IFEQS; 4220 DirectiveKindMap[".ifnc"] = DK_IFNC; 4221 DirectiveKindMap[".ifdef"] = DK_IFDEF; 4222 DirectiveKindMap[".ifndef"] = DK_IFNDEF; 4223 DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF; 4224 DirectiveKindMap[".elseif"] = DK_ELSEIF; 4225 DirectiveKindMap[".else"] = DK_ELSE; 4226 DirectiveKindMap[".end"] = DK_END; 4227 DirectiveKindMap[".endif"] = DK_ENDIF; 4228 DirectiveKindMap[".skip"] = DK_SKIP; 4229 DirectiveKindMap[".space"] = DK_SPACE; 4230 DirectiveKindMap[".file"] = DK_FILE; 4231 DirectiveKindMap[".line"] = DK_LINE; 4232 DirectiveKindMap[".loc"] = DK_LOC; 4233 DirectiveKindMap[".stabs"] = DK_STABS; 4234 DirectiveKindMap[".sleb128"] = DK_SLEB128; 4235 DirectiveKindMap[".uleb128"] = DK_ULEB128; 4236 DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS; 4237 DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC; 4238 DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC; 4239 DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA; 4240 DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET; 4241 DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET; 4242 DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER; 4243 DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET; 4244 DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET; 4245 DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY; 4246 DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA; 4247 DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE; 4248 DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE; 4249 DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE; 4250 DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE; 4251 DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE; 4252 DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; 4253 DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; 4254 DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; 4255 DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; 4256 DirectiveKindMap[".macros_on"] = DK_MACROS_ON; 4257 DirectiveKindMap[".macros_off"] = DK_MACROS_OFF; 4258 DirectiveKindMap[".macro"] = DK_MACRO; 4259 DirectiveKindMap[".exitm"] = DK_EXITM; 4260 DirectiveKindMap[".endm"] = DK_ENDM; 4261 DirectiveKindMap[".endmacro"] = DK_ENDMACRO; 4262 DirectiveKindMap[".purgem"] = DK_PURGEM; 4263 DirectiveKindMap[".err"] = DK_ERR; 4264 DirectiveKindMap[".error"] = DK_ERROR; 4265 DirectiveKindMap[".warning"] = DK_WARNING; 4266 } 4267 4268 MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { 4269 AsmToken EndToken, StartToken = getTok(); 4270 4271 unsigned NestLevel = 0; 4272 for (;;) { 4273 // Check whether we have reached the end of the file. 4274 if (getLexer().is(AsmToken::Eof)) { 4275 Error(DirectiveLoc, "no matching '.endr' in definition"); 4276 return nullptr; 4277 } 4278 4279 if (Lexer.is(AsmToken::Identifier) && 4280 (getTok().getIdentifier() == ".rept")) { 4281 ++NestLevel; 4282 } 4283 4284 // Otherwise, check whether we have reached the .endr. 4285 if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") { 4286 if (NestLevel == 0) { 4287 EndToken = getTok(); 4288 Lex(); 4289 if (Lexer.isNot(AsmToken::EndOfStatement)) { 4290 TokError("unexpected token in '.endr' directive"); 4291 return nullptr; 4292 } 4293 break; 4294 } 4295 --NestLevel; 4296 } 4297 4298 // Otherwise, scan till the end of the statement. 4299 eatToEndOfStatement(); 4300 } 4301 4302 const char *BodyStart = StartToken.getLoc().getPointer(); 4303 const char *BodyEnd = EndToken.getLoc().getPointer(); 4304 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 4305 4306 // We Are Anonymous. 4307 MacroLikeBodies.push_back(MCAsmMacro(StringRef(), Body, None)); 4308 return &MacroLikeBodies.back(); 4309 } 4310 4311 void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, 4312 raw_svector_ostream &OS) { 4313 OS << ".endr\n"; 4314 4315 MemoryBuffer *Instantiation = 4316 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 4317 4318 // Create the macro instantiation object and add to the current macro 4319 // instantiation stack. 4320 MacroInstantiation *MI = 4321 new MacroInstantiation(DirectiveLoc, CurBuffer, getTok().getLoc(), 4322 Instantiation, TheCondStack.size()); 4323 ActiveMacros.push_back(MI); 4324 4325 // Jump to the macro instantiation and prime the lexer. 4326 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 4327 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); 4328 Lex(); 4329 } 4330 4331 /// parseDirectiveRept 4332 /// ::= .rep | .rept count 4333 bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) { 4334 const MCExpr *CountExpr; 4335 SMLoc CountLoc = getTok().getLoc(); 4336 if (parseExpression(CountExpr)) 4337 return true; 4338 4339 int64_t Count; 4340 if (!CountExpr->EvaluateAsAbsolute(Count)) { 4341 eatToEndOfStatement(); 4342 return Error(CountLoc, "unexpected token in '" + Dir + "' directive"); 4343 } 4344 4345 if (Count < 0) 4346 return Error(CountLoc, "Count is negative"); 4347 4348 if (Lexer.isNot(AsmToken::EndOfStatement)) 4349 return TokError("unexpected token in '" + Dir + "' directive"); 4350 4351 // Eat the end of statement. 4352 Lex(); 4353 4354 // Lex the rept definition. 4355 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 4356 if (!M) 4357 return true; 4358 4359 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4360 // to hold the macro body with substitutions. 4361 SmallString<256> Buf; 4362 raw_svector_ostream OS(Buf); 4363 while (Count--) { 4364 if (expandMacro(OS, M->Body, None, None, getTok().getLoc())) 4365 return true; 4366 } 4367 instantiateMacroLikeBody(M, DirectiveLoc, OS); 4368 4369 return false; 4370 } 4371 4372 /// parseDirectiveIrp 4373 /// ::= .irp symbol,values 4374 bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { 4375 MCAsmMacroParameter Parameter; 4376 4377 if (parseIdentifier(Parameter.Name)) 4378 return TokError("expected identifier in '.irp' directive"); 4379 4380 if (Lexer.isNot(AsmToken::Comma)) 4381 return TokError("expected comma in '.irp' directive"); 4382 4383 Lex(); 4384 4385 MCAsmMacroArguments A; 4386 if (parseMacroArguments(nullptr, A)) 4387 return true; 4388 4389 // Eat the end of statement. 4390 Lex(); 4391 4392 // Lex the irp definition. 4393 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 4394 if (!M) 4395 return true; 4396 4397 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4398 // to hold the macro body with substitutions. 4399 SmallString<256> Buf; 4400 raw_svector_ostream OS(Buf); 4401 4402 for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { 4403 if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc())) 4404 return true; 4405 } 4406 4407 instantiateMacroLikeBody(M, DirectiveLoc, OS); 4408 4409 return false; 4410 } 4411 4412 /// parseDirectiveIrpc 4413 /// ::= .irpc symbol,values 4414 bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { 4415 MCAsmMacroParameter Parameter; 4416 4417 if (parseIdentifier(Parameter.Name)) 4418 return TokError("expected identifier in '.irpc' directive"); 4419 4420 if (Lexer.isNot(AsmToken::Comma)) 4421 return TokError("expected comma in '.irpc' directive"); 4422 4423 Lex(); 4424 4425 MCAsmMacroArguments A; 4426 if (parseMacroArguments(nullptr, A)) 4427 return true; 4428 4429 if (A.size() != 1 || A.front().size() != 1) 4430 return TokError("unexpected token in '.irpc' directive"); 4431 4432 // Eat the end of statement. 4433 Lex(); 4434 4435 // Lex the irpc definition. 4436 MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); 4437 if (!M) 4438 return true; 4439 4440 // Macro instantiation is lexical, unfortunately. We construct a new buffer 4441 // to hold the macro body with substitutions. 4442 SmallString<256> Buf; 4443 raw_svector_ostream OS(Buf); 4444 4445 StringRef Values = A.front().front().getString(); 4446 for (std::size_t I = 0, End = Values.size(); I != End; ++I) { 4447 MCAsmMacroArgument Arg; 4448 Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1))); 4449 4450 if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc())) 4451 return true; 4452 } 4453 4454 instantiateMacroLikeBody(M, DirectiveLoc, OS); 4455 4456 return false; 4457 } 4458 4459 bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) { 4460 if (ActiveMacros.empty()) 4461 return TokError("unmatched '.endr' directive"); 4462 4463 // The only .repl that should get here are the ones created by 4464 // instantiateMacroLikeBody. 4465 assert(getLexer().is(AsmToken::EndOfStatement)); 4466 4467 handleMacroExit(); 4468 return false; 4469 } 4470 4471 bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, 4472 size_t Len) { 4473 const MCExpr *Value; 4474 SMLoc ExprLoc = getLexer().getLoc(); 4475 if (parseExpression(Value)) 4476 return true; 4477 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4478 if (!MCE) 4479 return Error(ExprLoc, "unexpected expression in _emit"); 4480 uint64_t IntValue = MCE->getValue(); 4481 if (!isUIntN(8, IntValue) && !isIntN(8, IntValue)) 4482 return Error(ExprLoc, "literal value out of range for directive"); 4483 4484 Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len)); 4485 return false; 4486 } 4487 4488 bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { 4489 const MCExpr *Value; 4490 SMLoc ExprLoc = getLexer().getLoc(); 4491 if (parseExpression(Value)) 4492 return true; 4493 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); 4494 if (!MCE) 4495 return Error(ExprLoc, "unexpected expression in align"); 4496 uint64_t IntValue = MCE->getValue(); 4497 if (!isPowerOf2_64(IntValue)) 4498 return Error(ExprLoc, "literal value not a power of two greater then zero"); 4499 4500 Info.AsmRewrites->push_back( 4501 AsmRewrite(AOK_Align, IDLoc, 5, Log2_64(IntValue))); 4502 return false; 4503 } 4504 4505 // We are comparing pointers, but the pointers are relative to a single string. 4506 // Thus, this should always be deterministic. 4507 static int rewritesSort(const AsmRewrite *AsmRewriteA, 4508 const AsmRewrite *AsmRewriteB) { 4509 if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) 4510 return -1; 4511 if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) 4512 return 1; 4513 4514 // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output 4515 // rewrite to the same location. Make sure the SizeDirective rewrite is 4516 // performed first, then the Imm/ImmPrefix and finally the Input/Output. This 4517 // ensures the sort algorithm is stable. 4518 if (AsmRewritePrecedence[AsmRewriteA->Kind] > 4519 AsmRewritePrecedence[AsmRewriteB->Kind]) 4520 return -1; 4521 4522 if (AsmRewritePrecedence[AsmRewriteA->Kind] < 4523 AsmRewritePrecedence[AsmRewriteB->Kind]) 4524 return 1; 4525 llvm_unreachable("Unstable rewrite sort."); 4526 } 4527 4528 bool AsmParser::parseMSInlineAsm( 4529 void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, 4530 unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool> > &OpDecls, 4531 SmallVectorImpl<std::string> &Constraints, 4532 SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII, 4533 const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) { 4534 SmallVector<void *, 4> InputDecls; 4535 SmallVector<void *, 4> OutputDecls; 4536 SmallVector<bool, 4> InputDeclsAddressOf; 4537 SmallVector<bool, 4> OutputDeclsAddressOf; 4538 SmallVector<std::string, 4> InputConstraints; 4539 SmallVector<std::string, 4> OutputConstraints; 4540 SmallVector<unsigned, 4> ClobberRegs; 4541 4542 SmallVector<AsmRewrite, 4> AsmStrRewrites; 4543 4544 // Prime the lexer. 4545 Lex(); 4546 4547 // While we have input, parse each statement. 4548 unsigned InputIdx = 0; 4549 unsigned OutputIdx = 0; 4550 while (getLexer().isNot(AsmToken::Eof)) { 4551 ParseStatementInfo Info(&AsmStrRewrites); 4552 if (parseStatement(Info)) 4553 return true; 4554 4555 if (Info.ParseError) 4556 return true; 4557 4558 if (Info.Opcode == ~0U) 4559 continue; 4560 4561 const MCInstrDesc &Desc = MII->get(Info.Opcode); 4562 4563 // Build the list of clobbers, outputs and inputs. 4564 for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { 4565 MCParsedAsmOperand &Operand = *Info.ParsedOperands[i]; 4566 4567 // Immediate. 4568 if (Operand.isImm()) 4569 continue; 4570 4571 // Register operand. 4572 if (Operand.isReg() && !Operand.needAddressOf() && 4573 !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) { 4574 unsigned NumDefs = Desc.getNumDefs(); 4575 // Clobber. 4576 if (NumDefs && Operand.getMCOperandNum() < NumDefs) 4577 ClobberRegs.push_back(Operand.getReg()); 4578 continue; 4579 } 4580 4581 // Expr/Input or Output. 4582 StringRef SymName = Operand.getSymName(); 4583 if (SymName.empty()) 4584 continue; 4585 4586 void *OpDecl = Operand.getOpDecl(); 4587 if (!OpDecl) 4588 continue; 4589 4590 bool isOutput = (i == 1) && Desc.mayStore(); 4591 SMLoc Start = SMLoc::getFromPointer(SymName.data()); 4592 if (isOutput) { 4593 ++InputIdx; 4594 OutputDecls.push_back(OpDecl); 4595 OutputDeclsAddressOf.push_back(Operand.needAddressOf()); 4596 OutputConstraints.push_back('=' + Operand.getConstraint().str()); 4597 AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size())); 4598 } else { 4599 InputDecls.push_back(OpDecl); 4600 InputDeclsAddressOf.push_back(Operand.needAddressOf()); 4601 InputConstraints.push_back(Operand.getConstraint().str()); 4602 AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size())); 4603 } 4604 } 4605 4606 // Consider implicit defs to be clobbers. Think of cpuid and push. 4607 ArrayRef<uint16_t> ImpDefs(Desc.getImplicitDefs(), 4608 Desc.getNumImplicitDefs()); 4609 ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end()); 4610 } 4611 4612 // Set the number of Outputs and Inputs. 4613 NumOutputs = OutputDecls.size(); 4614 NumInputs = InputDecls.size(); 4615 4616 // Set the unique clobbers. 4617 array_pod_sort(ClobberRegs.begin(), ClobberRegs.end()); 4618 ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()), 4619 ClobberRegs.end()); 4620 Clobbers.assign(ClobberRegs.size(), std::string()); 4621 for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) { 4622 raw_string_ostream OS(Clobbers[I]); 4623 IP->printRegName(OS, ClobberRegs[I]); 4624 } 4625 4626 // Merge the various outputs and inputs. Output are expected first. 4627 if (NumOutputs || NumInputs) { 4628 unsigned NumExprs = NumOutputs + NumInputs; 4629 OpDecls.resize(NumExprs); 4630 Constraints.resize(NumExprs); 4631 for (unsigned i = 0; i < NumOutputs; ++i) { 4632 OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]); 4633 Constraints[i] = OutputConstraints[i]; 4634 } 4635 for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { 4636 OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]); 4637 Constraints[j] = InputConstraints[i]; 4638 } 4639 } 4640 4641 // Build the IR assembly string. 4642 std::string AsmStringIR; 4643 raw_string_ostream OS(AsmStringIR); 4644 StringRef ASMString = 4645 SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer(); 4646 const char *AsmStart = ASMString.begin(); 4647 const char *AsmEnd = ASMString.end(); 4648 array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); 4649 for (const AsmRewrite &AR : AsmStrRewrites) { 4650 AsmRewriteKind Kind = AR.Kind; 4651 if (Kind == AOK_Delete) 4652 continue; 4653 4654 const char *Loc = AR.Loc.getPointer(); 4655 assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); 4656 4657 // Emit everything up to the immediate/expression. 4658 if (unsigned Len = Loc - AsmStart) 4659 OS << StringRef(AsmStart, Len); 4660 4661 // Skip the original expression. 4662 if (Kind == AOK_Skip) { 4663 AsmStart = Loc + AR.Len; 4664 continue; 4665 } 4666 4667 unsigned AdditionalSkip = 0; 4668 // Rewrite expressions in $N notation. 4669 switch (Kind) { 4670 default: 4671 break; 4672 case AOK_Imm: 4673 OS << "$$" << AR.Val; 4674 break; 4675 case AOK_ImmPrefix: 4676 OS << "$$"; 4677 break; 4678 case AOK_Input: 4679 OS << '$' << InputIdx++; 4680 break; 4681 case AOK_Output: 4682 OS << '$' << OutputIdx++; 4683 break; 4684 case AOK_SizeDirective: 4685 switch (AR.Val) { 4686 default: break; 4687 case 8: OS << "byte ptr "; break; 4688 case 16: OS << "word ptr "; break; 4689 case 32: OS << "dword ptr "; break; 4690 case 64: OS << "qword ptr "; break; 4691 case 80: OS << "xword ptr "; break; 4692 case 128: OS << "xmmword ptr "; break; 4693 case 256: OS << "ymmword ptr "; break; 4694 } 4695 break; 4696 case AOK_Emit: 4697 OS << ".byte"; 4698 break; 4699 case AOK_Align: { 4700 unsigned Val = AR.Val; 4701 OS << ".align " << Val; 4702 4703 // Skip the original immediate. 4704 assert(Val < 10 && "Expected alignment less then 2^10."); 4705 AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4; 4706 break; 4707 } 4708 case AOK_DotOperator: 4709 // Insert the dot if the user omitted it. 4710 OS.flush(); 4711 if (AsmStringIR.back() != '.') 4712 OS << '.'; 4713 OS << AR.Val; 4714 break; 4715 } 4716 4717 // Skip the original expression. 4718 AsmStart = Loc + AR.Len + AdditionalSkip; 4719 } 4720 4721 // Emit the remainder of the asm string. 4722 if (AsmStart != AsmEnd) 4723 OS << StringRef(AsmStart, AsmEnd - AsmStart); 4724 4725 AsmString = OS.str(); 4726 return false; 4727 } 4728 4729 /// \brief Create an MCAsmParser instance. 4730 MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C, 4731 MCStreamer &Out, const MCAsmInfo &MAI) { 4732 return new AsmParser(SM, C, Out, MAI); 4733 } 4734