//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/TargetParser/Triple.h"
#include <cassert>
#include <cstdint>
#include <limits>
#include <utility>

using namespace llvm;

namespace {

class COFFAsmParser : public MCAsmParserExtension {
  template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
  void addDirectiveHandler(StringRef Directive) {
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
        this, HandleDirective<COFFAsmParser, HandlerMethod>);
    getParser().addDirectiveHandler(Directive, Handler);
  }

  bool parseSectionSwitch(StringRef Section, unsigned Characteristics);

  bool parseSectionSwitch(StringRef Section, unsigned Characteristics,
                          StringRef COMDATSymName, COFF::COMDATType Type);

  bool parseSectionName(StringRef &SectionName);
  bool parseSectionFlags(StringRef SectionName, StringRef FlagsString,
                         unsigned *Flags);

  void Initialize(MCAsmParser &Parser) override {
    // Call the base implementation.
    MCAsmParserExtension::Initialize(Parser);

    addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveText>(".text");
    addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveData>(".data");
    addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveBSS>(".bss");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSection>(".section");
    addDirectiveHandler<&COFFAsmParser::parseDirectivePushSection>(
        ".pushsection");
    addDirectiveHandler<&COFFAsmParser::parseDirectivePopSection>(
        ".popsection");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveDef>(".def");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveScl>(".scl");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveType>(".type");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveEndef>(".endef");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSecRel32>(".secrel32");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSymIdx>(".symidx");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSafeSEH>(".safeseh");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSecIdx>(".secidx");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveLinkOnce>(".linkonce");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveRVA>(".rva");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(".weak");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(
        ".weak_anti_dep");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveCGProfile>(".cg_profile");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSecNum>(".secnum");
    addDirectiveHandler<&COFFAsmParser::parseDirectiveSecOffset>(".secoffset");

    // Win64 EH directives.
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartProc>(
        ".seh_proc");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProc>(
        ".seh_endproc");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc>(
        ".seh_endfunclet");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartChained>(
        ".seh_startchained");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndChained>(
        ".seh_endchained");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandler>(
        ".seh_handler");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandlerData>(
        ".seh_handlerdata");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveAllocStack>(
        ".seh_stackalloc");
    addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProlog>(
        ".seh_endprologue");
  }

  bool parseSectionDirectiveText(StringRef, SMLoc) {
    return parseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
                                           COFF::IMAGE_SCN_MEM_EXECUTE |
                                           COFF::IMAGE_SCN_MEM_READ);
  }

  bool parseSectionDirectiveData(StringRef, SMLoc) {
    return parseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
                                           COFF::IMAGE_SCN_MEM_READ |
                                           COFF::IMAGE_SCN_MEM_WRITE);
  }

  bool parseSectionDirectiveBSS(StringRef, SMLoc) {
    return parseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
                                          COFF::IMAGE_SCN_MEM_READ |
                                          COFF::IMAGE_SCN_MEM_WRITE);
  }

  bool parseDirectiveSection(StringRef, SMLoc);
  bool parseSectionArguments(StringRef, SMLoc);
  bool parseDirectivePushSection(StringRef, SMLoc);
  bool parseDirectivePopSection(StringRef, SMLoc);
  bool parseDirectiveDef(StringRef, SMLoc);
  bool parseDirectiveScl(StringRef, SMLoc);
  bool parseDirectiveType(StringRef, SMLoc);
  bool parseDirectiveEndef(StringRef, SMLoc);
  bool parseDirectiveSecRel32(StringRef, SMLoc);
  bool parseDirectiveSecIdx(StringRef, SMLoc);
  bool parseDirectiveSafeSEH(StringRef, SMLoc);
  bool parseDirectiveSymIdx(StringRef, SMLoc);
  bool parseCOMDATType(COFF::COMDATType &Type);
  bool parseDirectiveLinkOnce(StringRef, SMLoc);
  bool parseDirectiveRVA(StringRef, SMLoc);
  bool parseDirectiveCGProfile(StringRef, SMLoc);
  bool parseDirectiveSecNum(StringRef, SMLoc);
  bool parseDirectiveSecOffset(StringRef, SMLoc);

  // Win64 EH directives.
  bool parseSEHDirectiveStartProc(StringRef, SMLoc);
  bool parseSEHDirectiveEndProc(StringRef, SMLoc);
  bool parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
  bool parseSEHDirectiveStartChained(StringRef, SMLoc);
  bool parseSEHDirectiveEndChained(StringRef, SMLoc);
  bool parseSEHDirectiveHandler(StringRef, SMLoc);
  bool parseSEHDirectiveHandlerData(StringRef, SMLoc);
  bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
  bool parseSEHDirectiveEndProlog(StringRef, SMLoc);

  bool parseAtUnwindOrAtExcept(bool &unwind, bool &except);
  bool parseDirectiveSymbolAttribute(StringRef Directive, SMLoc);

