summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp107
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp6
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp53
3 files changed, 95 insertions, 71 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 804734cea9396..edefdb4c36435 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -201,9 +201,9 @@ public:
}
virtual bool Warning(SMLoc L, const Twine &Msg,
- ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
+ ArrayRef<SMRange> Ranges = None);
virtual bool Error(SMLoc L, const Twine &Msg,
- ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
+ ArrayRef<SMRange> Ranges = None);
virtual const AsmToken &Lex();
@@ -221,6 +221,7 @@ public:
bool parseExpression(const MCExpr *&Res);
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool parseAbsoluteExpression(int64_t &Res);
@@ -285,7 +286,7 @@ private:
void PrintMacroInstantiations();
void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
- ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const {
+ ArrayRef<SMRange> Ranges = None) const {
SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
@@ -601,7 +602,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// If we are generating dwarf for assembly source files save the initial text
// section and generate a .file directive.
if (getContext().getGenDwarfForAssembly()) {
- getContext().setGenDwarfSection(getStreamer().getCurrentSection());
+ getContext().setGenDwarfSection(getStreamer().getCurrentSection().first);
MCSymbol *SectionStartSym = getContext().CreateTempSymbol();
getStreamer().EmitLabel(SectionStartSym);
getContext().setGenDwarfSectionStartSym(SectionStartSym);
@@ -666,7 +667,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
}
void AsmParser::checkForValidSection() {
- if (!ParsingInlineAsm && !getStreamer().getCurrentSection()) {
+ if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) {
TokError("expected section directive before assembly directive");
Out.InitToTextSection();
}
@@ -869,6 +870,10 @@ bool AsmParser::parseExpression(const MCExpr *&Res) {
return parseExpression(Res, EndLoc);
}
+bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ return ParsePrimaryExpr(Res, EndLoc);
+}
+
const MCExpr *
AsmParser::ApplyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant) {
@@ -1087,7 +1092,7 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
MCBinaryExpr::Opcode Dummy;
unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
if (TokPrec < NextTokPrec) {
- if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
+ if (ParseBinOpRHS(TokPrec+1, RHS, EndLoc)) return true;
}
// Merge LHS and RHS according to operator.
@@ -1488,7 +1493,8 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// section is the initial text section then generate a .loc directive for
// the instruction.
if (!HadError && getContext().getGenDwarfForAssembly() &&
- getContext().getGenDwarfSection() == getStreamer().getCurrentSection()) {
+ getContext().getGenDwarfSection() ==
+ getStreamer().getCurrentSection().first) {
unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
@@ -1978,7 +1984,6 @@ static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
case MCExpr::Binary: {
const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value);
return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS());
- break;
}
case MCExpr::Target:
case MCExpr::Constant:
@@ -2479,7 +2484,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
// Check whether we should use optimal code alignment for this .align
// directive.
- bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign();
+ bool UseCodeAlign = getStreamer().getCurrentSection().first->UseCodeAlign();
if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
ValueSize == 1 && UseCodeAlign) {
getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
@@ -2631,12 +2636,10 @@ bool AsmParser::ParseDirectiveLoc() {
Flags |= DWARF2_FLAG_IS_STMT;
else
return Error(Loc, "is_stmt value not 0 or 1");
- }
- else {
+ } else {
return Error(Loc, "is_stmt value not the constant value of 0 or 1");
}
- }
- else if (Name == "isa") {
+ } else if (Name == "isa") {
Loc = getTok().getLoc();
const MCExpr *Value;
if (parseExpression(Value))
@@ -2647,16 +2650,13 @@ bool AsmParser::ParseDirectiveLoc() {
if (Value < 0)
return Error(Loc, "isa number less than zero");
Isa = Value;
- }
- else {
+ } else {
return Error(Loc, "isa number not a constant value");
}
- }
- else if (Name == "discriminator") {
+ } else if (Name == "discriminator") {
if (parseAbsoluteExpression(Discriminator))
return true;
- }
- else {
+ } else {
return Error(Loc, "unknown sub-directive in '.loc' directive");
}
@@ -3615,18 +3615,17 @@ bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
- Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
- " an .elseif");
+ Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
+ " an .elseif");
TheCondState.TheCond = AsmCond::ElseIfCond;
bool LastIgnoreState = false;
if (!TheCondStack.empty())
- LastIgnoreState = TheCondStack.back().Ignore;
+ LastIgnoreState = TheCondStack.back().Ignore;
if (LastIgnoreState || TheCondState.CondMet) {
TheCondState.Ignore = true;
eatToEndOfStatement();
- }
- else {
+ } else {
int64_t ExprValue;
if (parseAbsoluteExpression(ExprValue))
return true;
@@ -3652,8 +3651,8 @@ bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
- Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
- ".elseif");
+ Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
+ ".elseif");
TheCondState.TheCond = AsmCond::ElseCond;
bool LastIgnoreState = false;
if (!TheCondStack.empty())
@@ -4046,19 +4045,17 @@ static int RewritesSort(const void *A, const void *B) {
if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
return 1;
- // It's possible to have a SizeDirective rewrite and an Input/Output rewrite
- // to the same location. Make sure the SizeDirective rewrite is performed
- // first. This also ensure the sort algorithm is stable.
- if (AsmRewriteA->Kind == AOK_SizeDirective) {
- assert ((AsmRewriteB->Kind == AOK_Input || AsmRewriteB->Kind == AOK_Output) &&
- "Expected an Input/Output rewrite!");
+ // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
+ // rewrite to the same location. Make sure the SizeDirective rewrite is
+ // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
+ // ensures the sort algorithm is stable.
+ if (AsmRewritePrecedence [AsmRewriteA->Kind] >
+ AsmRewritePrecedence [AsmRewriteB->Kind])
return -1;
- }
- if (AsmRewriteB->Kind == AOK_SizeDirective) {
- assert ((AsmRewriteA->Kind == AOK_Input || AsmRewriteA->Kind == AOK_Output) &&
- "Expected an Input/Output rewrite!");
+
+ if (AsmRewritePrecedence [AsmRewriteA->Kind] <
+ AsmRewritePrecedence [AsmRewriteB->Kind])
return 1;
- }
llvm_unreachable ("Unstable rewrite sort.");
}
@@ -4118,28 +4115,27 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
}
// Expr/Input or Output.
- bool IsVarDecl;
- unsigned Length, Size, Type;
- void *OpDecl = SI.LookupInlineAsmIdentifier(Operand->getName(), AsmLoc,
- Length, Size, Type,
- IsVarDecl);
+ StringRef SymName = Operand->getSymName();
+ if (SymName.empty())
+ continue;
+
+ void *OpDecl = Operand->getOpDecl();
if (!OpDecl)
continue;
bool isOutput = (i == 1) && Desc.mayStore();
+ SMLoc Start = SMLoc::getFromPointer(SymName.data());
if (isOutput) {
++InputIdx;
OutputDecls.push_back(OpDecl);
OutputDeclsAddressOf.push_back(Operand->needAddressOf());
OutputConstraints.push_back('=' + Operand->getConstraint().str());
- AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Operand->getStartLoc(),
- Operand->getNameLen()));
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size()));
} else {
InputDecls.push_back(OpDecl);
InputDeclsAddressOf.push_back(Operand->needAddressOf());
InputConstraints.push_back(Operand->getConstraint().str());
- AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Operand->getStartLoc(),
- Operand->getNameLen()));
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size()));
}
}
}
@@ -4182,20 +4178,17 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(),
E = AsmStrRewrites.end();
I != E; ++I) {
+ AsmRewriteKind Kind = (*I).Kind;
+ if (Kind == AOK_Delete)
+ continue;
+
const char *Loc = (*I).Loc.getPointer();
assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
- unsigned AdditionalSkip = 0;
- AsmRewriteKind Kind = (*I).Kind;
-
// Emit everything up to the immediate/expression.
unsigned Len = Loc - AsmStart;
- if (Len) {
- // For Input/Output operands we need to remove the brackets, if present.
- if ((Kind == AOK_Input || Kind == AOK_Output) && Loc[-1] == '[')
- --Len;
+ if (Len)
OS << StringRef(AsmStart, Len);
- }
// Skip the original expression.
if (Kind == AOK_Skip) {
@@ -4203,6 +4196,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
continue;
}
+ unsigned AdditionalSkip = 0;
// Rewrite expressions in $N notation.
switch (Kind) {
default: break;
@@ -4249,11 +4243,6 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
// Skip the original expression.
AsmStart = Loc + (*I).Len + AdditionalSkip;
-
- // For Input/Output operands we need to remove the brackets, if present.
- if ((Kind == AOK_Input || Kind == AOK_Output) && AsmStart != AsmEnd &&
- *AsmStart == ']')
- ++AsmStart;
}
// Emit the remainder of the asm string.
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 6d6409fb69e22..7eb8b748348e8 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -566,10 +566,10 @@ bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
/// ParseDirectivePrevious:
/// ::= .previous
bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
- const MCSection *PreviousSection = getStreamer().getPreviousSection();
- if (PreviousSection == NULL)
+ MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
+ if (PreviousSection.first == NULL)
return TokError(".previous without corresponding .section");
- getStreamer().SwitchSection(PreviousSection);
+ getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
return false;
}
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index 4c45e087445d7..3134fc3d85974 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -76,6 +76,7 @@ public:
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
}
// FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
@@ -147,9 +148,11 @@ public:
bool ParseDirectiveVersion(StringRef, SMLoc);
bool ParseDirectiveWeakref(StringRef, SMLoc);
bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
+ bool ParseDirectiveSubsection(StringRef, SMLoc);
private:
bool ParseSectionName(StringRef &SectionName);
+ bool ParseSectionArguments(bool IsPush);
};
}
@@ -191,12 +194,15 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
unsigned Flags, SectionKind Kind) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in section switching directive");
- Lex();
+ const MCExpr *Subsection = 0;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getParser().parseExpression(Subsection))
+ return true;
+ }
getStreamer().SwitchSection(getContext().getELFSection(
- Section, Type, Flags, Kind));
+ Section, Type, Flags, Kind),
+ Subsection);
return false;
}
@@ -316,7 +322,7 @@ static int parseSectionFlags(StringRef flagsStr) {
bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
getStreamer().PushSection();
- if (ParseDirectiveSection(s, loc)) {
+ if (ParseSectionArguments(/*IsPush=*/true)) {
getStreamer().PopSection();
return true;
}
@@ -332,6 +338,10 @@ bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
// FIXME: This is a work in progress.
bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
+ return ParseSectionArguments(/*IsPush=*/false);
+}
+
+bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
StringRef SectionName;
if (ParseSectionName(SectionName))
@@ -341,6 +351,7 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
int64_t Size = 0;
StringRef GroupName;
unsigned Flags = 0;
+ const MCExpr *Subsection = 0;
// Set the defaults first.
if (SectionName == ".fini" || SectionName == ".init" ||
@@ -352,6 +363,14 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
if (getLexer().is(AsmToken::Comma)) {
Lex();
+ if (IsPush && getLexer().isNot(AsmToken::String)) {
+ if (getParser().parseExpression(Subsection))
+ return true;
+ if (getLexer().isNot(AsmToken::Comma))
+ goto EndStmt;
+ Lex();
+ }
+
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in directive");
@@ -408,6 +427,7 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
}
}
+EndStmt:
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
@@ -444,15 +464,16 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
SectionKind Kind = computeSectionKind(Flags);
getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
Flags, Kind, Size,
- GroupName));
+ GroupName),
+ Subsection);
return false;
}
bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
- const MCSection *PreviousSection = getStreamer().getPreviousSection();
- if (PreviousSection == NULL)
+ MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
+ if (PreviousSection.first == NULL)
return TokError(".previous without corresponding .section");
- getStreamer().SwitchSection(PreviousSection);
+ getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
return false;
}
@@ -613,6 +634,20 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
return false;
}
+bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
+ const MCExpr *Subsection = 0;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getParser().parseExpression(Subsection))
+ return true;
+ }
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ getStreamer().SubSection(Subsection);
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createELFAsmParser() {