brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.1 KiB · c4c4c5e Raw
1198 lines · cpp
1//===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/SmallVector.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/ADT/StringSwitch.h"12#include "llvm/ADT/Twine.h"13#include "llvm/BinaryFormat/MachO.h"14#include "llvm/MC/MCContext.h"15#include "llvm/MC/MCDirectives.h"16#include "llvm/MC/MCParser/AsmLexer.h"17#include "llvm/MC/MCParser/MCAsmParser.h"18#include "llvm/MC/MCParser/MCAsmParserExtension.h"19#include "llvm/MC/MCSectionMachO.h"20#include "llvm/MC/MCStreamer.h"21#include "llvm/MC/MCSymbol.h"22#include "llvm/MC/SectionKind.h"23#include "llvm/Support/Error.h"24#include "llvm/Support/FileSystem.h"25#include "llvm/Support/MemoryBuffer.h"26#include "llvm/Support/SMLoc.h"27#include "llvm/Support/SourceMgr.h"28#include "llvm/Support/raw_ostream.h"29#include "llvm/TargetParser/Triple.h"30#include <cstddef>31#include <cstdint>32#include <string>33#include <system_error>34#include <utility>35 36using namespace llvm;37 38namespace {39 40/// Implementation of directive handling which is shared across all41/// Darwin targets.42class DarwinAsmParser : public MCAsmParserExtension {43  template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>44  void addDirectiveHandler(StringRef Directive) {45    MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(46        this, HandleDirective<DarwinAsmParser, HandlerMethod>);47    getParser().addDirectiveHandler(Directive, Handler);48  }49 50  bool parseSectionSwitch(StringRef Segment, StringRef Section,51                          unsigned TAA = 0, unsigned ImplicitAlign = 0,52                          unsigned StubSize = 0);53 54  SMLoc LastVersionDirective;55 56public:57  DarwinAsmParser() = default;58 59  void Initialize(MCAsmParser &Parser) override {60    // Call the base implementation.61    this->MCAsmParserExtension::Initialize(Parser);62 63    addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");64    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");65    addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(66      ".indirect_symbol");67    addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");68    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(69      ".subsections_via_symbols");70    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");71    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");72    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");73    addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(74      ".pushsection");75    addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(76      ".popsection");77    addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");78    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(79      ".secure_log_unique");80    addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(81      ".secure_log_reset");82    addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");83    addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");84 85    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(86      ".data_region");87    addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(88      ".end_data_region");89 90    // Special section directives.91    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");92    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");93    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(94      ".const_data");95    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(96      ".constructor");97    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(98      ".cstring");99    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");100    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(101      ".destructor");102    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");103    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(104      ".fvmlib_init0");105    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(106      ".fvmlib_init1");107    addDirectiveHandler<108      &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(109        ".lazy_symbol_pointer");110    addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(111      ".linker_option");112    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(113      ".literal16");114    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(115      ".literal4");116    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(117      ".literal8");118    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(119      ".mod_init_func");120    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(121      ".mod_term_func");122    addDirectiveHandler<123      &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(124        ".non_lazy_symbol_pointer");125    addDirectiveHandler<126      &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(127        ".thread_local_variable_pointer");128    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(129      ".objc_cat_cls_meth");130    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(131      ".objc_cat_inst_meth");132    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(133      ".objc_category");134    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(135      ".objc_class");136    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(137      ".objc_class_names");138    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(139      ".objc_class_vars");140    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(141      ".objc_cls_meth");142    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(143      ".objc_cls_refs");144    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(145      ".objc_inst_meth");146    addDirectiveHandler<147      &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(148        ".objc_instance_vars");149    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(150      ".objc_message_refs");151    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(152      ".objc_meta_class");153    addDirectiveHandler<154      &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(155        ".objc_meth_var_names");156    addDirectiveHandler<157      &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(158        ".objc_meth_var_types");159    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(160      ".objc_module_info");161    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(162      ".objc_protocol");163    addDirectiveHandler<164      &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(165        ".objc_selector_strs");166    addDirectiveHandler<167      &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(168        ".objc_string_object");169    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(170      ".objc_symbols");171    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(172      ".picsymbol_stub");173    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(174      ".static_const");175    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(176      ".static_data");177    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(178      ".symbol_stub");179    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");180    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");181    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(182      ".thread_init_func");183    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");184 185    addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");186    addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(187      ".watchos_version_min");188    addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(189      ".tvos_version_min");190    addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(191      ".ios_version_min");192    addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(193      ".macosx_version_min");194    addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");195    addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>(196        ".cg_profile");197 198    LastVersionDirective = SMLoc();199  }200 201  bool parseDirectiveAltEntry(StringRef, SMLoc);202  bool parseDirectiveDesc(StringRef, SMLoc);203  bool parseDirectiveIndirectSymbol(StringRef, SMLoc);204  bool parseDirectiveDumpOrLoad(StringRef, SMLoc);205  bool parseDirectiveLsym(StringRef, SMLoc);206  bool parseDirectiveLinkerOption(StringRef, SMLoc);207  bool parseDirectiveSection(StringRef, SMLoc);208  bool parseDirectivePushSection(StringRef, SMLoc);209  bool parseDirectivePopSection(StringRef, SMLoc);210  bool parseDirectivePrevious(StringRef, SMLoc);211  bool parseDirectiveSecureLogReset(StringRef, SMLoc);212  bool parseDirectiveSecureLogUnique(StringRef, SMLoc);213  bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);214  bool parseDirectiveTBSS(StringRef, SMLoc);215  bool parseDirectiveZerofill(StringRef, SMLoc);216  bool parseDirectiveDataRegion(StringRef, SMLoc);217  bool parseDirectiveDataRegionEnd(StringRef, SMLoc);218 219  // Named Section Directive220  bool parseSectionDirectiveBss(StringRef, SMLoc) {221    return parseSectionSwitch("__DATA", "__bss");222  }223 224  bool parseSectionDirectiveConst(StringRef, SMLoc) {225    return parseSectionSwitch("__TEXT", "__const");226  }227 228  bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {229    return parseSectionSwitch("__TEXT", "__static_const");230  }231 232  bool parseSectionDirectiveCString(StringRef, SMLoc) {233    return parseSectionSwitch("__TEXT","__cstring",234                              MachO::S_CSTRING_LITERALS);235  }236 237  bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {238    return parseSectionSwitch("__TEXT", "__literal4",239                              MachO::S_4BYTE_LITERALS, 4);240  }241 242  bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {243    return parseSectionSwitch("__TEXT", "__literal8",244                              MachO::S_8BYTE_LITERALS, 8);245  }246 247  bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {248    return parseSectionSwitch("__TEXT","__literal16",249                              MachO::S_16BYTE_LITERALS, 16);250  }251 252  bool parseSectionDirectiveConstructor(StringRef, SMLoc) {253    return parseSectionSwitch("__TEXT","__constructor");254  }255 256  bool parseSectionDirectiveDestructor(StringRef, SMLoc) {257    return parseSectionSwitch("__TEXT","__destructor");258  }259 260  bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {261    return parseSectionSwitch("__TEXT","__fvmlib_init0");262  }263 264  bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {265    return parseSectionSwitch("__TEXT","__fvmlib_init1");266  }267 268  bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {269    return parseSectionSwitch("__TEXT","__symbol_stub",270                              MachO::S_SYMBOL_STUBS |271                              MachO::S_ATTR_PURE_INSTRUCTIONS,272                              // FIXME: Different on PPC and ARM.273                              0, 16);274  }275 276  bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {277    return parseSectionSwitch("__TEXT","__picsymbol_stub",278                              MachO::S_SYMBOL_STUBS |279                              MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);280  }281 282  bool parseSectionDirectiveData(StringRef, SMLoc) {283    return parseSectionSwitch("__DATA", "__data");284  }285 286  bool parseSectionDirectiveStaticData(StringRef, SMLoc) {287    return parseSectionSwitch("__DATA", "__static_data");288  }289 290  bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {291    return parseSectionSwitch("__DATA", "__nl_symbol_ptr",292                              MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);293  }294 295  bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {296    return parseSectionSwitch("__DATA", "__la_symbol_ptr",297                              MachO::S_LAZY_SYMBOL_POINTERS, 4);298  }299 300  bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {301    return parseSectionSwitch("__DATA", "__thread_ptr",302                              MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);303  }304 305  bool parseSectionDirectiveDyld(StringRef, SMLoc) {306    return parseSectionSwitch("__DATA", "__dyld");307  }308 309  bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {310    return parseSectionSwitch("__DATA", "__mod_init_func",311                              MachO::S_MOD_INIT_FUNC_POINTERS, 4);312  }313 314  bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {315    return parseSectionSwitch("__DATA", "__mod_term_func",316                              MachO::S_MOD_TERM_FUNC_POINTERS, 4);317  }318 319  bool parseSectionDirectiveConstData(StringRef, SMLoc) {320    return parseSectionSwitch("__DATA", "__const");321  }322 323  bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {324    return parseSectionSwitch("__OBJC", "__class",325                              MachO::S_ATTR_NO_DEAD_STRIP);326  }327 328  bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {329    return parseSectionSwitch("__OBJC", "__meta_class",330                              MachO::S_ATTR_NO_DEAD_STRIP);331  }332 333  bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {334    return parseSectionSwitch("__OBJC", "__cat_cls_meth",335                              MachO::S_ATTR_NO_DEAD_STRIP);336  }337 338  bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {339    return parseSectionSwitch("__OBJC", "__cat_inst_meth",340                              MachO::S_ATTR_NO_DEAD_STRIP);341  }342 343  bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {344    return parseSectionSwitch("__OBJC", "__protocol",345                              MachO::S_ATTR_NO_DEAD_STRIP);346  }347 348  bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {349    return parseSectionSwitch("__OBJC", "__string_object",350                              MachO::S_ATTR_NO_DEAD_STRIP);351  }352 353  bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {354    return parseSectionSwitch("__OBJC", "__cls_meth",355                              MachO::S_ATTR_NO_DEAD_STRIP);356  }357 358  bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {359    return parseSectionSwitch("__OBJC", "__inst_meth",360                              MachO::S_ATTR_NO_DEAD_STRIP);361  }362 363  bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {364    return parseSectionSwitch("__OBJC", "__cls_refs",365                              MachO::S_ATTR_NO_DEAD_STRIP |366                              MachO::S_LITERAL_POINTERS, 4);367  }368 369  bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {370    return parseSectionSwitch("__OBJC", "__message_refs",371                              MachO::S_ATTR_NO_DEAD_STRIP |372                              MachO::S_LITERAL_POINTERS, 4);373  }374 375  bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {376    return parseSectionSwitch("__OBJC", "__symbols",377                              MachO::S_ATTR_NO_DEAD_STRIP);378  }379 380  bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {381    return parseSectionSwitch("__OBJC", "__category",382                              MachO::S_ATTR_NO_DEAD_STRIP);383  }384 385  bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {386    return parseSectionSwitch("__OBJC", "__class_vars",387                              MachO::S_ATTR_NO_DEAD_STRIP);388  }389 390  bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {391    return parseSectionSwitch("__OBJC", "__instance_vars",392                              MachO::S_ATTR_NO_DEAD_STRIP);393  }394 395  bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {396    return parseSectionSwitch("__OBJC", "__module_info",397                              MachO::S_ATTR_NO_DEAD_STRIP);398  }399 400  bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {401    return parseSectionSwitch("__TEXT", "__cstring",402                              MachO::S_CSTRING_LITERALS);403  }404 405  bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {406    return parseSectionSwitch("__TEXT", "__cstring",407                              MachO::S_CSTRING_LITERALS);408  }409 410  bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {411    return parseSectionSwitch("__TEXT", "__cstring",412                              MachO::S_CSTRING_LITERALS);413  }414 415  bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {416    return parseSectionSwitch("__OBJC", "__selector_strs",417                              MachO::S_CSTRING_LITERALS);418  }419 420  bool parseSectionDirectiveTData(StringRef, SMLoc) {421    return parseSectionSwitch("__DATA", "__thread_data",422                              MachO::S_THREAD_LOCAL_REGULAR);423  }424 425  bool parseSectionDirectiveText(StringRef, SMLoc) {426    return parseSectionSwitch("__TEXT", "__text",427                              MachO::S_ATTR_PURE_INSTRUCTIONS);428  }429 430  bool parseSectionDirectiveTLV(StringRef, SMLoc) {431    return parseSectionSwitch("__DATA", "__thread_vars",432                              MachO::S_THREAD_LOCAL_VARIABLES);433  }434 435  bool parseSectionDirectiveIdent(StringRef, SMLoc) {436    // Darwin silently ignores the .ident directive.437    getParser().eatToEndOfStatement();438    return false;439  }440 441  bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {442    return parseSectionSwitch("__DATA", "__thread_init",443                         MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);444  }445 446  bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {447    return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);448  }449  bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {450    return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);451  }452  bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {453    return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);454  }455  bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {456    return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);457  }458 459  bool parseBuildVersion(StringRef Directive, SMLoc Loc);460  bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);461  bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,462                                       const char *VersionName);463  bool parseOptionalTrailingVersionComponent(unsigned *Component,464                                             const char *ComponentName);465  bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);466  bool parseSDKVersion(VersionTuple &SDKVersion);467  void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,468                    Triple::OSType ExpectedOS);469  bool parseDirectiveCGProfile(StringRef Directive, SMLoc Loc);470};471 472} // end anonymous namespace473 474bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,475                                         unsigned TAA, unsigned Alignment,476                                         unsigned StubSize) {477  if (getLexer().isNot(AsmToken::EndOfStatement))478    return TokError("unexpected token in section switching directive");479  Lex();480 481  // FIXME: Arch specific.482  bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;483  getStreamer().switchSection(getContext().getMachOSection(484      Segment, Section, TAA, StubSize,485      isText ? SectionKind::getText() : SectionKind::getData()));486 487  // Set the implicit alignment, if any.488  //489  // FIXME: This isn't really what 'as' does; I think it just uses the implicit490  // alignment on the section (e.g., if one manually inserts bytes into the491  // section, then just issuing the section switch directive will not realign492  // the section. However, this is arguably more reasonable behavior, and there493  // is no good reason for someone to intentionally emit incorrectly sized494  // values into the implicitly aligned sections.495  if (Alignment)496    getStreamer().emitValueToAlignment(Align(Alignment));497 498  return false;499}500 501/// parseDirectiveAltEntry502///  ::= .alt_entry identifier503bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {504  MCSymbol *Sym;505  if (getParser().parseSymbol(Sym))506    return TokError("expected identifier in directive");507 508  if (Sym->isDefined())509    return TokError(".alt_entry must preceed symbol definition");510 511  if (!getStreamer().emitSymbolAttribute(Sym, MCSA_AltEntry))512    return TokError("unable to emit symbol attribute");513 514  Lex();515  return false;516}517 518/// parseDirectiveDesc519///  ::= .desc identifier , expression520bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {521  MCSymbol *Sym;522  if (getParser().parseSymbol(Sym))523    return TokError("expected identifier in directive");524 525  if (getLexer().isNot(AsmToken::Comma))526    return TokError("unexpected token in '.desc' directive");527  Lex();528 529  int64_t DescValue;530  if (getParser().parseAbsoluteExpression(DescValue))531    return true;532 533  if (getLexer().isNot(AsmToken::EndOfStatement))534    return TokError("unexpected token in '.desc' directive");535 536  Lex();537 538  // Set the n_desc field of this Symbol to this DescValue539  getStreamer().emitSymbolDesc(Sym, DescValue);540 541  return false;542}543 544/// parseDirectiveIndirectSymbol545///  ::= .indirect_symbol identifier546bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {547  const MCSectionMachO *Current = static_cast<const MCSectionMachO *>(548      getStreamer().getCurrentSectionOnly());549  MachO::SectionType SectionType = Current->getType();550  if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&551      SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&552      SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&553      SectionType != MachO::S_SYMBOL_STUBS)554    return Error(Loc, "indirect symbol not in a symbol pointer or stub "555                      "section");556 557  MCSymbol *Sym;558  if (getParser().parseSymbol(Sym))559    return TokError("expected identifier in .indirect_symbol directive");560 561  // Assembler local symbols don't make any sense here. Complain loudly.562  if (Sym->isTemporary())563    return TokError("non-local symbol required in directive");564 565  if (!getStreamer().emitSymbolAttribute(Sym, MCSA_IndirectSymbol))566    return TokError("unable to emit indirect symbol attribute for: " +567                    Sym->getName());568 569  if (getLexer().isNot(AsmToken::EndOfStatement))570    return TokError("unexpected token in '.indirect_symbol' directive");571 572  Lex();573 574  return false;575}576 577/// parseDirectiveDumpOrLoad578///  ::= ( .dump | .load ) "filename"579bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,580                                               SMLoc IDLoc) {581  bool IsDump = Directive == ".dump";582  if (getLexer().isNot(AsmToken::String))583    return TokError("expected string in '.dump' or '.load' directive");584 585  Lex();586 587  if (getLexer().isNot(AsmToken::EndOfStatement))588    return TokError("unexpected token in '.dump' or '.load' directive");589 590  Lex();591 592  // FIXME: If/when .dump and .load are implemented they will be done in the593  // the assembly parser and not have any need for an MCStreamer API.594  if (IsDump)595    return Warning(IDLoc, "ignoring directive .dump for now");596  else597    return Warning(IDLoc, "ignoring directive .load for now");598}599 600/// ParseDirectiveLinkerOption601///  ::= .linker_option "string" ( , "string" )*602bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {603  SmallVector<std::string, 4> Args;604  while (true) {605    if (getLexer().isNot(AsmToken::String))606      return TokError("expected string in '" + Twine(IDVal) + "' directive");607 608    std::string Data;609    if (getParser().parseEscapedString(Data))610      return true;611 612    Args.push_back(Data);613 614    if (getLexer().is(AsmToken::EndOfStatement))615      break;616 617    if (getLexer().isNot(AsmToken::Comma))618      return TokError("unexpected token in '" + Twine(IDVal) + "' directive");619    Lex();620  }621 622  getStreamer().emitLinkerOptions(Args);623  return false;624}625 626/// parseDirectiveLsym627///  ::= .lsym identifier , expression628bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {629  MCSymbol *Sym;630  if (getParser().parseSymbol(Sym))631    return TokError("expected identifier in directive");632 633  if (getLexer().isNot(AsmToken::Comma))634    return TokError("unexpected token in '.lsym' directive");635  Lex();636 637  const MCExpr *Value;638  if (getParser().parseExpression(Value))639    return true;640 641  if (getLexer().isNot(AsmToken::EndOfStatement))642    return TokError("unexpected token in '.lsym' directive");643 644  Lex();645 646  // We don't currently support this directive.647  //648  // FIXME: Diagnostic location!649  (void) Sym;650  return TokError("directive '.lsym' is unsupported");651}652 653/// parseDirectiveSection:654///   ::= .section identifier (',' identifier)*655bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {656  SMLoc Loc = getLexer().getLoc();657 658  StringRef SectionName;659  if (getParser().parseIdentifier(SectionName))660    return Error(Loc, "expected identifier after '.section' directive");661 662  // Verify there is a following comma.663  if (!getLexer().is(AsmToken::Comma))664    return TokError("unexpected token in '.section' directive");665 666  std::string SectionSpec = std::string(SectionName);667  SectionSpec += ",";668 669  // Add all the tokens until the end of the line, ParseSectionSpecifier will670  // handle this.671  StringRef EOL = getLexer().LexUntilEndOfStatement();672  SectionSpec.append(EOL.begin(), EOL.end());673 674  Lex();675  if (getLexer().isNot(AsmToken::EndOfStatement))676    return TokError("unexpected token in '.section' directive");677  Lex();678 679  StringRef Segment, Section;680  unsigned StubSize;681  unsigned TAA;682  bool TAAParsed;683  if (class Error E = MCSectionMachO::ParseSectionSpecifier(684          SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))685    return Error(Loc, toString(std::move(E)));686 687  // Issue a warning if the target is not powerpc and Section is a *coal* section.688  Triple TT = getParser().getContext().getTargetTriple();689  Triple::ArchType ArchTy = TT.getArch();690 691  if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {692    StringRef NonCoalSection = StringSwitch<StringRef>(Section)693                                   .Case("__textcoal_nt", "__text")694                                   .Case("__const_coal", "__const")695                                   .Case("__datacoal_nt", "__data")696                                   .Default(Section);697 698    if (Section != NonCoalSection) {699      StringRef SectionVal(Loc.getPointer());700      size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B);701      SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B);702      SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E);703      getParser().Warning(Loc, "section \"" + Section + "\" is deprecated",704                          SMRange(BLoc, ELoc));705      getParser().Note(Loc, "change section name to \"" + NonCoalSection +706                       "\"", SMRange(BLoc, ELoc));707    }708  }709 710  // FIXME: Arch specific.711  bool isText = Segment == "__TEXT";  // FIXME: Hack.712  getStreamer().switchSection(getContext().getMachOSection(713      Segment, Section, TAA, StubSize,714      isText ? SectionKind::getText() : SectionKind::getData()));715  return false;716}717 718/// ParseDirectivePushSection:719///   ::= .pushsection identifier (',' identifier)*720bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {721  getStreamer().pushSection();722 723  if (parseDirectiveSection(S, Loc)) {724    getStreamer().popSection();725    return true;726  }727 728  return false;729}730 731/// ParseDirectivePopSection:732///   ::= .popsection733bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {734  if (!getStreamer().popSection())735    return TokError(".popsection without corresponding .pushsection");736  return false;737}738 739/// ParseDirectivePrevious:740///   ::= .previous741bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {742  MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();743  if (!PreviousSection.first)744    return TokError(".previous without corresponding .section");745  getStreamer().switchSection(PreviousSection.first, PreviousSection.second);746  return false;747}748 749/// ParseDirectiveSecureLogUnique750///  ::= .secure_log_unique ... message ...751bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {752  StringRef LogMessage = getParser().parseStringToEndOfStatement();753  if (getLexer().isNot(AsmToken::EndOfStatement))754    return TokError("unexpected token in '.secure_log_unique' directive");755 756  if (getContext().getSecureLogUsed())757    return Error(IDLoc, ".secure_log_unique specified multiple times");758 759  // Get the secure log path.760  StringRef SecureLogFile = getContext().getSecureLogFile();761  if (SecureLogFile.empty())762    return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "763                 "environment variable unset.");764 765  // Open the secure log file if we haven't already.766  raw_fd_ostream *OS = getContext().getSecureLog();767  if (!OS) {768    std::error_code EC;769    auto NewOS = std::make_unique<raw_fd_ostream>(770        SecureLogFile, EC, sys::fs::OF_Append | sys::fs::OF_TextWithCRLF);771    if (EC)772       return Error(IDLoc, Twine("can't open secure log file: ") +773                               SecureLogFile + " (" + EC.message() + ")");774    OS = NewOS.get();775    getContext().setSecureLog(std::move(NewOS));776  }777 778  // Write the message.779  unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);780  *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()781      << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"782      << LogMessage + "\n";783 784  getContext().setSecureLogUsed(true);785 786  return false;787}788 789/// ParseDirectiveSecureLogReset790///  ::= .secure_log_reset791bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {792  if (getLexer().isNot(AsmToken::EndOfStatement))793    return TokError("unexpected token in '.secure_log_reset' directive");794 795  Lex();796 797  getContext().setSecureLogUsed(false);798 799  return false;800}801 802/// parseDirectiveSubsectionsViaSymbols803///  ::= .subsections_via_symbols804bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {805  if (getLexer().isNot(AsmToken::EndOfStatement))806    return TokError("unexpected token in '.subsections_via_symbols' directive");807 808  Lex();809 810  getStreamer().emitSubsectionsViaSymbols();811 812  return false;813}814 815/// ParseDirectiveTBSS816///  ::= .tbss identifier, size, align817bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {818  SMLoc IDLoc = getLexer().getLoc();819  MCSymbol *Sym;820  if (getParser().parseSymbol(Sym))821    return TokError("expected identifier in directive");822 823  if (getLexer().isNot(AsmToken::Comma))824    return TokError("unexpected token in directive");825  Lex();826 827  int64_t Size;828  SMLoc SizeLoc = getLexer().getLoc();829  if (getParser().parseAbsoluteExpression(Size))830    return true;831 832  int64_t Pow2Alignment = 0;833  SMLoc Pow2AlignmentLoc;834  if (getLexer().is(AsmToken::Comma)) {835    Lex();836    Pow2AlignmentLoc = getLexer().getLoc();837    if (getParser().parseAbsoluteExpression(Pow2Alignment))838      return true;839  }840 841  if (getLexer().isNot(AsmToken::EndOfStatement))842    return TokError("unexpected token in '.tbss' directive");843 844  Lex();845 846  if (Size < 0)847    return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"848                 "zero");849 850  // FIXME: Diagnose overflow.851  if (Pow2Alignment < 0)852    return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"853                 "than zero");854 855  if (!Sym->isUndefined())856    return Error(IDLoc, "invalid symbol redefinition");857 858  getStreamer().emitTBSSSymbol(859      getContext().getMachOSection("__DATA", "__thread_bss",860                                   MachO::S_THREAD_LOCAL_ZEROFILL, 0,861                                   SectionKind::getThreadBSS()),862      Sym, Size, Align(1ULL << Pow2Alignment));863 864  return false;865}866 867/// ParseDirectiveZerofill868///  ::= .zerofill segname , sectname [, identifier , size_expression [869///      , align_expression ]]870bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {871  StringRef Segment;872  if (getParser().parseIdentifier(Segment))873    return TokError("expected segment name after '.zerofill' directive");874 875  if (getLexer().isNot(AsmToken::Comma))876    return TokError("unexpected token in directive");877  Lex();878 879  StringRef Section;880  SMLoc SectionLoc = getLexer().getLoc();881  if (getParser().parseIdentifier(Section))882    return TokError("expected section name after comma in '.zerofill' "883                    "directive");884 885  // If this is the end of the line all that was wanted was to create the886  // the section but with no symbol.887  if (getLexer().is(AsmToken::EndOfStatement)) {888    // Create the zerofill section but no symbol889    getStreamer().emitZerofill(890        getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,891                                     SectionKind::getBSS()),892        /*Symbol=*/nullptr, /*Size=*/0, Align(1), SectionLoc);893    return false;894  }895 896  if (getLexer().isNot(AsmToken::Comma))897    return TokError("unexpected token in directive");898  Lex();899 900  SMLoc IDLoc = getLexer().getLoc();901  MCSymbol *Sym;902  if (getParser().parseSymbol(Sym))903    return TokError("expected identifier in directive");904 905  if (getLexer().isNot(AsmToken::Comma))906    return TokError("unexpected token in directive");907  Lex();908 909  int64_t Size;910  SMLoc SizeLoc = getLexer().getLoc();911  if (getParser().parseAbsoluteExpression(Size))912    return true;913 914  int64_t Pow2Alignment = 0;915  SMLoc Pow2AlignmentLoc;916  if (getLexer().is(AsmToken::Comma)) {917    Lex();918    Pow2AlignmentLoc = getLexer().getLoc();919    if (getParser().parseAbsoluteExpression(Pow2Alignment))920      return true;921  }922 923  if (getLexer().isNot(AsmToken::EndOfStatement))924    return TokError("unexpected token in '.zerofill' directive");925 926  Lex();927 928  if (Size < 0)929    return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "930                 "than zero");931 932  // NOTE: The alignment in the directive is a power of 2 value, the assembler933  // may internally end up wanting an alignment in bytes.934  // FIXME: Diagnose overflow.935  if (Pow2Alignment < 0)936    return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "937                 "can't be less than zero");938 939  if (!Sym->isUndefined())940    return Error(IDLoc, "invalid symbol redefinition");941 942  // Create the zerofill Symbol with Size and Pow2Alignment943  //944  // FIXME: Arch specific.945  getStreamer().emitZerofill(946      getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,947                                   SectionKind::getBSS()),948      Sym, Size, Align(1ULL << Pow2Alignment), SectionLoc);949 950  return false;951}952 953/// ParseDirectiveDataRegion954///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]955bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {956  if (getLexer().is(AsmToken::EndOfStatement)) {957    Lex();958    getStreamer().emitDataRegion(MCDR_DataRegion);959    return false;960  }961  StringRef RegionType;962  SMLoc Loc = getParser().getTok().getLoc();963  if (getParser().parseIdentifier(RegionType))964    return TokError("expected region type after '.data_region' directive");965  int Kind = StringSwitch<int>(RegionType)966    .Case("jt8", MCDR_DataRegionJT8)967    .Case("jt16", MCDR_DataRegionJT16)968    .Case("jt32", MCDR_DataRegionJT32)969    .Default(-1);970  if (Kind == -1)971    return Error(Loc, "unknown region type in '.data_region' directive");972  Lex();973 974  getStreamer().emitDataRegion((MCDataRegionType)Kind);975  return false;976}977 978/// ParseDirectiveDataRegionEnd979///  ::= .end_data_region980bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {981  if (getLexer().isNot(AsmToken::EndOfStatement))982    return TokError("unexpected token in '.end_data_region' directive");983 984  Lex();985  getStreamer().emitDataRegion(MCDR_DataRegionEnd);986  return false;987}988 989static bool isSDKVersionToken(const AsmToken &Tok) {990  return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";991}992 993/// parseMajorMinorVersionComponent ::= major, minor994bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,995                                                      unsigned *Minor,996                                                      const char *VersionName) {997  // Get the major version number.998  if (getLexer().isNot(AsmToken::Integer))999    return TokError(Twine("invalid ") + VersionName +1000                    " major version number, integer expected");1001  int64_t MajorVal = getLexer().getTok().getIntVal();1002  if (MajorVal > 65535 || MajorVal <= 0)1003    return TokError(Twine("invalid ") + VersionName + " major version number");1004  *Major = (unsigned)MajorVal;1005  Lex();1006  if (getLexer().isNot(AsmToken::Comma))1007    return TokError(Twine(VersionName) +1008                    " minor version number required, comma expected");1009  Lex();1010  // Get the minor version number.1011  if (getLexer().isNot(AsmToken::Integer))1012    return TokError(Twine("invalid ") + VersionName +1013                    " minor version number, integer expected");1014  int64_t MinorVal = getLexer().getTok().getIntVal();1015  if (MinorVal > 255 || MinorVal < 0)1016    return TokError(Twine("invalid ") + VersionName + " minor version number");1017  *Minor = MinorVal;1018  Lex();1019  return false;1020}1021 1022/// parseOptionalTrailingVersionComponent ::= , version_number1023bool DarwinAsmParser::parseOptionalTrailingVersionComponent(1024    unsigned *Component, const char *ComponentName) {1025  assert(getLexer().is(AsmToken::Comma) && "comma expected");1026  Lex();1027  if (getLexer().isNot(AsmToken::Integer))1028    return TokError(Twine("invalid ") + ComponentName +1029                    " version number, integer expected");1030  int64_t Val = getLexer().getTok().getIntVal();1031  if (Val > 255 || Val < 0)1032    return TokError(Twine("invalid ") + ComponentName + " version number");1033  *Component = Val;1034  Lex();1035  return false;1036}1037 1038/// parseVersion ::= parseMajorMinorVersionComponent1039///                      parseOptionalTrailingVersionComponent1040bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,1041                                   unsigned *Update) {1042  if (parseMajorMinorVersionComponent(Major, Minor, "OS"))1043    return true;1044 1045  // Get the update level, if specified1046  *Update = 0;1047  if (getLexer().is(AsmToken::EndOfStatement) ||1048      isSDKVersionToken(getLexer().getTok()))1049    return false;1050  if (getLexer().isNot(AsmToken::Comma))1051    return TokError("invalid OS update specifier, comma expected");1052  if (parseOptionalTrailingVersionComponent(Update, "OS update"))1053    return true;1054  return false;1055}1056 1057bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {1058  assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");1059  Lex();1060  unsigned Major, Minor;1061  if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))1062    return true;1063  SDKVersion = VersionTuple(Major, Minor);1064 1065  // Get the subminor version, if specified.1066  if (getLexer().is(AsmToken::Comma)) {1067    unsigned Subminor;1068    if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))1069      return true;1070    SDKVersion = VersionTuple(Major, Minor, Subminor);1071  }1072  return false;1073}1074 1075void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,1076                                   SMLoc Loc, Triple::OSType ExpectedOS) {1077  const Triple &Target = getContext().getTargetTriple();1078  if (Target.getOS() != ExpectedOS)1079    Warning(Loc, Twine(Directive) +1080            (Arg.empty() ? Twine() : Twine(' ') + Arg) +1081            " used while targeting " + Target.getOSName());1082 1083  if (LastVersionDirective.isValid()) {1084    Warning(Loc, "overriding previous version directive");1085    Note(LastVersionDirective, "previous definition is here");1086  }1087  LastVersionDirective = Loc;1088}1089 1090static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {1091  switch (Type) {1092  case MCVM_WatchOSVersionMin: return Triple::WatchOS;1093  case MCVM_TvOSVersionMin:    return Triple::TvOS;1094  case MCVM_IOSVersionMin:     return Triple::IOS;1095  case MCVM_OSXVersionMin:     return Triple::MacOSX;1096  }1097  llvm_unreachable("Invalid mc version min type");1098}1099 1100/// parseVersionMin1101///   ::= .ios_version_min parseVersion parseSDKVersion1102///   |   .macosx_version_min parseVersion parseSDKVersion1103///   |   .tvos_version_min parseVersion parseSDKVersion1104///   |   .watchos_version_min parseVersion parseSDKVersion1105bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,1106                                      MCVersionMinType Type) {1107  unsigned Major;1108  unsigned Minor;1109  unsigned Update;1110  if (parseVersion(&Major, &Minor, &Update))1111    return true;1112 1113  VersionTuple SDKVersion;1114  if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))1115    return true;1116 1117  if (parseEOL())1118    return addErrorSuffix(Twine(" in '") + Directive + "' directive");1119 1120  Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);1121  checkVersion(Directive, StringRef(), Loc, ExpectedOS);1122  getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion);1123  return false;1124}1125 1126static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {1127  switch (Type) {1128  case MachO::PLATFORM_UNKNOWN: /* silence warning */1129    break;1130  case MachO::PLATFORM_MACOS:   return Triple::MacOSX;1131  case MachO::PLATFORM_IOS:     return Triple::IOS;1132  case MachO::PLATFORM_TVOS:    return Triple::TvOS;1133  case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;1134  case MachO::PLATFORM_XROS:    return Triple::XROS;1135  case MachO::PLATFORM_BRIDGEOS:         /* silence warning */ break;1136  case MachO::PLATFORM_DRIVERKIT:1137    return Triple::DriverKit;1138  case MachO::PLATFORM_MACCATALYST: return Triple::IOS;1139  case MachO::PLATFORM_IOSSIMULATOR:     /* silence warning */ break;1140  case MachO::PLATFORM_TVOSSIMULATOR:    /* silence warning */ break;1141  case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;1142  case MachO::PLATFORM_XROS_SIMULATOR:   /* silence warning */ break;1143  }1144  llvm_unreachable("Invalid mach-o platform type");1145}1146 1147/// parseBuildVersion1148///   ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion1149bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {1150  StringRef PlatformName;1151  SMLoc PlatformLoc = getTok().getLoc();1152  if (getParser().parseIdentifier(PlatformName))1153    return TokError("platform name expected");1154 1155  unsigned Platform = StringSwitch<unsigned>(PlatformName)1156#define PLATFORM(platform, id, name, build_name, target, tapi_target,          \1157                 marketing)                                                    \1158  .Case(#build_name, MachO::PLATFORM_##platform)1159#include "llvm/BinaryFormat/MachO.def"1160                          .Default(MachO::PLATFORM_UNKNOWN);1161 1162  if (Platform == MachO::PLATFORM_UNKNOWN)1163    return Error(PlatformLoc, "unknown platform name");1164 1165  if (getLexer().isNot(AsmToken::Comma))1166    return TokError("version number required, comma expected");1167  Lex();1168 1169  unsigned Major;1170  unsigned Minor;1171  unsigned Update;1172  if (parseVersion(&Major, &Minor, &Update))1173    return true;1174 1175  VersionTuple SDKVersion;1176  if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))1177    return true;1178 1179  if (parseEOL())1180    return addErrorSuffix(" in '.build_version' directive");1181 1182  Triple::OSType ExpectedOS1183    = getOSTypeFromPlatform((MachO::PlatformType)Platform);1184  checkVersion(Directive, PlatformName, Loc, ExpectedOS);1185  getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);1186  return false;1187}1188 1189/// parseDirectiveCGProfile1190///   ::= .cg_profile from, to, count1191bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {1192  return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);1193}1194 1195MCAsmParserExtension *llvm::createDarwinAsmParser() {1196  return new DarwinAsmParser;1197}1198