//===- DarwinAsmParser.cpp - Darwin (Mach-O) 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/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include <cstddef>
#include <cstdint>
#include <string>
#include <system_error>
#include <utility>

using namespace llvm;

namespace {

/// Implementation of directive handling which is shared across all
/// Darwin targets.
class DarwinAsmParser : public MCAsmParserExtension {
  template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
  void addDirectiveHandler(StringRef Directive) {
    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
        this, HandleDirective<DarwinAsmParser, HandlerMethod>);
    getParser().addDirectiveHandler(Directive, Handler);
  }

  bool parseSectionSwitch(StringRef Segment, StringRef Section,
                          unsigned TAA = 0, unsigned ImplicitAlign = 0,
                          unsigned StubSize = 0);

  SMLoc LastVersionDirective;

public:
  DarwinAsmParser() = default;

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

    addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
      ".indirect_symbol");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
      ".subsections_via_symbols");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
    addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
      ".pushsection");
    addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
      ".popsection");
    addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
      ".secure_log_unique");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
      ".secure_log_reset");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");

    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
      ".data_region");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
      ".end_data_region");

    // Special section directives.
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
      ".const_data");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
      ".constructor");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
      ".cstring");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
      ".destructor");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
      ".fvmlib_init0");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
      ".fvmlib_init1");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
        ".lazy_symbol_pointer");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
      ".linker_option");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
      ".literal16");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
      ".literal4");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
      ".literal8");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
      ".mod_init_func");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
      ".mod_term_func");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
        ".non_lazy_symbol_pointer");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
        ".thread_local_variable_pointer");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
      ".objc_cat_cls_meth");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
      ".objc_cat_inst_meth");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
      ".objc_category");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
      ".objc_class");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
      ".objc_class_names");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
      ".objc_class_vars");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
      ".objc_cls_meth");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
      ".objc_cls_refs");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
      ".objc_inst_meth");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
        ".objc_instance_vars");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
      ".objc_message_refs");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
      ".objc_meta_class");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
        ".objc_meth_var_names");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
        ".objc_meth_var_types");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
      ".objc_module_info");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
      ".objc_protocol");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
        ".objc_selector_strs");
    addDirectiveHandler<
      &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
        ".objc_string_object");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
      ".objc_symbols");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
      ".picsymbol_stub");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
      ".static_const");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
      ".static_data");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
      ".symbol_stub");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
      ".thread_init_func");
    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");

    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
    addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
      ".watchos_version_min");
    addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
      ".tvos_version_min");
    addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
      ".ios_version_min");
    addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
      ".macosx_version_min");
    addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
    addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>(
        ".cg_profile");

    LastVersionDirective = SMLoc();
  }

  bool parseDirectiveAltEntry(StringRef, SMLoc);
  bool parseDirectiveDesc(StringRef, SMLoc);
  bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
  bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
  bool parseDirectiveLsym(StringRef, SMLoc);
  bool parseDirectiveLinkerOption(StringRef, SMLoc);
  bool parseDirectiveSection(StringRef, SMLoc);
  bool parseDirectivePushSection(StringRef, SMLoc);
  bool parseDirectivePopSection(StringRef, SMLoc);
  bool parseDirectivePrevious(StringRef, SMLoc);
  bool parseDirectiveSecureLogReset(StringRef, SMLoc);
  bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
  bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
  bool parseDirectiveTBSS(StringRef, SMLoc);
  bool parseDirectiveZerofill(StringRef, SMLoc);
  bool parseDirectiveDataRegion(StringRef, SMLoc);
  bool parseDirectiveDataRegionEnd(StringRef, SMLoc);

  // Named Section Directive
  bool parseSectionDirectiveBss(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__bss");
  }

  bool parseSectionDirectiveConst(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__const");
  }

  bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__static_const");
  }

  bool parseSectionDirectiveCString(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__cstring",
                              MachO::S_CSTRING_LITERALS);
  }

  bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__literal4",
                              MachO::S_4BYTE_LITERALS, 4);
  }

  bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__literal8",
                              MachO::S_8BYTE_LITERALS, 8);
  }

  bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__literal16",
                              MachO::S_16BYTE_LITERALS, 16);
  }

  bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__constructor");
  }

  bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__destructor");
  }

  bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__fvmlib_init0");
  }

  bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__fvmlib_init1");
  }

  bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__symbol_stub",
                              MachO::S_SYMBOL_STUBS |
                              MachO::S_ATTR_PURE_INSTRUCTIONS,
                              // FIXME: Different on PPC and ARM.
                              0, 16);
  }

  bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT","__picsymbol_stub",
                              MachO::S_SYMBOL_STUBS |
                              MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
  }

  bool parseSectionDirectiveData(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__data");
  }

  bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__static_data");
  }

  bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
                              MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
  }

  bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__la_symbol_ptr",
                              MachO::S_LAZY_SYMBOL_POINTERS, 4);
  }

  bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__thread_ptr",
                              MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
  }

  bool parseSectionDirectiveDyld(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__dyld");
  }

  bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__mod_init_func",
                              MachO::S_MOD_INIT_FUNC_POINTERS, 4);
  }

  bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__mod_term_func",
                              MachO::S_MOD_TERM_FUNC_POINTERS, 4);
  }

  bool parseSectionDirectiveConstData(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__const");
  }

  bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__class",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__meta_class",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__cat_cls_meth",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__cat_inst_meth",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__protocol",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__string_object",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__cls_meth",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__inst_meth",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__cls_refs",
                              MachO::S_ATTR_NO_DEAD_STRIP |
                              MachO::S_LITERAL_POINTERS, 4);
  }

  bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__message_refs",
                              MachO::S_ATTR_NO_DEAD_STRIP |
                              MachO::S_LITERAL_POINTERS, 4);
  }

  bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__symbols",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__category",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__class_vars",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__instance_vars",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__module_info",
                              MachO::S_ATTR_NO_DEAD_STRIP);
  }

  bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__cstring",
                              MachO::S_CSTRING_LITERALS);
  }

  bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__cstring",
                              MachO::S_CSTRING_LITERALS);
  }

  bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__cstring",
                              MachO::S_CSTRING_LITERALS);
  }

  bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
    return parseSectionSwitch("__OBJC", "__selector_strs",
                              MachO::S_CSTRING_LITERALS);
  }

  bool parseSectionDirectiveTData(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__thread_data",
                              MachO::S_THREAD_LOCAL_REGULAR);
  }

  bool parseSectionDirectiveText(StringRef, SMLoc) {
    return parseSectionSwitch("__TEXT", "__text",
                              MachO::S_ATTR_PURE_INSTRUCTIONS);
  }

  bool parseSectionDirectiveTLV(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__thread_vars",
                              MachO::S_THREAD_LOCAL_VARIABLES);
  }

  bool parseSectionDirectiveIdent(StringRef, SMLoc) {
    // Darwin silently ignores the .ident directive.
    getParser().eatToEndOfStatement();
    return false;
  }

  bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
    return parseSectionSwitch("__DATA", "__thread_init",
                         MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
  }

  bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {
    return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);
  }
  bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {
    return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);
  }
  bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {
    return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);
  }
  bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {
    return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);
  }

  bool parseBuildVersion(StringRef Directive, SMLoc Loc);
  bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
  bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,
                                       const char *VersionName);
  bool parseOptionalTrailingVersionComponent(unsigned *Component,
                                             const char *ComponentName);
  bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
  bool parseSDKVersion(VersionTuple &SDKVersion);
  void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
                    Triple::OSType ExpectedOS);
  bool parseDirectiveCGProfile(StringRef Directive, SMLoc Loc);
};

} // end anonymous namespace

bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,
                                         unsigned TAA, unsigned Alignment,
                                         unsigned StubSize) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in section switching directive");
  Lex();

  // FIXME: Arch specific.
  bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
  getStreamer().switchSection(getContext().getMachOSection(
      Segment, Section, TAA, StubSize,
      isText ? SectionKind::getText() : SectionKind::getData()));

  // Set the implicit alignment, if any.
  //
  // FIXME: This isn't really what 'as' does; I think it just uses the implicit
  // alignment on the section (e.g., if one manually inserts bytes into the
  // section, then just issuing the section switch directive will not realign
  // the section. However, this is arguably more reasonable behavior, and there
  // is no good reason for someone to intentionally emit incorrectly sized
  // values into the implicitly aligned sections.
  if (Alignment)
    getStreamer().emitValueToAlignment(Align(Alignment));

  return false;
}

/// parseDirectiveAltEntry
///  ::= .alt_entry identifier
bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {
  MCSymbol *Sym;
  if (getParser().parseSymbol(Sym))
    return TokError("expected identifier in directive");

  if (Sym->isDefined())
    return TokError(".alt_entry must preceed symbol definition");

  if (!getStreamer().emitSymbolAttribute(Sym, MCSA_AltEntry))
    return TokError("unable to emit symbol attribute");

  Lex();
  return false;
}

