diff options
author | Stephen Hines <srhines@google.com> | 2014-04-23 16:57:46 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-04-24 15:53:16 -0700 |
commit | 36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch) | |
tree | e6cfb69fbbd937f450eeb83bfb83b9da3b01275a /lib/MC/MCParser | |
parent | 69a8640022b04415ae9fac62f8ab090601d8f889 (diff) | |
download | external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2 |
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r-- | lib/MC/MCParser/Android.mk | 2 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 67 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 753 | ||||
-rw-r--r-- | lib/MC/MCParser/COFFAsmParser.cpp | 21 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 535 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 88 |
6 files changed, 962 insertions, 504 deletions
diff --git a/lib/MC/MCParser/Android.mk b/lib/MC/MCParser/Android.mk index c6045d1..505a12b 100644 --- a/lib/MC/MCParser/Android.mk +++ b/lib/MC/MCParser/Android.mk @@ -27,6 +27,7 @@ include $(BUILD_HOST_STATIC_LIBRARY) # For the device # ===================================================== include $(CLEAR_VARS) +ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS)) LOCAL_SRC_FILES := $(mc_parser_SRC_FILES) @@ -36,3 +37,4 @@ LOCAL_MODULE_TAGS := optional include $(LLVM_DEVICE_BUILD_MK) include $(BUILD_STATIC_LIBRARY) +endif diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index b49dd01..a3b68d8 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -25,6 +25,7 @@ AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { CurBuf = NULL; CurPtr = NULL; isAtStartOfLine = true; + AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); } AsmLexer::~AsmLexer() { @@ -139,8 +140,9 @@ AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) { } /// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@?]* -static bool IsIdentifierChar(char c) { - return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@' || c == '?'; +static bool IsIdentifierChar(char c, bool AllowAt) { + return isalnum(c) || c == '_' || c == '$' || c == '.' || + (c == '@' && AllowAt) || c == '?'; } AsmToken AsmLexer::LexIdentifier() { // Check for floating point literals. @@ -148,11 +150,12 @@ AsmToken AsmLexer::LexIdentifier() { // Disambiguate a .1243foo identifier from a floating literal. while (isdigit(*CurPtr)) ++CurPtr; - if (*CurPtr == 'e' || *CurPtr == 'E' || !IsIdentifierChar(*CurPtr)) + if (*CurPtr == 'e' || *CurPtr == 'E' || + !IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) return LexFloatLiteral(); } - while (IsIdentifierChar(*CurPtr)) + while (IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) ++CurPtr; // Handle . as a special case. @@ -235,6 +238,13 @@ static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) { return DefaultRadix; } +static AsmToken intToken(StringRef Ref, APInt &Value) +{ + if (Value.isIntN(64)) + return AsmToken(AsmToken::Integer, Ref, Value); + return AsmToken(AsmToken::BigNum, Ref, Value); +} + /// LexDigit: First character is [0-9]. /// Local Label: [0-9][:] /// Forward/Backward Label: [0-9][fb] @@ -255,16 +265,10 @@ AsmToken AsmLexer::LexDigit() { StringRef Result(TokStart, CurPtr - TokStart); - long long Value; - if (Result.getAsInteger(Radix, Value)) { - // Allow positive values that are too large to fit into a signed 64-bit - // integer, but that do fit in an unsigned one, we just convert them over. - unsigned long long UValue; - if (Result.getAsInteger(Radix, UValue)) - return ReturnError(TokStart, !isHex ? "invalid decimal number" : + APInt Value(128, 0, true); + if (Result.getAsInteger(Radix, Value)) + return ReturnError(TokStart, !isHex ? "invalid decimal number" : "invalid hexdecimal number"); - Value = (long long)UValue; - } // Consume the [bB][hH]. if (Radix == 2 || Radix == 16) @@ -274,7 +278,7 @@ AsmToken AsmLexer::LexDigit() { // suffices on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } if (*CurPtr == 'b') { @@ -295,7 +299,7 @@ AsmToken AsmLexer::LexDigit() { StringRef Result(TokStart, CurPtr - TokStart); - long long Value; + APInt Value(128, 0, true); if (Result.substr(2).getAsInteger(2, Value)) return ReturnError(TokStart, "invalid binary number"); @@ -303,7 +307,7 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } if (*CurPtr == 'x') { @@ -321,7 +325,7 @@ AsmToken AsmLexer::LexDigit() { if (CurPtr == NumStart) return ReturnError(CurPtr-2, "invalid hexadecimal number"); - unsigned long long Result; + APInt Result(128, 0); if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result)) return ReturnError(TokStart, "invalid hexadecimal number"); @@ -333,12 +337,11 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart), - (int64_t)Result); + return intToken(StringRef(TokStart, CurPtr - TokStart), Result); } // Either octal or hexadecimal. - long long Value; + APInt Value(128, 0, true); unsigned Radix = doLookAhead(CurPtr, 8); bool isHex = Radix == 16; StringRef Result(TokStart, CurPtr - TokStart); @@ -354,7 +357,7 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } /// LexSingleQuote: Integer: 'b' @@ -436,6 +439,28 @@ StringRef AsmLexer::LexUntilEndOfLine() { return StringRef(TokStart, CurPtr-TokStart); } +const AsmToken AsmLexer::peekTok(bool ShouldSkipSpace) { + const char *SavedTokStart = TokStart; + const char *SavedCurPtr = CurPtr; + bool SavedAtStartOfLine = isAtStartOfLine; + bool SavedSkipSpace = SkipSpace; + + std::string SavedErr = getErr(); + SMLoc SavedErrLoc = getErrLoc(); + + SkipSpace = ShouldSkipSpace; + AsmToken Token = LexToken(); + + SetError(SavedErrLoc, SavedErr); + + SkipSpace = SavedSkipSpace; + isAtStartOfLine = SavedAtStartOfLine; + CurPtr = SavedCurPtr; + TokStart = SavedTokStart; + + return Token; +} + bool AsmLexer::isAtStartOfComment(char Char) { // FIXME: This won't work for multi-character comment indicators like "//". return Char == *MAI.getCommentString(); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a91bd93..910a424 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/APFloat.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmInfo.h" @@ -22,6 +22,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/AsmCond.h" #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -50,11 +51,18 @@ FatalAssemblerWarnings("fatal-assembler-warnings", MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {} namespace { - /// \brief Helper types for tracking macro definitions. typedef std::vector<AsmToken> MCAsmMacroArgument; typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments; -typedef std::pair<StringRef, MCAsmMacroArgument> MCAsmMacroParameter; + +struct MCAsmMacroParameter { + StringRef Name; + MCAsmMacroArgument Value; + bool Required; + + MCAsmMacroParameter() : Required(false) { } +}; + typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters; struct MCAsmMacro { @@ -63,11 +71,8 @@ struct MCAsmMacro { MCAsmMacroParameters Parameters; public: - MCAsmMacro(StringRef N, StringRef B, const MCAsmMacroParameters &P) : + MCAsmMacro(StringRef N, StringRef B, ArrayRef<MCAsmMacroParameter> P) : Name(N), Body(B), Parameters(P) {} - - MCAsmMacro(const MCAsmMacro& Other) - : Name(Other.Name), Body(Other.Body), Parameters(Other.Parameters) {} }; /// \brief Helper class for storing information about an active macro @@ -185,10 +190,10 @@ public: const MCAsmInfo &MAI); virtual ~AsmParser(); - virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false); + bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; - virtual void addDirectiveHandler(StringRef Directive, - ExtensionDirectiveHandler Handler) { + void addDirectiveHandler(StringRef Directive, + ExtensionDirectiveHandler Handler) override { ExtensionDirectiveMap[Directive] = Handler; } @@ -196,51 +201,52 @@ public: /// @name MCAsmParser Interface /// { - virtual SourceMgr &getSourceManager() { return SrcMgr; } - virtual MCAsmLexer &getLexer() { return Lexer; } - virtual MCContext &getContext() { return Ctx; } - virtual MCStreamer &getStreamer() { return Out; } - virtual unsigned getAssemblerDialect() { + SourceMgr &getSourceManager() override { return SrcMgr; } + MCAsmLexer &getLexer() override { return Lexer; } + MCContext &getContext() override { return Ctx; } + MCStreamer &getStreamer() override { return Out; } + unsigned getAssemblerDialect() override { if (AssemblerDialect == ~0U) return MAI.getAssemblerDialect(); else return AssemblerDialect; } - virtual void setAssemblerDialect(unsigned i) { + void setAssemblerDialect(unsigned i) override { AssemblerDialect = i; } - virtual bool Warning(SMLoc L, const Twine &Msg, - ArrayRef<SMRange> Ranges = None); - virtual bool Error(SMLoc L, const Twine &Msg, - ArrayRef<SMRange> Ranges = None); + void Note(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = None) override; + bool Warning(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = None) override; + bool Error(SMLoc L, const Twine &Msg, + ArrayRef<SMRange> Ranges = None) override; - virtual const AsmToken &Lex(); + const AsmToken &Lex() override; - void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; } - bool isParsingInlineAsm() { return ParsingInlineAsm; } + void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; } + bool isParsingInlineAsm() override { return ParsingInlineAsm; } bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, SmallVectorImpl<std::pair<void *,bool> > &OpDecls, SmallVectorImpl<std::string> &Constraints, SmallVectorImpl<std::string> &Clobbers, - const MCInstrInfo *MII, - const MCInstPrinter *IP, - MCAsmParserSemaCallback &SI); + const MCInstrInfo *MII, const MCInstPrinter *IP, + MCAsmParserSemaCallback &SI) override; 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); + bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override; + bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; + bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override; + bool parseAbsoluteExpression(int64_t &Res) override; /// \brief Parse an identifier or string (as a quoted identifier) /// and set \p Res to the identifier contents. - virtual bool parseIdentifier(StringRef &Res); - virtual void eatToEndOfStatement(); + bool parseIdentifier(StringRef &Res) override; + void eatToEndOfStatement() override; - virtual void checkForValidSection(); + void checkForValidSection() override; /// } private: @@ -250,10 +256,10 @@ private: bool parseCppHashLineFilenameComment(const SMLoc &L); void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, - MCAsmMacroParameters Parameters); + ArrayRef<MCAsmMacroParameter> Parameters); bool expandMacro(raw_svector_ostream &OS, StringRef Body, - const MCAsmMacroParameters &Parameters, - const MCAsmMacroArguments &A, + ArrayRef<MCAsmMacroParameter> Parameters, + ArrayRef<MCAsmMacroArgument> A, const SMLoc &L); /// \brief Are macros enabled in the parser? @@ -285,11 +291,8 @@ private: /// \brief Handle exit from macro instantiation. void handleMacroExit(); - /// \brief Extract AsmTokens for a macro argument. If the argument delimiter - /// is initially unknown, set it to AsmToken::Eof. It will be set to the - /// correct delimiter by the method. - bool parseMacroArgument(MCAsmMacroArgument &MA, - AsmToken::TokenKind &ArgumentDelimiter); + /// \brief Extract AsmTokens for a macro argument. + bool parseMacroArgument(MCAsmMacroArgument &MA); /// \brief Parse all macro arguments for a given macro. bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); @@ -319,7 +322,7 @@ private: /// \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 /// will be either the EndOfStatement or EOF. - virtual StringRef parseStringToEndOfStatement(); + StringRef parseStringToEndOfStatement() override; /// \brief Parse until the end of a statement or a comma is encountered, /// return the contents from the current token up to the end or comma. @@ -338,8 +341,8 @@ private: enum DirectiveKind { DK_NO_DIRECTIVE, // Placeholder DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT, - DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_SINGLE, - DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW, + DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA, + DK_SINGLE, DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW, DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR, DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK, DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, @@ -347,8 +350,8 @@ 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_IFB, DK_IFNB, DK_IFC, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, - DK_ELSEIF, DK_ELSE, DK_ENDIF, + 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_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, @@ -357,7 +360,9 @@ private: DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE, DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM, - DK_SLEB128, DK_ULEB128 + DK_SLEB128, DK_ULEB128, + DK_ERR, DK_ERROR, + DK_END }; /// \brief Maps directive name --> DirectiveKind enum, for @@ -367,6 +372,7 @@ private: // ".ascii", ".asciz", ".string" bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ... + bool parseDirectiveOctaValue(); // ".octa" bool parseDirectiveRealValue(const fltSemantics &); // ".single", ... bool parseDirectiveFill(); // ".fill" bool parseDirectiveZero(); // ".zero" @@ -432,17 +438,20 @@ private: bool parseDirectiveInclude(); // ".include" bool parseDirectiveIncbin(); // ".incbin" - bool parseDirectiveIf(SMLoc DirectiveLoc); // ".if" + // ".if" or ".ifne" + bool parseDirectiveIf(SMLoc DirectiveLoc); // ".ifb" or ".ifnb", depending on ExpectBlank. bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); // ".ifc" or ".ifnc", depending on ExpectEqual. bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); + // ".ifeqs" + bool parseDirectiveIfeqs(SMLoc DirectiveLoc); // ".ifdef" or ".ifndef", depending on expect_defined bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else" bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif - virtual bool parseEscapedString(std::string &Data); + bool parseEscapedString(std::string &Data) override; const MCExpr *applyModifierToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind Variant); @@ -451,7 +460,7 @@ private: MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc); void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, raw_svector_ostream &OS); - bool parseDirectiveRept(SMLoc DirectiveLoc); // ".rept" + bool parseDirectiveRept(SMLoc DirectiveLoc, StringRef Directive); bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" @@ -463,6 +472,12 @@ private: // "align" bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); + // "end" + bool parseDirectiveEnd(SMLoc DirectiveLoc); + + // ".err" or ".error" + bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage); + void initializeDirectiveKindMap(); }; } @@ -491,19 +506,20 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); // Initialize the platform / file format parser. - // - // FIXME: This is a hack, we need to (majorly) cleanup how these objects are - // created. - if (_MAI.hasMicrosoftFastStdCallMangling()) { - PlatformParser = createCOFFAsmParser(); - PlatformParser->Initialize(*this); - } else if (_MAI.hasSubsectionsViaSymbols()) { - PlatformParser = createDarwinAsmParser(); - PlatformParser->Initialize(*this); - IsDarwin = true; - } else { - PlatformParser = createELFAsmParser(); - PlatformParser->Initialize(*this); + switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { + case MCObjectFileInfo::IsCOFF: + PlatformParser = createCOFFAsmParser(); + PlatformParser->Initialize(*this); + break; + case MCObjectFileInfo::IsMachO: + PlatformParser = createDarwinAsmParser(); + PlatformParser->Initialize(*this); + IsDarwin = true; + break; + case MCObjectFileInfo::IsELF: + PlatformParser = createELFAsmParser(); + PlatformParser->Initialize(*this); + break; } initializeDirectiveKindMap(); @@ -531,6 +547,11 @@ void AsmParser::printMacroInstantiations() { "while in macro instantiation"); } +void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { + printMessage(L, SourceMgr::DK_Note, Msg, Ranges); + printMacroInstantiations(); +} + bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { if (FatalAssemblerWarnings) return Error(L, Msg, Ranges); @@ -619,9 +640,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); getStreamer().EmitLabel(SectionStartSym); getContext().setGenDwarfSectionStartSym(SectionStartSym); - getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), - StringRef(), - getContext().getMainFileName()); + getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( + 0, StringRef(), getContext().getMainFileName())); } // While we have input, parse each statement. @@ -641,11 +661,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { return TokError("unmatched .ifs or .elses"); // Check to see there are no empty DwarfFile slots. - const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles = - getContext().getMCDwarfFiles(); - for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { - if (!MCDwarfFiles[i]) - TokError("unassigned file number: " + Twine(i) + " for .file directives"); + const auto &LineTables = getContext().getMCDwarfLineTables(); + if (!LineTables.empty()) { + unsigned Index = 0; + for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) { + if (File.Name.empty() && Index != 0) + TokError("unassigned file number: " + Twine(Index) + + " for .file directives"); + ++Index; + } } // Check to see that all assembler local symbols were actually defined. @@ -682,7 +706,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { void AsmParser::checkForValidSection() { if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) { TokError("expected section directive before assembly directive"); - Out.InitToTextSection(); + Out.InitSections(); } } @@ -784,10 +808,24 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { getContext()); EndLoc = FirstTokenLoc; return false; - } else - return Error(FirstTokenLoc, "invalid token in expression"); - return true; + } + return Error(FirstTokenLoc, "invalid token in expression"); + } + } + // Parse symbol variant + std::pair<StringRef, StringRef> Split; + if (!MAI.useParensForSymbolVariant()) { + Split = Identifier.split('@'); + } else if (Lexer.is(AsmToken::LParen)) { + Lexer.Lex(); // eat ( + StringRef VName; + parseIdentifier(VName); + if (Lexer.isNot(AsmToken::RParen)) { + return Error(Lexer.getTok().getLoc(), + "unexpected token in variant, expected ')'"); } + Lexer.Lex(); // eat ) + Split = std::make_pair(Identifier, VName); } EndLoc = SMLoc::getFromPointer(Identifier.end()); @@ -795,18 +833,17 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { // This is a symbol reference. StringRef SymbolName = Identifier; MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; - std::pair<StringRef, StringRef> Split = Identifier.split('@'); // Lookup the symbol variant if used. - if (Split.first.size() != Identifier.size()) { + if (Split.second.size()) { Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); if (Variant != MCSymbolRefExpr::VK_Invalid) { SymbolName = Split.first; - } else if (MAI.doesAllowAtInName()) { + } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) { Variant = MCSymbolRefExpr::VK_None; } else { - Variant = MCSymbolRefExpr::VK_None; - return TokError("invalid variant '" + Split.second + "'"); + return Error(SMLoc::getFromPointer(Split.second.begin()), + "invalid variant '" + Split.second + "'"); } } @@ -826,6 +863,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); return false; } + case AsmToken::BigNum: + return TokError("literal value out of range for directive"); case AsmToken::Integer: { SMLoc Loc = getTok().getLoc(); int64_t IntVal = getTok().getIntVal(); @@ -840,15 +879,13 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; if (Split.first.size() != IDVal.size()) { Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); - if (Variant == MCSymbolRefExpr::VK_Invalid) { - Variant = MCSymbolRefExpr::VK_None; + if (Variant == MCSymbolRefExpr::VK_Invalid) return TokError("invalid variant '" + Split.second + "'"); - } IDVal = Split.first; } if (IDVal == "f" || IDVal == "b") { MCSymbol *Sym = - Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "f" ? 1 : 0); + Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "b"); Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); if (IDVal == "b" && Sym->isUndefined()) return Error(Loc, "invalid reference to undefined symbol"); @@ -1196,6 +1233,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { default: break; case DK_IF: + case DK_IFNE: return parseDirectiveIf(IDLoc); case DK_IFB: return parseDirectiveIfb(IDLoc, true); @@ -1203,6 +1241,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { return parseDirectiveIfb(IDLoc, false); case DK_IFC: return parseDirectiveIfc(IDLoc, true); + case DK_IFEQS: + return parseDirectiveIfeqs(IDLoc); case DK_IFNC: return parseDirectiveIfc(IDLoc, false); case DK_IFDEF: @@ -1311,7 +1351,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { if (!getTargetParser().ParseDirective(ID)) return false; - // Next, check the extention directive map to see if any extension has + // Next, check the extension directive map to see if any extension has // registered itself to parse this directive. std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = ExtensionDirectiveMap.lookup(IDVal); @@ -1346,6 +1386,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { case DK_QUAD: case DK_8BYTE: return parseDirectiveValue(8); + case DK_OCTA: + return parseDirectiveOctaValue(); case DK_SINGLE: case DK_FLOAT: return parseDirectiveRealValue(APFloat::IEEEsingle); @@ -1414,7 +1456,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { case DK_CODE16GCC: return TokError(Twine(IDVal) + " not supported yet"); case DK_REPT: - return parseDirectiveRept(IDLoc); + return parseDirectiveRept(IDLoc, IDVal); case DK_IRP: return parseDirectiveIrp(IDLoc); case DK_IRPC: @@ -1492,6 +1534,12 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { return parseDirectiveEndMacro(IDVal); case DK_PURGEM: return parseDirectivePurgeMacro(IDLoc); + case DK_END: + return parseDirectiveEnd(IDLoc); + case DK_ERR: + return parseDirectiveError(IDLoc, false); + case DK_ERROR: + return parseDirectiveError(IDLoc, true); } return Error(IDLoc, "unknown directive"); @@ -1542,14 +1590,10 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { // If we previously parsed a cpp hash file line comment then make sure the // current Dwarf File is for the CppHashFilename if not then emit the // Dwarf File table for it and adjust the line number for the .loc. - const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles = - getContext().getMCDwarfFiles(); if (CppHashFilename.size() != 0) { - if (MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() != - CppHashFilename) - getStreamer().EmitDwarfFileDirective( - getContext().nextGenDwarfFileNumber(), StringRef(), - CppHashFilename); + unsigned FileNumber = getStreamer().EmitDwarfFileDirective( + 0, StringRef(), CppHashFilename); + getContext().setGenDwarfFileNumber(FileNumber); // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's // cache with the different Loc from the call above we save the last @@ -1575,9 +1619,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { // If parsing succeeded, match the instruction. if (!HadError) { unsigned ErrorInfo; - HadError = getTargetParser().MatchAndEmitInstruction( - IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo, - ParsingInlineAsm); + getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, + Info.ParsedOperands, Out, + ErrorInfo, ParsingInlineAsm); } // Don't skip the rest of the line, the instruction parser is responsible for @@ -1692,10 +1736,10 @@ static bool isIdentifierChar(char c) { } bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, - const MCAsmMacroParameters &Parameters, - const MCAsmMacroArguments &A, const SMLoc &L) { + ArrayRef<MCAsmMacroParameter> Parameters, + ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) { unsigned NParameters = Parameters.size(); - if (NParameters != 0 && NParameters != A.size()) + if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) return Error(L, "Wrong number of arguments"); // A macro without parameters is handled differently on Darwin: @@ -1705,7 +1749,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, std::size_t End = Body.size(), Pos = 0; for (; Pos != End; ++Pos) { // Check for a substitution or escape. - if (!NParameters) { + if (IsDarwin && !NParameters) { // This macro has no parameters, look for $0, $1, etc. if (Body[Pos] != '$' || Pos + 1 == End) continue; @@ -1728,7 +1772,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, if (Pos == End) break; - if (!NParameters) { + if (IsDarwin && !NParameters) { switch (Body[Pos + 1]) { // $$ => $ case '$': @@ -1765,7 +1809,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, StringRef Argument(Begin, I - (Pos + 1)); unsigned Index = 0; for (; Index < NParameters; ++Index) - if (Parameters[Index].first == Argument) + if (Parameters[Index].Name == Argument) break; if (Index == NParameters) { @@ -1830,31 +1874,35 @@ static bool isOperator(AsmToken::TokenKind kind) { } } -bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, - AsmToken::TokenKind &ArgumentDelimiter) { +namespace { +class AsmLexerSkipSpaceRAII { +public: + AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) { + Lexer.setSkipSpace(SkipSpace); + } + + ~AsmLexerSkipSpaceRAII() { + Lexer.setSkipSpace(true); + } + +private: + AsmLexer &Lexer; +}; +} + +bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA) { unsigned ParenLevel = 0; unsigned AddTokens = 0; - // gas accepts arguments separated by whitespace, except on Darwin - if (!IsDarwin) - Lexer.setSkipSpace(false); + // Darwin doesn't use spaces to delmit arguments. + AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin); for (;;) { - if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) { - Lexer.setSkipSpace(true); + if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) return TokError("unexpected token in macro instantiation"); - } - if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) { - // Spaces and commas cannot be mixed to delimit parameters - if (ArgumentDelimiter == AsmToken::Eof) - ArgumentDelimiter = AsmToken::Comma; - else if (ArgumentDelimiter != AsmToken::Comma) { - Lexer.setSkipSpace(true); - return TokError("expected ' ' for macro argument separator"); - } + if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) break; - } if (Lexer.is(AsmToken::Space)) { Lex(); // Eat spaces @@ -1862,8 +1910,7 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, // Spaces can delimit parameters, but could also be part an expression. // If the token after a space is an operator, add the token and the next // one into this argument - if (ArgumentDelimiter == AsmToken::Space || - ArgumentDelimiter == AsmToken::Eof) { + if (!IsDarwin) { if (isOperator(Lexer.getKind())) { // Check to see whether the token is used as an operator, // or part of an identifier @@ -1873,9 +1920,6 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, } if (!AddTokens && ParenLevel == 0) { - if (ArgumentDelimiter == AsmToken::Eof && - !isOperator(Lexer.getKind())) - ArgumentDelimiter = AsmToken::Space; break; } } @@ -1899,7 +1943,6 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, Lex(); } - Lexer.setSkipSpace(true); if (ParenLevel != 0) return TokError("unbalanced parentheses in macro argument"); return false; @@ -1909,46 +1952,100 @@ bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool AsmParser::parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) { const unsigned NParameters = M ? M->Parameters.size() : 0; - // Argument delimiter is initially unknown. It will be set by - // parseMacroArgument() - AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; + bool NamedParametersFound = false; + SmallVector<SMLoc, 4> FALocs; + + A.resize(NParameters); + FALocs.resize(NParameters); // Parse two kinds of macro invocations: // - macros defined without any parameters accept an arbitrary number of them // - macros defined with parameters accept at most that many of them for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; ++Parameter) { - MCAsmMacroArgument MA; + SMLoc IDLoc = Lexer.getLoc(); + MCAsmMacroParameter FA; + + if (Lexer.is(AsmToken::Identifier) && Lexer.peekTok().is(AsmToken::Equal)) { + if (parseIdentifier(FA.Name)) { + Error(IDLoc, "invalid argument identifier for formal argument"); + eatToEndOfStatement(); + return true; + } + + if (!Lexer.is(AsmToken::Equal)) { + TokError("expected '=' after formal parameter identifier"); + eatToEndOfStatement(); + return true; + } + Lex(); - if (parseMacroArgument(MA, ArgumentDelimiter)) + NamedParametersFound = true; + } + + if (NamedParametersFound && FA.Name.empty()) { + Error(IDLoc, "cannot mix positional and keyword arguments"); + eatToEndOfStatement(); return true; + } + + if (parseMacroArgument(FA.Value)) + return true; + + unsigned PI = Parameter; + if (!FA.Name.empty()) { + unsigned FAI = 0; + for (FAI = 0; FAI < NParameters; ++FAI) + if (M->Parameters[FAI].Name == FA.Name) + break; + + if (FAI >= NParameters) { + assert(M && "expected macro to be defined"); + Error(IDLoc, + "parameter named '" + FA.Name + "' does not exist for macro '" + + M->Name + "'"); + return true; + } + PI = FAI; + } + + if (!FA.Value.empty()) { + if (A.size() <= PI) + A.resize(PI + 1); + A[PI] = FA.Value; + + if (FALocs.size() <= PI) + FALocs.resize(PI + 1); - if (!MA.empty() || !NParameters) - A.push_back(MA); - else if (NParameters) { - if (!M->Parameters[Parameter].second.empty()) - A.push_back(M->Parameters[Parameter].second); + FALocs[PI] = Lexer.getLoc(); } // At the end of the statement, fill in remaining arguments that have // default values. If there aren't any, then the next argument is // required but missing if (Lexer.is(AsmToken::EndOfStatement)) { - if (NParameters && Parameter < NParameters - 1) { - if (M->Parameters[Parameter + 1].second.empty()) - return TokError("macro argument '" + - Twine(M->Parameters[Parameter + 1].first) + - "' is missing"); - else - continue; + bool Failure = false; + for (unsigned FAI = 0; FAI < NParameters; ++FAI) { + if (A[FAI].empty()) { + if (M->Parameters[FAI].Required) { + Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(), + "missing value for required parameter " + "'" + M->Parameters[FAI].Name + "' in macro '" + M->Name + "'"); + Failure = true; + } + + if (!M->Parameters[FAI].Value.empty()) + A[FAI] = M->Parameters[FAI].Value; + } } - return false; + return Failure; } if (Lexer.is(AsmToken::Comma)) Lex(); } - return TokError("Too many arguments"); + + return TokError("too many positional arguments"); } const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) { @@ -1978,12 +2075,6 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { if (parseMacroArguments(M, A)) return true; - // Remove any trailing empty arguments. Do this after-the-fact as we have - // to keep empty arguments in the middle of the list or positionality - // gets off. e.g., "foo 1, , 2" vs. "foo 1, 2," - while (!A.empty() && A.back().empty()) - A.pop_back(); - // Macro instantiation is lexical, unfortunately. We construct a new buffer // to hold the macro body with substitutions. SmallString<256> Buf; @@ -2063,12 +2154,6 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, if (Lexer.isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in assignment"); - // Error on assignment to '.'. - if (Name == ".") { - return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported " - "(use '.space' or '.org').)")); - } - // Eat the end of statement marker. Lex(); @@ -2096,11 +2181,15 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, // Don't count these checks as uses. Sym->setUsed(false); + } else if (Name == ".") { + if (Out.EmitValueToOffset(Value, 0)) { + Error(EqualLoc, "expected absolute expression"); + eatToEndOfStatement(); + } + return false; } else Sym = getContext().GetOrCreateSymbol(Name); - // FIXME: Handle '.'. - // Do the assignment. Out.EmitAssignment(Sym, Value); if (NoDeadStrip) @@ -2291,6 +2380,56 @@ bool AsmParser::parseDirectiveValue(unsigned Size) { return false; } +/// ParseDirectiveOctaValue +/// ::= .octa [ hexconstant (, hexconstant)* ] +bool AsmParser::parseDirectiveOctaValue() { + if (getLexer().isNot(AsmToken::EndOfStatement)) { + checkForValidSection(); + + for (;;) { + if (Lexer.getKind() == AsmToken::Error) + return true; + if (Lexer.getKind() != AsmToken::Integer && + Lexer.getKind() != AsmToken::BigNum) + return TokError("unknown token in expression"); + + SMLoc ExprLoc = getLexer().getLoc(); + APInt IntValue = getTok().getAPIntVal(); + Lex(); + + uint64_t hi, lo; + if (IntValue.isIntN(64)) { + hi = 0; + lo = IntValue.getZExtValue(); + } else if (IntValue.isIntN(128)) { + // It might actually have more than 128 bits, but the top ones are zero. + hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue(); + lo = IntValue.getLoBits(64).getZExtValue(); + } else + return Error(ExprLoc, "literal value out of range for directive"); + + if (MAI.isLittleEndian()) { + getStreamer().EmitIntValue(lo, 8); + getStreamer().EmitIntValue(hi, 8); + } else { + getStreamer().EmitIntValue(hi, 8); + getStreamer().EmitIntValue(lo, 8); + } + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + // FIXME: Improve diagnostic. + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + + Lex(); + return false; +} + /// parseDirectiveRealValue /// ::= (.single | .double) [ expression (, expression)* ] bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) { @@ -2380,18 +2519,27 @@ bool AsmParser::parseDirectiveZero() { bool AsmParser::parseDirectiveFill() { checkForValidSection(); + SMLoc RepeatLoc = getLexer().getLoc(); int64_t NumValues; if (parseAbsoluteExpression(NumValues)) return true; + if (NumValues < 0) { + Warning(RepeatLoc, + "'.fill' directive with negative repeat count has no effect"); + NumValues = 0; + } + int64_t FillSize = 1; int64_t FillExpr = 0; + SMLoc SizeLoc, ExprLoc; if (getLexer().isNot(AsmToken::EndOfStatement)) { if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in '.fill' directive"); Lex(); + SizeLoc = getLexer().getLoc(); if (parseAbsoluteExpression(FillSize)) return true; @@ -2400,6 +2548,7 @@ bool AsmParser::parseDirectiveFill() { return TokError("unexpected token in '.fill' directive"); Lex(); + ExprLoc = getLexer().getLoc(); if (parseAbsoluteExpression(FillExpr)) return true; @@ -2410,11 +2559,25 @@ bool AsmParser::parseDirectiveFill() { } } - if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) - return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); + if (FillSize < 0) { + Warning(SizeLoc, "'.fill' directive with negative size has no effect"); + NumValues = 0; + } + if (FillSize > 8) { + Warning(SizeLoc, "'.fill' directive with size greater than 8 has been truncated to 8"); + FillSize = 8; + } - for (uint64_t i = 0, e = NumValues; i != e; ++i) - getStreamer().EmitIntValue(FillExpr, FillSize); + if (!isUInt<32>(FillExpr) && FillSize > 4) + Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits"); + + int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize; + FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8); + + for (uint64_t i = 0, e = NumValues; i != e; ++i) { + getStreamer().EmitIntValue(FillExpr, NonZeroFillSize); + getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize); + } return false; } @@ -2533,7 +2696,9 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { // Check whether we should use optimal code alignment for this .align // directive. - bool UseCodeAlign = getStreamer().getCurrentSection().first->UseCodeAlign(); + const MCSection *Section = getStreamer().getCurrentSection().first; + assert(Section && "must have section to emit alignment"); + bool UseCodeAlign = Section->UseCodeAlign(); if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && ValueSize == 1 && UseCodeAlign) { getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); @@ -2597,7 +2762,8 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { "input can't have .file dwarf directives when -g is " "used to generate dwarf debug info for assembly code"); - if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename)) + if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) == + 0) Error(FileNumberLoc, "file number already allocated"); } @@ -2763,9 +2929,14 @@ bool AsmParser::parseDirectiveCFISections() { } /// parseDirectiveCFIStartProc -/// ::= .cfi_startproc +/// ::= .cfi_startproc [simple] bool AsmParser::parseDirectiveCFIStartProc() { - getStreamer().EmitCFIStartProc(); + StringRef Simple; + if (getLexer().isNot(AsmToken::EndOfStatement)) + if (parseIdentifier(Simple) || Simple != "simple") + return TokError("unexpected token in .cfi_startproc directive"); + + getStreamer().EmitCFIStartProc(!Simple.empty()); return false; } @@ -3058,41 +3229,64 @@ bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) { } /// parseDirectiveMacro -/// ::= .macro name [parameters] +/// ::= .macro name[,] [parameters] bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { StringRef Name; if (parseIdentifier(Name)) return TokError("expected identifier in '.macro' directive"); + if (getLexer().is(AsmToken::Comma)) + Lex(); + MCAsmMacroParameters Parameters; - // Argument delimiter is initially unknown. It will be set by - // parseMacroArgument() - AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; - if (getLexer().isNot(AsmToken::EndOfStatement)) { - for (;;) { - MCAsmMacroParameter Parameter; - if (parseIdentifier(Parameter.first)) - return TokError("expected identifier in '.macro' directive"); + while (getLexer().isNot(AsmToken::EndOfStatement)) { + MCAsmMacroParameter Parameter; + if (parseIdentifier(Parameter.Name)) + return TokError("expected identifier in '.macro' directive"); + + if (Lexer.is(AsmToken::Colon)) { + Lex(); // consume ':' + + SMLoc QualLoc; + StringRef Qualifier; + + QualLoc = Lexer.getLoc(); + if (parseIdentifier(Qualifier)) + return Error(QualLoc, "missing parameter qualifier for " + "'" + Parameter.Name + "' in macro '" + Name + "'"); + + if (Qualifier == "req") + Parameter.Required = true; + else + return Error(QualLoc, Qualifier + " is not a valid parameter qualifier " + "for '" + Parameter.Name + "' in macro '" + Name + "'"); + } - if (getLexer().is(AsmToken::Equal)) { - Lex(); - if (parseMacroArgument(Parameter.second, ArgumentDelimiter)) - return true; - } + if (getLexer().is(AsmToken::Equal)) { + Lex(); - Parameters.push_back(Parameter); + SMLoc ParamLoc; - if (getLexer().is(AsmToken::Comma)) - Lex(); - else if (getLexer().is(AsmToken::EndOfStatement)) - break; + ParamLoc = Lexer.getLoc(); + if (parseMacroArgument(Parameter.Value)) + return true; + + if (Parameter.Required) + Warning(ParamLoc, "pointless default value for required parameter " + "'" + Parameter.Name + "' in macro '" + Name + "'"); } + + Parameters.push_back(Parameter); + + if (getLexer().is(AsmToken::Comma)) + Lex(); } // Eat the end of statement. Lex(); AsmToken EndToken, StartToken = getTok(); + unsigned MacroDepth = 0; // Lex the macro definition. for (;;) { @@ -3101,15 +3295,25 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { return Error(DirectiveLoc, "no matching '.endmacro' in definition"); // Otherwise, check whether we have reach the .endmacro. - if (getLexer().is(AsmToken::Identifier) && - (getTok().getIdentifier() == ".endm" || - getTok().getIdentifier() == ".endmacro")) { - EndToken = getTok(); - Lex(); - if (getLexer().isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in '" + EndToken.getIdentifier() + - "' directive"); - break; + if (getLexer().is(AsmToken::Identifier)) { + if (getTok().getIdentifier() == ".endm" || + getTok().getIdentifier() == ".endmacro") { + if (MacroDepth == 0) { // Outermost macro. + EndToken = getTok(); + Lex(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '" + EndToken.getIdentifier() + + "' directive"); + break; + } else { + // Otherwise we just found the end of an inner macro. + --MacroDepth; + } + } else if (getTok().getIdentifier() == ".macro") { + // We allow nested macros. Those aren't instantiated until the outermost + // macro is expanded so just ignore them for now. + ++MacroDepth; + } } // Otherwise, scan til the end of the statement. @@ -3132,19 +3336,19 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { /// /// With the support added for named parameters there may be code out there that /// is transitioning from positional parameters. In versions of gas that did -/// not support named parameters they would be ignored on the macro defintion. +/// not support named parameters they would be ignored on the macro definition. /// But to support both styles of parameters this is not possible so if a macro -/// defintion has named parameters but does not use them and has what appears +/// definition has named parameters but does not use them and has what appears /// to be positional parameters, strings like $1, $2, ... and $n, then issue a /// warning that the positional parameter found in body which have no effect. /// Hoping the developer will either remove the named parameters from the macro -/// definiton so the positional parameters get used if that was what was +/// definition so the positional parameters get used if that was what was /// intended or change the macro to use the named parameters. It is possible /// this warning will trigger when the none of the named parameters are used /// and the strings like $1 are infact to simply to be passed trough unchanged. void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, - MCAsmMacroParameters Parameters) { + ArrayRef<MCAsmMacroParameter> Parameters) { // If this macro is not defined with named parameters the warning we are // checking for here doesn't apply. unsigned NParameters = Parameters.size(); @@ -3206,7 +3410,7 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Argument(Begin, I - (Pos + 1)); unsigned Index = 0; for (; Index < NParameters; ++Index) - if (Parameters[Index].first == Argument) + if (Parameters[Index].Name == Argument) break; if (Index == NParameters) { @@ -3570,6 +3774,7 @@ bool AsmParser::parseDirectiveIncbin() { /// parseDirectiveIf /// ::= .if expression +/// ::= .ifne expression bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; @@ -3617,6 +3822,7 @@ bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { /// parseDirectiveIfc /// ::= .ifc string1, string2 +/// ::= .ifnc string1, string2 bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; @@ -3638,13 +3844,50 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { Lex(); - TheCondState.CondMet = ExpectEqual == (Str1 == Str2); + TheCondState.CondMet = ExpectEqual == (Str1.trim() == Str2.trim()); TheCondState.Ignore = !TheCondState.CondMet; } return false; } +/// parseDirectiveIfeqs +/// ::= .ifeqs string1, string2 +bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { + if (Lexer.isNot(AsmToken::String)) { + TokError("expected string parameter for '.ifeqs' directive"); + eatToEndOfStatement(); + return true; + } + + StringRef String1 = getTok().getStringContents(); + Lex(); + + if (Lexer.isNot(AsmToken::Comma)) { + TokError("expected comma after first string for '.ifeqs' directive"); + eatToEndOfStatement(); + return true; + } + + Lex(); + + if (Lexer.isNot(AsmToken::String)) { + TokError("expected string parameter for '.ifeqs' directive"); + eatToEndOfStatement(); + return true; + } + + StringRef String2 = getTok().getStringContents(); + Lex(); + + TheCondStack.push_back(TheCondState); + TheCondState.TheCond = AsmCond::IfCond; + TheCondState.CondMet = String1 == String2; + TheCondState.Ignore = !TheCondState.CondMet; + + return false; +} + /// parseDirectiveIfdef /// ::= .ifdef symbol bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { @@ -3727,6 +3970,50 @@ bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) { return false; } +/// parseDirectiveEnd +/// ::= .end +bool AsmParser::parseDirectiveEnd(SMLoc DirectiveLoc) { + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.end' directive"); + + Lex(); + + while (Lexer.isNot(AsmToken::Eof)) + Lex(); + + return false; +} + +/// parseDirectiveError +/// ::= .err +/// ::= .error [string] +bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) { + if (!TheCondStack.empty()) { + if (TheCondStack.back().Ignore) { + eatToEndOfStatement(); + return false; + } + } + + if (!WithMessage) + return Error(L, ".err encountered"); + + StringRef Message = ".error directive invoked in source file"; + if (Lexer.isNot(AsmToken::EndOfStatement)) { + if (Lexer.isNot(AsmToken::String)) { + TokError(".error argument must be a string"); + eatToEndOfStatement(); + return true; + } + + Message = getTok().getStringContents(); + Lex(); + } + + Error(L, Message); + return true; +} + /// parseDirectiveEndIf /// ::= .endif bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { @@ -3762,6 +4049,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".4byte"] = DK_4BYTE; DirectiveKindMap[".quad"] = DK_QUAD; DirectiveKindMap[".8byte"] = DK_8BYTE; + DirectiveKindMap[".octa"] = DK_OCTA; DirectiveKindMap[".single"] = DK_SINGLE; DirectiveKindMap[".float"] = DK_FLOAT; DirectiveKindMap[".double"] = DK_DOUBLE; @@ -3796,6 +4084,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".code16"] = DK_CODE16; DirectiveKindMap[".code16gcc"] = DK_CODE16GCC; DirectiveKindMap[".rept"] = DK_REPT; + DirectiveKindMap[".rep"] = DK_REPT; DirectiveKindMap[".irp"] = DK_IRP; DirectiveKindMap[".irpc"] = DK_IRPC; DirectiveKindMap[".endr"] = DK_ENDR; @@ -3803,15 +4092,18 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK; DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK; DirectiveKindMap[".if"] = DK_IF; + DirectiveKindMap[".ifne"] = DK_IFNE; DirectiveKindMap[".ifb"] = DK_IFB; DirectiveKindMap[".ifnb"] = DK_IFNB; DirectiveKindMap[".ifc"] = DK_IFC; + DirectiveKindMap[".ifeqs"] = DK_IFEQS; DirectiveKindMap[".ifnc"] = DK_IFNC; DirectiveKindMap[".ifdef"] = DK_IFDEF; DirectiveKindMap[".ifndef"] = DK_IFNDEF; DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF; DirectiveKindMap[".elseif"] = DK_ELSEIF; DirectiveKindMap[".else"] = DK_ELSE; + DirectiveKindMap[".end"] = DK_END; DirectiveKindMap[".endif"] = DK_ENDIF; DirectiveKindMap[".skip"] = DK_SKIP; DirectiveKindMap[".space"] = DK_SPACE; @@ -3847,6 +4139,8 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".endm"] = DK_ENDM; DirectiveKindMap[".endmacro"] = DK_ENDMACRO; DirectiveKindMap[".purgem"] = DK_PURGEM; + DirectiveKindMap[".err"] = DK_ERR; + DirectiveKindMap[".error"] = DK_ERROR; } MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { @@ -3888,9 +4182,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); // We Are Anonymous. - StringRef Name; - MCAsmMacroParameters Parameters; - MacroLikeBodies.push_back(MCAsmMacro(Name, Body, Parameters)); + MacroLikeBodies.push_back(MCAsmMacro(StringRef(), Body, None)); return &MacroLikeBodies.back(); } @@ -3913,16 +4205,25 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, Lex(); } -bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) { +/// parseDirectiveRept +/// ::= .rep | .rept count +bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) { + const MCExpr *CountExpr; + SMLoc CountLoc = getTok().getLoc(); + if (parseExpression(CountExpr)) + return true; + int64_t Count; - if (parseAbsoluteExpression(Count)) - return TokError("unexpected token in '.rept' directive"); + if (!CountExpr->EvaluateAsAbsolute(Count)) { + eatToEndOfStatement(); + return Error(CountLoc, "unexpected token in '" + Dir + "' directive"); + } if (Count < 0) - return TokError("Count is negative"); + return Error(CountLoc, "Count is negative"); if (Lexer.isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in '.rept' directive"); + return TokError("unexpected token in '" + Dir + "' directive"); // Eat the end of statement. Lex(); @@ -3935,11 +4236,9 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) { // Macro instantiation is lexical, unfortunately. We construct a new buffer // to hold the macro body with substitutions. SmallString<256> Buf; - MCAsmMacroParameters Parameters; - MCAsmMacroArguments A; raw_svector_ostream OS(Buf); while (Count--) { - if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc())) + if (expandMacro(OS, M->Body, None, None, getTok().getLoc())) return true; } instantiateMacroLikeBody(M, DirectiveLoc, OS); @@ -3950,14 +4249,11 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) { /// parseDirectiveIrp /// ::= .irp symbol,values bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { - MCAsmMacroParameters Parameters; MCAsmMacroParameter Parameter; - if (parseIdentifier(Parameter.first)) + if (parseIdentifier(Parameter.Name)) return TokError("expected identifier in '.irp' directive"); - Parameters.push_back(Parameter); - if (Lexer.isNot(AsmToken::Comma)) return TokError("expected comma in '.irp' directive"); @@ -3981,10 +4277,7 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { raw_svector_ostream OS(Buf); for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { - MCAsmMacroArguments Args; - Args.push_back(*i); - - if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) + if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc())) return true; } @@ -3996,14 +4289,11 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { /// parseDirectiveIrpc /// ::= .irpc symbol,values bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { - MCAsmMacroParameters Parameters; MCAsmMacroParameter Parameter; - if (parseIdentifier(Parameter.first)) + if (parseIdentifier(Parameter.Name)) return TokError("expected identifier in '.irpc' directive"); - Parameters.push_back(Parameter); - if (Lexer.isNot(AsmToken::Comma)) return TokError("expected comma in '.irpc' directive"); @@ -4030,15 +4320,11 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { raw_svector_ostream OS(Buf); StringRef Values = A.front().front().getString(); - std::size_t I, End = Values.size(); - for (I = 0; I < End; ++I) { + for (std::size_t I = 0, End = Values.size(); I != End; ++I) { MCAsmMacroArgument Arg; Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1))); - MCAsmMacroArguments Args; - Args.push_back(Arg); - - if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) + if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc())) return true; } @@ -4192,6 +4478,11 @@ bool AsmParser::parseMSInlineAsm( 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]); } // Set the number of Outputs and Inputs. @@ -4292,6 +4583,10 @@ bool AsmParser::parseMSInlineAsm( break; } case AOK_DotOperator: + // Insert the dot if the user omitted it. + OS.flush(); + if (AsmStringIR.back() != '.') + OS << '.'; OS << (*I).Val; break; } diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index d8343a3..76d3f81 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -42,7 +42,7 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseSectionName(StringRef &SectionName); bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags); - virtual void Initialize(MCAsmParser &Parser) { + void Initialize(MCAsmParser &Parser) override { // Call the base implementation. MCAsmParserExtension::Initialize(Parser); @@ -55,6 +55,7 @@ class COFFAsmParser : public MCAsmParserExtension { addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32"); + addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce"); // Win64 EH directives. @@ -115,6 +116,7 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseDirectiveType(StringRef, SMLoc); bool ParseDirectiveEndef(StringRef, SMLoc); bool ParseDirectiveSecRel32(StringRef, SMLoc); + bool ParseDirectiveSecIdx(StringRef, SMLoc); bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, const MCSectionCOFF *&Assoc); bool ParseDirectiveLinkOnce(StringRef, SMLoc); @@ -432,7 +434,7 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) { bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { StringRef SymbolID; if (getParser().parseIdentifier(SymbolID)) - return true; + return TokError("expected identifier in directive"); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); @@ -444,6 +446,21 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { return false; } +bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) { + StringRef SymbolID; + if (getParser().parseIdentifier(SymbolID)) + return TokError("expected identifier in directive"); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); + + Lex(); + getStreamer().EmitCOFFSectionIndex(Symbol); + return false; +} + /// ::= [ identifier [ identifier ] ] bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, const MCSectionCOFF *&Assoc) { diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 4c9bafa..0856b6e 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -33,339 +33,343 @@ class DarwinAsmParser : public MCAsmParserExtension { getParser().addDirectiveHandler(Directive, Handler); } - bool ParseSectionSwitch(const char *Segment, const char *Section, + bool parseSectionSwitch(const char *Segment, const char *Section, unsigned TAA = 0, unsigned ImplicitAlign = 0, unsigned StubSize = 0); public: DarwinAsmParser() {} - virtual void Initialize(MCAsmParser &Parser) { + void Initialize(MCAsmParser &Parser) override { // Call the base implementation. this->MCAsmParserExtension::Initialize(Parser); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>( ".indirect_symbol"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>( ".subsections_via_symbols"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section"); + addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>( ".pushsection"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>( + addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>( ".popsection"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>( + addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>( ".secure_log_unique"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>( ".secure_log_reset"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss"); + addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>( ".data_region"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>( ".end_data_region"); // Special section directives. - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveBss>(".bss"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss"); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const"); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>( ".const_data"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>( ".constructor"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>( ".cstring"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data"); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>( ".destructor"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld"); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>( ".fvmlib_init0"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>( ".fvmlib_init1"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>( + &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>( ".lazy_symbol_pointer"); - addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>( + addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>( ".linker_option"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>( ".literal16"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>( ".literal4"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>( ".literal8"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>( ".mod_init_func"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>( ".mod_term_func"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>( + &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>( ".non_lazy_symbol_pointer"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>( ".objc_cat_cls_meth"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>( ".objc_cat_inst_meth"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>( ".objc_category"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>( ".objc_class"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>( ".objc_class_names"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>( ".objc_class_vars"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>( ".objc_cls_meth"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>( ".objc_cls_refs"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>( ".objc_inst_meth"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>( + &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>( ".objc_instance_vars"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>( ".objc_message_refs"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>( ".objc_meta_class"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>( + &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>( ".objc_meth_var_names"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>( + &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>( ".objc_meth_var_types"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>( ".objc_module_info"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>( ".objc_protocol"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>( + &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>( ".objc_selector_strs"); addDirectiveHandler< - &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>( + &DarwinAsmParser::parseSectionDirectiveObjCStringObject>( ".objc_string_object"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>( ".objc_symbols"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>( ".picsymbol_stub"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>( ".static_const"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>( ".static_data"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>( ".symbol_stub"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>( + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata"); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text"); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>( ".thread_init_func"); - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv"); - - addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident"); - } - - bool ParseDirectiveDesc(StringRef, SMLoc); - bool ParseDirectiveIndirectSymbol(StringRef, SMLoc); - bool ParseDirectiveDumpOrLoad(StringRef, SMLoc); - bool ParseDirectiveLsym(StringRef, SMLoc); - bool ParseDirectiveLinkerOption(StringRef, SMLoc); - bool ParseDirectiveSection(StringRef, SMLoc); - bool ParseDirectivePushSection(StringRef, SMLoc); - bool ParseDirectivePopSection(StringRef, SMLoc); - bool ParseDirectivePrevious(StringRef, SMLoc); - bool ParseDirectiveSecureLogReset(StringRef, SMLoc); - bool ParseDirectiveSecureLogUnique(StringRef, SMLoc); - bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); - bool ParseDirectiveTBSS(StringRef, SMLoc); - bool ParseDirectiveZerofill(StringRef, SMLoc); - bool ParseDirectiveDataRegion(StringRef, SMLoc); - bool ParseDirectiveDataRegionEnd(StringRef, SMLoc); + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv"); + + addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident"); + addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min"); + addDirectiveHandler<&DarwinAsmParser::parseVersionMin>( + ".macosx_version_min"); + } + + bool parseDirectiveDesc(StringRef, SMLoc); + bool parseDirectiveIndirectSymbol(StringRef, SMLoc); + bool parseDirectiveDumpOrLoad(StringRef, SMLoc); + bool parseDirectiveLsym(StringRef, SMLoc); + bool parseDirectiveLinkerOption(StringRef, SMLoc); + bool parseDirectiveSection(StringRef, SMLoc); + bool parseDirectivePushSection(StringRef, SMLoc); + bool parseDirectivePopSection(StringRef, SMLoc); + bool parseDirectivePrevious(StringRef, SMLoc); + bool parseDirectiveSecureLogReset(StringRef, SMLoc); + bool parseDirectiveSecureLogUnique(StringRef, SMLoc); + bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); + bool parseDirectiveTBSS(StringRef, SMLoc); + bool parseDirectiveZerofill(StringRef, SMLoc); + bool parseDirectiveDataRegion(StringRef, SMLoc); + bool parseDirectiveDataRegionEnd(StringRef, SMLoc); // Named Section Directive - bool ParseSectionDirectiveBss(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__bss"); + bool parseSectionDirectiveBss(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__bss"); } - bool ParseSectionDirectiveConst(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__const"); + bool parseSectionDirectiveConst(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__const"); } - bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__static_const"); + bool parseSectionDirectiveStaticConst(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__static_const"); } - bool ParseSectionDirectiveCString(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__cstring", - MCSectionMachO::S_CSTRING_LITERALS); + bool parseSectionDirectiveCString(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__cstring", + MachO::S_CSTRING_LITERALS); } - bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__literal4", - MCSectionMachO::S_4BYTE_LITERALS, 4); + bool parseSectionDirectiveLiteral4(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__literal4", + MachO::S_4BYTE_LITERALS, 4); } - bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__literal8", - MCSectionMachO::S_8BYTE_LITERALS, 8); + bool parseSectionDirectiveLiteral8(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__literal8", + MachO::S_8BYTE_LITERALS, 8); } - bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__literal16", - MCSectionMachO::S_16BYTE_LITERALS, 16); + bool parseSectionDirectiveLiteral16(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__literal16", + MachO::S_16BYTE_LITERALS, 16); } - bool ParseSectionDirectiveConstructor(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__constructor"); + bool parseSectionDirectiveConstructor(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__constructor"); } - bool ParseSectionDirectiveDestructor(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__destructor"); + bool parseSectionDirectiveDestructor(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__destructor"); } - bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__fvmlib_init0"); + bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__fvmlib_init0"); } - bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__fvmlib_init1"); + bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__fvmlib_init1"); } - bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__symbol_stub", - MCSectionMachO::S_SYMBOL_STUBS | - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__symbol_stub", + MachO::S_SYMBOL_STUBS | + MachO::S_ATTR_PURE_INSTRUCTIONS, // FIXME: Different on PPC and ARM. 0, 16); } - bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT","__picsymbol_stub", - MCSectionMachO::S_SYMBOL_STUBS | - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); + bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT","__picsymbol_stub", + MachO::S_SYMBOL_STUBS | + MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); } - bool ParseSectionDirectiveData(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__data"); + bool parseSectionDirectiveData(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__data"); } - bool ParseSectionDirectiveStaticData(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__static_data"); + bool parseSectionDirectiveStaticData(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__static_data"); } - bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__nl_symbol_ptr", - MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4); + bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__nl_symbol_ptr", + MachO::S_NON_LAZY_SYMBOL_POINTERS, 4); } - bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__la_symbol_ptr", - MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4); + bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__la_symbol_ptr", + MachO::S_LAZY_SYMBOL_POINTERS, 4); } - bool ParseSectionDirectiveDyld(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__dyld"); + bool parseSectionDirectiveDyld(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__dyld"); } - bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__mod_init_func", - MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4); + bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__mod_init_func", + MachO::S_MOD_INIT_FUNC_POINTERS, 4); } - bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__mod_term_func", - MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4); + bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__mod_term_func", + MachO::S_MOD_TERM_FUNC_POINTERS, 4); } - bool ParseSectionDirectiveConstData(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__const"); + bool parseSectionDirectiveConstData(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__const"); } - bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__class", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCClass(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__class", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__meta_class", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__meta_class", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__cat_cls_meth", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__cat_cls_meth", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__cat_inst_meth", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__cat_inst_meth", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__protocol", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__protocol", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__string_object", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__string_object", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__cls_meth", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__cls_meth", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__inst_meth", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__inst_meth", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__cls_refs", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP | - MCSectionMachO::S_LITERAL_POINTERS, 4); + bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__cls_refs", + MachO::S_ATTR_NO_DEAD_STRIP | + MachO::S_LITERAL_POINTERS, 4); } - bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__message_refs", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP | - MCSectionMachO::S_LITERAL_POINTERS, 4); + bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__message_refs", + MachO::S_ATTR_NO_DEAD_STRIP | + MachO::S_LITERAL_POINTERS, 4); } - bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__symbols", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__symbols", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__category", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__category", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__class_vars", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__class_vars", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__instance_vars", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__instance_vars", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__module_info", - MCSectionMachO::S_ATTR_NO_DEAD_STRIP); + bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__module_info", + MachO::S_ATTR_NO_DEAD_STRIP); } - bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__cstring", - MCSectionMachO::S_CSTRING_LITERALS); + bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__cstring", + MachO::S_CSTRING_LITERALS); } - bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__cstring", - MCSectionMachO::S_CSTRING_LITERALS); + bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__cstring", + MachO::S_CSTRING_LITERALS); } - bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__cstring", - MCSectionMachO::S_CSTRING_LITERALS); + bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__cstring", + MachO::S_CSTRING_LITERALS); } - bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { - return ParseSectionSwitch("__OBJC", "__selector_strs", - MCSectionMachO::S_CSTRING_LITERALS); + bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { + return parseSectionSwitch("__OBJC", "__selector_strs", + MachO::S_CSTRING_LITERALS); } - bool ParseSectionDirectiveTData(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__thread_data", - MCSectionMachO::S_THREAD_LOCAL_REGULAR); + bool parseSectionDirectiveTData(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__thread_data", + MachO::S_THREAD_LOCAL_REGULAR); } - bool ParseSectionDirectiveText(StringRef, SMLoc) { - return ParseSectionSwitch("__TEXT", "__text", - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); + bool parseSectionDirectiveText(StringRef, SMLoc) { + return parseSectionSwitch("__TEXT", "__text", + MachO::S_ATTR_PURE_INSTRUCTIONS); } - bool ParseSectionDirectiveTLV(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__thread_vars", - MCSectionMachO::S_THREAD_LOCAL_VARIABLES); + bool parseSectionDirectiveTLV(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__thread_vars", + MachO::S_THREAD_LOCAL_VARIABLES); } - bool ParseSectionDirectiveIdent(StringRef, SMLoc) { + bool parseSectionDirectiveIdent(StringRef, SMLoc) { // Darwin silently ignores the .ident directive. getParser().eatToEndOfStatement(); return false; } - bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { - return ParseSectionSwitch("__DATA", "__thread_init", - MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); + bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__thread_init", + MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); } + bool parseVersionMin(StringRef, SMLoc); }; } // end anonymous namespace -bool DarwinAsmParser::ParseSectionSwitch(const char *Segment, +bool DarwinAsmParser::parseSectionSwitch(const char *Segment, const char *Section, unsigned TAA, unsigned Align, unsigned StubSize) { @@ -374,7 +378,7 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment, Lex(); // FIXME: Arch specific. - bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS; + bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; getStreamer().SwitchSection(getContext().getMachOSection( Segment, Section, TAA, StubSize, isText ? SectionKind::getText() @@ -389,14 +393,14 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment, // is no good reason for someone to intentionally emit incorrectly sized // values into the implicitly aligned sections. if (Align) - getStreamer().EmitValueToAlignment(Align, 0, 1, 0); + getStreamer().EmitValueToAlignment(Align); return false; } -/// ParseDirectiveDesc +/// parseDirectiveDesc /// ::= .desc identifier , expression -bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { StringRef Name; if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); @@ -423,15 +427,15 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) { return false; } -/// ParseDirectiveIndirectSymbol +/// parseDirectiveIndirectSymbol /// ::= .indirect_symbol identifier -bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { +bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { const MCSectionMachO *Current = static_cast<const MCSectionMachO*>( getStreamer().getCurrentSection().first); - unsigned SectionType = Current->getType(); - if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS && - SectionType != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && - SectionType != MCSectionMachO::S_SYMBOL_STUBS) + MachO::SectionType SectionType = Current->getType(); + if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && + SectionType != MachO::S_LAZY_SYMBOL_POINTERS && + SectionType != MachO::S_SYMBOL_STUBS) return Error(Loc, "indirect symbol not in a symbol pointer or stub " "section"); @@ -456,9 +460,9 @@ bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { return false; } -/// ParseDirectiveDumpOrLoad +/// parseDirectiveDumpOrLoad /// ::= ( .dump | .load ) "filename" -bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive, +bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, SMLoc IDLoc) { bool IsDump = Directive == ".dump"; if (getLexer().isNot(AsmToken::String)) @@ -481,7 +485,7 @@ bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive, /// ParseDirectiveLinkerOption /// ::= .linker_option "string" ( , "string" )* -bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) { +bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { SmallVector<std::string, 4> Args; for (;;) { if (getLexer().isNot(AsmToken::String)) @@ -506,9 +510,9 @@ bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) { return false; } -/// ParseDirectiveLsym +/// parseDirectiveLsym /// ::= .lsym identifier , expression -bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { StringRef Name; if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); @@ -536,9 +540,9 @@ bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) { return TokError("directive '.lsym' is unsupported"); } -/// ParseDirectiveSection: +/// parseDirectiveSection: /// ::= .section identifier (',' identifier)* -bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { SMLoc Loc = getLexer().getLoc(); StringRef SectionName; @@ -585,10 +589,10 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) { /// ParseDirectivePushSection: /// ::= .pushsection identifier (',' identifier)* -bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) { +bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { getStreamer().PushSection(); - if (ParseDirectiveSection(S, Loc)) { + if (parseDirectiveSection(S, Loc)) { getStreamer().PopSection(); return true; } @@ -598,7 +602,7 @@ bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) { /// ParseDirectivePopSection: /// ::= .popsection -bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { if (!getStreamer().PopSection()) return TokError(".popsection without corresponding .pushsection"); return false; @@ -606,7 +610,7 @@ bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { /// ParseDirectivePrevious: /// ::= .previous -bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { +bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); if (PreviousSection.first == NULL) return TokError(".previous without corresponding .section"); @@ -616,7 +620,7 @@ bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { /// ParseDirectiveSecureLogUnique /// ::= .secure_log_unique ... message ... -bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { +bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { StringRef LogMessage = getParser().parseStringToEndOfStatement(); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.secure_log_unique' directive"); @@ -634,7 +638,8 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { raw_ostream *OS = getContext().getSecureLog(); if (OS == NULL) { std::string Err; - OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append); + OS = new raw_fd_ostream(SecureLogFile, Err, + sys::fs::F_Append | sys::fs::F_Text); if (!Err.empty()) { delete OS; return Error(IDLoc, Twine("can't open secure log file: ") + @@ -656,7 +661,7 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { /// ParseDirectiveSecureLogReset /// ::= .secure_log_reset -bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { +bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.secure_log_reset' directive"); @@ -667,9 +672,9 @@ bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { return false; } -/// ParseDirectiveSubsectionsViaSymbols +/// parseDirectiveSubsectionsViaSymbols /// ::= .subsections_via_symbols -bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.subsections_via_symbols' directive"); @@ -682,7 +687,7 @@ bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { /// ParseDirectiveTBSS /// ::= .tbss identifier, size, align -bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { SMLoc IDLoc = getLexer().getLoc(); StringRef Name; if (getParser().parseIdentifier(Name)) @@ -728,7 +733,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) { getStreamer().EmitTBSSSymbol(getContext().getMachOSection( "__DATA", "__thread_bss", - MCSectionMachO::S_THREAD_LOCAL_ZEROFILL, + MachO::S_THREAD_LOCAL_ZEROFILL, 0, SectionKind::getThreadBSS()), Sym, Size, 1 << Pow2Alignment); @@ -738,7 +743,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) { /// ParseDirectiveZerofill /// ::= .zerofill segname , sectname [, identifier , size_expression [ /// , align_expression ]] -bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { StringRef Segment; if (getParser().parseIdentifier(Segment)) return TokError("expected segment name after '.zerofill' directive"); @@ -757,7 +762,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) { if (getLexer().is(AsmToken::EndOfStatement)) { // Create the zerofill section but no symbol getStreamer().EmitZerofill(getContext().getMachOSection( - Segment, Section, MCSectionMachO::S_ZEROFILL, + Segment, Section, MachO::S_ZEROFILL, 0, SectionKind::getBSS())); return false; } @@ -815,7 +820,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) { // // FIXME: Arch specific. getStreamer().EmitZerofill(getContext().getMachOSection( - Segment, Section, MCSectionMachO::S_ZEROFILL, + Segment, Section, MachO::S_ZEROFILL, 0, SectionKind::getBSS()), Sym, Size, 1 << Pow2Alignment); @@ -824,7 +829,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) { /// ParseDirectiveDataRegion /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ] -bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { if (getLexer().is(AsmToken::EndOfStatement)) { Lex(); getStreamer().EmitDataRegion(MCDR_DataRegion); @@ -849,7 +854,7 @@ bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) { /// ParseDirectiveDataRegionEnd /// ::= .end_data_region -bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) { +bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.end_data_region' directive"); @@ -858,6 +863,50 @@ bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) { return false; } +/// parseVersionMin +/// ::= .ios_version_min major,minor[,update] +/// ::= .macosx_version_min major,minor[,update] +bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) { + int64_t Major = 0, Minor = 0, Update = 0; + int Kind = StringSwitch<int>(Directive) + .Case(".ios_version_min", MCVM_IOSVersionMin) + .Case(".macosx_version_min", MCVM_OSXVersionMin); + // Get the major version number. + if (getLexer().isNot(AsmToken::Integer)) + return TokError("invalid OS major version number"); + Major = getLexer().getTok().getIntVal(); + if (Major > 65535 || Major <= 0) + return TokError("invalid OS major version number"); + Lex(); + if (getLexer().isNot(AsmToken::Comma)) + return TokError("minor OS version number required, comma expected"); + Lex(); + // Get the minor version number. + if (getLexer().isNot(AsmToken::Integer)) + return TokError("invalid OS minor version number"); + Minor = getLexer().getTok().getIntVal(); + if (Minor > 255 || Minor < 0) + return TokError("invalid OS minor version number"); + Lex(); + // Get the update level, if specified + if (getLexer().isNot(AsmToken::EndOfStatement)) { + if (getLexer().isNot(AsmToken::Comma)) + return TokError("invalid update specifier, comma expected"); + Lex(); + if (getLexer().isNot(AsmToken::Integer)) + return TokError("invalid OS update number"); + Update = getLexer().getTok().getIntVal(); + if (Update > 255 || Update < 0) + return TokError("invalid OS update number"); + Lex(); + } + + // We've parsed a correct version specifier, so send it to the streamer. + getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update); + + return false; +} + namespace llvm { MCAsmParserExtension *createDarwinAsmParser() { diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 8807975..d79dd67 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -37,7 +37,7 @@ class ELFAsmParser : public MCAsmParserExtension { public: ELFAsmParser() { BracketExpressionsSupported = true; } - virtual void Initialize(MCAsmParser &Parser) { + void Initialize(MCAsmParser &Parser) override { // Call the base implementation. this->MCAsmParserExtension::Initialize(Parser); @@ -151,6 +151,7 @@ public: private: bool ParseSectionName(StringRef &SectionName); bool ParseSectionArguments(bool IsPush); + unsigned parseSunStyleSectionFlags(); }; } @@ -268,11 +269,37 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { return false; } -static SectionKind computeSectionKind(unsigned Flags) { +static SectionKind computeSectionKind(unsigned Flags, unsigned ElemSize) { if (Flags & ELF::SHF_EXECINSTR) return SectionKind::getText(); if (Flags & ELF::SHF_TLS) return SectionKind::getThreadData(); + if (Flags & ELF::SHF_MERGE) { + if (Flags & ELF::SHF_STRINGS) { + switch (ElemSize) { + default: + break; + case 1: + return SectionKind::getMergeable1ByteCString(); + case 2: + return SectionKind::getMergeable2ByteCString(); + case 4: + return SectionKind::getMergeable4ByteCString(); + } + } else { + switch (ElemSize) { + default: + break; + case 4: + return SectionKind::getMergeableConst4(); + case 8: + return SectionKind::getMergeableConst8(); + case 16: + return SectionKind::getMergeableConst16(); + } + } + } + return SectionKind::getDataRel(); } @@ -322,6 +349,36 @@ static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { return flags; } +unsigned ELFAsmParser::parseSunStyleSectionFlags() { + unsigned flags = 0; + while (getLexer().is(AsmToken::Hash)) { + Lex(); // Eat the #. + + if (!getLexer().is(AsmToken::Identifier)) + return -1U; + + StringRef flagId = getTok().getIdentifier(); + if (flagId == "alloc") + flags |= ELF::SHF_ALLOC; + else if (flagId == "execinstr") + flags |= ELF::SHF_EXECINSTR; + else if (flagId == "write") + flags |= ELF::SHF_WRITE; + else if (flagId == "tls") + flags |= ELF::SHF_TLS; + else + return -1U; + + Lex(); // Eat the flag. + + if (!getLexer().is(AsmToken::Comma)) + break; + Lex(); // Eat the comma. + } + return flags; +} + + bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { getStreamer().PushSection(); @@ -374,14 +431,20 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) { goto EndStmt; Lex(); } - - if (getLexer().isNot(AsmToken::String)) - return TokError("expected string in directive"); - StringRef FlagsStr = getTok().getStringContents(); - Lex(); + unsigned extraFlags; + + if (getLexer().isNot(AsmToken::String)) { + if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() + || getLexer().isNot(AsmToken::Hash)) + return TokError("expected string in directive"); + extraFlags = parseSunStyleSectionFlags(); + } else { + StringRef FlagsStr = getTok().getStringContents(); + Lex(); + extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); + } - unsigned extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); if (extraFlags == -1U) return TokError("unknown flag"); Flags |= extraFlags; @@ -481,7 +544,7 @@ EndStmt: } } - SectionKind Kind = computeSectionKind(Flags); + SectionKind Kind = computeSectionKind(Flags, Size); getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type, Flags, Kind, Size, GroupName), @@ -590,7 +653,14 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::Comma)) return TokError("expected a comma"); + // ARM assembly uses @ for a comment... + // except when parsing the second parameter of the .symver directive. + // Force the next symbol to allow @ in the identifier, which is + // required for this directive and then reset it to its initial state. + const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); + getLexer().setAllowAtInIdentifier(true); Lex(); + getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); StringRef AliasName; if (getParser().parseIdentifier(AliasName)) |