//===- 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/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.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/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#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");

    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);
};

} // end anonymous namespace

bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,
                                         unsigned TAA, unsigned Align,
                                         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 (Align)
    getStreamer().emitValueToAlignment(Align);

  return false;
}

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

  // Look up symbol.
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);

  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) {
  StringRef Name;
  if (getParser().parseIdentifier(Name))
    return TokError("expected identifier in directive");

  // Handle the identifier as the key symbol.
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);

  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");

  StringRef Name;
  if (getParser().parseIdentifier(Name))
    return TokError("expected identifier in .indirect_symbol directive");

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

  // Assembler local symbols don't make any sense here. Complain loudly.
  if (Sym->isTemporary())
    return TokError("non-local symbol required in directive");

  if (!getStreamer().emitSymbolAttribute(Sym, MCSA_IndirectSymbol))
    return TokError("unable to emit indirect symbol attribute for: " + Name);

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

  Lex();

  return false;
}

/// parseDirectiveDumpOrLoad
///  ::= ( .dump | .load ) "filename"
bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
                                               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) {
  StringRef Name;
  if (getParser().parseIdentifier(Name))
    return TokError("expected identifier in directive");

  // Handle the identifier as the key symbol.
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);

  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;
  std::string ErrorStr =
    MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
                                          TAA, TAAParsed, StubSize);

  if (!ErrorStr.empty())
    return Error(Loc, ErrorStr);

  // Issue a warning if the target is not powerpc and Section is a *coal* section.
  Triple TT = getParser().getContext().getObjectFileInfo()->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.equals(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.
  const char *SecureLogFile = getContext().getSecureLogFile();
  if (!SecureLogFile)
    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>(
        StringRef(SecureLogFile), EC, sys::fs::OF_Append | sys::fs::OF_Text);
    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().emitAssemblerFlag(MCAF_SubsectionsViaSymbols);

  return false;
}

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

  // Handle the identifier as the key symbol.
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);

  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, 1 << 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, /*ByteAlignment=*/0, SectionLoc);
    return false;
  }

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

  SMLoc IDLoc = getLexer().getLoc();
  StringRef IDStr;
  if (getParser().parseIdentifier(IDStr))
    return TokError("expected identifier in directive");

  // handle the identifier as the key symbol.
  MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr);

  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, 1 << 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().getObjectFileInfo()->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 (parseToken(AsmToken::EndOfStatement))
    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_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_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;
  case MachO::PLATFORM_DRIVERKIT:        /* 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)
    .Case("macos", MachO::PLATFORM_MACOS)
    .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");

  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 (parseToken(AsmToken::EndOfStatement))
    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;
}


namespace llvm {

MCAsmParserExtension *createDarwinAsmParser() {
  return new DarwinAsmParser;
}

} // end llvm namespace