public:
  COFFAsmParser() = default;
};

} // end anonymous namespace.

bool COFFAsmParser::parseSectionFlags(StringRef SectionName,
                                      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,
    Discardable = 1 << 8,
    Info = 1 << 9,
  };

  bool ReadOnlyRemoved = false;
  unsigned SecFlags = None;

  for (char FlagChar : FlagsString) {
    switch (FlagChar) {
    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 'D': // discardable
      SecFlags |= Discardable;
      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;

    case 'i': // info
      SecFlags |= Info;
      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 & Discardable) ||
      MCSectionCOFF::isImplicitlyDiscardable(SectionName))
    *Flags |= COFF::IMAGE_SCN_MEM_DISCARDABLE;
  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;
  if (SecFlags & Info)
    *Flags |= COFF::IMAGE_SCN_LNK_INFO;

  return false;
}

/// ParseDirectiveSymbolAttribute
///  ::= { ".weak", ... } [ identifier ( , identifier )* ]
bool COFFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
  MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
    .Case(".weak", MCSA_Weak)
    .Case(".weak_anti_dep", MCSA_WeakAntiDep)
    .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;
}

bool COFFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
  return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);
}

bool COFFAsmParser::parseSectionSwitch(StringRef Section,
                                       unsigned Characteristics) {
  return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0);
}

bool COFFAsmParser::parseSectionSwitch(StringRef Section,
                                       unsigned Characteristics,
                                       StringRef COMDATSymName,
                                       COFF::COMDATType Type) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in section switching directive");
  Lex();

  getStreamer().switchSection(getContext().getCOFFSection(
      Section, Characteristics, COMDATSymName, Type));

  return false;
}

bool COFFAsmParser::parseSectionName(StringRef &SectionName) {
  if (!getLexer().is(AsmToken::Identifier) && !getLexer().is(AsmToken::String))
    return true;

  SectionName = getTok().getIdentifier();
  Lex();
  return false;
}

bool COFFAsmParser::parseDirectiveSection(StringRef directive, SMLoc loc) {
  return parseSectionArguments(directive, loc);
}

// .section name [, "flags"] [, identifier [ identifier ], identifier]
// .pushsection <same as above>
//
// Supported flags:
//   a: Ignored.
//   b: BSS section (uninitialized data)
//   d: data section (initialized data)
//   n: "noload" section (removed by linker)
//   D: 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::parseSectionArguments(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(SectionName, FlagsStr, &Flags))
      return true;
  }

  COFF::COMDATType Type = (COFF::COMDATType)0;
  StringRef COMDATSymName;
  if (getLexer().is(AsmToken::Comma)) {
    Type = COFF::IMAGE_COMDAT_SELECT_ANY;
    Lex();

    Flags |= COFF::IMAGE_SCN_LNK_COMDAT;

    if (!getLexer().is(AsmToken::Identifier))
      return TokError("expected comdat type such as 'discard' or 'largest' "
                      "after protection bits");

    if (parseCOMDATType(Type))
      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");

  if (Flags & COFF::IMAGE_SCN_CNT_CODE) {
    const Triple &T = getContext().getTargetTriple();
    if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
      Flags |= COFF::IMAGE_SCN_MEM_16BIT;
  }
  parseSectionSwitch(SectionName, Flags, COMDATSymName, Type);
  return false;
}

bool COFFAsmParser::parseDirectivePushSection(StringRef directive, SMLoc loc) {
  getStreamer().pushSection();

  if (parseSectionArguments(directive, loc)) {
    getStreamer().popSection();
    return true;
  }

  return false;
}

bool COFFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
  if (!getStreamer().popSection())
    return TokError(".popsection without corresponding .pushsection");
  return false;
}

bool COFFAsmParser::parseDirectiveDef(StringRef, SMLoc) {
  StringRef SymbolName;

  if (getParser().parseIdentifier(SymbolName))
    return TokError("expected identifier in directive");

  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);

  getStreamer().beginCOFFSymbolDef(Sym);

  Lex();
  return false;
}

bool COFFAsmParser::parseDirectiveScl(StringRef, SMLoc) {
  int64_t SymbolStorageClass;
  if (getParser().parseAbsoluteExpression(SymbolStorageClass))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().emitCOFFSymbolStorageClass(SymbolStorageClass);
  return false;
}

bool COFFAsmParser::parseDirectiveType(StringRef, SMLoc) {
  int64_t Type;
  if (getParser().parseAbsoluteExpression(Type))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().emitCOFFSymbolType(Type);
  return false;
}

bool COFFAsmParser::parseDirectiveEndef(StringRef, SMLoc) {
  Lex();
  getStreamer().endCOFFSymbolDef();
  return false;
}