/// parseDirectiveDesc
///  ::= .desc identifier , expression
bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
  MCSymbol *Sym;
  if (getParser().parseSymbol(Sym))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("unexpected token in '.desc' directive");
  Lex();

  int64_t DescValue;
  if (getParser().parseAbsoluteExpression(DescValue))
    return true;

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

  Lex();

  // Set the n_desc field of this Symbol to this DescValue
  getStreamer().emitSymbolDesc(Sym, DescValue);

  return false;
}

/// parseDirectiveIndirectSymbol
///  ::= .indirect_symbol identifier
bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
  const MCSectionMachO *Current = static_cast<const MCSectionMachO *>(
      getStreamer().getCurrentSectionOnly());
  MachO::SectionType SectionType = Current->getType();
  if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
      SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
      SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
      SectionType != MachO::S_SYMBOL_STUBS)
    return Error(Loc, "indirect symbol not in a symbol pointer or stub "
                      "section");

  MCSymbol *Sym;
  if (getParser().parseSymbol(Sym))
    return TokError("expected identifier in .indirect_symbol directive");

  // 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: " +
                    Sym->getName());

  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,
                                               SMLoc IDLoc) {
  bool IsDump = Directive == ".dump";
  if (getLexer().isNot(AsmToken::String))
    return TokError("expected string in '.dump' or '.load' directive");

  Lex();

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

  Lex();

  // FIXME: If/when .dump and .load are implemented they will be done in the
  // the assembly parser and not have any need for an MCStreamer API.
  if (IsDump)
    return Warning(IDLoc, "ignoring directive .dump for now");
  else
    return Warning(IDLoc, "ignoring directive .load for now");
}

/// ParseDirectiveLinkerOption
///  ::= .linker_option "string" ( , "string" )*
bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
  SmallVector<std::string, 4> Args;
  while (true) {
    if (getLexer().isNot(AsmToken::String))
      return TokError("expected string in '" + Twine(IDVal) + "' directive");

    std::string Data;
    if (getParser().parseEscapedString(Data))
      return true;

    Args.push_back(Data);

    if (getLexer().is(AsmToken::EndOfStatement))
      break;

    if (getLexer().isNot(AsmToken::Comma))
      return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
    Lex();
  }

  getStreamer().emitLinkerOptions(Args);
  return false;
}

/// parseDirectiveLsym
///  ::= .lsym identifier , expression
bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
  MCSymbol *Sym;
  if (getParser().parseSymbol(Sym))
    return TokError("expected identifier in directive");

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("unexpected token in '.lsym' directive");
  Lex();

  const MCExpr *Value;
  if (getParser().parseExpression(Value))
    return true;

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

  Lex();

  // We don't currently support this directive.
  //
  // FIXME: Diagnostic location!
  (void) Sym;
  return TokError("directive '.lsym' is unsupported");
}

