AsmParser.cpp revision 206274
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/MC/MCParser/AsmParser.h" 15#include "llvm/ADT/SmallString.h" 16#include "llvm/ADT/Twine.h" 17#include "llvm/MC/MCContext.h" 18#include "llvm/MC/MCExpr.h" 19#include "llvm/MC/MCInst.h" 20#include "llvm/MC/MCSectionMachO.h" 21#include "llvm/MC/MCStreamer.h" 22#include "llvm/MC/MCSymbol.h" 23#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 24#include "llvm/Support/Compiler.h" 25#include "llvm/Support/SourceMgr.h" 26#include "llvm/Support/raw_ostream.h" 27#include "llvm/Target/TargetAsmParser.h" 28using namespace llvm; 29 30 31enum { DEFAULT_ADDRSPACE = 0 }; 32 33// Mach-O section uniquing. 34// 35// FIXME: Figure out where this should live, it should be shared by 36// TargetLoweringObjectFile. 37typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy; 38 39AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, 40 const MCAsmInfo &_MAI) 41 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), TargetParser(0), 42 CurBuffer(0), SectionUniquingMap(0) { 43 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 44 45 // Debugging directives. 46 AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile); 47 AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine); 48 AddDirectiveHandler(".loc", &AsmParser::ParseDirectiveLoc); 49} 50 51 52 53AsmParser::~AsmParser() { 54 // If we have the MachO uniquing map, free it. 55 delete (MachOUniqueMapTy*)SectionUniquingMap; 56} 57 58const MCSection *AsmParser::getMachOSection(const StringRef &Segment, 59 const StringRef &Section, 60 unsigned TypeAndAttributes, 61 unsigned Reserved2, 62 SectionKind Kind) const { 63 // We unique sections by their segment/section pair. The returned section 64 // may not have the same flags as the requested section, if so this should be 65 // diagnosed by the client as an error. 66 67 // Create the map if it doesn't already exist. 68 if (SectionUniquingMap == 0) 69 SectionUniquingMap = new MachOUniqueMapTy(); 70 MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)SectionUniquingMap; 71 72 // Form the name to look up. 73 SmallString<64> Name; 74 Name += Segment; 75 Name.push_back(','); 76 Name += Section; 77 78 // Do the lookup, if we have a hit, return it. 79 const MCSectionMachO *&Entry = Map[Name.str()]; 80 81 // FIXME: This should validate the type and attributes. 82 if (Entry) return Entry; 83 84 // Otherwise, return a new section. 85 return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes, 86 Reserved2, Kind, Ctx); 87} 88 89void AsmParser::Warning(SMLoc L, const Twine &Msg) { 90 PrintMessage(L, Msg.str(), "warning"); 91} 92 93bool AsmParser::Error(SMLoc L, const Twine &Msg) { 94 PrintMessage(L, Msg.str(), "error"); 95 return true; 96} 97 98bool AsmParser::TokError(const char *Msg) { 99 PrintMessage(Lexer.getLoc(), Msg, "error"); 100 return true; 101} 102 103void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg, 104 const char *Type) const { 105 SrcMgr.PrintMessage(Loc, Msg, Type); 106} 107 108bool AsmParser::EnterIncludeFile(const std::string &Filename) { 109 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc()); 110 if (NewBuf == -1) 111 return true; 112 113 CurBuffer = NewBuf; 114 115 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 116 117 return false; 118} 119 120const AsmToken &AsmParser::Lex() { 121 const AsmToken *tok = &Lexer.Lex(); 122 123 if (tok->is(AsmToken::Eof)) { 124 // If this is the end of an included file, pop the parent file off the 125 // include stack. 126 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); 127 if (ParentIncludeLoc != SMLoc()) { 128 CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); 129 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), 130 ParentIncludeLoc.getPointer()); 131 tok = &Lexer.Lex(); 132 } 133 } 134 135 if (tok->is(AsmToken::Error)) 136 PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error"); 137 138 return *tok; 139} 140 141bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { 142 // Create the initial section, if requested. 143 // 144 // FIXME: Target hook & command line option for initial section. 145 if (!NoInitialTextSection) 146 Out.SwitchSection(getMachOSection("__TEXT", "__text", 147 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 148 0, SectionKind::getText())); 149 150 // Prime the lexer. 151 Lex(); 152 153 bool HadError = false; 154 155 AsmCond StartingCondState = TheCondState; 156 157 // While we have input, parse each statement. 158 while (Lexer.isNot(AsmToken::Eof)) { 159 // Handle conditional assembly here before calling ParseStatement() 160 if (Lexer.getKind() == AsmToken::Identifier) { 161 // If we have an identifier, handle it as the key symbol. 162 AsmToken ID = getTok(); 163 SMLoc IDLoc = ID.getLoc(); 164 StringRef IDVal = ID.getString(); 165 166 if (IDVal == ".if" || 167 IDVal == ".elseif" || 168 IDVal == ".else" || 169 IDVal == ".endif") { 170 if (!ParseConditionalAssemblyDirectives(IDVal, IDLoc)) 171 continue; 172 HadError = true; 173 EatToEndOfStatement(); 174 continue; 175 } 176 } 177 if (TheCondState.Ignore) { 178 EatToEndOfStatement(); 179 continue; 180 } 181 182 if (!ParseStatement()) continue; 183 184 // We had an error, remember it and recover by skipping to the next line. 185 HadError = true; 186 EatToEndOfStatement(); 187 } 188 189 if (TheCondState.TheCond != StartingCondState.TheCond || 190 TheCondState.Ignore != StartingCondState.Ignore) 191 return TokError("unmatched .ifs or .elses"); 192 193 // Finalize the output stream if there are no errors and if the client wants 194 // us to. 195 if (!HadError && !NoFinalize) 196 Out.Finish(); 197 198 return HadError; 199} 200 201/// ParseConditionalAssemblyDirectives - parse the conditional assembly 202/// directives 203bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive, 204 SMLoc DirectiveLoc) { 205 if (Directive == ".if") 206 return ParseDirectiveIf(DirectiveLoc); 207 if (Directive == ".elseif") 208 return ParseDirectiveElseIf(DirectiveLoc); 209 if (Directive == ".else") 210 return ParseDirectiveElse(DirectiveLoc); 211 if (Directive == ".endif") 212 return ParseDirectiveEndIf(DirectiveLoc); 213 return true; 214} 215 216/// EatToEndOfStatement - Throw away the rest of the line for testing purposes. 217void AsmParser::EatToEndOfStatement() { 218 while (Lexer.isNot(AsmToken::EndOfStatement) && 219 Lexer.isNot(AsmToken::Eof)) 220 Lex(); 221 222 // Eat EOL. 223 if (Lexer.is(AsmToken::EndOfStatement)) 224 Lex(); 225} 226 227 228/// ParseParenExpr - Parse a paren expression and return it. 229/// NOTE: This assumes the leading '(' has already been consumed. 230/// 231/// parenexpr ::= expr) 232/// 233bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { 234 if (ParseExpression(Res)) return true; 235 if (Lexer.isNot(AsmToken::RParen)) 236 return TokError("expected ')' in parentheses expression"); 237 EndLoc = Lexer.getLoc(); 238 Lex(); 239 return false; 240} 241 242MCSymbol *AsmParser::CreateSymbol(StringRef Name) { 243 // FIXME: Inline into callers. 244 return Ctx.GetOrCreateSymbol(Name); 245} 246 247/// ParsePrimaryExpr - Parse a primary expression and return it. 248/// primaryexpr ::= (parenexpr 249/// primaryexpr ::= symbol 250/// primaryexpr ::= number 251/// primaryexpr ::= ~,+,- primaryexpr 252bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { 253 switch (Lexer.getKind()) { 254 default: 255 return TokError("unknown token in expression"); 256 case AsmToken::Exclaim: 257 Lex(); // Eat the operator. 258 if (ParsePrimaryExpr(Res, EndLoc)) 259 return true; 260 Res = MCUnaryExpr::CreateLNot(Res, getContext()); 261 return false; 262 case AsmToken::String: 263 case AsmToken::Identifier: { 264 // This is a symbol reference. 265 std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@'); 266 MCSymbol *Sym = CreateSymbol(Split.first); 267 268 // Lookup the symbol variant if used. 269 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 270 if (Split.first.size() != getTok().getIdentifier().size()) 271 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); 272 273 EndLoc = Lexer.getLoc(); 274 Lex(); // Eat identifier. 275 276 // If this is an absolute variable reference, substitute it now to preserve 277 // semantics in the face of reassignment. 278 if (Sym->getValue() && isa<MCConstantExpr>(Sym->getValue())) { 279 if (Variant) 280 return Error(EndLoc, "unexpected modified on variable reference"); 281 282 Res = Sym->getValue(); 283 return false; 284 } 285 286 // Otherwise create a symbol ref. 287 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); 288 return false; 289 } 290 case AsmToken::Integer: 291 Res = MCConstantExpr::Create(getTok().getIntVal(), getContext()); 292 EndLoc = Lexer.getLoc(); 293 Lex(); // Eat token. 294 return false; 295 case AsmToken::LParen: 296 Lex(); // Eat the '('. 297 return ParseParenExpr(Res, EndLoc); 298 case AsmToken::Minus: 299 Lex(); // Eat the operator. 300 if (ParsePrimaryExpr(Res, EndLoc)) 301 return true; 302 Res = MCUnaryExpr::CreateMinus(Res, getContext()); 303 return false; 304 case AsmToken::Plus: 305 Lex(); // Eat the operator. 306 if (ParsePrimaryExpr(Res, EndLoc)) 307 return true; 308 Res = MCUnaryExpr::CreatePlus(Res, getContext()); 309 return false; 310 case AsmToken::Tilde: 311 Lex(); // Eat the operator. 312 if (ParsePrimaryExpr(Res, EndLoc)) 313 return true; 314 Res = MCUnaryExpr::CreateNot(Res, getContext()); 315 return false; 316 } 317} 318 319bool AsmParser::ParseExpression(const MCExpr *&Res) { 320 SMLoc EndLoc; 321 return ParseExpression(Res, EndLoc); 322} 323 324/// ParseExpression - Parse an expression and return it. 325/// 326/// expr ::= expr +,- expr -> lowest. 327/// expr ::= expr |,^,&,! expr -> middle. 328/// expr ::= expr *,/,%,<<,>> expr -> highest. 329/// expr ::= primaryexpr 330/// 331bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { 332 // Parse the expression. 333 Res = 0; 334 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) 335 return true; 336 337 // Try to constant fold it up front, if possible. 338 int64_t Value; 339 if (Res->EvaluateAsAbsolute(Value)) 340 Res = MCConstantExpr::Create(Value, getContext()); 341 342 return false; 343} 344 345bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { 346 Res = 0; 347 return ParseParenExpr(Res, EndLoc) || 348 ParseBinOpRHS(1, Res, EndLoc); 349} 350 351bool AsmParser::ParseAbsoluteExpression(int64_t &Res) { 352 const MCExpr *Expr; 353 354 SMLoc StartLoc = Lexer.getLoc(); 355 if (ParseExpression(Expr)) 356 return true; 357 358 if (!Expr->EvaluateAsAbsolute(Res)) 359 return Error(StartLoc, "expected absolute expression"); 360 361 return false; 362} 363 364static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 365 MCBinaryExpr::Opcode &Kind) { 366 switch (K) { 367 default: 368 return 0; // not a binop. 369 370 // Lowest Precedence: &&, || 371 case AsmToken::AmpAmp: 372 Kind = MCBinaryExpr::LAnd; 373 return 1; 374 case AsmToken::PipePipe: 375 Kind = MCBinaryExpr::LOr; 376 return 1; 377 378 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >= 379 case AsmToken::Plus: 380 Kind = MCBinaryExpr::Add; 381 return 2; 382 case AsmToken::Minus: 383 Kind = MCBinaryExpr::Sub; 384 return 2; 385 case AsmToken::EqualEqual: 386 Kind = MCBinaryExpr::EQ; 387 return 2; 388 case AsmToken::ExclaimEqual: 389 case AsmToken::LessGreater: 390 Kind = MCBinaryExpr::NE; 391 return 2; 392 case AsmToken::Less: 393 Kind = MCBinaryExpr::LT; 394 return 2; 395 case AsmToken::LessEqual: 396 Kind = MCBinaryExpr::LTE; 397 return 2; 398 case AsmToken::Greater: 399 Kind = MCBinaryExpr::GT; 400 return 2; 401 case AsmToken::GreaterEqual: 402 Kind = MCBinaryExpr::GTE; 403 return 2; 404 405 // Intermediate Precedence: |, &, ^ 406 // 407 // FIXME: gas seems to support '!' as an infix operator? 408 case AsmToken::Pipe: 409 Kind = MCBinaryExpr::Or; 410 return 3; 411 case AsmToken::Caret: 412 Kind = MCBinaryExpr::Xor; 413 return 3; 414 case AsmToken::Amp: 415 Kind = MCBinaryExpr::And; 416 return 3; 417 418 // Highest Precedence: *, /, %, <<, >> 419 case AsmToken::Star: 420 Kind = MCBinaryExpr::Mul; 421 return 4; 422 case AsmToken::Slash: 423 Kind = MCBinaryExpr::Div; 424 return 4; 425 case AsmToken::Percent: 426 Kind = MCBinaryExpr::Mod; 427 return 4; 428 case AsmToken::LessLess: 429 Kind = MCBinaryExpr::Shl; 430 return 4; 431 case AsmToken::GreaterGreater: 432 Kind = MCBinaryExpr::Shr; 433 return 4; 434 } 435} 436 437 438/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. 439/// Res contains the LHS of the expression on input. 440bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, 441 SMLoc &EndLoc) { 442 while (1) { 443 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; 444 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); 445 446 // If the next token is lower precedence than we are allowed to eat, return 447 // successfully with what we ate already. 448 if (TokPrec < Precedence) 449 return false; 450 451 Lex(); 452 453 // Eat the next primary expression. 454 const MCExpr *RHS; 455 if (ParsePrimaryExpr(RHS, EndLoc)) return true; 456 457 // If BinOp binds less tightly with RHS than the operator after RHS, let 458 // the pending operator take RHS as its LHS. 459 MCBinaryExpr::Opcode Dummy; 460 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); 461 if (TokPrec < NextTokPrec) { 462 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true; 463 } 464 465 // Merge LHS and RHS according to operator. 466 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); 467 } 468} 469 470 471 472 473/// ParseStatement: 474/// ::= EndOfStatement 475/// ::= Label* Directive ...Operands... EndOfStatement 476/// ::= Label* Identifier OperandList* EndOfStatement 477bool AsmParser::ParseStatement() { 478 if (Lexer.is(AsmToken::EndOfStatement)) { 479 Lex(); 480 return false; 481 } 482 483 // Statements always start with an identifier. 484 AsmToken ID = getTok(); 485 SMLoc IDLoc = ID.getLoc(); 486 StringRef IDVal; 487 if (ParseIdentifier(IDVal)) 488 return TokError("unexpected token at start of statement"); 489 490 // FIXME: Recurse on local labels? 491 492 // See what kind of statement we have. 493 switch (Lexer.getKind()) { 494 case AsmToken::Colon: { 495 // identifier ':' -> Label. 496 Lex(); 497 498 // Diagnose attempt to use a variable as a label. 499 // 500 // FIXME: Diagnostics. Note the location of the definition as a label. 501 // FIXME: This doesn't diagnose assignment to a symbol which has been 502 // implicitly marked as external. 503 MCSymbol *Sym = CreateSymbol(IDVal); 504 if (!Sym->isUndefined()) 505 return Error(IDLoc, "invalid symbol redefinition"); 506 507 // Emit the label. 508 Out.EmitLabel(Sym); 509 510 return ParseStatement(); 511 } 512 513 case AsmToken::Equal: 514 // identifier '=' ... -> assignment statement 515 Lex(); 516 517 return ParseAssignment(IDVal); 518 519 default: // Normal instruction or directive. 520 break; 521 } 522 523 // Otherwise, we have a normal instruction or directive. 524 if (IDVal[0] == '.') { 525 // FIXME: This should be driven based on a hash lookup and callback. 526 if (IDVal == ".section") 527 return ParseDirectiveDarwinSection(); 528 if (IDVal == ".text") 529 // FIXME: This changes behavior based on the -static flag to the 530 // assembler. 531 return ParseDirectiveSectionSwitch("__TEXT", "__text", 532 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); 533 if (IDVal == ".const") 534 return ParseDirectiveSectionSwitch("__TEXT", "__const"); 535 if (IDVal == ".static_const") 536 return ParseDirectiveSectionSwitch("__TEXT", "__static_const"); 537 if (IDVal == ".cstring") 538 return ParseDirectiveSectionSwitch("__TEXT","__cstring", 539 MCSectionMachO::S_CSTRING_LITERALS); 540 if (IDVal == ".literal4") 541 return ParseDirectiveSectionSwitch("__TEXT", "__literal4", 542 MCSectionMachO::S_4BYTE_LITERALS, 543 4); 544 if (IDVal == ".literal8") 545 return ParseDirectiveSectionSwitch("__TEXT", "__literal8", 546 MCSectionMachO::S_8BYTE_LITERALS, 547 8); 548 if (IDVal == ".literal16") 549 return ParseDirectiveSectionSwitch("__TEXT","__literal16", 550 MCSectionMachO::S_16BYTE_LITERALS, 551 16); 552 if (IDVal == ".constructor") 553 return ParseDirectiveSectionSwitch("__TEXT","__constructor"); 554 if (IDVal == ".destructor") 555 return ParseDirectiveSectionSwitch("__TEXT","__destructor"); 556 if (IDVal == ".fvmlib_init0") 557 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0"); 558 if (IDVal == ".fvmlib_init1") 559 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1"); 560 561 // FIXME: The assembler manual claims that this has the self modify code 562 // flag, at least on x86-32, but that does not appear to be correct. 563 if (IDVal == ".symbol_stub") 564 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub", 565 MCSectionMachO::S_SYMBOL_STUBS | 566 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 567 // FIXME: Different on PPC and ARM. 568 0, 16); 569 // FIXME: PowerPC only? 570 if (IDVal == ".picsymbol_stub") 571 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub", 572 MCSectionMachO::S_SYMBOL_STUBS | 573 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 574 0, 26); 575 if (IDVal == ".data") 576 return ParseDirectiveSectionSwitch("__DATA", "__data"); 577 if (IDVal == ".static_data") 578 return ParseDirectiveSectionSwitch("__DATA", "__static_data"); 579 580 // FIXME: The section names of these two are misspelled in the assembler 581 // manual. 582 if (IDVal == ".non_lazy_symbol_pointer") 583 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr", 584 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 585 4); 586 if (IDVal == ".lazy_symbol_pointer") 587 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr", 588 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 589 4); 590 591 if (IDVal == ".dyld") 592 return ParseDirectiveSectionSwitch("__DATA", "__dyld"); 593 if (IDVal == ".mod_init_func") 594 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func", 595 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 596 4); 597 if (IDVal == ".mod_term_func") 598 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func", 599 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 600 4); 601 if (IDVal == ".const_data") 602 return ParseDirectiveSectionSwitch("__DATA", "__const"); 603 604 605 if (IDVal == ".objc_class") 606 return ParseDirectiveSectionSwitch("__OBJC", "__class", 607 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 608 if (IDVal == ".objc_meta_class") 609 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class", 610 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 611 if (IDVal == ".objc_cat_cls_meth") 612 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth", 613 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 614 if (IDVal == ".objc_cat_inst_meth") 615 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth", 616 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 617 if (IDVal == ".objc_protocol") 618 return ParseDirectiveSectionSwitch("__OBJC", "__protocol", 619 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 620 if (IDVal == ".objc_string_object") 621 return ParseDirectiveSectionSwitch("__OBJC", "__string_object", 622 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 623 if (IDVal == ".objc_cls_meth") 624 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth", 625 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 626 if (IDVal == ".objc_inst_meth") 627 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth", 628 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 629 if (IDVal == ".objc_cls_refs") 630 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs", 631 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 632 MCSectionMachO::S_LITERAL_POINTERS, 633 4); 634 if (IDVal == ".objc_message_refs") 635 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs", 636 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 637 MCSectionMachO::S_LITERAL_POINTERS, 638 4); 639 if (IDVal == ".objc_symbols") 640 return ParseDirectiveSectionSwitch("__OBJC", "__symbols", 641 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 642 if (IDVal == ".objc_category") 643 return ParseDirectiveSectionSwitch("__OBJC", "__category", 644 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 645 if (IDVal == ".objc_class_vars") 646 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars", 647 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 648 if (IDVal == ".objc_instance_vars") 649 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars", 650 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 651 if (IDVal == ".objc_module_info") 652 return ParseDirectiveSectionSwitch("__OBJC", "__module_info", 653 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 654 if (IDVal == ".objc_class_names") 655 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 656 MCSectionMachO::S_CSTRING_LITERALS); 657 if (IDVal == ".objc_meth_var_types") 658 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 659 MCSectionMachO::S_CSTRING_LITERALS); 660 if (IDVal == ".objc_meth_var_names") 661 return ParseDirectiveSectionSwitch("__TEXT", "__cstring", 662 MCSectionMachO::S_CSTRING_LITERALS); 663 if (IDVal == ".objc_selector_strs") 664 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs", 665 MCSectionMachO::S_CSTRING_LITERALS); 666 667 // Assembler features 668 if (IDVal == ".set") 669 return ParseDirectiveSet(); 670 671 // Data directives 672 673 if (IDVal == ".ascii") 674 return ParseDirectiveAscii(false); 675 if (IDVal == ".asciz") 676 return ParseDirectiveAscii(true); 677 678 if (IDVal == ".byte") 679 return ParseDirectiveValue(1); 680 if (IDVal == ".short") 681 return ParseDirectiveValue(2); 682 if (IDVal == ".long") 683 return ParseDirectiveValue(4); 684 if (IDVal == ".quad") 685 return ParseDirectiveValue(8); 686 687 // FIXME: Target hooks for IsPow2. 688 if (IDVal == ".align") 689 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 690 if (IDVal == ".align32") 691 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 692 if (IDVal == ".balign") 693 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); 694 if (IDVal == ".balignw") 695 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); 696 if (IDVal == ".balignl") 697 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); 698 if (IDVal == ".p2align") 699 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); 700 if (IDVal == ".p2alignw") 701 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); 702 if (IDVal == ".p2alignl") 703 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); 704 705 if (IDVal == ".org") 706 return ParseDirectiveOrg(); 707 708 if (IDVal == ".fill") 709 return ParseDirectiveFill(); 710 if (IDVal == ".space") 711 return ParseDirectiveSpace(); 712 713 // Symbol attribute directives 714 715 if (IDVal == ".globl" || IDVal == ".global") 716 return ParseDirectiveSymbolAttribute(MCSA_Global); 717 if (IDVal == ".hidden") 718 return ParseDirectiveSymbolAttribute(MCSA_Hidden); 719 if (IDVal == ".indirect_symbol") 720 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); 721 if (IDVal == ".internal") 722 return ParseDirectiveSymbolAttribute(MCSA_Internal); 723 if (IDVal == ".lazy_reference") 724 return ParseDirectiveSymbolAttribute(MCSA_LazyReference); 725 if (IDVal == ".no_dead_strip") 726 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); 727 if (IDVal == ".private_extern") 728 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); 729 if (IDVal == ".protected") 730 return ParseDirectiveSymbolAttribute(MCSA_Protected); 731 if (IDVal == ".reference") 732 return ParseDirectiveSymbolAttribute(MCSA_Reference); 733 if (IDVal == ".weak") 734 return ParseDirectiveSymbolAttribute(MCSA_Weak); 735 if (IDVal == ".weak_definition") 736 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); 737 if (IDVal == ".weak_reference") 738 return ParseDirectiveSymbolAttribute(MCSA_WeakReference); 739 740 if (IDVal == ".comm") 741 return ParseDirectiveComm(/*IsLocal=*/false); 742 if (IDVal == ".lcomm") 743 return ParseDirectiveComm(/*IsLocal=*/true); 744 if (IDVal == ".zerofill") 745 return ParseDirectiveDarwinZerofill(); 746 if (IDVal == ".desc") 747 return ParseDirectiveDarwinSymbolDesc(); 748 if (IDVal == ".lsym") 749 return ParseDirectiveDarwinLsym(); 750 751 if (IDVal == ".subsections_via_symbols") 752 return ParseDirectiveDarwinSubsectionsViaSymbols(); 753 if (IDVal == ".abort") 754 return ParseDirectiveAbort(); 755 if (IDVal == ".include") 756 return ParseDirectiveInclude(); 757 if (IDVal == ".dump") 758 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true); 759 if (IDVal == ".load") 760 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false); 761 762 // Look up the handler in the handler table, 763 bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal]; 764 if (Handler) 765 return (this->*Handler)(IDVal, IDLoc); 766 767 // Target hook for parsing target specific directives. 768 if (!getTargetParser().ParseDirective(ID)) 769 return false; 770 771 Warning(IDLoc, "ignoring directive for now"); 772 EatToEndOfStatement(); 773 return false; 774 } 775 776 777 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; 778 if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands)) 779 // FIXME: Leaking ParsedOperands on failure. 780 return true; 781 782 if (Lexer.isNot(AsmToken::EndOfStatement)) 783 // FIXME: Leaking ParsedOperands on failure. 784 return TokError("unexpected token in argument list"); 785 786 // Eat the end of statement marker. 787 Lex(); 788 789 790 MCInst Inst; 791 792 bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst); 793 794 // Free any parsed operands. 795 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) 796 delete ParsedOperands[i]; 797 798 if (MatchFail) { 799 // FIXME: We should give nicer diagnostics about the exact failure. 800 Error(IDLoc, "unrecognized instruction"); 801 return true; 802 } 803 804 // Instruction is good, process it. 805 Out.EmitInstruction(Inst); 806 807 // Skip to end of line for now. 808 return false; 809} 810 811bool AsmParser::ParseAssignment(const StringRef &Name) { 812 // FIXME: Use better location, we should use proper tokens. 813 SMLoc EqualLoc = Lexer.getLoc(); 814 815 const MCExpr *Value; 816 SMLoc StartLoc = Lexer.getLoc(); 817 if (ParseExpression(Value)) 818 return true; 819 820 if (Lexer.isNot(AsmToken::EndOfStatement)) 821 return TokError("unexpected token in assignment"); 822 823 // Eat the end of statement marker. 824 Lex(); 825 826 // Validate that the LHS is allowed to be a variable (either it has not been 827 // used as a symbol, or it is an absolute symbol). 828 MCSymbol *Sym = getContext().LookupSymbol(Name); 829 if (Sym) { 830 // Diagnose assignment to a label. 831 // 832 // FIXME: Diagnostics. Note the location of the definition as a label. 833 // FIXME: Diagnose assignment to protected identifier (e.g., register name). 834 if (!Sym->isUndefined() && !Sym->isAbsolute()) 835 return Error(EqualLoc, "redefinition of '" + Name + "'"); 836 else if (!Sym->isVariable()) 837 return Error(EqualLoc, "invalid assignment to '" + Name + "'"); 838 else if (!isa<MCConstantExpr>(Sym->getValue())) 839 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + 840 Name + "'"); 841 } else 842 Sym = CreateSymbol(Name); 843 844 // FIXME: Handle '.'. 845 846 // Do the assignment. 847 Out.EmitAssignment(Sym, Value); 848 849 return false; 850} 851 852/// ParseIdentifier: 853/// ::= identifier 854/// ::= string 855bool AsmParser::ParseIdentifier(StringRef &Res) { 856 if (Lexer.isNot(AsmToken::Identifier) && 857 Lexer.isNot(AsmToken::String)) 858 return true; 859 860 Res = getTok().getIdentifier(); 861 862 Lex(); // Consume the identifier token. 863 864 return false; 865} 866 867/// ParseDirectiveSet: 868/// ::= .set identifier ',' expression 869bool AsmParser::ParseDirectiveSet() { 870 StringRef Name; 871 872 if (ParseIdentifier(Name)) 873 return TokError("expected identifier after '.set' directive"); 874 875 if (Lexer.isNot(AsmToken::Comma)) 876 return TokError("unexpected token in '.set'"); 877 Lex(); 878 879 return ParseAssignment(Name); 880} 881 882/// ParseDirectiveSection: 883/// ::= .section identifier (',' identifier)* 884/// FIXME: This should actually parse out the segment, section, attributes and 885/// sizeof_stub fields. 886bool AsmParser::ParseDirectiveDarwinSection() { 887 SMLoc Loc = Lexer.getLoc(); 888 889 StringRef SectionName; 890 if (ParseIdentifier(SectionName)) 891 return Error(Loc, "expected identifier after '.section' directive"); 892 893 // Verify there is a following comma. 894 if (!Lexer.is(AsmToken::Comma)) 895 return TokError("unexpected token in '.section' directive"); 896 897 std::string SectionSpec = SectionName; 898 SectionSpec += ","; 899 900 // Add all the tokens until the end of the line, ParseSectionSpecifier will 901 // handle this. 902 StringRef EOL = Lexer.LexUntilEndOfStatement(); 903 SectionSpec.append(EOL.begin(), EOL.end()); 904 905 Lex(); 906 if (Lexer.isNot(AsmToken::EndOfStatement)) 907 return TokError("unexpected token in '.section' directive"); 908 Lex(); 909 910 911 StringRef Segment, Section; 912 unsigned TAA, StubSize; 913 std::string ErrorStr = 914 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 915 TAA, StubSize); 916 917 if (!ErrorStr.empty()) 918 return Error(Loc, ErrorStr.c_str()); 919 920 // FIXME: Arch specific. 921 bool isText = Segment == "__TEXT"; // FIXME: Hack. 922 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize, 923 isText ? SectionKind::getText() 924 : SectionKind::getDataRel())); 925 return false; 926} 927 928/// ParseDirectiveSectionSwitch - 929bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment, 930 const char *Section, 931 unsigned TAA, unsigned Align, 932 unsigned StubSize) { 933 if (Lexer.isNot(AsmToken::EndOfStatement)) 934 return TokError("unexpected token in section switching directive"); 935 Lex(); 936 937 // FIXME: Arch specific. 938 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack. 939 Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize, 940 isText ? SectionKind::getText() 941 : SectionKind::getDataRel())); 942 943 // Set the implicit alignment, if any. 944 // 945 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 946 // alignment on the section (e.g., if one manually inserts bytes into the 947 // section, then just issueing the section switch directive will not realign 948 // the section. However, this is arguably more reasonable behavior, and there 949 // is no good reason for someone to intentionally emit incorrectly sized 950 // values into the implicitly aligned sections. 951 if (Align) 952 Out.EmitValueToAlignment(Align, 0, 1, 0); 953 954 return false; 955} 956 957bool AsmParser::ParseEscapedString(std::string &Data) { 958 assert(Lexer.is(AsmToken::String) && "Unexpected current token!"); 959 960 Data = ""; 961 StringRef Str = getTok().getStringContents(); 962 for (unsigned i = 0, e = Str.size(); i != e; ++i) { 963 if (Str[i] != '\\') { 964 Data += Str[i]; 965 continue; 966 } 967 968 // Recognize escaped characters. Note that this escape semantics currently 969 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes. 970 ++i; 971 if (i == e) 972 return TokError("unexpected backslash at end of string"); 973 974 // Recognize octal sequences. 975 if ((unsigned) (Str[i] - '0') <= 7) { 976 // Consume up to three octal characters. 977 unsigned Value = Str[i] - '0'; 978 979 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 980 ++i; 981 Value = Value * 8 + (Str[i] - '0'); 982 983 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { 984 ++i; 985 Value = Value * 8 + (Str[i] - '0'); 986 } 987 } 988 989 if (Value > 255) 990 return TokError("invalid octal escape sequence (out of range)"); 991 992 Data += (unsigned char) Value; 993 continue; 994 } 995 996 // Otherwise recognize individual escapes. 997 switch (Str[i]) { 998 default: 999 // Just reject invalid escape sequences for now. 1000 return TokError("invalid escape sequence (unrecognized character)"); 1001 1002 case 'b': Data += '\b'; break; 1003 case 'f': Data += '\f'; break; 1004 case 'n': Data += '\n'; break; 1005 case 'r': Data += '\r'; break; 1006 case 't': Data += '\t'; break; 1007 case '"': Data += '"'; break; 1008 case '\\': Data += '\\'; break; 1009 } 1010 } 1011 1012 return false; 1013} 1014 1015/// ParseDirectiveAscii: 1016/// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ] 1017bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) { 1018 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1019 for (;;) { 1020 if (Lexer.isNot(AsmToken::String)) 1021 return TokError("expected string in '.ascii' or '.asciz' directive"); 1022 1023 std::string Data; 1024 if (ParseEscapedString(Data)) 1025 return true; 1026 1027 Out.EmitBytes(Data, DEFAULT_ADDRSPACE); 1028 if (ZeroTerminated) 1029 Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); 1030 1031 Lex(); 1032 1033 if (Lexer.is(AsmToken::EndOfStatement)) 1034 break; 1035 1036 if (Lexer.isNot(AsmToken::Comma)) 1037 return TokError("unexpected token in '.ascii' or '.asciz' directive"); 1038 Lex(); 1039 } 1040 } 1041 1042 Lex(); 1043 return false; 1044} 1045 1046/// ParseDirectiveValue 1047/// ::= (.byte | .short | ... ) [ expression (, expression)* ] 1048bool AsmParser::ParseDirectiveValue(unsigned Size) { 1049 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1050 for (;;) { 1051 const MCExpr *Value; 1052 SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc(); 1053 if (ParseExpression(Value)) 1054 return true; 1055 1056 Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE); 1057 1058 if (Lexer.is(AsmToken::EndOfStatement)) 1059 break; 1060 1061 // FIXME: Improve diagnostic. 1062 if (Lexer.isNot(AsmToken::Comma)) 1063 return TokError("unexpected token in directive"); 1064 Lex(); 1065 } 1066 } 1067 1068 Lex(); 1069 return false; 1070} 1071 1072/// ParseDirectiveSpace 1073/// ::= .space expression [ , expression ] 1074bool AsmParser::ParseDirectiveSpace() { 1075 int64_t NumBytes; 1076 if (ParseAbsoluteExpression(NumBytes)) 1077 return true; 1078 1079 int64_t FillExpr = 0; 1080 bool HasFillExpr = false; 1081 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1082 if (Lexer.isNot(AsmToken::Comma)) 1083 return TokError("unexpected token in '.space' directive"); 1084 Lex(); 1085 1086 if (ParseAbsoluteExpression(FillExpr)) 1087 return true; 1088 1089 HasFillExpr = true; 1090 1091 if (Lexer.isNot(AsmToken::EndOfStatement)) 1092 return TokError("unexpected token in '.space' directive"); 1093 } 1094 1095 Lex(); 1096 1097 if (NumBytes <= 0) 1098 return TokError("invalid number of bytes in '.space' directive"); 1099 1100 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. 1101 Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); 1102 1103 return false; 1104} 1105 1106/// ParseDirectiveFill 1107/// ::= .fill expression , expression , expression 1108bool AsmParser::ParseDirectiveFill() { 1109 int64_t NumValues; 1110 if (ParseAbsoluteExpression(NumValues)) 1111 return true; 1112 1113 if (Lexer.isNot(AsmToken::Comma)) 1114 return TokError("unexpected token in '.fill' directive"); 1115 Lex(); 1116 1117 int64_t FillSize; 1118 if (ParseAbsoluteExpression(FillSize)) 1119 return true; 1120 1121 if (Lexer.isNot(AsmToken::Comma)) 1122 return TokError("unexpected token in '.fill' directive"); 1123 Lex(); 1124 1125 int64_t FillExpr; 1126 if (ParseAbsoluteExpression(FillExpr)) 1127 return true; 1128 1129 if (Lexer.isNot(AsmToken::EndOfStatement)) 1130 return TokError("unexpected token in '.fill' directive"); 1131 1132 Lex(); 1133 1134 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) 1135 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); 1136 1137 for (uint64_t i = 0, e = NumValues; i != e; ++i) 1138 Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize, 1139 DEFAULT_ADDRSPACE); 1140 1141 return false; 1142} 1143 1144/// ParseDirectiveOrg 1145/// ::= .org expression [ , expression ] 1146bool AsmParser::ParseDirectiveOrg() { 1147 const MCExpr *Offset; 1148 SMLoc StartLoc = Lexer.getLoc(); 1149 if (ParseExpression(Offset)) 1150 return true; 1151 1152 // Parse optional fill expression. 1153 int64_t FillExpr = 0; 1154 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1155 if (Lexer.isNot(AsmToken::Comma)) 1156 return TokError("unexpected token in '.org' directive"); 1157 Lex(); 1158 1159 if (ParseAbsoluteExpression(FillExpr)) 1160 return true; 1161 1162 if (Lexer.isNot(AsmToken::EndOfStatement)) 1163 return TokError("unexpected token in '.org' directive"); 1164 } 1165 1166 Lex(); 1167 1168 // FIXME: Only limited forms of relocatable expressions are accepted here, it 1169 // has to be relative to the current section. 1170 Out.EmitValueToOffset(Offset, FillExpr); 1171 1172 return false; 1173} 1174 1175/// ParseDirectiveAlign 1176/// ::= {.align, ...} expression [ , expression [ , expression ]] 1177bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { 1178 SMLoc AlignmentLoc = Lexer.getLoc(); 1179 int64_t Alignment; 1180 if (ParseAbsoluteExpression(Alignment)) 1181 return true; 1182 1183 SMLoc MaxBytesLoc; 1184 bool HasFillExpr = false; 1185 int64_t FillExpr = 0; 1186 int64_t MaxBytesToFill = 0; 1187 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1188 if (Lexer.isNot(AsmToken::Comma)) 1189 return TokError("unexpected token in directive"); 1190 Lex(); 1191 1192 // The fill expression can be omitted while specifying a maximum number of 1193 // alignment bytes, e.g: 1194 // .align 3,,4 1195 if (Lexer.isNot(AsmToken::Comma)) { 1196 HasFillExpr = true; 1197 if (ParseAbsoluteExpression(FillExpr)) 1198 return true; 1199 } 1200 1201 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1202 if (Lexer.isNot(AsmToken::Comma)) 1203 return TokError("unexpected token in directive"); 1204 Lex(); 1205 1206 MaxBytesLoc = Lexer.getLoc(); 1207 if (ParseAbsoluteExpression(MaxBytesToFill)) 1208 return true; 1209 1210 if (Lexer.isNot(AsmToken::EndOfStatement)) 1211 return TokError("unexpected token in directive"); 1212 } 1213 } 1214 1215 Lex(); 1216 1217 if (!HasFillExpr) { 1218 // FIXME: Sometimes fill with nop. 1219 FillExpr = 0; 1220 } 1221 1222 // Compute alignment in bytes. 1223 if (IsPow2) { 1224 // FIXME: Diagnose overflow. 1225 if (Alignment >= 32) { 1226 Error(AlignmentLoc, "invalid alignment value"); 1227 Alignment = 31; 1228 } 1229 1230 Alignment = 1ULL << Alignment; 1231 } 1232 1233 // Diagnose non-sensical max bytes to align. 1234 if (MaxBytesLoc.isValid()) { 1235 if (MaxBytesToFill < 1) { 1236 Error(MaxBytesLoc, "alignment directive can never be satisfied in this " 1237 "many bytes, ignoring maximum bytes expression"); 1238 MaxBytesToFill = 0; 1239 } 1240 1241 if (MaxBytesToFill >= Alignment) { 1242 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " 1243 "has no effect"); 1244 MaxBytesToFill = 0; 1245 } 1246 } 1247 1248 // FIXME: hard code the parser to use EmitCodeAlignment for text when using 1249 // the TextAlignFillValue. 1250 if(Out.getCurrentSection()->getKind().isText() && 1251 Lexer.getMAI().getTextAlignFillValue() == FillExpr) 1252 Out.EmitCodeAlignment(Alignment, MaxBytesToFill); 1253 else 1254 // FIXME: Target specific behavior about how the "extra" bytes are filled. 1255 Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill); 1256 1257 return false; 1258} 1259 1260/// ParseDirectiveSymbolAttribute 1261/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] 1262bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { 1263 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1264 for (;;) { 1265 StringRef Name; 1266 1267 if (ParseIdentifier(Name)) 1268 return TokError("expected identifier in directive"); 1269 1270 MCSymbol *Sym = CreateSymbol(Name); 1271 1272 Out.EmitSymbolAttribute(Sym, Attr); 1273 1274 if (Lexer.is(AsmToken::EndOfStatement)) 1275 break; 1276 1277 if (Lexer.isNot(AsmToken::Comma)) 1278 return TokError("unexpected token in directive"); 1279 Lex(); 1280 } 1281 } 1282 1283 Lex(); 1284 return false; 1285} 1286 1287/// ParseDirectiveDarwinSymbolDesc 1288/// ::= .desc identifier , expression 1289bool AsmParser::ParseDirectiveDarwinSymbolDesc() { 1290 StringRef Name; 1291 if (ParseIdentifier(Name)) 1292 return TokError("expected identifier in directive"); 1293 1294 // Handle the identifier as the key symbol. 1295 MCSymbol *Sym = CreateSymbol(Name); 1296 1297 if (Lexer.isNot(AsmToken::Comma)) 1298 return TokError("unexpected token in '.desc' directive"); 1299 Lex(); 1300 1301 SMLoc DescLoc = Lexer.getLoc(); 1302 int64_t DescValue; 1303 if (ParseAbsoluteExpression(DescValue)) 1304 return true; 1305 1306 if (Lexer.isNot(AsmToken::EndOfStatement)) 1307 return TokError("unexpected token in '.desc' directive"); 1308 1309 Lex(); 1310 1311 // Set the n_desc field of this Symbol to this DescValue 1312 Out.EmitSymbolDesc(Sym, DescValue); 1313 1314 return false; 1315} 1316 1317/// ParseDirectiveComm 1318/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] 1319bool AsmParser::ParseDirectiveComm(bool IsLocal) { 1320 SMLoc IDLoc = Lexer.getLoc(); 1321 StringRef Name; 1322 if (ParseIdentifier(Name)) 1323 return TokError("expected identifier in directive"); 1324 1325 // Handle the identifier as the key symbol. 1326 MCSymbol *Sym = CreateSymbol(Name); 1327 1328 if (Lexer.isNot(AsmToken::Comma)) 1329 return TokError("unexpected token in directive"); 1330 Lex(); 1331 1332 int64_t Size; 1333 SMLoc SizeLoc = Lexer.getLoc(); 1334 if (ParseAbsoluteExpression(Size)) 1335 return true; 1336 1337 int64_t Pow2Alignment = 0; 1338 SMLoc Pow2AlignmentLoc; 1339 if (Lexer.is(AsmToken::Comma)) { 1340 Lex(); 1341 Pow2AlignmentLoc = Lexer.getLoc(); 1342 if (ParseAbsoluteExpression(Pow2Alignment)) 1343 return true; 1344 1345 // If this target takes alignments in bytes (not log) validate and convert. 1346 if (Lexer.getMAI().getAlignmentIsInBytes()) { 1347 if (!isPowerOf2_64(Pow2Alignment)) 1348 return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); 1349 Pow2Alignment = Log2_64(Pow2Alignment); 1350 } 1351 } 1352 1353 if (Lexer.isNot(AsmToken::EndOfStatement)) 1354 return TokError("unexpected token in '.comm' or '.lcomm' directive"); 1355 1356 Lex(); 1357 1358 // NOTE: a size of zero for a .comm should create a undefined symbol 1359 // but a size of .lcomm creates a bss symbol of size zero. 1360 if (Size < 0) 1361 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " 1362 "be less than zero"); 1363 1364 // NOTE: The alignment in the directive is a power of 2 value, the assember 1365 // may internally end up wanting an alignment in bytes. 1366 // FIXME: Diagnose overflow. 1367 if (Pow2Alignment < 0) 1368 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " 1369 "alignment, can't be less than zero"); 1370 1371 if (!Sym->isUndefined()) 1372 return Error(IDLoc, "invalid symbol redefinition"); 1373 1374 // '.lcomm' is equivalent to '.zerofill'. 1375 // Create the Symbol as a common or local common with Size and Pow2Alignment 1376 if (IsLocal) { 1377 Out.EmitZerofill(getMachOSection("__DATA", "__bss", 1378 MCSectionMachO::S_ZEROFILL, 0, 1379 SectionKind::getBSS()), 1380 Sym, Size, 1 << Pow2Alignment); 1381 return false; 1382 } 1383 1384 Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment); 1385 return false; 1386} 1387 1388/// ParseDirectiveDarwinZerofill 1389/// ::= .zerofill segname , sectname [, identifier , size_expression [ 1390/// , align_expression ]] 1391bool AsmParser::ParseDirectiveDarwinZerofill() { 1392 // FIXME: Handle quoted names here. 1393 1394 if (Lexer.isNot(AsmToken::Identifier)) 1395 return TokError("expected segment name after '.zerofill' directive"); 1396 StringRef Segment = getTok().getString(); 1397 Lex(); 1398 1399 if (Lexer.isNot(AsmToken::Comma)) 1400 return TokError("unexpected token in directive"); 1401 Lex(); 1402 1403 if (Lexer.isNot(AsmToken::Identifier)) 1404 return TokError("expected section name after comma in '.zerofill' " 1405 "directive"); 1406 StringRef Section = getTok().getString(); 1407 Lex(); 1408 1409 // If this is the end of the line all that was wanted was to create the 1410 // the section but with no symbol. 1411 if (Lexer.is(AsmToken::EndOfStatement)) { 1412 // Create the zerofill section but no symbol 1413 Out.EmitZerofill(getMachOSection(Segment, Section, 1414 MCSectionMachO::S_ZEROFILL, 0, 1415 SectionKind::getBSS())); 1416 return false; 1417 } 1418 1419 if (Lexer.isNot(AsmToken::Comma)) 1420 return TokError("unexpected token in directive"); 1421 Lex(); 1422 1423 if (Lexer.isNot(AsmToken::Identifier)) 1424 return TokError("expected identifier in directive"); 1425 1426 // handle the identifier as the key symbol. 1427 SMLoc IDLoc = Lexer.getLoc(); 1428 MCSymbol *Sym = CreateSymbol(getTok().getString()); 1429 Lex(); 1430 1431 if (Lexer.isNot(AsmToken::Comma)) 1432 return TokError("unexpected token in directive"); 1433 Lex(); 1434 1435 int64_t Size; 1436 SMLoc SizeLoc = Lexer.getLoc(); 1437 if (ParseAbsoluteExpression(Size)) 1438 return true; 1439 1440 int64_t Pow2Alignment = 0; 1441 SMLoc Pow2AlignmentLoc; 1442 if (Lexer.is(AsmToken::Comma)) { 1443 Lex(); 1444 Pow2AlignmentLoc = Lexer.getLoc(); 1445 if (ParseAbsoluteExpression(Pow2Alignment)) 1446 return true; 1447 } 1448 1449 if (Lexer.isNot(AsmToken::EndOfStatement)) 1450 return TokError("unexpected token in '.zerofill' directive"); 1451 1452 Lex(); 1453 1454 if (Size < 0) 1455 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 1456 "than zero"); 1457 1458 // NOTE: The alignment in the directive is a power of 2 value, the assember 1459 // may internally end up wanting an alignment in bytes. 1460 // FIXME: Diagnose overflow. 1461 if (Pow2Alignment < 0) 1462 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 1463 "can't be less than zero"); 1464 1465 if (!Sym->isUndefined()) 1466 return Error(IDLoc, "invalid symbol redefinition"); 1467 1468 // Create the zerofill Symbol with Size and Pow2Alignment 1469 // 1470 // FIXME: Arch specific. 1471 Out.EmitZerofill(getMachOSection(Segment, Section, 1472 MCSectionMachO::S_ZEROFILL, 0, 1473 SectionKind::getBSS()), 1474 Sym, Size, 1 << Pow2Alignment); 1475 1476 return false; 1477} 1478 1479/// ParseDirectiveDarwinSubsectionsViaSymbols 1480/// ::= .subsections_via_symbols 1481bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() { 1482 if (Lexer.isNot(AsmToken::EndOfStatement)) 1483 return TokError("unexpected token in '.subsections_via_symbols' directive"); 1484 1485 Lex(); 1486 1487 Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1488 1489 return false; 1490} 1491 1492/// ParseDirectiveAbort 1493/// ::= .abort [ "abort_string" ] 1494bool AsmParser::ParseDirectiveAbort() { 1495 // FIXME: Use loc from directive. 1496 SMLoc Loc = Lexer.getLoc(); 1497 1498 StringRef Str = ""; 1499 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1500 if (Lexer.isNot(AsmToken::String)) 1501 return TokError("expected string in '.abort' directive"); 1502 1503 Str = getTok().getString(); 1504 1505 Lex(); 1506 } 1507 1508 if (Lexer.isNot(AsmToken::EndOfStatement)) 1509 return TokError("unexpected token in '.abort' directive"); 1510 1511 Lex(); 1512 1513 // FIXME: Handle here. 1514 if (Str.empty()) 1515 Error(Loc, ".abort detected. Assembly stopping."); 1516 else 1517 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping."); 1518 1519 return false; 1520} 1521 1522/// ParseDirectiveLsym 1523/// ::= .lsym identifier , expression 1524bool AsmParser::ParseDirectiveDarwinLsym() { 1525 StringRef Name; 1526 if (ParseIdentifier(Name)) 1527 return TokError("expected identifier in directive"); 1528 1529 // Handle the identifier as the key symbol. 1530 MCSymbol *Sym = CreateSymbol(Name); 1531 1532 if (Lexer.isNot(AsmToken::Comma)) 1533 return TokError("unexpected token in '.lsym' directive"); 1534 Lex(); 1535 1536 const MCExpr *Value; 1537 SMLoc StartLoc = Lexer.getLoc(); 1538 if (ParseExpression(Value)) 1539 return true; 1540 1541 if (Lexer.isNot(AsmToken::EndOfStatement)) 1542 return TokError("unexpected token in '.lsym' directive"); 1543 1544 Lex(); 1545 1546 // We don't currently support this directive. 1547 // 1548 // FIXME: Diagnostic location! 1549 (void) Sym; 1550 return TokError("directive '.lsym' is unsupported"); 1551} 1552 1553/// ParseDirectiveInclude 1554/// ::= .include "filename" 1555bool AsmParser::ParseDirectiveInclude() { 1556 if (Lexer.isNot(AsmToken::String)) 1557 return TokError("expected string in '.include' directive"); 1558 1559 std::string Filename = getTok().getString(); 1560 SMLoc IncludeLoc = Lexer.getLoc(); 1561 Lex(); 1562 1563 if (Lexer.isNot(AsmToken::EndOfStatement)) 1564 return TokError("unexpected token in '.include' directive"); 1565 1566 // Strip the quotes. 1567 Filename = Filename.substr(1, Filename.size()-2); 1568 1569 // Attempt to switch the lexer to the included file before consuming the end 1570 // of statement to avoid losing it when we switch. 1571 if (EnterIncludeFile(Filename)) { 1572 PrintMessage(IncludeLoc, 1573 "Could not find include file '" + Filename + "'", 1574 "error"); 1575 return true; 1576 } 1577 1578 return false; 1579} 1580 1581/// ParseDirectiveDarwinDumpOrLoad 1582/// ::= ( .dump | .load ) "filename" 1583bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) { 1584 if (Lexer.isNot(AsmToken::String)) 1585 return TokError("expected string in '.dump' or '.load' directive"); 1586 1587 Lex(); 1588 1589 if (Lexer.isNot(AsmToken::EndOfStatement)) 1590 return TokError("unexpected token in '.dump' or '.load' directive"); 1591 1592 Lex(); 1593 1594 // FIXME: If/when .dump and .load are implemented they will be done in the 1595 // the assembly parser and not have any need for an MCStreamer API. 1596 if (IsDump) 1597 Warning(IDLoc, "ignoring directive .dump for now"); 1598 else 1599 Warning(IDLoc, "ignoring directive .load for now"); 1600 1601 return false; 1602} 1603 1604/// ParseDirectiveIf 1605/// ::= .if expression 1606bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { 1607 // Consume the identifier that was the .if directive 1608 Lex(); 1609 1610 TheCondStack.push_back(TheCondState); 1611 TheCondState.TheCond = AsmCond::IfCond; 1612 if(TheCondState.Ignore) { 1613 EatToEndOfStatement(); 1614 } 1615 else { 1616 int64_t ExprValue; 1617 if (ParseAbsoluteExpression(ExprValue)) 1618 return true; 1619 1620 if (Lexer.isNot(AsmToken::EndOfStatement)) 1621 return TokError("unexpected token in '.if' directive"); 1622 1623 Lex(); 1624 1625 TheCondState.CondMet = ExprValue; 1626 TheCondState.Ignore = !TheCondState.CondMet; 1627 } 1628 1629 return false; 1630} 1631 1632/// ParseDirectiveElseIf 1633/// ::= .elseif expression 1634bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { 1635 if (TheCondState.TheCond != AsmCond::IfCond && 1636 TheCondState.TheCond != AsmCond::ElseIfCond) 1637 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " 1638 " an .elseif"); 1639 TheCondState.TheCond = AsmCond::ElseIfCond; 1640 1641 // Consume the identifier that was the .elseif directive 1642 Lex(); 1643 1644 bool LastIgnoreState = false; 1645 if (!TheCondStack.empty()) 1646 LastIgnoreState = TheCondStack.back().Ignore; 1647 if (LastIgnoreState || TheCondState.CondMet) { 1648 TheCondState.Ignore = true; 1649 EatToEndOfStatement(); 1650 } 1651 else { 1652 int64_t ExprValue; 1653 if (ParseAbsoluteExpression(ExprValue)) 1654 return true; 1655 1656 if (Lexer.isNot(AsmToken::EndOfStatement)) 1657 return TokError("unexpected token in '.elseif' directive"); 1658 1659 Lex(); 1660 TheCondState.CondMet = ExprValue; 1661 TheCondState.Ignore = !TheCondState.CondMet; 1662 } 1663 1664 return false; 1665} 1666 1667/// ParseDirectiveElse 1668/// ::= .else 1669bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { 1670 // Consume the identifier that was the .else directive 1671 Lex(); 1672 1673 if (Lexer.isNot(AsmToken::EndOfStatement)) 1674 return TokError("unexpected token in '.else' directive"); 1675 1676 Lex(); 1677 1678 if (TheCondState.TheCond != AsmCond::IfCond && 1679 TheCondState.TheCond != AsmCond::ElseIfCond) 1680 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an " 1681 ".elseif"); 1682 TheCondState.TheCond = AsmCond::ElseCond; 1683 bool LastIgnoreState = false; 1684 if (!TheCondStack.empty()) 1685 LastIgnoreState = TheCondStack.back().Ignore; 1686 if (LastIgnoreState || TheCondState.CondMet) 1687 TheCondState.Ignore = true; 1688 else 1689 TheCondState.Ignore = false; 1690 1691 return false; 1692} 1693 1694/// ParseDirectiveEndIf 1695/// ::= .endif 1696bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { 1697 // Consume the identifier that was the .endif directive 1698 Lex(); 1699 1700 if (Lexer.isNot(AsmToken::EndOfStatement)) 1701 return TokError("unexpected token in '.endif' directive"); 1702 1703 Lex(); 1704 1705 if ((TheCondState.TheCond == AsmCond::NoCond) || 1706 TheCondStack.empty()) 1707 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " 1708 ".else"); 1709 if (!TheCondStack.empty()) { 1710 TheCondState = TheCondStack.back(); 1711 TheCondStack.pop_back(); 1712 } 1713 1714 return false; 1715} 1716 1717/// ParseDirectiveFile 1718/// ::= .file [number] string 1719bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) { 1720 // FIXME: I'm not sure what this is. 1721 int64_t FileNumber = -1; 1722 if (Lexer.is(AsmToken::Integer)) { 1723 FileNumber = getTok().getIntVal(); 1724 Lex(); 1725 1726 if (FileNumber < 1) 1727 return TokError("file number less than one"); 1728 } 1729 1730 if (Lexer.isNot(AsmToken::String)) 1731 return TokError("unexpected token in '.file' directive"); 1732 1733 StringRef Filename = getTok().getString(); 1734 Filename = Filename.substr(1, Filename.size()-2); 1735 Lex(); 1736 1737 if (Lexer.isNot(AsmToken::EndOfStatement)) 1738 return TokError("unexpected token in '.file' directive"); 1739 1740 if (FileNumber == -1) 1741 Out.EmitFileDirective(Filename); 1742 else 1743 Out.EmitDwarfFileDirective(FileNumber, Filename); 1744 1745 return false; 1746} 1747 1748/// ParseDirectiveLine 1749/// ::= .line [number] 1750bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) { 1751 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1752 if (Lexer.isNot(AsmToken::Integer)) 1753 return TokError("unexpected token in '.line' directive"); 1754 1755 int64_t LineNumber = getTok().getIntVal(); 1756 (void) LineNumber; 1757 Lex(); 1758 1759 // FIXME: Do something with the .line. 1760 } 1761 1762 if (Lexer.isNot(AsmToken::EndOfStatement)) 1763 return TokError("unexpected token in '.file' directive"); 1764 1765 return false; 1766} 1767 1768 1769/// ParseDirectiveLoc 1770/// ::= .loc number [number [number]] 1771bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) { 1772 if (Lexer.isNot(AsmToken::Integer)) 1773 return TokError("unexpected token in '.loc' directive"); 1774 1775 // FIXME: What are these fields? 1776 int64_t FileNumber = getTok().getIntVal(); 1777 (void) FileNumber; 1778 // FIXME: Validate file. 1779 1780 Lex(); 1781 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1782 if (Lexer.isNot(AsmToken::Integer)) 1783 return TokError("unexpected token in '.loc' directive"); 1784 1785 int64_t Param2 = getTok().getIntVal(); 1786 (void) Param2; 1787 Lex(); 1788 1789 if (Lexer.isNot(AsmToken::EndOfStatement)) { 1790 if (Lexer.isNot(AsmToken::Integer)) 1791 return TokError("unexpected token in '.loc' directive"); 1792 1793 int64_t Param3 = getTok().getIntVal(); 1794 (void) Param3; 1795 Lex(); 1796 1797 // FIXME: Do something with the .loc. 1798 } 1799 } 1800 1801 if (Lexer.isNot(AsmToken::EndOfStatement)) 1802 return TokError("unexpected token in '.file' directive"); 1803 1804 return false; 1805} 1806 1807