diff options
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 23 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 203 | ||||
-rw-r--r-- | lib/MC/MCParser/COFFAsmParser.cpp | 92 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 104 |
5 files changed, 225 insertions, 199 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index bca516e..145ad4a 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -22,7 +22,6 @@ using namespace llvm; AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { - CurBuf = nullptr; CurPtr = nullptr; isAtStartOfLine = true; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); @@ -31,13 +30,13 @@ AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { AsmLexer::~AsmLexer() { } -void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) { - CurBuf = buf; +void AsmLexer::setBuffer(StringRef Buf, const char *ptr) { + CurBuf = Buf; if (ptr) CurPtr = ptr; else - CurPtr = CurBuf->getBufferStart(); + CurPtr = CurBuf.begin(); TokStart = nullptr; } @@ -58,7 +57,7 @@ int AsmLexer::getNextChar() { case 0: // A nul character in the stream is either the end of the current buffer or // a random nul in the file. Disambiguate that here. - if (CurPtr-1 != CurBuf->getBufferEnd()) + if (CurPtr - 1 != CurBuf.end()) return 0; // Just whitespace. // Otherwise, return end of file. @@ -201,8 +200,8 @@ AsmToken AsmLexer::LexLineComment() { CurChar = getNextChar(); if (CurChar == EOF) - return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0)); - return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0)); + return AsmToken(AsmToken::Eof, StringRef(TokStart, 0)); + return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0)); } static void SkipIgnoredIntegerSuffix(const char *&CurPtr) { @@ -420,9 +419,8 @@ StringRef AsmLexer::LexUntilEndOfStatement() { while (!isAtStartOfComment(*CurPtr) && // Start of line comment. !isAtStatementSeparator(CurPtr) && // End of statement marker. - *CurPtr != '\n' && - *CurPtr != '\r' && - (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) { + *CurPtr != '\n' && *CurPtr != '\r' && + (*CurPtr != 0 || CurPtr != CurBuf.end())) { ++CurPtr; } return StringRef(TokStart, CurPtr-TokStart); @@ -431,9 +429,8 @@ StringRef AsmLexer::LexUntilEndOfStatement() { StringRef AsmLexer::LexUntilEndOfLine() { TokStart = CurPtr; - while (*CurPtr != '\n' && - *CurPtr != '\r' && - (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) { + while (*CurPtr != '\n' && *CurPtr != '\r' && + (*CurPtr != 0 || CurPtr != CurBuf.end())) { ++CurPtr; } return StringRef(TokStart, CurPtr-TokStart); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 168597f..62ab4a5 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -102,7 +102,7 @@ public: struct ParseStatementInfo { /// \brief The parsed operands from the last parsed statement. - SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; + SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands; /// \brief The opcode from the last parsed instruction. unsigned Opcode; @@ -115,13 +115,6 @@ struct ParseStatementInfo { ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {} ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {} - - ~ParseStatementInfo() { - // Free any parsed operands. - for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) - delete ParsedOperands[i]; - ParsedOperands.clear(); - } }; /// \brief The concrete assembly parser instance. @@ -140,7 +133,7 @@ private: /// This is the current buffer index we're lexing from as managed by the /// SourceMgr object. - int CurBuffer; + unsigned CurBuffer; AsmCond TheCondState; std::vector<AsmCond> TheCondStack; @@ -169,13 +162,13 @@ private: StringRef CppHashFilename; int64_t CppHashLineNumber; SMLoc CppHashLoc; - int CppHashBuf; + unsigned CppHashBuf; /// When generating dwarf for assembly source files we need to calculate the /// logical line number based on the last parsed cpp hash file line comment /// and current line. Since this is slow and messes up the SourceMgr's /// cache we save the last info we queried with SrcMgr.FindLineNumber(). SMLoc LastQueryIDLoc; - int LastQueryBuffer; + unsigned LastQueryBuffer; unsigned LastQueryLine; /// AssemblerDialect. ~OU means unset value and use value provided by MAI. @@ -317,9 +310,9 @@ private: /// current token is not set; clients should ensure Lex() is called /// subsequently. /// - /// \param InBuffer If not -1, should be the known buffer id that contains the + /// \param InBuffer If not 0, should be the known buffer id that contains the /// location. - void jumpToLoc(SMLoc Loc, int InBuffer=-1); + void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0); /// \brief Parse up to the end of statement and a return the contents from the /// current token until the end of the statement; the current token on exit @@ -352,8 +345,9 @@ private: DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, - DK_IF, DK_IFNE, DK_IFB, DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, - DK_IFNDEF, DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF, + DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB, + DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, + DK_ELSEIF, DK_ELSE, DK_ENDIF, DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, @@ -440,8 +434,8 @@ private: bool parseDirectiveInclude(); // ".include" bool parseDirectiveIncbin(); // ".incbin" - // ".if" or ".ifne" - bool parseDirectiveIf(SMLoc DirectiveLoc); + // ".if", ".ifeq", ".ifge", ".ifgt" , ".ifle", ".iflt" or ".ifne" + bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind); // ".ifb" or ".ifnb", depending on ExpectBlank. bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); // ".ifc" or ".ifnc", depending on ExpectEqual. @@ -497,15 +491,15 @@ enum { DEFAULT_ADDRSPACE = 0 }; AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, const MCAsmInfo &_MAI) : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), - PlatformParser(nullptr), CurBuffer(0), MacrosEnabledFlag(true), - HadError(false), CppHashLineNumber(0), AssemblerDialect(~0U), - IsDarwin(false), ParsingInlineAsm(false) { + PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()), + MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0), + AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { // Save the old handler. SavedDiagHandler = SrcMgr.getDiagHandler(); SavedDiagContext = SrcMgr.getDiagContext(); // Set our own handler which calls the saved handler. SrcMgr.setDiagHandler(DiagHandler, this); - Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); + Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); // Initialize the platform / file format parser. switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { @@ -572,14 +566,13 @@ bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { bool AsmParser::enterIncludeFile(const std::string &Filename) { std::string IncludedFile; - int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); - if (NewBuf == -1) + unsigned NewBuf = + SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); + if (!NewBuf) return true; CurBuffer = NewBuf; - - Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); - + Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); return false; } @@ -588,8 +581,9 @@ bool AsmParser::enterIncludeFile(const std::string &Filename) { /// returns true on failure. bool AsmParser::processIncbinFile(const std::string &Filename) { std::string IncludedFile; - int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); - if (NewBuf == -1) + unsigned NewBuf = + SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); + if (!NewBuf) return true; // Pick up the bytes from the file and emit them. @@ -597,13 +591,10 @@ bool AsmParser::processIncbinFile(const std::string &Filename) { return false; } -void AsmParser::jumpToLoc(SMLoc Loc, int InBuffer) { - if (InBuffer != -1) { - CurBuffer = InBuffer; - } else { - CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); - } - Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer()); +void AsmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer) { + CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc); + Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), + Loc.getPointer()); } const AsmToken &AsmParser::Lex() { @@ -639,10 +630,12 @@ 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().first); MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); getStreamer().EmitLabel(SectionStartSym); - getContext().setGenDwarfSectionStartSym(SectionStartSym); + auto InsertResult = getContext().addGenDwarfSection( + getStreamer().getCurrentSection().first); + assert(InsertResult.second && ".text section should not have debug info yet"); + InsertResult.first->second.first = SectionStartSym; getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( 0, StringRef(), getContext().getMainFileName())); } @@ -818,7 +811,19 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { // Parse symbol variant std::pair<StringRef, StringRef> Split; if (!MAI.useParensForSymbolVariant()) { - Split = Identifier.split('@'); + if (FirstTokenKind == AsmToken::String) { + if (Lexer.is(AsmToken::At)) { + Lexer.Lex(); // eat @ + SMLoc AtLoc = getLexer().getLoc(); + StringRef VName; + if (parseIdentifier(VName)) + return Error(AtLoc, "expected symbol variant after '@'"); + + Split = std::make_pair(Identifier, VName); + } + } else { + Split = Identifier.split('@'); + } } else if (Lexer.is(AsmToken::LParen)) { Lexer.Lex(); // eat ( StringRef VName; @@ -1236,8 +1241,13 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { default: break; case DK_IF: + case DK_IFEQ: + case DK_IFGE: + case DK_IFGT: + case DK_IFLE: + case DK_IFLT: case DK_IFNE: - return parseDirectiveIf(IDLoc); + return parseDirectiveIf(IDLoc, DirKind); case DK_IFB: return parseDirectiveIfb(IDLoc, true); case DK_IFNB: @@ -1581,12 +1591,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { printMessage(IDLoc, SourceMgr::DK_Note, OS.str()); } - // If we are generating dwarf for assembly source files and the current - // section is the initial text section then generate a .loc directive for - // the instruction. + // If we are generating dwarf for the current section then generate a .loc + // directive for the instruction. if (!HadError && getContext().getGenDwarfForAssembly() && - getContext().getGenDwarfSection() == - getStreamer().getCurrentSection().first) { + getContext().getGenDwarfSectionSyms().count( + getStreamer().getCurrentSection().first)) { unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); @@ -1685,13 +1694,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); const SMLoc &DiagLoc = Diag.getLoc(); - int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); - int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); + unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); + unsigned CppHashBuf = + Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); // Like SourceMgr::printMessage() we need to print the include stack if any // before printing the message. - int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); - if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { + unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); + if (!Parser->SavedDiagHandler && DiagCurBuffer && + DiagCurBuffer != DiagSrcMgr.getMainFileID()) { SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); } @@ -2018,7 +2029,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, break; if (FAI >= NParameters) { - assert(M && "expected macro to be defined"); + assert(M && "expected macro to be defined"); Error(IDLoc, "parameter named '" + FA.Name + "' does not exist for macro '" + M->Name + "'"); @@ -2117,7 +2128,7 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { // Jump to the macro instantiation and prime the lexer. CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); - Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); + Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); Lex(); return false; @@ -3799,9 +3810,8 @@ bool AsmParser::parseDirectiveIncbin() { } /// parseDirectiveIf -/// ::= .if expression -/// ::= .ifne expression -bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { +/// ::= .if{,eq,ge,gt,le,lt,ne} expression +bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; if (TheCondState.Ignore) { @@ -3816,6 +3826,29 @@ bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { Lex(); + switch (DirKind) { + default: + llvm_unreachable("unsupported directive"); + case DK_IF: + case DK_IFNE: + break; + case DK_IFEQ: + ExprValue = ExprValue == 0; + break; + case DK_IFGE: + ExprValue = ExprValue >= 0; + break; + case DK_IFGT: + ExprValue = ExprValue > 0; + break; + case DK_IFLE: + ExprValue = ExprValue <= 0; + break; + case DK_IFLT: + ExprValue = ExprValue < 0; + break; + } + TheCondState.CondMet = ExprValue; TheCondState.Ignore = !TheCondState.CondMet; } @@ -4118,6 +4151,11 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; DirectiveKindMap[".if"] = DK_IF; + DirectiveKindMap[".ifeq"] = DK_IFEQ; + DirectiveKindMap[".ifge"] = DK_IFGE; + DirectiveKindMap[".ifgt"] = DK_IFGT; + DirectiveKindMap[".ifle"] = DK_IFLE; + DirectiveKindMap[".iflt"] = DK_IFLT; DirectiveKindMap[".ifne"] = DK_IFNE; DirectiveKindMap[".ifb"] = DK_IFB; DirectiveKindMap[".ifnb"] = DK_IFNB; @@ -4227,7 +4265,7 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, // Jump to the macro instantiation and prime the lexer. CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc()); - Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); + Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); Lex(); } @@ -4465,27 +4503,27 @@ bool AsmParser::parseMSInlineAsm( // Build the list of clobbers, outputs and inputs. for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { - MCParsedAsmOperand *Operand = Info.ParsedOperands[i]; + MCParsedAsmOperand &Operand = *Info.ParsedOperands[i]; // Immediate. - if (Operand->isImm()) + if (Operand.isImm()) continue; // Register operand. - if (Operand->isReg() && !Operand->needAddressOf()) { + if (Operand.isReg() && !Operand.needAddressOf()) { unsigned NumDefs = Desc.getNumDefs(); // Clobber. - if (NumDefs && Operand->getMCOperandNum() < NumDefs) - ClobberRegs.push_back(Operand->getReg()); + if (NumDefs && Operand.getMCOperandNum() < NumDefs) + ClobberRegs.push_back(Operand.getReg()); continue; } // Expr/Input or Output. - StringRef SymName = Operand->getSymName(); + StringRef SymName = Operand.getSymName(); if (SymName.empty()) continue; - void *OpDecl = Operand->getOpDecl(); + void *OpDecl = Operand.getOpDecl(); if (!OpDecl) continue; @@ -4494,21 +4532,21 @@ bool AsmParser::parseMSInlineAsm( if (isOutput) { ++InputIdx; OutputDecls.push_back(OpDecl); - OutputDeclsAddressOf.push_back(Operand->needAddressOf()); - OutputConstraints.push_back('=' + Operand->getConstraint().str()); + OutputDeclsAddressOf.push_back(Operand.needAddressOf()); + OutputConstraints.push_back('=' + Operand.getConstraint().str()); 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()); + InputDeclsAddressOf.push_back(Operand.needAddressOf()); + InputConstraints.push_back(Operand.getConstraint().str()); AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Start, SymName.size())); } } // Consider implicit defs to be clobbers. Think of cpuid and push. - const uint16_t *ImpDefs = Desc.getImplicitDefs(); - for (unsigned I = 0, E = Desc.getNumImplicitDefs(); I != E; ++I) - ClobberRegs.push_back(ImpDefs[I]); + ArrayRef<uint16_t> ImpDefs(Desc.getImplicitDefs(), + Desc.getNumImplicitDefs()); + ClobberRegs.insert(ClobberRegs.end(), ImpDefs.begin(), ImpDefs.end()); } // Set the number of Outputs and Inputs. @@ -4543,27 +4581,26 @@ bool AsmParser::parseMSInlineAsm( // Build the IR assembly string. std::string AsmStringIR; raw_string_ostream OS(AsmStringIR); - const char *AsmStart = SrcMgr.getMemoryBuffer(0)->getBufferStart(); - const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd(); + StringRef ASMString = + SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer(); + const char *AsmStart = ASMString.begin(); + const char *AsmEnd = ASMString.end(); array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); - for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(), - E = AsmStrRewrites.end(); - I != E; ++I) { - AsmRewriteKind Kind = (*I).Kind; + for (const AsmRewrite &AR : AsmStrRewrites) { + AsmRewriteKind Kind = AR.Kind; if (Kind == AOK_Delete) continue; - const char *Loc = (*I).Loc.getPointer(); + const char *Loc = AR.Loc.getPointer(); assert(Loc >= AsmStart && "Expected Loc to be at or after Start!"); // Emit everything up to the immediate/expression. - unsigned Len = Loc - AsmStart; - if (Len) + if (unsigned Len = Loc - AsmStart) OS << StringRef(AsmStart, Len); // Skip the original expression. if (Kind == AOK_Skip) { - AsmStart = Loc + (*I).Len; + AsmStart = Loc + AR.Len; continue; } @@ -4573,7 +4610,7 @@ bool AsmParser::parseMSInlineAsm( default: break; case AOK_Imm: - OS << "$$" << (*I).Val; + OS << "$$" << AR.Val; break; case AOK_ImmPrefix: OS << "$$"; @@ -4585,7 +4622,7 @@ bool AsmParser::parseMSInlineAsm( OS << '$' << OutputIdx++; break; case AOK_SizeDirective: - switch ((*I).Val) { + switch (AR.Val) { default: break; case 8: OS << "byte ptr "; break; case 16: OS << "word ptr "; break; @@ -4600,7 +4637,7 @@ bool AsmParser::parseMSInlineAsm( OS << ".byte"; break; case AOK_Align: { - unsigned Val = (*I).Val; + unsigned Val = AR.Val; OS << ".align " << Val; // Skip the original immediate. @@ -4613,12 +4650,12 @@ bool AsmParser::parseMSInlineAsm( OS.flush(); if (AsmStringIR.back() != '.') OS << '.'; - OS << (*I).Val; + OS << AR.Val; break; } // Skip the original expression. - AsmStart = Loc + (*I).Len + AdditionalSkip; + AsmStart = Loc + AR.Len + AdditionalSkip; } // Emit the remainder of the asm string. diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index decf01c..5ecf9e5 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -13,6 +13,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionCOFF.h" @@ -37,7 +38,7 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, - COFF::COMDATType Type, const MCSectionCOFF *Assoc); + COFF::COMDATType Type); bool ParseSectionName(StringRef &SectionName); bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags); @@ -117,8 +118,7 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseDirectiveEndef(StringRef, SMLoc); bool ParseDirectiveSecRel32(StringRef, SMLoc); bool ParseDirectiveSecIdx(StringRef, SMLoc); - bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, - const MCSectionCOFF *&Assoc); + bool parseCOMDATType(COFF::COMDATType &Type); bool ParseDirectiveLinkOnce(StringRef, SMLoc); // Win64 EH directives. @@ -170,8 +170,8 @@ bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { bool ReadOnlyRemoved = false; unsigned SecFlags = None; - for (unsigned i = 0; i < FlagsString.size(); ++i) { - switch (FlagsString[i]) { + for (char FlagChar : FlagsString) { + switch (FlagChar) { case 'a': // Ignored. break; @@ -292,22 +292,20 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { bool COFFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind) { - return ParseSectionSwitch(Section, Characteristics, Kind, "", - COFF::IMAGE_COMDAT_SELECT_ANY, nullptr); + return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0); } bool COFFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, - COFF::COMDATType Type, - const MCSectionCOFF *Assoc) { + COFF::COMDATType Type) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in section switching directive"); Lex(); getStreamer().SwitchSection(getContext().getCOFFSection( - Section, Characteristics, Kind, COMDATSymName, Type, Assoc)); + Section, Characteristics, Kind, COMDATSymName, Type)); return false; } @@ -358,15 +356,15 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { return true; } - COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; - const MCSectionCOFF *Assoc = nullptr; + COFF::COMDATType Type = (COFF::COMDATType)0; StringRef COMDATSymName; if (getLexer().is(AsmToken::Comma)) { + Type = COFF::IMAGE_COMDAT_SELECT_ANY;; Lex(); Flags |= COFF::IMAGE_SCN_LNK_COMDAT; - if (parseCOMDATTypeAndAssoc(Type, Assoc)) + if (parseCOMDATType(Type)) return true; if (getLexer().isNot(AsmToken::Comma)) @@ -381,7 +379,12 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { return TokError("unexpected token in directive"); SectionKind Kind = computeSectionKind(Flags); - ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type, Assoc); + if (Kind.isText()) { + const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); + if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb) + Flags |= COFF::IMAGE_SCN_MEM_16BIT; + } + ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type); return false; } @@ -461,9 +464,8 @@ bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) { return false; } -/// ::= [ identifier [ identifier ] ] -bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, - const MCSectionCOFF *&Assoc) { +/// ::= [ identifier ] +bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) { StringRef TypeId = getTok().getIdentifier(); Type = StringSwitch<COFF::COMDATType>(TypeId) @@ -481,48 +483,28 @@ bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, Lex(); - if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { - SMLoc Loc = getTok().getLoc(); - StringRef AssocName; - if (ParseSectionName(AssocName)) - return TokError("expected associated section name"); - - Assoc = static_cast<const MCSectionCOFF*>( - getContext().getCOFFSection(AssocName)); - if (!Assoc) - return Error(Loc, "cannot associate unknown section '" + AssocName + "'"); - if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)) - return Error(Loc, "associated section must be a COMDAT section"); - if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) - return Error(Loc, "associated section cannot be itself associative"); - } - return false; } /// ParseDirectiveLinkOnce -/// ::= .linkonce [ identifier [ identifier ] ] +/// ::= .linkonce [ identifier ] bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) { COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; - const MCSectionCOFF *Assoc = nullptr; if (getLexer().is(AsmToken::Identifier)) - if (parseCOMDATTypeAndAssoc(Type, Assoc)) + if (parseCOMDATType(Type)) return true; const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>( getStreamer().getCurrentSection().first); - - if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { - if (Assoc == Current) - return Error(Loc, "cannot associate a section with itself"); - } + if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) + return Error(Loc, "cannot make section associative with .linkonce"); if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) return Error(Loc, Twine("section '") + Current->getSectionName() + "' is already linkonce"); - Current->setSelection(Type, Assoc); + Current->setSelection(Type); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); @@ -541,25 +523,25 @@ bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); Lex(); - getStreamer().EmitWin64EHStartProc(Symbol); + getStreamer().EmitWinCFIStartProc(Symbol); return false; } bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) { Lex(); - getStreamer().EmitWin64EHEndProc(); + getStreamer().EmitWinCFIEndProc(); return false; } bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) { Lex(); - getStreamer().EmitWin64EHStartChained(); + getStreamer().EmitWinCFIStartChained(); return false; } bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) { Lex(); - getStreamer().EmitWin64EHEndChained(); + getStreamer().EmitWinCFIEndChained(); return false; } @@ -585,13 +567,13 @@ bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) { MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID); Lex(); - getStreamer().EmitWin64EHHandler(handler, unwind, except); + getStreamer().EmitWinEHHandler(handler, unwind, except); return false; } bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) { Lex(); - getStreamer().EmitWin64EHHandlerData(); + getStreamer().EmitWinEHHandlerData(); return false; } @@ -604,7 +586,7 @@ bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) { return TokError("unexpected token in directive"); Lex(); - getStreamer().EmitWin64EHPushReg(Reg); + getStreamer().EmitWinCFIPushReg(Reg); return false; } @@ -628,7 +610,7 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) { return TokError("unexpected token in directive"); Lex(); - getStreamer().EmitWin64EHSetFrame(Reg, Off); + getStreamer().EmitWinCFISetFrame(Reg, Off); return false; } @@ -645,7 +627,7 @@ bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) { return TokError("unexpected token in directive"); Lex(); - getStreamer().EmitWin64EHAllocStack(Size); + getStreamer().EmitWinCFIAllocStack(Size); return false; } @@ -670,7 +652,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) { Lex(); // FIXME: Err on %xmm* registers - getStreamer().EmitWin64EHSaveReg(Reg, Off); + getStreamer().EmitWinCFISaveReg(Reg, Off); return false; } @@ -697,7 +679,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) { Lex(); // FIXME: Err on non-%xmm* registers - getStreamer().EmitWin64EHSaveXMM(Reg, Off); + getStreamer().EmitWinCFISaveXMM(Reg, Off); return false; } @@ -718,13 +700,13 @@ bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) { return TokError("unexpected token in directive"); Lex(); - getStreamer().EmitWin64EHPushFrame(Code); + getStreamer().EmitWinCFIPushFrame(Code); return false; } bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) { Lex(); - getStreamer().EmitWin64EHEndProlog(); + getStreamer().EmitWinCFIEndProlog(); return false; } diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index f74b30a..b2a6785 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -650,7 +650,7 @@ bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { } // Write the message. - int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); + unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" << LogMessage + "\n"; diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 95c4971..98b2b3b 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -150,7 +150,7 @@ public: private: bool ParseSectionName(StringRef &SectionName); - bool ParseSectionArguments(bool IsPush); + bool ParseSectionArguments(bool IsPush, SMLoc loc); unsigned parseSunStyleSectionFlags(); }; @@ -382,7 +382,7 @@ unsigned ELFAsmParser::parseSunStyleSectionFlags() { bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { getStreamer().PushSection(); - if (ParseSectionArguments(/*IsPush=*/true)) { + if (ParseSectionArguments(/*IsPush=*/true, loc)) { getStreamer().PopSection(); return true; } @@ -397,11 +397,11 @@ bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { } // FIXME: This is a work in progress. -bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { - return ParseSectionArguments(/*IsPush=*/false); +bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { + return ParseSectionArguments(/*IsPush=*/false, loc); } -bool ELFAsmParser::ParseSectionArguments(bool IsPush) { +bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { StringRef SectionName; if (ParseSectionName(SectionName)) @@ -545,10 +545,24 @@ EndStmt: } SectionKind Kind = computeSectionKind(Flags, Size); - getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type, - Flags, Kind, Size, - GroupName), - Subsection); + const MCSection *ELFSection = getContext().getELFSection( + SectionName, Type, Flags, Kind, Size, GroupName); + getStreamer().SwitchSection(ELFSection, Subsection); + + if (getContext().getGenDwarfForAssembly()) { + auto &Sections = getContext().getGenDwarfSectionSyms(); + auto InsertResult = Sections.insert( + std::make_pair(ELFSection, std::make_pair(nullptr, nullptr))); + if (InsertResult.second) { + if (getContext().getDwarfVersion() <= 2) + Error(loc, "DWARF2 only supports one section per compilation unit"); + + MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol(); + getStreamer().EmitLabel(SectionStartSymbol); + InsertResult.first->second.first = SectionStartSymbol; + } + } + return false; } @@ -561,6 +575,19 @@ bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { return false; } +static MCSymbolAttr MCAttrForString(StringRef Type) { + return StringSwitch<MCSymbolAttr>(Type) + .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) + .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) + .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) + .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) + .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) + .Cases("STT_GNU_IFUNC", "gnu_indirect_function", + MCSA_ELF_TypeIndFunction) + .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) + .Default(MCSA_Invalid); +} + /// ParseDirectiveELFType /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> /// ::= .type identifier , #attribute @@ -575,53 +602,36 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { // Handle the identifier as the key symbol. MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); - if (getLexer().isNot(AsmToken::Comma)) - return TokError("unexpected token in '.type' directive"); - Lex(); - - StringRef Type; - SMLoc TypeLoc; - MCSymbolAttr Attr; - if (getLexer().is(AsmToken::Identifier)) { - TypeLoc = getLexer().getLoc(); - if (getParser().parseIdentifier(Type)) - return TokError("expected symbol type in directive"); - Attr = StringSwitch<MCSymbolAttr>(Type) - .Case("STT_FUNC", MCSA_ELF_TypeFunction) - .Case("STT_OBJECT", MCSA_ELF_TypeObject) - .Case("STT_TLS", MCSA_ELF_TypeTLS) - .Case("STT_COMMON", MCSA_ELF_TypeCommon) - .Case("STT_NOTYPE", MCSA_ELF_TypeNoType) - .Case("STT_GNU_IFUNC", MCSA_ELF_TypeIndFunction) - .Default(MCSA_Invalid); - } else if (getLexer().is(AsmToken::Hash) || getLexer().is(AsmToken::At) || - getLexer().is(AsmToken::Percent) || - getLexer().is(AsmToken::String)) { - if (!getLexer().is(AsmToken::String)) - Lex(); + // NOTE the comma is optional in all cases. It is only documented as being + // optional in the first case, however, GAS will silently treat the comma as + // optional in all cases. Furthermore, although the documentation states that + // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS + // accepts both the upper case name as well as the lower case aliases. + if (getLexer().is(AsmToken::Comma)) + Lex(); - TypeLoc = getLexer().getLoc(); - if (getParser().parseIdentifier(Type)) - return TokError("expected symbol type in directive"); - Attr = StringSwitch<MCSymbolAttr>(Type) - .Case("function", MCSA_ELF_TypeFunction) - .Case("object", MCSA_ELF_TypeObject) - .Case("tls_object", MCSA_ELF_TypeTLS) - .Case("common", MCSA_ELF_TypeCommon) - .Case("notype", MCSA_ELF_TypeNoType) - .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) - .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) - .Default(MCSA_Invalid); - } else + if (getLexer().isNot(AsmToken::Identifier) && + getLexer().isNot(AsmToken::Hash) && getLexer().isNot(AsmToken::At) && + getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::String)) return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " "'%<type>' or \"<type>\""); + if (getLexer().isNot(AsmToken::String) && + getLexer().isNot(AsmToken::Identifier)) + Lex(); + + SMLoc TypeLoc = getLexer().getLoc(); + + StringRef Type; + if (getParser().parseIdentifier(Type)) + return TokError("expected symbol type in directive"); + + MCSymbolAttr Attr = MCAttrForString(Type); if (Attr == MCSA_Invalid) return Error(TypeLoc, "unsupported attribute in '.type' directive"); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.type' directive"); - Lex(); getStreamer().EmitSymbolAttribute(Sym, Attr); |