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/ADT/APFloat.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCParser/AsmCond.h"
23 #include "llvm/MC/MCParser/AsmLexer.h"
24 #include "llvm/MC/MCParser/MCAsmParser.h"
25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26 #include "llvm/MC/MCSectionMachO.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/MCDwarf.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/MathExtras.h"
32 #include "llvm/Support/MemoryBuffer.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include "llvm/Target/TargetAsmInfo.h"
36 #include "llvm/Target/TargetAsmParser.h"
42 FatalAssemblerWarnings("fatal-assembler-warnings",
43 cl::desc("Consider warnings as error"));
47 /// \brief Helper class for tracking macro definitions.
51 std::vector
<StringRef
> Parameters
;
54 Macro(StringRef N
, StringRef B
, const std::vector
<StringRef
> &P
) :
55 Name(N
), Body(B
), Parameters(P
) {}
58 /// \brief Helper class for storing information about an active macro
60 struct MacroInstantiation
{
61 /// The macro being instantiated.
62 const Macro
*TheMacro
;
64 /// The macro instantiation with substitutions.
65 MemoryBuffer
*Instantiation
;
67 /// The location of the instantiation.
68 SMLoc InstantiationLoc
;
70 /// The location where parsing should resume upon instantiation completion.
74 MacroInstantiation(const Macro
*M
, SMLoc IL
, SMLoc EL
,
78 /// \brief The concrete assembly parser instance.
79 class AsmParser
: public MCAsmParser
{
80 friend class GenericAsmParser
;
82 AsmParser(const AsmParser
&); // DO NOT IMPLEMENT
83 void operator=(const AsmParser
&); // DO NOT IMPLEMENT
90 MCAsmParserExtension
*GenericParser
;
91 MCAsmParserExtension
*PlatformParser
;
93 /// This is the current buffer index we're lexing from as managed by the
98 std::vector
<AsmCond
> TheCondStack
;
100 /// DirectiveMap - This is a table handlers for directives. Each handler is
101 /// invoked after the directive identifier is read and is responsible for
102 /// parsing and validating the rest of the directive. The handler is passed
103 /// in the directive name and the location of the directive keyword.
104 StringMap
<std::pair
<MCAsmParserExtension
*, DirectiveHandler
> > DirectiveMap
;
106 /// MacroMap - Map of currently defined macros.
107 StringMap
<Macro
*> MacroMap
;
109 /// ActiveMacros - Stack of active macro instantiations.
110 std::vector
<MacroInstantiation
*> ActiveMacros
;
112 /// Boolean tracking whether macro substitution is enabled.
113 unsigned MacrosEnabled
: 1;
115 /// Flag tracking whether any errors have been encountered.
116 unsigned HadError
: 1;
119 AsmParser(const Target
&T
, SourceMgr
&SM
, MCContext
&Ctx
, MCStreamer
&Out
,
120 const MCAsmInfo
&MAI
);
123 virtual bool Run(bool NoInitialTextSection
, bool NoFinalize
= false);
125 void AddDirectiveHandler(MCAsmParserExtension
*Object
,
127 DirectiveHandler Handler
) {
128 DirectiveMap
[Directive
] = std::make_pair(Object
, Handler
);
132 /// @name MCAsmParser Interface
135 virtual SourceMgr
&getSourceManager() { return SrcMgr
; }
136 virtual MCAsmLexer
&getLexer() { return Lexer
; }
137 virtual MCContext
&getContext() { return Ctx
; }
138 virtual MCStreamer
&getStreamer() { return Out
; }
140 virtual bool Warning(SMLoc L
, const Twine
&Msg
);
141 virtual bool Error(SMLoc L
, const Twine
&Msg
);
143 const AsmToken
&Lex();
145 bool ParseExpression(const MCExpr
*&Res
);
146 virtual bool ParseExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
);
147 virtual bool ParseParenExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
);
148 virtual bool ParseAbsoluteExpression(int64_t &Res
);
153 void CheckForValidSection();
155 bool ParseStatement();
157 bool HandleMacroEntry(StringRef Name
, SMLoc NameLoc
, const Macro
*M
);
158 bool expandMacro(SmallString
<256> &Buf
, StringRef Body
,
159 const std::vector
<StringRef
> &Parameters
,
160 const std::vector
<std::vector
<AsmToken
> > &A
,
162 void HandleMacroExit();
164 void PrintMacroInstantiations();
165 void PrintMessage(SMLoc Loc
, const Twine
&Msg
, const char *Type
,
166 bool ShowLine
= true) const {
167 SrcMgr
.PrintMessage(Loc
, Msg
, Type
, ShowLine
);
170 /// EnterIncludeFile - Enter the specified file. This returns true on failure.
171 bool EnterIncludeFile(const std::string
&Filename
);
173 /// \brief Reset the current lexer position to that given by \arg Loc. The
174 /// current token is not set; clients should ensure Lex() is called
176 void JumpToLoc(SMLoc Loc
);
178 void EatToEndOfStatement();
180 /// \brief Parse up to the end of statement and a return the contents from the
181 /// current token until the end of the statement; the current token on exit
182 /// will be either the EndOfStatement or EOF.
183 StringRef
ParseStringToEndOfStatement();
185 bool ParseAssignment(StringRef Name
, bool allow_redef
);
187 bool ParsePrimaryExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
);
188 bool ParseBinOpRHS(unsigned Precedence
, const MCExpr
*&Res
, SMLoc
&EndLoc
);
189 bool ParseParenExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
);
190 bool ParseBracketExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
);
192 /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
193 /// and set \arg Res to the identifier contents.
194 bool ParseIdentifier(StringRef
&Res
);
196 // Directive Parsing.
198 // ".ascii", ".asciiz", ".string"
199 bool ParseDirectiveAscii(StringRef IDVal
, bool ZeroTerminated
);
200 bool ParseDirectiveValue(unsigned Size
); // ".byte", ".long", ...
201 bool ParseDirectiveRealValue(const fltSemantics
&); // ".single", ...
202 bool ParseDirectiveFill(); // ".fill"
203 bool ParseDirectiveSpace(); // ".space"
204 bool ParseDirectiveZero(); // ".zero"
205 bool ParseDirectiveSet(StringRef IDVal
, bool allow_redef
); // ".set", ".equ", ".equiv"
206 bool ParseDirectiveOrg(); // ".org"
207 // ".align{,32}", ".p2align{,w,l}"
208 bool ParseDirectiveAlign(bool IsPow2
, unsigned ValueSize
);
210 /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
211 /// accepts a single symbol (which should be a label or an external).
212 bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr
);
214 bool ParseDirectiveComm(bool IsLocal
); // ".comm" and ".lcomm"
216 bool ParseDirectiveAbort(); // ".abort"
217 bool ParseDirectiveInclude(); // ".include"
219 bool ParseDirectiveIf(SMLoc DirectiveLoc
); // ".if"
220 // ".ifdef" or ".ifndef", depending on expect_defined
221 bool ParseDirectiveIfdef(SMLoc DirectiveLoc
, bool expect_defined
);
222 bool ParseDirectiveElseIf(SMLoc DirectiveLoc
); // ".elseif"
223 bool ParseDirectiveElse(SMLoc DirectiveLoc
); // ".else"
224 bool ParseDirectiveEndIf(SMLoc DirectiveLoc
); // .endif
226 /// ParseEscapedString - Parse the current token as a string which may include
227 /// escaped characters and return the string contents.
228 bool ParseEscapedString(std::string
&Data
);
230 const MCExpr
*ApplyModifierToExpr(const MCExpr
*E
,
231 MCSymbolRefExpr::VariantKind Variant
);
234 /// \brief Generic implementations of directive handling, etc. which is shared
235 /// (or the default, at least) for all assembler parser.
236 class GenericAsmParser
: public MCAsmParserExtension
{
237 template<bool (GenericAsmParser::*Handler
)(StringRef
, SMLoc
)>
238 void AddDirectiveHandler(StringRef Directive
) {
239 getParser().AddDirectiveHandler(this, Directive
,
240 HandleDirective
<GenericAsmParser
, Handler
>);
243 GenericAsmParser() {}
245 AsmParser
&getParser() {
246 return (AsmParser
&) this->MCAsmParserExtension::getParser();
249 virtual void Initialize(MCAsmParser
&Parser
) {
250 // Call the base implementation.
251 this->MCAsmParserExtension::Initialize(Parser
);
253 // Debugging directives.
254 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveFile
>(".file");
255 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLine
>(".line");
256 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLoc
>(".loc");
257 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveStabs
>(".stabs");
260 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFISections
>(
262 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIStartProc
>(
264 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIEndProc
>(
266 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIDefCfa
>(
268 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset
>(
269 ".cfi_def_cfa_offset");
270 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset
>(
271 ".cfi_adjust_cfa_offset");
272 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister
>(
273 ".cfi_def_cfa_register");
274 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIOffset
>(
276 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveCFIRelOffset
>(
279 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda
>(".cfi_personality");
281 &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda
>(".cfi_lsda");
283 &GenericAsmParser::ParseDirectiveCFIRememberState
>(".cfi_remember_state");
285 &GenericAsmParser::ParseDirectiveCFIRestoreState
>(".cfi_restore_state");
287 &GenericAsmParser::ParseDirectiveCFISameValue
>(".cfi_same_value");
290 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveMacrosOnOff
>(
292 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveMacrosOnOff
>(
294 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveMacro
>(".macro");
295 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveEndMacro
>(".endm");
296 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveEndMacro
>(".endmacro");
298 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLEB128
>(".sleb128");
299 AddDirectiveHandler
<&GenericAsmParser::ParseDirectiveLEB128
>(".uleb128");
302 bool ParseRegisterOrRegisterNumber(int64_t &Register
, SMLoc DirectiveLoc
);
304 bool ParseDirectiveFile(StringRef
, SMLoc DirectiveLoc
);
305 bool ParseDirectiveLine(StringRef
, SMLoc DirectiveLoc
);
306 bool ParseDirectiveLoc(StringRef
, SMLoc DirectiveLoc
);
307 bool ParseDirectiveStabs(StringRef
, SMLoc DirectiveLoc
);
308 bool ParseDirectiveCFISections(StringRef
, SMLoc DirectiveLoc
);
309 bool ParseDirectiveCFIStartProc(StringRef
, SMLoc DirectiveLoc
);
310 bool ParseDirectiveCFIEndProc(StringRef
, SMLoc DirectiveLoc
);
311 bool ParseDirectiveCFIDefCfa(StringRef
, SMLoc DirectiveLoc
);
312 bool ParseDirectiveCFIDefCfaOffset(StringRef
, SMLoc DirectiveLoc
);
313 bool ParseDirectiveCFIAdjustCfaOffset(StringRef
, SMLoc DirectiveLoc
);
314 bool ParseDirectiveCFIDefCfaRegister(StringRef
, SMLoc DirectiveLoc
);
315 bool ParseDirectiveCFIOffset(StringRef
, SMLoc DirectiveLoc
);
316 bool ParseDirectiveCFIRelOffset(StringRef
, SMLoc DirectiveLoc
);
317 bool ParseDirectiveCFIPersonalityOrLsda(StringRef
, SMLoc DirectiveLoc
);
318 bool ParseDirectiveCFIRememberState(StringRef
, SMLoc DirectiveLoc
);
319 bool ParseDirectiveCFIRestoreState(StringRef
, SMLoc DirectiveLoc
);
320 bool ParseDirectiveCFISameValue(StringRef
, SMLoc DirectiveLoc
);
322 bool ParseDirectiveMacrosOnOff(StringRef
, SMLoc DirectiveLoc
);
323 bool ParseDirectiveMacro(StringRef
, SMLoc DirectiveLoc
);
324 bool ParseDirectiveEndMacro(StringRef
, SMLoc DirectiveLoc
);
326 bool ParseDirectiveLEB128(StringRef
, SMLoc
);
333 extern MCAsmParserExtension
*createDarwinAsmParser();
334 extern MCAsmParserExtension
*createELFAsmParser();
335 extern MCAsmParserExtension
*createCOFFAsmParser();
339 enum { DEFAULT_ADDRSPACE
= 0 };
341 AsmParser::AsmParser(const Target
&T
, SourceMgr
&_SM
, MCContext
&_Ctx
,
342 MCStreamer
&_Out
, const MCAsmInfo
&_MAI
)
343 : Lexer(_MAI
), Ctx(_Ctx
), Out(_Out
), MAI(_MAI
), SrcMgr(_SM
),
344 GenericParser(new GenericAsmParser
), PlatformParser(0),
345 CurBuffer(0), MacrosEnabled(true) {
346 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
));
348 // Initialize the generic parser.
349 GenericParser
->Initialize(*this);
351 // Initialize the platform / file format parser.
353 // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
355 if (_MAI
.hasMicrosoftFastStdCallMangling()) {
356 PlatformParser
= createCOFFAsmParser();
357 PlatformParser
->Initialize(*this);
358 } else if (_MAI
.hasSubsectionsViaSymbols()) {
359 PlatformParser
= createDarwinAsmParser();
360 PlatformParser
->Initialize(*this);
362 PlatformParser
= createELFAsmParser();
363 PlatformParser
->Initialize(*this);
367 AsmParser::~AsmParser() {
368 assert(ActiveMacros
.empty() && "Unexpected active macro instantiation!");
370 // Destroy any macros.
371 for (StringMap
<Macro
*>::iterator it
= MacroMap
.begin(),
372 ie
= MacroMap
.end(); it
!= ie
; ++it
)
373 delete it
->getValue();
375 delete PlatformParser
;
376 delete GenericParser
;
379 void AsmParser::PrintMacroInstantiations() {
380 // Print the active macro instantiation stack.
381 for (std::vector
<MacroInstantiation
*>::const_reverse_iterator
382 it
= ActiveMacros
.rbegin(), ie
= ActiveMacros
.rend(); it
!= ie
; ++it
)
383 PrintMessage((*it
)->InstantiationLoc
, "while in macro instantiation",
387 bool AsmParser::Warning(SMLoc L
, const Twine
&Msg
) {
388 if (FatalAssemblerWarnings
)
389 return Error(L
, Msg
);
390 PrintMessage(L
, Msg
, "warning");
391 PrintMacroInstantiations();
395 bool AsmParser::Error(SMLoc L
, const Twine
&Msg
) {
397 PrintMessage(L
, Msg
, "error");
398 PrintMacroInstantiations();
402 bool AsmParser::EnterIncludeFile(const std::string
&Filename
) {
403 std::string IncludedFile
;
404 int NewBuf
= SrcMgr
.AddIncludeFile(Filename
, Lexer
.getLoc(), IncludedFile
);
410 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
));
415 void AsmParser::JumpToLoc(SMLoc Loc
) {
416 CurBuffer
= SrcMgr
.FindBufferContainingLoc(Loc
);
417 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
), Loc
.getPointer());
420 const AsmToken
&AsmParser::Lex() {
421 const AsmToken
*tok
= &Lexer
.Lex();
423 if (tok
->is(AsmToken::Eof
)) {
424 // If this is the end of an included file, pop the parent file off the
426 SMLoc ParentIncludeLoc
= SrcMgr
.getParentIncludeLoc(CurBuffer
);
427 if (ParentIncludeLoc
!= SMLoc()) {
428 JumpToLoc(ParentIncludeLoc
);
433 if (tok
->is(AsmToken::Error
))
434 Error(Lexer
.getErrLoc(), Lexer
.getErr());
439 bool AsmParser::Run(bool NoInitialTextSection
, bool NoFinalize
) {
440 // Create the initial section, if requested.
441 if (!NoInitialTextSection
)
448 AsmCond StartingCondState
= TheCondState
;
450 // While we have input, parse each statement.
451 while (Lexer
.isNot(AsmToken::Eof
)) {
452 if (!ParseStatement()) continue;
454 // We had an error, validate that one was emitted and recover by skipping to
456 assert(HadError
&& "Parse statement returned an error, but none emitted!");
457 EatToEndOfStatement();
460 if (TheCondState
.TheCond
!= StartingCondState
.TheCond
||
461 TheCondState
.Ignore
!= StartingCondState
.Ignore
)
462 return TokError("unmatched .ifs or .elses");
464 // Check to see there are no empty DwarfFile slots.
465 const std::vector
<MCDwarfFile
*> &MCDwarfFiles
=
466 getContext().getMCDwarfFiles();
467 for (unsigned i
= 1; i
< MCDwarfFiles
.size(); i
++) {
468 if (!MCDwarfFiles
[i
])
469 TokError("unassigned file number: " + Twine(i
) + " for .file directives");
472 // Check to see that all assembler local symbols were actually defined.
473 // Targets that don't do subsections via symbols may not want this, though,
474 // so conservatively exclude them. Only do this if we're finalizing, though,
475 // as otherwise we won't necessarilly have seen everything yet.
476 if (!NoFinalize
&& MAI
.hasSubsectionsViaSymbols()) {
477 const MCContext::SymbolTable
&Symbols
= getContext().getSymbols();
478 for (MCContext::SymbolTable::const_iterator i
= Symbols
.begin(),
481 MCSymbol
*Sym
= i
->getValue();
482 // Variable symbols may not be marked as defined, so check those
483 // explicitly. If we know it's a variable, we have a definition for
484 // the purposes of this check.
485 if (Sym
->isTemporary() && !Sym
->isVariable() && !Sym
->isDefined())
486 // FIXME: We would really like to refer back to where the symbol was
487 // first referenced for a source location. We need to add something
488 // to track that. Currently, we just point to the end of the file.
489 PrintMessage(getLexer().getLoc(), "assembler local symbol '" +
490 Sym
->getName() + "' not defined", "error", false);
495 // Finalize the output stream if there are no errors and if the client wants
497 if (!HadError
&& !NoFinalize
)
503 void AsmParser::CheckForValidSection() {
504 if (!getStreamer().getCurrentSection()) {
505 TokError("expected section directive before assembly directive");
506 Out
.SwitchSection(Ctx
.getMachOSection(
508 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
509 0, SectionKind::getText()));
513 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
514 void AsmParser::EatToEndOfStatement() {
515 while (Lexer
.isNot(AsmToken::EndOfStatement
) &&
516 Lexer
.isNot(AsmToken::Eof
))
520 if (Lexer
.is(AsmToken::EndOfStatement
))
524 StringRef
AsmParser::ParseStringToEndOfStatement() {
525 const char *Start
= getTok().getLoc().getPointer();
527 while (Lexer
.isNot(AsmToken::EndOfStatement
) &&
528 Lexer
.isNot(AsmToken::Eof
))
531 const char *End
= getTok().getLoc().getPointer();
532 return StringRef(Start
, End
- Start
);
535 /// ParseParenExpr - Parse a paren expression and return it.
536 /// NOTE: This assumes the leading '(' has already been consumed.
538 /// parenexpr ::= expr)
540 bool AsmParser::ParseParenExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
541 if (ParseExpression(Res
)) return true;
542 if (Lexer
.isNot(AsmToken::RParen
))
543 return TokError("expected ')' in parentheses expression");
544 EndLoc
= Lexer
.getLoc();
549 /// ParseBracketExpr - Parse a bracket expression and return it.
550 /// NOTE: This assumes the leading '[' has already been consumed.
552 /// bracketexpr ::= expr]
554 bool AsmParser::ParseBracketExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
555 if (ParseExpression(Res
)) return true;
556 if (Lexer
.isNot(AsmToken::RBrac
))
557 return TokError("expected ']' in brackets expression");
558 EndLoc
= Lexer
.getLoc();
563 /// ParsePrimaryExpr - Parse a primary expression and return it.
564 /// primaryexpr ::= (parenexpr
565 /// primaryexpr ::= symbol
566 /// primaryexpr ::= number
567 /// primaryexpr ::= '.'
568 /// primaryexpr ::= ~,+,- primaryexpr
569 bool AsmParser::ParsePrimaryExpr(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
570 switch (Lexer
.getKind()) {
572 return TokError("unknown token in expression");
573 // If we have an error assume that we've already handled it.
574 case AsmToken::Error
:
576 case AsmToken::Exclaim
:
577 Lex(); // Eat the operator.
578 if (ParsePrimaryExpr(Res
, EndLoc
))
580 Res
= MCUnaryExpr::CreateLNot(Res
, getContext());
582 case AsmToken::Dollar
:
583 case AsmToken::String
:
584 case AsmToken::Identifier
: {
585 EndLoc
= Lexer
.getLoc();
587 StringRef Identifier
;
588 if (ParseIdentifier(Identifier
))
591 // This is a symbol reference.
592 std::pair
<StringRef
, StringRef
> Split
= Identifier
.split('@');
593 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Split
.first
);
595 // Lookup the symbol variant if used.
596 MCSymbolRefExpr::VariantKind Variant
= MCSymbolRefExpr::VK_None
;
597 if (Split
.first
.size() != Identifier
.size()) {
598 Variant
= MCSymbolRefExpr::getVariantKindForName(Split
.second
);
599 if (Variant
== MCSymbolRefExpr::VK_Invalid
) {
600 Variant
= MCSymbolRefExpr::VK_None
;
601 return TokError("invalid variant '" + Split
.second
+ "'");
605 // If this is an absolute variable reference, substitute it now to preserve
606 // semantics in the face of reassignment.
607 if (Sym
->isVariable() && isa
<MCConstantExpr
>(Sym
->getVariableValue())) {
609 return Error(EndLoc
, "unexpected modifier on variable reference");
611 Res
= Sym
->getVariableValue();
615 // Otherwise create a symbol ref.
616 Res
= MCSymbolRefExpr::Create(Sym
, Variant
, getContext());
619 case AsmToken::Integer
: {
620 SMLoc Loc
= getTok().getLoc();
621 int64_t IntVal
= getTok().getIntVal();
622 Res
= MCConstantExpr::Create(IntVal
, getContext());
623 EndLoc
= Lexer
.getLoc();
625 // Look for 'b' or 'f' following an Integer as a directional label
626 if (Lexer
.getKind() == AsmToken::Identifier
) {
627 StringRef IDVal
= getTok().getString();
628 if (IDVal
== "f" || IDVal
== "b"){
629 MCSymbol
*Sym
= Ctx
.GetDirectionalLocalSymbol(IntVal
,
630 IDVal
== "f" ? 1 : 0);
631 Res
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_None
,
633 if(IDVal
== "b" && Sym
->isUndefined())
634 return Error(Loc
, "invalid reference to undefined symbol");
635 EndLoc
= Lexer
.getLoc();
636 Lex(); // Eat identifier.
641 case AsmToken::Real
: {
642 APFloat
RealVal(APFloat::IEEEdouble
, getTok().getString());
643 uint64_t IntVal
= RealVal
.bitcastToAPInt().getZExtValue();
644 Res
= MCConstantExpr::Create(IntVal
, getContext());
648 case AsmToken::Dot
: {
649 // This is a '.' reference, which references the current PC. Emit a
650 // temporary label to the streamer and refer to it.
651 MCSymbol
*Sym
= Ctx
.CreateTempSymbol();
653 Res
= MCSymbolRefExpr::Create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
654 EndLoc
= Lexer
.getLoc();
655 Lex(); // Eat identifier.
658 case AsmToken::LParen
:
659 Lex(); // Eat the '('.
660 return ParseParenExpr(Res
, EndLoc
);
661 case AsmToken::LBrac
:
662 if (!PlatformParser
->HasBracketExpressions())
663 return TokError("brackets expression not supported on this target");
664 Lex(); // Eat the '['.
665 return ParseBracketExpr(Res
, EndLoc
);
666 case AsmToken::Minus
:
667 Lex(); // Eat the operator.
668 if (ParsePrimaryExpr(Res
, EndLoc
))
670 Res
= MCUnaryExpr::CreateMinus(Res
, getContext());
673 Lex(); // Eat the operator.
674 if (ParsePrimaryExpr(Res
, EndLoc
))
676 Res
= MCUnaryExpr::CreatePlus(Res
, getContext());
678 case AsmToken::Tilde
:
679 Lex(); // Eat the operator.
680 if (ParsePrimaryExpr(Res
, EndLoc
))
682 Res
= MCUnaryExpr::CreateNot(Res
, getContext());
687 bool AsmParser::ParseExpression(const MCExpr
*&Res
) {
689 return ParseExpression(Res
, EndLoc
);
693 AsmParser::ApplyModifierToExpr(const MCExpr
*E
,
694 MCSymbolRefExpr::VariantKind Variant
) {
695 // Recurse over the given expression, rebuilding it to apply the given variant
696 // if there is exactly one symbol.
697 switch (E
->getKind()) {
699 case MCExpr::Constant
:
702 case MCExpr::SymbolRef
: {
703 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(E
);
705 if (SRE
->getKind() != MCSymbolRefExpr::VK_None
) {
706 TokError("invalid variant on expression '" +
707 getTok().getIdentifier() + "' (already modified)");
711 return MCSymbolRefExpr::Create(&SRE
->getSymbol(), Variant
, getContext());
714 case MCExpr::Unary
: {
715 const MCUnaryExpr
*UE
= cast
<MCUnaryExpr
>(E
);
716 const MCExpr
*Sub
= ApplyModifierToExpr(UE
->getSubExpr(), Variant
);
719 return MCUnaryExpr::Create(UE
->getOpcode(), Sub
, getContext());
722 case MCExpr::Binary
: {
723 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(E
);
724 const MCExpr
*LHS
= ApplyModifierToExpr(BE
->getLHS(), Variant
);
725 const MCExpr
*RHS
= ApplyModifierToExpr(BE
->getRHS(), Variant
);
730 if (!LHS
) LHS
= BE
->getLHS();
731 if (!RHS
) RHS
= BE
->getRHS();
733 return MCBinaryExpr::Create(BE
->getOpcode(), LHS
, RHS
, getContext());
737 assert(0 && "Invalid expression kind!");
741 /// ParseExpression - Parse an expression and return it.
743 /// expr ::= expr +,- expr -> lowest.
744 /// expr ::= expr |,^,&,! expr -> middle.
745 /// expr ::= expr *,/,%,<<,>> expr -> highest.
746 /// expr ::= primaryexpr
748 bool AsmParser::ParseExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
749 // Parse the expression.
751 if (ParsePrimaryExpr(Res
, EndLoc
) || ParseBinOpRHS(1, Res
, EndLoc
))
754 // As a special case, we support 'a op b @ modifier' by rewriting the
755 // expression to include the modifier. This is inefficient, but in general we
756 // expect users to use 'a@modifier op b'.
757 if (Lexer
.getKind() == AsmToken::At
) {
760 if (Lexer
.isNot(AsmToken::Identifier
))
761 return TokError("unexpected symbol modifier following '@'");
763 MCSymbolRefExpr::VariantKind Variant
=
764 MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
765 if (Variant
== MCSymbolRefExpr::VK_Invalid
)
766 return TokError("invalid variant '" + getTok().getIdentifier() + "'");
768 const MCExpr
*ModifiedRes
= ApplyModifierToExpr(Res
, Variant
);
770 return TokError("invalid modifier '" + getTok().getIdentifier() +
771 "' (no symbols present)");
779 // Try to constant fold it up front, if possible.
781 if (Res
->EvaluateAsAbsolute(Value
))
782 Res
= MCConstantExpr::Create(Value
, getContext());
787 bool AsmParser::ParseParenExpression(const MCExpr
*&Res
, SMLoc
&EndLoc
) {
789 return ParseParenExpr(Res
, EndLoc
) ||
790 ParseBinOpRHS(1, Res
, EndLoc
);
793 bool AsmParser::ParseAbsoluteExpression(int64_t &Res
) {
796 SMLoc StartLoc
= Lexer
.getLoc();
797 if (ParseExpression(Expr
))
800 if (!Expr
->EvaluateAsAbsolute(Res
))
801 return Error(StartLoc
, "expected absolute expression");
806 static unsigned getBinOpPrecedence(AsmToken::TokenKind K
,
807 MCBinaryExpr::Opcode
&Kind
) {
810 return 0; // not a binop.
812 // Lowest Precedence: &&, ||, @
813 case AsmToken::AmpAmp
:
814 Kind
= MCBinaryExpr::LAnd
;
816 case AsmToken::PipePipe
:
817 Kind
= MCBinaryExpr::LOr
;
821 // Low Precedence: |, &, ^
823 // FIXME: gas seems to support '!' as an infix operator?
825 Kind
= MCBinaryExpr::Or
;
827 case AsmToken::Caret
:
828 Kind
= MCBinaryExpr::Xor
;
831 Kind
= MCBinaryExpr::And
;
834 // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
835 case AsmToken::EqualEqual
:
836 Kind
= MCBinaryExpr::EQ
;
838 case AsmToken::ExclaimEqual
:
839 case AsmToken::LessGreater
:
840 Kind
= MCBinaryExpr::NE
;
843 Kind
= MCBinaryExpr::LT
;
845 case AsmToken::LessEqual
:
846 Kind
= MCBinaryExpr::LTE
;
848 case AsmToken::Greater
:
849 Kind
= MCBinaryExpr::GT
;
851 case AsmToken::GreaterEqual
:
852 Kind
= MCBinaryExpr::GTE
;
855 // High Intermediate Precedence: +, -
857 Kind
= MCBinaryExpr::Add
;
859 case AsmToken::Minus
:
860 Kind
= MCBinaryExpr::Sub
;
863 // Highest Precedence: *, /, %, <<, >>
865 Kind
= MCBinaryExpr::Mul
;
867 case AsmToken::Slash
:
868 Kind
= MCBinaryExpr::Div
;
870 case AsmToken::Percent
:
871 Kind
= MCBinaryExpr::Mod
;
873 case AsmToken::LessLess
:
874 Kind
= MCBinaryExpr::Shl
;
876 case AsmToken::GreaterGreater
:
877 Kind
= MCBinaryExpr::Shr
;
883 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
884 /// Res contains the LHS of the expression on input.
885 bool AsmParser::ParseBinOpRHS(unsigned Precedence
, const MCExpr
*&Res
,
888 MCBinaryExpr::Opcode Kind
= MCBinaryExpr::Add
;
889 unsigned TokPrec
= getBinOpPrecedence(Lexer
.getKind(), Kind
);
891 // If the next token is lower precedence than we are allowed to eat, return
892 // successfully with what we ate already.
893 if (TokPrec
< Precedence
)
898 // Eat the next primary expression.
900 if (ParsePrimaryExpr(RHS
, EndLoc
)) return true;
902 // If BinOp binds less tightly with RHS than the operator after RHS, let
903 // the pending operator take RHS as its LHS.
904 MCBinaryExpr::Opcode Dummy
;
905 unsigned NextTokPrec
= getBinOpPrecedence(Lexer
.getKind(), Dummy
);
906 if (TokPrec
< NextTokPrec
) {
907 if (ParseBinOpRHS(Precedence
+1, RHS
, EndLoc
)) return true;
910 // Merge LHS and RHS according to operator.
911 Res
= MCBinaryExpr::Create(Kind
, Res
, RHS
, getContext());
919 /// ::= EndOfStatement
920 /// ::= Label* Directive ...Operands... EndOfStatement
921 /// ::= Label* Identifier OperandList* EndOfStatement
922 bool AsmParser::ParseStatement() {
923 if (Lexer
.is(AsmToken::EndOfStatement
)) {
929 // Statements always start with an identifier or are a full line comment.
930 AsmToken ID
= getTok();
931 SMLoc IDLoc
= ID
.getLoc();
933 int64_t LocalLabelVal
= -1;
934 // A full line comment is a '#' as the first token.
935 if (Lexer
.is(AsmToken::Hash
)) {
936 EatToEndOfStatement();
940 // Allow an integer followed by a ':' as a directional local label.
941 if (Lexer
.is(AsmToken::Integer
)) {
942 LocalLabelVal
= getTok().getIntVal();
943 if (LocalLabelVal
< 0) {
944 if (!TheCondState
.Ignore
)
945 return TokError("unexpected token at start of statement");
949 IDVal
= getTok().getString();
950 Lex(); // Consume the integer token to be used as an identifier token.
951 if (Lexer
.getKind() != AsmToken::Colon
) {
952 if (!TheCondState
.Ignore
)
953 return TokError("unexpected token at start of statement");
957 } else if (Lexer
.is(AsmToken::Dot
)) {
958 // Treat '.' as a valid identifier in this context.
962 } else if (ParseIdentifier(IDVal
)) {
963 if (!TheCondState
.Ignore
)
964 return TokError("unexpected token at start of statement");
969 // Handle conditional assembly here before checking for skipping. We
970 // have to do this so that .endif isn't skipped in a ".if 0" block for
973 return ParseDirectiveIf(IDLoc
);
974 if (IDVal
== ".ifdef")
975 return ParseDirectiveIfdef(IDLoc
, true);
976 if (IDVal
== ".ifndef" || IDVal
== ".ifnotdef")
977 return ParseDirectiveIfdef(IDLoc
, false);
978 if (IDVal
== ".elseif")
979 return ParseDirectiveElseIf(IDLoc
);
980 if (IDVal
== ".else")
981 return ParseDirectiveElse(IDLoc
);
982 if (IDVal
== ".endif")
983 return ParseDirectiveEndIf(IDLoc
);
985 // If we are in a ".if 0" block, ignore this statement.
986 if (TheCondState
.Ignore
) {
987 EatToEndOfStatement();
991 // FIXME: Recurse on local labels?
993 // See what kind of statement we have.
994 switch (Lexer
.getKind()) {
995 case AsmToken::Colon
: {
996 CheckForValidSection();
998 // identifier ':' -> Label.
1001 // Diagnose attempt to use '.' as a label.
1003 return Error(IDLoc
, "invalid use of pseudo-symbol '.' as a label");
1005 // Diagnose attempt to use a variable as a label.
1007 // FIXME: Diagnostics. Note the location of the definition as a label.
1008 // FIXME: This doesn't diagnose assignment to a symbol which has been
1009 // implicitly marked as external.
1011 if (LocalLabelVal
== -1)
1012 Sym
= getContext().GetOrCreateSymbol(IDVal
);
1014 Sym
= Ctx
.CreateDirectionalLocalSymbol(LocalLabelVal
);
1015 if (!Sym
->isUndefined() || Sym
->isVariable())
1016 return Error(IDLoc
, "invalid symbol redefinition");
1021 // Consume any end of statement token, if present, to avoid spurious
1022 // AddBlankLine calls().
1023 if (Lexer
.is(AsmToken::EndOfStatement
)) {
1025 if (Lexer
.is(AsmToken::Eof
))
1029 return ParseStatement();
1032 case AsmToken::Equal
:
1033 // identifier '=' ... -> assignment statement
1036 return ParseAssignment(IDVal
, true);
1038 default: // Normal instruction or directive.
1042 // If macros are enabled, check to see if this is a macro instantiation.
1044 if (const Macro
*M
= MacroMap
.lookup(IDVal
))
1045 return HandleMacroEntry(IDVal
, IDLoc
, M
);
1047 // Otherwise, we have a normal instruction or directive.
1048 if (IDVal
[0] == '.' && IDVal
!= ".") {
1049 // Assembler features
1050 if (IDVal
== ".set" || IDVal
== ".equ")
1051 return ParseDirectiveSet(IDVal
, true);
1052 if (IDVal
== ".equiv")
1053 return ParseDirectiveSet(IDVal
, false);
1057 if (IDVal
== ".ascii")
1058 return ParseDirectiveAscii(IDVal
, false);
1059 if (IDVal
== ".asciz" || IDVal
== ".string")
1060 return ParseDirectiveAscii(IDVal
, true);
1062 if (IDVal
== ".byte")
1063 return ParseDirectiveValue(1);
1064 if (IDVal
== ".short")
1065 return ParseDirectiveValue(2);
1066 if (IDVal
== ".value")
1067 return ParseDirectiveValue(2);
1068 if (IDVal
== ".2byte")
1069 return ParseDirectiveValue(2);
1070 if (IDVal
== ".long")
1071 return ParseDirectiveValue(4);
1072 if (IDVal
== ".int")
1073 return ParseDirectiveValue(4);
1074 if (IDVal
== ".4byte")
1075 return ParseDirectiveValue(4);
1076 if (IDVal
== ".quad")
1077 return ParseDirectiveValue(8);
1078 if (IDVal
== ".8byte")
1079 return ParseDirectiveValue(8);
1080 if (IDVal
== ".single" || IDVal
== ".float")
1081 return ParseDirectiveRealValue(APFloat::IEEEsingle
);
1082 if (IDVal
== ".double")
1083 return ParseDirectiveRealValue(APFloat::IEEEdouble
);
1085 if (IDVal
== ".align") {
1086 bool IsPow2
= !getContext().getAsmInfo().getAlignmentIsInBytes();
1087 return ParseDirectiveAlign(IsPow2
, /*ExprSize=*/1);
1089 if (IDVal
== ".align32") {
1090 bool IsPow2
= !getContext().getAsmInfo().getAlignmentIsInBytes();
1091 return ParseDirectiveAlign(IsPow2
, /*ExprSize=*/4);
1093 if (IDVal
== ".balign")
1094 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
1095 if (IDVal
== ".balignw")
1096 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
1097 if (IDVal
== ".balignl")
1098 return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
1099 if (IDVal
== ".p2align")
1100 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
1101 if (IDVal
== ".p2alignw")
1102 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
1103 if (IDVal
== ".p2alignl")
1104 return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
1106 if (IDVal
== ".org")
1107 return ParseDirectiveOrg();
1109 if (IDVal
== ".fill")
1110 return ParseDirectiveFill();
1111 if (IDVal
== ".space" || IDVal
== ".skip")
1112 return ParseDirectiveSpace();
1113 if (IDVal
== ".zero")
1114 return ParseDirectiveZero();
1116 // Symbol attribute directives
1118 if (IDVal
== ".globl" || IDVal
== ".global")
1119 return ParseDirectiveSymbolAttribute(MCSA_Global
);
1120 // ELF only? Should it be here?
1121 if (IDVal
== ".local")
1122 return ParseDirectiveSymbolAttribute(MCSA_Local
);
1123 if (IDVal
== ".hidden")
1124 return ParseDirectiveSymbolAttribute(MCSA_Hidden
);
1125 if (IDVal
== ".indirect_symbol")
1126 return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol
);
1127 if (IDVal
== ".internal")
1128 return ParseDirectiveSymbolAttribute(MCSA_Internal
);
1129 if (IDVal
== ".lazy_reference")
1130 return ParseDirectiveSymbolAttribute(MCSA_LazyReference
);
1131 if (IDVal
== ".no_dead_strip")
1132 return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip
);
1133 if (IDVal
== ".symbol_resolver")
1134 return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver
);
1135 if (IDVal
== ".private_extern")
1136 return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern
);
1137 if (IDVal
== ".protected")
1138 return ParseDirectiveSymbolAttribute(MCSA_Protected
);
1139 if (IDVal
== ".reference")
1140 return ParseDirectiveSymbolAttribute(MCSA_Reference
);
1141 if (IDVal
== ".weak")
1142 return ParseDirectiveSymbolAttribute(MCSA_Weak
);
1143 if (IDVal
== ".weak_definition")
1144 return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition
);
1145 if (IDVal
== ".weak_reference")
1146 return ParseDirectiveSymbolAttribute(MCSA_WeakReference
);
1147 if (IDVal
== ".weak_def_can_be_hidden")
1148 return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate
);
1150 if (IDVal
== ".comm" || IDVal
== ".common")
1151 return ParseDirectiveComm(/*IsLocal=*/false);
1152 if (IDVal
== ".lcomm")
1153 return ParseDirectiveComm(/*IsLocal=*/true);
1155 if (IDVal
== ".abort")
1156 return ParseDirectiveAbort();
1157 if (IDVal
== ".include")
1158 return ParseDirectiveInclude();
1160 if (IDVal
== ".code16" || IDVal
== ".code32" || IDVal
== ".code64")
1161 return TokError(Twine(IDVal
) + " not supported yet");
1163 // Look up the handler in the handler table.
1164 std::pair
<MCAsmParserExtension
*, DirectiveHandler
> Handler
=
1165 DirectiveMap
.lookup(IDVal
);
1167 return (*Handler
.second
)(Handler
.first
, IDVal
, IDLoc
);
1169 // Target hook for parsing target specific directives.
1170 if (!getTargetParser().ParseDirective(ID
))
1173 bool retval
= Warning(IDLoc
, "ignoring directive for now");
1174 EatToEndOfStatement();
1178 CheckForValidSection();
1180 // Canonicalize the opcode to lower case.
1181 SmallString
<128> Opcode
;
1182 for (unsigned i
= 0, e
= IDVal
.size(); i
!= e
; ++i
)
1183 Opcode
.push_back(tolower(IDVal
[i
]));
1185 SmallVector
<MCParsedAsmOperand
*, 8> ParsedOperands
;
1186 bool HadError
= getTargetParser().ParseInstruction(Opcode
.str(), IDLoc
,
1189 // Dump the parsed representation, if requested.
1190 if (getShowParsedOperands()) {
1191 SmallString
<256> Str
;
1192 raw_svector_ostream
OS(Str
);
1193 OS
<< "parsed instruction: [";
1194 for (unsigned i
= 0; i
!= ParsedOperands
.size(); ++i
) {
1197 ParsedOperands
[i
]->dump(OS
);
1201 PrintMessage(IDLoc
, OS
.str(), "note");
1204 // If parsing succeeded, match the instruction.
1206 HadError
= getTargetParser().MatchAndEmitInstruction(IDLoc
, ParsedOperands
,
1209 // Free any parsed operands.
1210 for (unsigned i
= 0, e
= ParsedOperands
.size(); i
!= e
; ++i
)
1211 delete ParsedOperands
[i
];
1213 // Don't skip the rest of the line, the instruction parser is responsible for
1218 bool AsmParser::expandMacro(SmallString
<256> &Buf
, StringRef Body
,
1219 const std::vector
<StringRef
> &Parameters
,
1220 const std::vector
<std::vector
<AsmToken
> > &A
,
1222 raw_svector_ostream
OS(Buf
);
1223 unsigned NParameters
= Parameters
.size();
1224 if (NParameters
!= 0 && NParameters
!= A
.size())
1225 return Error(L
, "Wrong number of arguments");
1227 while (!Body
.empty()) {
1228 // Scan for the next substitution.
1229 std::size_t End
= Body
.size(), Pos
= 0;
1230 for (; Pos
!= End
; ++Pos
) {
1231 // Check for a substitution or escape.
1233 // This macro has no parameters, look for $0, $1, etc.
1234 if (Body
[Pos
] != '$' || Pos
+ 1 == End
)
1237 char Next
= Body
[Pos
+ 1];
1238 if (Next
== '$' || Next
== 'n' || isdigit(Next
))
1241 // This macro has parameters, look for \foo, \bar, etc.
1242 if (Body
[Pos
] == '\\' && Pos
+ 1 != End
)
1248 OS
<< Body
.slice(0, Pos
);
1250 // Check if we reached the end.
1255 switch (Body
[Pos
+1]) {
1261 // $n => number of arguments
1266 // $[0-9] => argument
1268 // Missing arguments are ignored.
1269 unsigned Index
= Body
[Pos
+1] - '0';
1270 if (Index
>= A
.size())
1273 // Otherwise substitute with the token values, with spaces eliminated.
1274 for (std::vector
<AsmToken
>::const_iterator it
= A
[Index
].begin(),
1275 ie
= A
[Index
].end(); it
!= ie
; ++it
)
1276 OS
<< it
->getString();
1282 unsigned I
= Pos
+ 1;
1283 while (isalnum(Body
[I
]) && I
+ 1 != End
)
1286 const char *Begin
= Body
.data() + Pos
+1;
1287 StringRef
Argument(Begin
, I
- (Pos
+1));
1289 for (; Index
< NParameters
; ++Index
)
1290 if (Parameters
[Index
] == Argument
)
1293 // FIXME: We should error at the macro definition.
1294 if (Index
== NParameters
)
1295 return Error(L
, "Parameter not found");
1297 for (std::vector
<AsmToken
>::const_iterator it
= A
[Index
].begin(),
1298 ie
= A
[Index
].end(); it
!= ie
; ++it
)
1299 OS
<< it
->getString();
1301 Pos
+= 1 + Argument
.size();
1303 // Update the scan point.
1304 Body
= Body
.substr(Pos
);
1307 // We include the .endmacro in the buffer as our queue to exit the macro
1309 OS
<< ".endmacro\n";
1313 MacroInstantiation::MacroInstantiation(const Macro
*M
, SMLoc IL
, SMLoc EL
,
1315 : TheMacro(M
), Instantiation(I
), InstantiationLoc(IL
), ExitLoc(EL
)
1319 bool AsmParser::HandleMacroEntry(StringRef Name
, SMLoc NameLoc
,
1321 // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
1322 // this, although we should protect against infinite loops.
1323 if (ActiveMacros
.size() == 20)
1324 return TokError("macros cannot be nested more than 20 levels deep");
1326 // Parse the macro instantiation arguments.
1327 std::vector
<std::vector
<AsmToken
> > MacroArguments
;
1328 MacroArguments
.push_back(std::vector
<AsmToken
>());
1329 unsigned ParenLevel
= 0;
1331 if (Lexer
.is(AsmToken::Eof
))
1332 return TokError("unexpected token in macro instantiation");
1333 if (Lexer
.is(AsmToken::EndOfStatement
))
1336 // If we aren't inside parentheses and this is a comma, start a new token
1338 if (ParenLevel
== 0 && Lexer
.is(AsmToken::Comma
)) {
1339 MacroArguments
.push_back(std::vector
<AsmToken
>());
1341 // Adjust the current parentheses level.
1342 if (Lexer
.is(AsmToken::LParen
))
1344 else if (Lexer
.is(AsmToken::RParen
) && ParenLevel
)
1347 // Append the token to the current argument list.
1348 MacroArguments
.back().push_back(getTok());
1353 // Macro instantiation is lexical, unfortunately. We construct a new buffer
1354 // to hold the macro body with substitutions.
1355 SmallString
<256> Buf
;
1356 StringRef Body
= M
->Body
;
1358 if (expandMacro(Buf
, Body
, M
->Parameters
, MacroArguments
, getTok().getLoc()))
1361 MemoryBuffer
*Instantiation
=
1362 MemoryBuffer::getMemBufferCopy(Buf
.str(), "<instantiation>");
1364 // Create the macro instantiation object and add to the current macro
1365 // instantiation stack.
1366 MacroInstantiation
*MI
= new MacroInstantiation(M
, NameLoc
,
1369 ActiveMacros
.push_back(MI
);
1371 // Jump to the macro instantiation and prime the lexer.
1372 CurBuffer
= SrcMgr
.AddNewSourceBuffer(MI
->Instantiation
, SMLoc());
1373 Lexer
.setBuffer(SrcMgr
.getMemoryBuffer(CurBuffer
));
1379 void AsmParser::HandleMacroExit() {
1380 // Jump to the EndOfStatement we should return to, and consume it.
1381 JumpToLoc(ActiveMacros
.back()->ExitLoc
);
1384 // Pop the instantiation entry.
1385 delete ActiveMacros
.back();
1386 ActiveMacros
.pop_back();
1389 static void MarkUsed(const MCExpr
*Value
) {
1390 switch (Value
->getKind()) {
1391 case MCExpr::Binary
:
1392 MarkUsed(static_cast<const MCBinaryExpr
*>(Value
)->getLHS());
1393 MarkUsed(static_cast<const MCBinaryExpr
*>(Value
)->getRHS());
1395 case MCExpr::Target
:
1396 case MCExpr::Constant
:
1398 case MCExpr::SymbolRef
: {
1399 static_cast<const MCSymbolRefExpr
*>(Value
)->getSymbol().setUsed(true);
1403 MarkUsed(static_cast<const MCUnaryExpr
*>(Value
)->getSubExpr());
1408 bool AsmParser::ParseAssignment(StringRef Name
, bool allow_redef
) {
1409 // FIXME: Use better location, we should use proper tokens.
1410 SMLoc EqualLoc
= Lexer
.getLoc();
1412 const MCExpr
*Value
;
1413 if (ParseExpression(Value
))
1418 if (Lexer
.isNot(AsmToken::EndOfStatement
))
1419 return TokError("unexpected token in assignment");
1421 // Error on assignment to '.'.
1423 return Error(EqualLoc
, ("assignment to pseudo-symbol '.' is unsupported "
1424 "(use '.space' or '.org').)"));
1427 // Eat the end of statement marker.
1430 // Validate that the LHS is allowed to be a variable (either it has not been
1431 // used as a symbol, or it is an absolute symbol).
1432 MCSymbol
*Sym
= getContext().LookupSymbol(Name
);
1434 // Diagnose assignment to a label.
1436 // FIXME: Diagnostics. Note the location of the definition as a label.
1437 // FIXME: Diagnose assignment to protected identifier (e.g., register name).
1438 if (Sym
->isUndefined() && !Sym
->isUsed() && !Sym
->isVariable())
1439 ; // Allow redefinitions of undefined symbols only used in directives.
1440 else if (!Sym
->isUndefined() && (!Sym
->isVariable() || !allow_redef
))
1441 return Error(EqualLoc
, "redefinition of '" + Name
+ "'");
1442 else if (!Sym
->isVariable())
1443 return Error(EqualLoc
, "invalid assignment to '" + Name
+ "'");
1444 else if (!isa
<MCConstantExpr
>(Sym
->getVariableValue()))
1445 return Error(EqualLoc
, "invalid reassignment of non-absolute variable '" +
1448 // Don't count these checks as uses.
1449 Sym
->setUsed(false);
1451 Sym
= getContext().GetOrCreateSymbol(Name
);
1453 // FIXME: Handle '.'.
1455 // Do the assignment.
1456 Out
.EmitAssignment(Sym
, Value
);
1461 /// ParseIdentifier:
1464 bool AsmParser::ParseIdentifier(StringRef
&Res
) {
1465 // The assembler has relaxed rules for accepting identifiers, in particular we
1466 // allow things like '.globl $foo', which would normally be separate
1467 // tokens. At this level, we have already lexed so we cannot (currently)
1468 // handle this as a context dependent token, instead we detect adjacent tokens
1469 // and return the combined identifier.
1470 if (Lexer
.is(AsmToken::Dollar
)) {
1471 SMLoc DollarLoc
= getLexer().getLoc();
1473 // Consume the dollar sign, and check for a following identifier.
1475 if (Lexer
.isNot(AsmToken::Identifier
))
1478 // We have a '$' followed by an identifier, make sure they are adjacent.
1479 if (DollarLoc
.getPointer() + 1 != getTok().getLoc().getPointer())
1482 // Construct the joined identifier and consume the token.
1483 Res
= StringRef(DollarLoc
.getPointer(),
1484 getTok().getIdentifier().size() + 1);
1489 if (Lexer
.isNot(AsmToken::Identifier
) &&
1490 Lexer
.isNot(AsmToken::String
))
1493 Res
= getTok().getIdentifier();
1495 Lex(); // Consume the identifier token.
1500 /// ParseDirectiveSet:
1501 /// ::= .equ identifier ',' expression
1502 /// ::= .equiv identifier ',' expression
1503 /// ::= .set identifier ',' expression
1504 bool AsmParser::ParseDirectiveSet(StringRef IDVal
, bool allow_redef
) {
1507 if (ParseIdentifier(Name
))
1508 return TokError("expected identifier after '" + Twine(IDVal
) + "'");
1510 if (getLexer().isNot(AsmToken::Comma
))
1511 return TokError("unexpected token in '" + Twine(IDVal
) + "'");
1514 return ParseAssignment(Name
, allow_redef
);
1517 bool AsmParser::ParseEscapedString(std::string
&Data
) {
1518 assert(getLexer().is(AsmToken::String
) && "Unexpected current token!");
1521 StringRef Str
= getTok().getStringContents();
1522 for (unsigned i
= 0, e
= Str
.size(); i
!= e
; ++i
) {
1523 if (Str
[i
] != '\\') {
1528 // Recognize escaped characters. Note that this escape semantics currently
1529 // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1532 return TokError("unexpected backslash at end of string");
1534 // Recognize octal sequences.
1535 if ((unsigned) (Str
[i
] - '0') <= 7) {
1536 // Consume up to three octal characters.
1537 unsigned Value
= Str
[i
] - '0';
1539 if (i
+ 1 != e
&& ((unsigned) (Str
[i
+ 1] - '0')) <= 7) {
1541 Value
= Value
* 8 + (Str
[i
] - '0');
1543 if (i
+ 1 != e
&& ((unsigned) (Str
[i
+ 1] - '0')) <= 7) {
1545 Value
= Value
* 8 + (Str
[i
] - '0');
1550 return TokError("invalid octal escape sequence (out of range)");
1552 Data
+= (unsigned char) Value
;
1556 // Otherwise recognize individual escapes.
1559 // Just reject invalid escape sequences for now.
1560 return TokError("invalid escape sequence (unrecognized character)");
1562 case 'b': Data
+= '\b'; break;
1563 case 'f': Data
+= '\f'; break;
1564 case 'n': Data
+= '\n'; break;
1565 case 'r': Data
+= '\r'; break;
1566 case 't': Data
+= '\t'; break;
1567 case '"': Data
+= '"'; break;
1568 case '\\': Data
+= '\\'; break;
1575 /// ParseDirectiveAscii:
1576 /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
1577 bool AsmParser::ParseDirectiveAscii(StringRef IDVal
, bool ZeroTerminated
) {
1578 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1579 CheckForValidSection();
1582 if (getLexer().isNot(AsmToken::String
))
1583 return TokError("expected string in '" + Twine(IDVal
) + "' directive");
1586 if (ParseEscapedString(Data
))
1589 getStreamer().EmitBytes(Data
, DEFAULT_ADDRSPACE
);
1591 getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE
);
1595 if (getLexer().is(AsmToken::EndOfStatement
))
1598 if (getLexer().isNot(AsmToken::Comma
))
1599 return TokError("unexpected token in '" + Twine(IDVal
) + "' directive");
1608 /// ParseDirectiveValue
1609 /// ::= (.byte | .short | ... ) [ expression (, expression)* ]
1610 bool AsmParser::ParseDirectiveValue(unsigned Size
) {
1611 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1612 CheckForValidSection();
1615 const MCExpr
*Value
;
1616 SMLoc ExprLoc
= getLexer().getLoc();
1617 if (ParseExpression(Value
))
1620 // Special case constant expressions to match code generator.
1621 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Value
)) {
1622 assert(Size
<= 8 && "Invalid size");
1623 uint64_t IntValue
= MCE
->getValue();
1624 if (!isUIntN(8 * Size
, IntValue
) && !isIntN(8 * Size
, IntValue
))
1625 return Error(ExprLoc
, "literal value out of range for directive");
1626 getStreamer().EmitIntValue(IntValue
, Size
, DEFAULT_ADDRSPACE
);
1628 getStreamer().EmitValue(Value
, Size
, DEFAULT_ADDRSPACE
);
1630 if (getLexer().is(AsmToken::EndOfStatement
))
1633 // FIXME: Improve diagnostic.
1634 if (getLexer().isNot(AsmToken::Comma
))
1635 return TokError("unexpected token in directive");
1644 /// ParseDirectiveRealValue
1645 /// ::= (.single | .double) [ expression (, expression)* ]
1646 bool AsmParser::ParseDirectiveRealValue(const fltSemantics
&Semantics
) {
1647 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1648 CheckForValidSection();
1651 // We don't truly support arithmetic on floating point expressions, so we
1652 // have to manually parse unary prefixes.
1654 if (getLexer().is(AsmToken::Minus
)) {
1657 } else if (getLexer().is(AsmToken::Plus
))
1660 if (getLexer().isNot(AsmToken::Integer
) &&
1661 getLexer().isNot(AsmToken::Real
) &&
1662 getLexer().isNot(AsmToken::Identifier
))
1663 return TokError("unexpected token in directive");
1665 // Convert to an APFloat.
1666 APFloat
Value(Semantics
);
1667 StringRef IDVal
= getTok().getString();
1668 if (getLexer().is(AsmToken::Identifier
)) {
1669 if (!IDVal
.compare_lower("infinity") || !IDVal
.compare_lower("inf"))
1670 Value
= APFloat::getInf(Semantics
);
1671 else if (!IDVal
.compare_lower("nan"))
1672 Value
= APFloat::getNaN(Semantics
, false, ~0);
1674 return TokError("invalid floating point literal");
1675 } else if (Value
.convertFromString(IDVal
, APFloat::rmNearestTiesToEven
) ==
1676 APFloat::opInvalidOp
)
1677 return TokError("invalid floating point literal");
1681 // Consume the numeric token.
1684 // Emit the value as an integer.
1685 APInt AsInt
= Value
.bitcastToAPInt();
1686 getStreamer().EmitIntValue(AsInt
.getLimitedValue(),
1687 AsInt
.getBitWidth() / 8, DEFAULT_ADDRSPACE
);
1689 if (getLexer().is(AsmToken::EndOfStatement
))
1692 if (getLexer().isNot(AsmToken::Comma
))
1693 return TokError("unexpected token in directive");
1702 /// ParseDirectiveSpace
1703 /// ::= .space expression [ , expression ]
1704 bool AsmParser::ParseDirectiveSpace() {
1705 CheckForValidSection();
1708 if (ParseAbsoluteExpression(NumBytes
))
1711 int64_t FillExpr
= 0;
1712 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1713 if (getLexer().isNot(AsmToken::Comma
))
1714 return TokError("unexpected token in '.space' directive");
1717 if (ParseAbsoluteExpression(FillExpr
))
1720 if (getLexer().isNot(AsmToken::EndOfStatement
))
1721 return TokError("unexpected token in '.space' directive");
1727 return TokError("invalid number of bytes in '.space' directive");
1729 // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1730 getStreamer().EmitFill(NumBytes
, FillExpr
, DEFAULT_ADDRSPACE
);
1735 /// ParseDirectiveZero
1736 /// ::= .zero expression
1737 bool AsmParser::ParseDirectiveZero() {
1738 CheckForValidSection();
1741 if (ParseAbsoluteExpression(NumBytes
))
1745 if (getLexer().is(AsmToken::Comma
)) {
1747 if (ParseAbsoluteExpression(Val
))
1751 if (getLexer().isNot(AsmToken::EndOfStatement
))
1752 return TokError("unexpected token in '.zero' directive");
1756 getStreamer().EmitFill(NumBytes
, Val
, DEFAULT_ADDRSPACE
);
1761 /// ParseDirectiveFill
1762 /// ::= .fill expression , expression , expression
1763 bool AsmParser::ParseDirectiveFill() {
1764 CheckForValidSection();
1767 if (ParseAbsoluteExpression(NumValues
))
1770 if (getLexer().isNot(AsmToken::Comma
))
1771 return TokError("unexpected token in '.fill' directive");
1775 if (ParseAbsoluteExpression(FillSize
))
1778 if (getLexer().isNot(AsmToken::Comma
))
1779 return TokError("unexpected token in '.fill' directive");
1783 if (ParseAbsoluteExpression(FillExpr
))
1786 if (getLexer().isNot(AsmToken::EndOfStatement
))
1787 return TokError("unexpected token in '.fill' directive");
1791 if (FillSize
!= 1 && FillSize
!= 2 && FillSize
!= 4 && FillSize
!= 8)
1792 return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1794 for (uint64_t i
= 0, e
= NumValues
; i
!= e
; ++i
)
1795 getStreamer().EmitIntValue(FillExpr
, FillSize
, DEFAULT_ADDRSPACE
);
1800 /// ParseDirectiveOrg
1801 /// ::= .org expression [ , expression ]
1802 bool AsmParser::ParseDirectiveOrg() {
1803 CheckForValidSection();
1805 const MCExpr
*Offset
;
1806 if (ParseExpression(Offset
))
1809 // Parse optional fill expression.
1810 int64_t FillExpr
= 0;
1811 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1812 if (getLexer().isNot(AsmToken::Comma
))
1813 return TokError("unexpected token in '.org' directive");
1816 if (ParseAbsoluteExpression(FillExpr
))
1819 if (getLexer().isNot(AsmToken::EndOfStatement
))
1820 return TokError("unexpected token in '.org' directive");
1825 // FIXME: Only limited forms of relocatable expressions are accepted here, it
1826 // has to be relative to the current section.
1827 getStreamer().EmitValueToOffset(Offset
, FillExpr
);
1832 /// ParseDirectiveAlign
1833 /// ::= {.align, ...} expression [ , expression [ , expression ]]
1834 bool AsmParser::ParseDirectiveAlign(bool IsPow2
, unsigned ValueSize
) {
1835 CheckForValidSection();
1837 SMLoc AlignmentLoc
= getLexer().getLoc();
1839 if (ParseAbsoluteExpression(Alignment
))
1843 bool HasFillExpr
= false;
1844 int64_t FillExpr
= 0;
1845 int64_t MaxBytesToFill
= 0;
1846 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1847 if (getLexer().isNot(AsmToken::Comma
))
1848 return TokError("unexpected token in directive");
1851 // The fill expression can be omitted while specifying a maximum number of
1852 // alignment bytes, e.g:
1854 if (getLexer().isNot(AsmToken::Comma
)) {
1856 if (ParseAbsoluteExpression(FillExpr
))
1860 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1861 if (getLexer().isNot(AsmToken::Comma
))
1862 return TokError("unexpected token in directive");
1865 MaxBytesLoc
= getLexer().getLoc();
1866 if (ParseAbsoluteExpression(MaxBytesToFill
))
1869 if (getLexer().isNot(AsmToken::EndOfStatement
))
1870 return TokError("unexpected token in directive");
1879 // Compute alignment in bytes.
1881 // FIXME: Diagnose overflow.
1882 if (Alignment
>= 32) {
1883 Error(AlignmentLoc
, "invalid alignment value");
1887 Alignment
= 1ULL << Alignment
;
1890 // Diagnose non-sensical max bytes to align.
1891 if (MaxBytesLoc
.isValid()) {
1892 if (MaxBytesToFill
< 1) {
1893 Error(MaxBytesLoc
, "alignment directive can never be satisfied in this "
1894 "many bytes, ignoring maximum bytes expression");
1898 if (MaxBytesToFill
>= Alignment
) {
1899 Warning(MaxBytesLoc
, "maximum bytes expression exceeds alignment and "
1905 // Check whether we should use optimal code alignment for this .align
1907 bool UseCodeAlign
= getStreamer().getCurrentSection()->UseCodeAlign();
1908 if ((!HasFillExpr
|| Lexer
.getMAI().getTextAlignFillValue() == FillExpr
) &&
1909 ValueSize
== 1 && UseCodeAlign
) {
1910 getStreamer().EmitCodeAlignment(Alignment
, MaxBytesToFill
);
1912 // FIXME: Target specific behavior about how the "extra" bytes are filled.
1913 getStreamer().EmitValueToAlignment(Alignment
, FillExpr
, ValueSize
,
1920 /// ParseDirectiveSymbolAttribute
1921 /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1922 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr
) {
1923 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1927 if (ParseIdentifier(Name
))
1928 return TokError("expected identifier in directive");
1930 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
1932 getStreamer().EmitSymbolAttribute(Sym
, Attr
);
1934 if (getLexer().is(AsmToken::EndOfStatement
))
1937 if (getLexer().isNot(AsmToken::Comma
))
1938 return TokError("unexpected token in directive");
1947 /// ParseDirectiveComm
1948 /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1949 bool AsmParser::ParseDirectiveComm(bool IsLocal
) {
1950 CheckForValidSection();
1952 SMLoc IDLoc
= getLexer().getLoc();
1954 if (ParseIdentifier(Name
))
1955 return TokError("expected identifier in directive");
1957 // Handle the identifier as the key symbol.
1958 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
1960 if (getLexer().isNot(AsmToken::Comma
))
1961 return TokError("unexpected token in directive");
1965 SMLoc SizeLoc
= getLexer().getLoc();
1966 if (ParseAbsoluteExpression(Size
))
1969 int64_t Pow2Alignment
= 0;
1970 SMLoc Pow2AlignmentLoc
;
1971 if (getLexer().is(AsmToken::Comma
)) {
1973 Pow2AlignmentLoc
= getLexer().getLoc();
1974 if (ParseAbsoluteExpression(Pow2Alignment
))
1977 // If this target takes alignments in bytes (not log) validate and convert.
1978 if (Lexer
.getMAI().getAlignmentIsInBytes()) {
1979 if (!isPowerOf2_64(Pow2Alignment
))
1980 return Error(Pow2AlignmentLoc
, "alignment must be a power of 2");
1981 Pow2Alignment
= Log2_64(Pow2Alignment
);
1985 if (getLexer().isNot(AsmToken::EndOfStatement
))
1986 return TokError("unexpected token in '.comm' or '.lcomm' directive");
1990 // NOTE: a size of zero for a .comm should create a undefined symbol
1991 // but a size of .lcomm creates a bss symbol of size zero.
1993 return Error(SizeLoc
, "invalid '.comm' or '.lcomm' directive size, can't "
1994 "be less than zero");
1996 // NOTE: The alignment in the directive is a power of 2 value, the assembler
1997 // may internally end up wanting an alignment in bytes.
1998 // FIXME: Diagnose overflow.
1999 if (Pow2Alignment
< 0)
2000 return Error(Pow2AlignmentLoc
, "invalid '.comm' or '.lcomm' directive "
2001 "alignment, can't be less than zero");
2003 if (!Sym
->isUndefined())
2004 return Error(IDLoc
, "invalid symbol redefinition");
2006 // '.lcomm' is equivalent to '.zerofill'.
2007 // Create the Symbol as a common or local common with Size and Pow2Alignment
2009 getStreamer().EmitZerofill(Ctx
.getMachOSection(
2010 "__DATA", "__bss", MCSectionMachO::S_ZEROFILL
,
2011 0, SectionKind::getBSS()),
2012 Sym
, Size
, 1 << Pow2Alignment
);
2016 getStreamer().EmitCommonSymbol(Sym
, Size
, 1 << Pow2Alignment
);
2020 /// ParseDirectiveAbort
2021 /// ::= .abort [... message ...]
2022 bool AsmParser::ParseDirectiveAbort() {
2023 // FIXME: Use loc from directive.
2024 SMLoc Loc
= getLexer().getLoc();
2026 StringRef Str
= ParseStringToEndOfStatement();
2027 if (getLexer().isNot(AsmToken::EndOfStatement
))
2028 return TokError("unexpected token in '.abort' directive");
2033 Error(Loc
, ".abort detected. Assembly stopping.");
2035 Error(Loc
, ".abort '" + Str
+ "' detected. Assembly stopping.");
2036 // FIXME: Actually abort assembly here.
2041 /// ParseDirectiveInclude
2042 /// ::= .include "filename"
2043 bool AsmParser::ParseDirectiveInclude() {
2044 if (getLexer().isNot(AsmToken::String
))
2045 return TokError("expected string in '.include' directive");
2047 std::string Filename
= getTok().getString();
2048 SMLoc IncludeLoc
= getLexer().getLoc();
2051 if (getLexer().isNot(AsmToken::EndOfStatement
))
2052 return TokError("unexpected token in '.include' directive");
2054 // Strip the quotes.
2055 Filename
= Filename
.substr(1, Filename
.size()-2);
2057 // Attempt to switch the lexer to the included file before consuming the end
2058 // of statement to avoid losing it when we switch.
2059 if (EnterIncludeFile(Filename
)) {
2060 Error(IncludeLoc
, "Could not find include file '" + Filename
+ "'");
2067 /// ParseDirectiveIf
2068 /// ::= .if expression
2069 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc
) {
2070 TheCondStack
.push_back(TheCondState
);
2071 TheCondState
.TheCond
= AsmCond::IfCond
;
2072 if(TheCondState
.Ignore
) {
2073 EatToEndOfStatement();
2077 if (ParseAbsoluteExpression(ExprValue
))
2080 if (getLexer().isNot(AsmToken::EndOfStatement
))
2081 return TokError("unexpected token in '.if' directive");
2085 TheCondState
.CondMet
= ExprValue
;
2086 TheCondState
.Ignore
= !TheCondState
.CondMet
;
2092 bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc
, bool expect_defined
) {
2094 TheCondStack
.push_back(TheCondState
);
2095 TheCondState
.TheCond
= AsmCond::IfCond
;
2097 if (TheCondState
.Ignore
) {
2098 EatToEndOfStatement();
2100 if (ParseIdentifier(Name
))
2101 return TokError("expected identifier after '.ifdef'");
2105 MCSymbol
*Sym
= getContext().LookupSymbol(Name
);
2108 TheCondState
.CondMet
= (Sym
!= NULL
&& !Sym
->isUndefined());
2110 TheCondState
.CondMet
= (Sym
== NULL
|| Sym
->isUndefined());
2111 TheCondState
.Ignore
= !TheCondState
.CondMet
;
2117 /// ParseDirectiveElseIf
2118 /// ::= .elseif expression
2119 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc
) {
2120 if (TheCondState
.TheCond
!= AsmCond::IfCond
&&
2121 TheCondState
.TheCond
!= AsmCond::ElseIfCond
)
2122 Error(DirectiveLoc
, "Encountered a .elseif that doesn't follow a .if or "
2124 TheCondState
.TheCond
= AsmCond::ElseIfCond
;
2126 bool LastIgnoreState
= false;
2127 if (!TheCondStack
.empty())
2128 LastIgnoreState
= TheCondStack
.back().Ignore
;
2129 if (LastIgnoreState
|| TheCondState
.CondMet
) {
2130 TheCondState
.Ignore
= true;
2131 EatToEndOfStatement();
2135 if (ParseAbsoluteExpression(ExprValue
))
2138 if (getLexer().isNot(AsmToken::EndOfStatement
))
2139 return TokError("unexpected token in '.elseif' directive");
2142 TheCondState
.CondMet
= ExprValue
;
2143 TheCondState
.Ignore
= !TheCondState
.CondMet
;
2149 /// ParseDirectiveElse
2151 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc
) {
2152 if (getLexer().isNot(AsmToken::EndOfStatement
))
2153 return TokError("unexpected token in '.else' directive");
2157 if (TheCondState
.TheCond
!= AsmCond::IfCond
&&
2158 TheCondState
.TheCond
!= AsmCond::ElseIfCond
)
2159 Error(DirectiveLoc
, "Encountered a .else that doesn't follow a .if or an "
2161 TheCondState
.TheCond
= AsmCond::ElseCond
;
2162 bool LastIgnoreState
= false;
2163 if (!TheCondStack
.empty())
2164 LastIgnoreState
= TheCondStack
.back().Ignore
;
2165 if (LastIgnoreState
|| TheCondState
.CondMet
)
2166 TheCondState
.Ignore
= true;
2168 TheCondState
.Ignore
= false;
2173 /// ParseDirectiveEndIf
2175 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc
) {
2176 if (getLexer().isNot(AsmToken::EndOfStatement
))
2177 return TokError("unexpected token in '.endif' directive");
2181 if ((TheCondState
.TheCond
== AsmCond::NoCond
) ||
2182 TheCondStack
.empty())
2183 Error(DirectiveLoc
, "Encountered a .endif that doesn't follow a .if or "
2185 if (!TheCondStack
.empty()) {
2186 TheCondState
= TheCondStack
.back();
2187 TheCondStack
.pop_back();
2193 /// ParseDirectiveFile
2194 /// ::= .file [number] string
2195 bool GenericAsmParser::ParseDirectiveFile(StringRef
, SMLoc DirectiveLoc
) {
2196 // FIXME: I'm not sure what this is.
2197 int64_t FileNumber
= -1;
2198 SMLoc FileNumberLoc
= getLexer().getLoc();
2199 if (getLexer().is(AsmToken::Integer
)) {
2200 FileNumber
= getTok().getIntVal();
2204 return TokError("file number less than one");
2207 if (getLexer().isNot(AsmToken::String
))
2208 return TokError("unexpected token in '.file' directive");
2210 StringRef Filename
= getTok().getString();
2211 Filename
= Filename
.substr(1, Filename
.size()-2);
2214 if (getLexer().isNot(AsmToken::EndOfStatement
))
2215 return TokError("unexpected token in '.file' directive");
2217 if (FileNumber
== -1)
2218 getStreamer().EmitFileDirective(Filename
);
2220 if (getStreamer().EmitDwarfFileDirective(FileNumber
, Filename
))
2221 Error(FileNumberLoc
, "file number already allocated");
2227 /// ParseDirectiveLine
2228 /// ::= .line [number]
2229 bool GenericAsmParser::ParseDirectiveLine(StringRef
, SMLoc DirectiveLoc
) {
2230 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
2231 if (getLexer().isNot(AsmToken::Integer
))
2232 return TokError("unexpected token in '.line' directive");
2234 int64_t LineNumber
= getTok().getIntVal();
2238 // FIXME: Do something with the .line.
2241 if (getLexer().isNot(AsmToken::EndOfStatement
))
2242 return TokError("unexpected token in '.line' directive");
2248 /// ParseDirectiveLoc
2249 /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
2250 /// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
2251 /// The first number is a file number, must have been previously assigned with
2252 /// a .file directive, the second number is the line number and optionally the
2253 /// third number is a column position (zero if not specified). The remaining
2254 /// optional items are .loc sub-directives.
2255 bool GenericAsmParser::ParseDirectiveLoc(StringRef
, SMLoc DirectiveLoc
) {
2257 if (getLexer().isNot(AsmToken::Integer
))
2258 return TokError("unexpected token in '.loc' directive");
2259 int64_t FileNumber
= getTok().getIntVal();
2261 return TokError("file number less than one in '.loc' directive");
2262 if (!getContext().isValidDwarfFileNumber(FileNumber
))
2263 return TokError("unassigned file number in '.loc' directive");
2266 int64_t LineNumber
= 0;
2267 if (getLexer().is(AsmToken::Integer
)) {
2268 LineNumber
= getTok().getIntVal();
2270 return TokError("line number less than one in '.loc' directive");
2274 int64_t ColumnPos
= 0;
2275 if (getLexer().is(AsmToken::Integer
)) {
2276 ColumnPos
= getTok().getIntVal();
2278 return TokError("column position less than zero in '.loc' directive");
2282 unsigned Flags
= DWARF2_LINE_DEFAULT_IS_STMT
? DWARF2_FLAG_IS_STMT
: 0;
2284 int64_t Discriminator
= 0;
2285 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
2287 if (getLexer().is(AsmToken::EndOfStatement
))
2291 SMLoc Loc
= getTok().getLoc();
2292 if (getParser().ParseIdentifier(Name
))
2293 return TokError("unexpected token in '.loc' directive");
2295 if (Name
== "basic_block")
2296 Flags
|= DWARF2_FLAG_BASIC_BLOCK
;
2297 else if (Name
== "prologue_end")
2298 Flags
|= DWARF2_FLAG_PROLOGUE_END
;
2299 else if (Name
== "epilogue_begin")
2300 Flags
|= DWARF2_FLAG_EPILOGUE_BEGIN
;
2301 else if (Name
== "is_stmt") {
2302 SMLoc Loc
= getTok().getLoc();
2303 const MCExpr
*Value
;
2304 if (getParser().ParseExpression(Value
))
2306 // The expression must be the constant 0 or 1.
2307 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Value
)) {
2308 int Value
= MCE
->getValue();
2310 Flags
&= ~DWARF2_FLAG_IS_STMT
;
2311 else if (Value
== 1)
2312 Flags
|= DWARF2_FLAG_IS_STMT
;
2314 return Error(Loc
, "is_stmt value not 0 or 1");
2317 return Error(Loc
, "is_stmt value not the constant value of 0 or 1");
2320 else if (Name
== "isa") {
2321 SMLoc Loc
= getTok().getLoc();
2322 const MCExpr
*Value
;
2323 if (getParser().ParseExpression(Value
))
2325 // The expression must be a constant greater or equal to 0.
2326 if (const MCConstantExpr
*MCE
= dyn_cast
<MCConstantExpr
>(Value
)) {
2327 int Value
= MCE
->getValue();
2329 return Error(Loc
, "isa number less than zero");
2333 return Error(Loc
, "isa number not a constant value");
2336 else if (Name
== "discriminator") {
2337 if (getParser().ParseAbsoluteExpression(Discriminator
))
2341 return Error(Loc
, "unknown sub-directive in '.loc' directive");
2344 if (getLexer().is(AsmToken::EndOfStatement
))
2349 getStreamer().EmitDwarfLocDirective(FileNumber
, LineNumber
, ColumnPos
, Flags
,
2350 Isa
, Discriminator
, StringRef());
2355 /// ParseDirectiveStabs
2356 /// ::= .stabs string, number, number, number
2357 bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive
,
2358 SMLoc DirectiveLoc
) {
2359 return TokError("unsupported directive '" + Directive
+ "'");
2362 /// ParseDirectiveCFISections
2363 /// ::= .cfi_sections section [, section]
2364 bool GenericAsmParser::ParseDirectiveCFISections(StringRef
,
2365 SMLoc DirectiveLoc
) {
2370 if (getParser().ParseIdentifier(Name
))
2371 return TokError("Expected an identifier");
2373 if (Name
== ".eh_frame")
2375 else if (Name
== ".debug_frame")
2378 if (getLexer().is(AsmToken::Comma
)) {
2381 if (getParser().ParseIdentifier(Name
))
2382 return TokError("Expected an identifier");
2384 if (Name
== ".eh_frame")
2386 else if (Name
== ".debug_frame")
2390 getStreamer().EmitCFISections(EH
, Debug
);
2395 /// ParseDirectiveCFIStartProc
2396 /// ::= .cfi_startproc
2397 bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef
,
2398 SMLoc DirectiveLoc
) {
2399 getStreamer().EmitCFIStartProc();
2403 /// ParseDirectiveCFIEndProc
2404 /// ::= .cfi_endproc
2405 bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef
, SMLoc DirectiveLoc
) {
2406 getStreamer().EmitCFIEndProc();
2410 /// ParseRegisterOrRegisterNumber - parse register name or number.
2411 bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register
,
2412 SMLoc DirectiveLoc
) {
2415 if (getLexer().isNot(AsmToken::Integer
)) {
2416 if (getParser().getTargetParser().ParseRegister(RegNo
, DirectiveLoc
,
2419 Register
= getContext().getTargetAsmInfo().getDwarfRegNum(RegNo
, true);
2421 return getParser().ParseAbsoluteExpression(Register
);
2426 /// ParseDirectiveCFIDefCfa
2427 /// ::= .cfi_def_cfa register, offset
2428 bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef
,
2429 SMLoc DirectiveLoc
) {
2430 int64_t Register
= 0;
2431 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2434 if (getLexer().isNot(AsmToken::Comma
))
2435 return TokError("unexpected token in directive");
2439 if (getParser().ParseAbsoluteExpression(Offset
))
2442 getStreamer().EmitCFIDefCfa(Register
, Offset
);
2446 /// ParseDirectiveCFIDefCfaOffset
2447 /// ::= .cfi_def_cfa_offset offset
2448 bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef
,
2449 SMLoc DirectiveLoc
) {
2451 if (getParser().ParseAbsoluteExpression(Offset
))
2454 getStreamer().EmitCFIDefCfaOffset(Offset
);
2458 /// ParseDirectiveCFIAdjustCfaOffset
2459 /// ::= .cfi_adjust_cfa_offset adjustment
2460 bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef
,
2461 SMLoc DirectiveLoc
) {
2462 int64_t Adjustment
= 0;
2463 if (getParser().ParseAbsoluteExpression(Adjustment
))
2466 getStreamer().EmitCFIAdjustCfaOffset(Adjustment
);
2470 /// ParseDirectiveCFIDefCfaRegister
2471 /// ::= .cfi_def_cfa_register register
2472 bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef
,
2473 SMLoc DirectiveLoc
) {
2474 int64_t Register
= 0;
2475 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2478 getStreamer().EmitCFIDefCfaRegister(Register
);
2482 /// ParseDirectiveCFIOffset
2483 /// ::= .cfi_offset register, offset
2484 bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef
, SMLoc DirectiveLoc
) {
2485 int64_t Register
= 0;
2488 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2491 if (getLexer().isNot(AsmToken::Comma
))
2492 return TokError("unexpected token in directive");
2495 if (getParser().ParseAbsoluteExpression(Offset
))
2498 getStreamer().EmitCFIOffset(Register
, Offset
);
2502 /// ParseDirectiveCFIRelOffset
2503 /// ::= .cfi_rel_offset register, offset
2504 bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef
,
2505 SMLoc DirectiveLoc
) {
2506 int64_t Register
= 0;
2508 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2511 if (getLexer().isNot(AsmToken::Comma
))
2512 return TokError("unexpected token in directive");
2516 if (getParser().ParseAbsoluteExpression(Offset
))
2519 getStreamer().EmitCFIRelOffset(Register
, Offset
);
2523 static bool isValidEncoding(int64_t Encoding
) {
2524 if (Encoding
& ~0xff)
2527 if (Encoding
== dwarf::DW_EH_PE_omit
)
2530 const unsigned Format
= Encoding
& 0xf;
2531 if (Format
!= dwarf::DW_EH_PE_absptr
&& Format
!= dwarf::DW_EH_PE_udata2
&&
2532 Format
!= dwarf::DW_EH_PE_udata4
&& Format
!= dwarf::DW_EH_PE_udata8
&&
2533 Format
!= dwarf::DW_EH_PE_sdata2
&& Format
!= dwarf::DW_EH_PE_sdata4
&&
2534 Format
!= dwarf::DW_EH_PE_sdata8
&& Format
!= dwarf::DW_EH_PE_signed
)
2537 const unsigned Application
= Encoding
& 0x70;
2538 if (Application
!= dwarf::DW_EH_PE_absptr
&&
2539 Application
!= dwarf::DW_EH_PE_pcrel
)
2545 /// ParseDirectiveCFIPersonalityOrLsda
2546 /// ::= .cfi_personality encoding, [symbol_name]
2547 /// ::= .cfi_lsda encoding, [symbol_name]
2548 bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal
,
2549 SMLoc DirectiveLoc
) {
2550 int64_t Encoding
= 0;
2551 if (getParser().ParseAbsoluteExpression(Encoding
))
2553 if (Encoding
== dwarf::DW_EH_PE_omit
)
2556 if (!isValidEncoding(Encoding
))
2557 return TokError("unsupported encoding.");
2559 if (getLexer().isNot(AsmToken::Comma
))
2560 return TokError("unexpected token in directive");
2564 if (getParser().ParseIdentifier(Name
))
2565 return TokError("expected identifier in directive");
2567 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
2569 if (IDVal
== ".cfi_personality")
2570 getStreamer().EmitCFIPersonality(Sym
, Encoding
);
2572 assert(IDVal
== ".cfi_lsda");
2573 getStreamer().EmitCFILsda(Sym
, Encoding
);
2578 /// ParseDirectiveCFIRememberState
2579 /// ::= .cfi_remember_state
2580 bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal
,
2581 SMLoc DirectiveLoc
) {
2582 getStreamer().EmitCFIRememberState();
2586 /// ParseDirectiveCFIRestoreState
2587 /// ::= .cfi_remember_state
2588 bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal
,
2589 SMLoc DirectiveLoc
) {
2590 getStreamer().EmitCFIRestoreState();
2594 /// ParseDirectiveCFISameValue
2595 /// ::= .cfi_same_value register
2596 bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal
,
2597 SMLoc DirectiveLoc
) {
2598 int64_t Register
= 0;
2600 if (ParseRegisterOrRegisterNumber(Register
, DirectiveLoc
))
2603 getStreamer().EmitCFISameValue(Register
);
2608 /// ParseDirectiveMacrosOnOff
2611 bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive
,
2612 SMLoc DirectiveLoc
) {
2613 if (getLexer().isNot(AsmToken::EndOfStatement
))
2614 return Error(getLexer().getLoc(),
2615 "unexpected token in '" + Directive
+ "' directive");
2617 getParser().MacrosEnabled
= Directive
== ".macros_on";
2622 /// ParseDirectiveMacro
2623 /// ::= .macro name [parameters]
2624 bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive
,
2625 SMLoc DirectiveLoc
) {
2627 if (getParser().ParseIdentifier(Name
))
2628 return TokError("expected identifier in directive");
2630 std::vector
<StringRef
> Parameters
;
2631 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
2633 StringRef Parameter
;
2634 if (getParser().ParseIdentifier(Parameter
))
2635 return TokError("expected identifier in directive");
2636 Parameters
.push_back(Parameter
);
2638 if (getLexer().isNot(AsmToken::Comma
))
2644 if (getLexer().isNot(AsmToken::EndOfStatement
))
2645 return TokError("unexpected token in '.macro' directive");
2647 // Eat the end of statement.
2650 AsmToken EndToken
, StartToken
= getTok();
2652 // Lex the macro definition.
2654 // Check whether we have reached the end of the file.
2655 if (getLexer().is(AsmToken::Eof
))
2656 return Error(DirectiveLoc
, "no matching '.endmacro' in definition");
2658 // Otherwise, check whether we have reach the .endmacro.
2659 if (getLexer().is(AsmToken::Identifier
) &&
2660 (getTok().getIdentifier() == ".endm" ||
2661 getTok().getIdentifier() == ".endmacro")) {
2662 EndToken
= getTok();
2664 if (getLexer().isNot(AsmToken::EndOfStatement
))
2665 return TokError("unexpected token in '" + EndToken
.getIdentifier() +
2670 // Otherwise, scan til the end of the statement.
2671 getParser().EatToEndOfStatement();
2674 if (getParser().MacroMap
.lookup(Name
)) {
2675 return Error(DirectiveLoc
, "macro '" + Name
+ "' is already defined");
2678 const char *BodyStart
= StartToken
.getLoc().getPointer();
2679 const char *BodyEnd
= EndToken
.getLoc().getPointer();
2680 StringRef Body
= StringRef(BodyStart
, BodyEnd
- BodyStart
);
2681 getParser().MacroMap
[Name
] = new Macro(Name
, Body
, Parameters
);
2685 /// ParseDirectiveEndMacro
2688 bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive
,
2689 SMLoc DirectiveLoc
) {
2690 if (getLexer().isNot(AsmToken::EndOfStatement
))
2691 return TokError("unexpected token in '" + Directive
+ "' directive");
2693 // If we are inside a macro instantiation, terminate the current
2695 if (!getParser().ActiveMacros
.empty()) {
2696 getParser().HandleMacroExit();
2700 // Otherwise, this .endmacro is a stray entry in the file; well formed
2701 // .endmacro directives are handled during the macro definition parsing.
2702 return TokError("unexpected '" + Directive
+ "' in file, "
2703 "no current macro definition");
2706 bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName
, SMLoc
) {
2707 getParser().CheckForValidSection();
2709 const MCExpr
*Value
;
2711 if (getParser().ParseExpression(Value
))
2714 if (getLexer().isNot(AsmToken::EndOfStatement
))
2715 return TokError("unexpected token in directive");
2717 if (DirName
[1] == 's')
2718 getStreamer().EmitSLEB128Value(Value
);
2720 getStreamer().EmitULEB128Value(Value
);
2726 /// \brief Create an MCAsmParser instance.
2727 MCAsmParser
*llvm::createMCAsmParser(const Target
&T
, SourceMgr
&SM
,
2728 MCContext
&C
, MCStreamer
&Out
,
2729 const MCAsmInfo
&MAI
) {
2730 return new AsmParser(T
, SM
, C
, Out
, MAI
);