diff options
Diffstat (limited to 'lib/MC/MCParser')
| -rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 32 | ||||
| -rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 69 | ||||
| -rw-r--r-- | lib/MC/MCParser/COFFAsmParser.cpp | 7 | ||||
| -rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 9 | ||||
| -rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 11 | ||||
| -rw-r--r-- | lib/MC/MCParser/MCAsmLexer.cpp | 7 | ||||
| -rw-r--r-- | lib/MC/MCParser/MCAsmParser.cpp | 7 | ||||
| -rw-r--r-- | lib/MC/MCParser/MCAsmParserExtension.cpp | 7 | ||||
| -rw-r--r-- | lib/MC/MCParser/MCTargetAsmParser.cpp | 7 | ||||
| -rw-r--r-- | lib/MC/MCParser/WasmAsmParser.cpp | 174 |
10 files changed, 233 insertions, 97 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index 2b0d20f9b8e2e..9155ae05d29db 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -1,9 +1,8 @@ //===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -62,8 +61,6 @@ int AsmLexer::getNextChar() { return (unsigned char)*CurPtr++; } -/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)? -/// /// The leading integral digit sequence and dot should have already been /// consumed, some or all of the fractional digit sequence *can* have been /// consumed. @@ -72,13 +69,16 @@ AsmToken AsmLexer::LexFloatLiteral() { while (isDigit(*CurPtr)) ++CurPtr; - // Check for exponent; we intentionally accept a slighlty wider set of - // literals here and rely on the upstream client to reject invalid ones (e.g., - // "1e+"). - if (*CurPtr == 'e' || *CurPtr == 'E') { + if (*CurPtr == '-' || *CurPtr == '+') + return ReturnError(CurPtr, "Invalid sign in float literal"); + + // Check for exponent + if ((*CurPtr == 'e' || *CurPtr == 'E')) { ++CurPtr; + if (*CurPtr == '-' || *CurPtr == '+') ++CurPtr; + while (isDigit(*CurPtr)) ++CurPtr; } @@ -146,8 +146,9 @@ AsmToken AsmLexer::LexIdentifier() { // Disambiguate a .1243foo identifier from a floating literal. while (isDigit(*CurPtr)) ++CurPtr; - if (*CurPtr == 'e' || *CurPtr == 'E' || - !IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) + + if (!IsIdentifierChar(*CurPtr, AllowAtInIdentifier) || + *CurPtr == 'e' || *CurPtr == 'E') return LexFloatLiteral(); } @@ -327,8 +328,9 @@ AsmToken AsmLexer::LexDigit() { unsigned Radix = doHexLookAhead(CurPtr, 10, LexMasmIntegers); bool isHex = Radix == 16; // Check for floating point literals. - if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) { - ++CurPtr; + if (!isHex && (*CurPtr == '.' || *CurPtr == 'e' || *CurPtr == 'E')) { + if (*CurPtr == '.') + ++CurPtr; return LexFloatLiteral(); } @@ -557,7 +559,7 @@ AsmToken AsmLexer::LexToken() { AsmToken TokenBuf[2]; MutableArrayRef<AsmToken> Buf(TokenBuf, 2); size_t num = peekTokens(Buf, true); - // There cannot be a space preceeding this + // There cannot be a space preceding this if (IsAtStartOfLine && num == 2 && TokenBuf[0].is(AsmToken::Integer) && TokenBuf[1].is(AsmToken::String)) { CurPtr = TokStart; // reset curPtr; diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index cf42a6f7075b9..084f6a7a2e141 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1,9 +1,8 @@ //===- AsmParser.cpp - Parser for Assembly Files --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -159,12 +158,16 @@ private: /// The values from the last parsed cpp hash file line comment if any. struct CppHashInfoTy { StringRef Filename; - int64_t LineNumber = 0; + int64_t LineNumber; SMLoc Loc; - unsigned Buf = 0; + unsigned Buf; + CppHashInfoTy() : Filename(), LineNumber(0), Loc(), Buf(0) {} }; CppHashInfoTy CppHashInfo; + /// The filename from the first cpp hash file line comment, if any. + StringRef FirstCppHashFilename; + /// List of forward directional labels for diagnosis at the end. SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels; @@ -426,6 +429,7 @@ private: DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, DK_WEAK_DEF_CAN_BE_HIDDEN, + DK_COLD, DK_COMM, DK_COMMON, DK_LCOMM, @@ -709,6 +713,9 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, case MCObjectFileInfo::IsWasm: PlatformParser.reset(createWasmAsmParser()); break; + case MCObjectFileInfo::IsXCOFF: + // TODO: Need to implement createXCOFFAsmParser for XCOFF format. + break; } PlatformParser->Initialize(*this); @@ -844,9 +851,20 @@ bool AsmParser::enabledGenDwarfForAssembly() { // If we haven't encountered any .file directives (which would imply that // the assembler source was produced with debug info already) then emit one // describing the assembler source file itself. - if (getContext().getGenDwarfFileNumber() == 0) + if (getContext().getGenDwarfFileNumber() == 0) { + // Use the first #line directive for this, if any. It's preprocessed, so + // there is no checksum, and of course no source directive. + if (!FirstCppHashFilename.empty()) + getContext().setMCLineTableRootFile(/*CUID=*/0, + getContext().getCompilationDir(), + FirstCppHashFilename, + /*Cksum=*/None, /*Source=*/None); + const MCDwarfFile &RootFile = + getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile(); getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( - 0, StringRef(), getContext().getMainFileName())); + /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name, + RootFile.Checksum, RootFile.Source)); + } return true; } @@ -1983,6 +2001,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveSymbolAttribute(MCSA_WeakReference); case DK_WEAK_DEF_CAN_BE_HIDDEN: return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate); + case DK_COLD: + return parseDirectiveSymbolAttribute(MCSA_Cold); case DK_COMM: case DK_COMMON: return parseDirectiveComm(/*IsLocal=*/false); @@ -2275,11 +2295,14 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) { // Get rid of the enclosing quotes. Filename = Filename.substr(1, Filename.size() - 2); - // Save the SMLoc, Filename and LineNumber for later use by diagnostics. + // Save the SMLoc, Filename and LineNumber for later use by diagnostics + // and possibly DWARF file info. CppHashInfo.Loc = L; CppHashInfo.Filename = Filename; CppHashInfo.LineNumber = LineNumber; CppHashInfo.Buf = CurBuffer; + if (FirstCppHashFilename.empty()) + FirstCppHashFilename = Filename; return false; } @@ -3364,26 +3387,28 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { } if (FileNumber == -1) { - if (!getContext().getAsmInfo()->hasSingleParameterDotFile()) - return Error(DirectiveLoc, - "target does not support '.file' without a number"); - getStreamer().EmitFileDirective(Filename); + // Ignore the directive if there is no number and the target doesn't support + // numberless .file directives. This allows some portability of assembler + // between different object file formats. + if (getContext().getAsmInfo()->hasSingleParameterDotFile()) + getStreamer().EmitFileDirective(Filename); } else { // In case there is a -g option as well as debug info from directive .file, // we turn off the -g option, directly use the existing debug info instead. - // Also reset any implicit ".file 0" for the assembler source. + // Throw away any implicit file table for the assembler source. if (Ctx.getGenDwarfForAssembly()) { - Ctx.getMCDwarfLineTable(0).resetRootFile(); + Ctx.getMCDwarfLineTable(0).resetFileTable(); Ctx.setGenDwarfForAssembly(false); } - MD5::MD5Result *CKMem = nullptr; + Optional<MD5::MD5Result> CKMem; if (HasMD5) { - CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1); + MD5::MD5Result Sum; for (unsigned i = 0; i != 8; ++i) { - CKMem->Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); - CKMem->Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); + Sum.Bytes[i] = uint8_t(MD5Hi >> ((7 - i) * 8)); + Sum.Bytes[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8)); } + CKMem = Sum; } if (HasSource) { char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size())); @@ -3399,7 +3424,6 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { FileNumber, Directory, Filename, CKMem, Source); if (!FileNumOrErr) return Error(DirectiveLoc, toString(FileNumOrErr.takeError())); - FileNumber = FileNumOrErr.get(); } // Alert the user if there are some .file directives with MD5 and some not. // But only do that once. @@ -5035,9 +5059,9 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { MCSymbol *Sym = getContext().lookupSymbol(Name); if (expect_defined) - TheCondState.CondMet = (Sym && !Sym->isUndefined()); + TheCondState.CondMet = (Sym && !Sym->isUndefined(false)); else - TheCondState.CondMet = (!Sym || Sym->isUndefined()); + TheCondState.CondMet = (!Sym || Sym->isUndefined(false)); TheCondState.Ignore = !TheCondState.CondMet; } @@ -5223,6 +5247,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION; DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE; DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN; + DirectiveKindMap[".cold"] = DK_COLD; DirectiveKindMap[".comm"] = DK_COMM; DirectiveKindMap[".common"] = DK_COMMON; DirectiveKindMap[".lcomm"] = DK_LCOMM; diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index 388304a72395c..1217ea99e4656 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -1,9 +1,8 @@ //===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index cd99112292a95..1160934dc62c4 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -1,9 +1,8 @@ //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -1149,6 +1148,7 @@ static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) { case MachO::PLATFORM_TVOS: return Triple::TvOS; case MachO::PLATFORM_WATCHOS: return Triple::WatchOS; case MachO::PLATFORM_BRIDGEOS: /* silence warning */ break; + case MachO::PLATFORM_MACCATALYST: return Triple::IOS; case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break; case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break; case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break; @@ -1169,6 +1169,7 @@ bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) { .Case("ios", MachO::PLATFORM_IOS) .Case("tvos", MachO::PLATFORM_TVOS) .Case("watchos", MachO::PLATFORM_WATCHOS) + .Case("macCatalyst", MachO::PLATFORM_MACCATALYST) .Default(0); if (Platform == 0) return Error(PlatformLoc, "unknown platform name"); diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index d568f7a71eeb5..a55bdd5364cb7 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -1,9 +1,8 @@ //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -616,6 +615,10 @@ EndStmt: Type = ELF::SHT_LLVM_LINKER_OPTIONS; else if (TypeName == "llvm_call_graph_profile") Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE; + else if (TypeName == "llvm_dependent_libraries") + Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES; + else if (TypeName == "llvm_sympart") + Type = ELF::SHT_LLVM_SYMPART; else if (TypeName.getAsInteger(0, Type)) return TokError("unknown section type"); } diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp index 10960fc696334..497055bc1760a 100644 --- a/lib/MC/MCParser/MCAsmLexer.cpp +++ b/lib/MC/MCParser/MCAsmLexer.cpp @@ -1,9 +1,8 @@ //===- MCAsmLexer.cpp - Abstract Asm Lexer Interface ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp index efedcdc5a314d..41a1ee555d6fb 100644 --- a/lib/MC/MCParser/MCAsmParser.cpp +++ b/lib/MC/MCParser/MCAsmParser.cpp @@ -1,9 +1,8 @@ //===-- MCAsmParser.cpp - Abstract Asm Parser Interface -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/MC/MCParser/MCAsmParserExtension.cpp b/lib/MC/MCParser/MCAsmParserExtension.cpp index 031f473dc5fe4..18d18f0cf6ed5 100644 --- a/lib/MC/MCParser/MCAsmParserExtension.cpp +++ b/lib/MC/MCParser/MCAsmParserExtension.cpp @@ -1,9 +1,8 @@ //===- MCAsmParserExtension.cpp - Asm Parser Hooks ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/MC/MCParser/MCTargetAsmParser.cpp b/lib/MC/MCParser/MCTargetAsmParser.cpp index a0c06c9d50189..940f26d4750b4 100644 --- a/lib/MC/MCParser/MCTargetAsmParser.cpp +++ b/lib/MC/MCParser/MCTargetAsmParser.cpp @@ -1,9 +1,8 @@ //===-- MCTargetAsmParser.cpp - Target Assembly Parser --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/MC/MCParser/WasmAsmParser.cpp b/lib/MC/MCParser/WasmAsmParser.cpp index 93bb0cb3c72e4..28d4459fecd44 100644 --- a/lib/MC/MCParser/WasmAsmParser.cpp +++ b/lib/MC/MCParser/WasmAsmParser.cpp @@ -1,9 +1,8 @@ //===- WasmAsmParser.cpp - Wasm Assembly Parser -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // -- // @@ -22,6 +21,7 @@ #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCAsmParserExtension.h" +#include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolWasm.h" @@ -32,8 +32,8 @@ using namespace llvm; namespace { class WasmAsmParser : public MCAsmParserExtension { - MCAsmParser *Parser; - MCAsmLexer *Lexer; + MCAsmParser *Parser = nullptr; + MCAsmLexer *Lexer = nullptr; template<bool (WasmAsmParser::*HandlerMethod)(StringRef, SMLoc)> void addDirectiveHandler(StringRef Directive) { @@ -44,9 +44,7 @@ class WasmAsmParser : public MCAsmParserExtension { } public: - WasmAsmParser() : Parser(nullptr), Lexer(nullptr) { - BracketExpressionsSupported = true; - } + WasmAsmParser() { BracketExpressionsSupported = true; } void Initialize(MCAsmParser &P) override { Parser = &P; @@ -58,21 +56,31 @@ public: addDirectiveHandler<&WasmAsmParser::parseSectionDirective>(".section"); addDirectiveHandler<&WasmAsmParser::parseDirectiveSize>(".size"); addDirectiveHandler<&WasmAsmParser::parseDirectiveType>(".type"); + addDirectiveHandler<&WasmAsmParser::ParseDirectiveIdent>(".ident"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".weak"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".local"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".internal"); + addDirectiveHandler< + &WasmAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); } - bool Error(const StringRef &msg, const AsmToken &tok) { - return Parser->Error(tok.getLoc(), msg + tok.getString()); + bool error(const StringRef &Msg, const AsmToken &Tok) { + return Parser->Error(Tok.getLoc(), Msg + Tok.getString()); } - bool IsNext(AsmToken::TokenKind Kind) { - auto ok = Lexer->is(Kind); - if (ok) Lex(); - return ok; + bool isNext(AsmToken::TokenKind Kind) { + auto Ok = Lexer->is(Kind); + if (Ok) + Lex(); + return Ok; } - bool Expect(AsmToken::TokenKind Kind, const char *KindName) { - if (!IsNext(Kind)) - return Error(std::string("Expected ") + KindName + ", instead got: ", + bool expect(AsmToken::TokenKind Kind, const char *KindName) { + if (!isNext(Kind)) + return error(std::string("Expected ") + KindName + ", instead got: ", Lexer->getTok()); return false; } @@ -82,9 +90,65 @@ public: return false; } + bool parseSectionFlags(StringRef FlagStr, bool &Passive) { + SmallVector<StringRef, 2> Flags; + // If there are no flags, keep Flags empty + FlagStr.split(Flags, ",", -1, false); + for (auto &Flag : Flags) { + if (Flag == "passive") + Passive = true; + else + return error("Expected section flags, instead got: ", Lexer->getTok()); + } + return false; + } + bool parseSectionDirective(StringRef, SMLoc) { - // FIXME: .section currently no-op. - while (Lexer->isNot(AsmToken::EndOfStatement)) Parser->Lex(); + StringRef Name; + if (Parser->parseIdentifier(Name)) + return TokError("expected identifier in directive"); + + if (expect(AsmToken::Comma, ",")) + return true; + + if (Lexer->isNot(AsmToken::String)) + return error("expected string in directive, instead got: ", Lexer->getTok()); + + auto Kind = StringSwitch<Optional<SectionKind>>(Name) + .StartsWith(".data", SectionKind::getData()) + .StartsWith(".rodata", SectionKind::getReadOnly()) + .StartsWith(".text", SectionKind::getText()) + .StartsWith(".custom_section", SectionKind::getMetadata()) + .StartsWith(".bss", SectionKind::getBSS()) + // See use of .init_array in WasmObjectWriter and + // TargetLoweringObjectFileWasm + .StartsWith(".init_array", SectionKind::getData()) + .Default(Optional<SectionKind>()); + if (!Kind.hasValue()) + return Parser->Error(Lexer->getLoc(), "unknown section kind: " + Name); + + MCSectionWasm *Section = getContext().getWasmSection(Name, Kind.getValue()); + + // Update section flags if present in this .section directive + bool Passive = false; + if (parseSectionFlags(getTok().getStringContents(), Passive)) + return true; + + if (Passive) { + if (!Section->isWasmData()) + return Parser->Error(getTok().getLoc(), + "Only data sections can be passive"); + Section->setPassive(); + } + + Lex(); + + if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") || + expect(AsmToken::EndOfStatement, "eol")) + return true; + + auto WS = getContext().getWasmSection(Name, Kind.getValue()); + getStreamer().SwitchSection(WS); return false; } @@ -95,16 +159,15 @@ public: if (Parser->parseIdentifier(Name)) return TokError("expected identifier in directive"); auto Sym = getContext().getOrCreateSymbol(Name); - if (Lexer->isNot(AsmToken::Comma)) - return TokError("unexpected token in directive"); - Lex(); + if (expect(AsmToken::Comma, ",")) + return true; const MCExpr *Expr; if (Parser->parseExpression(Expr)) return true; - if (Lexer->isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in directive"); - Lex(); - // MCWasmStreamer implements this. + if (expect(AsmToken::EndOfStatement, "eol")) + return true; + // This is done automatically by the assembler for functions currently, + // so this is only currently needed for data sections: getStreamer().emitELFSize(Sym, Expr); return false; } @@ -113,24 +176,71 @@ public: // This could be the start of a function, check if followed by // "label,@function" if (!Lexer->is(AsmToken::Identifier)) - return Error("Expected label after .type directive, got: ", + return error("Expected label after .type directive, got: ", Lexer->getTok()); auto WasmSym = cast<MCSymbolWasm>( getStreamer().getContext().getOrCreateSymbol( Lexer->getTok().getString())); Lex(); - if (!(IsNext(AsmToken::Comma) && IsNext(AsmToken::At) && + if (!(isNext(AsmToken::Comma) && isNext(AsmToken::At) && Lexer->is(AsmToken::Identifier))) - return Error("Expected label,@type declaration, got: ", Lexer->getTok()); + return error("Expected label,@type declaration, got: ", Lexer->getTok()); auto TypeName = Lexer->getTok().getString(); if (TypeName == "function") WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); else if (TypeName == "global") WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); + else if (TypeName == "object") + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_DATA); else - return Error("Unknown WASM symbol type: ", Lexer->getTok()); + return error("Unknown WASM symbol type: ", Lexer->getTok()); Lex(); - return Expect(AsmToken::EndOfStatement, "EOL"); + return expect(AsmToken::EndOfStatement, "EOL"); + } + + // FIXME: Shared with ELF. + /// ParseDirectiveIdent + /// ::= .ident string + bool ParseDirectiveIdent(StringRef, SMLoc) { + if (getLexer().isNot(AsmToken::String)) + return TokError("unexpected token in '.ident' directive"); + StringRef Data = getTok().getIdentifier(); + Lex(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.ident' directive"); + Lex(); + getStreamer().EmitIdent(Data); + return false; + } + + // FIXME: Shared with ELF. + /// ParseDirectiveSymbolAttribute + /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] + bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { + MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) + .Case(".weak", MCSA_Weak) + .Case(".local", MCSA_Local) + .Case(".hidden", MCSA_Hidden) + .Case(".internal", MCSA_Internal) + .Case(".protected", MCSA_Protected) + .Default(MCSA_Invalid); + assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); + if (getLexer().isNot(AsmToken::EndOfStatement)) { + while (true) { + StringRef Name; + if (getParser().parseIdentifier(Name)) + return TokError("expected identifier in directive"); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); + getStreamer().EmitSymbolAttribute(Sym, Attr); + if (getLexer().is(AsmToken::EndOfStatement)) + break; + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + Lex(); + return false; } }; |