/// parseDirectiveSection:
///   ::= .section identifier (',' identifier)*
bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
  SMLoc Loc = getLexer().getLoc();

  StringRef SectionName;
  if (getParser().parseIdentifier(SectionName))
    return Error(Loc, "expected identifier after '.section' directive");

  // Verify there is a following comma.
  if (!getLexer().is(AsmToken::Comma))
    return TokError("unexpected token in '.section' directive");

  std::string SectionSpec = std::string(SectionName);
  SectionSpec += ",";

  // Add all the tokens until the end of the line, ParseSectionSpecifier will
  // handle this.
  StringRef EOL = getLexer().LexUntilEndOfStatement();
  SectionSpec.append(EOL.begin(), EOL.end());

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

  StringRef Segment, Section;
  unsigned StubSize;
  unsigned TAA;
  bool TAAParsed;
  if (class Error E = MCSectionMachO::ParseSectionSpecifier(
          SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))
    return Error(Loc, toString(std::move(E)));

  // Issue a warning if the target is not powerpc and Section is a *coal* section.
  Triple TT = getParser().getContext().getTargetTriple();
  Triple::ArchType ArchTy = TT.getArch();

  if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {
    StringRef NonCoalSection = StringSwitch<StringRef>(Section)
                                   .Case("__textcoal_nt", "__text")
                                   .Case("__const_coal", "__const")
                                   .Case("__datacoal_nt", "__data")
                                   .Default(Section);

    if (Section != NonCoalSection) {
      StringRef SectionVal(Loc.getPointer());
      size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B);
      SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B);
      SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E);
      getParser().Warning(Loc, "section \"" + Section + "\" is deprecated",
                          SMRange(BLoc, ELoc));
      getParser().Note(Loc, "change section name to \"" + NonCoalSection +
                       "\"", SMRange(BLoc, ELoc));
    }
  }

  // FIXME: Arch specific.
  bool isText = Segment == "__TEXT";  // FIXME: Hack.
  getStreamer().switchSection(getContext().getMachOSection(
      Segment, Section, TAA, StubSize,
      isText ? SectionKind::getText() : SectionKind::getData()));
  return false;
}

/// ParseDirectivePushSection:
///   ::= .pushsection identifier (',' identifier)*
bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
  getStreamer().pushSection();

  if (parseDirectiveSection(S, Loc)) {
    getStreamer().popSection();
    return true;
  }

  return false;
}

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

/// ParseDirectivePrevious:
///   ::= .previous
bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
  MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
  if (!PreviousSection.first)
    return TokError(".previous without corresponding .section");
  getStreamer().switchSection(PreviousSection.first, PreviousSection.second);
  return false;
}

/// ParseDirectiveSecureLogUnique
///  ::= .secure_log_unique ... message ...
bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
  StringRef LogMessage = getParser().parseStringToEndOfStatement();
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in '.secure_log_unique' directive");

  if (getContext().getSecureLogUsed())
    return Error(IDLoc, ".secure_log_unique specified multiple times");

  // Get the secure log path.
  StringRef SecureLogFile = getContext().getSecureLogFile();
  if (SecureLogFile.empty())
    return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
                 "environment variable unset.");

  // Open the secure log file if we haven't already.
  raw_fd_ostream *OS = getContext().getSecureLog();
  if (!OS) {
    std::error_code EC;
    auto NewOS = std::make_unique<raw_fd_ostream>(
        SecureLogFile, EC, sys::fs::OF_Append | sys::fs::OF_TextWithCRLF);
    if (EC)
       return Error(IDLoc, Twine("can't open secure log file: ") +
                               SecureLogFile + " (" + EC.message() + ")");
    OS = NewOS.get();
    getContext().setSecureLog(std::move(NewOS));
  }

  // Write the message.
  unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
  *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
      << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
      << LogMessage + "\n";

  getContext().setSecureLogUsed(true);

  return false;
}