bool COFFAsmParser::parseDirectiveSecRel32(StringRef, SMLoc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return TokError("expected identifier in directive");

  int64_t Offset = 0;
  SMLoc OffsetLoc;
  if (getLexer().is(AsmToken::Plus)) {
    OffsetLoc = getLexer().getLoc();
    if (getParser().parseAbsoluteExpression(Offset))
      return true;
  }

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
    return Error(
        OffsetLoc,
        "invalid '.secrel32' directive offset, can't be less "
        "than zero or greater than std::numeric_limits<uint32_t>::max()");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitCOFFSecRel32(Symbol, Offset);
  return false;
}

bool COFFAsmParser::parseDirectiveRVA(StringRef, SMLoc) {
  auto parseOp = [&]() -> bool {
    StringRef SymbolID;
    if (getParser().parseIdentifier(SymbolID))
      return TokError("expected identifier in directive");

    int64_t Offset = 0;
    SMLoc OffsetLoc;
    if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
      OffsetLoc = getLexer().getLoc();
      if (getParser().parseAbsoluteExpression(Offset))
        return true;
    }

    if (Offset < std::numeric_limits<int32_t>::min() ||
        Offset > std::numeric_limits<int32_t>::max())
      return Error(OffsetLoc, "invalid '.rva' directive offset, can't be less "
                              "than -2147483648 or greater than "
                              "2147483647");

    MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

    getStreamer().emitCOFFImgRel32(Symbol, Offset);
    return false;
  };

  if (getParser().parseMany(parseOp))
    return addErrorSuffix(" in directive");
  return false;
}

bool COFFAsmParser::parseDirectiveSafeSEH(StringRef, SMLoc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitCOFFSafeSEH(Symbol);
  return false;
}

bool COFFAsmParser::parseDirectiveSecIdx(StringRef, SMLoc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitCOFFSectionIndex(Symbol);
  return false;
}

bool COFFAsmParser::parseDirectiveSymIdx(StringRef, SMLoc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitCOFFSymbolIndex(Symbol);
  return false;
}

bool COFFAsmParser::parseDirectiveSecNum(StringRef, SMLoc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitCOFFSecNumber(Symbol);
  return false;
}

bool COFFAsmParser::parseDirectiveSecOffset(StringRef, SMLoc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitCOFFSecOffset(Symbol);
  return false;
}

/// ::= [ identifier ]
bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
  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();

  return false;
}

/// ParseDirectiveLinkOnce
///  ::= .linkonce [ identifier ]
bool COFFAsmParser::parseDirectiveLinkOnce(StringRef, SMLoc Loc) {
  COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
  if (getLexer().is(AsmToken::Identifier))
    if (parseCOMDATType(Type))
      return true;

  const MCSectionCOFF *Current =
      static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly());

  if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
    return Error(Loc, "cannot make section associative with .linkonce");

  if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
    return Error(Loc, Twine("section '") + Current->getName() +
                          "' is already linkonce");

  Current->setSelection(Type);

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  return false;
}

bool COFFAsmParser::parseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitWinCFIStartProc(Symbol, Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
  Lex();
  getStreamer().emitWinCFIEndProc(Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
  Lex();
  getStreamer().emitWinCFIFuncletOrFuncEnd(Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
  Lex();
  getStreamer().emitWinCFIStartChained(Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
  Lex();
  getStreamer().emitWinCFIEndChained(Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveHandler(StringRef, SMLoc Loc) {
  StringRef SymbolID;
  if (getParser().parseIdentifier(SymbolID))
    return true;

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("you must specify one or both of @unwind or @except");
  Lex();
  bool unwind = false, except = false;
  if (parseAtUnwindOrAtExcept(unwind, except))
    return true;
  if (getLexer().is(AsmToken::Comma)) {
    Lex();
    if (parseAtUnwindOrAtExcept(unwind, except))
      return true;
  }
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);

  Lex();
  getStreamer().emitWinEHHandler(handler, unwind, except, Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
  Lex();
  getStreamer().emitWinEHHandlerData();
  return false;
}

bool COFFAsmParser::parseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
  int64_t Size;
  if (getParser().parseAbsoluteExpression(Size))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().emitWinCFIAllocStack(Size, Loc);
  return false;
}

bool COFFAsmParser::parseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
  Lex();
  getStreamer().emitWinCFIEndProlog(Loc);
  return false;
}

bool COFFAsmParser::parseAtUnwindOrAtExcept(bool &unwind, bool &except) {
  StringRef identifier;
  if (getLexer().isNot(AsmToken::At) && getLexer().isNot(AsmToken::Percent))
    return TokError("a handler attribute must begin with '@' or '%'");
  SMLoc startLoc = getLexer().getLoc();
  Lex();
  if (getParser().parseIdentifier(identifier))
    return Error(startLoc, "expected @unwind or @except");
  if (identifier == "unwind")
    unwind = true;
  else if (identifier == "except")
    except = true;
  else
    return Error(startLoc, "expected @unwind or @except");
  return false;
}

namespace llvm {

MCAsmParserExtension *createCOFFAsmParser() {
  return new COFFAsmParser;
}

} // end namespace llvm
