diff options
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 107 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 6 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 53 |
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() { |