/// ParseDirectiveSecureLogReset
///  ::= .secure_log_reset
bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in '.secure_log_reset' directive");

  Lex();

  getContext().setSecureLogUsed(false);

  return false;
}

/// parseDirectiveSubsectionsViaSymbols
///  ::= .subsections_via_symbols
bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in '.subsections_via_symbols' directive");

  Lex();

  getStreamer().emitSubsectionsViaSymbols();

  return false;
}

/// ParseDirectiveTBSS
///  ::= .tbss identifier, size, align
bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
  SMLoc IDLoc = getLexer().getLoc();
  MCSymbol *Sym;
  if (getParser().parseSymbol(Sym))
    return TokError("expected identifier in directive");

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

  int64_t Size;
  SMLoc SizeLoc = getLexer().getLoc();
  if (getParser().parseAbsoluteExpression(Size))
    return true;

  int64_t Pow2Alignment = 0;
  SMLoc Pow2AlignmentLoc;
  if (getLexer().is(AsmToken::Comma)) {
    Lex();
    Pow2AlignmentLoc = getLexer().getLoc();
    if (getParser().parseAbsoluteExpression(Pow2Alignment))
      return true;
  }

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

  Lex();

  if (Size < 0)
    return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
                 "zero");

  // FIXME: Diagnose overflow.
  if (Pow2Alignment < 0)
    return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
                 "than zero");

  if (!Sym->isUndefined())
    return Error(IDLoc, "invalid symbol redefinition");

  getStreamer().emitTBSSSymbol(
      getContext().getMachOSection("__DATA", "__thread_bss",
                                   MachO::S_THREAD_LOCAL_ZEROFILL, 0,
                                   SectionKind::getThreadBSS()),
      Sym, Size, Align(1ULL << Pow2Alignment));

  return false;
}

/// ParseDirectiveZerofill
///  ::= .zerofill segname , sectname [, identifier , size_expression [
///      , align_expression ]]
bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
  StringRef Segment;
  if (getParser().parseIdentifier(Segment))
    return TokError("expected segment name after '.zerofill' directive");

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

  StringRef Section;
  SMLoc SectionLoc = getLexer().getLoc();
  if (getParser().parseIdentifier(Section))
    return TokError("expected section name after comma in '.zerofill' "
                    "directive");

  // If this is the end of the line all that was wanted was to create the
  // the section but with no symbol.
  if (getLexer().is(AsmToken::EndOfStatement)) {
    // Create the zerofill section but no symbol
    getStreamer().emitZerofill(
        getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
                                     SectionKind::getBSS()),
        /*Symbol=*/nullptr, /*Size=*/0, Align(1), SectionLoc);
    return false;
  }

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

  SMLoc IDLoc = getLexer().getLoc();
  MCSymbol *Sym;
  if (getParser().parseSymbol(Sym))
    return TokError("expected identifier in directive");

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

  int64_t Size;
  SMLoc SizeLoc = getLexer().getLoc();
  if (getParser().parseAbsoluteExpression(Size))
    return true;

  int64_t Pow2Alignment = 0;
  SMLoc Pow2AlignmentLoc;
  if (getLexer().is(AsmToken::Comma)) {
    Lex();
    Pow2AlignmentLoc = getLexer().getLoc();
    if (getParser().parseAbsoluteExpression(Pow2Alignment))
      return true;
  }

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

  Lex();

  if (Size < 0)
    return Error(SizeLoc, "invalid '.zerofill' directive size, can't 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 '.zerofill' directive alignment, "
                 "can't be less than zero");

  if (!Sym->isUndefined())
    return Error(IDLoc, "invalid symbol redefinition");

  // Create the zerofill Symbol with Size and Pow2Alignment
  //
  // FIXME: Arch specific.
  getStreamer().emitZerofill(
      getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
                                   SectionKind::getBSS()),
      Sym, Size, Align(1ULL << Pow2Alignment), SectionLoc);

  return false;
}

