diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser')
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/AsmLexer.cpp | 58 | ||||
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/AsmParser.cpp | 1658 | ||||
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp | 284 | ||||
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp | 43 | ||||
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp | 121 |
5 files changed, 1307 insertions, 857 deletions
diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp index c1c594a..b49dd01 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -91,9 +91,56 @@ AsmToken AsmLexer::LexFloatLiteral() { StringRef(TokStart, CurPtr - TokStart)); } -/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]* +/// LexHexFloatLiteral matches essentially (.[0-9a-fA-F]*)?[pP][+-]?[0-9a-fA-F]+ +/// while making sure there are enough actual digits around for the constant to +/// be valid. +/// +/// The leading "0x[0-9a-fA-F]*" (i.e. integer part) has already been consumed +/// before we get here. +AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) { + assert((*CurPtr == 'p' || *CurPtr == 'P' || *CurPtr == '.') && + "unexpected parse state in floating hex"); + bool NoFracDigits = true; + + // Skip the fractional part if there is one + if (*CurPtr == '.') { + ++CurPtr; + + const char *FracStart = CurPtr; + while (isxdigit(*CurPtr)) + ++CurPtr; + + NoFracDigits = CurPtr == FracStart; + } + + if (NoIntDigits && NoFracDigits) + return ReturnError(TokStart, "invalid hexadecimal floating-point constant: " + "expected at least one significand digit"); + + // Make sure we do have some kind of proper exponent part + if (*CurPtr != 'p' && *CurPtr != 'P') + return ReturnError(TokStart, "invalid hexadecimal floating-point constant: " + "expected exponent part 'p'"); + ++CurPtr; + + if (*CurPtr == '+' || *CurPtr == '-') + ++CurPtr; + + // N.b. exponent digits are *not* hex + const char *ExpStart = CurPtr; + while (isdigit(*CurPtr)) + ++CurPtr; + + if (CurPtr == ExpStart) + return ReturnError(TokStart, "invalid hexadecimal floating-point constant: " + "expected at least one exponent digit"); + + return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart)); +} + +/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@?]* static bool IsIdentifierChar(char c) { - return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@'; + return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@' || c == '?'; } AsmToken AsmLexer::LexIdentifier() { // Check for floating point literals. @@ -265,7 +312,12 @@ AsmToken AsmLexer::LexDigit() { while (isxdigit(CurPtr[0])) ++CurPtr; - // Requires at least one hex digit. + // "0x.0p0" is valid, and "0x0p0" (but not "0xp0" for example, which will be + // diagnosed by LexHexFloatLiteral). + if (CurPtr[0] == '.' || CurPtr[0] == 'p' || CurPtr[0] == 'P') + return LexHexFloatLiteral(NumStart == CurPtr); + + // Otherwise requires at least one hex digit. if (CurPtr == NumStart) return ReturnError(CurPtr-2, "invalid hexadecimal number"); diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index edefdb4..a91bd93 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -94,13 +94,13 @@ public: }; struct ParseStatementInfo { - /// ParsedOperands - The parsed operands from the last parsed statement. + /// \brief The parsed operands from the last parsed statement. SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; - /// Opcode - The opcode from the last parsed instruction. + /// \brief The opcode from the last parsed instruction. unsigned Opcode; - /// Error - Was there an error parsing the inline assembly? + /// \brief Was there an error parsing the inline assembly? bool ParseError; SmallVectorImpl<AsmRewrite> *AsmRewrites; @@ -138,17 +138,20 @@ private: AsmCond TheCondState; std::vector<AsmCond> TheCondStack; - /// ExtensionDirectiveMap - maps directive names to handler methods in parser + /// \brief maps directive names to handler methods in parser /// extensions. Extensions register themselves in this map by calling /// addDirectiveHandler. StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap; - /// MacroMap - Map of currently defined macros. + /// \brief Map of currently defined macros. StringMap<MCAsmMacro*> MacroMap; - /// ActiveMacros - Stack of active macro instantiations. + /// \brief Stack of active macro instantiations. std::vector<MacroInstantiation*> ActiveMacros; + /// \brief List of bodies of anonymous macros. + std::deque<MCAsmMacro> MacroLikeBodies; + /// Boolean tracking whether macro substitution is enabled. unsigned MacrosEnabledFlag : 1; @@ -160,14 +163,21 @@ private: int64_t CppHashLineNumber; SMLoc CppHashLoc; int CppHashBuf; + /// When generating dwarf for assembly source files we need to calculate the + /// logical line number based on the last parsed cpp hash file line comment + /// and current line. Since this is slow and messes up the SourceMgr's + /// cache we save the last info we queried with SrcMgr.FindLineNumber(). + SMLoc LastQueryIDLoc; + int LastQueryBuffer; + unsigned LastQueryLine; /// AssemblerDialect. ~OU means unset value and use value provided by MAI. unsigned AssemblerDialect; - /// IsDarwin - is Darwin compatibility enabled? + /// \brief is Darwin compatibility enabled? bool IsDarwin; - /// ParsingInlineAsm - Are we parsing ms-style inline assembly? + /// \brief Are we parsing ms-style inline assembly? bool ParsingInlineAsm; public: @@ -225,7 +235,7 @@ public: virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc); virtual bool parseAbsoluteExpression(int64_t &Res); - /// parseIdentifier - Parse an identifier or string (as a quoted identifier) + /// \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(); @@ -235,11 +245,11 @@ public: private: - bool ParseStatement(ParseStatementInfo &Info); - void EatToEndOfLine(); - bool ParseCppHashLineFilenameComment(const SMLoc &L); + bool parseStatement(ParseStatementInfo &Info); + void eatToEndOfLine(); + bool parseCppHashLineFilenameComment(const SMLoc &L); - void CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, + void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, MCAsmMacroParameters Parameters); bool expandMacro(raw_svector_ostream &OS, StringRef Body, const MCAsmMacroParameters &Parameters, @@ -247,55 +257,56 @@ private: const SMLoc &L); /// \brief Are macros enabled in the parser? - bool MacrosEnabled() {return MacrosEnabledFlag;} + bool areMacrosEnabled() {return MacrosEnabledFlag;} /// \brief Control a flag in the parser that enables or disables macros. - void SetMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;} + void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;} /// \brief Lookup a previously defined macro. /// \param Name Macro name. /// \returns Pointer to macro. NULL if no such macro was defined. - const MCAsmMacro* LookupMacro(StringRef Name); + const MCAsmMacro* lookupMacro(StringRef Name); /// \brief Define a new macro with the given name and information. - void DefineMacro(StringRef Name, const MCAsmMacro& Macro); + void defineMacro(StringRef Name, const MCAsmMacro& Macro); /// \brief Undefine a macro. If no such macro was defined, it's a no-op. - void UndefineMacro(StringRef Name); + void undefineMacro(StringRef Name); /// \brief Are we inside a macro instantiation? - bool InsideMacroInstantiation() {return !ActiveMacros.empty();} + bool isInsideMacroInstantiation() {return !ActiveMacros.empty();} - /// \brief Handle entry to macro instantiation. + /// \brief Handle entry to macro instantiation. /// /// \param M The macro. /// \param NameLoc Instantiation location. - bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc); + bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc); /// \brief Handle exit from macro instantiation. - void HandleMacroExit(); + 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, + bool parseMacroArgument(MCAsmMacroArgument &MA, AsmToken::TokenKind &ArgumentDelimiter); /// \brief Parse all macro arguments for a given macro. - bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); + bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); - void PrintMacroInstantiations(); - void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, + void printMacroInstantiations(); + void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges = None) const { SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges); } static void DiagHandler(const SMDiagnostic &Diag, void *Context); - /// EnterIncludeFile - Enter the specified file. This returns true on failure. - bool EnterIncludeFile(const std::string &Filename); - /// ProcessIncbinFile - Process the specified file for the .incbin directive. + /// \brief Enter the specified file. This returns true on failure. + bool enterIncludeFile(const std::string &Filename); + + /// \brief Process the specified file for the .incbin directive. /// This returns true on failure. - bool ProcessIncbinFile(const std::string &Filename); + bool processIncbinFile(const std::string &Filename); /// \brief Reset the current lexer position to that given by \p Loc. The /// current token is not set; clients should ensure Lex() is called @@ -303,7 +314,7 @@ private: /// /// \param InBuffer If not -1, should be the known buffer id that contains the /// location. - void JumpToLoc(SMLoc Loc, int InBuffer=-1); + void jumpToLoc(SMLoc Loc, int InBuffer=-1); /// \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 @@ -312,17 +323,16 @@ private: /// \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. - StringRef ParseStringToComma(); + StringRef parseStringToComma(); - bool ParseAssignment(StringRef Name, bool allow_redef, + bool parseAssignment(StringRef Name, bool allow_redef, bool NoDeadStrip = false); - bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); - bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); - bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); - bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); + bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); + bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); + bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); - bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); + bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc); // Generic (target and platform independent) directive parsing. enum DirectiveKind { @@ -332,7 +342,7 @@ private: 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, DK_INDIRECT_SYMBOL, + DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN, DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, @@ -345,112 +355,113 @@ private: DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA, DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE, DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED, - DK_CFI_REGISTER, + 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 }; - /// DirectiveKindMap - Maps directive name --> DirectiveKind enum, for + /// \brief Maps directive name --> DirectiveKind enum, for /// directives parsed by this class. StringMap<DirectiveKind> DirectiveKindMap; // ".ascii", ".asciz", ".string" - bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); - bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ... - bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ... - bool ParseDirectiveFill(); // ".fill" - bool ParseDirectiveZero(); // ".zero" + bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); + bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ... + bool parseDirectiveRealValue(const fltSemantics &); // ".single", ... + bool parseDirectiveFill(); // ".fill" + bool parseDirectiveZero(); // ".zero" // ".set", ".equ", ".equiv" - bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); - bool ParseDirectiveOrg(); // ".org" + bool parseDirectiveSet(StringRef IDVal, bool allow_redef); + bool parseDirectiveOrg(); // ".org" // ".align{,32}", ".p2align{,w,l}" - bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize); + bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize); // ".file", ".line", ".loc", ".stabs" - bool ParseDirectiveFile(SMLoc DirectiveLoc); - bool ParseDirectiveLine(); - bool ParseDirectiveLoc(); - bool ParseDirectiveStabs(); + bool parseDirectiveFile(SMLoc DirectiveLoc); + bool parseDirectiveLine(); + bool parseDirectiveLoc(); + bool parseDirectiveStabs(); // .cfi directives - bool ParseDirectiveCFIRegister(SMLoc DirectiveLoc); - bool ParseDirectiveCFISections(); - bool ParseDirectiveCFIStartProc(); - bool ParseDirectiveCFIEndProc(); - bool ParseDirectiveCFIDefCfaOffset(); - bool ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc); - bool ParseDirectiveCFIAdjustCfaOffset(); - bool ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc); - bool ParseDirectiveCFIOffset(SMLoc DirectiveLoc); - bool ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc); - bool ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality); - bool ParseDirectiveCFIRememberState(); - bool ParseDirectiveCFIRestoreState(); - bool ParseDirectiveCFISameValue(SMLoc DirectiveLoc); - bool ParseDirectiveCFIRestore(SMLoc DirectiveLoc); - bool ParseDirectiveCFIEscape(); - bool ParseDirectiveCFISignalFrame(); - bool ParseDirectiveCFIUndefined(SMLoc DirectiveLoc); + bool parseDirectiveCFIRegister(SMLoc DirectiveLoc); + bool parseDirectiveCFIWindowSave(); + bool parseDirectiveCFISections(); + bool parseDirectiveCFIStartProc(); + bool parseDirectiveCFIEndProc(); + bool parseDirectiveCFIDefCfaOffset(); + bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc); + bool parseDirectiveCFIAdjustCfaOffset(); + bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc); + bool parseDirectiveCFIOffset(SMLoc DirectiveLoc); + bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc); + bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality); + bool parseDirectiveCFIRememberState(); + bool parseDirectiveCFIRestoreState(); + bool parseDirectiveCFISameValue(SMLoc DirectiveLoc); + bool parseDirectiveCFIRestore(SMLoc DirectiveLoc); + bool parseDirectiveCFIEscape(); + bool parseDirectiveCFISignalFrame(); + bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc); // macro directives - bool ParseDirectivePurgeMacro(SMLoc DirectiveLoc); - bool ParseDirectiveEndMacro(StringRef Directive); - bool ParseDirectiveMacro(SMLoc DirectiveLoc); - bool ParseDirectiveMacrosOnOff(StringRef Directive); + bool parseDirectivePurgeMacro(SMLoc DirectiveLoc); + bool parseDirectiveEndMacro(StringRef Directive); + bool parseDirectiveMacro(SMLoc DirectiveLoc); + bool parseDirectiveMacrosOnOff(StringRef Directive); // ".bundle_align_mode" - bool ParseDirectiveBundleAlignMode(); + bool parseDirectiveBundleAlignMode(); // ".bundle_lock" - bool ParseDirectiveBundleLock(); + bool parseDirectiveBundleLock(); // ".bundle_unlock" - bool ParseDirectiveBundleUnlock(); + bool parseDirectiveBundleUnlock(); // ".space", ".skip" - bool ParseDirectiveSpace(StringRef IDVal); + bool parseDirectiveSpace(StringRef IDVal); // .sleb128 (Signed=true) and .uleb128 (Signed=false) - bool ParseDirectiveLEB128(bool Signed); + bool parseDirectiveLEB128(bool Signed); - /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which + /// \brief Parse a directive like ".globl" which /// accepts a single symbol (which should be a label or an external). - bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); + bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr); - bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" + bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" - bool ParseDirectiveAbort(); // ".abort" - bool ParseDirectiveInclude(); // ".include" - bool ParseDirectiveIncbin(); // ".incbin" + bool parseDirectiveAbort(); // ".abort" + bool parseDirectiveInclude(); // ".include" + bool parseDirectiveIncbin(); // ".incbin" - bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if" + bool parseDirectiveIf(SMLoc DirectiveLoc); // ".if" // ".ifb" or ".ifnb", depending on ExpectBlank. - bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); + bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); // ".ifc" or ".ifnc", depending on ExpectEqual. - bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); + bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); // ".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 + 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); - const MCExpr *ApplyModifierToExpr(const MCExpr *E, + const MCExpr *applyModifierToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind Variant); // Macro-like directives - MCAsmMacro *ParseMacroLikeBody(SMLoc DirectiveLoc); - void InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, + MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc); + void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, raw_svector_ostream &OS); - bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept" - bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" - bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" - bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" + bool parseDirectiveRept(SMLoc DirectiveLoc); // ".rept" + bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" + bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" + bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" // "_emit" or "__emit" - bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, + bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info, size_t Len); // "align" - bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); + bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info); void initializeDirectiveKindMap(); }; @@ -466,12 +477,12 @@ extern MCAsmParserExtension *createCOFFAsmParser(); enum { DEFAULT_ADDRSPACE = 0 }; -AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, - MCStreamer &_Out, const MCAsmInfo &_MAI) - : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), - PlatformParser(0), - CurBuffer(0), MacrosEnabledFlag(true), CppHashLineNumber(0), - AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { +AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, + const MCAsmInfo &_MAI) + : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), + PlatformParser(0), CurBuffer(0), MacrosEnabledFlag(true), + CppHashLineNumber(0), AssemblerDialect(~0U), IsDarwin(false), + ParsingInlineAsm(false) { // Save the old handler. SavedDiagHandler = SrcMgr.getDiagHandler(); SavedDiagContext = SrcMgr.getDiagContext(); @@ -502,37 +513,40 @@ AsmParser::~AsmParser() { assert(ActiveMacros.empty() && "Unexpected active macro instantiation!"); // Destroy any macros. - for (StringMap<MCAsmMacro*>::iterator it = MacroMap.begin(), - ie = MacroMap.end(); it != ie; ++it) + for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(), + ie = MacroMap.end(); + it != ie; ++it) delete it->getValue(); delete PlatformParser; } -void AsmParser::PrintMacroInstantiations() { +void AsmParser::printMacroInstantiations() { // Print the active macro instantiation stack. - for (std::vector<MacroInstantiation*>::const_reverse_iterator - it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it) - PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, + for (std::vector<MacroInstantiation *>::const_reverse_iterator + it = ActiveMacros.rbegin(), + ie = ActiveMacros.rend(); + it != ie; ++it) + printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note, "while in macro instantiation"); } bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { if (FatalAssemblerWarnings) return Error(L, Msg, Ranges); - PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges); - PrintMacroInstantiations(); + printMessage(L, SourceMgr::DK_Warning, Msg, Ranges); + printMacroInstantiations(); return false; } bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) { HadError = true; - PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges); - PrintMacroInstantiations(); + printMessage(L, SourceMgr::DK_Error, Msg, Ranges); + printMacroInstantiations(); return true; } -bool AsmParser::EnterIncludeFile(const std::string &Filename) { +bool AsmParser::enterIncludeFile(const std::string &Filename) { std::string IncludedFile; int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); if (NewBuf == -1) @@ -545,22 +559,21 @@ bool AsmParser::EnterIncludeFile(const std::string &Filename) { return false; } -/// Process the specified .incbin file by seaching for it in the include paths +/// Process the specified .incbin file by searching for it in the include paths /// then just emitting the byte contents of the file to the streamer. This /// returns true on failure. -bool AsmParser::ProcessIncbinFile(const std::string &Filename) { +bool AsmParser::processIncbinFile(const std::string &Filename) { std::string IncludedFile; int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile); if (NewBuf == -1) return true; // Pick up the bytes from the file and emit them. - getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer(), - DEFAULT_ADDRSPACE); + getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer()); return false; } -void AsmParser::JumpToLoc(SMLoc Loc, int InBuffer) { +void AsmParser::jumpToLoc(SMLoc Loc, int InBuffer) { if (InBuffer != -1) { CurBuffer = InBuffer; } else { @@ -577,7 +590,7 @@ const AsmToken &AsmParser::Lex() { // include stack. SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); if (ParentIncludeLoc != SMLoc()) { - JumpToLoc(ParentIncludeLoc); + jumpToLoc(ParentIncludeLoc); tok = &Lexer.Lex(); } } @@ -614,7 +627,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // While we have input, parse each statement. while (Lexer.isNot(AsmToken::Eof)) { ParseStatementInfo Info; - if (!ParseStatement(Info)) continue; + if (!parseStatement(Info)) + continue; // We had an error, validate that one was emitted and recover by skipping to // the next line. @@ -628,7 +642,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // Check to see there are no empty DwarfFile slots. const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles = - getContext().getMCDwarfFiles(); + getContext().getMCDwarfFiles(); for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { if (!MCDwarfFiles[i]) TokError("unassigned file number: " + Twine(i) + " for .file directives"); @@ -641,7 +655,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) { const MCContext::SymbolTable &Symbols = getContext().getSymbols(); for (MCContext::SymbolTable::const_iterator i = Symbols.begin(), - e = Symbols.end(); + e = Symbols.end(); i != e; ++i) { MCSymbol *Sym = i->getValue(); // Variable symbols may not be marked as defined, so check those @@ -651,13 +665,12 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // FIXME: We would really like to refer back to where the symbol was // first referenced for a source location. We need to add something // to track that. Currently, we just point to the end of the file. - PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error, - "assembler local symbol '" + Sym->getName() + - "' not defined"); + printMessage( + getLexer().getLoc(), SourceMgr::DK_Error, + "assembler local symbol '" + Sym->getName() + "' not defined"); } } - // Finalize the output stream if there are no errors and if the client wants // us to. if (!HadError && !NoFinalize) @@ -673,10 +686,9 @@ void AsmParser::checkForValidSection() { } } -/// eatToEndOfStatement - Throw away the rest of the line for testing purposes. +/// \brief Throw away the rest of the line for testing purposes. void AsmParser::eatToEndOfStatement() { - while (Lexer.isNot(AsmToken::EndOfStatement) && - Lexer.isNot(AsmToken::Eof)) + while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) Lex(); // Eat EOL. @@ -687,33 +699,32 @@ void AsmParser::eatToEndOfStatement() { StringRef AsmParser::parseStringToEndOfStatement() { const char *Start = getTok().getLoc().getPointer(); - while (Lexer.isNot(AsmToken::EndOfStatement) && - Lexer.isNot(AsmToken::Eof)) + while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof)) Lex(); const char *End = getTok().getLoc().getPointer(); return StringRef(Start, End - Start); } -StringRef AsmParser::ParseStringToComma() { +StringRef AsmParser::parseStringToComma() { const char *Start = getTok().getLoc().getPointer(); while (Lexer.isNot(AsmToken::EndOfStatement) && - Lexer.isNot(AsmToken::Comma) && - Lexer.isNot(AsmToken::Eof)) + Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof)) Lex(); const char *End = getTok().getLoc().getPointer(); return StringRef(Start, End - Start); } -/// ParseParenExpr - Parse a paren expression and return it. +/// \brief Parse a paren expression and return it. /// NOTE: This assumes the leading '(' has already been consumed. /// /// parenexpr ::= expr) /// -bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { - if (parseExpression(Res)) return true; +bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { + if (parseExpression(Res)) + return true; if (Lexer.isNot(AsmToken::RParen)) return TokError("expected ')' in parentheses expression"); EndLoc = Lexer.getTok().getEndLoc(); @@ -721,13 +732,14 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) { return false; } -/// ParseBracketExpr - Parse a bracket expression and return it. +/// \brief Parse a bracket expression and return it. /// NOTE: This assumes the leading '[' has already been consumed. /// /// bracketexpr ::= expr] /// -bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { - if (parseExpression(Res)) return true; +bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { + if (parseExpression(Res)) + return true; if (Lexer.isNot(AsmToken::RBrac)) return TokError("expected ']' in brackets expression"); EndLoc = Lexer.getTok().getEndLoc(); @@ -735,13 +747,13 @@ bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) { return false; } -/// ParsePrimaryExpr - Parse a primary expression and return it. +/// \brief Parse a primary expression and return it. /// primaryexpr ::= (parenexpr /// primaryexpr ::= symbol /// primaryexpr ::= number /// primaryexpr ::= '.' /// primaryexpr ::= ~,+,- primaryexpr -bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { +bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { SMLoc FirstTokenLoc = getLexer().getLoc(); AsmToken::TokenKind FirstTokenKind = Lexer.getKind(); switch (FirstTokenKind) { @@ -752,36 +764,54 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { return true; case AsmToken::Exclaim: Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res, EndLoc)) + if (parsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreateLNot(Res, getContext()); return false; case AsmToken::Dollar: + case AsmToken::At: case AsmToken::String: case AsmToken::Identifier: { StringRef Identifier; if (parseIdentifier(Identifier)) { - if (FirstTokenKind == AsmToken::Dollar) - return Error(FirstTokenLoc, "invalid token in expression"); - return true; + if (FirstTokenKind == AsmToken::Dollar) { + if (Lexer.getMAI().getDollarIsPC()) { + // This is a '$' reference, which references the current PC. Emit a + // temporary label to the streamer and refer to it. + MCSymbol *Sym = Ctx.CreateTempSymbol(); + Out.EmitLabel(Sym); + Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, + getContext()); + EndLoc = FirstTokenLoc; + return false; + } else + return Error(FirstTokenLoc, "invalid token in expression"); + return true; + } } EndLoc = SMLoc::getFromPointer(Identifier.end()); // This is a symbol reference. + StringRef SymbolName = Identifier; + MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; std::pair<StringRef, StringRef> Split = Identifier.split('@'); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first); // Lookup the symbol variant if used. - MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; if (Split.first.size() != Identifier.size()) { Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); - if (Variant == MCSymbolRefExpr::VK_Invalid) { + if (Variant != MCSymbolRefExpr::VK_Invalid) { + SymbolName = Split.first; + } else if (MAI.doesAllowAtInName()) { + Variant = MCSymbolRefExpr::VK_None; + } else { Variant = MCSymbolRefExpr::VK_None; return TokError("invalid variant '" + Split.second + "'"); } } + MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); + // If this is an absolute variable reference, substitute it now to preserve // semantics in the face of reassignment. if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) { @@ -805,11 +835,21 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { // Look for 'b' or 'f' following an Integer as a directional label if (Lexer.getKind() == AsmToken::Identifier) { StringRef IDVal = getTok().getString(); - if (IDVal == "f" || IDVal == "b"){ - MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal, - IDVal == "f" ? 1 : 0); - Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, - getContext()); + // Lookup the symbol variant if used. + std::pair<StringRef, StringRef> Split = IDVal.split('@'); + 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; + return TokError("invalid variant '" + Split.second + "'"); + } + IDVal = Split.first; + } + if (IDVal == "f" || IDVal == "b") { + MCSymbol *Sym = + Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "f" ? 1 : 0); + Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); if (IDVal == "b" && Sym->isUndefined()) return Error(Loc, "invalid reference to undefined symbol"); EndLoc = Lexer.getTok().getEndLoc(); @@ -838,27 +878,27 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { } case AsmToken::LParen: Lex(); // Eat the '('. - return ParseParenExpr(Res, EndLoc); + return parseParenExpr(Res, EndLoc); case AsmToken::LBrac: if (!PlatformParser->HasBracketExpressions()) return TokError("brackets expression not supported on this target"); Lex(); // Eat the '['. - return ParseBracketExpr(Res, EndLoc); + return parseBracketExpr(Res, EndLoc); case AsmToken::Minus: Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res, EndLoc)) + if (parsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreateMinus(Res, getContext()); return false; case AsmToken::Plus: Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res, EndLoc)) + if (parsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreatePlus(Res, getContext()); return false; case AsmToken::Tilde: Lex(); // Eat the operator. - if (ParsePrimaryExpr(Res, EndLoc)) + if (parsePrimaryExpr(Res, EndLoc)) return true; Res = MCUnaryExpr::CreateNot(Res, getContext()); return false; @@ -870,13 +910,13 @@ bool AsmParser::parseExpression(const MCExpr *&Res) { return parseExpression(Res, EndLoc); } -bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { - return ParsePrimaryExpr(Res, EndLoc); -} - const MCExpr * -AsmParser::ApplyModifierToExpr(const MCExpr *E, +AsmParser::applyModifierToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind Variant) { + // Ask the target implementation about this expression first. + const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx); + if (NewE) + return NewE; // Recurse over the given expression, rebuilding it to apply the given variant // if there is exactly one symbol. switch (E->getKind()) { @@ -888,8 +928,8 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E, const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); if (SRE->getKind() != MCSymbolRefExpr::VK_None) { - TokError("invalid variant on expression '" + - getTok().getIdentifier() + "' (already modified)"); + TokError("invalid variant on expression '" + getTok().getIdentifier() + + "' (already modified)"); return E; } @@ -898,7 +938,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E, case MCExpr::Unary: { const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); - const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant); + const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant); if (!Sub) return 0; return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); @@ -906,14 +946,16 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E, case MCExpr::Binary: { const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); - const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant); - const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant); + const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant); + const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant); if (!LHS && !RHS) return 0; - if (!LHS) LHS = BE->getLHS(); - if (!RHS) RHS = BE->getRHS(); + if (!LHS) + LHS = BE->getLHS(); + if (!RHS) + RHS = BE->getRHS(); return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); } @@ -922,7 +964,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E, llvm_unreachable("Invalid expression kind!"); } -/// parseExpression - Parse an expression and return it. +/// \brief Parse an expression and return it. /// /// expr ::= expr &&,|| expr -> lowest. /// expr ::= expr |,^,&,! expr @@ -935,7 +977,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E, bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { // Parse the expression. Res = 0; - if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc)) + if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc)) return true; // As a special case, we support 'a op b @ modifier' by rewriting the @@ -948,11 +990,11 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { return TokError("unexpected symbol modifier following '@'"); MCSymbolRefExpr::VariantKind Variant = - MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); + MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier()); if (Variant == MCSymbolRefExpr::VK_Invalid) return TokError("invalid variant '" + getTok().getIdentifier() + "'"); - const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant); + const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant); if (!ModifiedRes) { return TokError("invalid modifier '" + getTok().getIdentifier() + "' (no symbols present)"); @@ -972,8 +1014,7 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { Res = 0; - return ParseParenExpr(Res, EndLoc) || - ParseBinOpRHS(1, Res, EndLoc); + return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc); } bool AsmParser::parseAbsoluteExpression(int64_t &Res) { @@ -993,9 +1034,9 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, MCBinaryExpr::Opcode &Kind) { switch (K) { default: - return 0; // not a binop. + return 0; // not a binop. - // Lowest Precedence: &&, || + // Lowest Precedence: &&, || case AsmToken::AmpAmp: Kind = MCBinaryExpr::LAnd; return 1; @@ -1003,10 +1044,9 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::LOr; return 1; - - // Low Precedence: |, &, ^ - // - // FIXME: gas seems to support '!' as an infix operator? + // Low Precedence: |, &, ^ + // + // FIXME: gas seems to support '!' as an infix operator? case AsmToken::Pipe: Kind = MCBinaryExpr::Or; return 2; @@ -1017,7 +1057,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::And; return 2; - // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= + // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >= case AsmToken::EqualEqual: Kind = MCBinaryExpr::EQ; return 3; @@ -1038,7 +1078,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::GTE; return 3; - // Intermediate Precedence: <<, >> + // Intermediate Precedence: <<, >> case AsmToken::LessLess: Kind = MCBinaryExpr::Shl; return 4; @@ -1046,7 +1086,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::Shr; return 4; - // High Intermediate Precedence: +, - + // High Intermediate Precedence: +, - case AsmToken::Plus: Kind = MCBinaryExpr::Add; return 5; @@ -1054,7 +1094,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::Sub; return 5; - // Highest Precedence: *, /, % + // Highest Precedence: *, /, % case AsmToken::Star: Kind = MCBinaryExpr::Mul; return 6; @@ -1067,10 +1107,9 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, } } - -/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. +/// \brief Parse all binary operators with precedence >= 'Precedence'. /// Res contains the LHS of the expression on input. -bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, +bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc) { while (1) { MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; @@ -1085,15 +1124,15 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, // Eat the next primary expression. const MCExpr *RHS; - if (ParsePrimaryExpr(RHS, EndLoc)) return true; + if (parsePrimaryExpr(RHS, EndLoc)) + return true; // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. MCBinaryExpr::Opcode Dummy; unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy); - if (TokPrec < NextTokPrec) { - if (ParseBinOpRHS(TokPrec+1, RHS, EndLoc)) return true; - } + if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc)) + return true; // Merge LHS and RHS according to operator. Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext()); @@ -1104,7 +1143,7 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, /// ::= EndOfStatement /// ::= Label* Directive ...Operands... EndOfStatement /// ::= Label* Identifier OperandList* EndOfStatement -bool AsmParser::ParseStatement(ParseStatementInfo &Info) { +bool AsmParser::parseStatement(ParseStatementInfo &Info) { if (Lexer.is(AsmToken::EndOfStatement)) { Out.AddBlankLine(); Lex(); @@ -1118,7 +1157,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { int64_t LocalLabelVal = -1; // A full line comment is a '#' as the first token. if (Lexer.is(AsmToken::Hash)) - return ParseCppHashLineFilenameComment(IDLoc); + return parseCppHashLineFilenameComment(IDLoc); // Allow an integer followed by a ':' as a directional local label. if (Lexer.is(AsmToken::Integer)) { @@ -1149,34 +1188,34 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { // have to do this so that .endif isn't skipped in a ".if 0" block for // example. StringMap<DirectiveKind>::const_iterator DirKindIt = - DirectiveKindMap.find(IDVal); - DirectiveKind DirKind = - (DirKindIt == DirectiveKindMap.end()) ? DK_NO_DIRECTIVE : - DirKindIt->getValue(); + DirectiveKindMap.find(IDVal); + DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end()) + ? DK_NO_DIRECTIVE + : DirKindIt->getValue(); switch (DirKind) { - default: - break; - case DK_IF: - return ParseDirectiveIf(IDLoc); - case DK_IFB: - return ParseDirectiveIfb(IDLoc, true); - case DK_IFNB: - return ParseDirectiveIfb(IDLoc, false); - case DK_IFC: - return ParseDirectiveIfc(IDLoc, true); - case DK_IFNC: - return ParseDirectiveIfc(IDLoc, false); - case DK_IFDEF: - return ParseDirectiveIfdef(IDLoc, true); - case DK_IFNDEF: - case DK_IFNOTDEF: - return ParseDirectiveIfdef(IDLoc, false); - case DK_ELSEIF: - return ParseDirectiveElseIf(IDLoc); - case DK_ELSE: - return ParseDirectiveElse(IDLoc); - case DK_ENDIF: - return ParseDirectiveEndIf(IDLoc); + default: + break; + case DK_IF: + return parseDirectiveIf(IDLoc); + case DK_IFB: + return parseDirectiveIfb(IDLoc, true); + case DK_IFNB: + return parseDirectiveIfb(IDLoc, false); + case DK_IFC: + return parseDirectiveIfc(IDLoc, true); + case DK_IFNC: + return parseDirectiveIfc(IDLoc, false); + case DK_IFDEF: + return parseDirectiveIfdef(IDLoc, true); + case DK_IFNDEF: + case DK_IFNOTDEF: + return parseDirectiveIfdef(IDLoc, false); + case DK_ELSEIF: + return parseDirectiveElseIf(IDLoc); + case DK_ELSE: + return parseDirectiveElse(IDLoc); + case DK_ENDIF: + return parseDirectiveEndIf(IDLoc); } // Ignore the statement if in the middle of inactive conditional @@ -1223,6 +1262,8 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), IDLoc); + getTargetParser().onLabelParsed(Sym); + // Consume any end of statement token, if present, to avoid spurious // AddBlankLine calls(). if (Lexer.is(AsmToken::EndOfStatement)) { @@ -1238,24 +1279,24 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { // identifier '=' ... -> assignment statement Lex(); - return ParseAssignment(IDVal, true); + return parseAssignment(IDVal, true); default: // Normal instruction or directive. break; } // If macros are enabled, check to see if this is a macro instantiation. - if (MacrosEnabled()) - if (const MCAsmMacro *M = LookupMacro(IDVal)) { - return HandleMacroEntry(M, IDLoc); + if (areMacrosEnabled()) + if (const MCAsmMacro *M = lookupMacro(IDVal)) { + return handleMacroEntry(M, IDLoc); } // Otherwise, we have a normal instruction or directive. - + // Directives start with "." if (IDVal[0] == '.' && IDVal != ".") { // There are several entities interested in parsing directives: - // + // // 1. The target-specific assembly parser. Some directives are target // specific or may potentially behave differently on certain targets. // 2. Asm parser extensions. For example, platform-specific parsers @@ -1272,185 +1313,185 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { // Next, check the extention directive map to see if any extension has // registered itself to parse this directive. - std::pair<MCAsmParserExtension*, DirectiveHandler> Handler = - ExtensionDirectiveMap.lookup(IDVal); + std::pair<MCAsmParserExtension *, DirectiveHandler> Handler = + ExtensionDirectiveMap.lookup(IDVal); if (Handler.first) return (*Handler.second)(Handler.first, IDVal, IDLoc); // Finally, if no one else is interested in this directive, it must be // generic and familiar to this class. switch (DirKind) { - default: - break; - case DK_SET: - case DK_EQU: - return ParseDirectiveSet(IDVal, true); - case DK_EQUIV: - return ParseDirectiveSet(IDVal, false); - case DK_ASCII: - return ParseDirectiveAscii(IDVal, false); - case DK_ASCIZ: - case DK_STRING: - return ParseDirectiveAscii(IDVal, true); - case DK_BYTE: - return ParseDirectiveValue(1); - case DK_SHORT: - case DK_VALUE: - case DK_2BYTE: - return ParseDirectiveValue(2); - case DK_LONG: - case DK_INT: - case DK_4BYTE: - return ParseDirectiveValue(4); - case DK_QUAD: - case DK_8BYTE: - return ParseDirectiveValue(8); - case DK_SINGLE: - case DK_FLOAT: - return ParseDirectiveRealValue(APFloat::IEEEsingle); - case DK_DOUBLE: - return ParseDirectiveRealValue(APFloat::IEEEdouble); - case DK_ALIGN: { - bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes(); - return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1); - } - case DK_ALIGN32: { - bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes(); - return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4); - } - case DK_BALIGN: - return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); - case DK_BALIGNW: - return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); - case DK_BALIGNL: - return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); - case DK_P2ALIGN: - return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); - case DK_P2ALIGNW: - return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); - case DK_P2ALIGNL: - return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); - case DK_ORG: - return ParseDirectiveOrg(); - case DK_FILL: - return ParseDirectiveFill(); - case DK_ZERO: - return ParseDirectiveZero(); - case DK_EXTERN: - eatToEndOfStatement(); // .extern is the default, ignore it. - return false; - case DK_GLOBL: - case DK_GLOBAL: - return ParseDirectiveSymbolAttribute(MCSA_Global); - case DK_INDIRECT_SYMBOL: - return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); - case DK_LAZY_REFERENCE: - return ParseDirectiveSymbolAttribute(MCSA_LazyReference); - case DK_NO_DEAD_STRIP: - return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); - case DK_SYMBOL_RESOLVER: - return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); - case DK_PRIVATE_EXTERN: - return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); - case DK_REFERENCE: - return ParseDirectiveSymbolAttribute(MCSA_Reference); - case DK_WEAK_DEFINITION: - return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); - case DK_WEAK_REFERENCE: - return ParseDirectiveSymbolAttribute(MCSA_WeakReference); - case DK_WEAK_DEF_CAN_BE_HIDDEN: - return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); - case DK_COMM: - case DK_COMMON: - return ParseDirectiveComm(/*IsLocal=*/false); - case DK_LCOMM: - return ParseDirectiveComm(/*IsLocal=*/true); - case DK_ABORT: - return ParseDirectiveAbort(); - case DK_INCLUDE: - return ParseDirectiveInclude(); - case DK_INCBIN: - return ParseDirectiveIncbin(); - case DK_CODE16: - case DK_CODE16GCC: - return TokError(Twine(IDVal) + " not supported yet"); - case DK_REPT: - return ParseDirectiveRept(IDLoc); - case DK_IRP: - return ParseDirectiveIrp(IDLoc); - case DK_IRPC: - return ParseDirectiveIrpc(IDLoc); - case DK_ENDR: - return ParseDirectiveEndr(IDLoc); - case DK_BUNDLE_ALIGN_MODE: - return ParseDirectiveBundleAlignMode(); - case DK_BUNDLE_LOCK: - return ParseDirectiveBundleLock(); - case DK_BUNDLE_UNLOCK: - return ParseDirectiveBundleUnlock(); - case DK_SLEB128: - return ParseDirectiveLEB128(true); - case DK_ULEB128: - return ParseDirectiveLEB128(false); - case DK_SPACE: - case DK_SKIP: - return ParseDirectiveSpace(IDVal); - case DK_FILE: - return ParseDirectiveFile(IDLoc); - case DK_LINE: - return ParseDirectiveLine(); - case DK_LOC: - return ParseDirectiveLoc(); - case DK_STABS: - return ParseDirectiveStabs(); - case DK_CFI_SECTIONS: - return ParseDirectiveCFISections(); - case DK_CFI_STARTPROC: - return ParseDirectiveCFIStartProc(); - case DK_CFI_ENDPROC: - return ParseDirectiveCFIEndProc(); - case DK_CFI_DEF_CFA: - return ParseDirectiveCFIDefCfa(IDLoc); - case DK_CFI_DEF_CFA_OFFSET: - return ParseDirectiveCFIDefCfaOffset(); - case DK_CFI_ADJUST_CFA_OFFSET: - return ParseDirectiveCFIAdjustCfaOffset(); - case DK_CFI_DEF_CFA_REGISTER: - return ParseDirectiveCFIDefCfaRegister(IDLoc); - case DK_CFI_OFFSET: - return ParseDirectiveCFIOffset(IDLoc); - case DK_CFI_REL_OFFSET: - return ParseDirectiveCFIRelOffset(IDLoc); - case DK_CFI_PERSONALITY: - return ParseDirectiveCFIPersonalityOrLsda(true); - case DK_CFI_LSDA: - return ParseDirectiveCFIPersonalityOrLsda(false); - case DK_CFI_REMEMBER_STATE: - return ParseDirectiveCFIRememberState(); - case DK_CFI_RESTORE_STATE: - return ParseDirectiveCFIRestoreState(); - case DK_CFI_SAME_VALUE: - return ParseDirectiveCFISameValue(IDLoc); - case DK_CFI_RESTORE: - return ParseDirectiveCFIRestore(IDLoc); - case DK_CFI_ESCAPE: - return ParseDirectiveCFIEscape(); - case DK_CFI_SIGNAL_FRAME: - return ParseDirectiveCFISignalFrame(); - case DK_CFI_UNDEFINED: - return ParseDirectiveCFIUndefined(IDLoc); - case DK_CFI_REGISTER: - return ParseDirectiveCFIRegister(IDLoc); - case DK_MACROS_ON: - case DK_MACROS_OFF: - return ParseDirectiveMacrosOnOff(IDVal); - case DK_MACRO: - return ParseDirectiveMacro(IDLoc); - case DK_ENDM: - case DK_ENDMACRO: - return ParseDirectiveEndMacro(IDVal); - case DK_PURGEM: - return ParseDirectivePurgeMacro(IDLoc); + default: + break; + case DK_SET: + case DK_EQU: + return parseDirectiveSet(IDVal, true); + case DK_EQUIV: + return parseDirectiveSet(IDVal, false); + case DK_ASCII: + return parseDirectiveAscii(IDVal, false); + case DK_ASCIZ: + case DK_STRING: + return parseDirectiveAscii(IDVal, true); + case DK_BYTE: + return parseDirectiveValue(1); + case DK_SHORT: + case DK_VALUE: + case DK_2BYTE: + return parseDirectiveValue(2); + case DK_LONG: + case DK_INT: + case DK_4BYTE: + return parseDirectiveValue(4); + case DK_QUAD: + case DK_8BYTE: + return parseDirectiveValue(8); + case DK_SINGLE: + case DK_FLOAT: + return parseDirectiveRealValue(APFloat::IEEEsingle); + case DK_DOUBLE: + return parseDirectiveRealValue(APFloat::IEEEdouble); + case DK_ALIGN: { + bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); + return parseDirectiveAlign(IsPow2, /*ExprSize=*/1); + } + case DK_ALIGN32: { + bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes(); + return parseDirectiveAlign(IsPow2, /*ExprSize=*/4); + } + case DK_BALIGN: + return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1); + case DK_BALIGNW: + return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2); + case DK_BALIGNL: + return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4); + case DK_P2ALIGN: + return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1); + case DK_P2ALIGNW: + return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2); + case DK_P2ALIGNL: + return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4); + case DK_ORG: + return parseDirectiveOrg(); + case DK_FILL: + return parseDirectiveFill(); + case DK_ZERO: + return parseDirectiveZero(); + case DK_EXTERN: + eatToEndOfStatement(); // .extern is the default, ignore it. + return false; + case DK_GLOBL: + case DK_GLOBAL: + return parseDirectiveSymbolAttribute(MCSA_Global); + case DK_LAZY_REFERENCE: + return parseDirectiveSymbolAttribute(MCSA_LazyReference); + case DK_NO_DEAD_STRIP: + return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip); + case DK_SYMBOL_RESOLVER: + return parseDirectiveSymbolAttribute(MCSA_SymbolResolver); + case DK_PRIVATE_EXTERN: + return parseDirectiveSymbolAttribute(MCSA_PrivateExtern); + case DK_REFERENCE: + return parseDirectiveSymbolAttribute(MCSA_Reference); + case DK_WEAK_DEFINITION: + return parseDirectiveSymbolAttribute(MCSA_WeakDefinition); + case DK_WEAK_REFERENCE: + return parseDirectiveSymbolAttribute(MCSA_WeakReference); + case DK_WEAK_DEF_CAN_BE_HIDDEN: + return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); + case DK_COMM: + case DK_COMMON: + return parseDirectiveComm(/*IsLocal=*/false); + case DK_LCOMM: + return parseDirectiveComm(/*IsLocal=*/true); + case DK_ABORT: + return parseDirectiveAbort(); + case DK_INCLUDE: + return parseDirectiveInclude(); + case DK_INCBIN: + return parseDirectiveIncbin(); + case DK_CODE16: + case DK_CODE16GCC: + return TokError(Twine(IDVal) + " not supported yet"); + case DK_REPT: + return parseDirectiveRept(IDLoc); + case DK_IRP: + return parseDirectiveIrp(IDLoc); + case DK_IRPC: + return parseDirectiveIrpc(IDLoc); + case DK_ENDR: + return parseDirectiveEndr(IDLoc); + case DK_BUNDLE_ALIGN_MODE: + return parseDirectiveBundleAlignMode(); + case DK_BUNDLE_LOCK: + return parseDirectiveBundleLock(); + case DK_BUNDLE_UNLOCK: + return parseDirectiveBundleUnlock(); + case DK_SLEB128: + return parseDirectiveLEB128(true); + case DK_ULEB128: + return parseDirectiveLEB128(false); + case DK_SPACE: + case DK_SKIP: + return parseDirectiveSpace(IDVal); + case DK_FILE: + return parseDirectiveFile(IDLoc); + case DK_LINE: + return parseDirectiveLine(); + case DK_LOC: + return parseDirectiveLoc(); + case DK_STABS: + return parseDirectiveStabs(); + case DK_CFI_SECTIONS: + return parseDirectiveCFISections(); + case DK_CFI_STARTPROC: + return parseDirectiveCFIStartProc(); + case DK_CFI_ENDPROC: + return parseDirectiveCFIEndProc(); + case DK_CFI_DEF_CFA: + return parseDirectiveCFIDefCfa(IDLoc); + case DK_CFI_DEF_CFA_OFFSET: + return parseDirectiveCFIDefCfaOffset(); + case DK_CFI_ADJUST_CFA_OFFSET: + return parseDirectiveCFIAdjustCfaOffset(); + case DK_CFI_DEF_CFA_REGISTER: + return parseDirectiveCFIDefCfaRegister(IDLoc); + case DK_CFI_OFFSET: + return parseDirectiveCFIOffset(IDLoc); + case DK_CFI_REL_OFFSET: + return parseDirectiveCFIRelOffset(IDLoc); + case DK_CFI_PERSONALITY: + return parseDirectiveCFIPersonalityOrLsda(true); + case DK_CFI_LSDA: + return parseDirectiveCFIPersonalityOrLsda(false); + case DK_CFI_REMEMBER_STATE: + return parseDirectiveCFIRememberState(); + case DK_CFI_RESTORE_STATE: + return parseDirectiveCFIRestoreState(); + case DK_CFI_SAME_VALUE: + return parseDirectiveCFISameValue(IDLoc); + case DK_CFI_RESTORE: + return parseDirectiveCFIRestore(IDLoc); + case DK_CFI_ESCAPE: + return parseDirectiveCFIEscape(); + case DK_CFI_SIGNAL_FRAME: + return parseDirectiveCFISignalFrame(); + case DK_CFI_UNDEFINED: + return parseDirectiveCFIUndefined(IDLoc); + case DK_CFI_REGISTER: + return parseDirectiveCFIRegister(IDLoc); + case DK_CFI_WINDOW_SAVE: + return parseDirectiveCFIWindowSave(); + case DK_MACROS_ON: + case DK_MACROS_OFF: + return parseDirectiveMacrosOnOff(IDVal); + case DK_MACRO: + return parseDirectiveMacro(IDLoc); + case DK_ENDM: + case DK_ENDMACRO: + return parseDirectiveEndMacro(IDVal); + case DK_PURGEM: + return parseDirectivePurgeMacro(IDLoc); } return Error(IDLoc, "unknown directive"); @@ -1459,19 +1500,19 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { // __asm _emit or __asm __emit if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" || IDVal == "_EMIT" || IDVal == "__EMIT")) - return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size()); + return parseDirectiveMSEmit(IDLoc, Info, IDVal.size()); // __asm align if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN")) - return ParseDirectiveMSAlign(IDLoc, Info); + return parseDirectiveMSAlign(IDLoc, Info); checkForValidSection(); // Canonicalize the opcode to lower case. std::string OpcodeStr = IDVal.lower(); ParseInstructionInfo IInfo(Info.AsmRewrites); - bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, - IDLoc, Info.ParsedOperands); + bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, IDLoc, + Info.ParsedOperands); Info.ParseError = HadError; // Dump the parsed representation, if requested. @@ -1486,7 +1527,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { } OS << "]"; - PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str()); + printMessage(IDLoc, SourceMgr::DK_Note, OS.str()); } // If we are generating dwarf for assembly source files and the current @@ -1494,38 +1535,49 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { // the instruction. if (!HadError && getContext().getGenDwarfForAssembly() && getContext().getGenDwarfSection() == - getStreamer().getCurrentSection().first) { + getStreamer().getCurrentSection().first) { unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); // 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(); + const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles = + getContext().getMCDwarfFiles(); if (CppHashFilename.size() != 0) { if (MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() != CppHashFilename) getStreamer().EmitDwarfFileDirective( - getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename); - - unsigned CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc,CppHashBuf); - Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); + getContext().nextGenDwarfFileNumber(), StringRef(), + CppHashFilename); + + // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's + // cache with the different Loc from the call above we save the last + // info we queried here with SrcMgr.FindLineNumber(). + unsigned CppHashLocLineNo; + if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf) + CppHashLocLineNo = LastQueryLine; + else { + CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf); + LastQueryLine = CppHashLocLineNo; + LastQueryIDLoc = CppHashLoc; + LastQueryBuffer = CppHashBuf; + } + Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); } - getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(), - Line, 0, DWARF2_LINE_DEFAULT_IS_STMT ? - DWARF2_FLAG_IS_STMT : 0, 0, 0, - StringRef()); + getStreamer().EmitDwarfLocDirective( + getContext().getGenDwarfFileNumber(), Line, 0, + DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0, + StringRef()); } // If parsing succeeded, match the instruction. if (!HadError) { unsigned ErrorInfo; - HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, - Info.ParsedOperands, - Out, ErrorInfo, - ParsingInlineAsm); + HadError = getTargetParser().MatchAndEmitInstruction( + IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo, + ParsingInlineAsm); } // Don't skip the rest of the line, the instruction parser is responsible for @@ -1533,25 +1585,25 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) { return false; } -/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line +/// eatToEndOfLine uses the Lexer to eat the characters to the end of the line /// since they may not be able to be tokenized to get to the end of line token. -void AsmParser::EatToEndOfLine() { +void AsmParser::eatToEndOfLine() { if (!Lexer.is(AsmToken::EndOfStatement)) Lexer.LexUntilEndOfLine(); - // Eat EOL. - Lex(); + // Eat EOL. + Lex(); } -/// ParseCppHashLineFilenameComment as this: +/// parseCppHashLineFilenameComment as this: /// ::= # number "filename" /// or just as a full line comment if it doesn't have a number and a string. -bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { +bool AsmParser::parseCppHashLineFilenameComment(const SMLoc &L) { Lex(); // Eat the hash token. if (getLexer().isNot(AsmToken::Integer)) { // Consume the line since in cases it is not a well-formed line directive, // as if were simply a full line comment. - EatToEndOfLine(); + eatToEndOfLine(); return false; } @@ -1559,13 +1611,13 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { Lex(); if (getLexer().isNot(AsmToken::String)) { - EatToEndOfLine(); + eatToEndOfLine(); return false; } StringRef Filename = getTok().getString(); // Get rid of the enclosing quotes. - Filename = Filename.substr(1, Filename.size()-2); + Filename = Filename.substr(1, Filename.size() - 2); // Save the SMLoc, Filename and LineNumber for later use by diagnostics. CppHashLoc = L; @@ -1574,14 +1626,14 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { CppHashBuf = CurBuffer; // Ignore any trailing characters, they're just comment. - EatToEndOfLine(); + eatToEndOfLine(); return false; } -/// DiagHandler - will use the last parsed cpp hash line filename comment +/// \brief will use the last parsed cpp hash line filename comment /// for the Filename and LineNo if any in the diagnostic. void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { - const AsmParser *Parser = static_cast<const AsmParser*>(Context); + const AsmParser *Parser = static_cast<const AsmParser *>(Context); raw_ostream &OS = errs(); const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); @@ -1589,19 +1641,18 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); - // Like SourceMgr::PrintMessage() we need to print the include stack if any + // Like SourceMgr::printMessage() we need to print the include stack if any // before printing the message. int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { - SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); - DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); + SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); + DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); } // If we have not parsed a cpp hash line filename comment or the source // manager changed or buffer changed (like in a nested include) then just // print the normal diagnostic using its Filename and LineNo. - if (!Parser->CppHashLineNumber || - &DiagSrcMgr != &Parser->SrcMgr || + if (!Parser->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr || DiagBuf != CppHashBuf) { if (Parser->SavedDiagHandler) Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); @@ -1613,17 +1664,16 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { // Use the CppHashFilename and calculate a line number based on the // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for // the diagnostic. - const std::string Filename = Parser->CppHashFilename; + const std::string &Filename = Parser->CppHashFilename; int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); int CppHashLocLineNo = Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); - int LineNo = Parser->CppHashLineNumber - 1 + - (DiagLocLineNo - CppHashLocLineNo); + int LineNo = + Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); - SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), - Filename, LineNo, Diag.getColumnNo(), - Diag.getKind(), Diag.getMessage(), + SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo, + Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(), Diag.getLineContents(), Diag.getRanges()); if (Parser->SavedDiagHandler) @@ -1643,8 +1693,7 @@ static bool isIdentifierChar(char c) { bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, const MCAsmMacroParameters &Parameters, - const MCAsmMacroArguments &A, - const SMLoc &L) { + const MCAsmMacroArguments &A, const SMLoc &L) { unsigned NParameters = Parameters.size(); if (NParameters != 0 && NParameters != A.size()) return Error(L, "Wrong number of arguments"); @@ -1680,27 +1729,28 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, break; if (!NParameters) { - switch (Body[Pos+1]) { - // $$ => $ + switch (Body[Pos + 1]) { + // $$ => $ case '$': OS << '$'; break; - // $n => number of arguments + // $n => number of arguments case 'n': OS << A.size(); break; - // $[0-9] => argument + // $[0-9] => argument default: { // Missing arguments are ignored. - unsigned Index = Body[Pos+1] - '0'; + unsigned Index = Body[Pos + 1] - '0'; if (Index >= A.size()) break; // Otherwise substitute with the token values, with spaces eliminated. for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), - ie = A[Index].end(); it != ie; ++it) + ie = A[Index].end(); + it != ie; ++it) OS << it->getString(); break; } @@ -1711,23 +1761,24 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, while (isIdentifierChar(Body[I]) && I + 1 != End) ++I; - const char *Begin = Body.data() + Pos +1; - StringRef Argument(Begin, I - (Pos +1)); + const char *Begin = Body.data() + Pos + 1; + StringRef Argument(Begin, I - (Pos + 1)); unsigned Index = 0; for (; Index < NParameters; ++Index) if (Parameters[Index].first == Argument) break; if (Index == NParameters) { - if (Body[Pos+1] == '(' && Body[Pos+2] == ')') - Pos += 3; - else { - OS << '\\' << Argument; - Pos = I; - } + if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') + Pos += 3; + else { + OS << '\\' << Argument; + Pos = I; + } } else { for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), - ie = A[Index].end(); it != ie; ++it) + ie = A[Index].end(); + it != ie; ++it) if (it->getKind() == AsmToken::String) OS << it->getStringContents(); else @@ -1743,48 +1794,43 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, return false; } -MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, - int EB, SMLoc EL, - MemoryBuffer *I) - : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), - ExitLoc(EL) -{ -} +MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, + SMLoc EL, MemoryBuffer *I) + : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), + ExitLoc(EL) {} -static bool IsOperator(AsmToken::TokenKind kind) -{ - switch (kind) - { - default: - return false; - case AsmToken::Plus: - case AsmToken::Minus: - case AsmToken::Tilde: - case AsmToken::Slash: - case AsmToken::Star: - case AsmToken::Dot: - case AsmToken::Equal: - case AsmToken::EqualEqual: - case AsmToken::Pipe: - case AsmToken::PipePipe: - case AsmToken::Caret: - case AsmToken::Amp: - case AsmToken::AmpAmp: - case AsmToken::Exclaim: - case AsmToken::ExclaimEqual: - case AsmToken::Percent: - case AsmToken::Less: - case AsmToken::LessEqual: - case AsmToken::LessLess: - case AsmToken::LessGreater: - case AsmToken::Greater: - case AsmToken::GreaterEqual: - case AsmToken::GreaterGreater: - return true; +static bool isOperator(AsmToken::TokenKind kind) { + switch (kind) { + default: + return false; + case AsmToken::Plus: + case AsmToken::Minus: + case AsmToken::Tilde: + case AsmToken::Slash: + case AsmToken::Star: + case AsmToken::Dot: + case AsmToken::Equal: + case AsmToken::EqualEqual: + case AsmToken::Pipe: + case AsmToken::PipePipe: + case AsmToken::Caret: + case AsmToken::Amp: + case AsmToken::AmpAmp: + case AsmToken::Exclaim: + case AsmToken::ExclaimEqual: + case AsmToken::Percent: + case AsmToken::Less: + case AsmToken::LessEqual: + case AsmToken::LessLess: + case AsmToken::LessGreater: + case AsmToken::Greater: + case AsmToken::GreaterEqual: + case AsmToken::GreaterGreater: + return true; } } -bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA, +bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, AsmToken::TokenKind &ArgumentDelimiter) { unsigned ParenLevel = 0; unsigned AddTokens = 0; @@ -1818,7 +1864,7 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA, // one into this argument if (ArgumentDelimiter == AsmToken::Space || ArgumentDelimiter == AsmToken::Eof) { - if (IsOperator(Lexer.getKind())) { + if (isOperator(Lexer.getKind())) { // Check to see whether the token is used as an operator, // or part of an identifier const char *NextChar = getTok().getEndLoc().getPointer(); @@ -1828,14 +1874,14 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA, if (!AddTokens && ParenLevel == 0) { if (ArgumentDelimiter == AsmToken::Eof && - !IsOperator(Lexer.getKind())) + !isOperator(Lexer.getKind())) ArgumentDelimiter = AsmToken::Space; break; } } } - // HandleMacroEntry relies on not advancing the lexer here + // handleMacroEntry relies on not advancing the lexer here // to be able to fill in the remaining default parameter values if (Lexer.is(AsmToken::EndOfStatement)) break; @@ -1860,10 +1906,11 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA, } // Parse the macro instantiation arguments. -bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) { +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() + // parseMacroArgument() AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; // Parse two kinds of macro invocations: @@ -1873,7 +1920,7 @@ bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) ++Parameter) { MCAsmMacroArgument MA; - if (ParseMacroArgument(MA, ArgumentDelimiter)) + if (parseMacroArgument(MA, ArgumentDelimiter)) return true; if (!MA.empty() || !NParameters) @@ -1904,31 +1951,31 @@ bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) return TokError("Too many arguments"); } -const MCAsmMacro* AsmParser::LookupMacro(StringRef Name) { - StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name); +const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) { + StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); return (I == MacroMap.end()) ? NULL : I->getValue(); } -void AsmParser::DefineMacro(StringRef Name, const MCAsmMacro& Macro) { +void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) { MacroMap[Name] = new MCAsmMacro(Macro); } -void AsmParser::UndefineMacro(StringRef Name) { - StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name); +void AsmParser::undefineMacro(StringRef Name) { + StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); if (I != MacroMap.end()) { delete I->getValue(); MacroMap.erase(I); } } -bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { +bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate // this, although we should protect against infinite loops. if (ActiveMacros.size() == 20) return TokError("macros cannot be nested more than 20 levels deep"); MCAsmMacroArguments A; - if (ParseMacroArguments(M, A)) + if (parseMacroArguments(M, A)) return true; // Remove any trailing empty arguments. Do this after-the-fact as we have @@ -1951,14 +1998,12 @@ bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { OS << ".endmacro\n"; MemoryBuffer *Instantiation = - MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); + MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); // Create the macro instantiation object and add to the current macro // instantiation stack. - MacroInstantiation *MI = new MacroInstantiation(M, NameLoc, - CurBuffer, - getTok().getLoc(), - Instantiation); + MacroInstantiation *MI = new MacroInstantiation( + M, NameLoc, CurBuffer, getTok().getLoc(), Instantiation); ActiveMacros.push_back(MI); // Jump to the macro instantiation and prime the lexer. @@ -1969,9 +2014,9 @@ bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { return false; } -void AsmParser::HandleMacroExit() { +void AsmParser::handleMacroExit() { // Jump to the EndOfStatement we should return to, and consume it. - JumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer); + jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer); Lex(); // Pop the instantiation entry. @@ -1979,29 +2024,30 @@ void AsmParser::HandleMacroExit() { ActiveMacros.pop_back(); } -static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) { +static bool isUsedIn(const MCSymbol *Sym, const MCExpr *Value) { switch (Value->getKind()) { case MCExpr::Binary: { - const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value); - return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS()); + const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value); + return isUsedIn(Sym, BE->getLHS()) || isUsedIn(Sym, BE->getRHS()); } case MCExpr::Target: case MCExpr::Constant: return false; case MCExpr::SymbolRef: { - const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol(); + const MCSymbol &S = + static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); if (S.isVariable()) - return IsUsedIn(Sym, S.getVariableValue()); + return isUsedIn(Sym, S.getVariableValue()); return &S == Sym; } case MCExpr::Unary: - return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr()); + return isUsedIn(Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr()); } llvm_unreachable("Unknown expr kind!"); } -bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, +bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, bool NoDeadStrip) { // FIXME: Use better location, we should use proper tokens. SMLoc EqualLoc = Lexer.getLoc(); @@ -2034,7 +2080,7 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, // // FIXME: Diagnostics. Note the location of the definition as a label. // FIXME: Diagnose assignment to protected identifier (e.g., register name). - if (IsUsedIn(Sym, Value)) + if (isUsedIn(Sym, Value)) return Error(EqualLoc, "Recursive use of '" + Name + "'"); else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable()) ; // Allow redefinitions of undefined symbols only used in directives. @@ -2046,7 +2092,7 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, return Error(EqualLoc, "invalid assignment to '" + Name + "'"); else if (!isa<MCConstantExpr>(Sym->getVariableValue())) return Error(EqualLoc, "invalid reassignment of non-absolute variable '" + - Name + "'"); + Name + "'"); // Don't count these checks as uses. Sym->setUsed(false); @@ -2060,7 +2106,6 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, if (NoDeadStrip) Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip); - return false; } @@ -2069,31 +2114,30 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, /// ::= string bool AsmParser::parseIdentifier(StringRef &Res) { // The assembler has relaxed rules for accepting identifiers, in particular we - // allow things like '.globl $foo', which would normally be separate - // tokens. At this level, we have already lexed so we cannot (currently) + // allow things like '.globl $foo' and '.def @feat.00', which would normally be + // separate tokens. At this level, we have already lexed so we cannot (currently) // handle this as a context dependent token, instead we detect adjacent tokens // and return the combined identifier. - if (Lexer.is(AsmToken::Dollar)) { - SMLoc DollarLoc = getLexer().getLoc(); + if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) { + SMLoc PrefixLoc = getLexer().getLoc(); - // Consume the dollar sign, and check for a following identifier. + // Consume the prefix character, and check for a following identifier. Lex(); if (Lexer.isNot(AsmToken::Identifier)) return true; - // We have a '$' followed by an identifier, make sure they are adjacent. - if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) + // We have a '$' or '@' followed by an identifier, make sure they are adjacent. + if (PrefixLoc.getPointer() + 1 != getTok().getLoc().getPointer()) return true; // Construct the joined identifier and consume the token. - Res = StringRef(DollarLoc.getPointer(), - getTok().getIdentifier().size() + 1); + Res = + StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1); Lex(); return false; } - if (Lexer.isNot(AsmToken::Identifier) && - Lexer.isNot(AsmToken::String)) + if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String)) return true; Res = getTok().getIdentifier(); @@ -2103,11 +2147,11 @@ bool AsmParser::parseIdentifier(StringRef &Res) { return false; } -/// ParseDirectiveSet: +/// parseDirectiveSet: /// ::= .equ identifier ',' expression /// ::= .equiv identifier ',' expression /// ::= .set identifier ',' expression -bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) { +bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) { StringRef Name; if (parseIdentifier(Name)) @@ -2117,7 +2161,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) { return TokError("unexpected token in '" + Twine(IDVal) + "'"); Lex(); - return ParseAssignment(Name, allow_redef, true); + return parseAssignment(Name, allow_redef, true); } bool AsmParser::parseEscapedString(std::string &Data) { @@ -2138,15 +2182,15 @@ bool AsmParser::parseEscapedString(std::string &Data) { return TokError("unexpected backslash at end of string"); // Recognize octal sequences. - if ((unsigned) (Str[i] - '0') <= 7) { + if ((unsigned)(Str[i] - '0') <= 7) { // Consume up to three octal characters. unsigned Value = Str[i] - '0'; - if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { + if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) { ++i; Value = Value * 8 + (Str[i] - '0'); - if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) { + if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) { ++i; Value = Value * 8 + (Str[i] - '0'); } @@ -2155,7 +2199,7 @@ bool AsmParser::parseEscapedString(std::string &Data) { if (Value > 255) return TokError("invalid octal escape sequence (out of range)"); - Data += (unsigned char) Value; + Data += (unsigned char)Value; continue; } @@ -2178,9 +2222,9 @@ bool AsmParser::parseEscapedString(std::string &Data) { return false; } -/// ParseDirectiveAscii: +/// parseDirectiveAscii: /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ] -bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { +bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { if (getLexer().isNot(AsmToken::EndOfStatement)) { checkForValidSection(); @@ -2192,9 +2236,9 @@ bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { if (parseEscapedString(Data)) return true; - getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE); + getStreamer().EmitBytes(Data); if (ZeroTerminated) - getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE); + getStreamer().EmitBytes(StringRef("\0", 1)); Lex(); @@ -2211,9 +2255,9 @@ bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) { return false; } -/// ParseDirectiveValue +/// parseDirectiveValue /// ::= (.byte | .short | ... ) [ expression (, expression)* ] -bool AsmParser::ParseDirectiveValue(unsigned Size) { +bool AsmParser::parseDirectiveValue(unsigned Size) { if (getLexer().isNot(AsmToken::EndOfStatement)) { checkForValidSection(); @@ -2229,9 +2273,9 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) { uint64_t IntValue = MCE->getValue(); if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) return Error(ExprLoc, "literal value out of range for directive"); - getStreamer().EmitIntValue(IntValue, Size, DEFAULT_ADDRSPACE); + getStreamer().EmitIntValue(IntValue, Size); } else - getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE); + getStreamer().EmitValue(Value, Size); if (getLexer().is(AsmToken::EndOfStatement)) break; @@ -2247,9 +2291,9 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) { return false; } -/// ParseDirectiveRealValue +/// parseDirectiveRealValue /// ::= (.single | .double) [ expression (, expression)* ] -bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { +bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) { if (getLexer().isNot(AsmToken::EndOfStatement)) { checkForValidSection(); @@ -2279,7 +2323,7 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { else return TokError("invalid floating point literal"); } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) == - APFloat::opInvalidOp) + APFloat::opInvalidOp) return TokError("invalid floating point literal"); if (IsNeg) Value.changeSign(); @@ -2290,7 +2334,7 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { // Emit the value as an integer. APInt AsInt = Value.bitcastToAPInt(); getStreamer().EmitIntValue(AsInt.getLimitedValue(), - AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE); + AsInt.getBitWidth() / 8); if (getLexer().is(AsmToken::EndOfStatement)) break; @@ -2305,9 +2349,9 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) { return false; } -/// ParseDirectiveZero +/// parseDirectiveZero /// ::= .zero expression -bool AsmParser::ParseDirectiveZero() { +bool AsmParser::parseDirectiveZero() { checkForValidSection(); int64_t NumBytes; @@ -2326,53 +2370,58 @@ bool AsmParser::ParseDirectiveZero() { Lex(); - getStreamer().EmitFill(NumBytes, Val, DEFAULT_ADDRSPACE); + getStreamer().EmitFill(NumBytes, Val); return false; } -/// ParseDirectiveFill -/// ::= .fill expression , expression , expression -bool AsmParser::ParseDirectiveFill() { +/// parseDirectiveFill +/// ::= .fill expression [ , expression [ , expression ] ] +bool AsmParser::parseDirectiveFill() { checkForValidSection(); int64_t NumValues; if (parseAbsoluteExpression(NumValues)) return true; - if (getLexer().isNot(AsmToken::Comma)) - return TokError("unexpected token in '.fill' directive"); - Lex(); + int64_t FillSize = 1; + int64_t FillExpr = 0; - int64_t FillSize; - if (parseAbsoluteExpression(FillSize)) - return true; + if (getLexer().isNot(AsmToken::EndOfStatement)) { + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in '.fill' directive"); + Lex(); - if (getLexer().isNot(AsmToken::Comma)) - return TokError("unexpected token in '.fill' directive"); - Lex(); + if (parseAbsoluteExpression(FillSize)) + return true; - int64_t FillExpr; - if (parseAbsoluteExpression(FillExpr)) - return true; + if (getLexer().isNot(AsmToken::EndOfStatement)) { + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in '.fill' directive"); + Lex(); - if (getLexer().isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in '.fill' directive"); + if (parseAbsoluteExpression(FillExpr)) + return true; - Lex(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.fill' directive"); + + Lex(); + } + } if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8) return TokError("invalid '.fill' size, expected 1, 2, 4, or 8"); for (uint64_t i = 0, e = NumValues; i != e; ++i) - getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE); + getStreamer().EmitIntValue(FillExpr, FillSize); return false; } -/// ParseDirectiveOrg +/// parseDirectiveOrg /// ::= .org expression [ , expression ] -bool AsmParser::ParseDirectiveOrg() { +bool AsmParser::parseDirectiveOrg() { checkForValidSection(); const MCExpr *Offset; @@ -2405,9 +2454,9 @@ bool AsmParser::ParseDirectiveOrg() { return false; } -/// ParseDirectiveAlign +/// parseDirectiveAlign /// ::= {.align, ...} expression [ , expression [ , expression ]] -bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { +bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) { checkForValidSection(); SMLoc AlignmentLoc = getLexer().getLoc(); @@ -2471,13 +2520,13 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { if (MaxBytesLoc.isValid()) { if (MaxBytesToFill < 1) { Error(MaxBytesLoc, "alignment directive can never be satisfied in this " - "many bytes, ignoring maximum bytes expression"); + "many bytes, ignoring maximum bytes expression"); MaxBytesToFill = 0; } if (MaxBytesToFill >= Alignment) { Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and " - "has no effect"); + "has no effect"); MaxBytesToFill = 0; } } @@ -2497,10 +2546,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { return false; } -/// ParseDirectiveFile +/// parseDirectiveFile /// ::= .file [number] filename /// ::= .file number directory filename -bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { // FIXME: I'm not sure what this is. int64_t FileNumber = -1; SMLoc FileNumberLoc = getLexer().getLoc(); @@ -2516,17 +2565,21 @@ bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) { return TokError("unexpected token in '.file' directive"); // Usually the directory and filename together, otherwise just the directory. - StringRef Path = getTok().getString(); - Path = Path.substr(1, Path.size()-2); + // Allow the strings to have escaped octal character sequence. + std::string Path = getTok().getString(); + if (parseEscapedString(Path)) + return true; Lex(); StringRef Directory; StringRef Filename; + std::string FilenameData; if (getLexer().is(AsmToken::String)) { if (FileNumber == -1) return TokError("explicit path specified, but no file number"); - Filename = getTok().getString(); - Filename = Filename.substr(1, Filename.size()-2); + if (parseEscapedString(FilenameData)) + return true; + Filename = FilenameData; Directory = Path; Lex(); } else { @@ -2540,8 +2593,9 @@ bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) { getStreamer().EmitFileDirective(Filename); else { if (getContext().getGenDwarfForAssembly() == true) - Error(DirectiveLoc, "input can't have .file dwarf directives when -g is " - "used to generate dwarf debug info for assembly code"); + Error(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)) Error(FileNumberLoc, "file number already allocated"); @@ -2550,15 +2604,15 @@ bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) { return false; } -/// ParseDirectiveLine +/// parseDirectiveLine /// ::= .line [number] -bool AsmParser::ParseDirectiveLine() { +bool AsmParser::parseDirectiveLine() { if (getLexer().isNot(AsmToken::EndOfStatement)) { if (getLexer().isNot(AsmToken::Integer)) return TokError("unexpected token in '.line' directive"); int64_t LineNumber = getTok().getIntVal(); - (void) LineNumber; + (void)LineNumber; Lex(); // FIXME: Do something with the .line. @@ -2570,14 +2624,14 @@ bool AsmParser::ParseDirectiveLine() { return false; } -/// ParseDirectiveLoc +/// parseDirectiveLoc /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end] /// [epilogue_begin] [is_stmt VALUE] [isa VALUE] /// The first number is a file number, must have been previously assigned with /// a .file directive, the second number is the line number and optionally the /// third number is a column position (zero if not specified). The remaining /// optional items are .loc sub-directives. -bool AsmParser::ParseDirectiveLoc() { +bool AsmParser::parseDirectiveLoc() { if (getLexer().isNot(AsmToken::Integer)) return TokError("unexpected token in '.loc' directive"); int64_t FileNumber = getTok().getIntVal(); @@ -2590,8 +2644,8 @@ bool AsmParser::ParseDirectiveLoc() { int64_t LineNumber = 0; if (getLexer().is(AsmToken::Integer)) { LineNumber = getTok().getIntVal(); - if (LineNumber < 1) - return TokError("line number less than one in '.loc' directive"); + if (LineNumber < 0) + return TokError("line number less than zero in '.loc' directive"); Lex(); } @@ -2671,15 +2725,15 @@ bool AsmParser::ParseDirectiveLoc() { return false; } -/// ParseDirectiveStabs +/// parseDirectiveStabs /// ::= .stabs string, number, number, number -bool AsmParser::ParseDirectiveStabs() { +bool AsmParser::parseDirectiveStabs() { return TokError("unsupported directive '.stabs'"); } -/// ParseDirectiveCFISections +/// parseDirectiveCFISections /// ::= .cfi_sections section [, section] -bool AsmParser::ParseDirectiveCFISections() { +bool AsmParser::parseDirectiveCFISections() { StringRef Name; bool EH = false; bool Debug = false; @@ -2708,40 +2762,40 @@ bool AsmParser::ParseDirectiveCFISections() { return false; } -/// ParseDirectiveCFIStartProc +/// parseDirectiveCFIStartProc /// ::= .cfi_startproc -bool AsmParser::ParseDirectiveCFIStartProc() { +bool AsmParser::parseDirectiveCFIStartProc() { getStreamer().EmitCFIStartProc(); return false; } -/// ParseDirectiveCFIEndProc +/// parseDirectiveCFIEndProc /// ::= .cfi_endproc -bool AsmParser::ParseDirectiveCFIEndProc() { +bool AsmParser::parseDirectiveCFIEndProc() { getStreamer().EmitCFIEndProc(); return false; } -/// ParseRegisterOrRegisterNumber - parse register name or number. -bool AsmParser::ParseRegisterOrRegisterNumber(int64_t &Register, +/// \brief parse register name or number. +bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc) { unsigned RegNo; if (getLexer().isNot(AsmToken::Integer)) { if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) return true; - Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true); + Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true); } else return parseAbsoluteExpression(Register); return false; } -/// ParseDirectiveCFIDefCfa +/// parseDirectiveCFIDefCfa /// ::= .cfi_def_cfa register, offset -bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { int64_t Register = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; if (getLexer().isNot(AsmToken::Comma)) @@ -2756,9 +2810,9 @@ bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) { return false; } -/// ParseDirectiveCFIDefCfaOffset +/// parseDirectiveCFIDefCfaOffset /// ::= .cfi_def_cfa_offset offset -bool AsmParser::ParseDirectiveCFIDefCfaOffset() { +bool AsmParser::parseDirectiveCFIDefCfaOffset() { int64_t Offset = 0; if (parseAbsoluteExpression(Offset)) return true; @@ -2767,11 +2821,11 @@ bool AsmParser::ParseDirectiveCFIDefCfaOffset() { return false; } -/// ParseDirectiveCFIRegister +/// parseDirectiveCFIRegister /// ::= .cfi_register register, register -bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) { int64_t Register1 = 0; - if (ParseRegisterOrRegisterNumber(Register1, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc)) return true; if (getLexer().isNot(AsmToken::Comma)) @@ -2779,16 +2833,23 @@ bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) { Lex(); int64_t Register2 = 0; - if (ParseRegisterOrRegisterNumber(Register2, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register2, DirectiveLoc)) return true; getStreamer().EmitCFIRegister(Register1, Register2); return false; } -/// ParseDirectiveCFIAdjustCfaOffset +/// parseDirectiveCFIWindowSave +/// ::= .cfi_window_save +bool AsmParser::parseDirectiveCFIWindowSave() { + getStreamer().EmitCFIWindowSave(); + return false; +} + +/// parseDirectiveCFIAdjustCfaOffset /// ::= .cfi_adjust_cfa_offset adjustment -bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() { +bool AsmParser::parseDirectiveCFIAdjustCfaOffset() { int64_t Adjustment = 0; if (parseAbsoluteExpression(Adjustment)) return true; @@ -2797,24 +2858,24 @@ bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() { return false; } -/// ParseDirectiveCFIDefCfaRegister +/// parseDirectiveCFIDefCfaRegister /// ::= .cfi_def_cfa_register register -bool AsmParser::ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) { int64_t Register = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; getStreamer().EmitCFIDefCfaRegister(Register); return false; } -/// ParseDirectiveCFIOffset +/// parseDirectiveCFIOffset /// ::= .cfi_offset register, offset -bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) { int64_t Register = 0; int64_t Offset = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; if (getLexer().isNot(AsmToken::Comma)) @@ -2828,12 +2889,12 @@ bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) { return false; } -/// ParseDirectiveCFIRelOffset +/// parseDirectiveCFIRelOffset /// ::= .cfi_rel_offset register, offset -bool AsmParser::ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) { int64_t Register = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; if (getLexer().isNot(AsmToken::Comma)) @@ -2870,11 +2931,11 @@ static bool isValidEncoding(int64_t Encoding) { return true; } -/// ParseDirectiveCFIPersonalityOrLsda +/// parseDirectiveCFIPersonalityOrLsda /// IsPersonality true for cfi_personality, false for cfi_lsda /// ::= .cfi_personality encoding, [symbol_name] /// ::= .cfi_lsda encoding, [symbol_name] -bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { +bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { int64_t Encoding = 0; if (parseAbsoluteExpression(Encoding)) return true; @@ -2901,46 +2962,46 @@ bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { return false; } -/// ParseDirectiveCFIRememberState +/// parseDirectiveCFIRememberState /// ::= .cfi_remember_state -bool AsmParser::ParseDirectiveCFIRememberState() { +bool AsmParser::parseDirectiveCFIRememberState() { getStreamer().EmitCFIRememberState(); return false; } -/// ParseDirectiveCFIRestoreState +/// parseDirectiveCFIRestoreState /// ::= .cfi_remember_state -bool AsmParser::ParseDirectiveCFIRestoreState() { +bool AsmParser::parseDirectiveCFIRestoreState() { getStreamer().EmitCFIRestoreState(); return false; } -/// ParseDirectiveCFISameValue +/// parseDirectiveCFISameValue /// ::= .cfi_same_value register -bool AsmParser::ParseDirectiveCFISameValue(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) { int64_t Register = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; getStreamer().EmitCFISameValue(Register); return false; } -/// ParseDirectiveCFIRestore +/// parseDirectiveCFIRestore /// ::= .cfi_restore register -bool AsmParser::ParseDirectiveCFIRestore(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) { int64_t Register = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; getStreamer().EmitCFIRestore(Register); return false; } -/// ParseDirectiveCFIEscape +/// parseDirectiveCFIEscape /// ::= .cfi_escape expression[,...] -bool AsmParser::ParseDirectiveCFIEscape() { +bool AsmParser::parseDirectiveCFIEscape() { std::string Values; int64_t CurrValue; if (parseAbsoluteExpression(CurrValue)) @@ -2961,9 +3022,9 @@ bool AsmParser::ParseDirectiveCFIEscape() { return false; } -/// ParseDirectiveCFISignalFrame +/// parseDirectiveCFISignalFrame /// ::= .cfi_signal_frame -bool AsmParser::ParseDirectiveCFISignalFrame() { +bool AsmParser::parseDirectiveCFISignalFrame() { if (getLexer().isNot(AsmToken::EndOfStatement)) return Error(getLexer().getLoc(), "unexpected token in '.cfi_signal_frame'"); @@ -2972,40 +3033,40 @@ bool AsmParser::ParseDirectiveCFISignalFrame() { return false; } -/// ParseDirectiveCFIUndefined +/// parseDirectiveCFIUndefined /// ::= .cfi_undefined register -bool AsmParser::ParseDirectiveCFIUndefined(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) { int64_t Register = 0; - if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc)) + if (parseRegisterOrRegisterNumber(Register, DirectiveLoc)) return true; getStreamer().EmitCFIUndefined(Register); return false; } -/// ParseDirectiveMacrosOnOff +/// parseDirectiveMacrosOnOff /// ::= .macros_on /// ::= .macros_off -bool AsmParser::ParseDirectiveMacrosOnOff(StringRef Directive) { +bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) { if (getLexer().isNot(AsmToken::EndOfStatement)) return Error(getLexer().getLoc(), "unexpected token in '" + Directive + "' directive"); - SetMacrosEnabled(Directive == ".macros_on"); + setMacrosEnabled(Directive == ".macros_on"); return false; } -/// ParseDirectiveMacro +/// parseDirectiveMacro /// ::= .macro name [parameters] -bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { StringRef Name; if (parseIdentifier(Name)) return TokError("expected identifier in '.macro' directive"); MCAsmMacroParameters Parameters; // Argument delimiter is initially unknown. It will be set by - // ParseMacroArgument() + // parseMacroArgument() AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; if (getLexer().isNot(AsmToken::EndOfStatement)) { for (;;) { @@ -3015,7 +3076,7 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) { if (getLexer().is(AsmToken::Equal)) { Lex(); - if (ParseMacroArgument(Parameter.second, ArgumentDelimiter)) + if (parseMacroArgument(Parameter.second, ArgumentDelimiter)) return true; } @@ -3055,19 +3116,19 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) { eatToEndOfStatement(); } - if (LookupMacro(Name)) { + if (lookupMacro(Name)) { return Error(DirectiveLoc, "macro '" + Name + "' is already defined"); } const char *BodyStart = StartToken.getLoc().getPointer(); const char *BodyEnd = EndToken.getLoc().getPointer(); StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart); - CheckForBadMacro(DirectiveLoc, Name, Body, Parameters); - DefineMacro(Name, MCAsmMacro(Name, Body, Parameters)); + checkForBadMacro(DirectiveLoc, Name, Body, Parameters); + defineMacro(Name, MCAsmMacro(Name, Body, Parameters)); return false; } -/// CheckForBadMacro +/// checkForBadMacro /// /// 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 @@ -3081,7 +3142,7 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) { /// 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, +void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body, MCAsmMacroParameters Parameters) { // If this macro is not defined with named parameters the warning we are @@ -3119,21 +3180,21 @@ void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, break; if (Body[Pos] == '$') { - switch (Body[Pos+1]) { - // $$ => $ + switch (Body[Pos + 1]) { + // $$ => $ case '$': break; - // $n => number of arguments + // $n => number of arguments case 'n': PositionalParametersFound = true; break; - // $[0-9] => argument + // $[0-9] => argument default: { PositionalParametersFound = true; break; - } + } } Pos += 2; } else { @@ -3141,19 +3202,19 @@ void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, while (isIdentifierChar(Body[I]) && I + 1 != End) ++I; - const char *Begin = Body.data() + Pos +1; - StringRef Argument(Begin, I - (Pos +1)); + const char *Begin = Body.data() + Pos + 1; + StringRef Argument(Begin, I - (Pos + 1)); unsigned Index = 0; for (; Index < NParameters; ++Index) if (Parameters[Index].first == Argument) break; if (Index == NParameters) { - if (Body[Pos+1] == '(' && Body[Pos+2] == ')') - Pos += 3; - else { - Pos = I; - } + if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') + Pos += 3; + else { + Pos = I; + } } else { NamedParametersFound = true; Pos += 1 + Argument.size(); @@ -3169,29 +3230,29 @@ void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, "found in body which will have no effect"); } -/// ParseDirectiveEndMacro +/// parseDirectiveEndMacro /// ::= .endm /// ::= .endmacro -bool AsmParser::ParseDirectiveEndMacro(StringRef Directive) { +bool AsmParser::parseDirectiveEndMacro(StringRef Directive) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '" + Directive + "' directive"); // If we are inside a macro instantiation, terminate the current // instantiation. - if (InsideMacroInstantiation()) { - HandleMacroExit(); + if (isInsideMacroInstantiation()) { + handleMacroExit(); return false; } // Otherwise, this .endmacro is a stray entry in the file; well formed // .endmacro directives are handled during the macro definition parsing. return TokError("unexpected '" + Directive + "' in file, " - "no current macro definition"); + "no current macro definition"); } -/// ParseDirectivePurgeMacro +/// parseDirectivePurgeMacro /// ::= .purgem -bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) { StringRef Name; if (parseIdentifier(Name)) return TokError("expected identifier in '.purgem' directive"); @@ -3199,16 +3260,16 @@ bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.purgem' directive"); - if (!LookupMacro(Name)) + if (!lookupMacro(Name)) return Error(DirectiveLoc, "macro '" + Name + "' is not defined"); - UndefineMacro(Name); + undefineMacro(Name); return false; } -/// ParseDirectiveBundleAlignMode +/// parseDirectiveBundleAlignMode /// ::= {.bundle_align_mode} expression -bool AsmParser::ParseDirectiveBundleAlignMode() { +bool AsmParser::parseDirectiveBundleAlignMode() { checkForValidSection(); // Expect a single argument: an expression that evaluates to a constant @@ -3232,9 +3293,9 @@ bool AsmParser::ParseDirectiveBundleAlignMode() { return false; } -/// ParseDirectiveBundleLock +/// parseDirectiveBundleLock /// ::= {.bundle_lock} [align_to_end] -bool AsmParser::ParseDirectiveBundleLock() { +bool AsmParser::parseDirectiveBundleLock() { checkForValidSection(); bool AlignToEnd = false; @@ -3242,7 +3303,7 @@ bool AsmParser::ParseDirectiveBundleLock() { StringRef Option; SMLoc Loc = getTok().getLoc(); const char *kInvalidOptionError = - "invalid option for '.bundle_lock' directive"; + "invalid option for '.bundle_lock' directive"; if (parseIdentifier(Option)) return Error(Loc, kInvalidOptionError); @@ -3261,9 +3322,9 @@ bool AsmParser::ParseDirectiveBundleLock() { return false; } -/// ParseDirectiveBundleLock +/// parseDirectiveBundleLock /// ::= {.bundle_lock} -bool AsmParser::ParseDirectiveBundleUnlock() { +bool AsmParser::parseDirectiveBundleUnlock() { checkForValidSection(); if (getLexer().isNot(AsmToken::EndOfStatement)) @@ -3274,9 +3335,9 @@ bool AsmParser::ParseDirectiveBundleUnlock() { return false; } -/// ParseDirectiveSpace +/// parseDirectiveSpace /// ::= (.skip | .space) expression [ , expression ] -bool AsmParser::ParseDirectiveSpace(StringRef IDVal) { +bool AsmParser::parseDirectiveSpace(StringRef IDVal) { checkForValidSection(); int64_t NumBytes; @@ -3299,18 +3360,18 @@ bool AsmParser::ParseDirectiveSpace(StringRef IDVal) { Lex(); if (NumBytes <= 0) - return TokError("invalid number of bytes in '" + - Twine(IDVal) + "' directive"); + return TokError("invalid number of bytes in '" + Twine(IDVal) + + "' directive"); // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0. - getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE); + getStreamer().EmitFill(NumBytes, FillExpr); return false; } -/// ParseDirectiveLEB128 +/// parseDirectiveLEB128 /// ::= (.sleb128 | .uleb128) expression -bool AsmParser::ParseDirectiveLEB128(bool Signed) { +bool AsmParser::parseDirectiveLEB128(bool Signed) { checkForValidSection(); const MCExpr *Value; @@ -3328,9 +3389,9 @@ bool AsmParser::ParseDirectiveLEB128(bool Signed) { return false; } -/// ParseDirectiveSymbolAttribute +/// parseDirectiveSymbolAttribute /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ] -bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { +bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { if (getLexer().isNot(AsmToken::EndOfStatement)) { for (;;) { StringRef Name; @@ -3345,7 +3406,8 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { if (Sym->isTemporary()) return Error(Loc, "non-local symbol required in directive"); - getStreamer().EmitSymbolAttribute(Sym, Attr); + if (!getStreamer().EmitSymbolAttribute(Sym, Attr)) + return Error(Loc, "unable to emit symbol attribute"); if (getLexer().is(AsmToken::EndOfStatement)) break; @@ -3360,9 +3422,9 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { return false; } -/// ParseDirectiveComm +/// parseDirectiveComm /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ] -bool AsmParser::ParseDirectiveComm(bool IsLocal) { +bool AsmParser::parseDirectiveComm(bool IsLocal) { checkForValidSection(); SMLoc IDLoc = getLexer().getLoc(); @@ -3412,14 +3474,14 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { // but a size of .lcomm creates a bss symbol of size zero. if (Size < 0) return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't " - "be less than zero"); + "be less than zero"); // NOTE: The alignment in the directive is a power of 2 value, the assembler // may internally end up wanting an alignment in bytes. // FIXME: Diagnose overflow. if (Pow2Alignment < 0) return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive " - "alignment, can't be less than zero"); + "alignment, can't be less than zero"); if (!Sym->isUndefined()) return Error(IDLoc, "invalid symbol redefinition"); @@ -3434,9 +3496,9 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { return false; } -/// ParseDirectiveAbort +/// parseDirectiveAbort /// ::= .abort [... message ...] -bool AsmParser::ParseDirectiveAbort() { +bool AsmParser::parseDirectiveAbort() { // FIXME: Use loc from directive. SMLoc Loc = getLexer().getLoc(); @@ -3455,25 +3517,25 @@ bool AsmParser::ParseDirectiveAbort() { return false; } -/// ParseDirectiveInclude +/// parseDirectiveInclude /// ::= .include "filename" -bool AsmParser::ParseDirectiveInclude() { +bool AsmParser::parseDirectiveInclude() { if (getLexer().isNot(AsmToken::String)) return TokError("expected string in '.include' directive"); - std::string Filename = getTok().getString(); + // Allow the strings to have escaped octal character sequence. + std::string Filename; + if (parseEscapedString(Filename)) + return true; SMLoc IncludeLoc = getLexer().getLoc(); Lex(); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.include' directive"); - // Strip the quotes. - Filename = Filename.substr(1, Filename.size()-2); - // Attempt to switch the lexer to the included file before consuming the end // of statement to avoid losing it when we switch. - if (EnterIncludeFile(Filename)) { + if (enterIncludeFile(Filename)) { Error(IncludeLoc, "Could not find include file '" + Filename + "'"); return true; } @@ -3481,24 +3543,24 @@ bool AsmParser::ParseDirectiveInclude() { return false; } -/// ParseDirectiveIncbin +/// parseDirectiveIncbin /// ::= .incbin "filename" -bool AsmParser::ParseDirectiveIncbin() { +bool AsmParser::parseDirectiveIncbin() { if (getLexer().isNot(AsmToken::String)) return TokError("expected string in '.incbin' directive"); - std::string Filename = getTok().getString(); + // Allow the strings to have escaped octal character sequence. + std::string Filename; + if (parseEscapedString(Filename)) + return true; SMLoc IncbinLoc = getLexer().getLoc(); Lex(); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.incbin' directive"); - // Strip the quotes. - Filename = Filename.substr(1, Filename.size()-2); - // Attempt to process the included file. - if (ProcessIncbinFile(Filename)) { + if (processIncbinFile(Filename)) { Error(IncbinLoc, "Could not find incbin file '" + Filename + "'"); return true; } @@ -3506,9 +3568,9 @@ bool AsmParser::ParseDirectiveIncbin() { return false; } -/// ParseDirectiveIf +/// parseDirectiveIf /// ::= .if expression -bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; if (TheCondState.Ignore) { @@ -3530,9 +3592,9 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) { return false; } -/// ParseDirectiveIfb +/// parseDirectiveIfb /// ::= .ifb string -bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { +bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; @@ -3553,16 +3615,16 @@ bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) { return false; } -/// ParseDirectiveIfc +/// parseDirectiveIfc /// ::= .ifc string1, string2 -bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { +bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; if (TheCondState.Ignore) { eatToEndOfStatement(); } else { - StringRef Str1 = ParseStringToComma(); + StringRef Str1 = parseStringToComma(); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in '.ifc' directive"); @@ -3583,9 +3645,9 @@ bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { return false; } -/// ParseDirectiveIfdef +/// parseDirectiveIfdef /// ::= .ifdef symbol -bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { +bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { StringRef Name; TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; @@ -3610,9 +3672,9 @@ bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { return false; } -/// ParseDirectiveElseIf +/// parseDirectiveElseIf /// ::= .elseif expression -bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) { if (TheCondState.TheCond != AsmCond::IfCond && TheCondState.TheCond != AsmCond::ElseIfCond) Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or " @@ -3641,9 +3703,9 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) { return false; } -/// ParseDirectiveElse +/// parseDirectiveElse /// ::= .else -bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.else' directive"); @@ -3665,16 +3727,15 @@ bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) { return false; } -/// ParseDirectiveEndIf +/// parseDirectiveEndIf /// ::= .endif -bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.endif' directive"); Lex(); - if ((TheCondState.TheCond == AsmCond::NoCond) || - TheCondStack.empty()) + if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty()) Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or " ".else"); if (!TheCondStack.empty()) { @@ -3718,7 +3779,6 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".extern"] = DK_EXTERN; DirectiveKindMap[".globl"] = DK_GLOBL; DirectiveKindMap[".global"] = DK_GLOBAL; - DirectiveKindMap[".indirect_symbol"] = DK_INDIRECT_SYMBOL; DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE; DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP; DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER; @@ -3780,6 +3840,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME; DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED; DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER; + DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE; DirectiveKindMap[".macros_on"] = DK_MACROS_ON; DirectiveKindMap[".macros_off"] = DK_MACROS_OFF; DirectiveKindMap[".macro"] = DK_MACRO; @@ -3788,8 +3849,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".purgem"] = DK_PURGEM; } - -MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { +MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { AsmToken EndToken, StartToken = getTok(); unsigned NestLevel = 0; @@ -3806,8 +3866,7 @@ MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { } // Otherwise, check whether we have reached the .endr. - if (Lexer.is(AsmToken::Identifier) && - getTok().getIdentifier() == ".endr") { + if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") { if (NestLevel == 0) { EndToken = getTok(); Lex(); @@ -3831,22 +3890,21 @@ MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) { // We Are Anonymous. StringRef Name; MCAsmMacroParameters Parameters; - return new MCAsmMacro(Name, Body, Parameters); + MacroLikeBodies.push_back(MCAsmMacro(Name, Body, Parameters)); + return &MacroLikeBodies.back(); } -void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, +void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, raw_svector_ostream &OS) { OS << ".endr\n"; MemoryBuffer *Instantiation = - MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); + MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>"); // Create the macro instantiation object and add to the current macro // instantiation stack. - MacroInstantiation *MI = new MacroInstantiation(M, DirectiveLoc, - CurBuffer, - getTok().getLoc(), - Instantiation); + MacroInstantiation *MI = new MacroInstantiation( + M, DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation); ActiveMacros.push_back(MI); // Jump to the macro instantiation and prime the lexer. @@ -3855,7 +3913,7 @@ void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc, Lex(); } -bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) { int64_t Count; if (parseAbsoluteExpression(Count)) return TokError("unexpected token in '.rept' directive"); @@ -3870,7 +3928,7 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { Lex(); // Lex the rept definition. - MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc); + MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); if (!M) return true; @@ -3884,14 +3942,14 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) { if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc())) return true; } - InstantiateMacroLikeBody(M, DirectiveLoc, OS); + instantiateMacroLikeBody(M, DirectiveLoc, OS); return false; } -/// ParseDirectiveIrp +/// parseDirectiveIrp /// ::= .irp symbol,values -bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { MCAsmMacroParameters Parameters; MCAsmMacroParameter Parameter; @@ -3906,14 +3964,14 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { Lex(); MCAsmMacroArguments A; - if (ParseMacroArguments(0, A)) + if (parseMacroArguments(0, A)) return true; // Eat the end of statement. Lex(); // Lex the irp definition. - MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc); + MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); if (!M) return true; @@ -3930,14 +3988,14 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { return true; } - InstantiateMacroLikeBody(M, DirectiveLoc, OS); + instantiateMacroLikeBody(M, DirectiveLoc, OS); return false; } -/// ParseDirectiveIrpc +/// parseDirectiveIrpc /// ::= .irpc symbol,values -bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { MCAsmMacroParameters Parameters; MCAsmMacroParameter Parameter; @@ -3952,7 +4010,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { Lex(); MCAsmMacroArguments A; - if (ParseMacroArguments(0, A)) + if (parseMacroArguments(0, A)) return true; if (A.size() != 1 || A.front().size() != 1) @@ -3962,7 +4020,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { Lex(); // Lex the irpc definition. - MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc); + MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc); if (!M) return true; @@ -3975,7 +4033,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { std::size_t I, End = Values.size(); for (I = 0; I < End; ++I) { MCAsmMacroArgument Arg; - Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1))); + Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1))); MCAsmMacroArguments Args; Args.push_back(Arg); @@ -3984,24 +4042,24 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { return true; } - InstantiateMacroLikeBody(M, DirectiveLoc, OS); + instantiateMacroLikeBody(M, DirectiveLoc, OS); return false; } -bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) { if (ActiveMacros.empty()) return TokError("unmatched '.endr' directive"); // The only .repl that should get here are the ones created by - // InstantiateMacroLikeBody. + // instantiateMacroLikeBody. assert(getLexer().is(AsmToken::EndOfStatement)); - HandleMacroExit(); + handleMacroExit(); return false; } -bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, +bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t Len) { const MCExpr *Value; SMLoc ExprLoc = getLexer().getLoc(); @@ -4018,7 +4076,7 @@ bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, return false; } -bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { +bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { const MCExpr *Value; SMLoc ExprLoc = getLexer().getLoc(); if (parseExpression(Value)) @@ -4030,16 +4088,15 @@ bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { if (!isPowerOf2_64(IntValue)) return Error(ExprLoc, "literal value not a power of two greater then zero"); - Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5, - Log2_64(IntValue))); + Info.AsmRewrites->push_back( + AsmRewrite(AOK_Align, IDLoc, 5, Log2_64(IntValue))); return false; } // We are comparing pointers, but the pointers are relative to a single string. // Thus, this should always be deterministic. -static int RewritesSort(const void *A, const void *B) { - const AsmRewrite *AsmRewriteA = static_cast<const AsmRewrite *>(A); - const AsmRewrite *AsmRewriteB = static_cast<const AsmRewrite *>(B); +static int rewritesSort(const AsmRewrite *AsmRewriteA, + const AsmRewrite *AsmRewriteB) { if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) return -1; if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) @@ -4049,25 +4106,22 @@ static int RewritesSort(const void *A, const void *B) { // rewrite to the same location. Make sure the SizeDirective rewrite is // performed first, then the Imm/ImmPrefix and finally the Input/Output. This // ensures the sort algorithm is stable. - if (AsmRewritePrecedence [AsmRewriteA->Kind] > - AsmRewritePrecedence [AsmRewriteB->Kind]) + if (AsmRewritePrecedence[AsmRewriteA->Kind] > + AsmRewritePrecedence[AsmRewriteB->Kind]) return -1; - if (AsmRewritePrecedence [AsmRewriteA->Kind] < - AsmRewritePrecedence [AsmRewriteB->Kind]) + if (AsmRewritePrecedence[AsmRewriteA->Kind] < + AsmRewritePrecedence[AsmRewriteB->Kind]) return 1; - llvm_unreachable ("Unstable rewrite sort."); + llvm_unreachable("Unstable rewrite sort."); } -bool -AsmParser::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) { +bool AsmParser::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) { SmallVector<void *, 4> InputDecls; SmallVector<void *, 4> OutputDecls; SmallVector<bool, 4> InputDeclsAddressOf; @@ -4086,7 +4140,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString, unsigned OutputIdx = 0; while (getLexer().isNot(AsmToken::Eof)) { ParseStatementInfo Info(&AsmStrRewrites); - if (ParseStatement(Info)) + if (parseStatement(Info)) return true; if (Info.ParseError) @@ -4174,7 +4228,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString, raw_string_ostream OS(AsmStringIR); const char *AsmStart = SrcMgr.getMemoryBuffer(0)->getBufferStart(); const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd(); - array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), RewritesSort); + array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort); for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) { @@ -4199,7 +4253,8 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString, unsigned AdditionalSkip = 0; // Rewrite expressions in $N notation. switch (Kind) { - default: break; + default: + break; case AOK_Imm: OS << "$$" << (*I).Val; break; @@ -4254,8 +4309,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString, } /// \brief Create an MCAsmParser instance. -MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, - MCContext &C, MCStreamer &Out, - const MCAsmInfo &MAI) { +MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C, + MCStreamer &Out, const MCAsmInfo &MAI) { return new AsmParser(SM, C, Out, MAI); } diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp index a50eab2..d8343a3 100644 --- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -35,6 +35,13 @@ class COFFAsmParser : public MCAsmParserExtension { unsigned Characteristics, SectionKind Kind); + bool ParseSectionSwitch(StringRef Section, unsigned Characteristics, + SectionKind Kind, StringRef COMDATSymName, + COFF::COMDATType Type, const MCSectionCOFF *Assoc); + + bool ParseSectionName(StringRef &SectionName); + bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags); + virtual void Initialize(MCAsmParser &Parser) { // Call the base implementation. MCAsmParserExtension::Initialize(Parser); @@ -42,11 +49,13 @@ class COFFAsmParser : public MCAsmParserExtension { addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text"); addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data"); addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss"); + addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32"); + addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce"); // Win64 EH directives. addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>( @@ -100,11 +109,15 @@ class COFFAsmParser : public MCAsmParserExtension { SectionKind::getBSS()); } + bool ParseDirectiveSection(StringRef, SMLoc); bool ParseDirectiveDef(StringRef, SMLoc); bool ParseDirectiveScl(StringRef, SMLoc); bool ParseDirectiveType(StringRef, SMLoc); bool ParseDirectiveEndef(StringRef, SMLoc); bool ParseDirectiveSecRel32(StringRef, SMLoc); + bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, + const MCSectionCOFF *&Assoc); + bool ParseDirectiveLinkOnce(StringRef, SMLoc); // Win64 EH directives. bool ParseSEHDirectiveStartProc(StringRef, SMLoc); @@ -130,6 +143,119 @@ public: } // end annonomous namespace. +static SectionKind computeSectionKind(unsigned Flags) { + if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE) + return SectionKind::getText(); + if (Flags & COFF::IMAGE_SCN_MEM_READ && + (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0) + return SectionKind::getReadOnly(); + return SectionKind::getDataRel(); +} + +bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { + enum { + None = 0, + Alloc = 1 << 0, + Code = 1 << 1, + Load = 1 << 2, + InitData = 1 << 3, + Shared = 1 << 4, + NoLoad = 1 << 5, + NoRead = 1 << 6, + NoWrite = 1 << 7 + }; + + bool ReadOnlyRemoved = false; + unsigned SecFlags = None; + + for (unsigned i = 0; i < FlagsString.size(); ++i) { + switch (FlagsString[i]) { + case 'a': + // Ignored. + break; + + case 'b': // bss section + SecFlags |= Alloc; + if (SecFlags & InitData) + return TokError("conflicting section flags 'b' and 'd'."); + SecFlags &= ~Load; + break; + + case 'd': // data section + SecFlags |= InitData; + if (SecFlags & Alloc) + return TokError("conflicting section flags 'b' and 'd'."); + SecFlags &= ~NoWrite; + if ((SecFlags & NoLoad) == 0) + SecFlags |= Load; + break; + + case 'n': // section is not loaded + SecFlags |= NoLoad; + SecFlags &= ~Load; + break; + + case 'r': // read-only + ReadOnlyRemoved = false; + SecFlags |= NoWrite; + if ((SecFlags & Code) == 0) + SecFlags |= InitData; + if ((SecFlags & NoLoad) == 0) + SecFlags |= Load; + break; + + case 's': // shared section + SecFlags |= Shared | InitData; + SecFlags &= ~NoWrite; + if ((SecFlags & NoLoad) == 0) + SecFlags |= Load; + break; + + case 'w': // writable + SecFlags &= ~NoWrite; + ReadOnlyRemoved = true; + break; + + case 'x': // executable section + SecFlags |= Code; + if ((SecFlags & NoLoad) == 0) + SecFlags |= Load; + if (!ReadOnlyRemoved) + SecFlags |= NoWrite; + break; + + case 'y': // not readable + SecFlags |= NoRead | NoWrite; + break; + + default: + return TokError("unknown flag"); + } + } + + *Flags = 0; + + if (SecFlags == None) + SecFlags = InitData; + + if (SecFlags & Code) + *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE; + if (SecFlags & InitData) + *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; + if ((SecFlags & Alloc) && (SecFlags & Load) == 0) + *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; + if (SecFlags & NoLoad) + *Flags |= COFF::IMAGE_SCN_LNK_REMOVE; + if ((SecFlags & NoRead) == 0) + *Flags |= COFF::IMAGE_SCN_MEM_READ; + if ((SecFlags & NoWrite) == 0) + *Flags |= COFF::IMAGE_SCN_MEM_WRITE; + if (SecFlags & Shared) + *Flags |= COFF::IMAGE_SCN_MEM_SHARED; + + return false; +} + /// ParseDirectiveSymbolAttribute /// ::= { ".weak", ... } [ identifier ( , identifier )* ] bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { @@ -164,13 +290,96 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { bool COFFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind) { + return ParseSectionSwitch(Section, Characteristics, Kind, "", + COFF::IMAGE_COMDAT_SELECT_ANY, 0); +} + +bool COFFAsmParser::ParseSectionSwitch(StringRef Section, + unsigned Characteristics, + SectionKind Kind, + StringRef COMDATSymName, + COFF::COMDATType Type, + const MCSectionCOFF *Assoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in section switching directive"); Lex(); getStreamer().SwitchSection(getContext().getCOFFSection( - Section, Characteristics, Kind)); + Section, Characteristics, Kind, COMDATSymName, Type, Assoc)); + + return false; +} + +bool COFFAsmParser::ParseSectionName(StringRef &SectionName) { + if (!getLexer().is(AsmToken::Identifier)) + return true; + + SectionName = getTok().getIdentifier(); + Lex(); + return false; +} + +// .section name [, "flags"] [, identifier [ identifier ], identifier] +// +// Supported flags: +// a: Ignored. +// b: BSS section (uninitialized data) +// d: data section (initialized data) +// n: Discardable section +// r: Readable section +// s: Shared section +// w: Writable section +// x: Executable section +// y: Not-readable section (clears 'r') +// +// Subsections are not supported. +bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { + StringRef SectionName; + + if (ParseSectionName(SectionName)) + return TokError("expected identifier in directive"); + + unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE; + + if (getLexer().is(AsmToken::Comma)) { + Lex(); + + if (getLexer().isNot(AsmToken::String)) + return TokError("expected string in directive"); + + StringRef FlagsStr = getTok().getStringContents(); + Lex(); + + if (ParseSectionFlags(FlagsStr, &Flags)) + return true; + } + + COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; + const MCSectionCOFF *Assoc = 0; + StringRef COMDATSymName; + if (getLexer().is(AsmToken::Comma)) { + Lex(); + + Flags |= COFF::IMAGE_SCN_LNK_COMDAT; + if (parseCOMDATTypeAndAssoc(Type, Assoc)) + return true; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("expected comma in directive"); + Lex(); + + if (getParser().parseIdentifier(COMDATSymName)) + return TokError("expected identifier in directive"); + } + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + SectionKind Kind = computeSectionKind(Flags); + ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type, Assoc); return false; } @@ -235,6 +444,75 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { return false; } +/// ::= [ identifier [ identifier ] ] +bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, + const MCSectionCOFF *&Assoc) { + StringRef TypeId = getTok().getIdentifier(); + + Type = StringSwitch<COFF::COMDATType>(TypeId) + .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES) + .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY) + .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE) + .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH) + .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) + .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST) + .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST) + .Default((COFF::COMDATType)0); + + if (Type == 0) + return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'")); + + Lex(); + + if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { + SMLoc Loc = getTok().getLoc(); + StringRef AssocName; + if (ParseSectionName(AssocName)) + return TokError("expected associated section name"); + + Assoc = static_cast<const MCSectionCOFF*>( + getContext().getCOFFSection(AssocName)); + if (!Assoc) + return Error(Loc, "cannot associate unknown section '" + AssocName + "'"); + if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)) + return Error(Loc, "associated section must be a COMDAT section"); + if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) + return Error(Loc, "associated section cannot be itself associative"); + } + + return false; +} + +/// ParseDirectiveLinkOnce +/// ::= .linkonce [ identifier [ identifier ] ] +bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) { + COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; + const MCSectionCOFF *Assoc = 0; + if (getLexer().is(AsmToken::Identifier)) + if (parseCOMDATTypeAndAssoc(Type, Assoc)) + return true; + + const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>( + getStreamer().getCurrentSection().first); + + + if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { + if (Assoc == Current) + return Error(Loc, "cannot associate a section with itself"); + } + + if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) + return Error(Loc, Twine("section '") + Current->getSectionName() + + "' is already linkonce"); + + Current->setSelection(Type, Assoc); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + return false; +} + bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { StringRef SymbolID; if (getParser().parseIdentifier(SymbolID)) @@ -453,7 +731,7 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) { SMLoc startLoc = getLexer().getLoc(); if (getLexer().is(AsmToken::Percent)) { - const MCRegisterInfo &MRI = getContext().getRegisterInfo(); + const MCRegisterInfo *MRI = getContext().getRegisterInfo(); SMLoc endLoc; unsigned LLVMRegNo; if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc)) @@ -473,7 +751,7 @@ bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) { return Error(startLoc, "expected non-volatile register"); #endif - int SEHRegNo = MRI.getSEHRegNum(LLVMRegNo); + int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo); if (SEHRegNo < 0) return Error(startLoc,"register can't be represented in SEH unwind info"); RegNo = SEHRegNo; diff --git a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp index 7eb8b74..4c9bafa 100644 --- a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp @@ -45,6 +45,8 @@ public: this->MCAsmParserExtension::Initialize(Parser); addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc"); + addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>( + ".indirect_symbol"); addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym"); addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>( ".subsections_via_symbols"); @@ -69,6 +71,7 @@ public: ".end_data_region"); // Special section directives. + addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveBss>(".bss"); addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const"); addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>( ".const_data"); @@ -163,6 +166,7 @@ public: } bool ParseDirectiveDesc(StringRef, SMLoc); + bool ParseDirectiveIndirectSymbol(StringRef, SMLoc); bool ParseDirectiveDumpOrLoad(StringRef, SMLoc); bool ParseDirectiveLsym(StringRef, SMLoc); bool ParseDirectiveLinkerOption(StringRef, SMLoc); @@ -179,6 +183,10 @@ public: bool ParseDirectiveDataRegionEnd(StringRef, SMLoc); // Named Section Directive + bool ParseSectionDirectiveBss(StringRef, SMLoc) { + return ParseSectionSwitch("__DATA", "__bss"); + } + bool ParseSectionDirectiveConst(StringRef, SMLoc) { return ParseSectionSwitch("__TEXT", "__const"); } @@ -415,6 +423,39 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) { return false; } +/// ParseDirectiveIndirectSymbol +/// ::= .indirect_symbol identifier +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) + return Error(Loc, "indirect symbol not in a symbol pointer or stub " + "section"); + + StringRef Name; + if (getParser().parseIdentifier(Name)) + return TokError("expected identifier in .indirect_symbol directive"); + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + + // Assembler local symbols don't make any sense here. Complain loudly. + if (Sym->isTemporary()) + return TokError("non-local symbol required in directive"); + + if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) + return TokError("unable to emit indirect symbol attribute for: " + Name); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.indirect_symbol' directive"); + + Lex(); + + return false; +} + /// ParseDirectiveDumpOrLoad /// ::= ( .dump | .load ) "filename" bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive, @@ -593,7 +634,7 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { raw_ostream *OS = getContext().getSecureLog(); if (OS == NULL) { std::string Err; - OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append); + OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append); if (!Err.empty()) { delete OS; return Error(IDLoc, Twine("can't open secure log file: ") + diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 3134fc3..8807975 100644 --- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/ELF.h" using namespace llvm; @@ -30,14 +31,11 @@ class ELFAsmParser : public MCAsmParserExtension { getParser().addDirectiveHandler(Directive, Handler); } - bool ParseSectionSwitch(StringRef Section, unsigned Type, - unsigned Flags, SectionKind Kind); - bool SeenIdent; + bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind); public: - ELFAsmParser() : SeenIdent(false) { - BracketExpressionsSupported = true; - } + ELFAsmParser() { BracketExpressionsSupported = true; } virtual void Initialize(MCAsmParser &Parser) { // Call the base implementation. @@ -241,7 +239,6 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { } for (;;) { - StringRef Tmp; unsigned CurSize; SMLoc PrevLoc = getLexer().getLoc(); @@ -279,14 +276,17 @@ static SectionKind computeSectionKind(unsigned Flags) { return SectionKind::getDataRel(); } -static int parseSectionFlags(StringRef flagsStr) { - int flags = 0; +static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { + unsigned flags = 0; for (unsigned i = 0; i < flagsStr.size(); i++) { switch (flagsStr[i]) { case 'a': flags |= ELF::SHF_ALLOC; break; + case 'e': + flags |= ELF::SHF_EXCLUDE; + break; case 'x': flags |= ELF::SHF_EXECINSTR; break; @@ -311,8 +311,11 @@ static int parseSectionFlags(StringRef flagsStr) { case 'G': flags |= ELF::SHF_GROUP; break; + case '?': + *UseLastGroup = true; + break; default: - return -1; + return -1U; } } @@ -352,6 +355,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) { StringRef GroupName; unsigned Flags = 0; const MCExpr *Subsection = 0; + bool UseLastGroup = false; // Set the defaults first. if (SectionName == ".fini" || SectionName == ".init" || @@ -377,13 +381,16 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) { StringRef FlagsStr = getTok().getStringContents(); Lex(); - int extraFlags = parseSectionFlags(FlagsStr); - if (extraFlags < 0) + unsigned extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); + if (extraFlags == -1U) return TokError("unknown flag"); Flags |= extraFlags; bool Mergeable = Flags & ELF::SHF_MERGE; bool Group = Flags & ELF::SHF_GROUP; + if (Group && UseLastGroup) + return TokError("Section cannot specifiy a group name while also acting " + "as a member of the last group"); if (getLexer().isNot(AsmToken::Comma)) { if (Mergeable) @@ -392,10 +399,13 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) { return TokError("Group section must specify the type"); } else { Lex(); - if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) - return TokError("expected '@' or '%' before type"); + if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) || + getLexer().is(AsmToken::String)) { + if (!getLexer().is(AsmToken::String)) + Lex(); + } else + return TokError("expected '@<type>', '%<type>' or \"<type>\""); - Lex(); if (getParser().parseIdentifier(TypeName)) return TokError("expected identifier in directive"); @@ -461,6 +471,16 @@ EndStmt: return TokError("unknown section type"); } + if (UseLastGroup) { + MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); + if (const MCSectionELF *Section = + cast_or_null<MCSectionELF>(CurrentSection.first)) + if (const MCSymbol *Group = Section->getGroup()) { + GroupName = Group->getName(); + Flags |= ELF::SHF_GROUP; + } + } + SectionKind Kind = computeSectionKind(Flags); getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type, Flags, Kind, Size, @@ -479,7 +499,11 @@ bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { } /// ParseDirectiveELFType +/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> +/// ::= .type identifier , #attribute /// ::= .type identifier , @attribute +/// ::= .type identifier , %attribute +/// ::= .type identifier , "attribute" bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { StringRef Name; if (getParser().parseIdentifier(Name)) @@ -492,26 +516,42 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { return TokError("unexpected token in '.type' directive"); Lex(); - if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) - return TokError("expected '@' or '%' before type"); - Lex(); - StringRef Type; SMLoc TypeLoc; + MCSymbolAttr Attr; + if (getLexer().is(AsmToken::Identifier)) { + TypeLoc = getLexer().getLoc(); + if (getParser().parseIdentifier(Type)) + return TokError("expected symbol type in directive"); + Attr = StringSwitch<MCSymbolAttr>(Type) + .Case("STT_FUNC", MCSA_ELF_TypeFunction) + .Case("STT_OBJECT", MCSA_ELF_TypeObject) + .Case("STT_TLS", MCSA_ELF_TypeTLS) + .Case("STT_COMMON", MCSA_ELF_TypeCommon) + .Case("STT_NOTYPE", MCSA_ELF_TypeNoType) + .Case("STT_GNU_IFUNC", MCSA_ELF_TypeIndFunction) + .Default(MCSA_Invalid); + } else if (getLexer().is(AsmToken::Hash) || getLexer().is(AsmToken::At) || + getLexer().is(AsmToken::Percent) || + getLexer().is(AsmToken::String)) { + if (!getLexer().is(AsmToken::String)) + Lex(); - TypeLoc = getLexer().getLoc(); - if (getParser().parseIdentifier(Type)) - return TokError("expected symbol type in directive"); - - MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type) - .Case("function", MCSA_ELF_TypeFunction) - .Case("object", MCSA_ELF_TypeObject) - .Case("tls_object", MCSA_ELF_TypeTLS) - .Case("common", MCSA_ELF_TypeCommon) - .Case("notype", MCSA_ELF_TypeNoType) - .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) - .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) - .Default(MCSA_Invalid); + TypeLoc = getLexer().getLoc(); + if (getParser().parseIdentifier(Type)) + return TokError("expected symbol type in directive"); + Attr = StringSwitch<MCSymbolAttr>(Type) + .Case("function", MCSA_ELF_TypeFunction) + .Case("object", MCSA_ELF_TypeObject) + .Case("tls_object", MCSA_ELF_TypeTLS) + .Case("common", MCSA_ELF_TypeCommon) + .Case("notype", MCSA_ELF_TypeNoType) + .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) + .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) + .Default(MCSA_Invalid); + } else + return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " + "'%<type>' or \"<type>\""); if (Attr == MCSA_Invalid) return Error(TypeLoc, "unsupported attribute in '.type' directive"); @@ -536,22 +576,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { Lex(); - const MCSection *Comment = - getContext().getELFSection(".comment", ELF::SHT_PROGBITS, - ELF::SHF_MERGE | - ELF::SHF_STRINGS, - SectionKind::getReadOnly(), - 1, ""); - - getStreamer().PushSection(); - getStreamer().SwitchSection(Comment); - if (!SeenIdent) { - getStreamer().EmitIntValue(0, 1); - SeenIdent = true; - } - getStreamer().EmitBytes(Data); - getStreamer().EmitIntValue(0, 1); - getStreamer().PopSection(); + getStreamer().EmitIdent(Data); return false; } |