1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This class implements the parser for assembly files.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/MC/MCParser/AsmParser.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSectionMachO.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Support/SourceMgr.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include "llvm/Target/TargetAsmParser.h"
35 /// \brief Generic implementations of directive handling, etc. which is shared
36 /// (or the default, at least) for all assembler parser.
37 class GenericAsmParser : public MCAsmParserExtension {
41 virtual void Initialize(MCAsmParser &Parser) {
42 // Call the base implementation.
43 this->MCAsmParserExtension::Initialize(Parser);
45 // Debugging directives.
46 Parser.AddDirectiveHandler(this, ".file", MCAsmParser::DirectiveHandler(
47 &GenericAsmParser::ParseDirectiveFile));
48 Parser.AddDirectiveHandler(this, ".line", MCAsmParser::DirectiveHandler(
49 &GenericAsmParser::ParseDirectiveLine));
50 Parser.AddDirectiveHandler(this, ".loc", MCAsmParser::DirectiveHandler(
51 &GenericAsmParser::ParseDirectiveLoc));
54 bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file"
55 bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line"
56 bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc"
61 enum { DEFAULT_ADDRSPACE = 0 };
63 AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
64 MCStreamer &_Out, const MCAsmInfo &_MAI)
65 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM),
66 GenericParser(new GenericAsmParser), TargetParser(0), CurBuffer(0) {
67 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
69 // Initialize the generic parser.
70 GenericParser->Initialize(*this);
73 AsmParser::~AsmParser() {
77 void AsmParser::setTargetParser(TargetAsmParser &P) {
78 assert(!TargetParser && "Target parser is already initialized!");
80 TargetParser->Initialize(*this);
83 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
84 PrintMessage(L, Msg.str(), "warning");
87 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
88 PrintMessage(L, Msg.str(), "error");
92 void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg,
93 const char *Type) const {
94 SrcMgr.PrintMessage(Loc, Msg, Type);
97 bool AsmParser::EnterIncludeFile(const std::string &Filename) {
98 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
104 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
109 const AsmToken &AsmParser::Lex() {
110 const AsmToken *tok = &Lexer.Lex();
112 if (tok->is(AsmToken::Eof)) {
113 // If this is the end of an included file, pop the parent file off the
115 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
116 if (ParentIncludeLoc != SMLoc()) {
117 CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
118 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer),
119 ParentIncludeLoc.getPointer());
124 if (tok->is(AsmToken::Error))
125 PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
130 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
131 // Create the initial section, if requested.
133 // FIXME: Target hook & command line option for initial section.
134 if (!NoInitialTextSection)
135 Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
136 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
137 0, SectionKind::getText()));
142 bool HadError = false;
144 AsmCond StartingCondState = TheCondState;
146 // While we have input, parse each statement.
147 while (Lexer.isNot(AsmToken::Eof)) {
148 if (!ParseStatement()) continue;
150 // We had an error, remember it and recover by skipping to the next line.
152 EatToEndOfStatement();
155 if (TheCondState.TheCond != StartingCondState.TheCond ||
156 TheCondState.Ignore != StartingCondState.Ignore)
157 return TokError("unmatched .ifs or .elses");
159 // Finalize the output stream if there are no errors and if the client wants
161 if (!HadError && !NoFinalize)
167 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
168 void AsmParser::EatToEndOfStatement() {
169 while (Lexer.isNot(AsmToken::EndOfStatement) &&
170 Lexer.isNot(AsmToken::Eof))
174 if (Lexer.is(AsmToken::EndOfStatement))
179 /// ParseParenExpr - Parse a paren expression and return it.
180 /// NOTE: This assumes the leading '(' has already been consumed.
182 /// parenexpr ::= expr)
184 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
185 if (ParseExpression(Res)) return true;
186 if (Lexer.isNot(AsmToken::RParen))
187 return TokError("expected ')' in parentheses expression");
188 EndLoc = Lexer.getLoc();
193 MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
194 // FIXME: Inline into callers.
195 return Ctx.GetOrCreateSymbol(Name);
198 /// ParsePrimaryExpr - Parse a primary expression and return it.
199 /// primaryexpr ::= (parenexpr
200 /// primaryexpr ::= symbol
201 /// primaryexpr ::= number
202 /// primaryexpr ::= '.'
203 /// primaryexpr ::= ~,+,- primaryexpr
204 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
205 switch (Lexer.getKind()) {
207 return TokError("unknown token in expression");
208 case AsmToken::Exclaim:
209 Lex(); // Eat the operator.
210 if (ParsePrimaryExpr(Res, EndLoc))
212 Res = MCUnaryExpr::CreateLNot(Res, getContext());
214 case AsmToken::String:
215 case AsmToken::Identifier: {
216 // This is a symbol reference.
217 std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
218 MCSymbol *Sym = CreateSymbol(Split.first);
220 // Mark the symbol as used in an expression.
221 Sym->setUsedInExpr(true);
223 // Lookup the symbol variant if used.
224 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
225 if (Split.first.size() != getTok().getIdentifier().size())
226 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
228 EndLoc = Lexer.getLoc();
229 Lex(); // Eat identifier.
231 // If this is an absolute variable reference, substitute it now to preserve
232 // semantics in the face of reassignment.
233 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
235 return Error(EndLoc, "unexpected modified on variable reference");
237 Res = Sym->getVariableValue();
241 // Otherwise create a symbol ref.
242 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
245 case AsmToken::Integer: {
246 SMLoc Loc = getTok().getLoc();
247 int64_t IntVal = getTok().getIntVal();
248 Res = MCConstantExpr::Create(IntVal, getContext());
249 EndLoc = Lexer.getLoc();
251 // Look for 'b' or 'f' following an Integer as a directional label
252 if (Lexer.getKind() == AsmToken::Identifier) {
253 StringRef IDVal = getTok().getString();
254 if (IDVal == "f" || IDVal == "b"){
255 MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
256 IDVal == "f" ? 1 : 0);
257 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
259 if(IDVal == "b" && Sym->isUndefined())
260 return Error(Loc, "invalid reference to undefined symbol");
261 EndLoc = Lexer.getLoc();
262 Lex(); // Eat identifier.
267 case AsmToken::Dot: {
268 // This is a '.' reference, which references the current PC. Emit a
269 // temporary label to the streamer and refer to it.
270 MCSymbol *Sym = Ctx.CreateTempSymbol();
272 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
273 EndLoc = Lexer.getLoc();
274 Lex(); // Eat identifier.
278 case AsmToken::LParen:
279 Lex(); // Eat the '('.
280 return ParseParenExpr(Res, EndLoc);
281 case AsmToken::Minus:
282 Lex(); // Eat the operator.
283 if (ParsePrimaryExpr(Res, EndLoc))
285 Res = MCUnaryExpr::CreateMinus(Res, getContext());
288 Lex(); // Eat the operator.
289 if (ParsePrimaryExpr(Res, EndLoc))
291 Res = MCUnaryExpr::CreatePlus(Res, getContext());
293 case AsmToken::Tilde:
294 Lex(); // Eat the operator.
295 if (ParsePrimaryExpr(Res, EndLoc))
297 Res = MCUnaryExpr::CreateNot(Res, getContext());
302 bool AsmParser::ParseExpression(const MCExpr *&Res) {
304 return ParseExpression(Res, EndLoc);
307 /// ParseExpression - Parse an expression and return it.
309 /// expr ::= expr +,- expr -> lowest.
310 /// expr ::= expr |,^,&,! expr -> middle.
311 /// expr ::= expr *,/,%,<<,>> expr -> highest.
312 /// expr ::= primaryexpr
314 bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
315 // Parse the expression.
317 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
320 // Try to constant fold it up front, if possible.
322 if (Res->EvaluateAsAbsolute(Value))
323 Res = MCConstantExpr::Create(Value, getContext());
328 bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
330 return ParseParenExpr(Res, EndLoc) ||
331 ParseBinOpRHS(1, Res, EndLoc);
334 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
337 SMLoc StartLoc = Lexer.getLoc();
338 if (ParseExpression(Expr))
341 if (!Expr->EvaluateAsAbsolute(Res))
342 return Error(StartLoc, "expected absolute expression");
347 static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
348 MCBinaryExpr::Opcode &Kind) {
351 return 0; // not a binop.
353 // Lowest Precedence: &&, ||
354 case AsmToken::AmpAmp:
355 Kind = MCBinaryExpr::LAnd;
357 case AsmToken::PipePipe:
358 Kind = MCBinaryExpr::LOr;
361 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
363 Kind = MCBinaryExpr::Add;
365 case AsmToken::Minus:
366 Kind = MCBinaryExpr::Sub;
368 case AsmToken::EqualEqual:
369 Kind = MCBinaryExpr::EQ;
371 case AsmToken::ExclaimEqual:
372 case AsmToken::LessGreater:
373 Kind = MCBinaryExpr::NE;
376 Kind = MCBinaryExpr::LT;
378 case AsmToken::LessEqual:
379 Kind = MCBinaryExpr::LTE;
381 case AsmToken::Greater:
382 Kind = MCBinaryExpr::GT;
384 case AsmToken::GreaterEqual:
385 Kind = MCBinaryExpr::GTE;
388 // Intermediate Precedence: |, &, ^
390 // FIXME: gas seems to support '!' as an infix operator?
392 Kind = MCBinaryExpr::Or;
394 case AsmToken::Caret:
395 Kind = MCBinaryExpr::Xor;
398 Kind = MCBinaryExpr::And;
401 // Highest Precedence: *, /, %, <<, >>
403 Kind = MCBinaryExpr::Mul;
405 case AsmToken::Slash:
406 Kind = MCBinaryExpr::Div;
408 case AsmToken::Percent:
409 Kind = MCBinaryExpr::Mod;
411 case AsmToken::LessLess:
412 Kind = MCBinaryExpr::Shl;
414 case AsmToken::GreaterGreater:
415 Kind = MCBinaryExpr::Shr;
421 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
422 /// Res contains the LHS of the expression on input.
423 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
426 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
427 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
429 // If the next token is lower precedence than we are allowed to eat, return
430 // successfully with what we ate already.
431 if (TokPrec < Precedence)
436 // Eat the next primary expression.
438 if (ParsePrimaryExpr(RHS, EndLoc)) return true;
440 // If BinOp binds less tightly with RHS than the operator after RHS, let
441 // the pending operator take RHS as its LHS.
442 MCBinaryExpr::Opcode Dummy;
443 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
444 if (TokPrec < NextTokPrec) {
445 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
448 // Merge LHS and RHS according to operator.
449 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
457 /// ::= EndOfStatement
458 /// ::= Label* Directive ...Operands... EndOfStatement
459 /// ::= Label* Identifier OperandList* EndOfStatement
460 bool AsmParser::ParseStatement() {
461 if (Lexer.is(AsmToken::EndOfStatement)) {
467 // Statements always start with an identifier.
468 AsmToken ID = getTok();
469 SMLoc IDLoc = ID.getLoc();
471 int64_t LocalLabelVal = -1;
472 // GUESS allow an integer followed by a ':' as a directional local label
473 if (Lexer.is(AsmToken::Integer)) {
474 LocalLabelVal = getTok().getIntVal();
475 if (LocalLabelVal < 0) {
476 if (!TheCondState.Ignore)
477 return TokError("unexpected token at start of statement");
481 IDVal = getTok().getString();
482 Lex(); // Consume the integer token to be used as an identifier token.
483 if (Lexer.getKind() != AsmToken::Colon) {
484 if (!TheCondState.Ignore)
485 return TokError("unexpected token at start of statement");
489 else if (ParseIdentifier(IDVal)) {
490 if (!TheCondState.Ignore)
491 return TokError("unexpected token at start of statement");
495 // Handle conditional assembly here before checking for skipping. We
496 // have to do this so that .endif isn't skipped in a ".if 0" block for
499 return ParseDirectiveIf(IDLoc);
500 if (IDVal == ".elseif")
501 return ParseDirectiveElseIf(IDLoc);
502 if (IDVal == ".else")
503 return ParseDirectiveElse(IDLoc);
504 if (IDVal == ".endif")
505 return ParseDirectiveEndIf(IDLoc);
507 // If we are in a ".if 0" block, ignore this statement.
508 if (TheCondState.Ignore) {
509 EatToEndOfStatement();
513 // FIXME: Recurse on local labels?
515 // See what kind of statement we have.
516 switch (Lexer.getKind()) {
517 case AsmToken::Colon: {
518 // identifier ':' -> Label.
521 // Diagnose attempt to use a variable as a label.
523 // FIXME: Diagnostics. Note the location of the definition as a label.
524 // FIXME: This doesn't diagnose assignment to a symbol which has been
525 // implicitly marked as external.
527 if (LocalLabelVal == -1)
528 Sym = CreateSymbol(IDVal);
530 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
531 if (!Sym->isUndefined() || Sym->isVariable())
532 return Error(IDLoc, "invalid symbol redefinition");
537 // Consume any end of statement token, if present, to avoid spurious
538 // AddBlankLine calls().
539 if (Lexer.is(AsmToken::EndOfStatement)) {
541 if (Lexer.is(AsmToken::Eof))
545 return ParseStatement();
548 case AsmToken::Equal:
549 // identifier '=' ... -> assignment statement
552 return ParseAssignment(IDVal);
554 default: // Normal instruction or directive.
558 // Otherwise, we have a normal instruction or directive.
559 if (IDVal[0] == '.') {
560 // FIXME: This should be driven based on a hash lookup and callback.
561 if (IDVal == ".section")
562 return ParseDirectiveDarwinSection();
563 if (IDVal == ".text")
564 // FIXME: This changes behavior based on the -static flag to the
566 return ParseDirectiveSectionSwitch("__TEXT", "__text",
567 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
568 if (IDVal == ".const")
569 return ParseDirectiveSectionSwitch("__TEXT", "__const");
570 if (IDVal == ".static_const")
571 return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
572 if (IDVal == ".cstring")
573 return ParseDirectiveSectionSwitch("__TEXT","__cstring",
574 MCSectionMachO::S_CSTRING_LITERALS);
575 if (IDVal == ".literal4")
576 return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
577 MCSectionMachO::S_4BYTE_LITERALS,
579 if (IDVal == ".literal8")
580 return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
581 MCSectionMachO::S_8BYTE_LITERALS,
583 if (IDVal == ".literal16")
584 return ParseDirectiveSectionSwitch("__TEXT","__literal16",
585 MCSectionMachO::S_16BYTE_LITERALS,
587 if (IDVal == ".constructor")
588 return ParseDirectiveSectionSwitch("__TEXT","__constructor");
589 if (IDVal == ".destructor")
590 return ParseDirectiveSectionSwitch("__TEXT","__destructor");
591 if (IDVal == ".fvmlib_init0")
592 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
593 if (IDVal == ".fvmlib_init1")
594 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
596 // FIXME: The assembler manual claims that this has the self modify code
597 // flag, at least on x86-32, but that does not appear to be correct.
598 if (IDVal == ".symbol_stub")
599 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
600 MCSectionMachO::S_SYMBOL_STUBS |
601 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
602 // FIXME: Different on PPC and ARM.
604 // FIXME: PowerPC only?
605 if (IDVal == ".picsymbol_stub")
606 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
607 MCSectionMachO::S_SYMBOL_STUBS |
608 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
610 if (IDVal == ".data")
611 return ParseDirectiveSectionSwitch("__DATA", "__data");
612 if (IDVal == ".static_data")
613 return ParseDirectiveSectionSwitch("__DATA", "__static_data");
615 // FIXME: The section names of these two are misspelled in the assembler
617 if (IDVal == ".non_lazy_symbol_pointer")
618 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
619 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
621 if (IDVal == ".lazy_symbol_pointer")
622 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
623 MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
626 if (IDVal == ".dyld")
627 return ParseDirectiveSectionSwitch("__DATA", "__dyld");
628 if (IDVal == ".mod_init_func")
629 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
630 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
632 if (IDVal == ".mod_term_func")
633 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
634 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
636 if (IDVal == ".const_data")
637 return ParseDirectiveSectionSwitch("__DATA", "__const");
640 if (IDVal == ".objc_class")
641 return ParseDirectiveSectionSwitch("__OBJC", "__class",
642 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
643 if (IDVal == ".objc_meta_class")
644 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
645 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
646 if (IDVal == ".objc_cat_cls_meth")
647 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
648 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
649 if (IDVal == ".objc_cat_inst_meth")
650 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
651 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
652 if (IDVal == ".objc_protocol")
653 return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
654 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
655 if (IDVal == ".objc_string_object")
656 return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
657 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
658 if (IDVal == ".objc_cls_meth")
659 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
660 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
661 if (IDVal == ".objc_inst_meth")
662 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
663 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
664 if (IDVal == ".objc_cls_refs")
665 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
666 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
667 MCSectionMachO::S_LITERAL_POINTERS,
669 if (IDVal == ".objc_message_refs")
670 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
671 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
672 MCSectionMachO::S_LITERAL_POINTERS,
674 if (IDVal == ".objc_symbols")
675 return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
676 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
677 if (IDVal == ".objc_category")
678 return ParseDirectiveSectionSwitch("__OBJC", "__category",
679 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
680 if (IDVal == ".objc_class_vars")
681 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
682 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
683 if (IDVal == ".objc_instance_vars")
684 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
685 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
686 if (IDVal == ".objc_module_info")
687 return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
688 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
689 if (IDVal == ".objc_class_names")
690 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
691 MCSectionMachO::S_CSTRING_LITERALS);
692 if (IDVal == ".objc_meth_var_types")
693 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
694 MCSectionMachO::S_CSTRING_LITERALS);
695 if (IDVal == ".objc_meth_var_names")
696 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
697 MCSectionMachO::S_CSTRING_LITERALS);
698 if (IDVal == ".objc_selector_strs")
699 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
700 MCSectionMachO::S_CSTRING_LITERALS);
702 if (IDVal == ".tdata")
703 return ParseDirectiveSectionSwitch("__DATA", "__thread_data",
704 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
706 return ParseDirectiveSectionSwitch("__DATA", "__thread_vars",
707 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
708 if (IDVal == ".thread_init_func")
709 return ParseDirectiveSectionSwitch("__DATA", "__thread_init",
710 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
712 // Assembler features
714 return ParseDirectiveSet();
718 if (IDVal == ".ascii")
719 return ParseDirectiveAscii(false);
720 if (IDVal == ".asciz")
721 return ParseDirectiveAscii(true);
723 if (IDVal == ".byte")
724 return ParseDirectiveValue(1);
725 if (IDVal == ".short")
726 return ParseDirectiveValue(2);
727 if (IDVal == ".long")
728 return ParseDirectiveValue(4);
729 if (IDVal == ".quad")
730 return ParseDirectiveValue(8);
732 // FIXME: Target hooks for IsPow2.
733 if (IDVal == ".align")
734 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
735 if (IDVal == ".align32")
736 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
737 if (IDVal == ".balign")
738 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
739 if (IDVal == ".balignw")
740 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
741 if (IDVal == ".balignl")
742 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
743 if (IDVal == ".p2align")
744 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
745 if (IDVal == ".p2alignw")
746 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
747 if (IDVal == ".p2alignl")
748 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
751 return ParseDirectiveOrg();
753 if (IDVal == ".fill")
754 return ParseDirectiveFill();
755 if (IDVal == ".space")
756 return ParseDirectiveSpace();
758 // Symbol attribute directives
760 if (IDVal == ".globl" || IDVal == ".global")
761 return ParseDirectiveSymbolAttribute(MCSA_Global);
762 if (IDVal == ".hidden")
763 return ParseDirectiveSymbolAttribute(MCSA_Hidden);
764 if (IDVal == ".indirect_symbol")
765 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
766 if (IDVal == ".internal")
767 return ParseDirectiveSymbolAttribute(MCSA_Internal);
768 if (IDVal == ".lazy_reference")
769 return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
770 if (IDVal == ".no_dead_strip")
771 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
772 if (IDVal == ".private_extern")
773 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
774 if (IDVal == ".protected")
775 return ParseDirectiveSymbolAttribute(MCSA_Protected);
776 if (IDVal == ".reference")
777 return ParseDirectiveSymbolAttribute(MCSA_Reference);
778 if (IDVal == ".type")
779 return ParseDirectiveELFType();
780 if (IDVal == ".weak")
781 return ParseDirectiveSymbolAttribute(MCSA_Weak);
782 if (IDVal == ".weak_definition")
783 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
784 if (IDVal == ".weak_reference")
785 return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
786 if (IDVal == ".weak_def_can_be_hidden")
787 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
789 if (IDVal == ".comm")
790 return ParseDirectiveComm(/*IsLocal=*/false);
791 if (IDVal == ".lcomm")
792 return ParseDirectiveComm(/*IsLocal=*/true);
793 if (IDVal == ".zerofill")
794 return ParseDirectiveDarwinZerofill();
795 if (IDVal == ".desc")
796 return ParseDirectiveDarwinSymbolDesc();
797 if (IDVal == ".lsym")
798 return ParseDirectiveDarwinLsym();
799 if (IDVal == ".tbss")
800 return ParseDirectiveDarwinTBSS();
802 if (IDVal == ".subsections_via_symbols")
803 return ParseDirectiveDarwinSubsectionsViaSymbols();
804 if (IDVal == ".abort")
805 return ParseDirectiveAbort();
806 if (IDVal == ".include")
807 return ParseDirectiveInclude();
808 if (IDVal == ".dump")
809 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
810 if (IDVal == ".load")
811 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
812 if (IDVal == ".secure_log_unique")
813 return ParseDirectiveDarwinSecureLogUnique(IDLoc);
814 if (IDVal == ".secure_log_reset")
815 return ParseDirectiveDarwinSecureLogReset(IDLoc);
817 // Look up the handler in the handler table.
818 std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
819 DirectiveMap.lookup(IDVal);
821 return (Handler.first->*Handler.second)(IDVal, IDLoc);
823 // Target hook for parsing target specific directives.
824 if (!getTargetParser().ParseDirective(ID))
827 Warning(IDLoc, "ignoring directive for now");
828 EatToEndOfStatement();
832 // Canonicalize the opcode to lower case.
833 SmallString<128> Opcode;
834 for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
835 Opcode.push_back(tolower(IDVal[i]));
837 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
838 bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
840 if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
841 HadError = TokError("unexpected token in argument list");
843 // If parsing succeeded, match the instruction.
846 if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
847 // Emit the instruction on success.
848 Out.EmitInstruction(Inst);
850 // Otherwise emit a diagnostic about the match failure and set the error
853 // FIXME: We should give nicer diagnostics about the exact failure.
854 Error(IDLoc, "unrecognized instruction");
859 // If there was no error, consume the end-of-statement token. Otherwise this
860 // will be done by our caller.
864 // Free any parsed operands.
865 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
866 delete ParsedOperands[i];
871 bool AsmParser::ParseAssignment(const StringRef &Name) {
872 // FIXME: Use better location, we should use proper tokens.
873 SMLoc EqualLoc = Lexer.getLoc();
876 if (ParseExpression(Value))
879 if (Lexer.isNot(AsmToken::EndOfStatement))
880 return TokError("unexpected token in assignment");
882 // Eat the end of statement marker.
885 // Validate that the LHS is allowed to be a variable (either it has not been
886 // used as a symbol, or it is an absolute symbol).
887 MCSymbol *Sym = getContext().LookupSymbol(Name);
889 // Diagnose assignment to a label.
891 // FIXME: Diagnostics. Note the location of the definition as a label.
892 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
893 if (Sym->isUndefined() && !Sym->isUsedInExpr())
894 ; // Allow redefinitions of undefined symbols only used in directives.
895 else if (!Sym->isUndefined() && !Sym->isAbsolute())
896 return Error(EqualLoc, "redefinition of '" + Name + "'");
897 else if (!Sym->isVariable())
898 return Error(EqualLoc, "invalid assignment to '" + Name + "'");
899 else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
900 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
903 Sym = CreateSymbol(Name);
905 // FIXME: Handle '.'.
907 Sym->setUsedInExpr(true);
909 // Do the assignment.
910 Out.EmitAssignment(Sym, Value);
918 bool AsmParser::ParseIdentifier(StringRef &Res) {
919 if (Lexer.isNot(AsmToken::Identifier) &&
920 Lexer.isNot(AsmToken::String))
923 Res = getTok().getIdentifier();
925 Lex(); // Consume the identifier token.
930 /// ParseDirectiveSet:
931 /// ::= .set identifier ',' expression
932 bool AsmParser::ParseDirectiveSet() {
935 if (ParseIdentifier(Name))
936 return TokError("expected identifier after '.set' directive");
938 if (getLexer().isNot(AsmToken::Comma))
939 return TokError("unexpected token in '.set'");
942 return ParseAssignment(Name);
945 /// ParseDirectiveSection:
946 /// ::= .section identifier (',' identifier)*
947 /// FIXME: This should actually parse out the segment, section, attributes and
948 /// sizeof_stub fields.
949 bool AsmParser::ParseDirectiveDarwinSection() {
950 SMLoc Loc = getLexer().getLoc();
952 StringRef SectionName;
953 if (ParseIdentifier(SectionName))
954 return Error(Loc, "expected identifier after '.section' directive");
956 // Verify there is a following comma.
957 if (!getLexer().is(AsmToken::Comma))
958 return TokError("unexpected token in '.section' directive");
960 std::string SectionSpec = SectionName;
963 // Add all the tokens until the end of the line, ParseSectionSpecifier will
965 StringRef EOL = Lexer.LexUntilEndOfStatement();
966 SectionSpec.append(EOL.begin(), EOL.end());
969 if (getLexer().isNot(AsmToken::EndOfStatement))
970 return TokError("unexpected token in '.section' directive");
974 StringRef Segment, Section;
975 unsigned TAA, StubSize;
976 std::string ErrorStr =
977 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
980 if (!ErrorStr.empty())
981 return Error(Loc, ErrorStr.c_str());
983 // FIXME: Arch specific.
984 bool isText = Segment == "__TEXT"; // FIXME: Hack.
985 getStreamer().SwitchSection(Ctx.getMachOSection(
986 Segment, Section, TAA, StubSize,
987 isText ? SectionKind::getText()
988 : SectionKind::getDataRel()));
992 /// ParseDirectiveSectionSwitch -
993 bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
995 unsigned TAA, unsigned Align,
997 if (getLexer().isNot(AsmToken::EndOfStatement))
998 return TokError("unexpected token in section switching directive");
1001 // FIXME: Arch specific.
1002 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
1003 getStreamer().SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
1004 isText ? SectionKind::getText()
1005 : SectionKind::getDataRel()));
1007 // Set the implicit alignment, if any.
1009 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
1010 // alignment on the section (e.g., if one manually inserts bytes into the
1011 // section, then just issueing the section switch directive will not realign
1012 // the section. However, this is arguably more reasonable behavior, and there
1013 // is no good reason for someone to intentionally emit incorrectly sized
1014 // values into the implicitly aligned sections.
1016 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
1021 bool AsmParser::ParseEscapedString(std::string &Data) {
1022 assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
1025 StringRef Str = getTok().getStringContents();
1026 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
1027 if (Str[i] != '\\') {
1032 // Recognize escaped characters. Note that this escape semantics currently
1033 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1036 return TokError("unexpected backslash at end of string");
1038 // Recognize octal sequences.
1039 if ((unsigned) (Str[i] - '0') <= 7) {
1040 // Consume up to three octal characters.
1041 unsigned Value = Str[i] - '0';
1043 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1045 Value = Value * 8 + (Str[i] - '0');
1047 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1049 Value = Value * 8 + (Str[i] - '0');
1054 return TokError("invalid octal escape sequence (out of range)");
1056 Data += (unsigned char) Value;
1060 // Otherwise recognize individual escapes.
1063 // Just reject invalid escape sequences for now.
1064 return TokError("invalid escape sequence (unrecognized character)");
1066 case 'b': Data += '\b'; break;
1067 case 'f': Data += '\f'; break;
1068 case 'n': Data += '\n'; break;
1069 case 'r': Data += '\r'; break;
1070 case 't': Data += '\t'; break;
1071 case '"': Data += '"'; break;
1072 case '\\': Data += '\\'; break;
1079 /// ParseDirectiveAscii:
1080 /// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
1081 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
1082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1084 if (getLexer().isNot(AsmToken::String))
1085 return TokError("expected string in '.ascii' or '.asciz' directive");
1088 if (ParseEscapedString(Data))
1091 getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
1093 getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
1097 if (getLexer().is(AsmToken::EndOfStatement))
1100 if (getLexer().isNot(AsmToken::Comma))
1101 return TokError("unexpected token in '.ascii' or '.asciz' directive");
1110 /// ParseDirectiveValue
1111 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
1112 bool AsmParser::ParseDirectiveValue(unsigned Size) {
1113 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1115 const MCExpr *Value;
1116 SMLoc ATTRIBUTE_UNUSED StartLoc = getLexer().getLoc();
1117 if (ParseExpression(Value))
1120 // Special case constant expressions to match code generator.
1121 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value))
1122 getStreamer().EmitIntValue(MCE->getValue(), Size, DEFAULT_ADDRSPACE);
1124 getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1126 if (getLexer().is(AsmToken::EndOfStatement))
1129 // FIXME: Improve diagnostic.
1130 if (getLexer().isNot(AsmToken::Comma))
1131 return TokError("unexpected token in directive");
1140 /// ParseDirectiveSpace
1141 /// ::= .space expression [ , expression ]
1142 bool AsmParser::ParseDirectiveSpace() {
1144 if (ParseAbsoluteExpression(NumBytes))
1147 int64_t FillExpr = 0;
1148 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1149 if (getLexer().isNot(AsmToken::Comma))
1150 return TokError("unexpected token in '.space' directive");
1153 if (ParseAbsoluteExpression(FillExpr))
1156 if (getLexer().isNot(AsmToken::EndOfStatement))
1157 return TokError("unexpected token in '.space' directive");
1163 return TokError("invalid number of bytes in '.space' directive");
1165 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1166 getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1171 /// ParseDirectiveFill
1172 /// ::= .fill expression , expression , expression
1173 bool AsmParser::ParseDirectiveFill() {
1175 if (ParseAbsoluteExpression(NumValues))
1178 if (getLexer().isNot(AsmToken::Comma))
1179 return TokError("unexpected token in '.fill' directive");
1183 if (ParseAbsoluteExpression(FillSize))
1186 if (getLexer().isNot(AsmToken::Comma))
1187 return TokError("unexpected token in '.fill' directive");
1191 if (ParseAbsoluteExpression(FillExpr))
1194 if (getLexer().isNot(AsmToken::EndOfStatement))
1195 return TokError("unexpected token in '.fill' directive");
1199 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1200 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1202 for (uint64_t i = 0, e = NumValues; i != e; ++i)
1203 getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
1208 /// ParseDirectiveOrg
1209 /// ::= .org expression [ , expression ]
1210 bool AsmParser::ParseDirectiveOrg() {
1211 const MCExpr *Offset;
1212 if (ParseExpression(Offset))
1215 // Parse optional fill expression.
1216 int64_t FillExpr = 0;
1217 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1218 if (getLexer().isNot(AsmToken::Comma))
1219 return TokError("unexpected token in '.org' directive");
1222 if (ParseAbsoluteExpression(FillExpr))
1225 if (getLexer().isNot(AsmToken::EndOfStatement))
1226 return TokError("unexpected token in '.org' directive");
1231 // FIXME: Only limited forms of relocatable expressions are accepted here, it
1232 // has to be relative to the current section.
1233 getStreamer().EmitValueToOffset(Offset, FillExpr);
1238 /// ParseDirectiveAlign
1239 /// ::= {.align, ...} expression [ , expression [ , expression ]]
1240 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1241 SMLoc AlignmentLoc = getLexer().getLoc();
1243 if (ParseAbsoluteExpression(Alignment))
1247 bool HasFillExpr = false;
1248 int64_t FillExpr = 0;
1249 int64_t MaxBytesToFill = 0;
1250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1251 if (getLexer().isNot(AsmToken::Comma))
1252 return TokError("unexpected token in directive");
1255 // The fill expression can be omitted while specifying a maximum number of
1256 // alignment bytes, e.g:
1258 if (getLexer().isNot(AsmToken::Comma)) {
1260 if (ParseAbsoluteExpression(FillExpr))
1264 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1265 if (getLexer().isNot(AsmToken::Comma))
1266 return TokError("unexpected token in directive");
1269 MaxBytesLoc = getLexer().getLoc();
1270 if (ParseAbsoluteExpression(MaxBytesToFill))
1273 if (getLexer().isNot(AsmToken::EndOfStatement))
1274 return TokError("unexpected token in directive");
1283 // Compute alignment in bytes.
1285 // FIXME: Diagnose overflow.
1286 if (Alignment >= 32) {
1287 Error(AlignmentLoc, "invalid alignment value");
1291 Alignment = 1ULL << Alignment;
1294 // Diagnose non-sensical max bytes to align.
1295 if (MaxBytesLoc.isValid()) {
1296 if (MaxBytesToFill < 1) {
1297 Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1298 "many bytes, ignoring maximum bytes expression");
1302 if (MaxBytesToFill >= Alignment) {
1303 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1309 // Check whether we should use optimal code alignment for this .align
1312 // FIXME: This should be using a target hook.
1313 bool UseCodeAlign = false;
1314 if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>(
1315 getStreamer().getCurrentSection()))
1316 UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
1317 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
1318 ValueSize == 1 && UseCodeAlign) {
1319 getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
1321 // FIXME: Target specific behavior about how the "extra" bytes are filled.
1322 getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1328 /// ParseDirectiveSymbolAttribute
1329 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1330 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
1331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1335 if (ParseIdentifier(Name))
1336 return TokError("expected identifier in directive");
1338 MCSymbol *Sym = CreateSymbol(Name);
1340 getStreamer().EmitSymbolAttribute(Sym, Attr);
1342 if (getLexer().is(AsmToken::EndOfStatement))
1345 if (getLexer().isNot(AsmToken::Comma))
1346 return TokError("unexpected token in directive");
1355 /// ParseDirectiveELFType
1356 /// ::= .type identifier , @attribute
1357 bool AsmParser::ParseDirectiveELFType() {
1359 if (ParseIdentifier(Name))
1360 return TokError("expected identifier in directive");
1362 // Handle the identifier as the key symbol.
1363 MCSymbol *Sym = CreateSymbol(Name);
1365 if (getLexer().isNot(AsmToken::Comma))
1366 return TokError("unexpected token in '.type' directive");
1369 if (getLexer().isNot(AsmToken::At))
1370 return TokError("expected '@' before type");
1376 TypeLoc = getLexer().getLoc();
1377 if (ParseIdentifier(Type))
1378 return TokError("expected symbol type in directive");
1380 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
1381 .Case("function", MCSA_ELF_TypeFunction)
1382 .Case("object", MCSA_ELF_TypeObject)
1383 .Case("tls_object", MCSA_ELF_TypeTLS)
1384 .Case("common", MCSA_ELF_TypeCommon)
1385 .Case("notype", MCSA_ELF_TypeNoType)
1386 .Default(MCSA_Invalid);
1388 if (Attr == MCSA_Invalid)
1389 return Error(TypeLoc, "unsupported attribute in '.type' directive");
1391 if (getLexer().isNot(AsmToken::EndOfStatement))
1392 return TokError("unexpected token in '.type' directive");
1396 getStreamer().EmitSymbolAttribute(Sym, Attr);
1401 /// ParseDirectiveDarwinSymbolDesc
1402 /// ::= .desc identifier , expression
1403 bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
1405 if (ParseIdentifier(Name))
1406 return TokError("expected identifier in directive");
1408 // Handle the identifier as the key symbol.
1409 MCSymbol *Sym = CreateSymbol(Name);
1411 if (getLexer().isNot(AsmToken::Comma))
1412 return TokError("unexpected token in '.desc' directive");
1416 if (ParseAbsoluteExpression(DescValue))
1419 if (getLexer().isNot(AsmToken::EndOfStatement))
1420 return TokError("unexpected token in '.desc' directive");
1424 // Set the n_desc field of this Symbol to this DescValue
1425 getStreamer().EmitSymbolDesc(Sym, DescValue);
1430 /// ParseDirectiveComm
1431 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1432 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1433 SMLoc IDLoc = getLexer().getLoc();
1435 if (ParseIdentifier(Name))
1436 return TokError("expected identifier in directive");
1438 // Handle the identifier as the key symbol.
1439 MCSymbol *Sym = CreateSymbol(Name);
1441 if (getLexer().isNot(AsmToken::Comma))
1442 return TokError("unexpected token in directive");
1446 SMLoc SizeLoc = getLexer().getLoc();
1447 if (ParseAbsoluteExpression(Size))
1450 int64_t Pow2Alignment = 0;
1451 SMLoc Pow2AlignmentLoc;
1452 if (getLexer().is(AsmToken::Comma)) {
1454 Pow2AlignmentLoc = getLexer().getLoc();
1455 if (ParseAbsoluteExpression(Pow2Alignment))
1458 // If this target takes alignments in bytes (not log) validate and convert.
1459 if (Lexer.getMAI().getAlignmentIsInBytes()) {
1460 if (!isPowerOf2_64(Pow2Alignment))
1461 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1462 Pow2Alignment = Log2_64(Pow2Alignment);
1466 if (getLexer().isNot(AsmToken::EndOfStatement))
1467 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1471 // NOTE: a size of zero for a .comm should create a undefined symbol
1472 // but a size of .lcomm creates a bss symbol of size zero.
1474 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1475 "be less than zero");
1477 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1478 // may internally end up wanting an alignment in bytes.
1479 // FIXME: Diagnose overflow.
1480 if (Pow2Alignment < 0)
1481 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1482 "alignment, can't be less than zero");
1484 if (!Sym->isUndefined())
1485 return Error(IDLoc, "invalid symbol redefinition");
1487 // '.lcomm' is equivalent to '.zerofill'.
1488 // Create the Symbol as a common or local common with Size and Pow2Alignment
1490 getStreamer().EmitZerofill(Ctx.getMachOSection(
1491 "__DATA", "__bss", MCSectionMachO::S_ZEROFILL,
1492 0, SectionKind::getBSS()),
1493 Sym, Size, 1 << Pow2Alignment);
1497 getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1501 /// ParseDirectiveDarwinZerofill
1502 /// ::= .zerofill segname , sectname [, identifier , size_expression [
1503 /// , align_expression ]]
1504 bool AsmParser::ParseDirectiveDarwinZerofill() {
1506 if (ParseIdentifier(Segment))
1507 return TokError("expected segment name after '.zerofill' directive");
1509 if (getLexer().isNot(AsmToken::Comma))
1510 return TokError("unexpected token in directive");
1514 if (ParseIdentifier(Section))
1515 return TokError("expected section name after comma in '.zerofill' "
1518 // If this is the end of the line all that was wanted was to create the
1519 // the section but with no symbol.
1520 if (getLexer().is(AsmToken::EndOfStatement)) {
1521 // Create the zerofill section but no symbol
1522 getStreamer().EmitZerofill(Ctx.getMachOSection(Segment, Section,
1523 MCSectionMachO::S_ZEROFILL, 0,
1524 SectionKind::getBSS()));
1528 if (getLexer().isNot(AsmToken::Comma))
1529 return TokError("unexpected token in directive");
1532 SMLoc IDLoc = getLexer().getLoc();
1534 if (ParseIdentifier(IDStr))
1535 return TokError("expected identifier in directive");
1537 // handle the identifier as the key symbol.
1538 MCSymbol *Sym = CreateSymbol(IDStr);
1540 if (getLexer().isNot(AsmToken::Comma))
1541 return TokError("unexpected token in directive");
1545 SMLoc SizeLoc = getLexer().getLoc();
1546 if (ParseAbsoluteExpression(Size))
1549 int64_t Pow2Alignment = 0;
1550 SMLoc Pow2AlignmentLoc;
1551 if (getLexer().is(AsmToken::Comma)) {
1553 Pow2AlignmentLoc = getLexer().getLoc();
1554 if (ParseAbsoluteExpression(Pow2Alignment))
1558 if (getLexer().isNot(AsmToken::EndOfStatement))
1559 return TokError("unexpected token in '.zerofill' directive");
1564 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1567 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1568 // may internally end up wanting an alignment in bytes.
1569 // FIXME: Diagnose overflow.
1570 if (Pow2Alignment < 0)
1571 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1572 "can't be less than zero");
1574 if (!Sym->isUndefined())
1575 return Error(IDLoc, "invalid symbol redefinition");
1577 // Create the zerofill Symbol with Size and Pow2Alignment
1579 // FIXME: Arch specific.
1580 getStreamer().EmitZerofill(Ctx.getMachOSection(Segment, Section,
1581 MCSectionMachO::S_ZEROFILL, 0,
1582 SectionKind::getBSS()),
1583 Sym, Size, 1 << Pow2Alignment);
1588 /// ParseDirectiveDarwinTBSS
1589 /// ::= .tbss identifier, size, align
1590 bool AsmParser::ParseDirectiveDarwinTBSS() {
1591 SMLoc IDLoc = getLexer().getLoc();
1593 if (ParseIdentifier(Name))
1594 return TokError("expected identifier in directive");
1596 // Handle the identifier as the key symbol.
1597 MCSymbol *Sym = CreateSymbol(Name);
1599 if (getLexer().isNot(AsmToken::Comma))
1600 return TokError("unexpected token in directive");
1604 SMLoc SizeLoc = getLexer().getLoc();
1605 if (ParseAbsoluteExpression(Size))
1608 int64_t Pow2Alignment = 0;
1609 SMLoc Pow2AlignmentLoc;
1610 if (getLexer().is(AsmToken::Comma)) {
1612 Pow2AlignmentLoc = getLexer().getLoc();
1613 if (ParseAbsoluteExpression(Pow2Alignment))
1617 if (getLexer().isNot(AsmToken::EndOfStatement))
1618 return TokError("unexpected token in '.tbss' directive");
1623 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
1626 // FIXME: Diagnose overflow.
1627 if (Pow2Alignment < 0)
1628 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
1631 if (!Sym->isUndefined())
1632 return Error(IDLoc, "invalid symbol redefinition");
1634 getStreamer().EmitTBSSSymbol(Ctx.getMachOSection(
1635 "__DATA", "__thread_bss",
1636 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
1637 0, SectionKind::getThreadBSS()),
1638 Sym, Size, 1 << Pow2Alignment);
1643 /// ParseDirectiveDarwinSubsectionsViaSymbols
1644 /// ::= .subsections_via_symbols
1645 bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
1646 if (getLexer().isNot(AsmToken::EndOfStatement))
1647 return TokError("unexpected token in '.subsections_via_symbols' directive");
1651 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1656 /// ParseDirectiveAbort
1657 /// ::= .abort [ "abort_string" ]
1658 bool AsmParser::ParseDirectiveAbort() {
1659 // FIXME: Use loc from directive.
1660 SMLoc Loc = getLexer().getLoc();
1663 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1664 if (getLexer().isNot(AsmToken::String))
1665 return TokError("expected string in '.abort' directive");
1667 Str = getTok().getString();
1672 if (getLexer().isNot(AsmToken::EndOfStatement))
1673 return TokError("unexpected token in '.abort' directive");
1677 // FIXME: Handle here.
1679 Error(Loc, ".abort detected. Assembly stopping.");
1681 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1686 /// ParseDirectiveLsym
1687 /// ::= .lsym identifier , expression
1688 bool AsmParser::ParseDirectiveDarwinLsym() {
1690 if (ParseIdentifier(Name))
1691 return TokError("expected identifier in directive");
1693 // Handle the identifier as the key symbol.
1694 MCSymbol *Sym = CreateSymbol(Name);
1696 if (getLexer().isNot(AsmToken::Comma))
1697 return TokError("unexpected token in '.lsym' directive");
1700 const MCExpr *Value;
1701 if (ParseExpression(Value))
1704 if (getLexer().isNot(AsmToken::EndOfStatement))
1705 return TokError("unexpected token in '.lsym' directive");
1709 // We don't currently support this directive.
1711 // FIXME: Diagnostic location!
1713 return TokError("directive '.lsym' is unsupported");
1716 /// ParseDirectiveInclude
1717 /// ::= .include "filename"
1718 bool AsmParser::ParseDirectiveInclude() {
1719 if (getLexer().isNot(AsmToken::String))
1720 return TokError("expected string in '.include' directive");
1722 std::string Filename = getTok().getString();
1723 SMLoc IncludeLoc = getLexer().getLoc();
1726 if (getLexer().isNot(AsmToken::EndOfStatement))
1727 return TokError("unexpected token in '.include' directive");
1729 // Strip the quotes.
1730 Filename = Filename.substr(1, Filename.size()-2);
1732 // Attempt to switch the lexer to the included file before consuming the end
1733 // of statement to avoid losing it when we switch.
1734 if (EnterIncludeFile(Filename)) {
1735 PrintMessage(IncludeLoc,
1736 "Could not find include file '" + Filename + "'",
1744 /// ParseDirectiveDarwinDumpOrLoad
1745 /// ::= ( .dump | .load ) "filename"
1746 bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
1747 if (getLexer().isNot(AsmToken::String))
1748 return TokError("expected string in '.dump' or '.load' directive");
1752 if (getLexer().isNot(AsmToken::EndOfStatement))
1753 return TokError("unexpected token in '.dump' or '.load' directive");
1757 // FIXME: If/when .dump and .load are implemented they will be done in the
1758 // the assembly parser and not have any need for an MCStreamer API.
1760 Warning(IDLoc, "ignoring directive .dump for now");
1762 Warning(IDLoc, "ignoring directive .load for now");
1767 /// ParseDirectiveDarwinSecureLogUnique
1768 /// ::= .secure_log_unique "log message"
1769 bool AsmParser::ParseDirectiveDarwinSecureLogUnique(SMLoc IDLoc) {
1770 std::string LogMessage;
1772 if (Lexer.isNot(AsmToken::String))
1775 LogMessage = getTok().getString();
1779 if (Lexer.isNot(AsmToken::EndOfStatement))
1780 return TokError("unexpected token in '.secure_log_unique' directive");
1782 if (getContext().getSecureLogUsed() != false)
1783 return Error(IDLoc, ".secure_log_unique specified multiple times");
1785 char *SecureLogFile = getContext().getSecureLogFile();
1786 if (SecureLogFile == NULL)
1787 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
1788 "environment variable unset.");
1790 raw_ostream *OS = getContext().getSecureLog();
1793 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
1796 return Error(IDLoc, Twine("can't open secure log file: ") +
1797 SecureLogFile + " (" + Err + ")");
1799 getContext().setSecureLog(OS);
1802 int CurBuf = SrcMgr.FindBufferContainingLoc(IDLoc);
1803 *OS << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"
1804 << SrcMgr.FindLineNumber(IDLoc, CurBuf) << ":"
1805 << LogMessage + "\n";
1807 getContext().setSecureLogUsed(true);
1812 /// ParseDirectiveDarwinSecureLogReset
1813 /// ::= .secure_log_reset
1814 bool AsmParser::ParseDirectiveDarwinSecureLogReset(SMLoc IDLoc) {
1815 if (getLexer().isNot(AsmToken::EndOfStatement))
1816 return TokError("unexpected token in '.secure_log_reset' directive");
1820 getContext().setSecureLogUsed(false);
1825 /// ParseDirectiveIf
1826 /// ::= .if expression
1827 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1828 TheCondStack.push_back(TheCondState);
1829 TheCondState.TheCond = AsmCond::IfCond;
1830 if(TheCondState.Ignore) {
1831 EatToEndOfStatement();
1835 if (ParseAbsoluteExpression(ExprValue))
1838 if (getLexer().isNot(AsmToken::EndOfStatement))
1839 return TokError("unexpected token in '.if' directive");
1843 TheCondState.CondMet = ExprValue;
1844 TheCondState.Ignore = !TheCondState.CondMet;
1850 /// ParseDirectiveElseIf
1851 /// ::= .elseif expression
1852 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1853 if (TheCondState.TheCond != AsmCond::IfCond &&
1854 TheCondState.TheCond != AsmCond::ElseIfCond)
1855 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1857 TheCondState.TheCond = AsmCond::ElseIfCond;
1859 bool LastIgnoreState = false;
1860 if (!TheCondStack.empty())
1861 LastIgnoreState = TheCondStack.back().Ignore;
1862 if (LastIgnoreState || TheCondState.CondMet) {
1863 TheCondState.Ignore = true;
1864 EatToEndOfStatement();
1868 if (ParseAbsoluteExpression(ExprValue))
1871 if (getLexer().isNot(AsmToken::EndOfStatement))
1872 return TokError("unexpected token in '.elseif' directive");
1875 TheCondState.CondMet = ExprValue;
1876 TheCondState.Ignore = !TheCondState.CondMet;
1882 /// ParseDirectiveElse
1884 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1885 if (getLexer().isNot(AsmToken::EndOfStatement))
1886 return TokError("unexpected token in '.else' directive");
1890 if (TheCondState.TheCond != AsmCond::IfCond &&
1891 TheCondState.TheCond != AsmCond::ElseIfCond)
1892 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1894 TheCondState.TheCond = AsmCond::ElseCond;
1895 bool LastIgnoreState = false;
1896 if (!TheCondStack.empty())
1897 LastIgnoreState = TheCondStack.back().Ignore;
1898 if (LastIgnoreState || TheCondState.CondMet)
1899 TheCondState.Ignore = true;
1901 TheCondState.Ignore = false;
1906 /// ParseDirectiveEndIf
1908 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1909 if (getLexer().isNot(AsmToken::EndOfStatement))
1910 return TokError("unexpected token in '.endif' directive");
1914 if ((TheCondState.TheCond == AsmCond::NoCond) ||
1915 TheCondStack.empty())
1916 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1918 if (!TheCondStack.empty()) {
1919 TheCondState = TheCondStack.back();
1920 TheCondStack.pop_back();
1926 /// ParseDirectiveFile
1927 /// ::= .file [number] string
1928 bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
1929 // FIXME: I'm not sure what this is.
1930 int64_t FileNumber = -1;
1931 if (getLexer().is(AsmToken::Integer)) {
1932 FileNumber = getTok().getIntVal();
1936 return TokError("file number less than one");
1939 if (getLexer().isNot(AsmToken::String))
1940 return TokError("unexpected token in '.file' directive");
1942 StringRef Filename = getTok().getString();
1943 Filename = Filename.substr(1, Filename.size()-2);
1946 if (getLexer().isNot(AsmToken::EndOfStatement))
1947 return TokError("unexpected token in '.file' directive");
1949 if (FileNumber == -1)
1950 getStreamer().EmitFileDirective(Filename);
1952 getStreamer().EmitDwarfFileDirective(FileNumber, Filename);
1957 /// ParseDirectiveLine
1958 /// ::= .line [number]
1959 bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
1960 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1961 if (getLexer().isNot(AsmToken::Integer))
1962 return TokError("unexpected token in '.line' directive");
1964 int64_t LineNumber = getTok().getIntVal();
1968 // FIXME: Do something with the .line.
1971 if (getLexer().isNot(AsmToken::EndOfStatement))
1972 return TokError("unexpected token in '.line' directive");
1978 /// ParseDirectiveLoc
1979 /// ::= .loc number [number [number]]
1980 bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
1981 if (getLexer().isNot(AsmToken::Integer))
1982 return TokError("unexpected token in '.loc' directive");
1984 // FIXME: What are these fields?
1985 int64_t FileNumber = getTok().getIntVal();
1987 // FIXME: Validate file.
1990 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1991 if (getLexer().isNot(AsmToken::Integer))
1992 return TokError("unexpected token in '.loc' directive");
1994 int64_t Param2 = getTok().getIntVal();
1998 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1999 if (getLexer().isNot(AsmToken::Integer))
2000 return TokError("unexpected token in '.loc' directive");
2002 int64_t Param3 = getTok().getIntVal();
2006 // FIXME: Do something with the .loc.
2010 if (getLexer().isNot(AsmToken::EndOfStatement))
2011 return TokError("unexpected token in '.file' directive");