/// ParseDirectiveDataRegion
///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
  if (getLexer().is(AsmToken::EndOfStatement)) {
    Lex();
    getStreamer().emitDataRegion(MCDR_DataRegion);
    return false;
  }
  StringRef RegionType;
  SMLoc Loc = getParser().getTok().getLoc();
  if (getParser().parseIdentifier(RegionType))
    return TokError("expected region type after '.data_region' directive");
  int Kind = StringSwitch<int>(RegionType)
    .Case("jt8", MCDR_DataRegionJT8)
    .Case("jt16", MCDR_DataRegionJT16)
    .Case("jt32", MCDR_DataRegionJT32)
    .Default(-1);
  if (Kind == -1)
    return Error(Loc, "unknown region type in '.data_region' directive");
  Lex();

  getStreamer().emitDataRegion((MCDataRegionType)Kind);
  return false;
}

/// ParseDirectiveDataRegionEnd
///  ::= .end_data_region
bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in '.end_data_region' directive");

  Lex();
  getStreamer().emitDataRegion(MCDR_DataRegionEnd);
  return false;
}

static bool isSDKVersionToken(const AsmToken &Tok) {
  return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";
}

/// parseMajorMinorVersionComponent ::= major, minor
bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,
                                                      unsigned *Minor,
                                                      const char *VersionName) {
  // Get the major version number.
  if (getLexer().isNot(AsmToken::Integer))
    return TokError(Twine("invalid ") + VersionName +
                    " major version number, integer expected");
  int64_t MajorVal = getLexer().getTok().getIntVal();
  if (MajorVal > 65535 || MajorVal <= 0)
    return TokError(Twine("invalid ") + VersionName + " major version number");
  *Major = (unsigned)MajorVal;
  Lex();
  if (getLexer().isNot(AsmToken::Comma))
    return TokError(Twine(VersionName) +
                    " minor version number required, comma expected");
  Lex();
  // Get the minor version number.
  if (getLexer().isNot(AsmToken::Integer))
    return TokError(Twine("invalid ") + VersionName +
                    " minor version number, integer expected");
  int64_t MinorVal = getLexer().getTok().getIntVal();
  if (MinorVal > 255 || MinorVal < 0)
    return TokError(Twine("invalid ") + VersionName + " minor version number");
  *Minor = MinorVal;
  Lex();
  return false;
}

/// parseOptionalTrailingVersionComponent ::= , version_number
bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
    unsigned *Component, const char *ComponentName) {
  assert(getLexer().is(AsmToken::Comma) && "comma expected");
  Lex();
  if (getLexer().isNot(AsmToken::Integer))
    return TokError(Twine("invalid ") + ComponentName +
                    " version number, integer expected");
  int64_t Val = getLexer().getTok().getIntVal();
  if (Val > 255 || Val < 0)
    return TokError(Twine("invalid ") + ComponentName + " version number");
  *Component = Val;
  Lex();
  return false;
}

/// parseVersion ::= parseMajorMinorVersionComponent
///                      parseOptionalTrailingVersionComponent
bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
                                   unsigned *Update) {
  if (parseMajorMinorVersionComponent(Major, Minor, "OS"))
    return true;

  // Get the update level, if specified
  *Update = 0;
  if (getLexer().is(AsmToken::EndOfStatement) ||
      isSDKVersionToken(getLexer().getTok()))
    return false;
  if (getLexer().isNot(AsmToken::Comma))
    return TokError("invalid OS update specifier, comma expected");
  if (parseOptionalTrailingVersionComponent(Update, "OS update"))
    return true;
  return false;
}

bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {
  assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
  Lex();
  unsigned Major, Minor;
  if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))
    return true;
  SDKVersion = VersionTuple(Major, Minor);

  // Get the subminor version, if specified.
  if (getLexer().is(AsmToken::Comma)) {
    unsigned Subminor;
    if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))
      return true;
    SDKVersion = VersionTuple(Major, Minor, Subminor);
  }
  return false;
}

