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"
33 enum { DEFAULT_ADDRSPACE = 0 };
35 AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
36 MCStreamer &_Out, const MCAsmInfo &_MAI)
37 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), CurBuffer(0) {
38 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
40 // Debugging directives.
41 AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile);
42 AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine);
43 AddDirectiveHandler(".loc", &AsmParser::ParseDirectiveLoc);
46 AsmParser::~AsmParser() {
49 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
50 PrintMessage(L, Msg.str(), "warning");
53 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
54 PrintMessage(L, Msg.str(), "error");
58 bool AsmParser::TokError(const char *Msg) {
59 PrintMessage(Lexer.getLoc(), Msg, "error");
63 void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg,
64 const char *Type) const {
65 SrcMgr.PrintMessage(Loc, Msg, Type);
68 bool AsmParser::EnterIncludeFile(const std::string &Filename) {
69 int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
75 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
80 const AsmToken &AsmParser::Lex() {
81 const AsmToken *tok = &Lexer.Lex();
83 if (tok->is(AsmToken::Eof)) {
84 // If this is the end of an included file, pop the parent file off the
86 SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
87 if (ParentIncludeLoc != SMLoc()) {
88 CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
89 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer),
90 ParentIncludeLoc.getPointer());
95 if (tok->is(AsmToken::Error))
96 PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
101 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
102 // Create the initial section, if requested.
104 // FIXME: Target hook & command line option for initial section.
105 if (!NoInitialTextSection)
106 Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
107 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
108 0, SectionKind::getText()));
113 bool HadError = false;
115 AsmCond StartingCondState = TheCondState;
117 // While we have input, parse each statement.
118 while (Lexer.isNot(AsmToken::Eof)) {
119 if (!ParseStatement()) continue;
121 // We had an error, remember it and recover by skipping to the next line.
123 EatToEndOfStatement();
126 if (TheCondState.TheCond != StartingCondState.TheCond ||
127 TheCondState.Ignore != StartingCondState.Ignore)
128 return TokError("unmatched .ifs or .elses");
130 // Finalize the output stream if there are no errors and if the client wants
132 if (!HadError && !NoFinalize)
138 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
139 void AsmParser::EatToEndOfStatement() {
140 while (Lexer.isNot(AsmToken::EndOfStatement) &&
141 Lexer.isNot(AsmToken::Eof))
145 if (Lexer.is(AsmToken::EndOfStatement))
150 /// ParseParenExpr - Parse a paren expression and return it.
151 /// NOTE: This assumes the leading '(' has already been consumed.
153 /// parenexpr ::= expr)
155 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
156 if (ParseExpression(Res)) return true;
157 if (Lexer.isNot(AsmToken::RParen))
158 return TokError("expected ')' in parentheses expression");
159 EndLoc = Lexer.getLoc();
164 MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
165 // FIXME: Inline into callers.
166 return Ctx.GetOrCreateSymbol(Name);
169 /// ParsePrimaryExpr - Parse a primary expression and return it.
170 /// primaryexpr ::= (parenexpr
171 /// primaryexpr ::= symbol
172 /// primaryexpr ::= number
173 /// primaryexpr ::= '.'
174 /// primaryexpr ::= ~,+,- primaryexpr
175 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
176 switch (Lexer.getKind()) {
178 return TokError("unknown token in expression");
179 case AsmToken::Exclaim:
180 Lex(); // Eat the operator.
181 if (ParsePrimaryExpr(Res, EndLoc))
183 Res = MCUnaryExpr::CreateLNot(Res, getContext());
185 case AsmToken::String:
186 case AsmToken::Identifier: {
187 // This is a symbol reference.
188 std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
189 MCSymbol *Sym = CreateSymbol(Split.first);
191 // Mark the symbol as used in an expression.
192 Sym->setUsedInExpr(true);
194 // Lookup the symbol variant if used.
195 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
196 if (Split.first.size() != getTok().getIdentifier().size())
197 Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
199 EndLoc = Lexer.getLoc();
200 Lex(); // Eat identifier.
202 // If this is an absolute variable reference, substitute it now to preserve
203 // semantics in the face of reassignment.
204 if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
206 return Error(EndLoc, "unexpected modified on variable reference");
208 Res = Sym->getVariableValue();
212 // Otherwise create a symbol ref.
213 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
216 case AsmToken::Integer: {
217 SMLoc Loc = getTok().getLoc();
218 int64_t IntVal = getTok().getIntVal();
219 Res = MCConstantExpr::Create(IntVal, getContext());
220 EndLoc = Lexer.getLoc();
222 // Look for 'b' or 'f' following an Integer as a directional label
223 if (Lexer.getKind() == AsmToken::Identifier) {
224 StringRef IDVal = getTok().getString();
225 if (IDVal == "f" || IDVal == "b"){
226 MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
227 IDVal == "f" ? 1 : 0);
228 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
230 if(IDVal == "b" && Sym->isUndefined())
231 return Error(Loc, "invalid reference to undefined symbol");
232 EndLoc = Lexer.getLoc();
233 Lex(); // Eat identifier.
238 case AsmToken::Dot: {
239 // This is a '.' reference, which references the current PC. Emit a
240 // temporary label to the streamer and refer to it.
241 MCSymbol *Sym = Ctx.CreateTempSymbol();
243 Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
244 EndLoc = Lexer.getLoc();
245 Lex(); // Eat identifier.
249 case AsmToken::LParen:
250 Lex(); // Eat the '('.
251 return ParseParenExpr(Res, EndLoc);
252 case AsmToken::Minus:
253 Lex(); // Eat the operator.
254 if (ParsePrimaryExpr(Res, EndLoc))
256 Res = MCUnaryExpr::CreateMinus(Res, getContext());
259 Lex(); // Eat the operator.
260 if (ParsePrimaryExpr(Res, EndLoc))
262 Res = MCUnaryExpr::CreatePlus(Res, getContext());
264 case AsmToken::Tilde:
265 Lex(); // Eat the operator.
266 if (ParsePrimaryExpr(Res, EndLoc))
268 Res = MCUnaryExpr::CreateNot(Res, getContext());
273 bool AsmParser::ParseExpression(const MCExpr *&Res) {
275 return ParseExpression(Res, EndLoc);
278 /// ParseExpression - Parse an expression and return it.
280 /// expr ::= expr +,- expr -> lowest.
281 /// expr ::= expr |,^,&,! expr -> middle.
282 /// expr ::= expr *,/,%,<<,>> expr -> highest.
283 /// expr ::= primaryexpr
285 bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
286 // Parse the expression.
288 if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
291 // Try to constant fold it up front, if possible.
293 if (Res->EvaluateAsAbsolute(Value))
294 Res = MCConstantExpr::Create(Value, getContext());
299 bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
301 return ParseParenExpr(Res, EndLoc) ||
302 ParseBinOpRHS(1, Res, EndLoc);
305 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
308 SMLoc StartLoc = Lexer.getLoc();
309 if (ParseExpression(Expr))
312 if (!Expr->EvaluateAsAbsolute(Res))
313 return Error(StartLoc, "expected absolute expression");
318 static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
319 MCBinaryExpr::Opcode &Kind) {
322 return 0; // not a binop.
324 // Lowest Precedence: &&, ||
325 case AsmToken::AmpAmp:
326 Kind = MCBinaryExpr::LAnd;
328 case AsmToken::PipePipe:
329 Kind = MCBinaryExpr::LOr;
332 // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
334 Kind = MCBinaryExpr::Add;
336 case AsmToken::Minus:
337 Kind = MCBinaryExpr::Sub;
339 case AsmToken::EqualEqual:
340 Kind = MCBinaryExpr::EQ;
342 case AsmToken::ExclaimEqual:
343 case AsmToken::LessGreater:
344 Kind = MCBinaryExpr::NE;
347 Kind = MCBinaryExpr::LT;
349 case AsmToken::LessEqual:
350 Kind = MCBinaryExpr::LTE;
352 case AsmToken::Greater:
353 Kind = MCBinaryExpr::GT;
355 case AsmToken::GreaterEqual:
356 Kind = MCBinaryExpr::GTE;
359 // Intermediate Precedence: |, &, ^
361 // FIXME: gas seems to support '!' as an infix operator?
363 Kind = MCBinaryExpr::Or;
365 case AsmToken::Caret:
366 Kind = MCBinaryExpr::Xor;
369 Kind = MCBinaryExpr::And;
372 // Highest Precedence: *, /, %, <<, >>
374 Kind = MCBinaryExpr::Mul;
376 case AsmToken::Slash:
377 Kind = MCBinaryExpr::Div;
379 case AsmToken::Percent:
380 Kind = MCBinaryExpr::Mod;
382 case AsmToken::LessLess:
383 Kind = MCBinaryExpr::Shl;
385 case AsmToken::GreaterGreater:
386 Kind = MCBinaryExpr::Shr;
392 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
393 /// Res contains the LHS of the expression on input.
394 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
397 MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
398 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
400 // If the next token is lower precedence than we are allowed to eat, return
401 // successfully with what we ate already.
402 if (TokPrec < Precedence)
407 // Eat the next primary expression.
409 if (ParsePrimaryExpr(RHS, EndLoc)) return true;
411 // If BinOp binds less tightly with RHS than the operator after RHS, let
412 // the pending operator take RHS as its LHS.
413 MCBinaryExpr::Opcode Dummy;
414 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
415 if (TokPrec < NextTokPrec) {
416 if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
419 // Merge LHS and RHS according to operator.
420 Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
428 /// ::= EndOfStatement
429 /// ::= Label* Directive ...Operands... EndOfStatement
430 /// ::= Label* Identifier OperandList* EndOfStatement
431 bool AsmParser::ParseStatement() {
432 if (Lexer.is(AsmToken::EndOfStatement)) {
438 // Statements always start with an identifier.
439 AsmToken ID = getTok();
440 SMLoc IDLoc = ID.getLoc();
442 int64_t LocalLabelVal = -1;
443 // GUESS allow an integer followed by a ':' as a directional local label
444 if (Lexer.is(AsmToken::Integer)) {
445 LocalLabelVal = getTok().getIntVal();
446 if (LocalLabelVal < 0) {
447 if (!TheCondState.Ignore)
448 return TokError("unexpected token at start of statement");
452 IDVal = getTok().getString();
453 Lex(); // Consume the integer token to be used as an identifier token.
454 if (Lexer.getKind() != AsmToken::Colon) {
455 if (!TheCondState.Ignore)
456 return TokError("unexpected token at start of statement");
460 else if (ParseIdentifier(IDVal)) {
461 if (!TheCondState.Ignore)
462 return TokError("unexpected token at start of statement");
466 // Handle conditional assembly here before checking for skipping. We
467 // have to do this so that .endif isn't skipped in a ".if 0" block for
470 return ParseDirectiveIf(IDLoc);
471 if (IDVal == ".elseif")
472 return ParseDirectiveElseIf(IDLoc);
473 if (IDVal == ".else")
474 return ParseDirectiveElse(IDLoc);
475 if (IDVal == ".endif")
476 return ParseDirectiveEndIf(IDLoc);
478 // If we are in a ".if 0" block, ignore this statement.
479 if (TheCondState.Ignore) {
480 EatToEndOfStatement();
484 // FIXME: Recurse on local labels?
486 // See what kind of statement we have.
487 switch (Lexer.getKind()) {
488 case AsmToken::Colon: {
489 // identifier ':' -> Label.
492 // Diagnose attempt to use a variable as a label.
494 // FIXME: Diagnostics. Note the location of the definition as a label.
495 // FIXME: This doesn't diagnose assignment to a symbol which has been
496 // implicitly marked as external.
498 if (LocalLabelVal == -1)
499 Sym = CreateSymbol(IDVal);
501 Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
502 if (!Sym->isUndefined() || Sym->isVariable())
503 return Error(IDLoc, "invalid symbol redefinition");
508 // Consume any end of statement token, if present, to avoid spurious
509 // AddBlankLine calls().
510 if (Lexer.is(AsmToken::EndOfStatement)) {
512 if (Lexer.is(AsmToken::Eof))
516 return ParseStatement();
519 case AsmToken::Equal:
520 // identifier '=' ... -> assignment statement
523 return ParseAssignment(IDVal);
525 default: // Normal instruction or directive.
529 // Otherwise, we have a normal instruction or directive.
530 if (IDVal[0] == '.') {
531 // FIXME: This should be driven based on a hash lookup and callback.
532 if (IDVal == ".section")
533 return ParseDirectiveDarwinSection();
534 if (IDVal == ".text")
535 // FIXME: This changes behavior based on the -static flag to the
537 return ParseDirectiveSectionSwitch("__TEXT", "__text",
538 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
539 if (IDVal == ".const")
540 return ParseDirectiveSectionSwitch("__TEXT", "__const");
541 if (IDVal == ".static_const")
542 return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
543 if (IDVal == ".cstring")
544 return ParseDirectiveSectionSwitch("__TEXT","__cstring",
545 MCSectionMachO::S_CSTRING_LITERALS);
546 if (IDVal == ".literal4")
547 return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
548 MCSectionMachO::S_4BYTE_LITERALS,
550 if (IDVal == ".literal8")
551 return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
552 MCSectionMachO::S_8BYTE_LITERALS,
554 if (IDVal == ".literal16")
555 return ParseDirectiveSectionSwitch("__TEXT","__literal16",
556 MCSectionMachO::S_16BYTE_LITERALS,
558 if (IDVal == ".constructor")
559 return ParseDirectiveSectionSwitch("__TEXT","__constructor");
560 if (IDVal == ".destructor")
561 return ParseDirectiveSectionSwitch("__TEXT","__destructor");
562 if (IDVal == ".fvmlib_init0")
563 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
564 if (IDVal == ".fvmlib_init1")
565 return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
567 // FIXME: The assembler manual claims that this has the self modify code
568 // flag, at least on x86-32, but that does not appear to be correct.
569 if (IDVal == ".symbol_stub")
570 return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
571 MCSectionMachO::S_SYMBOL_STUBS |
572 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
573 // FIXME: Different on PPC and ARM.
575 // FIXME: PowerPC only?
576 if (IDVal == ".picsymbol_stub")
577 return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
578 MCSectionMachO::S_SYMBOL_STUBS |
579 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
581 if (IDVal == ".data")
582 return ParseDirectiveSectionSwitch("__DATA", "__data");
583 if (IDVal == ".static_data")
584 return ParseDirectiveSectionSwitch("__DATA", "__static_data");
586 // FIXME: The section names of these two are misspelled in the assembler
588 if (IDVal == ".non_lazy_symbol_pointer")
589 return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
590 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
592 if (IDVal == ".lazy_symbol_pointer")
593 return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
594 MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
597 if (IDVal == ".dyld")
598 return ParseDirectiveSectionSwitch("__DATA", "__dyld");
599 if (IDVal == ".mod_init_func")
600 return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
601 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
603 if (IDVal == ".mod_term_func")
604 return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
605 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
607 if (IDVal == ".const_data")
608 return ParseDirectiveSectionSwitch("__DATA", "__const");
611 if (IDVal == ".objc_class")
612 return ParseDirectiveSectionSwitch("__OBJC", "__class",
613 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
614 if (IDVal == ".objc_meta_class")
615 return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
616 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
617 if (IDVal == ".objc_cat_cls_meth")
618 return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
619 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
620 if (IDVal == ".objc_cat_inst_meth")
621 return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
622 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
623 if (IDVal == ".objc_protocol")
624 return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
625 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
626 if (IDVal == ".objc_string_object")
627 return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
628 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
629 if (IDVal == ".objc_cls_meth")
630 return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
631 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
632 if (IDVal == ".objc_inst_meth")
633 return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
634 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
635 if (IDVal == ".objc_cls_refs")
636 return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
637 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
638 MCSectionMachO::S_LITERAL_POINTERS,
640 if (IDVal == ".objc_message_refs")
641 return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
642 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
643 MCSectionMachO::S_LITERAL_POINTERS,
645 if (IDVal == ".objc_symbols")
646 return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
647 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
648 if (IDVal == ".objc_category")
649 return ParseDirectiveSectionSwitch("__OBJC", "__category",
650 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
651 if (IDVal == ".objc_class_vars")
652 return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
653 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
654 if (IDVal == ".objc_instance_vars")
655 return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
656 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
657 if (IDVal == ".objc_module_info")
658 return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
659 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
660 if (IDVal == ".objc_class_names")
661 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
662 MCSectionMachO::S_CSTRING_LITERALS);
663 if (IDVal == ".objc_meth_var_types")
664 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
665 MCSectionMachO::S_CSTRING_LITERALS);
666 if (IDVal == ".objc_meth_var_names")
667 return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
668 MCSectionMachO::S_CSTRING_LITERALS);
669 if (IDVal == ".objc_selector_strs")
670 return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
671 MCSectionMachO::S_CSTRING_LITERALS);
673 if (IDVal == ".tdata")
674 return ParseDirectiveSectionSwitch("__DATA", "__thread_data",
675 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
677 return ParseDirectiveSectionSwitch("__DATA", "__thread_vars",
678 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
679 if (IDVal == ".thread_init_func")
680 return ParseDirectiveSectionSwitch("__DATA", "__thread_init",
681 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
683 // Assembler features
685 return ParseDirectiveSet();
689 if (IDVal == ".ascii")
690 return ParseDirectiveAscii(false);
691 if (IDVal == ".asciz")
692 return ParseDirectiveAscii(true);
694 if (IDVal == ".byte")
695 return ParseDirectiveValue(1);
696 if (IDVal == ".short")
697 return ParseDirectiveValue(2);
698 if (IDVal == ".long")
699 return ParseDirectiveValue(4);
700 if (IDVal == ".quad")
701 return ParseDirectiveValue(8);
703 // FIXME: Target hooks for IsPow2.
704 if (IDVal == ".align")
705 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
706 if (IDVal == ".align32")
707 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
708 if (IDVal == ".balign")
709 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
710 if (IDVal == ".balignw")
711 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
712 if (IDVal == ".balignl")
713 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
714 if (IDVal == ".p2align")
715 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
716 if (IDVal == ".p2alignw")
717 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
718 if (IDVal == ".p2alignl")
719 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
722 return ParseDirectiveOrg();
724 if (IDVal == ".fill")
725 return ParseDirectiveFill();
726 if (IDVal == ".space")
727 return ParseDirectiveSpace();
729 // Symbol attribute directives
731 if (IDVal == ".globl" || IDVal == ".global")
732 return ParseDirectiveSymbolAttribute(MCSA_Global);
733 if (IDVal == ".hidden")
734 return ParseDirectiveSymbolAttribute(MCSA_Hidden);
735 if (IDVal == ".indirect_symbol")
736 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
737 if (IDVal == ".internal")
738 return ParseDirectiveSymbolAttribute(MCSA_Internal);
739 if (IDVal == ".lazy_reference")
740 return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
741 if (IDVal == ".no_dead_strip")
742 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
743 if (IDVal == ".private_extern")
744 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
745 if (IDVal == ".protected")
746 return ParseDirectiveSymbolAttribute(MCSA_Protected);
747 if (IDVal == ".reference")
748 return ParseDirectiveSymbolAttribute(MCSA_Reference);
749 if (IDVal == ".type")
750 return ParseDirectiveELFType();
751 if (IDVal == ".weak")
752 return ParseDirectiveSymbolAttribute(MCSA_Weak);
753 if (IDVal == ".weak_definition")
754 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
755 if (IDVal == ".weak_reference")
756 return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
758 if (IDVal == ".comm")
759 return ParseDirectiveComm(/*IsLocal=*/false);
760 if (IDVal == ".lcomm")
761 return ParseDirectiveComm(/*IsLocal=*/true);
762 if (IDVal == ".zerofill")
763 return ParseDirectiveDarwinZerofill();
764 if (IDVal == ".desc")
765 return ParseDirectiveDarwinSymbolDesc();
766 if (IDVal == ".lsym")
767 return ParseDirectiveDarwinLsym();
768 if (IDVal == ".tbss")
769 return ParseDirectiveDarwinTBSS();
771 if (IDVal == ".subsections_via_symbols")
772 return ParseDirectiveDarwinSubsectionsViaSymbols();
773 if (IDVal == ".abort")
774 return ParseDirectiveAbort();
775 if (IDVal == ".include")
776 return ParseDirectiveInclude();
777 if (IDVal == ".dump")
778 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
779 if (IDVal == ".load")
780 return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
781 if (IDVal == ".secure_log_unique")
782 return ParseDirectiveDarwinSecureLogUnique(IDLoc);
783 if (IDVal == ".secure_log_reset")
784 return ParseDirectiveDarwinSecureLogReset(IDLoc);
786 // Look up the handler in the handler table,
787 bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal];
789 return (this->*Handler)(IDVal, IDLoc);
791 // Target hook for parsing target specific directives.
792 if (!getTargetParser().ParseDirective(ID))
795 Warning(IDLoc, "ignoring directive for now");
796 EatToEndOfStatement();
800 // Canonicalize the opcode to lower case.
801 SmallString<128> Opcode;
802 for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
803 Opcode.push_back(tolower(IDVal[i]));
805 SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
806 bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
808 if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
809 HadError = TokError("unexpected token in argument list");
811 // If parsing succeeded, match the instruction.
814 if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
815 // Emit the instruction on success.
816 Out.EmitInstruction(Inst);
818 // Otherwise emit a diagnostic about the match failure and set the error
821 // FIXME: We should give nicer diagnostics about the exact failure.
822 Error(IDLoc, "unrecognized instruction");
827 // If there was no error, consume the end-of-statement token. Otherwise this
828 // will be done by our caller.
832 // Free any parsed operands.
833 for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
834 delete ParsedOperands[i];
839 bool AsmParser::ParseAssignment(const StringRef &Name) {
840 // FIXME: Use better location, we should use proper tokens.
841 SMLoc EqualLoc = Lexer.getLoc();
844 if (ParseExpression(Value))
847 if (Lexer.isNot(AsmToken::EndOfStatement))
848 return TokError("unexpected token in assignment");
850 // Eat the end of statement marker.
853 // Validate that the LHS is allowed to be a variable (either it has not been
854 // used as a symbol, or it is an absolute symbol).
855 MCSymbol *Sym = getContext().LookupSymbol(Name);
857 // Diagnose assignment to a label.
859 // FIXME: Diagnostics. Note the location of the definition as a label.
860 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
861 if (Sym->isUndefined() && !Sym->isUsedInExpr())
862 ; // Allow redefinitions of undefined symbols only used in directives.
863 else if (!Sym->isUndefined() && !Sym->isAbsolute())
864 return Error(EqualLoc, "redefinition of '" + Name + "'");
865 else if (!Sym->isVariable())
866 return Error(EqualLoc, "invalid assignment to '" + Name + "'");
867 else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
868 return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
871 Sym = CreateSymbol(Name);
873 // FIXME: Handle '.'.
875 Sym->setUsedInExpr(true);
877 // Do the assignment.
878 Out.EmitAssignment(Sym, Value);
886 bool AsmParser::ParseIdentifier(StringRef &Res) {
887 if (Lexer.isNot(AsmToken::Identifier) &&
888 Lexer.isNot(AsmToken::String))
891 Res = getTok().getIdentifier();
893 Lex(); // Consume the identifier token.
898 /// ParseDirectiveSet:
899 /// ::= .set identifier ',' expression
900 bool AsmParser::ParseDirectiveSet() {
903 if (ParseIdentifier(Name))
904 return TokError("expected identifier after '.set' directive");
906 if (Lexer.isNot(AsmToken::Comma))
907 return TokError("unexpected token in '.set'");
910 return ParseAssignment(Name);
913 /// ParseDirectiveSection:
914 /// ::= .section identifier (',' identifier)*
915 /// FIXME: This should actually parse out the segment, section, attributes and
916 /// sizeof_stub fields.
917 bool AsmParser::ParseDirectiveDarwinSection() {
918 SMLoc Loc = Lexer.getLoc();
920 StringRef SectionName;
921 if (ParseIdentifier(SectionName))
922 return Error(Loc, "expected identifier after '.section' directive");
924 // Verify there is a following comma.
925 if (!Lexer.is(AsmToken::Comma))
926 return TokError("unexpected token in '.section' directive");
928 std::string SectionSpec = SectionName;
931 // Add all the tokens until the end of the line, ParseSectionSpecifier will
933 StringRef EOL = Lexer.LexUntilEndOfStatement();
934 SectionSpec.append(EOL.begin(), EOL.end());
937 if (Lexer.isNot(AsmToken::EndOfStatement))
938 return TokError("unexpected token in '.section' directive");
942 StringRef Segment, Section;
943 unsigned TAA, StubSize;
944 std::string ErrorStr =
945 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
948 if (!ErrorStr.empty())
949 return Error(Loc, ErrorStr.c_str());
951 // FIXME: Arch specific.
952 bool isText = Segment == "__TEXT"; // FIXME: Hack.
953 Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
954 isText ? SectionKind::getText()
955 : SectionKind::getDataRel()));
959 /// ParseDirectiveSectionSwitch -
960 bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
962 unsigned TAA, unsigned Align,
964 if (Lexer.isNot(AsmToken::EndOfStatement))
965 return TokError("unexpected token in section switching directive");
968 // FIXME: Arch specific.
969 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
970 Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
971 isText ? SectionKind::getText()
972 : SectionKind::getDataRel()));
974 // Set the implicit alignment, if any.
976 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
977 // alignment on the section (e.g., if one manually inserts bytes into the
978 // section, then just issueing the section switch directive will not realign
979 // the section. However, this is arguably more reasonable behavior, and there
980 // is no good reason for someone to intentionally emit incorrectly sized
981 // values into the implicitly aligned sections.
983 Out.EmitValueToAlignment(Align, 0, 1, 0);
988 bool AsmParser::ParseEscapedString(std::string &Data) {
989 assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
992 StringRef Str = getTok().getStringContents();
993 for (unsigned i = 0, e = Str.size(); i != e; ++i) {
994 if (Str[i] != '\\') {
999 // Recognize escaped characters. Note that this escape semantics currently
1000 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1003 return TokError("unexpected backslash at end of string");
1005 // Recognize octal sequences.
1006 if ((unsigned) (Str[i] - '0') <= 7) {
1007 // Consume up to three octal characters.
1008 unsigned Value = Str[i] - '0';
1010 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1012 Value = Value * 8 + (Str[i] - '0');
1014 if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1016 Value = Value * 8 + (Str[i] - '0');
1021 return TokError("invalid octal escape sequence (out of range)");
1023 Data += (unsigned char) Value;
1027 // Otherwise recognize individual escapes.
1030 // Just reject invalid escape sequences for now.
1031 return TokError("invalid escape sequence (unrecognized character)");
1033 case 'b': Data += '\b'; break;
1034 case 'f': Data += '\f'; break;
1035 case 'n': Data += '\n'; break;
1036 case 'r': Data += '\r'; break;
1037 case 't': Data += '\t'; break;
1038 case '"': Data += '"'; break;
1039 case '\\': Data += '\\'; break;
1046 /// ParseDirectiveAscii:
1047 /// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
1048 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
1049 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1051 if (Lexer.isNot(AsmToken::String))
1052 return TokError("expected string in '.ascii' or '.asciz' directive");
1055 if (ParseEscapedString(Data))
1058 Out.EmitBytes(Data, DEFAULT_ADDRSPACE);
1060 Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
1064 if (Lexer.is(AsmToken::EndOfStatement))
1067 if (Lexer.isNot(AsmToken::Comma))
1068 return TokError("unexpected token in '.ascii' or '.asciz' directive");
1077 /// ParseDirectiveValue
1078 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
1079 bool AsmParser::ParseDirectiveValue(unsigned Size) {
1080 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1082 const MCExpr *Value;
1083 SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc();
1084 if (ParseExpression(Value))
1087 // Special case constant expressions to match code generator.
1088 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value))
1089 Out.EmitIntValue(MCE->getValue(), Size, DEFAULT_ADDRSPACE);
1091 Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1093 if (Lexer.is(AsmToken::EndOfStatement))
1096 // FIXME: Improve diagnostic.
1097 if (Lexer.isNot(AsmToken::Comma))
1098 return TokError("unexpected token in directive");
1107 /// ParseDirectiveSpace
1108 /// ::= .space expression [ , expression ]
1109 bool AsmParser::ParseDirectiveSpace() {
1111 if (ParseAbsoluteExpression(NumBytes))
1114 int64_t FillExpr = 0;
1115 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1116 if (Lexer.isNot(AsmToken::Comma))
1117 return TokError("unexpected token in '.space' directive");
1120 if (ParseAbsoluteExpression(FillExpr))
1123 if (Lexer.isNot(AsmToken::EndOfStatement))
1124 return TokError("unexpected token in '.space' directive");
1130 return TokError("invalid number of bytes in '.space' directive");
1132 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1133 Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1138 /// ParseDirectiveFill
1139 /// ::= .fill expression , expression , expression
1140 bool AsmParser::ParseDirectiveFill() {
1142 if (ParseAbsoluteExpression(NumValues))
1145 if (Lexer.isNot(AsmToken::Comma))
1146 return TokError("unexpected token in '.fill' directive");
1150 if (ParseAbsoluteExpression(FillSize))
1153 if (Lexer.isNot(AsmToken::Comma))
1154 return TokError("unexpected token in '.fill' directive");
1158 if (ParseAbsoluteExpression(FillExpr))
1161 if (Lexer.isNot(AsmToken::EndOfStatement))
1162 return TokError("unexpected token in '.fill' directive");
1166 if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1167 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1169 for (uint64_t i = 0, e = NumValues; i != e; ++i)
1170 Out.EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
1175 /// ParseDirectiveOrg
1176 /// ::= .org expression [ , expression ]
1177 bool AsmParser::ParseDirectiveOrg() {
1178 const MCExpr *Offset;
1179 if (ParseExpression(Offset))
1182 // Parse optional fill expression.
1183 int64_t FillExpr = 0;
1184 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1185 if (Lexer.isNot(AsmToken::Comma))
1186 return TokError("unexpected token in '.org' directive");
1189 if (ParseAbsoluteExpression(FillExpr))
1192 if (Lexer.isNot(AsmToken::EndOfStatement))
1193 return TokError("unexpected token in '.org' directive");
1198 // FIXME: Only limited forms of relocatable expressions are accepted here, it
1199 // has to be relative to the current section.
1200 Out.EmitValueToOffset(Offset, FillExpr);
1205 /// ParseDirectiveAlign
1206 /// ::= {.align, ...} expression [ , expression [ , expression ]]
1207 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1208 SMLoc AlignmentLoc = Lexer.getLoc();
1210 if (ParseAbsoluteExpression(Alignment))
1214 bool HasFillExpr = false;
1215 int64_t FillExpr = 0;
1216 int64_t MaxBytesToFill = 0;
1217 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1218 if (Lexer.isNot(AsmToken::Comma))
1219 return TokError("unexpected token in directive");
1222 // The fill expression can be omitted while specifying a maximum number of
1223 // alignment bytes, e.g:
1225 if (Lexer.isNot(AsmToken::Comma)) {
1227 if (ParseAbsoluteExpression(FillExpr))
1231 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1232 if (Lexer.isNot(AsmToken::Comma))
1233 return TokError("unexpected token in directive");
1236 MaxBytesLoc = Lexer.getLoc();
1237 if (ParseAbsoluteExpression(MaxBytesToFill))
1240 if (Lexer.isNot(AsmToken::EndOfStatement))
1241 return TokError("unexpected token in directive");
1250 // Compute alignment in bytes.
1252 // FIXME: Diagnose overflow.
1253 if (Alignment >= 32) {
1254 Error(AlignmentLoc, "invalid alignment value");
1258 Alignment = 1ULL << Alignment;
1261 // Diagnose non-sensical max bytes to align.
1262 if (MaxBytesLoc.isValid()) {
1263 if (MaxBytesToFill < 1) {
1264 Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1265 "many bytes, ignoring maximum bytes expression");
1269 if (MaxBytesToFill >= Alignment) {
1270 Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1276 // Check whether we should use optimal code alignment for this .align
1279 // FIXME: This should be using a target hook.
1280 bool UseCodeAlign = false;
1281 if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>(
1282 Out.getCurrentSection()))
1283 UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
1284 if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
1285 ValueSize == 1 && UseCodeAlign) {
1286 Out.EmitCodeAlignment(Alignment, MaxBytesToFill);
1288 // FIXME: Target specific behavior about how the "extra" bytes are filled.
1289 Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1295 /// ParseDirectiveSymbolAttribute
1296 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1297 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
1298 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1302 if (ParseIdentifier(Name))
1303 return TokError("expected identifier in directive");
1305 MCSymbol *Sym = CreateSymbol(Name);
1307 Out.EmitSymbolAttribute(Sym, Attr);
1309 if (Lexer.is(AsmToken::EndOfStatement))
1312 if (Lexer.isNot(AsmToken::Comma))
1313 return TokError("unexpected token in directive");
1322 /// ParseDirectiveELFType
1323 /// ::= .type identifier , @attribute
1324 bool AsmParser::ParseDirectiveELFType() {
1326 if (ParseIdentifier(Name))
1327 return TokError("expected identifier in directive");
1329 // Handle the identifier as the key symbol.
1330 MCSymbol *Sym = CreateSymbol(Name);
1332 if (Lexer.isNot(AsmToken::Comma))
1333 return TokError("unexpected token in '.type' directive");
1336 if (Lexer.isNot(AsmToken::At))
1337 return TokError("expected '@' before type");
1343 TypeLoc = Lexer.getLoc();
1344 if (ParseIdentifier(Type))
1345 return TokError("expected symbol type in directive");
1347 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
1348 .Case("function", MCSA_ELF_TypeFunction)
1349 .Case("object", MCSA_ELF_TypeObject)
1350 .Case("tls_object", MCSA_ELF_TypeTLS)
1351 .Case("common", MCSA_ELF_TypeCommon)
1352 .Case("notype", MCSA_ELF_TypeNoType)
1353 .Default(MCSA_Invalid);
1355 if (Attr == MCSA_Invalid)
1356 return Error(TypeLoc, "unsupported attribute in '.type' directive");
1358 if (Lexer.isNot(AsmToken::EndOfStatement))
1359 return TokError("unexpected token in '.type' directive");
1363 Out.EmitSymbolAttribute(Sym, Attr);
1368 /// ParseDirectiveDarwinSymbolDesc
1369 /// ::= .desc identifier , expression
1370 bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
1372 if (ParseIdentifier(Name))
1373 return TokError("expected identifier in directive");
1375 // Handle the identifier as the key symbol.
1376 MCSymbol *Sym = CreateSymbol(Name);
1378 if (Lexer.isNot(AsmToken::Comma))
1379 return TokError("unexpected token in '.desc' directive");
1383 if (ParseAbsoluteExpression(DescValue))
1386 if (Lexer.isNot(AsmToken::EndOfStatement))
1387 return TokError("unexpected token in '.desc' directive");
1391 // Set the n_desc field of this Symbol to this DescValue
1392 Out.EmitSymbolDesc(Sym, DescValue);
1397 /// ParseDirectiveComm
1398 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1399 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1400 SMLoc IDLoc = Lexer.getLoc();
1402 if (ParseIdentifier(Name))
1403 return TokError("expected identifier in directive");
1405 // Handle the identifier as the key symbol.
1406 MCSymbol *Sym = CreateSymbol(Name);
1408 if (Lexer.isNot(AsmToken::Comma))
1409 return TokError("unexpected token in directive");
1413 SMLoc SizeLoc = Lexer.getLoc();
1414 if (ParseAbsoluteExpression(Size))
1417 int64_t Pow2Alignment = 0;
1418 SMLoc Pow2AlignmentLoc;
1419 if (Lexer.is(AsmToken::Comma)) {
1421 Pow2AlignmentLoc = Lexer.getLoc();
1422 if (ParseAbsoluteExpression(Pow2Alignment))
1425 // If this target takes alignments in bytes (not log) validate and convert.
1426 if (Lexer.getMAI().getAlignmentIsInBytes()) {
1427 if (!isPowerOf2_64(Pow2Alignment))
1428 return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1429 Pow2Alignment = Log2_64(Pow2Alignment);
1433 if (Lexer.isNot(AsmToken::EndOfStatement))
1434 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1438 // NOTE: a size of zero for a .comm should create a undefined symbol
1439 // but a size of .lcomm creates a bss symbol of size zero.
1441 return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1442 "be less than zero");
1444 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1445 // may internally end up wanting an alignment in bytes.
1446 // FIXME: Diagnose overflow.
1447 if (Pow2Alignment < 0)
1448 return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1449 "alignment, can't be less than zero");
1451 if (!Sym->isUndefined())
1452 return Error(IDLoc, "invalid symbol redefinition");
1454 // '.lcomm' is equivalent to '.zerofill'.
1455 // Create the Symbol as a common or local common with Size and Pow2Alignment
1457 Out.EmitZerofill(Ctx.getMachOSection("__DATA", "__bss",
1458 MCSectionMachO::S_ZEROFILL, 0,
1459 SectionKind::getBSS()),
1460 Sym, Size, 1 << Pow2Alignment);
1464 Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1468 /// ParseDirectiveDarwinZerofill
1469 /// ::= .zerofill segname , sectname [, identifier , size_expression [
1470 /// , align_expression ]]
1471 bool AsmParser::ParseDirectiveDarwinZerofill() {
1473 if (ParseIdentifier(Segment))
1474 return TokError("expected segment name after '.zerofill' directive");
1476 if (Lexer.isNot(AsmToken::Comma))
1477 return TokError("unexpected token in directive");
1481 if (ParseIdentifier(Section))
1482 return TokError("expected section name after comma in '.zerofill' "
1485 // If this is the end of the line all that was wanted was to create the
1486 // the section but with no symbol.
1487 if (Lexer.is(AsmToken::EndOfStatement)) {
1488 // Create the zerofill section but no symbol
1489 Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
1490 MCSectionMachO::S_ZEROFILL, 0,
1491 SectionKind::getBSS()));
1495 if (Lexer.isNot(AsmToken::Comma))
1496 return TokError("unexpected token in directive");
1499 SMLoc IDLoc = Lexer.getLoc();
1501 if (ParseIdentifier(IDStr))
1502 return TokError("expected identifier in directive");
1504 // handle the identifier as the key symbol.
1505 MCSymbol *Sym = CreateSymbol(IDStr);
1507 if (Lexer.isNot(AsmToken::Comma))
1508 return TokError("unexpected token in directive");
1512 SMLoc SizeLoc = Lexer.getLoc();
1513 if (ParseAbsoluteExpression(Size))
1516 int64_t Pow2Alignment = 0;
1517 SMLoc Pow2AlignmentLoc;
1518 if (Lexer.is(AsmToken::Comma)) {
1520 Pow2AlignmentLoc = Lexer.getLoc();
1521 if (ParseAbsoluteExpression(Pow2Alignment))
1525 if (Lexer.isNot(AsmToken::EndOfStatement))
1526 return TokError("unexpected token in '.zerofill' directive");
1531 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1534 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1535 // may internally end up wanting an alignment in bytes.
1536 // FIXME: Diagnose overflow.
1537 if (Pow2Alignment < 0)
1538 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1539 "can't be less than zero");
1541 if (!Sym->isUndefined())
1542 return Error(IDLoc, "invalid symbol redefinition");
1544 // Create the zerofill Symbol with Size and Pow2Alignment
1546 // FIXME: Arch specific.
1547 Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
1548 MCSectionMachO::S_ZEROFILL, 0,
1549 SectionKind::getBSS()),
1550 Sym, Size, 1 << Pow2Alignment);
1555 /// ParseDirectiveDarwinTBSS
1556 /// ::= .tbss identifier, size, align
1557 bool AsmParser::ParseDirectiveDarwinTBSS() {
1558 SMLoc IDLoc = Lexer.getLoc();
1560 if (ParseIdentifier(Name))
1561 return TokError("expected identifier in directive");
1563 // Handle the identifier as the key symbol.
1564 MCSymbol *Sym = CreateSymbol(Name);
1566 if (Lexer.isNot(AsmToken::Comma))
1567 return TokError("unexpected token in directive");
1571 SMLoc SizeLoc = Lexer.getLoc();
1572 if (ParseAbsoluteExpression(Size))
1575 int64_t Pow2Alignment = 0;
1576 SMLoc Pow2AlignmentLoc;
1577 if (Lexer.is(AsmToken::Comma)) {
1579 Pow2AlignmentLoc = Lexer.getLoc();
1580 if (ParseAbsoluteExpression(Pow2Alignment))
1584 if (Lexer.isNot(AsmToken::EndOfStatement))
1585 return TokError("unexpected token in '.tbss' directive");
1590 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
1593 // FIXME: Diagnose overflow.
1594 if (Pow2Alignment < 0)
1595 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
1598 if (!Sym->isUndefined())
1599 return Error(IDLoc, "invalid symbol redefinition");
1601 Out.EmitTBSSSymbol(Ctx.getMachOSection("__DATA", "__thread_bss",
1602 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
1603 0, SectionKind::getThreadBSS()),
1604 Sym, Size, 1 << Pow2Alignment);
1609 /// ParseDirectiveDarwinSubsectionsViaSymbols
1610 /// ::= .subsections_via_symbols
1611 bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
1612 if (Lexer.isNot(AsmToken::EndOfStatement))
1613 return TokError("unexpected token in '.subsections_via_symbols' directive");
1617 Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1622 /// ParseDirectiveAbort
1623 /// ::= .abort [ "abort_string" ]
1624 bool AsmParser::ParseDirectiveAbort() {
1625 // FIXME: Use loc from directive.
1626 SMLoc Loc = Lexer.getLoc();
1629 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1630 if (Lexer.isNot(AsmToken::String))
1631 return TokError("expected string in '.abort' directive");
1633 Str = getTok().getString();
1638 if (Lexer.isNot(AsmToken::EndOfStatement))
1639 return TokError("unexpected token in '.abort' directive");
1643 // FIXME: Handle here.
1645 Error(Loc, ".abort detected. Assembly stopping.");
1647 Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1652 /// ParseDirectiveLsym
1653 /// ::= .lsym identifier , expression
1654 bool AsmParser::ParseDirectiveDarwinLsym() {
1656 if (ParseIdentifier(Name))
1657 return TokError("expected identifier in directive");
1659 // Handle the identifier as the key symbol.
1660 MCSymbol *Sym = CreateSymbol(Name);
1662 if (Lexer.isNot(AsmToken::Comma))
1663 return TokError("unexpected token in '.lsym' directive");
1666 const MCExpr *Value;
1667 if (ParseExpression(Value))
1670 if (Lexer.isNot(AsmToken::EndOfStatement))
1671 return TokError("unexpected token in '.lsym' directive");
1675 // We don't currently support this directive.
1677 // FIXME: Diagnostic location!
1679 return TokError("directive '.lsym' is unsupported");
1682 /// ParseDirectiveInclude
1683 /// ::= .include "filename"
1684 bool AsmParser::ParseDirectiveInclude() {
1685 if (Lexer.isNot(AsmToken::String))
1686 return TokError("expected string in '.include' directive");
1688 std::string Filename = getTok().getString();
1689 SMLoc IncludeLoc = Lexer.getLoc();
1692 if (Lexer.isNot(AsmToken::EndOfStatement))
1693 return TokError("unexpected token in '.include' directive");
1695 // Strip the quotes.
1696 Filename = Filename.substr(1, Filename.size()-2);
1698 // Attempt to switch the lexer to the included file before consuming the end
1699 // of statement to avoid losing it when we switch.
1700 if (EnterIncludeFile(Filename)) {
1701 PrintMessage(IncludeLoc,
1702 "Could not find include file '" + Filename + "'",
1710 /// ParseDirectiveDarwinDumpOrLoad
1711 /// ::= ( .dump | .load ) "filename"
1712 bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
1713 if (Lexer.isNot(AsmToken::String))
1714 return TokError("expected string in '.dump' or '.load' directive");
1718 if (Lexer.isNot(AsmToken::EndOfStatement))
1719 return TokError("unexpected token in '.dump' or '.load' directive");
1723 // FIXME: If/when .dump and .load are implemented they will be done in the
1724 // the assembly parser and not have any need for an MCStreamer API.
1726 Warning(IDLoc, "ignoring directive .dump for now");
1728 Warning(IDLoc, "ignoring directive .load for now");
1733 /// ParseDirectiveDarwinSecureLogUnique
1734 /// ::= .secure_log_unique "log message"
1735 bool AsmParser::ParseDirectiveDarwinSecureLogUnique(SMLoc IDLoc) {
1736 std::string LogMessage;
1738 if (Lexer.isNot(AsmToken::String))
1741 LogMessage = getTok().getString();
1745 if (Lexer.isNot(AsmToken::EndOfStatement))
1746 return TokError("unexpected token in '.secure_log_unique' directive");
1748 if (getContext().getSecureLogUsed() != false)
1749 return Error(IDLoc, ".secure_log_unique specified multiple times");
1751 char *SecureLogFile = getContext().getSecureLogFile();
1752 if (SecureLogFile == NULL)
1753 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
1754 "environment variable unset.");
1756 raw_ostream *OS = getContext().getSecureLog();
1759 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
1762 return Error(IDLoc, Twine("can't open secure log file: ") +
1763 SecureLogFile + " (" + Err + ")");
1765 getContext().setSecureLog(OS);
1768 int CurBuf = SrcMgr.FindBufferContainingLoc(IDLoc);
1769 *OS << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":"
1770 << SrcMgr.FindLineNumber(IDLoc, CurBuf) << ":"
1771 << LogMessage + "\n";
1773 getContext().setSecureLogUsed(true);
1778 /// ParseDirectiveDarwinSecureLogReset
1779 /// ::= .secure_log_reset
1780 bool AsmParser::ParseDirectiveDarwinSecureLogReset(SMLoc IDLoc) {
1781 if (Lexer.isNot(AsmToken::EndOfStatement))
1782 return TokError("unexpected token in '.secure_log_reset' directive");
1786 getContext().setSecureLogUsed(false);
1791 /// ParseDirectiveIf
1792 /// ::= .if expression
1793 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
1794 TheCondStack.push_back(TheCondState);
1795 TheCondState.TheCond = AsmCond::IfCond;
1796 if(TheCondState.Ignore) {
1797 EatToEndOfStatement();
1801 if (ParseAbsoluteExpression(ExprValue))
1804 if (Lexer.isNot(AsmToken::EndOfStatement))
1805 return TokError("unexpected token in '.if' directive");
1809 TheCondState.CondMet = ExprValue;
1810 TheCondState.Ignore = !TheCondState.CondMet;
1816 /// ParseDirectiveElseIf
1817 /// ::= .elseif expression
1818 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
1819 if (TheCondState.TheCond != AsmCond::IfCond &&
1820 TheCondState.TheCond != AsmCond::ElseIfCond)
1821 Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
1823 TheCondState.TheCond = AsmCond::ElseIfCond;
1825 bool LastIgnoreState = false;
1826 if (!TheCondStack.empty())
1827 LastIgnoreState = TheCondStack.back().Ignore;
1828 if (LastIgnoreState || TheCondState.CondMet) {
1829 TheCondState.Ignore = true;
1830 EatToEndOfStatement();
1834 if (ParseAbsoluteExpression(ExprValue))
1837 if (Lexer.isNot(AsmToken::EndOfStatement))
1838 return TokError("unexpected token in '.elseif' directive");
1841 TheCondState.CondMet = ExprValue;
1842 TheCondState.Ignore = !TheCondState.CondMet;
1848 /// ParseDirectiveElse
1850 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
1851 if (Lexer.isNot(AsmToken::EndOfStatement))
1852 return TokError("unexpected token in '.else' directive");
1856 if (TheCondState.TheCond != AsmCond::IfCond &&
1857 TheCondState.TheCond != AsmCond::ElseIfCond)
1858 Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
1860 TheCondState.TheCond = AsmCond::ElseCond;
1861 bool LastIgnoreState = false;
1862 if (!TheCondStack.empty())
1863 LastIgnoreState = TheCondStack.back().Ignore;
1864 if (LastIgnoreState || TheCondState.CondMet)
1865 TheCondState.Ignore = true;
1867 TheCondState.Ignore = false;
1872 /// ParseDirectiveEndIf
1874 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
1875 if (Lexer.isNot(AsmToken::EndOfStatement))
1876 return TokError("unexpected token in '.endif' directive");
1880 if ((TheCondState.TheCond == AsmCond::NoCond) ||
1881 TheCondStack.empty())
1882 Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
1884 if (!TheCondStack.empty()) {
1885 TheCondState = TheCondStack.back();
1886 TheCondStack.pop_back();
1892 /// ParseDirectiveFile
1893 /// ::= .file [number] string
1894 bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
1895 // FIXME: I'm not sure what this is.
1896 int64_t FileNumber = -1;
1897 if (Lexer.is(AsmToken::Integer)) {
1898 FileNumber = getTok().getIntVal();
1902 return TokError("file number less than one");
1905 if (Lexer.isNot(AsmToken::String))
1906 return TokError("unexpected token in '.file' directive");
1908 StringRef Filename = getTok().getString();
1909 Filename = Filename.substr(1, Filename.size()-2);
1912 if (Lexer.isNot(AsmToken::EndOfStatement))
1913 return TokError("unexpected token in '.file' directive");
1915 if (FileNumber == -1)
1916 Out.EmitFileDirective(Filename);
1918 Out.EmitDwarfFileDirective(FileNumber, Filename);
1923 /// ParseDirectiveLine
1924 /// ::= .line [number]
1925 bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
1926 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1927 if (Lexer.isNot(AsmToken::Integer))
1928 return TokError("unexpected token in '.line' directive");
1930 int64_t LineNumber = getTok().getIntVal();
1934 // FIXME: Do something with the .line.
1937 if (Lexer.isNot(AsmToken::EndOfStatement))
1938 return TokError("unexpected token in '.line' directive");
1944 /// ParseDirectiveLoc
1945 /// ::= .loc number [number [number]]
1946 bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
1947 if (Lexer.isNot(AsmToken::Integer))
1948 return TokError("unexpected token in '.loc' directive");
1950 // FIXME: What are these fields?
1951 int64_t FileNumber = getTok().getIntVal();
1953 // FIXME: Validate file.
1956 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1957 if (Lexer.isNot(AsmToken::Integer))
1958 return TokError("unexpected token in '.loc' directive");
1960 int64_t Param2 = getTok().getIntVal();
1964 if (Lexer.isNot(AsmToken::EndOfStatement)) {
1965 if (Lexer.isNot(AsmToken::Integer))
1966 return TokError("unexpected token in '.loc' directive");
1968 int64_t Param3 = getTok().getIntVal();
1972 // FIXME: Do something with the .loc.
1976 if (Lexer.isNot(AsmToken::EndOfStatement))
1977 return TokError("unexpected token in '.file' directive");