xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCParser/DarwinAsmParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
100b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
110b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
120b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
130b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParserExtension.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
220b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h"
23fe6060f1SDimitry Andric #include "llvm/Support/Error.h"
240b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
250b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
260b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
270b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
280b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
2906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
300b57cec5SDimitry Andric #include <cstddef>
310b57cec5SDimitry Andric #include <cstdint>
320b57cec5SDimitry Andric #include <string>
330b57cec5SDimitry Andric #include <system_error>
340b57cec5SDimitry Andric #include <utility>
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric namespace {
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric /// Implementation of directive handling which is shared across all
410b57cec5SDimitry Andric /// Darwin targets.
420b57cec5SDimitry Andric class DarwinAsmParser : public MCAsmParserExtension {
430b57cec5SDimitry Andric   template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
440b57cec5SDimitry Andric   void addDirectiveHandler(StringRef Directive) {
450b57cec5SDimitry Andric     MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
460b57cec5SDimitry Andric         this, HandleDirective<DarwinAsmParser, HandlerMethod>);
470b57cec5SDimitry Andric     getParser().addDirectiveHandler(Directive, Handler);
480b57cec5SDimitry Andric   }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   bool parseSectionSwitch(StringRef Segment, StringRef Section,
510b57cec5SDimitry Andric                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
520b57cec5SDimitry Andric                           unsigned StubSize = 0);
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   SMLoc LastVersionDirective;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric public:
570b57cec5SDimitry Andric   DarwinAsmParser() = default;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   void Initialize(MCAsmParser &Parser) override {
600b57cec5SDimitry Andric     // Call the base implementation.
610b57cec5SDimitry Andric     this->MCAsmParserExtension::Initialize(Parser);
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
640b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
650b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
660b57cec5SDimitry Andric       ".indirect_symbol");
670b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
680b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
690b57cec5SDimitry Andric       ".subsections_via_symbols");
700b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
710b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
720b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
730b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
740b57cec5SDimitry Andric       ".pushsection");
750b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
760b57cec5SDimitry Andric       ".popsection");
770b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
780b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
790b57cec5SDimitry Andric       ".secure_log_unique");
800b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
810b57cec5SDimitry Andric       ".secure_log_reset");
820b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
830b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
860b57cec5SDimitry Andric       ".data_region");
870b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
880b57cec5SDimitry Andric       ".end_data_region");
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric     // Special section directives.
910b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
920b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
930b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
940b57cec5SDimitry Andric       ".const_data");
950b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
960b57cec5SDimitry Andric       ".constructor");
970b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
980b57cec5SDimitry Andric       ".cstring");
990b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
1000b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
1010b57cec5SDimitry Andric       ".destructor");
1020b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
1030b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
1040b57cec5SDimitry Andric       ".fvmlib_init0");
1050b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
1060b57cec5SDimitry Andric       ".fvmlib_init1");
1070b57cec5SDimitry Andric     addDirectiveHandler<
1080b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
1090b57cec5SDimitry Andric         ".lazy_symbol_pointer");
1100b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
1110b57cec5SDimitry Andric       ".linker_option");
1120b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
1130b57cec5SDimitry Andric       ".literal16");
1140b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
1150b57cec5SDimitry Andric       ".literal4");
1160b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
1170b57cec5SDimitry Andric       ".literal8");
1180b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
1190b57cec5SDimitry Andric       ".mod_init_func");
1200b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
1210b57cec5SDimitry Andric       ".mod_term_func");
1220b57cec5SDimitry Andric     addDirectiveHandler<
1230b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
1240b57cec5SDimitry Andric         ".non_lazy_symbol_pointer");
1250b57cec5SDimitry Andric     addDirectiveHandler<
1260b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
1270b57cec5SDimitry Andric         ".thread_local_variable_pointer");
1280b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
1290b57cec5SDimitry Andric       ".objc_cat_cls_meth");
1300b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
1310b57cec5SDimitry Andric       ".objc_cat_inst_meth");
1320b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
1330b57cec5SDimitry Andric       ".objc_category");
1340b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
1350b57cec5SDimitry Andric       ".objc_class");
1360b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
1370b57cec5SDimitry Andric       ".objc_class_names");
1380b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
1390b57cec5SDimitry Andric       ".objc_class_vars");
1400b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
1410b57cec5SDimitry Andric       ".objc_cls_meth");
1420b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
1430b57cec5SDimitry Andric       ".objc_cls_refs");
1440b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
1450b57cec5SDimitry Andric       ".objc_inst_meth");
1460b57cec5SDimitry Andric     addDirectiveHandler<
1470b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
1480b57cec5SDimitry Andric         ".objc_instance_vars");
1490b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
1500b57cec5SDimitry Andric       ".objc_message_refs");
1510b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
1520b57cec5SDimitry Andric       ".objc_meta_class");
1530b57cec5SDimitry Andric     addDirectiveHandler<
1540b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
1550b57cec5SDimitry Andric         ".objc_meth_var_names");
1560b57cec5SDimitry Andric     addDirectiveHandler<
1570b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
1580b57cec5SDimitry Andric         ".objc_meth_var_types");
1590b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
1600b57cec5SDimitry Andric       ".objc_module_info");
1610b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
1620b57cec5SDimitry Andric       ".objc_protocol");
1630b57cec5SDimitry Andric     addDirectiveHandler<
1640b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
1650b57cec5SDimitry Andric         ".objc_selector_strs");
1660b57cec5SDimitry Andric     addDirectiveHandler<
1670b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
1680b57cec5SDimitry Andric         ".objc_string_object");
1690b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
1700b57cec5SDimitry Andric       ".objc_symbols");
1710b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
1720b57cec5SDimitry Andric       ".picsymbol_stub");
1730b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
1740b57cec5SDimitry Andric       ".static_const");
1750b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
1760b57cec5SDimitry Andric       ".static_data");
1770b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
1780b57cec5SDimitry Andric       ".symbol_stub");
1790b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
1800b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
1810b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
1820b57cec5SDimitry Andric       ".thread_init_func");
1830b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
1860b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
1870b57cec5SDimitry Andric       ".watchos_version_min");
1880b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
1890b57cec5SDimitry Andric       ".tvos_version_min");
1900b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
1910b57cec5SDimitry Andric       ".ios_version_min");
1920b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
1930b57cec5SDimitry Andric       ".macosx_version_min");
1940b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
19504eeddc0SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>(
19604eeddc0SDimitry Andric         ".cg_profile");
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric     LastVersionDirective = SMLoc();
1990b57cec5SDimitry Andric   }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   bool parseDirectiveAltEntry(StringRef, SMLoc);
2020b57cec5SDimitry Andric   bool parseDirectiveDesc(StringRef, SMLoc);
2030b57cec5SDimitry Andric   bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
2040b57cec5SDimitry Andric   bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
2050b57cec5SDimitry Andric   bool parseDirectiveLsym(StringRef, SMLoc);
2060b57cec5SDimitry Andric   bool parseDirectiveLinkerOption(StringRef, SMLoc);
2070b57cec5SDimitry Andric   bool parseDirectiveSection(StringRef, SMLoc);
2080b57cec5SDimitry Andric   bool parseDirectivePushSection(StringRef, SMLoc);
2090b57cec5SDimitry Andric   bool parseDirectivePopSection(StringRef, SMLoc);
2100b57cec5SDimitry Andric   bool parseDirectivePrevious(StringRef, SMLoc);
2110b57cec5SDimitry Andric   bool parseDirectiveSecureLogReset(StringRef, SMLoc);
2120b57cec5SDimitry Andric   bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
2130b57cec5SDimitry Andric   bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
2140b57cec5SDimitry Andric   bool parseDirectiveTBSS(StringRef, SMLoc);
2150b57cec5SDimitry Andric   bool parseDirectiveZerofill(StringRef, SMLoc);
2160b57cec5SDimitry Andric   bool parseDirectiveDataRegion(StringRef, SMLoc);
2170b57cec5SDimitry Andric   bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // Named Section Directive
2200b57cec5SDimitry Andric   bool parseSectionDirectiveBss(StringRef, SMLoc) {
2210b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__bss");
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   bool parseSectionDirectiveConst(StringRef, SMLoc) {
2250b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__const");
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
2290b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__static_const");
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   bool parseSectionDirectiveCString(StringRef, SMLoc) {
2330b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__cstring",
2340b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
2350b57cec5SDimitry Andric   }
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
2380b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__literal4",
2390b57cec5SDimitry Andric                               MachO::S_4BYTE_LITERALS, 4);
2400b57cec5SDimitry Andric   }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
2430b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__literal8",
2440b57cec5SDimitry Andric                               MachO::S_8BYTE_LITERALS, 8);
2450b57cec5SDimitry Andric   }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
2480b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__literal16",
2490b57cec5SDimitry Andric                               MachO::S_16BYTE_LITERALS, 16);
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
2530b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__constructor");
2540b57cec5SDimitry Andric   }
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
2570b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__destructor");
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
2610b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__fvmlib_init0");
2620b57cec5SDimitry Andric   }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
2650b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__fvmlib_init1");
2660b57cec5SDimitry Andric   }
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
2690b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__symbol_stub",
2700b57cec5SDimitry Andric                               MachO::S_SYMBOL_STUBS |
2710b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS,
2720b57cec5SDimitry Andric                               // FIXME: Different on PPC and ARM.
2730b57cec5SDimitry Andric                               0, 16);
2740b57cec5SDimitry Andric   }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric   bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
2770b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__picsymbol_stub",
2780b57cec5SDimitry Andric                               MachO::S_SYMBOL_STUBS |
2790b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   bool parseSectionDirectiveData(StringRef, SMLoc) {
2830b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__data");
2840b57cec5SDimitry Andric   }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
2870b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__static_data");
2880b57cec5SDimitry Andric   }
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
2910b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
2920b57cec5SDimitry Andric                               MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
2930b57cec5SDimitry Andric   }
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
2960b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__la_symbol_ptr",
2970b57cec5SDimitry Andric                               MachO::S_LAZY_SYMBOL_POINTERS, 4);
2980b57cec5SDimitry Andric   }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
3010b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_ptr",
3020b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
3030b57cec5SDimitry Andric   }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   bool parseSectionDirectiveDyld(StringRef, SMLoc) {
3060b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__dyld");
3070b57cec5SDimitry Andric   }
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
3100b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__mod_init_func",
3110b57cec5SDimitry Andric                               MachO::S_MOD_INIT_FUNC_POINTERS, 4);
3120b57cec5SDimitry Andric   }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
3150b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__mod_term_func",
3160b57cec5SDimitry Andric                               MachO::S_MOD_TERM_FUNC_POINTERS, 4);
3170b57cec5SDimitry Andric   }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   bool parseSectionDirectiveConstData(StringRef, SMLoc) {
3200b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__const");
3210b57cec5SDimitry Andric   }
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
3240b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__class",
3250b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3260b57cec5SDimitry Andric   }
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
3290b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__meta_class",
3300b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
3340b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cat_cls_meth",
3350b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3360b57cec5SDimitry Andric   }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
3390b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cat_inst_meth",
3400b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3410b57cec5SDimitry Andric   }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
3440b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__protocol",
3450b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3460b57cec5SDimitry Andric   }
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
3490b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__string_object",
3500b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3510b57cec5SDimitry Andric   }
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
3540b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cls_meth",
3550b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
3590b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__inst_meth",
3600b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3610b57cec5SDimitry Andric   }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
3640b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cls_refs",
3650b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP |
3660b57cec5SDimitry Andric                               MachO::S_LITERAL_POINTERS, 4);
3670b57cec5SDimitry Andric   }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
3700b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__message_refs",
3710b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP |
3720b57cec5SDimitry Andric                               MachO::S_LITERAL_POINTERS, 4);
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
3760b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__symbols",
3770b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3780b57cec5SDimitry Andric   }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
3810b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__category",
3820b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3830b57cec5SDimitry Andric   }
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
3860b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__class_vars",
3870b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
3910b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__instance_vars",
3920b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3930b57cec5SDimitry Andric   }
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric   bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
3960b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__module_info",
3970b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3980b57cec5SDimitry Andric   }
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
4010b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
4020b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4030b57cec5SDimitry Andric   }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
4060b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
4070b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
4110b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
4120b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
4160b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__selector_strs",
4170b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   bool parseSectionDirectiveTData(StringRef, SMLoc) {
4210b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_data",
4220b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_REGULAR);
4230b57cec5SDimitry Andric   }
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   bool parseSectionDirectiveText(StringRef, SMLoc) {
4260b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__text",
4270b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS);
4280b57cec5SDimitry Andric   }
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   bool parseSectionDirectiveTLV(StringRef, SMLoc) {
4310b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_vars",
4320b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_VARIABLES);
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   bool parseSectionDirectiveIdent(StringRef, SMLoc) {
4360b57cec5SDimitry Andric     // Darwin silently ignores the .ident directive.
4370b57cec5SDimitry Andric     getParser().eatToEndOfStatement();
4380b57cec5SDimitry Andric     return false;
4390b57cec5SDimitry Andric   }
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric   bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
4420b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_init",
4430b57cec5SDimitry Andric                          MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
4440b57cec5SDimitry Andric   }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric   bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {
4470b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric   bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {
4500b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric   bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {
4530b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);
4540b57cec5SDimitry Andric   }
4550b57cec5SDimitry Andric   bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {
4560b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);
4570b57cec5SDimitry Andric   }
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   bool parseBuildVersion(StringRef Directive, SMLoc Loc);
4600b57cec5SDimitry Andric   bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
4610b57cec5SDimitry Andric   bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,
4620b57cec5SDimitry Andric                                        const char *VersionName);
4630b57cec5SDimitry Andric   bool parseOptionalTrailingVersionComponent(unsigned *Component,
4640b57cec5SDimitry Andric                                              const char *ComponentName);
4650b57cec5SDimitry Andric   bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
4660b57cec5SDimitry Andric   bool parseSDKVersion(VersionTuple &SDKVersion);
4670b57cec5SDimitry Andric   void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
4680b57cec5SDimitry Andric                     Triple::OSType ExpectedOS);
46904eeddc0SDimitry Andric   bool parseDirectiveCGProfile(StringRef Directive, SMLoc Loc);
4700b57cec5SDimitry Andric };
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric } // end anonymous namespace
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,
475bdd1243dSDimitry Andric                                          unsigned TAA, unsigned Alignment,
4760b57cec5SDimitry Andric                                          unsigned StubSize) {
4770b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
4780b57cec5SDimitry Andric     return TokError("unexpected token in section switching directive");
4790b57cec5SDimitry Andric   Lex();
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   // FIXME: Arch specific.
4820b57cec5SDimitry Andric   bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
48381ad6265SDimitry Andric   getStreamer().switchSection(getContext().getMachOSection(
4840b57cec5SDimitry Andric       Segment, Section, TAA, StubSize,
4850b57cec5SDimitry Andric       isText ? SectionKind::getText() : SectionKind::getData()));
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   // Set the implicit alignment, if any.
4880b57cec5SDimitry Andric   //
4890b57cec5SDimitry Andric   // FIXME: This isn't really what 'as' does; I think it just uses the implicit
4900b57cec5SDimitry Andric   // alignment on the section (e.g., if one manually inserts bytes into the
4910b57cec5SDimitry Andric   // section, then just issuing the section switch directive will not realign
4920b57cec5SDimitry Andric   // the section. However, this is arguably more reasonable behavior, and there
4930b57cec5SDimitry Andric   // is no good reason for someone to intentionally emit incorrectly sized
4940b57cec5SDimitry Andric   // values into the implicitly aligned sections.
495bdd1243dSDimitry Andric   if (Alignment)
496bdd1243dSDimitry Andric     getStreamer().emitValueToAlignment(Align(Alignment));
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   return false;
4990b57cec5SDimitry Andric }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric /// parseDirectiveAltEntry
5020b57cec5SDimitry Andric ///  ::= .alt_entry identifier
5030b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {
5040b57cec5SDimitry Andric   StringRef Name;
5050b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
5060b57cec5SDimitry Andric     return TokError("expected identifier in directive");
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   // Look up symbol.
5090b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric   if (Sym->isDefined())
5120b57cec5SDimitry Andric     return TokError(".alt_entry must preceed symbol definition");
5130b57cec5SDimitry Andric 
5145ffd83dbSDimitry Andric   if (!getStreamer().emitSymbolAttribute(Sym, MCSA_AltEntry))
5150b57cec5SDimitry Andric     return TokError("unable to emit symbol attribute");
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric   Lex();
5180b57cec5SDimitry Andric   return false;
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric /// parseDirectiveDesc
5220b57cec5SDimitry Andric ///  ::= .desc identifier , expression
5230b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
5240b57cec5SDimitry Andric   StringRef Name;
5250b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
5260b57cec5SDimitry Andric     return TokError("expected identifier in directive");
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
5290b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
5320b57cec5SDimitry Andric     return TokError("unexpected token in '.desc' directive");
5330b57cec5SDimitry Andric   Lex();
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   int64_t DescValue;
5360b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(DescValue))
5370b57cec5SDimitry Andric     return true;
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
5400b57cec5SDimitry Andric     return TokError("unexpected token in '.desc' directive");
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric   Lex();
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   // Set the n_desc field of this Symbol to this DescValue
5455ffd83dbSDimitry Andric   getStreamer().emitSymbolDesc(Sym, DescValue);
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   return false;
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric /// parseDirectiveIndirectSymbol
5510b57cec5SDimitry Andric ///  ::= .indirect_symbol identifier
5520b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
5530b57cec5SDimitry Andric   const MCSectionMachO *Current = static_cast<const MCSectionMachO *>(
5540b57cec5SDimitry Andric       getStreamer().getCurrentSectionOnly());
5550b57cec5SDimitry Andric   MachO::SectionType SectionType = Current->getType();
5560b57cec5SDimitry Andric   if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
5570b57cec5SDimitry Andric       SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
5580b57cec5SDimitry Andric       SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
5590b57cec5SDimitry Andric       SectionType != MachO::S_SYMBOL_STUBS)
5600b57cec5SDimitry Andric     return Error(Loc, "indirect symbol not in a symbol pointer or stub "
5610b57cec5SDimitry Andric                       "section");
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric   StringRef Name;
5640b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
5650b57cec5SDimitry Andric     return TokError("expected identifier in .indirect_symbol directive");
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   // Assembler local symbols don't make any sense here. Complain loudly.
5700b57cec5SDimitry Andric   if (Sym->isTemporary())
5710b57cec5SDimitry Andric     return TokError("non-local symbol required in directive");
5720b57cec5SDimitry Andric 
5735ffd83dbSDimitry Andric   if (!getStreamer().emitSymbolAttribute(Sym, MCSA_IndirectSymbol))
5740b57cec5SDimitry Andric     return TokError("unable to emit indirect symbol attribute for: " + Name);
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
5770b57cec5SDimitry Andric     return TokError("unexpected token in '.indirect_symbol' directive");
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   Lex();
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   return false;
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric /// parseDirectiveDumpOrLoad
5850b57cec5SDimitry Andric ///  ::= ( .dump | .load ) "filename"
5860b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
5870b57cec5SDimitry Andric                                                SMLoc IDLoc) {
5880b57cec5SDimitry Andric   bool IsDump = Directive == ".dump";
5890b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::String))
5900b57cec5SDimitry Andric     return TokError("expected string in '.dump' or '.load' directive");
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   Lex();
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
5950b57cec5SDimitry Andric     return TokError("unexpected token in '.dump' or '.load' directive");
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric   Lex();
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric   // FIXME: If/when .dump and .load are implemented they will be done in the
6000b57cec5SDimitry Andric   // the assembly parser and not have any need for an MCStreamer API.
6010b57cec5SDimitry Andric   if (IsDump)
6020b57cec5SDimitry Andric     return Warning(IDLoc, "ignoring directive .dump for now");
6030b57cec5SDimitry Andric   else
6040b57cec5SDimitry Andric     return Warning(IDLoc, "ignoring directive .load for now");
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric /// ParseDirectiveLinkerOption
6080b57cec5SDimitry Andric ///  ::= .linker_option "string" ( , "string" )*
6090b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
6100b57cec5SDimitry Andric   SmallVector<std::string, 4> Args;
6110b57cec5SDimitry Andric   while (true) {
6120b57cec5SDimitry Andric     if (getLexer().isNot(AsmToken::String))
6130b57cec5SDimitry Andric       return TokError("expected string in '" + Twine(IDVal) + "' directive");
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric     std::string Data;
6160b57cec5SDimitry Andric     if (getParser().parseEscapedString(Data))
6170b57cec5SDimitry Andric       return true;
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric     Args.push_back(Data);
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric     if (getLexer().is(AsmToken::EndOfStatement))
6220b57cec5SDimitry Andric       break;
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric     if (getLexer().isNot(AsmToken::Comma))
6250b57cec5SDimitry Andric       return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
6260b57cec5SDimitry Andric     Lex();
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric 
6295ffd83dbSDimitry Andric   getStreamer().emitLinkerOptions(Args);
6300b57cec5SDimitry Andric   return false;
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric /// parseDirectiveLsym
6340b57cec5SDimitry Andric ///  ::= .lsym identifier , expression
6350b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
6360b57cec5SDimitry Andric   StringRef Name;
6370b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
6380b57cec5SDimitry Andric     return TokError("expected identifier in directive");
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
6410b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
6440b57cec5SDimitry Andric     return TokError("unexpected token in '.lsym' directive");
6450b57cec5SDimitry Andric   Lex();
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric   const MCExpr *Value;
6480b57cec5SDimitry Andric   if (getParser().parseExpression(Value))
6490b57cec5SDimitry Andric     return true;
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
6520b57cec5SDimitry Andric     return TokError("unexpected token in '.lsym' directive");
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric   Lex();
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   // We don't currently support this directive.
6570b57cec5SDimitry Andric   //
6580b57cec5SDimitry Andric   // FIXME: Diagnostic location!
6590b57cec5SDimitry Andric   (void) Sym;
6600b57cec5SDimitry Andric   return TokError("directive '.lsym' is unsupported");
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric /// parseDirectiveSection:
6640b57cec5SDimitry Andric ///   ::= .section identifier (',' identifier)*
6650b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
6660b57cec5SDimitry Andric   SMLoc Loc = getLexer().getLoc();
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric   StringRef SectionName;
6690b57cec5SDimitry Andric   if (getParser().parseIdentifier(SectionName))
6700b57cec5SDimitry Andric     return Error(Loc, "expected identifier after '.section' directive");
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric   // Verify there is a following comma.
6730b57cec5SDimitry Andric   if (!getLexer().is(AsmToken::Comma))
6740b57cec5SDimitry Andric     return TokError("unexpected token in '.section' directive");
6750b57cec5SDimitry Andric 
6765ffd83dbSDimitry Andric   std::string SectionSpec = std::string(SectionName);
6770b57cec5SDimitry Andric   SectionSpec += ",";
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric   // Add all the tokens until the end of the line, ParseSectionSpecifier will
6800b57cec5SDimitry Andric   // handle this.
6810b57cec5SDimitry Andric   StringRef EOL = getLexer().LexUntilEndOfStatement();
6820b57cec5SDimitry Andric   SectionSpec.append(EOL.begin(), EOL.end());
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric   Lex();
6850b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
6860b57cec5SDimitry Andric     return TokError("unexpected token in '.section' directive");
6870b57cec5SDimitry Andric   Lex();
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   StringRef Segment, Section;
6900b57cec5SDimitry Andric   unsigned StubSize;
6910b57cec5SDimitry Andric   unsigned TAA;
6920b57cec5SDimitry Andric   bool TAAParsed;
693fe6060f1SDimitry Andric   if (class Error E = MCSectionMachO::ParseSectionSpecifier(
694fe6060f1SDimitry Andric           SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))
695fe6060f1SDimitry Andric     return Error(Loc, toString(std::move(E)));
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric   // Issue a warning if the target is not powerpc and Section is a *coal* section.
698fe6060f1SDimitry Andric   Triple TT = getParser().getContext().getTargetTriple();
6990b57cec5SDimitry Andric   Triple::ArchType ArchTy = TT.getArch();
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric   if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {
7020b57cec5SDimitry Andric     StringRef NonCoalSection = StringSwitch<StringRef>(Section)
7030b57cec5SDimitry Andric                                    .Case("__textcoal_nt", "__text")
7040b57cec5SDimitry Andric                                    .Case("__const_coal", "__const")
7050b57cec5SDimitry Andric                                    .Case("__datacoal_nt", "__data")
7060b57cec5SDimitry Andric                                    .Default(Section);
7070b57cec5SDimitry Andric 
708*0fca6ea1SDimitry Andric     if (Section != NonCoalSection) {
7090b57cec5SDimitry Andric       StringRef SectionVal(Loc.getPointer());
7100b57cec5SDimitry Andric       size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B);
7110b57cec5SDimitry Andric       SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B);
7120b57cec5SDimitry Andric       SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E);
7130b57cec5SDimitry Andric       getParser().Warning(Loc, "section \"" + Section + "\" is deprecated",
7140b57cec5SDimitry Andric                           SMRange(BLoc, ELoc));
7150b57cec5SDimitry Andric       getParser().Note(Loc, "change section name to \"" + NonCoalSection +
7160b57cec5SDimitry Andric                        "\"", SMRange(BLoc, ELoc));
7170b57cec5SDimitry Andric     }
7180b57cec5SDimitry Andric   }
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric   // FIXME: Arch specific.
7210b57cec5SDimitry Andric   bool isText = Segment == "__TEXT";  // FIXME: Hack.
72281ad6265SDimitry Andric   getStreamer().switchSection(getContext().getMachOSection(
7230b57cec5SDimitry Andric       Segment, Section, TAA, StubSize,
7240b57cec5SDimitry Andric       isText ? SectionKind::getText() : SectionKind::getData()));
7250b57cec5SDimitry Andric   return false;
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric /// ParseDirectivePushSection:
7290b57cec5SDimitry Andric ///   ::= .pushsection identifier (',' identifier)*
7300b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
73181ad6265SDimitry Andric   getStreamer().pushSection();
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric   if (parseDirectiveSection(S, Loc)) {
73481ad6265SDimitry Andric     getStreamer().popSection();
7350b57cec5SDimitry Andric     return true;
7360b57cec5SDimitry Andric   }
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric   return false;
7390b57cec5SDimitry Andric }
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric /// ParseDirectivePopSection:
7420b57cec5SDimitry Andric ///   ::= .popsection
7430b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
74481ad6265SDimitry Andric   if (!getStreamer().popSection())
7450b57cec5SDimitry Andric     return TokError(".popsection without corresponding .pushsection");
7460b57cec5SDimitry Andric   return false;
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric /// ParseDirectivePrevious:
7500b57cec5SDimitry Andric ///   ::= .previous
7510b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
7520b57cec5SDimitry Andric   MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
7530b57cec5SDimitry Andric   if (!PreviousSection.first)
7540b57cec5SDimitry Andric     return TokError(".previous without corresponding .section");
75581ad6265SDimitry Andric   getStreamer().switchSection(PreviousSection.first, PreviousSection.second);
7560b57cec5SDimitry Andric   return false;
7570b57cec5SDimitry Andric }
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric /// ParseDirectiveSecureLogUnique
7600b57cec5SDimitry Andric ///  ::= .secure_log_unique ... message ...
7610b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
7620b57cec5SDimitry Andric   StringRef LogMessage = getParser().parseStringToEndOfStatement();
7630b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
7640b57cec5SDimitry Andric     return TokError("unexpected token in '.secure_log_unique' directive");
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric   if (getContext().getSecureLogUsed())
7670b57cec5SDimitry Andric     return Error(IDLoc, ".secure_log_unique specified multiple times");
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric   // Get the secure log path.
770bdd1243dSDimitry Andric   StringRef SecureLogFile = getContext().getSecureLogFile();
771bdd1243dSDimitry Andric   if (SecureLogFile.empty())
7720b57cec5SDimitry Andric     return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
7730b57cec5SDimitry Andric                  "environment variable unset.");
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   // Open the secure log file if we haven't already.
7760b57cec5SDimitry Andric   raw_fd_ostream *OS = getContext().getSecureLog();
7770b57cec5SDimitry Andric   if (!OS) {
7780b57cec5SDimitry Andric     std::error_code EC;
779bdd1243dSDimitry Andric     auto NewOS = std::make_unique<raw_fd_ostream>(
780bdd1243dSDimitry Andric         SecureLogFile, EC, sys::fs::OF_Append | sys::fs::OF_TextWithCRLF);
7810b57cec5SDimitry Andric     if (EC)
7820b57cec5SDimitry Andric        return Error(IDLoc, Twine("can't open secure log file: ") +
7830b57cec5SDimitry Andric                                SecureLogFile + " (" + EC.message() + ")");
7840b57cec5SDimitry Andric     OS = NewOS.get();
7850b57cec5SDimitry Andric     getContext().setSecureLog(std::move(NewOS));
7860b57cec5SDimitry Andric   }
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric   // Write the message.
7890b57cec5SDimitry Andric   unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
7900b57cec5SDimitry Andric   *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
7910b57cec5SDimitry Andric       << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
7920b57cec5SDimitry Andric       << LogMessage + "\n";
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   getContext().setSecureLogUsed(true);
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric   return false;
7970b57cec5SDimitry Andric }
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric /// ParseDirectiveSecureLogReset
8000b57cec5SDimitry Andric ///  ::= .secure_log_reset
8010b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
8020b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
8030b57cec5SDimitry Andric     return TokError("unexpected token in '.secure_log_reset' directive");
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric   Lex();
8060b57cec5SDimitry Andric 
8070b57cec5SDimitry Andric   getContext().setSecureLogUsed(false);
8080b57cec5SDimitry Andric 
8090b57cec5SDimitry Andric   return false;
8100b57cec5SDimitry Andric }
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric /// parseDirectiveSubsectionsViaSymbols
8130b57cec5SDimitry Andric ///  ::= .subsections_via_symbols
8140b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
8150b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
8160b57cec5SDimitry Andric     return TokError("unexpected token in '.subsections_via_symbols' directive");
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   Lex();
8190b57cec5SDimitry Andric 
8205ffd83dbSDimitry Andric   getStreamer().emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric   return false;
8230b57cec5SDimitry Andric }
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric /// ParseDirectiveTBSS
8260b57cec5SDimitry Andric ///  ::= .tbss identifier, size, align
8270b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
8280b57cec5SDimitry Andric   SMLoc IDLoc = getLexer().getLoc();
8290b57cec5SDimitry Andric   StringRef Name;
8300b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
8310b57cec5SDimitry Andric     return TokError("expected identifier in directive");
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
8340b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
8370b57cec5SDimitry Andric     return TokError("unexpected token in directive");
8380b57cec5SDimitry Andric   Lex();
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric   int64_t Size;
8410b57cec5SDimitry Andric   SMLoc SizeLoc = getLexer().getLoc();
8420b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(Size))
8430b57cec5SDimitry Andric     return true;
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric   int64_t Pow2Alignment = 0;
8460b57cec5SDimitry Andric   SMLoc Pow2AlignmentLoc;
8470b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
8480b57cec5SDimitry Andric     Lex();
8490b57cec5SDimitry Andric     Pow2AlignmentLoc = getLexer().getLoc();
8500b57cec5SDimitry Andric     if (getParser().parseAbsoluteExpression(Pow2Alignment))
8510b57cec5SDimitry Andric       return true;
8520b57cec5SDimitry Andric   }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
8550b57cec5SDimitry Andric     return TokError("unexpected token in '.tbss' directive");
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric   Lex();
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric   if (Size < 0)
8600b57cec5SDimitry Andric     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
8610b57cec5SDimitry Andric                  "zero");
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric   // FIXME: Diagnose overflow.
8640b57cec5SDimitry Andric   if (Pow2Alignment < 0)
8650b57cec5SDimitry Andric     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
8660b57cec5SDimitry Andric                  "than zero");
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric   if (!Sym->isUndefined())
8690b57cec5SDimitry Andric     return Error(IDLoc, "invalid symbol redefinition");
8700b57cec5SDimitry Andric 
8715ffd83dbSDimitry Andric   getStreamer().emitTBSSSymbol(
8725ffd83dbSDimitry Andric       getContext().getMachOSection("__DATA", "__thread_bss",
8735ffd83dbSDimitry Andric                                    MachO::S_THREAD_LOCAL_ZEROFILL, 0,
8745ffd83dbSDimitry Andric                                    SectionKind::getThreadBSS()),
875bdd1243dSDimitry Andric       Sym, Size, Align(1ULL << Pow2Alignment));
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric   return false;
8780b57cec5SDimitry Andric }
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric /// ParseDirectiveZerofill
8810b57cec5SDimitry Andric ///  ::= .zerofill segname , sectname [, identifier , size_expression [
8820b57cec5SDimitry Andric ///      , align_expression ]]
8830b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
8840b57cec5SDimitry Andric   StringRef Segment;
8850b57cec5SDimitry Andric   if (getParser().parseIdentifier(Segment))
8860b57cec5SDimitry Andric     return TokError("expected segment name after '.zerofill' directive");
8870b57cec5SDimitry Andric 
8880b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
8890b57cec5SDimitry Andric     return TokError("unexpected token in directive");
8900b57cec5SDimitry Andric   Lex();
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   StringRef Section;
8930b57cec5SDimitry Andric   SMLoc SectionLoc = getLexer().getLoc();
8940b57cec5SDimitry Andric   if (getParser().parseIdentifier(Section))
8950b57cec5SDimitry Andric     return TokError("expected section name after comma in '.zerofill' "
8960b57cec5SDimitry Andric                     "directive");
8970b57cec5SDimitry Andric 
8980b57cec5SDimitry Andric   // If this is the end of the line all that was wanted was to create the
8990b57cec5SDimitry Andric   // the section but with no symbol.
9000b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement)) {
9010b57cec5SDimitry Andric     // Create the zerofill section but no symbol
9025ffd83dbSDimitry Andric     getStreamer().emitZerofill(
9030b57cec5SDimitry Andric         getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
9040b57cec5SDimitry Andric                                      SectionKind::getBSS()),
905bdd1243dSDimitry Andric         /*Symbol=*/nullptr, /*Size=*/0, Align(1), SectionLoc);
9060b57cec5SDimitry Andric     return false;
9070b57cec5SDimitry Andric   }
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
9100b57cec5SDimitry Andric     return TokError("unexpected token in directive");
9110b57cec5SDimitry Andric   Lex();
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric   SMLoc IDLoc = getLexer().getLoc();
9140b57cec5SDimitry Andric   StringRef IDStr;
9150b57cec5SDimitry Andric   if (getParser().parseIdentifier(IDStr))
9160b57cec5SDimitry Andric     return TokError("expected identifier in directive");
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric   // handle the identifier as the key symbol.
9190b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr);
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
9220b57cec5SDimitry Andric     return TokError("unexpected token in directive");
9230b57cec5SDimitry Andric   Lex();
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric   int64_t Size;
9260b57cec5SDimitry Andric   SMLoc SizeLoc = getLexer().getLoc();
9270b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(Size))
9280b57cec5SDimitry Andric     return true;
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric   int64_t Pow2Alignment = 0;
9310b57cec5SDimitry Andric   SMLoc Pow2AlignmentLoc;
9320b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
9330b57cec5SDimitry Andric     Lex();
9340b57cec5SDimitry Andric     Pow2AlignmentLoc = getLexer().getLoc();
9350b57cec5SDimitry Andric     if (getParser().parseAbsoluteExpression(Pow2Alignment))
9360b57cec5SDimitry Andric       return true;
9370b57cec5SDimitry Andric   }
9380b57cec5SDimitry Andric 
9390b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
9400b57cec5SDimitry Andric     return TokError("unexpected token in '.zerofill' directive");
9410b57cec5SDimitry Andric 
9420b57cec5SDimitry Andric   Lex();
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric   if (Size < 0)
9450b57cec5SDimitry Andric     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
9460b57cec5SDimitry Andric                  "than zero");
9470b57cec5SDimitry Andric 
9480b57cec5SDimitry Andric   // NOTE: The alignment in the directive is a power of 2 value, the assembler
9490b57cec5SDimitry Andric   // may internally end up wanting an alignment in bytes.
9500b57cec5SDimitry Andric   // FIXME: Diagnose overflow.
9510b57cec5SDimitry Andric   if (Pow2Alignment < 0)
9520b57cec5SDimitry Andric     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
9530b57cec5SDimitry Andric                  "can't be less than zero");
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric   if (!Sym->isUndefined())
9560b57cec5SDimitry Andric     return Error(IDLoc, "invalid symbol redefinition");
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   // Create the zerofill Symbol with Size and Pow2Alignment
9590b57cec5SDimitry Andric   //
9600b57cec5SDimitry Andric   // FIXME: Arch specific.
961bdd1243dSDimitry Andric   getStreamer().emitZerofill(
962bdd1243dSDimitry Andric       getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
963bdd1243dSDimitry Andric                                    SectionKind::getBSS()),
964bdd1243dSDimitry Andric       Sym, Size, Align(1ULL << Pow2Alignment), SectionLoc);
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric   return false;
9670b57cec5SDimitry Andric }
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric /// ParseDirectiveDataRegion
9700b57cec5SDimitry Andric ///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
9710b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
9720b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement)) {
9730b57cec5SDimitry Andric     Lex();
9745ffd83dbSDimitry Andric     getStreamer().emitDataRegion(MCDR_DataRegion);
9750b57cec5SDimitry Andric     return false;
9760b57cec5SDimitry Andric   }
9770b57cec5SDimitry Andric   StringRef RegionType;
9780b57cec5SDimitry Andric   SMLoc Loc = getParser().getTok().getLoc();
9790b57cec5SDimitry Andric   if (getParser().parseIdentifier(RegionType))
9800b57cec5SDimitry Andric     return TokError("expected region type after '.data_region' directive");
9810b57cec5SDimitry Andric   int Kind = StringSwitch<int>(RegionType)
9820b57cec5SDimitry Andric     .Case("jt8", MCDR_DataRegionJT8)
9830b57cec5SDimitry Andric     .Case("jt16", MCDR_DataRegionJT16)
9840b57cec5SDimitry Andric     .Case("jt32", MCDR_DataRegionJT32)
9850b57cec5SDimitry Andric     .Default(-1);
9860b57cec5SDimitry Andric   if (Kind == -1)
9870b57cec5SDimitry Andric     return Error(Loc, "unknown region type in '.data_region' directive");
9880b57cec5SDimitry Andric   Lex();
9890b57cec5SDimitry Andric 
9905ffd83dbSDimitry Andric   getStreamer().emitDataRegion((MCDataRegionType)Kind);
9910b57cec5SDimitry Andric   return false;
9920b57cec5SDimitry Andric }
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric /// ParseDirectiveDataRegionEnd
9950b57cec5SDimitry Andric ///  ::= .end_data_region
9960b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
9970b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
9980b57cec5SDimitry Andric     return TokError("unexpected token in '.end_data_region' directive");
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric   Lex();
10015ffd83dbSDimitry Andric   getStreamer().emitDataRegion(MCDR_DataRegionEnd);
10020b57cec5SDimitry Andric   return false;
10030b57cec5SDimitry Andric }
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric static bool isSDKVersionToken(const AsmToken &Tok) {
10060b57cec5SDimitry Andric   return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";
10070b57cec5SDimitry Andric }
10080b57cec5SDimitry Andric 
10090b57cec5SDimitry Andric /// parseMajorMinorVersionComponent ::= major, minor
10100b57cec5SDimitry Andric bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,
10110b57cec5SDimitry Andric                                                       unsigned *Minor,
10120b57cec5SDimitry Andric                                                       const char *VersionName) {
10130b57cec5SDimitry Andric   // Get the major version number.
10140b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
10150b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName +
10160b57cec5SDimitry Andric                     " major version number, integer expected");
10170b57cec5SDimitry Andric   int64_t MajorVal = getLexer().getTok().getIntVal();
10180b57cec5SDimitry Andric   if (MajorVal > 65535 || MajorVal <= 0)
10190b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName + " major version number");
10200b57cec5SDimitry Andric   *Major = (unsigned)MajorVal;
10210b57cec5SDimitry Andric   Lex();
10220b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
10230b57cec5SDimitry Andric     return TokError(Twine(VersionName) +
10240b57cec5SDimitry Andric                     " minor version number required, comma expected");
10250b57cec5SDimitry Andric   Lex();
10260b57cec5SDimitry Andric   // Get the minor version number.
10270b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
10280b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName +
10290b57cec5SDimitry Andric                     " minor version number, integer expected");
10300b57cec5SDimitry Andric   int64_t MinorVal = getLexer().getTok().getIntVal();
10310b57cec5SDimitry Andric   if (MinorVal > 255 || MinorVal < 0)
10320b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName + " minor version number");
10330b57cec5SDimitry Andric   *Minor = MinorVal;
10340b57cec5SDimitry Andric   Lex();
10350b57cec5SDimitry Andric   return false;
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric /// parseOptionalTrailingVersionComponent ::= , version_number
10390b57cec5SDimitry Andric bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
10400b57cec5SDimitry Andric     unsigned *Component, const char *ComponentName) {
10410b57cec5SDimitry Andric   assert(getLexer().is(AsmToken::Comma) && "comma expected");
10420b57cec5SDimitry Andric   Lex();
10430b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
10440b57cec5SDimitry Andric     return TokError(Twine("invalid ") + ComponentName +
10450b57cec5SDimitry Andric                     " version number, integer expected");
10460b57cec5SDimitry Andric   int64_t Val = getLexer().getTok().getIntVal();
10470b57cec5SDimitry Andric   if (Val > 255 || Val < 0)
10480b57cec5SDimitry Andric     return TokError(Twine("invalid ") + ComponentName + " version number");
10490b57cec5SDimitry Andric   *Component = Val;
10500b57cec5SDimitry Andric   Lex();
10510b57cec5SDimitry Andric   return false;
10520b57cec5SDimitry Andric }
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric /// parseVersion ::= parseMajorMinorVersionComponent
10550b57cec5SDimitry Andric ///                      parseOptionalTrailingVersionComponent
10560b57cec5SDimitry Andric bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
10570b57cec5SDimitry Andric                                    unsigned *Update) {
10580b57cec5SDimitry Andric   if (parseMajorMinorVersionComponent(Major, Minor, "OS"))
10590b57cec5SDimitry Andric     return true;
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric   // Get the update level, if specified
10620b57cec5SDimitry Andric   *Update = 0;
10630b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement) ||
10640b57cec5SDimitry Andric       isSDKVersionToken(getLexer().getTok()))
10650b57cec5SDimitry Andric     return false;
10660b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
10670b57cec5SDimitry Andric     return TokError("invalid OS update specifier, comma expected");
10680b57cec5SDimitry Andric   if (parseOptionalTrailingVersionComponent(Update, "OS update"))
10690b57cec5SDimitry Andric     return true;
10700b57cec5SDimitry Andric   return false;
10710b57cec5SDimitry Andric }
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {
10740b57cec5SDimitry Andric   assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
10750b57cec5SDimitry Andric   Lex();
10760b57cec5SDimitry Andric   unsigned Major, Minor;
10770b57cec5SDimitry Andric   if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))
10780b57cec5SDimitry Andric     return true;
10790b57cec5SDimitry Andric   SDKVersion = VersionTuple(Major, Minor);
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   // Get the subminor version, if specified.
10820b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
10830b57cec5SDimitry Andric     unsigned Subminor;
10840b57cec5SDimitry Andric     if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))
10850b57cec5SDimitry Andric       return true;
10860b57cec5SDimitry Andric     SDKVersion = VersionTuple(Major, Minor, Subminor);
10870b57cec5SDimitry Andric   }
10880b57cec5SDimitry Andric   return false;
10890b57cec5SDimitry Andric }
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
10920b57cec5SDimitry Andric                                    SMLoc Loc, Triple::OSType ExpectedOS) {
1093fe6060f1SDimitry Andric   const Triple &Target = getContext().getTargetTriple();
10940b57cec5SDimitry Andric   if (Target.getOS() != ExpectedOS)
10950b57cec5SDimitry Andric     Warning(Loc, Twine(Directive) +
10960b57cec5SDimitry Andric             (Arg.empty() ? Twine() : Twine(' ') + Arg) +
10970b57cec5SDimitry Andric             " used while targeting " + Target.getOSName());
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric   if (LastVersionDirective.isValid()) {
11000b57cec5SDimitry Andric     Warning(Loc, "overriding previous version directive");
11010b57cec5SDimitry Andric     Note(LastVersionDirective, "previous definition is here");
11020b57cec5SDimitry Andric   }
11030b57cec5SDimitry Andric   LastVersionDirective = Loc;
11040b57cec5SDimitry Andric }
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
11070b57cec5SDimitry Andric   switch (Type) {
11080b57cec5SDimitry Andric   case MCVM_WatchOSVersionMin: return Triple::WatchOS;
11090b57cec5SDimitry Andric   case MCVM_TvOSVersionMin:    return Triple::TvOS;
11100b57cec5SDimitry Andric   case MCVM_IOSVersionMin:     return Triple::IOS;
11110b57cec5SDimitry Andric   case MCVM_OSXVersionMin:     return Triple::MacOSX;
11120b57cec5SDimitry Andric   }
11130b57cec5SDimitry Andric   llvm_unreachable("Invalid mc version min type");
11140b57cec5SDimitry Andric }
11150b57cec5SDimitry Andric 
11160b57cec5SDimitry Andric /// parseVersionMin
11170b57cec5SDimitry Andric ///   ::= .ios_version_min parseVersion parseSDKVersion
11180b57cec5SDimitry Andric ///   |   .macosx_version_min parseVersion parseSDKVersion
11190b57cec5SDimitry Andric ///   |   .tvos_version_min parseVersion parseSDKVersion
11200b57cec5SDimitry Andric ///   |   .watchos_version_min parseVersion parseSDKVersion
11210b57cec5SDimitry Andric bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
11220b57cec5SDimitry Andric                                       MCVersionMinType Type) {
11230b57cec5SDimitry Andric   unsigned Major;
11240b57cec5SDimitry Andric   unsigned Minor;
11250b57cec5SDimitry Andric   unsigned Update;
11260b57cec5SDimitry Andric   if (parseVersion(&Major, &Minor, &Update))
11270b57cec5SDimitry Andric     return true;
11280b57cec5SDimitry Andric 
11290b57cec5SDimitry Andric   VersionTuple SDKVersion;
11300b57cec5SDimitry Andric   if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
11310b57cec5SDimitry Andric     return true;
11320b57cec5SDimitry Andric 
113306c3fb27SDimitry Andric   if (parseEOL())
11340b57cec5SDimitry Andric     return addErrorSuffix(Twine(" in '") + Directive + "' directive");
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
11370b57cec5SDimitry Andric   checkVersion(Directive, StringRef(), Loc, ExpectedOS);
11385ffd83dbSDimitry Andric   getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion);
11390b57cec5SDimitry Andric   return false;
11400b57cec5SDimitry Andric }
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
11430b57cec5SDimitry Andric   switch (Type) {
114404eeddc0SDimitry Andric   case MachO::PLATFORM_UNKNOWN: /* silence warning */
114504eeddc0SDimitry Andric     break;
11460b57cec5SDimitry Andric   case MachO::PLATFORM_MACOS:   return Triple::MacOSX;
11470b57cec5SDimitry Andric   case MachO::PLATFORM_IOS:     return Triple::IOS;
11480b57cec5SDimitry Andric   case MachO::PLATFORM_TVOS:    return Triple::TvOS;
11490b57cec5SDimitry Andric   case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;
11507a6dacacSDimitry Andric   case MachO::PLATFORM_XROS:    return Triple::XROS;
11510b57cec5SDimitry Andric   case MachO::PLATFORM_BRIDGEOS:         /* silence warning */ break;
115281ad6265SDimitry Andric   case MachO::PLATFORM_DRIVERKIT:
115381ad6265SDimitry Andric     return Triple::DriverKit;
11540b57cec5SDimitry Andric   case MachO::PLATFORM_MACCATALYST: return Triple::IOS;
11550b57cec5SDimitry Andric   case MachO::PLATFORM_IOSSIMULATOR:     /* silence warning */ break;
11560b57cec5SDimitry Andric   case MachO::PLATFORM_TVOSSIMULATOR:    /* silence warning */ break;
11570b57cec5SDimitry Andric   case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;
11587a6dacacSDimitry Andric   case MachO::PLATFORM_XROS_SIMULATOR:   /* silence warning */ break;
11590b57cec5SDimitry Andric   }
11600b57cec5SDimitry Andric   llvm_unreachable("Invalid mach-o platform type");
11610b57cec5SDimitry Andric }
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric /// parseBuildVersion
11640b57cec5SDimitry Andric ///   ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
11650b57cec5SDimitry Andric bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
11660b57cec5SDimitry Andric   StringRef PlatformName;
11670b57cec5SDimitry Andric   SMLoc PlatformLoc = getTok().getLoc();
11680b57cec5SDimitry Andric   if (getParser().parseIdentifier(PlatformName))
11690b57cec5SDimitry Andric     return TokError("platform name expected");
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric   unsigned Platform = StringSwitch<unsigned>(PlatformName)
11725f757f3fSDimitry Andric #define PLATFORM(platform, id, name, build_name, target, tapi_target,          \
11735f757f3fSDimitry Andric                  marketing)                                                    \
11745f757f3fSDimitry Andric   .Case(#build_name, MachO::PLATFORM_##platform)
11755f757f3fSDimitry Andric #include "llvm/BinaryFormat/MachO.def"
11765f757f3fSDimitry Andric                           .Default(MachO::PLATFORM_UNKNOWN);
11775f757f3fSDimitry Andric 
11785f757f3fSDimitry Andric   if (Platform == MachO::PLATFORM_UNKNOWN)
11790b57cec5SDimitry Andric     return Error(PlatformLoc, "unknown platform name");
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
11820b57cec5SDimitry Andric     return TokError("version number required, comma expected");
11830b57cec5SDimitry Andric   Lex();
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric   unsigned Major;
11860b57cec5SDimitry Andric   unsigned Minor;
11870b57cec5SDimitry Andric   unsigned Update;
11880b57cec5SDimitry Andric   if (parseVersion(&Major, &Minor, &Update))
11890b57cec5SDimitry Andric     return true;
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric   VersionTuple SDKVersion;
11920b57cec5SDimitry Andric   if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
11930b57cec5SDimitry Andric     return true;
11940b57cec5SDimitry Andric 
119506c3fb27SDimitry Andric   if (parseEOL())
11960b57cec5SDimitry Andric     return addErrorSuffix(" in '.build_version' directive");
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   Triple::OSType ExpectedOS
11990b57cec5SDimitry Andric     = getOSTypeFromPlatform((MachO::PlatformType)Platform);
12000b57cec5SDimitry Andric   checkVersion(Directive, PlatformName, Loc, ExpectedOS);
12015ffd83dbSDimitry Andric   getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
12020b57cec5SDimitry Andric   return false;
12030b57cec5SDimitry Andric }
12040b57cec5SDimitry Andric 
120504eeddc0SDimitry Andric /// parseDirectiveCGProfile
120604eeddc0SDimitry Andric ///   ::= .cg_profile from, to, count
120704eeddc0SDimitry Andric bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
120804eeddc0SDimitry Andric   return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc);
120904eeddc0SDimitry Andric }
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric namespace llvm {
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric MCAsmParserExtension *createDarwinAsmParser() {
12140b57cec5SDimitry Andric   return new DarwinAsmParser;
12150b57cec5SDimitry Andric }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric } // end llvm namespace
1218