void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
                                   SMLoc Loc, Triple::OSType ExpectedOS) {
  const Triple &Target = getContext().getTargetTriple();
  if (Target.getOS() != ExpectedOS)
    Warning(Loc, Twine(Directive) +
            (Arg.empty() ? Twine() : Twine(' ') + Arg) +
            " used while targeting " + Target.getOSName());

  if (LastVersionDirective.isValid()) {
    Warning(Loc, "overriding previous version directive");
    Note(LastVersionDirective, "previous definition is here");
  }
  LastVersionDirective = Loc;
}

static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
  switch (Type) {
  case MCVM_WatchOSVersionMin: return Triple::WatchOS;
  case MCVM_TvOSVersionMin:    return Triple::TvOS;
  case MCVM_IOSVersionMin:     return Triple::IOS;
  case MCVM_OSXVersionMin:     return Triple::MacOSX;
  }
  llvm_unreachable("Invalid mc version min type");
}

/// parseVersionMin
///   ::= .ios_version_min parseVersion parseSDKVersion
///   |   .macosx_version_min parseVersion parseSDKVersion
///   |   .tvos_version_min parseVersion parseSDKVersion
///   |   .watchos_version_min parseVersion parseSDKVersion
bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
                                      MCVersionMinType Type) {
  unsigned Major;
  unsigned Minor;
  unsigned Update;
  if (parseVersion(&Major, &Minor, &Update))
    return true;

  VersionTuple SDKVersion;
  if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
    return true;

  if (parseEOL())
    return addErrorSuffix(Twine(" in '") + Directive + "' directive");

  Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
  checkVersion(Directive, StringRef(), Loc, ExpectedOS);
  getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion);
  return false;
}

static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
  switch (Type) {
  case MachO::PLATFORM_UNKNOWN: /* silence warning */
    break;
  case MachO::PLATFORM_MACOS:   return Triple::MacOSX;
  case MachO::PLATFORM_IOS:     return Triple::IOS;
  case MachO::PLATFORM_TVOS:    return Triple::TvOS;
  case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;
  case MachO::PLATFORM_XROS:    return Triple::XROS;
  case MachO::PLATFORM_BRIDGEOS:         /* silence warning */ break;
  case MachO::PLATFORM_DRIVERKIT:
    return Triple::DriverKit;
  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;
  case MachO::PLATFORM_XROS_SIMULATOR:   /* silence warning */ break;
  }
  llvm_unreachable("Invalid mach-o platform type");
}

/// parseBuildVersion
///   ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
  StringRef PlatformName;
  SMLoc PlatformLoc = getTok().getLoc();
  if (getParser().parseIdentifier(PlatformName))
    return TokError("platform name expected");

  unsigned Platform = StringSwitch<unsigned>(PlatformName)
#define PLATFORM(platform, id, name, build_name, target, tapi_target,          \
                 marketing)                                                    \
  .Case(#build_name, MachO::PLATFORM_##platform)
#include "llvm/BinaryFormat/MachO.def"
                          .Default(MachO::PLATFORM_UNKNOWN);

  if (Platform == MachO::PLATFORM_UNKNOWN)
    return Error(PlatformLoc, "unknown platform name");

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("version number required, comma expected");
  Lex();

  unsigned Major;
  unsigned Minor;
  unsigned Update;
  if (parseVersion(&Major, &Minor, &Update))
    return true;

  VersionTuple SDKVersion;
  if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
    return true;

  if (parseEOL())
    return addErrorSuffix(" in '.build_version' directive");

  Triple::OSType ExpectedOS
    = getOSTypeFromPlatform((MachO::PlatformType)Platform);
  checkVersion(Directive, PlatformName, Loc, ExpectedOS);
  getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
  return false;
}

/// parseDirectiveCGProfile
///   ::= .cg_profile from, to, count
bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
  return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);
}

namespace llvm {

MCAsmParserExtension *createDarwinAsmParser() {
  return new DarwinAsmParser;
}

} // end llvm namespace
