AsmParser.cpp revision 3f90a4c42d1683600e91c2aea325bacf59c37f5e
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/SmallString.h" 16#include "llvm/ADT/StringMap.h" 17#include "llvm/ADT/Twine.h" 18#include "llvm/MC/MCAsmInfo.h" 19#include "llvm/MC/MCContext.h" 20#include "llvm/MC/MCDwarf.h" 21#include "llvm/MC/MCExpr.h" 22#include "llvm/MC/MCParser/AsmCond.h" 23#include "llvm/MC/MCParser/AsmLexer.h" 24#include "llvm/MC/MCParser/MCAsmParser.h" 25#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 26#include "llvm/MC/MCRegisterInfo.h" 27#include "llvm/MC/MCSectionMachO.h" 28#include "llvm/MC/MCStreamer.h" 29#include "llvm/MC/MCSymbol.h" 30#include "llvm/MC/MCTargetAsmParser.h" 31#include "llvm/Support/CommandLine.h" 32#include "llvm/Support/ErrorHandling.h" 33#include "llvm/Support/MathExtras.h" 34#include "llvm/Support/MemoryBuffer.h" 35#include "llvm/Support/SourceMgr.h" 36#include "llvm/Support/raw_ostream.h" 37#include <cctype> 38#include <vector> 39using namespace llvm; 40 41static cl::opt<bool> 42FatalAssemblerWarnings("fatal-assembler-warnings", 43 cl::desc("Consider warnings as error")); 44 45namespace { 46 47/// \brief Helper class for tracking macro definitions. 48typedef std::vector<AsmToken> MacroArgument; 49typedef std::vector<MacroArgument> MacroArguments; 50typedef StringRef MacroParameter; 51typedef std::vector<MacroParameter> MacroParameters; 52 53struct Macro { 54 StringRef Name; 55 StringRef Body; 56 MacroParameters Parameters; 57 58public: 59 Macro(StringRef N, StringRef B, const MacroParameters &P) : 60 Name(N), Body(B), Parameters(P) {} 61}; 62 63/// \brief Helper class for storing information about an active macro 64/// instantiation. 65struct MacroInstantiation { 66 /// The macro being instantiated. 67 const Macro *TheMacro; 68 69 /// The macro instantiation with substitutions. 70 MemoryBuffer *Instantiation; 71 72 /// The location of the instantiation. 73 SMLoc InstantiationLoc; 74 75 /// The location where parsing should resume upon instantiation completion. 76 SMLoc ExitLoc; 77 78public: 79 MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, 80 MemoryBuffer *I); 81}; 82 83/// \brief The concrete assembly parser instance. 84class AsmParser : public MCAsmParser { 85 friend class GenericAsmParser; 86 87 AsmParser(const AsmParser &); // DO NOT IMPLEMENT 88 void operator=(const AsmParser &); // DO NOT IMPLEMENT 89private: 90 AsmLexer Lexer; 91 MCContext &Ctx; 92 MCStreamer &Out; 93 const MCAsmInfo &MAI; 94 SourceMgr &SrcMgr; 95 SourceMgr::DiagHandlerTy SavedDiagHandler; 96 void *SavedDiagContext; 97 MCAsmParserExtension *GenericParser; 98 MCAsmParserExtension *PlatformParser; 99 100 /// This is the current buffer index we're lexing from as managed by the 101 /// SourceMgr object. 102 int CurBuffer; 103 104 AsmCond TheCondState; 105 std::vector<AsmCond> TheCondStack; 106 107 /// DirectiveMap - This is a table handlers for directives. Each handler is 108 /// invoked after the directive identifier is read and is responsible for 109 /// parsing and validating the rest of the directive. The handler is passed 110 /// in the directive name and the location of the directive keyword. 111 StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap; 112 113 /// MacroMap - Map of currently defined macros. 114 StringMap<Macro*> MacroMap; 115 116 /// ActiveMacros - Stack of active macro instantiations. 117 std::vector<MacroInstantiation*> ActiveMacros; 118 119 /// Boolean tracking whether macro substitution is enabled. 120 unsigned MacrosEnabled : 1; 121 122 /// Flag tracking whether any errors have been encountered. 123 unsigned HadError : 1; 124 125 /// The values from the last parsed cpp hash file line comment if any. 126 StringRef CppHashFilename; 127 int64_t CppHashLineNumber; 128 SMLoc CppHashLoc; 129 130 /// AssemblerDialect. ~OU means unset value and use value provided by MAI. 131 unsigned AssemblerDialect; 132 133public: 134 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, 135 const MCAsmInfo &MAI); 136 virtual ~AsmParser(); 137 138 virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false); 139 140 virtual void AddDirectiveHandler(MCAsmParserExtension *Object, 141 StringRef Directive, 142 DirectiveHandler Handler) { 143 DirectiveMap[Directive] = std::make_pair(Object, Handler); 144 } 145 146public: 147 /// @name MCAsmParser Interface 148 /// { 149 150 virtual SourceMgr &getSourceManager() { return SrcMgr; } 151 virtual MCAsmLexer &getLexer() { return Lexer; } 152 virtual MCContext &getContext() { return Ctx; } 153 virtual MCStreamer &getStreamer() { return Out; } 154 virtual unsigned getAssemblerDialect() { 155 if (AssemblerDialect == ~0U) 156 return MAI.getAssemblerDialect(); 157 else 158 return AssemblerDialect; 159 } 160 virtual void setAssemblerDialect(unsigned i) { 161 AssemblerDialect = i; 162 } 163 164 virtual bool Warning(SMLoc L, const Twine &Msg, 165 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); 166 virtual bool Error(SMLoc L, const Twine &Msg, 167 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); 168 169 virtual const AsmToken &Lex(); 170 171 bool ParseExpression(const MCExpr *&Res); 172 virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc); 173 virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc); 174 virtual bool ParseAbsoluteExpression(int64_t &Res); 175 176 /// } 177 178private: 179 void CheckForValidSection(); 180 181 bool ParseStatement(); 182 void EatToEndOfLine(); 183 bool ParseCppHashLineFilenameComment(const SMLoc &L); 184 185 bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M); 186 bool expandMacro(raw_svector_ostream &OS, StringRef Body, 187 const MacroParameters &Parameters, 188 const MacroArguments &A, 189 const SMLoc &L); 190 void HandleMacroExit(); 191 192 void PrintMacroInstantiations(); 193 void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, 194 ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const { 195 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); 196 } 197 static void DiagHandler(const SMDiagnostic &Diag, void *Context); 198 199 /// EnterIncludeFile - Enter the specified file. This returns true on failure. 200 bool EnterIncludeFile(const std::string &Filename); 201 /// ProcessIncbinFile - Process the specified file for the .incbin directive. 202 /// This returns true on failure. 203 bool ProcessIncbinFile(const std::string &Filename); 204 205 /// \brief Reset the current lexer position to that given by \arg Loc. The 206 /// current token is not set; clients should ensure Lex() is called 207 /// subsequently. 208 void JumpToLoc(SMLoc Loc); 209 210 virtual void EatToEndOfStatement(); 211 212 bool ParseMacroArgument(MacroArgument &MA); 213 bool ParseMacroArguments(const Macro *M, MacroArguments &A); 214 215 /// \brief Parse up to the end of statement and a return the contents from the 216 /// current token until the end of the statement; the current token on exit 217 /// will be either the EndOfStatement or EOF. 218 virtual StringRef ParseStringToEndOfStatement(); 219 220 /// \brief Parse until the end of a statement or a comma is encountered, 221 /// return the contents from the current token up to the end or comma. 222 StringRef ParseStringToComma(); 223 224 bool ParseAssignment(StringRef Name, bool allow_redef, 225 bool NoDeadStrip = false); 226 227 bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); 228 bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); 229 bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); 230 bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); 231 232 /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) 233 /// and set \arg Res to the identifier contents. 234 virtual bool ParseIdentifier(StringRef &Res); 235 236 // Directive Parsing. 237 238 // ".ascii", ".asciiz", ".string" 239 bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); 240 bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ... 241 bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ... 242 bool ParseDirectiveFill(); // ".fill" 243 bool ParseDirectiveSpace(); // ".space" 244 bool ParseDirectiveZero(); // ".zero" 245 bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv" 246 bool ParseDirectiveOrg(); // ".org" 247 // ".align{,32}", ".p2align{,w,l}" 248 bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize); 249 250 /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which 251 /// accepts a single symbol (which should be a label or an external). 252 bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); 253 254 bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" 255 256 bool ParseDirectiveAbort(); // ".abort" 257 bool ParseDirectiveInclude(); // ".include" 258 bool ParseDirectiveIncbin(); // ".incbin" 259 260 bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" 261 // ".ifb" or ".ifnb", depending on ExpectBlank. 262 bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); 263 // ".ifc" or ".ifnc", depending on ExpectEqual. 264 bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); 265 // ".ifdef" or ".ifndef", depending on expect_defined 266 bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); 267 bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" 268 bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else" 269 bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif 270 271 /// ParseEscapedString - Parse the current token as a string which may include 272 /// escaped characters and return the string contents. 273 bool ParseEscapedString(std::string &Data); 274 275 const MCExpr *ApplyModifierToExpr(const MCExpr *E, 276 MCSymbolRefExpr::VariantKind Variant); 277 278 // Macro-like directives 279 Macro *ParseMacroLikeBody(SMLoc DirectiveLoc); 280 void InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc, 281 raw_svector_ostream &OS); 282 bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept" 283 bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" 284 bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" 285 bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" 286}; 287 288/// \brief Generic implementations of directive handling, etc. which is shared 289/// (or the default, at least) for all assembler parser. 290class GenericAsmParser : public MCAsmParserExtension { 291 template<bool (GenericAsmParser::*Handler)(StringRef, SMLoc)> 292 void AddDirectiveHandler(StringRef Directive) { 293 getParser().AddDirectiveHandler(this, Directive, 294 HandleDirective<GenericAsmParser, Handler>); 295 } 296public: 297 GenericAsmParser() {} 298 299 AsmParser &getParser() { 300 return (AsmParser&) this->MCAsmParserExtension::getParser(); 301 } 302 303 virtual void Initialize(MCAsmParser &Parser) { 304 // Call the base implementation. 305 this->MCAsmParserExtension::Initialize(Parser); 306 307 // Debugging directives. 308 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveFile>(".file"); 309 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLine>(".line"); 310 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc"); 311 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs"); 312 313 // CFI directives. 314 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>( 315 ".cfi_sections"); 316 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>( 317 ".cfi_startproc"); 318 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>( 319 ".cfi_endproc"); 320 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>( 321 ".cfi_def_cfa"); 322 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>( 323 ".cfi_def_cfa_offset"); 324 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset>( 325 ".cfi_adjust_cfa_offset"); 326 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>( 327 ".cfi_def_cfa_register"); 328 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>( 329 ".cfi_offset"); 330 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIRelOffset>( 331 ".cfi_rel_offset"); 332 AddDirectiveHandler< 333 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality"); 334 AddDirectiveHandler< 335 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda"); 336 AddDirectiveHandler< 337 &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state"); 338 AddDirectiveHandler< 339 &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state"); 340 AddDirectiveHandler< 341 &GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value"); 342 AddDirectiveHandler< 343 &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore"); 344 AddDirectiveHandler< 345 &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape"); 346 AddDirectiveHandler< 347 &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame"); 348 349 // Macro directives. 350 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( 351 ".macros_on"); 352 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>( 353 ".macros_off"); 354 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro"); 355 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm"); 356 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro"); 357 AddDirectiveHandler<&GenericAsmParser::ParseDirectivePurgeMacro>(".purgem"); 358 359 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128"); 360 AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128"); 361 } 362 363 bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); 364 365 bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); 366 bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); 367 bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); 368 bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc); 369 bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc); 370 bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc); 371 bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc); 372 bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc); 373 bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc); 374 bool ParseDirectiveCFIAdjustCfaOffset(StringRef, SMLoc DirectiveLoc); 375 bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc); 376 bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc); 377 bool ParseDirectiveCFIRelOffset(StringRef, SMLoc DirectiveLoc); 378 bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc); 379 bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc); 380 bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc); 381 bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc); 382 bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc); 383 bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc); 384 bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc); 385 386 bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); 387 bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); 388 bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc); 389 bool ParseDirectivePurgeMacro(StringRef, SMLoc DirectiveLoc); 390 391 bool ParseDirectiveLEB128(StringRef, SMLoc); 392}; 393 394} 395 396namespace llvm { 397 398extern MCAsmParserExtension *createDarwinAsmParser(); 399extern MCAsmParserExtension *createELFAsmParser(); 400extern MCAsmParserExtension *createCOFFAsmParser(); 401 402} 403 404enum { DEFAULT_ADDRSPACE = 0 }; 405 406AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, 407 MCStreamer &_Out, const MCAsmInfo &_MAI) 408 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), 409 GenericParser(new GenericAsmParser), PlatformParser(0), 410 CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0), 411 AssemblerDialect(~0U) { 412 // Save the old handler. 413 SavedDiagHandler = SrcMgr.getDiagHandler(); 414 SavedDiagContext = SrcMgr.getDiagContext(); 415 // Set our own handler which calls the saved handler. 416 SrcMgr.setDiagHandler(DiagHandler, this); 417 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 418 419 // Initialize the generic parser. 420 GenericParser->Initialize(*this); 421 422 // Initialize the platform / file format parser. 423 // 424 // FIXME: This is a hack, we need to (majorly) cleanup how these objects are 425 // created. 426 if (_MAI.hasMicrosoftFastStdCallMangling()) { 427 PlatformParser = createCOFFAsmParser(); 428 PlatformParser->Initialize(*this); 429 } else if (_MAI.hasSubsectionsViaSymbols()) { 430 PlatformParser = createDarwinAsmParser(); 431 PlatformParser->Initialize(*this); 432 } else { 433 PlatformParser = createELFAsmParser(); 434 PlatformParser->Initialize(*this); 435 } 436} 437 438AsmParser::~AsmParser() { 439 assert(ActiveMacros.empty() && "Unexpected active macro instantiation!"); 440 441 // Destroy any macros. 442 for (StringMap<Macro*>::iterator it = MacroMap.begin(), 443 ie = MacroMap.end(); it != ie; ++it) 444 delete it->getValue(); 445 446 delete PlatformParser; 447 delete GenericParser; 448} 449 450void AsmParser::PrintMacroInstantiations() { 451 // Print the active macro instantiation stack. 452 for (std::vector<MacroInstantiation*>::const_reverse_iterator 453 it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it) 454 PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, 455 "while in macro instantiation"); 456} 457 458bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 459 if (FatalAssemblerWarnings) 460 return Error(L, Msg, Ranges); 461 PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges); 462 PrintMacroInstantiations(); 463 return false; 464} 465 466bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { 467 HadError = true; 468 PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges); 469 PrintMacroInstantiations(); 470 return true; 471} 472 473bool AsmParser::EnterIncludeFile(const std::string &Filename) { 474 std::string IncludedFile; 475 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 476 if (NewBuf == -1) 477 return true; 478 479 CurBuffer = NewBuf; 480 481 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 482 483 return false; 484} 485 486/// Process the specified .incbin file by seaching for it in the include paths 487/// then just emitting the byte contents of the file to the streamer. This 488/// returns true on failure. 489bool AsmParser::ProcessIncbinFile(const std::string &Filename) { 490 std::string IncludedFile; 491 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); 492 if (NewBuf == -1) 493 return true; 494 495 // Pick up the bytes from the file and emit them. 496 getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer(), 497 DEFAULT_ADDRSPACE); 498 return false; 499} 500 501void AsmParser::JumpToLoc(SMLoc Loc) { 502 CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); 503 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer()); 504} 505 506const AsmToken &AsmParser::Lex() { 507 const AsmToken *tok = &Lexer.Lex(); 508 509 if (tok->is(AsmToken::Eof)) { 510 // If this is the end of an included file, pop the parent file off the 511 // include stack. 512 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 513 if (ParentIncludeLoc != SMLoc()) { 514 JumpToLoc(ParentIncludeLoc); 515 tok = &Lexer.Lex(); 516 } 517 } 518 519 if (tok->is(AsmToken::Error)) 520 Error(Lexer.getErrLoc(), Lexer.getErr()); 521 522 return *tok; 523} 524 525bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 526 // Create the initial section, if requested. 527 if (!NoInitialTextSection) 528 Out.InitSections(); 529 530 // Prime the lexer. 531 Lex(); 532 533 HadError = false; 534 AsmCond StartingCondState = TheCondState; 535 536 // If we are generating dwarf for assembly source files save the initial text 537 // section and generate a .file directive. 538 if (getContext().getGenDwarfForAssembly()) { 539 getContext().setGenDwarfSection(getStreamer().getCurrentSection()); 540 MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); 541 getStreamer().EmitLabel(SectionStartSym); 542 getContext().setGenDwarfSectionStartSym(SectionStartSym); 543 getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), 544 StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier()); 545 } 546 547 // While we have input, parse each statement. 548 while (Lexer.isNot(AsmToken::Eof)) { 549 if (!ParseStatement()) continue; 550 551 // We had an error, validate that one was emitted and recover by skipping to 552 // the next line. 553 assert(HadError && "Parse statement returned an error, but none emitted!"); 554 EatToEndOfStatement(); 555 } 556 557 if (TheCondState.TheCond != StartingCondState.TheCond || 558 TheCondState.Ignore != StartingCondState.Ignore) 559 return TokError("unmatched .ifs or .elses"); 560 561 // Check to see there are no empty DwarfFile slots. 562 const std::vector<MCDwarfFile *> &MCDwarfFiles = 563 getContext().getMCDwarfFiles(); 564 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { 565 if (!MCDwarfFiles[i]) 566 TokError("unassigned file number: " + Twine(i) + " for .file directives"); 567 } 568 569 // Check to see that all assembler local symbols were actually defined. 570 // Targets that don't do subsections via symbols may not want this, though, 571 // so conservatively exclude them. Only do this if we're finalizing, though, 572 // as otherwise we won't necessarilly have seen everything yet. 573 if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) { 574 const MCContext::SymbolTable &Symbols = getContext().getSymbols(); 575 for (MCContext::SymbolTable::const_iterator i = Symbols.begin(), 576 e = Symbols.end(); 577 i != e; ++i) { 578 MCSymbol *Sym = i->getValue(); 579 // Variable symbols may not be marked as defined, so check those 580 // explicitly. If we know it's a variable, we have a definition for 581 // the purposes of this check. 582 if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined()) 583 // FIXME: We would really like to refer back to where the symbol was 584 // first referenced for a source location. We need to add something 585 // to track that. Currently, we just point to the end of the file. 586 PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error, 587 "assembler local symbol '" + Sym->getName() + 588 "' not defined"); 589 } 590 } 591 592 593 // Finalize the output stream if there are no errors and if the client wants 594 // us to. 595 if (!HadError && !NoFinalize) 596 Out.Finish(); 597 598 return HadError; 599} 600 601void AsmParser::CheckForValidSection() { 602 if (!getStreamer().getCurrentSection()) { 603 TokError("expected section directive before assembly directive"); 604 Out.SwitchSection(Ctx.getMachOSection( 605 "__TEXT", "__text", 606 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 607 0, SectionKind::getText())); 608 } 609} 610 611/// EatToEndOfStatement - Throw away the rest of the line for testing purposes. 612void AsmParser::EatToEndOfStatement() { 613 while (Lexer.isNot(AsmToken::EndOfStatement) && 614 Lexer.isNot(AsmToken::Eof)) 615 Lex(); 616 617 // Eat EOL. 618 if (Lexer.is(AsmToken::EndOfStatement)) 619 Lex(); 620} 621 622StringRef AsmParser::ParseStringToEndOfStatement() { 623 const char *Start = getTok().getLoc().getPointer(); 624 625 while (Lexer.isNot(AsmToken::EndOfStatement) && 626 Lexer.isNot(AsmToken::Eof)) 627 Lex(); 628 629 const char *End = getTok().getLoc().getPointer(); 630 return StringRef(Start, End - Start); 631} 632 633StringRef AsmParser::ParseStringToComma() { 634 const char *Start = getTok().getLoc().getPointer(); 635 636 while (Lexer.isNot(AsmToken::EndOfStatement) && 637 Lexer.isNot(AsmToken::Comma) && 638 Lexer.isNot(AsmToken::Eof)) 639 Lex(); 640 641 const char *End = getTok().getLoc().getPointer(); 642 return StringRef(Start, End - Start); 643} 644 645/// ParseParenExpr - Parse a paren expression and return it. 646/// NOTE: This assumes the leading '(' has already been consumed. 647/// 648/// parenexpr ::= expr) 649/// 650bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 651 if (ParseExpression(Res)) return true; 652 if (Lexer.isNot(AsmToken::RParen)) 653 return TokError("expected ')' in parentheses expression"); 654 EndLoc = Lexer.getLoc(); 655 Lex(); 656 return false; 657} 658 659/// ParseBracketExpr - Parse a bracket expression and return it. 660/// NOTE: This assumes the leading '[' has already been consumed. 661/// 662/// bracketexpr ::= expr] 663/// 664bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { 665 if (ParseExpression(Res)) return true; 666 if (Lexer.isNot(AsmToken::RBrac)) 667 return TokError("expected ']' in brackets expression"); 668 EndLoc = Lexer.getLoc(); 669 Lex(); 670 return false; 671} 672 673/// ParsePrimaryExpr - Parse a primary expression and return it. 674/// primaryexpr ::= (parenexpr 675/// primaryexpr ::= symbol 676/// primaryexpr ::= number 677/// primaryexpr ::= '.' 678/// primaryexpr ::= ~,+,- primaryexpr 679bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 680 switch (Lexer.getKind()) { 681 default: 682 return TokError("unknown token in expression"); 683 // If we have an error assume that we've already handled it. 684 case AsmToken::Error: 685 return true; 686 case AsmToken::Exclaim: 687 Lex(); // Eat the operator. 688 if (ParsePrimaryExpr(Res, EndLoc)) 689 return true; 690 Res = MCUnaryExpr::CreateLNot(Res, getContext()); 691 return false; 692 case AsmToken::Dollar: 693 case AsmToken::String: 694 case AsmToken::Identifier: { 695 EndLoc = Lexer.getLoc(); 696 697 StringRef Identifier; 698 if (ParseIdentifier(Identifier)) 699 return true; 700 701 // This is a symbol reference. 702 std::pair<StringRef, StringRef> Split = Identifier.split('@'); 703 MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first); 704 705 // Lookup the symbol variant if used. 706 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 707 if (Split.first.size() != Identifier.size()) { 708 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 709 if (Variant == MCSymbolRefExpr::VK_Invalid) { 710 Variant = MCSymbolRefExpr::VK_None; 711 return TokError("invalid variant '" + Split.second + "'"); 712 } 713 } 714 715 // If this is an absolute variable reference, substitute it now to preserve 716 // semantics in the face of reassignment. 717 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) { 718 if (Variant) 719 return Error(EndLoc, "unexpected modifier on variable reference"); 720 721 Res = Sym->getVariableValue(); 722 return false; 723 } 724 725 // Otherwise create a symbol ref. 726 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 727 return false; 728 } 729 case AsmToken::Integer: { 730 SMLoc Loc = getTok().getLoc(); 731 int64_t IntVal = getTok().getIntVal(); 732 Res = MCConstantExpr::Create(IntVal, getContext()); 733 EndLoc = Lexer.getLoc(); 734 Lex(); // Eat token. 735 // Look for 'b' or 'f' following an Integer as a directional label 736 if (Lexer.getKind() == AsmToken::Identifier) { 737 StringRef IDVal = getTok().getString(); 738 if (IDVal == "f" || IDVal == "b"){ 739 MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal, 740 IDVal == "f" ? 1 : 0); 741 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 742 getContext()); 743 if (IDVal == "b" && Sym->isUndefined()) 744 return Error(Loc, "invalid reference to undefined symbol"); 745 EndLoc = Lexer.getLoc(); 746 Lex(); // Eat identifier. 747 } 748 } 749 return false; 750 } 751 case AsmToken::Real: { 752 APFloat RealVal(APFloat::IEEEdouble, getTok().getString()); 753 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue(); 754 Res = MCConstantExpr::Create(IntVal, getContext()); 755 Lex(); // Eat token. 756 return false; 757 } 758 case AsmToken::Dot: { 759 // This is a '.' reference, which references the current PC. Emit a 760 // temporary label to the streamer and refer to it. 761 MCSymbol *Sym = Ctx.CreateTempSymbol(); 762 Out.EmitLabel(Sym); 763 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 764 EndLoc = Lexer.getLoc(); 765 Lex(); // Eat identifier. 766 return false; 767 } 768 case AsmToken::LParen: 769 Lex(); // Eat the '('. 770 return ParseParenExpr(Res, EndLoc); 771 case AsmToken::LBrac: 772 if (!PlatformParser->HasBracketExpressions()) 773 return TokError("brackets expression not supported on this target"); 774 Lex(); // Eat the '['. 775 return ParseBracketExpr(Res, EndLoc); 776 case AsmToken::Minus: 777 Lex(); // Eat the operator. 778 if (ParsePrimaryExpr(Res, EndLoc)) 779 return true; 780 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 781 return false; 782 case AsmToken::Plus: 783 Lex(); // Eat the operator. 784 if (ParsePrimaryExpr(Res, EndLoc)) 785 return true; 786 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 787 return false; 788 case AsmToken::Tilde: 789 Lex(); // Eat the operator. 790 if (ParsePrimaryExpr(Res, EndLoc)) 791 return true; 792 Res = MCUnaryExpr::CreateNot(Res, getContext()); 793 return false; 794 } 795} 796 797bool AsmParser::ParseExpression(const MCExpr *&Res) { 798 SMLoc EndLoc; 799 return ParseExpression(Res, EndLoc); 800} 801 802const MCExpr * 803AsmParser::ApplyModifierToExpr(const MCExpr *E, 804 MCSymbolRefExpr::VariantKind Variant) { 805 // Recurse over the given expression, rebuilding it to apply the given variant 806 // if there is exactly one symbol. 807 switch (E->getKind()) { 808 case MCExpr::Target: 809 case MCExpr::Constant: 810 return 0; 811 812 case MCExpr::SymbolRef: { 813 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 814 815 if (SRE->getKind() != MCSymbolRefExpr::VK_None) { 816 TokError("invalid variant on expression '" + 817 getTok().getIdentifier() + "' (already modified)"); 818 return E; 819 } 820 821 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 822 } 823 824 case MCExpr::Unary: { 825 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); 826 const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant); 827 if (!Sub) 828 return 0; 829 return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); 830 } 831 832 case MCExpr::Binary: { 833 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 834 const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant); 835 const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant); 836 837 if (!LHS && !RHS) 838 return 0; 839 840 if (!LHS) LHS = BE->getLHS(); 841 if (!RHS) RHS = BE->getRHS(); 842 843 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 844 } 845 } 846 847 llvm_unreachable("Invalid expression kind!"); 848} 849 850/// ParseExpression - Parse an expression and return it. 851/// 852/// expr ::= expr &&,|| expr -> lowest. 853/// expr ::= expr |,^,&,! expr 854/// expr ::= expr ==,!=,<>,<,<=,>,>= expr 855/// expr ::= expr <<,>> expr 856/// expr ::= expr +,- expr 857/// expr ::= expr *,/,% expr -> highest. 858/// expr ::= primaryexpr 859/// 860bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 861 // Parse the expression. 862 Res = 0; 863 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) 864 return true; 865 866 // As a special case, we support 'a op b @ modifier' by rewriting the 867 // expression to include the modifier. This is inefficient, but in general we 868 // expect users to use 'a@modifier op b'. 869 if (Lexer.getKind() == AsmToken::At) { 870 Lex(); 871 872 if (Lexer.isNot(AsmToken::Identifier)) 873 return TokError("unexpected symbol modifier following '@'"); 874 875 MCSymbolRefExpr::VariantKind Variant = 876 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); 877 if (Variant == MCSymbolRefExpr::VK_Invalid) 878 return TokError("invalid variant '" + getTok().getIdentifier() + "'"); 879 880 const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant); 881 if (!ModifiedRes) { 882 return TokError("invalid modifier '" + getTok().getIdentifier() + 883 "' (no symbols present)"); 884 } 885 886 Res = ModifiedRes; 887 Lex(); 888 } 889 890 // Try to constant fold it up front, if possible. 891 int64_t Value; 892 if (Res->EvaluateAsAbsolute(Value)) 893 Res = MCConstantExpr::Create(Value, getContext()); 894 895 return false; 896} 897 898bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 899 Res = 0; 900 return ParseParenExpr(Res, EndLoc) || 901 ParseBinOpRHS(1, Res, EndLoc); 902} 903 904bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { 905 const MCExpr *Expr; 906 907 SMLoc StartLoc = Lexer.getLoc(); 908 if (ParseExpression(Expr)) 909 return true; 910 911 if (!Expr->EvaluateAsAbsolute(Res)) 912 return Error(StartLoc, "expected absolute expression"); 913 914 return false; 915} 916 917static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 918 MCBinaryExpr::Opcode &Kind) { 919 switch (K) { 920 default: 921 return 0; // not a binop. 922 923 // Lowest Precedence: &&, || 924 case AsmToken::AmpAmp: 925 Kind = MCBinaryExpr::LAnd; 926 return 1; 927 case AsmToken::PipePipe: 928 Kind = MCBinaryExpr::LOr; 929 return 1; 930 931 932 // Low Precedence: |, &, ^ 933 // 934 // FIXME: gas seems to support '!' as an infix operator? 935 case AsmToken::Pipe: 936 Kind = MCBinaryExpr::Or; 937 return 2; 938 case AsmToken::Caret: 939 Kind = MCBinaryExpr::Xor; 940 return 2; 941 case AsmToken::Amp: 942 Kind = MCBinaryExpr::And; 943 return 2; 944 945 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= 946 case AsmToken::EqualEqual: 947 Kind = MCBinaryExpr::EQ; 948 return 3; 949 case AsmToken::ExclaimEqual: 950 case AsmToken::LessGreater: 951 Kind = MCBinaryExpr::NE; 952 return 3; 953 case AsmToken::Less: 954 Kind = MCBinaryExpr::LT; 955 return 3; 956 case AsmToken::LessEqual: 957 Kind = MCBinaryExpr::LTE; 958 return 3; 959 case AsmToken::Greater: 960 Kind = MCBinaryExpr::GT; 961 return 3; 962 case AsmToken::GreaterEqual: 963 Kind = MCBinaryExpr::GTE; 964 return 3; 965 966 // Intermediate Precedence: <<, >> 967 case AsmToken::LessLess: 968 Kind = MCBinaryExpr::Shl; 969 return 4; 970 case AsmToken::GreaterGreater: 971 Kind = MCBinaryExpr::Shr; 972 return 4; 973 974 // High Intermediate Precedence: +, - 975 case AsmToken::Plus: 976 Kind = MCBinaryExpr::Add; 977 return 5; 978 case AsmToken::Minus: 979 Kind = MCBinaryExpr::Sub; 980 return 5; 981 982 // Highest Precedence: *, /, % 983 case AsmToken::Star: 984 Kind = MCBinaryExpr::Mul; 985 return 6; 986 case AsmToken::Slash: 987 Kind = MCBinaryExpr::Div; 988 return 6; 989 case AsmToken::Percent: 990 Kind = MCBinaryExpr::Mod; 991 return 6; 992 } 993} 994 995 996/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. 997/// Res contains the LHS of the expression on input. 998bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 999 SMLoc &EndLoc) { 1000 while (1) { 1001 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 1002 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 1003 1004 // If the next token is lower precedence than we are allowed to eat, return 1005 // successfully with what we ate already. 1006 if (TokPrec < Precedence) 1007 return false; 1008 1009 Lex(); 1010 1011 // Eat the next primary expression. 1012 const MCExpr *RHS; 1013 if (ParsePrimaryExpr(RHS, EndLoc)) return true; 1014 1015 // If BinOp binds less tightly with RHS than the operator after RHS, let 1016 // the pending operator take RHS as its LHS. 1017 MCBinaryExpr::Opcode Dummy; 1018 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 1019 if (TokPrec < NextTokPrec) { 1020 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true; 1021 } 1022 1023 // Merge LHS and RHS according to operator. 1024 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 1025 } 1026} 1027 1028 1029 1030 1031/// ParseStatement: 1032/// ::= EndOfStatement 1033/// ::= Label* Directive ...Operands... EndOfStatement 1034/// ::= Label* Identifier OperandList* EndOfStatement 1035bool AsmParser::ParseStatement() { 1036 if (Lexer.is(AsmToken::EndOfStatement)) { 1037 Out.AddBlankLine(); 1038 Lex(); 1039 return false; 1040 } 1041 1042 // Statements always start with an identifier or are a full line comment. 1043 AsmToken ID = getTok(); 1044 SMLoc IDLoc = ID.getLoc(); 1045 StringRef IDVal; 1046 int64_t LocalLabelVal = -1; 1047 // A full line comment is a '#' as the first token. 1048 if (Lexer.is(AsmToken::Hash)) 1049 return ParseCppHashLineFilenameComment(IDLoc); 1050 1051 // Allow an integer followed by a ':' as a directional local label. 1052 if (Lexer.is(AsmToken::Integer)) { 1053 LocalLabelVal = getTok().getIntVal(); 1054 if (LocalLabelVal < 0) { 1055 if (!TheCondState.Ignore) 1056 return TokError("unexpected token at start of statement"); 1057 IDVal = ""; 1058 } 1059 else { 1060 IDVal = getTok().getString(); 1061 Lex(); // Consume the integer token to be used as an identifier token. 1062 if (Lexer.getKind() != AsmToken::Colon) { 1063 if (!TheCondState.Ignore) 1064 return TokError("unexpected token at start of statement"); 1065 } 1066 } 1067 1068 } else if (Lexer.is(AsmToken::Dot)) { 1069 // Treat '.' as a valid identifier in this context. 1070 Lex(); 1071 IDVal = "."; 1072 1073 } else if (ParseIdentifier(IDVal)) { 1074 if (!TheCondState.Ignore) 1075 return TokError("unexpected token at start of statement"); 1076 IDVal = ""; 1077 } 1078 1079 1080 // Handle conditional assembly here before checking for skipping. We 1081 // have to do this so that .endif isn't skipped in a ".if 0" block for 1082 // example. 1083 if (IDVal == ".if") 1084 return ParseDirectiveIf(IDLoc); 1085 if (IDVal == ".ifb") 1086 return ParseDirectiveIfb(IDLoc, true); 1087 if (IDVal == ".ifnb") 1088 return ParseDirectiveIfb(IDLoc, false); 1089 if (IDVal == ".ifc") 1090 return ParseDirectiveIfc(IDLoc, true); 1091 if (IDVal == ".ifnc") 1092 return ParseDirectiveIfc(IDLoc, false); 1093 if (IDVal == ".ifdef") 1094 return ParseDirectiveIfdef(IDLoc, true); 1095 if (IDVal == ".ifndef" || IDVal == ".ifnotdef") 1096 return ParseDirectiveIfdef(IDLoc, false); 1097 if (IDVal == ".elseif") 1098 return ParseDirectiveElseIf(IDLoc); 1099 if (IDVal == ".else") 1100 return ParseDirectiveElse(IDLoc); 1101 if (IDVal == ".endif") 1102 return ParseDirectiveEndIf(IDLoc); 1103 1104 // If we are in a ".if 0" block, ignore this statement. 1105 if (TheCondState.Ignore) { 1106 EatToEndOfStatement(); 1107 return false; 1108 } 1109 1110 // FIXME: Recurse on local labels? 1111 1112 // See what kind of statement we have. 1113 switch (Lexer.getKind()) { 1114 case AsmToken::Colon: { 1115 CheckForValidSection(); 1116 1117 // identifier ':' -> Label. 1118 Lex(); 1119 1120 // Diagnose attempt to use '.' as a label. 1121 if (IDVal == ".") 1122 return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label"); 1123 1124 // Diagnose attempt to use a variable as a label. 1125 // 1126 // FIXME: Diagnostics. Note the location of the definition as a label. 1127 // FIXME: This doesn't diagnose assignment to a symbol which has been 1128 // implicitly marked as external. 1129 MCSymbol *Sym; 1130 if (LocalLabelVal == -1) 1131 Sym = getContext().GetOrCreateSymbol(IDVal); 1132 else 1133 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); 1134 if (!Sym->isUndefined() || Sym->isVariable()) 1135 return Error(IDLoc, "invalid symbol redefinition"); 1136 1137 // Emit the label. 1138 Out.EmitLabel(Sym); 1139 1140 // If we are generating dwarf for assembly source files then gather the 1141 // info to make a dwarf label entry for this label if needed. 1142 if (getContext().getGenDwarfForAssembly()) 1143 MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), 1144 IDLoc); 1145 1146 // Consume any end of statement token, if present, to avoid spurious 1147 // AddBlankLine calls(). 1148 if (Lexer.is(AsmToken::EndOfStatement)) { 1149 Lex(); 1150 if (Lexer.is(AsmToken::Eof)) 1151 return false; 1152 } 1153 1154 return ParseStatement(); 1155 } 1156 1157 case AsmToken::Equal: 1158 // identifier '=' ... -> assignment statement 1159 Lex(); 1160 1161 return ParseAssignment(IDVal, true); 1162 1163 default: // Normal instruction or directive. 1164 break; 1165 } 1166 1167 // If macros are enabled, check to see if this is a macro instantiation. 1168 if (MacrosEnabled) 1169 if (const Macro *M = MacroMap.lookup(IDVal)) 1170 return HandleMacroEntry(IDVal, IDLoc, M); 1171 1172 // Otherwise, we have a normal instruction or directive. 1173 if (IDVal[0] == '.' && IDVal != ".") { 1174 1175 // Target hook for parsing target specific directives. 1176 if (!getTargetParser().ParseDirective(ID)) 1177 return false; 1178 1179 // Assembler features 1180 if (IDVal == ".set" || IDVal == ".equ") 1181 return ParseDirectiveSet(IDVal, true); 1182 if (IDVal == ".equiv") 1183 return ParseDirectiveSet(IDVal, false); 1184 1185 // Data directives 1186 1187 if (IDVal == ".ascii") 1188 return ParseDirectiveAscii(IDVal, false); 1189 if (IDVal == ".asciz" || IDVal == ".string") 1190 return ParseDirectiveAscii(IDVal, true); 1191 1192 if (IDVal == ".byte") 1193 return ParseDirectiveValue(1); 1194 if (IDVal == ".short") 1195 return ParseDirectiveValue(2); 1196 if (IDVal == ".value") 1197 return ParseDirectiveValue(2); 1198 if (IDVal == ".2byte") 1199 return ParseDirectiveValue(2); 1200 if (IDVal == ".long") 1201 return ParseDirectiveValue(4); 1202 if (IDVal == ".int") 1203 return ParseDirectiveValue(4); 1204 if (IDVal == ".4byte") 1205 return ParseDirectiveValue(4); 1206 if (IDVal == ".quad") 1207 return ParseDirectiveValue(8); 1208 if (IDVal == ".8byte") 1209 return ParseDirectiveValue(8); 1210 if (IDVal == ".single" || IDVal == ".float") 1211 return ParseDirectiveRealValue(APFloat::IEEEsingle); 1212 if (IDVal == ".double") 1213 return ParseDirectiveRealValue(APFloat::IEEEdouble); 1214 1215 if (IDVal == ".align") { 1216 bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes(); 1217 return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1); 1218 } 1219 if (IDVal == ".align32") { 1220 bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes(); 1221 return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4); 1222 } 1223 if (IDVal == ".balign") 1224 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 1225 if (IDVal == ".balignw") 1226 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 1227 if (IDVal == ".balignl") 1228 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 1229 if (IDVal == ".p2align") 1230 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 1231 if (IDVal == ".p2alignw") 1232 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 1233 if (IDVal == ".p2alignl") 1234 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 1235 1236 if (IDVal == ".org") 1237 return ParseDirectiveOrg(); 1238 1239 if (IDVal == ".fill") 1240 return ParseDirectiveFill(); 1241 if (IDVal == ".space" || IDVal == ".skip") 1242 return ParseDirectiveSpace(); 1243 if (IDVal == ".zero") 1244 return ParseDirectiveZero(); 1245 1246 // Symbol attribute directives 1247 1248 if (IDVal == ".extern") { 1249 EatToEndOfStatement(); // .extern is the default, ignore it. 1250 return false; 1251 } 1252 if (IDVal == ".globl" || IDVal == ".global") 1253 return ParseDirectiveSymbolAttribute(MCSA_Global); 1254 if (IDVal == ".indirect_symbol") 1255 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); 1256 if (IDVal == ".lazy_reference") 1257 return ParseDirectiveSymbolAttribute(MCSA_LazyReference); 1258 if (IDVal == ".no_dead_strip") 1259 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 1260 if (IDVal == ".symbol_resolver") 1261 return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); 1262 if (IDVal == ".private_extern") 1263 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); 1264 if (IDVal == ".reference") 1265 return ParseDirectiveSymbolAttribute(MCSA_Reference); 1266 if (IDVal == ".weak_definition") 1267 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); 1268 if (IDVal == ".weak_reference") 1269 return ParseDirectiveSymbolAttribute(MCSA_WeakReference); 1270 if (IDVal == ".weak_def_can_be_hidden") 1271 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); 1272 1273 if (IDVal == ".comm" || IDVal == ".common") 1274 return ParseDirectiveComm(/*IsLocal=*/false); 1275 if (IDVal == ".lcomm") 1276 return ParseDirectiveComm(/*IsLocal=*/true); 1277 1278 if (IDVal == ".abort") 1279 return ParseDirectiveAbort(); 1280 if (IDVal == ".include") 1281 return ParseDirectiveInclude(); 1282 if (IDVal == ".incbin") 1283 return ParseDirectiveIncbin(); 1284 1285 if (IDVal == ".code16" || IDVal == ".code16gcc") 1286 return TokError(Twine(IDVal) + " not supported yet"); 1287 1288 // Macro-like directives 1289 if (IDVal == ".rept") 1290 return ParseDirectiveRept(IDLoc); 1291 if (IDVal == ".irp") 1292 return ParseDirectiveIrp(IDLoc); 1293 if (IDVal == ".irpc") 1294 return ParseDirectiveIrpc(IDLoc); 1295 if (IDVal == ".endr") 1296 return ParseDirectiveEndr(IDLoc); 1297 1298 // Look up the handler in the handler table. 1299 std::pair<MCAsmParserExtension*, DirectiveHandler> Handler = 1300 DirectiveMap.lookup(IDVal); 1301 if (Handler.first) 1302 return (*Handler.second)(Handler.first, IDVal, IDLoc); 1303 1304 1305 return Error(IDLoc, "unknown directive"); 1306 } 1307 1308 CheckForValidSection(); 1309 1310 // Canonicalize the opcode to lower case. 1311 SmallString<128> Opcode; 1312 for (unsigned i = 0, e = IDVal.size(); i != e; ++i) 1313 Opcode.push_back(tolower(IDVal[i])); 1314 1315 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 1316 bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc, 1317 ParsedOperands); 1318 1319 // Dump the parsed representation, if requested. 1320 if (getShowParsedOperands()) { 1321 SmallString<256> Str; 1322 raw_svector_ostream OS(Str); 1323 OS << "parsed instruction: ["; 1324 for (unsigned i = 0; i != ParsedOperands.size(); ++i) { 1325 if (i != 0) 1326 OS << ", "; 1327 ParsedOperands[i]->print(OS); 1328 } 1329 OS << "]"; 1330 1331 PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str()); 1332 } 1333 1334 // If we are generating dwarf for assembly source files and the current 1335 // section is the initial text section then generate a .loc directive for 1336 // the instruction. 1337 if (!HadError && getContext().getGenDwarfForAssembly() && 1338 getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) { 1339 getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(), 1340 SrcMgr.FindLineNumber(IDLoc, CurBuffer), 1341 0, DWARF2_LINE_DEFAULT_IS_STMT ? 1342 DWARF2_FLAG_IS_STMT : 0, 0, 0, 1343 StringRef()); 1344 } 1345 1346 // If parsing succeeded, match the instruction. 1347 if (!HadError) 1348 HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, ParsedOperands, 1349 Out); 1350 1351 // Free any parsed operands. 1352 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 1353 delete ParsedOperands[i]; 1354 1355 // Don't skip the rest of the line, the instruction parser is responsible for 1356 // that. 1357 return false; 1358} 1359 1360/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line 1361/// since they may not be able to be tokenized to get to the end of line token. 1362void AsmParser::EatToEndOfLine() { 1363 if (!Lexer.is(AsmToken::EndOfStatement)) 1364 Lexer.LexUntilEndOfLine(); 1365 // Eat EOL. 1366 Lex(); 1367} 1368 1369/// ParseCppHashLineFilenameComment as this: 1370/// ::= # number "filename" 1371/// or just as a full line comment if it doesn't have a number and a string. 1372bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { 1373 Lex(); // Eat the hash token. 1374 1375 if (getLexer().isNot(AsmToken::Integer)) { 1376 // Consume the line since in cases it is not a well-formed line directive, 1377 // as if were simply a full line comment. 1378 EatToEndOfLine(); 1379 return false; 1380 } 1381 1382 int64_t LineNumber = getTok().getIntVal(); 1383 Lex(); 1384 1385 if (getLexer().isNot(AsmToken::String)) { 1386 EatToEndOfLine(); 1387 return false; 1388 } 1389 1390 StringRef Filename = getTok().getString(); 1391 // Get rid of the enclosing quotes. 1392 Filename = Filename.substr(1, Filename.size()-2); 1393 1394 // Save the SMLoc, Filename and LineNumber for later use by diagnostics. 1395 CppHashLoc = L; 1396 CppHashFilename = Filename; 1397 CppHashLineNumber = LineNumber; 1398 1399 // Ignore any trailing characters, they're just comment. 1400 EatToEndOfLine(); 1401 return false; 1402} 1403 1404/// DiagHandler - will use the last parsed cpp hash line filename comment 1405/// for the Filename and LineNo if any in the diagnostic. 1406void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { 1407 const AsmParser *Parser = static_cast<const AsmParser*>(Context); 1408 raw_ostream &OS = errs(); 1409 1410 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); 1411 const SMLoc &DiagLoc = Diag.getLoc(); 1412 int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1413 int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); 1414 1415 // Like SourceMgr::PrintMessage() we need to print the include stack if any 1416 // before printing the message. 1417 int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); 1418 if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { 1419 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); 1420 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); 1421 } 1422 1423 // If we have not parsed a cpp hash line filename comment or the source 1424 // manager changed or buffer changed (like in a nested include) then just 1425 // print the normal diagnostic using its Filename and LineNo. 1426 if (!Parser->CppHashLineNumber || 1427 &DiagSrcMgr != &Parser->SrcMgr || 1428 DiagBuf != CppHashBuf) { 1429 if (Parser->SavedDiagHandler) 1430 Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); 1431 else 1432 Diag.print(0, OS); 1433 return; 1434 } 1435 1436 // Use the CppHashFilename and calculate a line number based on the 1437 // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for 1438 // the diagnostic. 1439 const std::string Filename = Parser->CppHashFilename; 1440 1441 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); 1442 int CppHashLocLineNo = 1443 Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); 1444 int LineNo = Parser->CppHashLineNumber - 1 + 1445 (DiagLocLineNo - CppHashLocLineNo); 1446 1447 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), 1448 Filename, LineNo, Diag.getColumnNo(), 1449 Diag.getKind(), Diag.getMessage(), 1450 Diag.getLineContents(), Diag.getRanges()); 1451 1452 if (Parser->SavedDiagHandler) 1453 Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); 1454 else 1455 NewDiag.print(0, OS); 1456} 1457 1458// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The 1459// difference being that that function accepts '@' as part of identifiers and 1460// we can't do that. AsmLexer.cpp should probably be changed to handle 1461// '@' as a special case when needed. 1462static bool isIdentifierChar(char c) { 1463 return isalnum(c) || c == '_' || c == '$' || c == '.'; 1464} 1465 1466bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, 1467 const MacroParameters &Parameters, 1468 const MacroArguments &A, 1469 const SMLoc &L) { 1470 unsigned NParameters = Parameters.size(); 1471 if (NParameters != 0 && NParameters != A.size()) 1472 return Error(L, "Wrong number of arguments"); 1473 1474 while (!Body.empty()) { 1475 // Scan for the next substitution. 1476 std::size_t End = Body.size(), Pos = 0; 1477 for (; Pos != End; ++Pos) { 1478 // Check for a substitution or escape. 1479 if (!NParameters) { 1480 // This macro has no parameters, look for $0, $1, etc. 1481 if (Body[Pos] != '$' || Pos + 1 == End) 1482 continue; 1483 1484 char Next = Body[Pos + 1]; 1485 if (Next == '$' || Next == 'n' || isdigit(Next)) 1486 break; 1487 } else { 1488 // This macro has parameters, look for \foo, \bar, etc. 1489 if (Body[Pos] == '\\' && Pos + 1 != End) 1490 break; 1491 } 1492 } 1493 1494 // Add the prefix. 1495 OS << Body.slice(0, Pos); 1496 1497 // Check if we reached the end. 1498 if (Pos == End) 1499 break; 1500 1501 if (!NParameters) { 1502 switch (Body[Pos+1]) { 1503 // $$ => $ 1504 case '$': 1505 OS << '$'; 1506 break; 1507 1508 // $n => number of arguments 1509 case 'n': 1510 OS << A.size(); 1511 break; 1512 1513 // $[0-9] => argument 1514 default: { 1515 // Missing arguments are ignored. 1516 unsigned Index = Body[Pos+1] - '0'; 1517 if (Index >= A.size()) 1518 break; 1519 1520 // Otherwise substitute with the token values, with spaces eliminated. 1521 for (MacroArgument::const_iterator it = A[Index].begin(), 1522 ie = A[Index].end(); it != ie; ++it) 1523 OS << it->getString(); 1524 break; 1525 } 1526 } 1527 Pos += 2; 1528 } else { 1529 unsigned I = Pos + 1; 1530 while (isIdentifierChar(Body[I]) && I + 1 != End) 1531 ++I; 1532 1533 const char *Begin = Body.data() + Pos +1; 1534 StringRef Argument(Begin, I - (Pos +1)); 1535 unsigned Index = 0; 1536 for (; Index < NParameters; ++Index) 1537 if (Parameters[Index] == Argument) 1538 break; 1539 1540 // FIXME: We should error at the macro definition. 1541 if (Index == NParameters) 1542 return Error(L, "Parameter not found"); 1543 1544 for (MacroArgument::const_iterator it = A[Index].begin(), 1545 ie = A[Index].end(); it != ie; ++it) 1546 OS << it->getString(); 1547 1548 Pos += 1 + Argument.size(); 1549 } 1550 // Update the scan point. 1551 Body = Body.substr(Pos); 1552 } 1553 1554 return false; 1555} 1556 1557MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, 1558 MemoryBuffer *I) 1559 : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitLoc(EL) 1560{ 1561} 1562 1563/// ParseMacroArgument - Extract AsmTokens for a macro argument. 1564/// This is used for both default macro parameter values and the 1565/// arguments in macro invocations 1566bool AsmParser::ParseMacroArgument(MacroArgument &MA) { 1567 unsigned ParenLevel = 0; 1568 1569 for (;;) { 1570 if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) 1571 return TokError("unexpected token in macro instantiation"); 1572 1573 // HandleMacroEntry relies on not advancing the lexer here 1574 // to be able to fill in the remaining default parameter values 1575 if (Lexer.is(AsmToken::EndOfStatement)) 1576 break; 1577 if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) 1578 break; 1579 1580 // Adjust the current parentheses level. 1581 if (Lexer.is(AsmToken::LParen)) 1582 ++ParenLevel; 1583 else if (Lexer.is(AsmToken::RParen) && ParenLevel) 1584 --ParenLevel; 1585 1586 // Append the token to the current argument list. 1587 MA.push_back(getTok()); 1588 Lex(); 1589 } 1590 if (ParenLevel != 0) 1591 return TokError("unbalanced parentheses in macro argument"); 1592 return false; 1593} 1594 1595// Parse the macro instantiation arguments. 1596bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) { 1597 const unsigned NParameters = M ? M->Parameters.size() : 0; 1598 1599 // Parse two kinds of macro invocations: 1600 // - macros defined without any parameters accept an arbitrary number of them 1601 // - macros defined with parameters accept at most that many of them 1602 for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; 1603 ++Parameter) { 1604 MacroArgument MA; 1605 1606 if (ParseMacroArgument(MA)) 1607 return true; 1608 1609 A.push_back(MA); 1610 1611 if (Lexer.is(AsmToken::EndOfStatement)) 1612 return false; 1613 1614 if (Lexer.is(AsmToken::Comma)) 1615 Lex(); 1616 } 1617 return TokError("Too many arguments"); 1618} 1619 1620bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc, 1621 const Macro *M) { 1622 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate 1623 // this, although we should protect against infinite loops. 1624 if (ActiveMacros.size() == 20) 1625 return TokError("macros cannot be nested more than 20 levels deep"); 1626 1627 MacroArguments A; 1628 if (ParseMacroArguments(M, A)) 1629 return true; 1630 1631 // Remove any trailing empty arguments. Do this after-the-fact as we have 1632 // to keep empty arguments in the middle of the list or positionality 1633 // gets off. e.g., "foo 1, , 2" vs. "foo 1, 2," 1634 while (!A.empty() && A.back().empty()) 1635 A.pop_back(); 1636 1637 // Macro instantiation is lexical, unfortunately. We construct a new buffer 1638 // to hold the macro body with substitutions. 1639 SmallString<256> Buf; 1640 StringRef Body = M->Body; 1641 raw_svector_ostream OS(Buf); 1642 1643 if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) 1644 return true; 1645 1646 // We include the .endmacro in the buffer as our queue to exit the macro 1647 // instantiation. 1648 OS << ".endmacro\n"; 1649 1650 MemoryBuffer *Instantiation = 1651 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 1652 1653 // Create the macro instantiation object and add to the current macro 1654 // instantiation stack. 1655 MacroInstantiation *MI = new MacroInstantiation(M, NameLoc, 1656 getTok().getLoc(), 1657 Instantiation); 1658 ActiveMacros.push_back(MI); 1659 1660 // Jump to the macro instantiation and prime the lexer. 1661 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 1662 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 1663 Lex(); 1664 1665 return false; 1666} 1667 1668void AsmParser::HandleMacroExit() { 1669 // Jump to the EndOfStatement we should return to, and consume it. 1670 JumpToLoc(ActiveMacros.back()->ExitLoc); 1671 Lex(); 1672 1673 // Pop the instantiation entry. 1674 delete ActiveMacros.back(); 1675 ActiveMacros.pop_back(); 1676} 1677 1678static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) { 1679 switch (Value->getKind()) { 1680 case MCExpr::Binary: { 1681 const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value); 1682 return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS()); 1683 break; 1684 } 1685 case MCExpr::Target: 1686 case MCExpr::Constant: 1687 return false; 1688 case MCExpr::SymbolRef: { 1689 const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol(); 1690 if (S.isVariable()) 1691 return IsUsedIn(Sym, S.getVariableValue()); 1692 return &S == Sym; 1693 } 1694 case MCExpr::Unary: 1695 return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr()); 1696 } 1697 1698 llvm_unreachable("Unknown expr kind!"); 1699} 1700 1701bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, 1702 bool NoDeadStrip) { 1703 // FIXME: Use better location, we should use proper tokens. 1704 SMLoc EqualLoc = Lexer.getLoc(); 1705 1706 const MCExpr *Value; 1707 if (ParseExpression(Value)) 1708 return true; 1709 1710 // Note: we don't count b as used in "a = b". This is to allow 1711 // a = b 1712 // b = c 1713 1714 if (Lexer.isNot(AsmToken::EndOfStatement)) 1715 return TokError("unexpected token in assignment"); 1716 1717 // Error on assignment to '.'. 1718 if (Name == ".") { 1719 return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported " 1720 "(use '.space' or '.org').)")); 1721 } 1722 1723 // Eat the end of statement marker. 1724 Lex(); 1725 1726 // Validate that the LHS is allowed to be a variable (either it has not been 1727 // used as a symbol, or it is an absolute symbol). 1728 MCSymbol *Sym = getContext().LookupSymbol(Name); 1729 if (Sym) { 1730 // Diagnose assignment to a label. 1731 // 1732 // FIXME: Diagnostics. Note the location of the definition as a label. 1733 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 1734 if (IsUsedIn(Sym, Value)) 1735 return Error(EqualLoc, "Recursive use of '" + Name + "'"); 1736 else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable()) 1737 ; // Allow redefinitions of undefined symbols only used in directives. 1738 else if (Sym->isVariable() && !Sym->isUsed() && allow_redef) 1739 ; // Allow redefinitions of variables that haven't yet been used. 1740 else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef)) 1741 return Error(EqualLoc, "redefinition of '" + Name + "'"); 1742 else if (!Sym->isVariable()) 1743 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 1744 else if (!isa<MCConstantExpr>(Sym->getVariableValue())) 1745 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 1746 Name + "'"); 1747 1748 // Don't count these checks as uses. 1749 Sym->setUsed(false); 1750 } else 1751 Sym = getContext().GetOrCreateSymbol(Name); 1752 1753 // FIXME: Handle '.'. 1754 1755 // Do the assignment. 1756 Out.EmitAssignment(Sym, Value); 1757 if (NoDeadStrip) 1758 Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip); 1759 1760 1761 return false; 1762} 1763 1764/// ParseIdentifier: 1765/// ::= identifier 1766/// ::= string 1767bool AsmParser::ParseIdentifier(StringRef &Res) { 1768 // The assembler has relaxed rules for accepting identifiers, in particular we 1769 // allow things like '.globl $foo', which would normally be separate 1770 // tokens. At this level, we have already lexed so we cannot (currently) 1771 // handle this as a context dependent token, instead we detect adjacent tokens 1772 // and return the combined identifier. 1773 if (Lexer.is(AsmToken::Dollar)) { 1774 SMLoc DollarLoc = getLexer().getLoc(); 1775 1776 // Consume the dollar sign, and check for a following identifier. 1777 Lex(); 1778 if (Lexer.isNot(AsmToken::Identifier)) 1779 return true; 1780 1781 // We have a '$' followed by an identifier, make sure they are adjacent. 1782 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1783 return true; 1784 1785 // Construct the joined identifier and consume the token. 1786 Res = StringRef(DollarLoc.getPointer(), 1787 getTok().getIdentifier().size() + 1); 1788 Lex(); 1789 return false; 1790 } 1791 1792 if (Lexer.isNot(AsmToken::Identifier) && 1793 Lexer.isNot(AsmToken::String)) 1794 return true; 1795 1796 Res = getTok().getIdentifier(); 1797 1798 Lex(); // Consume the identifier token. 1799 1800 return false; 1801} 1802 1803/// ParseDirectiveSet: 1804/// ::= .equ identifier ',' expression 1805/// ::= .equiv identifier ',' expression 1806/// ::= .set identifier ',' expression 1807bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) { 1808 StringRef Name; 1809 1810 if (ParseIdentifier(Name)) 1811 return TokError("expected identifier after '" + Twine(IDVal) + "'"); 1812 1813 if (getLexer().isNot(AsmToken::Comma)) 1814 return TokError("unexpected token in '" + Twine(IDVal) + "'"); 1815 Lex(); 1816 1817 return ParseAssignment(Name, allow_redef, true); 1818} 1819 1820bool AsmParser::ParseEscapedString(std::string &Data) { 1821 assert(getLexer().is(AsmToken::String) && "Unexpected current token!"); 1822 1823 Data = ""; 1824 StringRef Str = getTok().getStringContents(); 1825 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 1826 if (Str[i] != '\\') { 1827 Data += Str[i]; 1828 continue; 1829 } 1830 1831 // Recognize escaped characters. Note that this escape semantics currently 1832 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 1833 ++i; 1834 if (i == e) 1835 return TokError("unexpected backslash at end of string"); 1836 1837 // Recognize octal sequences. 1838 if ((unsigned) (Str[i] - '0') <= 7) { 1839 // Consume up to three octal characters. 1840 unsigned Value = Str[i] - '0'; 1841 1842 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 1843 ++i; 1844 Value = Value * 8 + (Str[i] - '0'); 1845 1846 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 1847 ++i; 1848 Value = Value * 8 + (Str[i] - '0'); 1849 } 1850 } 1851 1852 if (Value > 255) 1853 return TokError("invalid octal escape sequence (out of range)"); 1854 1855 Data += (unsigned char) Value; 1856 continue; 1857 } 1858 1859 // Otherwise recognize individual escapes. 1860 switch (Str[i]) { 1861 default: 1862 // Just reject invalid escape sequences for now. 1863 return TokError("invalid escape sequence (unrecognized character)"); 1864 1865 case 'b': Data += '\b'; break; 1866 case 'f': Data += '\f'; break; 1867 case 'n': Data += '\n'; break; 1868 case 'r': Data += '\r'; break; 1869 case 't': Data += '\t'; break; 1870 case '"': Data += '"'; break; 1871 case '\\': Data += '\\'; break; 1872 } 1873 } 1874 1875 return false; 1876} 1877 1878/// ParseDirectiveAscii: 1879/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] 1880bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { 1881 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1882 CheckForValidSection(); 1883 1884 for (;;) { 1885 if (getLexer().isNot(AsmToken::String)) 1886 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 1887 1888 std::string Data; 1889 if (ParseEscapedString(Data)) 1890 return true; 1891 1892 getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE); 1893 if (ZeroTerminated) 1894 getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); 1895 1896 Lex(); 1897 1898 if (getLexer().is(AsmToken::EndOfStatement)) 1899 break; 1900 1901 if (getLexer().isNot(AsmToken::Comma)) 1902 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 1903 Lex(); 1904 } 1905 } 1906 1907 Lex(); 1908 return false; 1909} 1910 1911/// ParseDirectiveValue 1912/// ::= (.byte | .short | ... ) [ expression (, expression)* ] 1913bool AsmParser::ParseDirectiveValue(unsigned Size) { 1914 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1915 CheckForValidSection(); 1916 1917 for (;;) { 1918 const MCExpr *Value; 1919 SMLoc ExprLoc = getLexer().getLoc(); 1920 if (ParseExpression(Value)) 1921 return true; 1922 1923 // Special case constant expressions to match code generator. 1924 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 1925 assert(Size <= 8 && "Invalid size"); 1926 uint64_t IntValue = MCE->getValue(); 1927 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) 1928 return Error(ExprLoc, "literal value out of range for directive"); 1929 getStreamer().EmitIntValue(IntValue, Size, DEFAULT_ADDRSPACE); 1930 } else 1931 getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE); 1932 1933 if (getLexer().is(AsmToken::EndOfStatement)) 1934 break; 1935 1936 // FIXME: Improve diagnostic. 1937 if (getLexer().isNot(AsmToken::Comma)) 1938 return TokError("unexpected token in directive"); 1939 Lex(); 1940 } 1941 } 1942 1943 Lex(); 1944 return false; 1945} 1946 1947/// ParseDirectiveRealValue 1948/// ::= (.single | .double) [ expression (, expression)* ] 1949bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { 1950 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1951 CheckForValidSection(); 1952 1953 for (;;) { 1954 // We don't truly support arithmetic on floating point expressions, so we 1955 // have to manually parse unary prefixes. 1956 bool IsNeg = false; 1957 if (getLexer().is(AsmToken::Minus)) { 1958 Lex(); 1959 IsNeg = true; 1960 } else if (getLexer().is(AsmToken::Plus)) 1961 Lex(); 1962 1963 if (getLexer().isNot(AsmToken::Integer) && 1964 getLexer().isNot(AsmToken::Real) && 1965 getLexer().isNot(AsmToken::Identifier)) 1966 return TokError("unexpected token in directive"); 1967 1968 // Convert to an APFloat. 1969 APFloat Value(Semantics); 1970 StringRef IDVal = getTok().getString(); 1971 if (getLexer().is(AsmToken::Identifier)) { 1972 if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf")) 1973 Value = APFloat::getInf(Semantics); 1974 else if (!IDVal.compare_lower("nan")) 1975 Value = APFloat::getNaN(Semantics, false, ~0); 1976 else 1977 return TokError("invalid floating point literal"); 1978 } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == 1979 APFloat::opInvalidOp) 1980 return TokError("invalid floating point literal"); 1981 if (IsNeg) 1982 Value.changeSign(); 1983 1984 // Consume the numeric token. 1985 Lex(); 1986 1987 // Emit the value as an integer. 1988 APInt AsInt = Value.bitcastToAPInt(); 1989 getStreamer().EmitIntValue(AsInt.getLimitedValue(), 1990 AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE); 1991 1992 if (getLexer().is(AsmToken::EndOfStatement)) 1993 break; 1994 1995 if (getLexer().isNot(AsmToken::Comma)) 1996 return TokError("unexpected token in directive"); 1997 Lex(); 1998 } 1999 } 2000 2001 Lex(); 2002 return false; 2003} 2004 2005/// ParseDirectiveSpace 2006/// ::= .space expression [ , expression ] 2007bool AsmParser::ParseDirectiveSpace() { 2008 CheckForValidSection(); 2009 2010 int64_t NumBytes; 2011 if (ParseAbsoluteExpression(NumBytes)) 2012 return true; 2013 2014 int64_t FillExpr = 0; 2015 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2016 if (getLexer().isNot(AsmToken::Comma)) 2017 return TokError("unexpected token in '.space' directive"); 2018 Lex(); 2019 2020 if (ParseAbsoluteExpression(FillExpr)) 2021 return true; 2022 2023 if (getLexer().isNot(AsmToken::EndOfStatement)) 2024 return TokError("unexpected token in '.space' directive"); 2025 } 2026 2027 Lex(); 2028 2029 if (NumBytes <= 0) 2030 return TokError("invalid number of bytes in '.space' directive"); 2031 2032 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 2033 getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); 2034 2035 return false; 2036} 2037 2038/// ParseDirectiveZero 2039/// ::= .zero expression 2040bool AsmParser::ParseDirectiveZero() { 2041 CheckForValidSection(); 2042 2043 int64_t NumBytes; 2044 if (ParseAbsoluteExpression(NumBytes)) 2045 return true; 2046 2047 int64_t Val = 0; 2048 if (getLexer().is(AsmToken::Comma)) { 2049 Lex(); 2050 if (ParseAbsoluteExpression(Val)) 2051 return true; 2052 } 2053 2054 if (getLexer().isNot(AsmToken::EndOfStatement)) 2055 return TokError("unexpected token in '.zero' directive"); 2056 2057 Lex(); 2058 2059 getStreamer().EmitFill(NumBytes, Val, DEFAULT_ADDRSPACE); 2060 2061 return false; 2062} 2063 2064/// ParseDirectiveFill 2065/// ::= .fill expression , expression , expression 2066bool AsmParser::ParseDirectiveFill() { 2067 CheckForValidSection(); 2068 2069 int64_t NumValues; 2070 if (ParseAbsoluteExpression(NumValues)) 2071 return true; 2072 2073 if (getLexer().isNot(AsmToken::Comma)) 2074 return TokError("unexpected token in '.fill' directive"); 2075 Lex(); 2076 2077 int64_t FillSize; 2078 if (ParseAbsoluteExpression(FillSize)) 2079 return true; 2080 2081 if (getLexer().isNot(AsmToken::Comma)) 2082 return TokError("unexpected token in '.fill' directive"); 2083 Lex(); 2084 2085 int64_t FillExpr; 2086 if (ParseAbsoluteExpression(FillExpr)) 2087 return true; 2088 2089 if (getLexer().isNot(AsmToken::EndOfStatement)) 2090 return TokError("unexpected token in '.fill' directive"); 2091 2092 Lex(); 2093 2094 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) 2095 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); 2096 2097 for (uint64_t i = 0, e = NumValues; i != e; ++i) 2098 getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE); 2099 2100 return false; 2101} 2102 2103/// ParseDirectiveOrg 2104/// ::= .org expression [ , expression ] 2105bool AsmParser::ParseDirectiveOrg() { 2106 CheckForValidSection(); 2107 2108 const MCExpr *Offset; 2109 SMLoc Loc = getTok().getLoc(); 2110 if (ParseExpression(Offset)) 2111 return true; 2112 2113 // Parse optional fill expression. 2114 int64_t FillExpr = 0; 2115 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2116 if (getLexer().isNot(AsmToken::Comma)) 2117 return TokError("unexpected token in '.org' directive"); 2118 Lex(); 2119 2120 if (ParseAbsoluteExpression(FillExpr)) 2121 return true; 2122 2123 if (getLexer().isNot(AsmToken::EndOfStatement)) 2124 return TokError("unexpected token in '.org' directive"); 2125 } 2126 2127 Lex(); 2128 2129 // Only limited forms of relocatable expressions are accepted here, it 2130 // has to be relative to the current section. The streamer will return 2131 // 'true' if the expression wasn't evaluatable. 2132 if (getStreamer().EmitValueToOffset(Offset, FillExpr)) 2133 return Error(Loc, "expected assembly-time absolute expression"); 2134 2135 return false; 2136} 2137 2138/// ParseDirectiveAlign 2139/// ::= {.align, ...} expression [ , expression [ , expression ]] 2140bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 2141 CheckForValidSection(); 2142 2143 SMLoc AlignmentLoc = getLexer().getLoc(); 2144 int64_t Alignment; 2145 if (ParseAbsoluteExpression(Alignment)) 2146 return true; 2147 2148 SMLoc MaxBytesLoc; 2149 bool HasFillExpr = false; 2150 int64_t FillExpr = 0; 2151 int64_t MaxBytesToFill = 0; 2152 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2153 if (getLexer().isNot(AsmToken::Comma)) 2154 return TokError("unexpected token in directive"); 2155 Lex(); 2156 2157 // The fill expression can be omitted while specifying a maximum number of 2158 // alignment bytes, e.g: 2159 // .align 3,,4 2160 if (getLexer().isNot(AsmToken::Comma)) { 2161 HasFillExpr = true; 2162 if (ParseAbsoluteExpression(FillExpr)) 2163 return true; 2164 } 2165 2166 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2167 if (getLexer().isNot(AsmToken::Comma)) 2168 return TokError("unexpected token in directive"); 2169 Lex(); 2170 2171 MaxBytesLoc = getLexer().getLoc(); 2172 if (ParseAbsoluteExpression(MaxBytesToFill)) 2173 return true; 2174 2175 if (getLexer().isNot(AsmToken::EndOfStatement)) 2176 return TokError("unexpected token in directive"); 2177 } 2178 } 2179 2180 Lex(); 2181 2182 if (!HasFillExpr) 2183 FillExpr = 0; 2184 2185 // Compute alignment in bytes. 2186 if (IsPow2) { 2187 // FIXME: Diagnose overflow. 2188 if (Alignment >= 32) { 2189 Error(AlignmentLoc, "invalid alignment value"); 2190 Alignment = 31; 2191 } 2192 2193 Alignment = 1ULL << Alignment; 2194 } 2195 2196 // Diagnose non-sensical max bytes to align. 2197 if (MaxBytesLoc.isValid()) { 2198 if (MaxBytesToFill < 1) { 2199 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 2200 "many bytes, ignoring maximum bytes expression"); 2201 MaxBytesToFill = 0; 2202 } 2203 2204 if (MaxBytesToFill >= Alignment) { 2205 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 2206 "has no effect"); 2207 MaxBytesToFill = 0; 2208 } 2209 } 2210 2211 // Check whether we should use optimal code alignment for this .align 2212 // directive. 2213 bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign(); 2214 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && 2215 ValueSize == 1 && UseCodeAlign) { 2216 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); 2217 } else { 2218 // FIXME: Target specific behavior about how the "extra" bytes are filled. 2219 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, 2220 MaxBytesToFill); 2221 } 2222 2223 return false; 2224} 2225 2226/// ParseDirectiveSymbolAttribute 2227/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 2228bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 2229 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2230 for (;;) { 2231 StringRef Name; 2232 SMLoc Loc = getTok().getLoc(); 2233 2234 if (ParseIdentifier(Name)) 2235 return Error(Loc, "expected identifier in directive"); 2236 2237 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2238 2239 // Assembler local symbols don't make any sense here. Complain loudly. 2240 if (Sym->isTemporary()) 2241 return Error(Loc, "non-local symbol required in directive"); 2242 2243 getStreamer().EmitSymbolAttribute(Sym, Attr); 2244 2245 if (getLexer().is(AsmToken::EndOfStatement)) 2246 break; 2247 2248 if (getLexer().isNot(AsmToken::Comma)) 2249 return TokError("unexpected token in directive"); 2250 Lex(); 2251 } 2252 } 2253 2254 Lex(); 2255 return false; 2256} 2257 2258/// ParseDirectiveComm 2259/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 2260bool AsmParser::ParseDirectiveComm(bool IsLocal) { 2261 CheckForValidSection(); 2262 2263 SMLoc IDLoc = getLexer().getLoc(); 2264 StringRef Name; 2265 if (ParseIdentifier(Name)) 2266 return TokError("expected identifier in directive"); 2267 2268 // Handle the identifier as the key symbol. 2269 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2270 2271 if (getLexer().isNot(AsmToken::Comma)) 2272 return TokError("unexpected token in directive"); 2273 Lex(); 2274 2275 int64_t Size; 2276 SMLoc SizeLoc = getLexer().getLoc(); 2277 if (ParseAbsoluteExpression(Size)) 2278 return true; 2279 2280 int64_t Pow2Alignment = 0; 2281 SMLoc Pow2AlignmentLoc; 2282 if (getLexer().is(AsmToken::Comma)) { 2283 Lex(); 2284 Pow2AlignmentLoc = getLexer().getLoc(); 2285 if (ParseAbsoluteExpression(Pow2Alignment)) 2286 return true; 2287 2288 LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); 2289 if (IsLocal && LCOMM == LCOMM::NoAlignment) 2290 return Error(Pow2AlignmentLoc, "alignment not supported on this target"); 2291 2292 // If this target takes alignments in bytes (not log) validate and convert. 2293 if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || 2294 (IsLocal && LCOMM == LCOMM::ByteAlignment)) { 2295 if (!isPowerOf2_64(Pow2Alignment)) 2296 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 2297 Pow2Alignment = Log2_64(Pow2Alignment); 2298 } 2299 } 2300 2301 if (getLexer().isNot(AsmToken::EndOfStatement)) 2302 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 2303 2304 Lex(); 2305 2306 // NOTE: a size of zero for a .comm should create a undefined symbol 2307 // but a size of .lcomm creates a bss symbol of size zero. 2308 if (Size < 0) 2309 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 2310 "be less than zero"); 2311 2312 // NOTE: The alignment in the directive is a power of 2 value, the assembler 2313 // may internally end up wanting an alignment in bytes. 2314 // FIXME: Diagnose overflow. 2315 if (Pow2Alignment < 0) 2316 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 2317 "alignment, can't be less than zero"); 2318 2319 if (!Sym->isUndefined()) 2320 return Error(IDLoc, "invalid symbol redefinition"); 2321 2322 // Create the Symbol as a common or local common with Size and Pow2Alignment 2323 if (IsLocal) { 2324 getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); 2325 return false; 2326 } 2327 2328 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 2329 return false; 2330} 2331 2332/// ParseDirectiveAbort 2333/// ::= .abort [... message ...] 2334bool AsmParser::ParseDirectiveAbort() { 2335 // FIXME: Use loc from directive. 2336 SMLoc Loc = getLexer().getLoc(); 2337 2338 StringRef Str = ParseStringToEndOfStatement(); 2339 if (getLexer().isNot(AsmToken::EndOfStatement)) 2340 return TokError("unexpected token in '.abort' directive"); 2341 2342 Lex(); 2343 2344 if (Str.empty()) 2345 Error(Loc, ".abort detected. Assembly stopping."); 2346 else 2347 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 2348 // FIXME: Actually abort assembly here. 2349 2350 return false; 2351} 2352 2353/// ParseDirectiveInclude 2354/// ::= .include "filename" 2355bool AsmParser::ParseDirectiveInclude() { 2356 if (getLexer().isNot(AsmToken::String)) 2357 return TokError("expected string in '.include' directive"); 2358 2359 std::string Filename = getTok().getString(); 2360 SMLoc IncludeLoc = getLexer().getLoc(); 2361 Lex(); 2362 2363 if (getLexer().isNot(AsmToken::EndOfStatement)) 2364 return TokError("unexpected token in '.include' directive"); 2365 2366 // Strip the quotes. 2367 Filename = Filename.substr(1, Filename.size()-2); 2368 2369 // Attempt to switch the lexer to the included file before consuming the end 2370 // of statement to avoid losing it when we switch. 2371 if (EnterIncludeFile(Filename)) { 2372 Error(IncludeLoc, "Could not find include file '" + Filename + "'"); 2373 return true; 2374 } 2375 2376 return false; 2377} 2378 2379/// ParseDirectiveIncbin 2380/// ::= .incbin "filename" 2381bool AsmParser::ParseDirectiveIncbin() { 2382 if (getLexer().isNot(AsmToken::String)) 2383 return TokError("expected string in '.incbin' directive"); 2384 2385 std::string Filename = getTok().getString(); 2386 SMLoc IncbinLoc = getLexer().getLoc(); 2387 Lex(); 2388 2389 if (getLexer().isNot(AsmToken::EndOfStatement)) 2390 return TokError("unexpected token in '.incbin' directive"); 2391 2392 // Strip the quotes. 2393 Filename = Filename.substr(1, Filename.size()-2); 2394 2395 // Attempt to process the included file. 2396 if (ProcessIncbinFile(Filename)) { 2397 Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); 2398 return true; 2399 } 2400 2401 return false; 2402} 2403 2404/// ParseDirectiveIf 2405/// ::= .if expression 2406bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { 2407 TheCondStack.push_back(TheCondState); 2408 TheCondState.TheCond = AsmCond::IfCond; 2409 if (TheCondState.Ignore) { 2410 EatToEndOfStatement(); 2411 } else { 2412 int64_t ExprValue; 2413 if (ParseAbsoluteExpression(ExprValue)) 2414 return true; 2415 2416 if (getLexer().isNot(AsmToken::EndOfStatement)) 2417 return TokError("unexpected token in '.if' directive"); 2418 2419 Lex(); 2420 2421 TheCondState.CondMet = ExprValue; 2422 TheCondState.Ignore = !TheCondState.CondMet; 2423 } 2424 2425 return false; 2426} 2427 2428/// ParseDirectiveIfb 2429/// ::= .ifb string 2430bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { 2431 TheCondStack.push_back(TheCondState); 2432 TheCondState.TheCond = AsmCond::IfCond; 2433 2434 if (TheCondState.Ignore) { 2435 EatToEndOfStatement(); 2436 } else { 2437 StringRef Str = ParseStringToEndOfStatement(); 2438 2439 if (getLexer().isNot(AsmToken::EndOfStatement)) 2440 return TokError("unexpected token in '.ifb' directive"); 2441 2442 Lex(); 2443 2444 TheCondState.CondMet = ExpectBlank == Str.empty(); 2445 TheCondState.Ignore = !TheCondState.CondMet; 2446 } 2447 2448 return false; 2449} 2450 2451/// ParseDirectiveIfc 2452/// ::= .ifc string1, string2 2453bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { 2454 TheCondStack.push_back(TheCondState); 2455 TheCondState.TheCond = AsmCond::IfCond; 2456 2457 if (TheCondState.Ignore) { 2458 EatToEndOfStatement(); 2459 } else { 2460 StringRef Str1 = ParseStringToComma(); 2461 2462 if (getLexer().isNot(AsmToken::Comma)) 2463 return TokError("unexpected token in '.ifc' directive"); 2464 2465 Lex(); 2466 2467 StringRef Str2 = ParseStringToEndOfStatement(); 2468 2469 if (getLexer().isNot(AsmToken::EndOfStatement)) 2470 return TokError("unexpected token in '.ifc' directive"); 2471 2472 Lex(); 2473 2474 TheCondState.CondMet = ExpectEqual == (Str1 == Str2); 2475 TheCondState.Ignore = !TheCondState.CondMet; 2476 } 2477 2478 return false; 2479} 2480 2481/// ParseDirectiveIfdef 2482/// ::= .ifdef symbol 2483bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { 2484 StringRef Name; 2485 TheCondStack.push_back(TheCondState); 2486 TheCondState.TheCond = AsmCond::IfCond; 2487 2488 if (TheCondState.Ignore) { 2489 EatToEndOfStatement(); 2490 } else { 2491 if (ParseIdentifier(Name)) 2492 return TokError("expected identifier after '.ifdef'"); 2493 2494 Lex(); 2495 2496 MCSymbol *Sym = getContext().LookupSymbol(Name); 2497 2498 if (expect_defined) 2499 TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined()); 2500 else 2501 TheCondState.CondMet = (Sym == NULL || Sym->isUndefined()); 2502 TheCondState.Ignore = !TheCondState.CondMet; 2503 } 2504 2505 return false; 2506} 2507 2508/// ParseDirectiveElseIf 2509/// ::= .elseif expression 2510bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { 2511 if (TheCondState.TheCond != AsmCond::IfCond && 2512 TheCondState.TheCond != AsmCond::ElseIfCond) 2513 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 2514 " an .elseif"); 2515 TheCondState.TheCond = AsmCond::ElseIfCond; 2516 2517 bool LastIgnoreState = false; 2518 if (!TheCondStack.empty()) 2519 LastIgnoreState = TheCondStack.back().Ignore; 2520 if (LastIgnoreState || TheCondState.CondMet) { 2521 TheCondState.Ignore = true; 2522 EatToEndOfStatement(); 2523 } 2524 else { 2525 int64_t ExprValue; 2526 if (ParseAbsoluteExpression(ExprValue)) 2527 return true; 2528 2529 if (getLexer().isNot(AsmToken::EndOfStatement)) 2530 return TokError("unexpected token in '.elseif' directive"); 2531 2532 Lex(); 2533 TheCondState.CondMet = ExprValue; 2534 TheCondState.Ignore = !TheCondState.CondMet; 2535 } 2536 2537 return false; 2538} 2539 2540/// ParseDirectiveElse 2541/// ::= .else 2542bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { 2543 if (getLexer().isNot(AsmToken::EndOfStatement)) 2544 return TokError("unexpected token in '.else' directive"); 2545 2546 Lex(); 2547 2548 if (TheCondState.TheCond != AsmCond::IfCond && 2549 TheCondState.TheCond != AsmCond::ElseIfCond) 2550 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 2551 ".elseif"); 2552 TheCondState.TheCond = AsmCond::ElseCond; 2553 bool LastIgnoreState = false; 2554 if (!TheCondStack.empty()) 2555 LastIgnoreState = TheCondStack.back().Ignore; 2556 if (LastIgnoreState || TheCondState.CondMet) 2557 TheCondState.Ignore = true; 2558 else 2559 TheCondState.Ignore = false; 2560 2561 return false; 2562} 2563 2564/// ParseDirectiveEndIf 2565/// ::= .endif 2566bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { 2567 if (getLexer().isNot(AsmToken::EndOfStatement)) 2568 return TokError("unexpected token in '.endif' directive"); 2569 2570 Lex(); 2571 2572 if ((TheCondState.TheCond == AsmCond::NoCond) || 2573 TheCondStack.empty()) 2574 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 2575 ".else"); 2576 if (!TheCondStack.empty()) { 2577 TheCondState = TheCondStack.back(); 2578 TheCondStack.pop_back(); 2579 } 2580 2581 return false; 2582} 2583 2584/// ParseDirectiveFile 2585/// ::= .file [number] filename 2586/// ::= .file number directory filename 2587bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { 2588 // FIXME: I'm not sure what this is. 2589 int64_t FileNumber = -1; 2590 SMLoc FileNumberLoc = getLexer().getLoc(); 2591 if (getLexer().is(AsmToken::Integer)) { 2592 FileNumber = getTok().getIntVal(); 2593 Lex(); 2594 2595 if (FileNumber < 1) 2596 return TokError("file number less than one"); 2597 } 2598 2599 if (getLexer().isNot(AsmToken::String)) 2600 return TokError("unexpected token in '.file' directive"); 2601 2602 // Usually the directory and filename together, otherwise just the directory. 2603 StringRef Path = getTok().getString(); 2604 Path = Path.substr(1, Path.size()-2); 2605 Lex(); 2606 2607 StringRef Directory; 2608 StringRef Filename; 2609 if (getLexer().is(AsmToken::String)) { 2610 if (FileNumber == -1) 2611 return TokError("explicit path specified, but no file number"); 2612 Filename = getTok().getString(); 2613 Filename = Filename.substr(1, Filename.size()-2); 2614 Directory = Path; 2615 Lex(); 2616 } else { 2617 Filename = Path; 2618 } 2619 2620 if (getLexer().isNot(AsmToken::EndOfStatement)) 2621 return TokError("unexpected token in '.file' directive"); 2622 2623 if (FileNumber == -1) 2624 getStreamer().EmitFileDirective(Filename); 2625 else { 2626 if (getContext().getGenDwarfForAssembly() == true) 2627 Error(DirectiveLoc, "input can't have .file dwarf directives when -g is " 2628 "used to generate dwarf debug info for assembly code"); 2629 2630 if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename)) 2631 Error(FileNumberLoc, "file number already allocated"); 2632 } 2633 2634 return false; 2635} 2636 2637/// ParseDirectiveLine 2638/// ::= .line [number] 2639bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { 2640 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2641 if (getLexer().isNot(AsmToken::Integer)) 2642 return TokError("unexpected token in '.line' directive"); 2643 2644 int64_t LineNumber = getTok().getIntVal(); 2645 (void) LineNumber; 2646 Lex(); 2647 2648 // FIXME: Do something with the .line. 2649 } 2650 2651 if (getLexer().isNot(AsmToken::EndOfStatement)) 2652 return TokError("unexpected token in '.line' directive"); 2653 2654 return false; 2655} 2656 2657 2658/// ParseDirectiveLoc 2659/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] 2660/// [epilogue_begin] [is_stmt VALUE] [isa VALUE] 2661/// The first number is a file number, must have been previously assigned with 2662/// a .file directive, the second number is the line number and optionally the 2663/// third number is a column position (zero if not specified). The remaining 2664/// optional items are .loc sub-directives. 2665bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { 2666 2667 if (getLexer().isNot(AsmToken::Integer)) 2668 return TokError("unexpected token in '.loc' directive"); 2669 int64_t FileNumber = getTok().getIntVal(); 2670 if (FileNumber < 1) 2671 return TokError("file number less than one in '.loc' directive"); 2672 if (!getContext().isValidDwarfFileNumber(FileNumber)) 2673 return TokError("unassigned file number in '.loc' directive"); 2674 Lex(); 2675 2676 int64_t LineNumber = 0; 2677 if (getLexer().is(AsmToken::Integer)) { 2678 LineNumber = getTok().getIntVal(); 2679 if (LineNumber < 1) 2680 return TokError("line number less than one in '.loc' directive"); 2681 Lex(); 2682 } 2683 2684 int64_t ColumnPos = 0; 2685 if (getLexer().is(AsmToken::Integer)) { 2686 ColumnPos = getTok().getIntVal(); 2687 if (ColumnPos < 0) 2688 return TokError("column position less than zero in '.loc' directive"); 2689 Lex(); 2690 } 2691 2692 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 2693 unsigned Isa = 0; 2694 int64_t Discriminator = 0; 2695 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2696 for (;;) { 2697 if (getLexer().is(AsmToken::EndOfStatement)) 2698 break; 2699 2700 StringRef Name; 2701 SMLoc Loc = getTok().getLoc(); 2702 if (getParser().ParseIdentifier(Name)) 2703 return TokError("unexpected token in '.loc' directive"); 2704 2705 if (Name == "basic_block") 2706 Flags |= DWARF2_FLAG_BASIC_BLOCK; 2707 else if (Name == "prologue_end") 2708 Flags |= DWARF2_FLAG_PROLOGUE_END; 2709 else if (Name == "epilogue_begin") 2710 Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; 2711 else if (Name == "is_stmt") { 2712 SMLoc Loc = getTok().getLoc(); 2713 const MCExpr *Value; 2714 if (getParser().ParseExpression(Value)) 2715 return true; 2716 // The expression must be the constant 0 or 1. 2717 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2718 int Value = MCE->getValue(); 2719 if (Value == 0) 2720 Flags &= ~DWARF2_FLAG_IS_STMT; 2721 else if (Value == 1) 2722 Flags |= DWARF2_FLAG_IS_STMT; 2723 else 2724 return Error(Loc, "is_stmt value not 0 or 1"); 2725 } 2726 else { 2727 return Error(Loc, "is_stmt value not the constant value of 0 or 1"); 2728 } 2729 } 2730 else if (Name == "isa") { 2731 SMLoc Loc = getTok().getLoc(); 2732 const MCExpr *Value; 2733 if (getParser().ParseExpression(Value)) 2734 return true; 2735 // The expression must be a constant greater or equal to 0. 2736 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) { 2737 int Value = MCE->getValue(); 2738 if (Value < 0) 2739 return Error(Loc, "isa number less than zero"); 2740 Isa = Value; 2741 } 2742 else { 2743 return Error(Loc, "isa number not a constant value"); 2744 } 2745 } 2746 else if (Name == "discriminator") { 2747 if (getParser().ParseAbsoluteExpression(Discriminator)) 2748 return true; 2749 } 2750 else { 2751 return Error(Loc, "unknown sub-directive in '.loc' directive"); 2752 } 2753 2754 if (getLexer().is(AsmToken::EndOfStatement)) 2755 break; 2756 } 2757 } 2758 2759 getStreamer().EmitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags, 2760 Isa, Discriminator, StringRef()); 2761 2762 return false; 2763} 2764 2765/// ParseDirectiveStabs 2766/// ::= .stabs string, number, number, number 2767bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive, 2768 SMLoc DirectiveLoc) { 2769 return TokError("unsupported directive '" + Directive + "'"); 2770} 2771 2772/// ParseDirectiveCFISections 2773/// ::= .cfi_sections section [, section] 2774bool GenericAsmParser::ParseDirectiveCFISections(StringRef, 2775 SMLoc DirectiveLoc) { 2776 StringRef Name; 2777 bool EH = false; 2778 bool Debug = false; 2779 2780 if (getParser().ParseIdentifier(Name)) 2781 return TokError("Expected an identifier"); 2782 2783 if (Name == ".eh_frame") 2784 EH = true; 2785 else if (Name == ".debug_frame") 2786 Debug = true; 2787 2788 if (getLexer().is(AsmToken::Comma)) { 2789 Lex(); 2790 2791 if (getParser().ParseIdentifier(Name)) 2792 return TokError("Expected an identifier"); 2793 2794 if (Name == ".eh_frame") 2795 EH = true; 2796 else if (Name == ".debug_frame") 2797 Debug = true; 2798 } 2799 2800 getStreamer().EmitCFISections(EH, Debug); 2801 2802 return false; 2803} 2804 2805/// ParseDirectiveCFIStartProc 2806/// ::= .cfi_startproc 2807bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef, 2808 SMLoc DirectiveLoc) { 2809 getStreamer().EmitCFIStartProc(); 2810 return false; 2811} 2812 2813/// ParseDirectiveCFIEndProc 2814/// ::= .cfi_endproc 2815bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) { 2816 getStreamer().EmitCFIEndProc(); 2817 return false; 2818} 2819 2820/// ParseRegisterOrRegisterNumber - parse register name or number. 2821bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register, 2822 SMLoc DirectiveLoc) { 2823 unsigned RegNo; 2824 2825 if (getLexer().isNot(AsmToken::Integer)) { 2826 if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc, 2827 DirectiveLoc)) 2828 return true; 2829 Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true); 2830 } else 2831 return getParser().ParseAbsoluteExpression(Register); 2832 2833 return false; 2834} 2835 2836/// ParseDirectiveCFIDefCfa 2837/// ::= .cfi_def_cfa register, offset 2838bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef, 2839 SMLoc DirectiveLoc) { 2840 int64_t Register = 0; 2841 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2842 return true; 2843 2844 if (getLexer().isNot(AsmToken::Comma)) 2845 return TokError("unexpected token in directive"); 2846 Lex(); 2847 2848 int64_t Offset = 0; 2849 if (getParser().ParseAbsoluteExpression(Offset)) 2850 return true; 2851 2852 getStreamer().EmitCFIDefCfa(Register, Offset); 2853 return false; 2854} 2855 2856/// ParseDirectiveCFIDefCfaOffset 2857/// ::= .cfi_def_cfa_offset offset 2858bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef, 2859 SMLoc DirectiveLoc) { 2860 int64_t Offset = 0; 2861 if (getParser().ParseAbsoluteExpression(Offset)) 2862 return true; 2863 2864 getStreamer().EmitCFIDefCfaOffset(Offset); 2865 return false; 2866} 2867 2868/// ParseDirectiveCFIAdjustCfaOffset 2869/// ::= .cfi_adjust_cfa_offset adjustment 2870bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef, 2871 SMLoc DirectiveLoc) { 2872 int64_t Adjustment = 0; 2873 if (getParser().ParseAbsoluteExpression(Adjustment)) 2874 return true; 2875 2876 getStreamer().EmitCFIAdjustCfaOffset(Adjustment); 2877 return false; 2878} 2879 2880/// ParseDirectiveCFIDefCfaRegister 2881/// ::= .cfi_def_cfa_register register 2882bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef, 2883 SMLoc DirectiveLoc) { 2884 int64_t Register = 0; 2885 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2886 return true; 2887 2888 getStreamer().EmitCFIDefCfaRegister(Register); 2889 return false; 2890} 2891 2892/// ParseDirectiveCFIOffset 2893/// ::= .cfi_offset register, offset 2894bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) { 2895 int64_t Register = 0; 2896 int64_t Offset = 0; 2897 2898 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2899 return true; 2900 2901 if (getLexer().isNot(AsmToken::Comma)) 2902 return TokError("unexpected token in directive"); 2903 Lex(); 2904 2905 if (getParser().ParseAbsoluteExpression(Offset)) 2906 return true; 2907 2908 getStreamer().EmitCFIOffset(Register, Offset); 2909 return false; 2910} 2911 2912/// ParseDirectiveCFIRelOffset 2913/// ::= .cfi_rel_offset register, offset 2914bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef, 2915 SMLoc DirectiveLoc) { 2916 int64_t Register = 0; 2917 2918 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 2919 return true; 2920 2921 if (getLexer().isNot(AsmToken::Comma)) 2922 return TokError("unexpected token in directive"); 2923 Lex(); 2924 2925 int64_t Offset = 0; 2926 if (getParser().ParseAbsoluteExpression(Offset)) 2927 return true; 2928 2929 getStreamer().EmitCFIRelOffset(Register, Offset); 2930 return false; 2931} 2932 2933static bool isValidEncoding(int64_t Encoding) { 2934 if (Encoding & ~0xff) 2935 return false; 2936 2937 if (Encoding == dwarf::DW_EH_PE_omit) 2938 return true; 2939 2940 const unsigned Format = Encoding & 0xf; 2941 if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && 2942 Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && 2943 Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && 2944 Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) 2945 return false; 2946 2947 const unsigned Application = Encoding & 0x70; 2948 if (Application != dwarf::DW_EH_PE_absptr && 2949 Application != dwarf::DW_EH_PE_pcrel) 2950 return false; 2951 2952 return true; 2953} 2954 2955/// ParseDirectiveCFIPersonalityOrLsda 2956/// ::= .cfi_personality encoding, [symbol_name] 2957/// ::= .cfi_lsda encoding, [symbol_name] 2958bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal, 2959 SMLoc DirectiveLoc) { 2960 int64_t Encoding = 0; 2961 if (getParser().ParseAbsoluteExpression(Encoding)) 2962 return true; 2963 if (Encoding == dwarf::DW_EH_PE_omit) 2964 return false; 2965 2966 if (!isValidEncoding(Encoding)) 2967 return TokError("unsupported encoding."); 2968 2969 if (getLexer().isNot(AsmToken::Comma)) 2970 return TokError("unexpected token in directive"); 2971 Lex(); 2972 2973 StringRef Name; 2974 if (getParser().ParseIdentifier(Name)) 2975 return TokError("expected identifier in directive"); 2976 2977 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2978 2979 if (IDVal == ".cfi_personality") 2980 getStreamer().EmitCFIPersonality(Sym, Encoding); 2981 else { 2982 assert(IDVal == ".cfi_lsda"); 2983 getStreamer().EmitCFILsda(Sym, Encoding); 2984 } 2985 return false; 2986} 2987 2988/// ParseDirectiveCFIRememberState 2989/// ::= .cfi_remember_state 2990bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal, 2991 SMLoc DirectiveLoc) { 2992 getStreamer().EmitCFIRememberState(); 2993 return false; 2994} 2995 2996/// ParseDirectiveCFIRestoreState 2997/// ::= .cfi_remember_state 2998bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal, 2999 SMLoc DirectiveLoc) { 3000 getStreamer().EmitCFIRestoreState(); 3001 return false; 3002} 3003 3004/// ParseDirectiveCFISameValue 3005/// ::= .cfi_same_value register 3006bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal, 3007 SMLoc DirectiveLoc) { 3008 int64_t Register = 0; 3009 3010 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3011 return true; 3012 3013 getStreamer().EmitCFISameValue(Register); 3014 3015 return false; 3016} 3017 3018/// ParseDirectiveCFIRestore 3019/// ::= .cfi_restore register 3020bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal, 3021 SMLoc DirectiveLoc) { 3022 int64_t Register = 0; 3023 if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) 3024 return true; 3025 3026 getStreamer().EmitCFIRestore(Register); 3027 3028 return false; 3029} 3030 3031/// ParseDirectiveCFIEscape 3032/// ::= .cfi_escape expression[,...] 3033bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal, 3034 SMLoc DirectiveLoc) { 3035 std::string Values; 3036 int64_t CurrValue; 3037 if (getParser().ParseAbsoluteExpression(CurrValue)) 3038 return true; 3039 3040 Values.push_back((uint8_t)CurrValue); 3041 3042 while (getLexer().is(AsmToken::Comma)) { 3043 Lex(); 3044 3045 if (getParser().ParseAbsoluteExpression(CurrValue)) 3046 return true; 3047 3048 Values.push_back((uint8_t)CurrValue); 3049 } 3050 3051 getStreamer().EmitCFIEscape(Values); 3052 return false; 3053} 3054 3055/// ParseDirectiveCFISignalFrame 3056/// ::= .cfi_signal_frame 3057bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive, 3058 SMLoc DirectiveLoc) { 3059 if (getLexer().isNot(AsmToken::EndOfStatement)) 3060 return Error(getLexer().getLoc(), 3061 "unexpected token in '" + Directive + "' directive"); 3062 3063 getStreamer().EmitCFISignalFrame(); 3064 3065 return false; 3066} 3067 3068/// ParseDirectiveMacrosOnOff 3069/// ::= .macros_on 3070/// ::= .macros_off 3071bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive, 3072 SMLoc DirectiveLoc) { 3073 if (getLexer().isNot(AsmToken::EndOfStatement)) 3074 return Error(getLexer().getLoc(), 3075 "unexpected token in '" + Directive + "' directive"); 3076 3077 getParser().MacrosEnabled = Directive == ".macros_on"; 3078 3079 return false; 3080} 3081 3082/// ParseDirectiveMacro 3083/// ::= .macro name [parameters] 3084bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, 3085 SMLoc DirectiveLoc) { 3086 StringRef Name; 3087 if (getParser().ParseIdentifier(Name)) 3088 return TokError("expected identifier in '.macro' directive"); 3089 3090 MacroParameters Parameters; 3091 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3092 for (;;) { 3093 MacroParameter Parameter; 3094 if (getParser().ParseIdentifier(Parameter)) 3095 return TokError("expected identifier in '.macro' directive"); 3096 Parameters.push_back(Parameter); 3097 3098 if (getLexer().isNot(AsmToken::Comma)) 3099 break; 3100 Lex(); 3101 } 3102 } 3103 3104 if (getLexer().isNot(AsmToken::EndOfStatement)) 3105 return TokError("unexpected token in '.macro' directive"); 3106 3107 // Eat the end of statement. 3108 Lex(); 3109 3110 AsmToken EndToken, StartToken = getTok(); 3111 3112 // Lex the macro definition. 3113 for (;;) { 3114 // Check whether we have reached the end of the file. 3115 if (getLexer().is(AsmToken::Eof)) 3116 return Error(DirectiveLoc, "no matching '.endmacro' in definition"); 3117 3118 // Otherwise, check whether we have reach the .endmacro. 3119 if (getLexer().is(AsmToken::Identifier) && 3120 (getTok().getIdentifier() == ".endm" || 3121 getTok().getIdentifier() == ".endmacro")) { 3122 EndToken = getTok(); 3123 Lex(); 3124 if (getLexer().isNot(AsmToken::EndOfStatement)) 3125 return TokError("unexpected token in '" + EndToken.getIdentifier() + 3126 "' directive"); 3127 break; 3128 } 3129 3130 // Otherwise, scan til the end of the statement. 3131 getParser().EatToEndOfStatement(); 3132 } 3133 3134 if (getParser().MacroMap.lookup(Name)) { 3135 return Error(DirectiveLoc, "macro '" + Name + "' is already defined"); 3136 } 3137 3138 const char *BodyStart = StartToken.getLoc().getPointer(); 3139 const char *BodyEnd = EndToken.getLoc().getPointer(); 3140 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3141 getParser().MacroMap[Name] = new Macro(Name, Body, Parameters); 3142 return false; 3143} 3144 3145/// ParseDirectiveEndMacro 3146/// ::= .endm 3147/// ::= .endmacro 3148bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive, 3149 SMLoc DirectiveLoc) { 3150 if (getLexer().isNot(AsmToken::EndOfStatement)) 3151 return TokError("unexpected token in '" + Directive + "' directive"); 3152 3153 // If we are inside a macro instantiation, terminate the current 3154 // instantiation. 3155 if (!getParser().ActiveMacros.empty()) { 3156 getParser().HandleMacroExit(); 3157 return false; 3158 } 3159 3160 // Otherwise, this .endmacro is a stray entry in the file; well formed 3161 // .endmacro directives are handled during the macro definition parsing. 3162 return TokError("unexpected '" + Directive + "' in file, " 3163 "no current macro definition"); 3164} 3165 3166/// ParseDirectivePurgeMacro 3167/// ::= .purgem 3168bool GenericAsmParser::ParseDirectivePurgeMacro(StringRef Directive, 3169 SMLoc DirectiveLoc) { 3170 StringRef Name; 3171 if (getParser().ParseIdentifier(Name)) 3172 return TokError("expected identifier in '.purgem' directive"); 3173 3174 if (getLexer().isNot(AsmToken::EndOfStatement)) 3175 return TokError("unexpected token in '.purgem' directive"); 3176 3177 StringMap<Macro*>::iterator I = getParser().MacroMap.find(Name); 3178 if (I == getParser().MacroMap.end()) 3179 return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); 3180 3181 // Undefine the macro. 3182 delete I->getValue(); 3183 getParser().MacroMap.erase(I); 3184 return false; 3185} 3186 3187bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) { 3188 getParser().CheckForValidSection(); 3189 3190 const MCExpr *Value; 3191 3192 if (getParser().ParseExpression(Value)) 3193 return true; 3194 3195 if (getLexer().isNot(AsmToken::EndOfStatement)) 3196 return TokError("unexpected token in directive"); 3197 3198 if (DirName[1] == 's') 3199 getStreamer().EmitSLEB128Value(Value); 3200 else 3201 getStreamer().EmitULEB128Value(Value); 3202 3203 return false; 3204} 3205 3206Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { 3207 AsmToken EndToken, StartToken = getTok(); 3208 3209 unsigned NestLevel = 0; 3210 for (;;) { 3211 // Check whether we have reached the end of the file. 3212 if (getLexer().is(AsmToken::Eof)) { 3213 Error(DirectiveLoc, "no matching '.endr' in definition"); 3214 return 0; 3215 } 3216 3217 if (Lexer.is(AsmToken::Identifier) && 3218 (getTok().getIdentifier() == ".rept")) { 3219 ++NestLevel; 3220 } 3221 3222 // Otherwise, check whether we have reached the .endr. 3223 if (Lexer.is(AsmToken::Identifier) && 3224 getTok().getIdentifier() == ".endr") { 3225 if (NestLevel == 0) { 3226 EndToken = getTok(); 3227 Lex(); 3228 if (Lexer.isNot(AsmToken::EndOfStatement)) { 3229 TokError("unexpected token in '.endr' directive"); 3230 return 0; 3231 } 3232 break; 3233 } 3234 --NestLevel; 3235 } 3236 3237 // Otherwise, scan till the end of the statement. 3238 EatToEndOfStatement(); 3239 } 3240 3241 const char *BodyStart = StartToken.getLoc().getPointer(); 3242 const char *BodyEnd = EndToken.getLoc().getPointer(); 3243 StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); 3244 3245 // We Are Anonymous. 3246 StringRef Name; 3247 MacroParameters Parameters; 3248 return new Macro(Name, Body, Parameters); 3249} 3250 3251void AsmParser::InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc, 3252 raw_svector_ostream &OS) { 3253 OS << ".endr\n"; 3254 3255 MemoryBuffer *Instantiation = 3256 MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); 3257 3258 // Create the macro instantiation object and add to the current macro 3259 // instantiation stack. 3260 MacroInstantiation *MI = new MacroInstantiation(M, DirectiveLoc, 3261 getTok().getLoc(), 3262 Instantiation); 3263 ActiveMacros.push_back(MI); 3264 3265 // Jump to the macro instantiation and prime the lexer. 3266 CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); 3267 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 3268 Lex(); 3269} 3270 3271bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { 3272 int64_t Count; 3273 if (ParseAbsoluteExpression(Count)) 3274 return TokError("unexpected token in '.rept' directive"); 3275 3276 if (Count < 0) 3277 return TokError("Count is negative"); 3278 3279 if (Lexer.isNot(AsmToken::EndOfStatement)) 3280 return TokError("unexpected token in '.rept' directive"); 3281 3282 // Eat the end of statement. 3283 Lex(); 3284 3285 // Lex the rept definition. 3286 Macro *M = ParseMacroLikeBody(DirectiveLoc); 3287 if (!M) 3288 return true; 3289 3290 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3291 // to hold the macro body with substitutions. 3292 SmallString<256> Buf; 3293 MacroParameters Parameters; 3294 MacroArguments A; 3295 raw_svector_ostream OS(Buf); 3296 while (Count--) { 3297 if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc())) 3298 return true; 3299 } 3300 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3301 3302 return false; 3303} 3304 3305/// ParseDirectiveIrp 3306/// ::= .irp symbol,values 3307bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { 3308 MacroParameters Parameters; 3309 MacroParameter Parameter; 3310 3311 if (ParseIdentifier(Parameter)) 3312 return TokError("expected identifier in '.irp' directive"); 3313 3314 Parameters.push_back(Parameter); 3315 3316 if (Lexer.isNot(AsmToken::Comma)) 3317 return TokError("expected comma in '.irp' directive"); 3318 3319 Lex(); 3320 3321 MacroArguments A; 3322 if (ParseMacroArguments(0, A)) 3323 return true; 3324 3325 // Eat the end of statement. 3326 Lex(); 3327 3328 // Lex the irp definition. 3329 Macro *M = ParseMacroLikeBody(DirectiveLoc); 3330 if (!M) 3331 return true; 3332 3333 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3334 // to hold the macro body with substitutions. 3335 SmallString<256> Buf; 3336 raw_svector_ostream OS(Buf); 3337 3338 for (MacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { 3339 MacroArguments Args; 3340 Args.push_back(*i); 3341 3342 if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) 3343 return true; 3344 } 3345 3346 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3347 3348 return false; 3349} 3350 3351/// ParseDirectiveIrpc 3352/// ::= .irpc symbol,values 3353bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { 3354 MacroParameters Parameters; 3355 MacroParameter Parameter; 3356 3357 if (ParseIdentifier(Parameter)) 3358 return TokError("expected identifier in '.irpc' directive"); 3359 3360 Parameters.push_back(Parameter); 3361 3362 if (Lexer.isNot(AsmToken::Comma)) 3363 return TokError("expected comma in '.irpc' directive"); 3364 3365 Lex(); 3366 3367 MacroArguments A; 3368 if (ParseMacroArguments(0, A)) 3369 return true; 3370 3371 if (A.size() != 1 || A.front().size() != 1) 3372 return TokError("unexpected token in '.irpc' directive"); 3373 3374 // Eat the end of statement. 3375 Lex(); 3376 3377 // Lex the irpc definition. 3378 Macro *M = ParseMacroLikeBody(DirectiveLoc); 3379 if (!M) 3380 return true; 3381 3382 // Macro instantiation is lexical, unfortunately. We construct a new buffer 3383 // to hold the macro body with substitutions. 3384 SmallString<256> Buf; 3385 raw_svector_ostream OS(Buf); 3386 3387 StringRef Values = A.front().front().getString(); 3388 std::size_t I, End = Values.size(); 3389 for (I = 0; I < End; ++I) { 3390 MacroArgument Arg; 3391 Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1))); 3392 3393 MacroArguments Args; 3394 Args.push_back(Arg); 3395 3396 if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) 3397 return true; 3398 } 3399 3400 InstantiateMacroLikeBody(M, DirectiveLoc, OS); 3401 3402 return false; 3403} 3404 3405bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { 3406 if (ActiveMacros.empty()) 3407 return TokError("unexpected '.endr' directive, no current .rept"); 3408 3409 // The only .repl that should get here are the ones created by 3410 // InstantiateMacroLikeBody. 3411 assert(getLexer().is(AsmToken::EndOfStatement)); 3412 3413 HandleMacroExit(); 3414 return false; 3415} 3416 3417/// \brief Create an MCAsmParser instance. 3418MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, 3419 MCContext &C, MCStreamer &Out, 3420 const MCAsmInfo &MAI) { 3421 return new AsmParser(SM, C, Out, MAI); 3422} 3423