summaryrefslogtreecommitdiffstats
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp5
-rw-r--r--lib/MC/MCParser/AsmParser.cpp211
2 files changed, 82 insertions, 134 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index 22c8d76..1183312 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -74,6 +74,11 @@ AsmToken AsmLexer::LexIdentifier() {
while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' ||
*CurPtr == '.' || *CurPtr == '@')
++CurPtr;
+
+ // Handle . as a special case.
+ if (CurPtr == TokStart+1 && TokStart[0] == '.')
+ return AsmToken(AsmToken::Dot, StringRef(TokStart, 1));
+
return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 4e62689..a63d2e4 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -30,16 +30,10 @@ using namespace llvm;
enum { DEFAULT_ADDRSPACE = 0 };
-// Mach-O section uniquing.
-//
-// FIXME: Figure out where this should live, it should be shared by
-// TargetLoweringObjectFile.
-typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
-
AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
const MCAsmInfo &_MAI)
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), TargetParser(0),
- CurBuffer(0), SectionUniquingMap(0) {
+ CurBuffer(0) {
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
// Debugging directives.
@@ -51,39 +45,6 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
AsmParser::~AsmParser() {
- // If we have the MachO uniquing map, free it.
- delete (MachOUniqueMapTy*)SectionUniquingMap;
-}
-
-const MCSection *AsmParser::getMachOSection(const StringRef &Segment,
- const StringRef &Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind Kind) const {
- // We unique sections by their segment/section pair. The returned section
- // may not have the same flags as the requested section, if so this should be
- // diagnosed by the client as an error.
-
- // Create the map if it doesn't already exist.
- if (SectionUniquingMap == 0)
- SectionUniquingMap = new MachOUniqueMapTy();
- MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)SectionUniquingMap;
-
- // Form the name to look up.
- SmallString<64> Name;
- Name += Segment;
- Name.push_back(',');
- Name += Section;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionMachO *&Entry = Map[Name.str()];
-
- // FIXME: This should validate the type and attributes.
- if (Entry) return Entry;
-
- // Otherwise, return a new section.
- return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
- Reserved2, Kind, Ctx);
}
void AsmParser::Warning(SMLoc L, const Twine &Msg) {
@@ -143,7 +104,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
//
// FIXME: Target hook & command line option for initial section.
if (!NoInitialTextSection)
- Out.SwitchSection(getMachOSection("__TEXT", "__text",
+ Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
0, SectionKind::getText()));
@@ -156,29 +117,6 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
- // Handle conditional assembly here before calling ParseStatement()
- if (Lexer.getKind() == AsmToken::Identifier) {
- // If we have an identifier, handle it as the key symbol.
- AsmToken ID = getTok();
- SMLoc IDLoc = ID.getLoc();
- StringRef IDVal = ID.getString();
-
- if (IDVal == ".if" ||
- IDVal == ".elseif" ||
- IDVal == ".else" ||
- IDVal == ".endif") {
- if (!ParseConditionalAssemblyDirectives(IDVal, IDLoc))
- continue;
- HadError = true;
- EatToEndOfStatement();
- continue;
- }
- }
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- continue;
- }
-
if (!ParseStatement()) continue;
// We had an error, remember it and recover by skipping to the next line.
@@ -198,21 +136,6 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
return HadError;
}
-/// ParseConditionalAssemblyDirectives - parse the conditional assembly
-/// directives
-bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive,
- SMLoc DirectiveLoc) {
- if (Directive == ".if")
- return ParseDirectiveIf(DirectiveLoc);
- if (Directive == ".elseif")
- return ParseDirectiveElseIf(DirectiveLoc);
- if (Directive == ".else")
- return ParseDirectiveElse(DirectiveLoc);
- if (Directive == ".endif")
- return ParseDirectiveEndIf(DirectiveLoc);
- return true;
-}
-
/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
void AsmParser::EatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
@@ -248,6 +171,7 @@ MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
/// primaryexpr ::= (parenexpr
/// primaryexpr ::= symbol
/// primaryexpr ::= number
+/// primaryexpr ::= '.'
/// primaryexpr ::= ~,+,- primaryexpr
bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
switch (Lexer.getKind()) {
@@ -292,6 +216,17 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
EndLoc = Lexer.getLoc();
Lex(); // Eat token.
return false;
+ case AsmToken::Dot: {
+ // This is a '.' reference, which references the current PC. Emit a
+ // temporary label to the streamer and refer to it.
+ MCSymbol *Sym = Ctx.CreateTempSymbol();
+ Out.EmitLabel(Sym);
+ Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
+ EndLoc = Lexer.getLoc();
+ Lex(); // Eat identifier.
+ return false;
+ }
+
case AsmToken::LParen:
Lex(); // Eat the '('.
return ParseParenExpr(Res, EndLoc);
@@ -484,9 +419,30 @@ bool AsmParser::ParseStatement() {
AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
- if (ParseIdentifier(IDVal))
- return TokError("unexpected token at start of statement");
+ if (ParseIdentifier(IDVal)) {
+ if (!TheCondState.Ignore)
+ return TokError("unexpected token at start of statement");
+ IDVal = "";
+ }
+ // Handle conditional assembly here before checking for skipping. We
+ // have to do this so that .endif isn't skipped in a ".if 0" block for
+ // example.
+ if (IDVal == ".if")
+ return ParseDirectiveIf(IDLoc);
+ if (IDVal == ".elseif")
+ return ParseDirectiveElseIf(IDLoc);
+ if (IDVal == ".else")
+ return ParseDirectiveElse(IDLoc);
+ if (IDVal == ".endif")
+ return ParseDirectiveEndIf(IDLoc);
+
+ // If we are in a ".if 0" block, ignore this statement.
+ if (TheCondState.Ignore) {
+ EatToEndOfStatement();
+ return false;
+ }
+
// FIXME: Recurse on local labels?
// See what kind of statement we have.
@@ -773,39 +729,38 @@ bool AsmParser::ParseStatement() {
return false;
}
-
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
- if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands))
- // FIXME: Leaking ParsedOperands on failure.
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- // FIXME: Leaking ParsedOperands on failure.
- return TokError("unexpected token in argument list");
-
- // Eat the end of statement marker.
- Lex();
-
-
- MCInst Inst;
+ bool HadError = getTargetParser().ParseInstruction(IDVal, IDLoc,
+ ParsedOperands);
+ if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
+ HadError = TokError("unexpected token in argument list");
+
+ // If parsing succeeded, match the instruction.
+ if (!HadError) {
+ MCInst Inst;
+ if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
+ // Emit the instruction on success.
+ Out.EmitInstruction(Inst);
+ } else {
+ // Otherwise emit a diagnostic about the match failure and set the error
+ // flag.
+ //
+ // FIXME: We should give nicer diagnostics about the exact failure.
+ Error(IDLoc, "unrecognized instruction");
+ HadError = true;
+ }
+ }
- bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst);
+ // If there was no error, consume the end-of-statement token. Otherwise this
+ // will be done by our caller.
+ if (!HadError)
+ Lex();
// Free any parsed operands.
for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
delete ParsedOperands[i];
- if (MatchFail) {
- // FIXME: We should give nicer diagnostics about the exact failure.
- Error(IDLoc, "unrecognized instruction");
- return true;
- }
-
- // Instruction is good, process it.
- Out.EmitInstruction(Inst);
-
- // Skip to end of line for now.
- return false;
+ return HadError;
}
bool AsmParser::ParseAssignment(const StringRef &Name) {
@@ -919,9 +874,9 @@ bool AsmParser::ParseDirectiveDarwinSection() {
// FIXME: Arch specific.
bool isText = Segment == "__TEXT"; // FIXME: Hack.
- Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
- isText ? SectionKind::getText()
- : SectionKind::getDataRel()));
+ Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
+ isText ? SectionKind::getText()
+ : SectionKind::getDataRel()));
return false;
}
@@ -936,9 +891,9 @@ bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
// FIXME: Arch specific.
bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
- Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
- isText ? SectionKind::getText()
- : SectionKind::getDataRel()));
+ Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
+ isText ? SectionKind::getText()
+ : SectionKind::getDataRel()));
// Set the implicit alignment, if any.
//
@@ -1374,9 +1329,9 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
// '.lcomm' is equivalent to '.zerofill'.
// Create the Symbol as a common or local common with Size and Pow2Alignment
if (IsLocal) {
- Out.EmitZerofill(getMachOSection("__DATA", "__bss",
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind::getBSS()),
+ Out.EmitZerofill(Ctx.getMachOSection("__DATA", "__bss",
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind::getBSS()),
Sym, Size, 1 << Pow2Alignment);
return false;
}
@@ -1410,9 +1365,9 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
// the section but with no symbol.
if (Lexer.is(AsmToken::EndOfStatement)) {
// Create the zerofill section but no symbol
- Out.EmitZerofill(getMachOSection(Segment, Section,
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind::getBSS()));
+ Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind::getBSS()));
return false;
}
@@ -1468,9 +1423,9 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
// Create the zerofill Symbol with Size and Pow2Alignment
//
// FIXME: Arch specific.
- Out.EmitZerofill(getMachOSection(Segment, Section,
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind::getBSS()),
+ Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind::getBSS()),
Sym, Size, 1 << Pow2Alignment);
return false;
@@ -1604,9 +1559,6 @@ bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
/// ParseDirectiveIf
/// ::= .if expression
bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
- // Consume the identifier that was the .if directive
- Lex();
-
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
if(TheCondState.Ignore) {
@@ -1638,9 +1590,6 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
" an .elseif");
TheCondState.TheCond = AsmCond::ElseIfCond;
- // Consume the identifier that was the .elseif directive
- Lex();
-
bool LastIgnoreState = false;
if (!TheCondStack.empty())
LastIgnoreState = TheCondStack.back().Ignore;
@@ -1667,9 +1616,6 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
/// ParseDirectiveElse
/// ::= .else
bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
- // Consume the identifier that was the .else directive
- Lex();
-
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.else' directive");
@@ -1694,9 +1640,6 @@ bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
/// ParseDirectiveEndIf
/// ::= .endif
bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
- // Consume the identifier that was the .endif directive
- Lex();
-
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.endif' directive");
OpenPOWER on IntegriCloud