xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCParser/DarwinAsmParser.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
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/STLExtras.h"
100b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
110b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
120b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
130b57cec5SDimitry Andric #include "llvm/ADT/Triple.h"
140b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
150b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParserExtension.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
250b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h"
26*fe6060f1SDimitry Andric #include "llvm/Support/Error.h"
270b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
280b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
290b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
300b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
310b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
320b57cec5SDimitry Andric #include <algorithm>
330b57cec5SDimitry Andric #include <cstddef>
340b57cec5SDimitry Andric #include <cstdint>
350b57cec5SDimitry Andric #include <string>
360b57cec5SDimitry Andric #include <system_error>
370b57cec5SDimitry Andric #include <utility>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric using namespace llvm;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric namespace {
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric /// Implementation of directive handling which is shared across all
440b57cec5SDimitry Andric /// Darwin targets.
450b57cec5SDimitry Andric class DarwinAsmParser : public MCAsmParserExtension {
460b57cec5SDimitry Andric   template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
470b57cec5SDimitry Andric   void addDirectiveHandler(StringRef Directive) {
480b57cec5SDimitry Andric     MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
490b57cec5SDimitry Andric         this, HandleDirective<DarwinAsmParser, HandlerMethod>);
500b57cec5SDimitry Andric     getParser().addDirectiveHandler(Directive, Handler);
510b57cec5SDimitry Andric   }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   bool parseSectionSwitch(StringRef Segment, StringRef Section,
540b57cec5SDimitry Andric                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
550b57cec5SDimitry Andric                           unsigned StubSize = 0);
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   SMLoc LastVersionDirective;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric public:
600b57cec5SDimitry Andric   DarwinAsmParser() = default;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   void Initialize(MCAsmParser &Parser) override {
630b57cec5SDimitry Andric     // Call the base implementation.
640b57cec5SDimitry Andric     this->MCAsmParserExtension::Initialize(Parser);
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");
670b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
680b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
690b57cec5SDimitry Andric       ".indirect_symbol");
700b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
710b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
720b57cec5SDimitry Andric       ".subsections_via_symbols");
730b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
740b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
750b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
760b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
770b57cec5SDimitry Andric       ".pushsection");
780b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
790b57cec5SDimitry Andric       ".popsection");
800b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
810b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
820b57cec5SDimitry Andric       ".secure_log_unique");
830b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
840b57cec5SDimitry Andric       ".secure_log_reset");
850b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
860b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
890b57cec5SDimitry Andric       ".data_region");
900b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
910b57cec5SDimitry Andric       ".end_data_region");
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric     // Special section directives.
940b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
950b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
960b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
970b57cec5SDimitry Andric       ".const_data");
980b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
990b57cec5SDimitry Andric       ".constructor");
1000b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
1010b57cec5SDimitry Andric       ".cstring");
1020b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
1030b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
1040b57cec5SDimitry Andric       ".destructor");
1050b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
1060b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
1070b57cec5SDimitry Andric       ".fvmlib_init0");
1080b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
1090b57cec5SDimitry Andric       ".fvmlib_init1");
1100b57cec5SDimitry Andric     addDirectiveHandler<
1110b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
1120b57cec5SDimitry Andric         ".lazy_symbol_pointer");
1130b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
1140b57cec5SDimitry Andric       ".linker_option");
1150b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
1160b57cec5SDimitry Andric       ".literal16");
1170b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
1180b57cec5SDimitry Andric       ".literal4");
1190b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
1200b57cec5SDimitry Andric       ".literal8");
1210b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
1220b57cec5SDimitry Andric       ".mod_init_func");
1230b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
1240b57cec5SDimitry Andric       ".mod_term_func");
1250b57cec5SDimitry Andric     addDirectiveHandler<
1260b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
1270b57cec5SDimitry Andric         ".non_lazy_symbol_pointer");
1280b57cec5SDimitry Andric     addDirectiveHandler<
1290b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(
1300b57cec5SDimitry Andric         ".thread_local_variable_pointer");
1310b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
1320b57cec5SDimitry Andric       ".objc_cat_cls_meth");
1330b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
1340b57cec5SDimitry Andric       ".objc_cat_inst_meth");
1350b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
1360b57cec5SDimitry Andric       ".objc_category");
1370b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
1380b57cec5SDimitry Andric       ".objc_class");
1390b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
1400b57cec5SDimitry Andric       ".objc_class_names");
1410b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
1420b57cec5SDimitry Andric       ".objc_class_vars");
1430b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
1440b57cec5SDimitry Andric       ".objc_cls_meth");
1450b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
1460b57cec5SDimitry Andric       ".objc_cls_refs");
1470b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
1480b57cec5SDimitry Andric       ".objc_inst_meth");
1490b57cec5SDimitry Andric     addDirectiveHandler<
1500b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
1510b57cec5SDimitry Andric         ".objc_instance_vars");
1520b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
1530b57cec5SDimitry Andric       ".objc_message_refs");
1540b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
1550b57cec5SDimitry Andric       ".objc_meta_class");
1560b57cec5SDimitry Andric     addDirectiveHandler<
1570b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
1580b57cec5SDimitry Andric         ".objc_meth_var_names");
1590b57cec5SDimitry Andric     addDirectiveHandler<
1600b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
1610b57cec5SDimitry Andric         ".objc_meth_var_types");
1620b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
1630b57cec5SDimitry Andric       ".objc_module_info");
1640b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
1650b57cec5SDimitry Andric       ".objc_protocol");
1660b57cec5SDimitry Andric     addDirectiveHandler<
1670b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
1680b57cec5SDimitry Andric         ".objc_selector_strs");
1690b57cec5SDimitry Andric     addDirectiveHandler<
1700b57cec5SDimitry Andric       &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
1710b57cec5SDimitry Andric         ".objc_string_object");
1720b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
1730b57cec5SDimitry Andric       ".objc_symbols");
1740b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
1750b57cec5SDimitry Andric       ".picsymbol_stub");
1760b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
1770b57cec5SDimitry Andric       ".static_const");
1780b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
1790b57cec5SDimitry Andric       ".static_data");
1800b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
1810b57cec5SDimitry Andric       ".symbol_stub");
1820b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
1830b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
1840b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
1850b57cec5SDimitry Andric       ".thread_init_func");
1860b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
1890b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(
1900b57cec5SDimitry Andric       ".watchos_version_min");
1910b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(
1920b57cec5SDimitry Andric       ".tvos_version_min");
1930b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(
1940b57cec5SDimitry Andric       ".ios_version_min");
1950b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(
1960b57cec5SDimitry Andric       ".macosx_version_min");
1970b57cec5SDimitry Andric     addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric     LastVersionDirective = SMLoc();
2000b57cec5SDimitry Andric   }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   bool parseDirectiveAltEntry(StringRef, SMLoc);
2030b57cec5SDimitry Andric   bool parseDirectiveDesc(StringRef, SMLoc);
2040b57cec5SDimitry Andric   bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
2050b57cec5SDimitry Andric   bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
2060b57cec5SDimitry Andric   bool parseDirectiveLsym(StringRef, SMLoc);
2070b57cec5SDimitry Andric   bool parseDirectiveLinkerOption(StringRef, SMLoc);
2080b57cec5SDimitry Andric   bool parseDirectiveSection(StringRef, SMLoc);
2090b57cec5SDimitry Andric   bool parseDirectivePushSection(StringRef, SMLoc);
2100b57cec5SDimitry Andric   bool parseDirectivePopSection(StringRef, SMLoc);
2110b57cec5SDimitry Andric   bool parseDirectivePrevious(StringRef, SMLoc);
2120b57cec5SDimitry Andric   bool parseDirectiveSecureLogReset(StringRef, SMLoc);
2130b57cec5SDimitry Andric   bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
2140b57cec5SDimitry Andric   bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
2150b57cec5SDimitry Andric   bool parseDirectiveTBSS(StringRef, SMLoc);
2160b57cec5SDimitry Andric   bool parseDirectiveZerofill(StringRef, SMLoc);
2170b57cec5SDimitry Andric   bool parseDirectiveDataRegion(StringRef, SMLoc);
2180b57cec5SDimitry Andric   bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   // Named Section Directive
2210b57cec5SDimitry Andric   bool parseSectionDirectiveBss(StringRef, SMLoc) {
2220b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__bss");
2230b57cec5SDimitry Andric   }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   bool parseSectionDirectiveConst(StringRef, SMLoc) {
2260b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__const");
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
2300b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__static_const");
2310b57cec5SDimitry Andric   }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   bool parseSectionDirectiveCString(StringRef, SMLoc) {
2340b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__cstring",
2350b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
2390b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__literal4",
2400b57cec5SDimitry Andric                               MachO::S_4BYTE_LITERALS, 4);
2410b57cec5SDimitry Andric   }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
2440b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__literal8",
2450b57cec5SDimitry Andric                               MachO::S_8BYTE_LITERALS, 8);
2460b57cec5SDimitry Andric   }
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
2490b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__literal16",
2500b57cec5SDimitry Andric                               MachO::S_16BYTE_LITERALS, 16);
2510b57cec5SDimitry Andric   }
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
2540b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__constructor");
2550b57cec5SDimitry Andric   }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
2580b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__destructor");
2590b57cec5SDimitry Andric   }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
2620b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__fvmlib_init0");
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
2660b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__fvmlib_init1");
2670b57cec5SDimitry Andric   }
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
2700b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__symbol_stub",
2710b57cec5SDimitry Andric                               MachO::S_SYMBOL_STUBS |
2720b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS,
2730b57cec5SDimitry Andric                               // FIXME: Different on PPC and ARM.
2740b57cec5SDimitry Andric                               0, 16);
2750b57cec5SDimitry Andric   }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
2780b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT","__picsymbol_stub",
2790b57cec5SDimitry Andric                               MachO::S_SYMBOL_STUBS |
2800b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
2810b57cec5SDimitry Andric   }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   bool parseSectionDirectiveData(StringRef, SMLoc) {
2840b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__data");
2850b57cec5SDimitry Andric   }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
2880b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__static_data");
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
2920b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
2930b57cec5SDimitry Andric                               MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
2940b57cec5SDimitry Andric   }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
2970b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__la_symbol_ptr",
2980b57cec5SDimitry Andric                               MachO::S_LAZY_SYMBOL_POINTERS, 4);
2990b57cec5SDimitry Andric   }
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {
3020b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_ptr",
3030b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   bool parseSectionDirectiveDyld(StringRef, SMLoc) {
3070b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__dyld");
3080b57cec5SDimitry Andric   }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
3110b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__mod_init_func",
3120b57cec5SDimitry Andric                               MachO::S_MOD_INIT_FUNC_POINTERS, 4);
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
3160b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__mod_term_func",
3170b57cec5SDimitry Andric                               MachO::S_MOD_TERM_FUNC_POINTERS, 4);
3180b57cec5SDimitry Andric   }
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   bool parseSectionDirectiveConstData(StringRef, SMLoc) {
3210b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__const");
3220b57cec5SDimitry Andric   }
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
3250b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__class",
3260b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
3300b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__meta_class",
3310b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3320b57cec5SDimitry Andric   }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
3350b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cat_cls_meth",
3360b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3370b57cec5SDimitry Andric   }
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
3400b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cat_inst_meth",
3410b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3420b57cec5SDimitry Andric   }
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
3450b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__protocol",
3460b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3470b57cec5SDimitry Andric   }
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
3500b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__string_object",
3510b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
3550b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cls_meth",
3560b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
3600b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__inst_meth",
3610b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3620b57cec5SDimitry Andric   }
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
3650b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__cls_refs",
3660b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP |
3670b57cec5SDimitry Andric                               MachO::S_LITERAL_POINTERS, 4);
3680b57cec5SDimitry Andric   }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
3710b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__message_refs",
3720b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP |
3730b57cec5SDimitry Andric                               MachO::S_LITERAL_POINTERS, 4);
3740b57cec5SDimitry Andric   }
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
3770b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__symbols",
3780b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
3820b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__category",
3830b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3840b57cec5SDimitry Andric   }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
3870b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__class_vars",
3880b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3890b57cec5SDimitry Andric   }
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
3920b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__instance_vars",
3930b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3940b57cec5SDimitry Andric   }
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
3970b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__module_info",
3980b57cec5SDimitry Andric                               MachO::S_ATTR_NO_DEAD_STRIP);
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
4020b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
4030b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4040b57cec5SDimitry Andric   }
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
4070b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
4080b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4090b57cec5SDimitry Andric   }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
4120b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__cstring",
4130b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
4170b57cec5SDimitry Andric     return parseSectionSwitch("__OBJC", "__selector_strs",
4180b57cec5SDimitry Andric                               MachO::S_CSTRING_LITERALS);
4190b57cec5SDimitry Andric   }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   bool parseSectionDirectiveTData(StringRef, SMLoc) {
4220b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_data",
4230b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_REGULAR);
4240b57cec5SDimitry Andric   }
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   bool parseSectionDirectiveText(StringRef, SMLoc) {
4270b57cec5SDimitry Andric     return parseSectionSwitch("__TEXT", "__text",
4280b57cec5SDimitry Andric                               MachO::S_ATTR_PURE_INSTRUCTIONS);
4290b57cec5SDimitry Andric   }
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   bool parseSectionDirectiveTLV(StringRef, SMLoc) {
4320b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_vars",
4330b57cec5SDimitry Andric                               MachO::S_THREAD_LOCAL_VARIABLES);
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   bool parseSectionDirectiveIdent(StringRef, SMLoc) {
4370b57cec5SDimitry Andric     // Darwin silently ignores the .ident directive.
4380b57cec5SDimitry Andric     getParser().eatToEndOfStatement();
4390b57cec5SDimitry Andric     return false;
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
4430b57cec5SDimitry Andric     return parseSectionSwitch("__DATA", "__thread_init",
4440b57cec5SDimitry Andric                          MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
4450b57cec5SDimitry Andric   }
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {
4480b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);
4490b57cec5SDimitry Andric   }
4500b57cec5SDimitry Andric   bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {
4510b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);
4520b57cec5SDimitry Andric   }
4530b57cec5SDimitry Andric   bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {
4540b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);
4550b57cec5SDimitry Andric   }
4560b57cec5SDimitry Andric   bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {
4570b57cec5SDimitry Andric     return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   bool parseBuildVersion(StringRef Directive, SMLoc Loc);
4610b57cec5SDimitry Andric   bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);
4620b57cec5SDimitry Andric   bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,
4630b57cec5SDimitry Andric                                        const char *VersionName);
4640b57cec5SDimitry Andric   bool parseOptionalTrailingVersionComponent(unsigned *Component,
4650b57cec5SDimitry Andric                                              const char *ComponentName);
4660b57cec5SDimitry Andric   bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);
4670b57cec5SDimitry Andric   bool parseSDKVersion(VersionTuple &SDKVersion);
4680b57cec5SDimitry Andric   void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,
4690b57cec5SDimitry Andric                     Triple::OSType ExpectedOS);
4700b57cec5SDimitry Andric };
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric } // end anonymous namespace
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,
4750b57cec5SDimitry Andric                                          unsigned TAA, unsigned Align,
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;
4830b57cec5SDimitry 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.
4950b57cec5SDimitry Andric   if (Align)
4965ffd83dbSDimitry Andric     getStreamer().emitValueToAlignment(Align);
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;
693*fe6060f1SDimitry Andric   if (class Error E = MCSectionMachO::ParseSectionSpecifier(
694*fe6060f1SDimitry Andric           SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))
695*fe6060f1SDimitry 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.
698*fe6060f1SDimitry 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 
7080b57cec5SDimitry Andric     if (!Section.equals(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.
7220b57cec5SDimitry 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) {
7310b57cec5SDimitry Andric   getStreamer().PushSection();
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric   if (parseDirectiveSection(S, Loc)) {
7340b57cec5SDimitry 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) {
7440b57cec5SDimitry 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");
7550b57cec5SDimitry 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.
7700b57cec5SDimitry Andric   const char *SecureLogFile = getContext().getSecureLogFile();
7710b57cec5SDimitry Andric   if (!SecureLogFile)
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;
779*fe6060f1SDimitry Andric     auto NewOS = std::make_unique<raw_fd_ostream>(StringRef(SecureLogFile), EC,
780*fe6060f1SDimitry Andric                                                   sys::fs::OF_Append |
781*fe6060f1SDimitry Andric                                                       sys::fs::OF_TextWithCRLF);
7820b57cec5SDimitry Andric     if (EC)
7830b57cec5SDimitry Andric        return Error(IDLoc, Twine("can't open secure log file: ") +
7840b57cec5SDimitry Andric                                SecureLogFile + " (" + EC.message() + ")");
7850b57cec5SDimitry Andric     OS = NewOS.get();
7860b57cec5SDimitry Andric     getContext().setSecureLog(std::move(NewOS));
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   // Write the message.
7900b57cec5SDimitry Andric   unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
7910b57cec5SDimitry Andric   *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
7920b57cec5SDimitry Andric       << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
7930b57cec5SDimitry Andric       << LogMessage + "\n";
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric   getContext().setSecureLogUsed(true);
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric   return false;
7980b57cec5SDimitry Andric }
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric /// ParseDirectiveSecureLogReset
8010b57cec5SDimitry Andric ///  ::= .secure_log_reset
8020b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
8030b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
8040b57cec5SDimitry Andric     return TokError("unexpected token in '.secure_log_reset' directive");
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   Lex();
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   getContext().setSecureLogUsed(false);
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric   return false;
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric /// parseDirectiveSubsectionsViaSymbols
8140b57cec5SDimitry Andric ///  ::= .subsections_via_symbols
8150b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
8160b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
8170b57cec5SDimitry Andric     return TokError("unexpected token in '.subsections_via_symbols' directive");
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   Lex();
8200b57cec5SDimitry Andric 
8215ffd83dbSDimitry Andric   getStreamer().emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   return false;
8240b57cec5SDimitry Andric }
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric /// ParseDirectiveTBSS
8270b57cec5SDimitry Andric ///  ::= .tbss identifier, size, align
8280b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
8290b57cec5SDimitry Andric   SMLoc IDLoc = getLexer().getLoc();
8300b57cec5SDimitry Andric   StringRef Name;
8310b57cec5SDimitry Andric   if (getParser().parseIdentifier(Name))
8320b57cec5SDimitry Andric     return TokError("expected identifier in directive");
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric   // Handle the identifier as the key symbol.
8350b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
8380b57cec5SDimitry Andric     return TokError("unexpected token in directive");
8390b57cec5SDimitry Andric   Lex();
8400b57cec5SDimitry Andric 
8410b57cec5SDimitry Andric   int64_t Size;
8420b57cec5SDimitry Andric   SMLoc SizeLoc = getLexer().getLoc();
8430b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(Size))
8440b57cec5SDimitry Andric     return true;
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric   int64_t Pow2Alignment = 0;
8470b57cec5SDimitry Andric   SMLoc Pow2AlignmentLoc;
8480b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
8490b57cec5SDimitry Andric     Lex();
8500b57cec5SDimitry Andric     Pow2AlignmentLoc = getLexer().getLoc();
8510b57cec5SDimitry Andric     if (getParser().parseAbsoluteExpression(Pow2Alignment))
8520b57cec5SDimitry Andric       return true;
8530b57cec5SDimitry Andric   }
8540b57cec5SDimitry Andric 
8550b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
8560b57cec5SDimitry Andric     return TokError("unexpected token in '.tbss' directive");
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   Lex();
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric   if (Size < 0)
8610b57cec5SDimitry Andric     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
8620b57cec5SDimitry Andric                  "zero");
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric   // FIXME: Diagnose overflow.
8650b57cec5SDimitry Andric   if (Pow2Alignment < 0)
8660b57cec5SDimitry Andric     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
8670b57cec5SDimitry Andric                  "than zero");
8680b57cec5SDimitry Andric 
8690b57cec5SDimitry Andric   if (!Sym->isUndefined())
8700b57cec5SDimitry Andric     return Error(IDLoc, "invalid symbol redefinition");
8710b57cec5SDimitry Andric 
8725ffd83dbSDimitry Andric   getStreamer().emitTBSSSymbol(
8735ffd83dbSDimitry Andric       getContext().getMachOSection("__DATA", "__thread_bss",
8745ffd83dbSDimitry Andric                                    MachO::S_THREAD_LOCAL_ZEROFILL, 0,
8755ffd83dbSDimitry Andric                                    SectionKind::getThreadBSS()),
8760b57cec5SDimitry Andric       Sym, Size, 1 << Pow2Alignment);
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   return false;
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric 
8810b57cec5SDimitry Andric /// ParseDirectiveZerofill
8820b57cec5SDimitry Andric ///  ::= .zerofill segname , sectname [, identifier , size_expression [
8830b57cec5SDimitry Andric ///      , align_expression ]]
8840b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
8850b57cec5SDimitry Andric   StringRef Segment;
8860b57cec5SDimitry Andric   if (getParser().parseIdentifier(Segment))
8870b57cec5SDimitry Andric     return TokError("expected segment name after '.zerofill' directive");
8880b57cec5SDimitry Andric 
8890b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
8900b57cec5SDimitry Andric     return TokError("unexpected token in directive");
8910b57cec5SDimitry Andric   Lex();
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   StringRef Section;
8940b57cec5SDimitry Andric   SMLoc SectionLoc = getLexer().getLoc();
8950b57cec5SDimitry Andric   if (getParser().parseIdentifier(Section))
8960b57cec5SDimitry Andric     return TokError("expected section name after comma in '.zerofill' "
8970b57cec5SDimitry Andric                     "directive");
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric   // If this is the end of the line all that was wanted was to create the
9000b57cec5SDimitry Andric   // the section but with no symbol.
9010b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement)) {
9020b57cec5SDimitry Andric     // Create the zerofill section but no symbol
9035ffd83dbSDimitry Andric     getStreamer().emitZerofill(
9040b57cec5SDimitry Andric         getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,
9050b57cec5SDimitry Andric                                      SectionKind::getBSS()),
9060b57cec5SDimitry Andric         /*Symbol=*/nullptr, /*Size=*/0, /*ByteAlignment=*/0, SectionLoc);
9070b57cec5SDimitry Andric     return false;
9080b57cec5SDimitry Andric   }
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
9110b57cec5SDimitry Andric     return TokError("unexpected token in directive");
9120b57cec5SDimitry Andric   Lex();
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric   SMLoc IDLoc = getLexer().getLoc();
9150b57cec5SDimitry Andric   StringRef IDStr;
9160b57cec5SDimitry Andric   if (getParser().parseIdentifier(IDStr))
9170b57cec5SDimitry Andric     return TokError("expected identifier in directive");
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric   // handle the identifier as the key symbol.
9200b57cec5SDimitry Andric   MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr);
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
9230b57cec5SDimitry Andric     return TokError("unexpected token in directive");
9240b57cec5SDimitry Andric   Lex();
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric   int64_t Size;
9270b57cec5SDimitry Andric   SMLoc SizeLoc = getLexer().getLoc();
9280b57cec5SDimitry Andric   if (getParser().parseAbsoluteExpression(Size))
9290b57cec5SDimitry Andric     return true;
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   int64_t Pow2Alignment = 0;
9320b57cec5SDimitry Andric   SMLoc Pow2AlignmentLoc;
9330b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
9340b57cec5SDimitry Andric     Lex();
9350b57cec5SDimitry Andric     Pow2AlignmentLoc = getLexer().getLoc();
9360b57cec5SDimitry Andric     if (getParser().parseAbsoluteExpression(Pow2Alignment))
9370b57cec5SDimitry Andric       return true;
9380b57cec5SDimitry Andric   }
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
9410b57cec5SDimitry Andric     return TokError("unexpected token in '.zerofill' directive");
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   Lex();
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric   if (Size < 0)
9460b57cec5SDimitry Andric     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
9470b57cec5SDimitry Andric                  "than zero");
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric   // NOTE: The alignment in the directive is a power of 2 value, the assembler
9500b57cec5SDimitry Andric   // may internally end up wanting an alignment in bytes.
9510b57cec5SDimitry Andric   // FIXME: Diagnose overflow.
9520b57cec5SDimitry Andric   if (Pow2Alignment < 0)
9530b57cec5SDimitry Andric     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
9540b57cec5SDimitry Andric                  "can't be less than zero");
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric   if (!Sym->isUndefined())
9570b57cec5SDimitry Andric     return Error(IDLoc, "invalid symbol redefinition");
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric   // Create the zerofill Symbol with Size and Pow2Alignment
9600b57cec5SDimitry Andric   //
9610b57cec5SDimitry Andric   // FIXME: Arch specific.
9625ffd83dbSDimitry Andric   getStreamer().emitZerofill(getContext().getMachOSection(
9630b57cec5SDimitry Andric                                Segment, Section, MachO::S_ZEROFILL,
9640b57cec5SDimitry Andric                                0, SectionKind::getBSS()),
9650b57cec5SDimitry Andric                              Sym, Size, 1 << Pow2Alignment, SectionLoc);
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric   return false;
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric /// ParseDirectiveDataRegion
9710b57cec5SDimitry Andric ///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
9720b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
9730b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement)) {
9740b57cec5SDimitry Andric     Lex();
9755ffd83dbSDimitry Andric     getStreamer().emitDataRegion(MCDR_DataRegion);
9760b57cec5SDimitry Andric     return false;
9770b57cec5SDimitry Andric   }
9780b57cec5SDimitry Andric   StringRef RegionType;
9790b57cec5SDimitry Andric   SMLoc Loc = getParser().getTok().getLoc();
9800b57cec5SDimitry Andric   if (getParser().parseIdentifier(RegionType))
9810b57cec5SDimitry Andric     return TokError("expected region type after '.data_region' directive");
9820b57cec5SDimitry Andric   int Kind = StringSwitch<int>(RegionType)
9830b57cec5SDimitry Andric     .Case("jt8", MCDR_DataRegionJT8)
9840b57cec5SDimitry Andric     .Case("jt16", MCDR_DataRegionJT16)
9850b57cec5SDimitry Andric     .Case("jt32", MCDR_DataRegionJT32)
9860b57cec5SDimitry Andric     .Default(-1);
9870b57cec5SDimitry Andric   if (Kind == -1)
9880b57cec5SDimitry Andric     return Error(Loc, "unknown region type in '.data_region' directive");
9890b57cec5SDimitry Andric   Lex();
9900b57cec5SDimitry Andric 
9915ffd83dbSDimitry Andric   getStreamer().emitDataRegion((MCDataRegionType)Kind);
9920b57cec5SDimitry Andric   return false;
9930b57cec5SDimitry Andric }
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric /// ParseDirectiveDataRegionEnd
9960b57cec5SDimitry Andric ///  ::= .end_data_region
9970b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
9980b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement))
9990b57cec5SDimitry Andric     return TokError("unexpected token in '.end_data_region' directive");
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   Lex();
10025ffd83dbSDimitry Andric   getStreamer().emitDataRegion(MCDR_DataRegionEnd);
10030b57cec5SDimitry Andric   return false;
10040b57cec5SDimitry Andric }
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric static bool isSDKVersionToken(const AsmToken &Tok) {
10070b57cec5SDimitry Andric   return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric /// parseMajorMinorVersionComponent ::= major, minor
10110b57cec5SDimitry Andric bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,
10120b57cec5SDimitry Andric                                                       unsigned *Minor,
10130b57cec5SDimitry Andric                                                       const char *VersionName) {
10140b57cec5SDimitry Andric   // Get the major version number.
10150b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
10160b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName +
10170b57cec5SDimitry Andric                     " major version number, integer expected");
10180b57cec5SDimitry Andric   int64_t MajorVal = getLexer().getTok().getIntVal();
10190b57cec5SDimitry Andric   if (MajorVal > 65535 || MajorVal <= 0)
10200b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName + " major version number");
10210b57cec5SDimitry Andric   *Major = (unsigned)MajorVal;
10220b57cec5SDimitry Andric   Lex();
10230b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
10240b57cec5SDimitry Andric     return TokError(Twine(VersionName) +
10250b57cec5SDimitry Andric                     " minor version number required, comma expected");
10260b57cec5SDimitry Andric   Lex();
10270b57cec5SDimitry Andric   // Get the minor version number.
10280b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
10290b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName +
10300b57cec5SDimitry Andric                     " minor version number, integer expected");
10310b57cec5SDimitry Andric   int64_t MinorVal = getLexer().getTok().getIntVal();
10320b57cec5SDimitry Andric   if (MinorVal > 255 || MinorVal < 0)
10330b57cec5SDimitry Andric     return TokError(Twine("invalid ") + VersionName + " minor version number");
10340b57cec5SDimitry Andric   *Minor = MinorVal;
10350b57cec5SDimitry Andric   Lex();
10360b57cec5SDimitry Andric   return false;
10370b57cec5SDimitry Andric }
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric /// parseOptionalTrailingVersionComponent ::= , version_number
10400b57cec5SDimitry Andric bool DarwinAsmParser::parseOptionalTrailingVersionComponent(
10410b57cec5SDimitry Andric     unsigned *Component, const char *ComponentName) {
10420b57cec5SDimitry Andric   assert(getLexer().is(AsmToken::Comma) && "comma expected");
10430b57cec5SDimitry Andric   Lex();
10440b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Integer))
10450b57cec5SDimitry Andric     return TokError(Twine("invalid ") + ComponentName +
10460b57cec5SDimitry Andric                     " version number, integer expected");
10470b57cec5SDimitry Andric   int64_t Val = getLexer().getTok().getIntVal();
10480b57cec5SDimitry Andric   if (Val > 255 || Val < 0)
10490b57cec5SDimitry Andric     return TokError(Twine("invalid ") + ComponentName + " version number");
10500b57cec5SDimitry Andric   *Component = Val;
10510b57cec5SDimitry Andric   Lex();
10520b57cec5SDimitry Andric   return false;
10530b57cec5SDimitry Andric }
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric /// parseVersion ::= parseMajorMinorVersionComponent
10560b57cec5SDimitry Andric ///                      parseOptionalTrailingVersionComponent
10570b57cec5SDimitry Andric bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,
10580b57cec5SDimitry Andric                                    unsigned *Update) {
10590b57cec5SDimitry Andric   if (parseMajorMinorVersionComponent(Major, Minor, "OS"))
10600b57cec5SDimitry Andric     return true;
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric   // Get the update level, if specified
10630b57cec5SDimitry Andric   *Update = 0;
10640b57cec5SDimitry Andric   if (getLexer().is(AsmToken::EndOfStatement) ||
10650b57cec5SDimitry Andric       isSDKVersionToken(getLexer().getTok()))
10660b57cec5SDimitry Andric     return false;
10670b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
10680b57cec5SDimitry Andric     return TokError("invalid OS update specifier, comma expected");
10690b57cec5SDimitry Andric   if (parseOptionalTrailingVersionComponent(Update, "OS update"))
10700b57cec5SDimitry Andric     return true;
10710b57cec5SDimitry Andric   return false;
10720b57cec5SDimitry Andric }
10730b57cec5SDimitry Andric 
10740b57cec5SDimitry Andric bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {
10750b57cec5SDimitry Andric   assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");
10760b57cec5SDimitry Andric   Lex();
10770b57cec5SDimitry Andric   unsigned Major, Minor;
10780b57cec5SDimitry Andric   if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))
10790b57cec5SDimitry Andric     return true;
10800b57cec5SDimitry Andric   SDKVersion = VersionTuple(Major, Minor);
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric   // Get the subminor version, if specified.
10830b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
10840b57cec5SDimitry Andric     unsigned Subminor;
10850b57cec5SDimitry Andric     if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))
10860b57cec5SDimitry Andric       return true;
10870b57cec5SDimitry Andric     SDKVersion = VersionTuple(Major, Minor, Subminor);
10880b57cec5SDimitry Andric   }
10890b57cec5SDimitry Andric   return false;
10900b57cec5SDimitry Andric }
10910b57cec5SDimitry Andric 
10920b57cec5SDimitry Andric void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,
10930b57cec5SDimitry Andric                                    SMLoc Loc, Triple::OSType ExpectedOS) {
1094*fe6060f1SDimitry Andric   const Triple &Target = getContext().getTargetTriple();
10950b57cec5SDimitry Andric   if (Target.getOS() != ExpectedOS)
10960b57cec5SDimitry Andric     Warning(Loc, Twine(Directive) +
10970b57cec5SDimitry Andric             (Arg.empty() ? Twine() : Twine(' ') + Arg) +
10980b57cec5SDimitry Andric             " used while targeting " + Target.getOSName());
10990b57cec5SDimitry Andric 
11000b57cec5SDimitry Andric   if (LastVersionDirective.isValid()) {
11010b57cec5SDimitry Andric     Warning(Loc, "overriding previous version directive");
11020b57cec5SDimitry Andric     Note(LastVersionDirective, "previous definition is here");
11030b57cec5SDimitry Andric   }
11040b57cec5SDimitry Andric   LastVersionDirective = Loc;
11050b57cec5SDimitry Andric }
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {
11080b57cec5SDimitry Andric   switch (Type) {
11090b57cec5SDimitry Andric   case MCVM_WatchOSVersionMin: return Triple::WatchOS;
11100b57cec5SDimitry Andric   case MCVM_TvOSVersionMin:    return Triple::TvOS;
11110b57cec5SDimitry Andric   case MCVM_IOSVersionMin:     return Triple::IOS;
11120b57cec5SDimitry Andric   case MCVM_OSXVersionMin:     return Triple::MacOSX;
11130b57cec5SDimitry Andric   }
11140b57cec5SDimitry Andric   llvm_unreachable("Invalid mc version min type");
11150b57cec5SDimitry Andric }
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric /// parseVersionMin
11180b57cec5SDimitry Andric ///   ::= .ios_version_min parseVersion parseSDKVersion
11190b57cec5SDimitry Andric ///   |   .macosx_version_min parseVersion parseSDKVersion
11200b57cec5SDimitry Andric ///   |   .tvos_version_min parseVersion parseSDKVersion
11210b57cec5SDimitry Andric ///   |   .watchos_version_min parseVersion parseSDKVersion
11220b57cec5SDimitry Andric bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,
11230b57cec5SDimitry Andric                                       MCVersionMinType Type) {
11240b57cec5SDimitry Andric   unsigned Major;
11250b57cec5SDimitry Andric   unsigned Minor;
11260b57cec5SDimitry Andric   unsigned Update;
11270b57cec5SDimitry Andric   if (parseVersion(&Major, &Minor, &Update))
11280b57cec5SDimitry Andric     return true;
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric   VersionTuple SDKVersion;
11310b57cec5SDimitry Andric   if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
11320b57cec5SDimitry Andric     return true;
11330b57cec5SDimitry Andric 
11340b57cec5SDimitry Andric   if (parseToken(AsmToken::EndOfStatement))
11350b57cec5SDimitry Andric     return addErrorSuffix(Twine(" in '") + Directive + "' directive");
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric   Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);
11380b57cec5SDimitry Andric   checkVersion(Directive, StringRef(), Loc, ExpectedOS);
11395ffd83dbSDimitry Andric   getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion);
11400b57cec5SDimitry Andric   return false;
11410b57cec5SDimitry Andric }
11420b57cec5SDimitry Andric 
11430b57cec5SDimitry Andric static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {
11440b57cec5SDimitry Andric   switch (Type) {
11450b57cec5SDimitry Andric   case MachO::PLATFORM_MACOS:   return Triple::MacOSX;
11460b57cec5SDimitry Andric   case MachO::PLATFORM_IOS:     return Triple::IOS;
11470b57cec5SDimitry Andric   case MachO::PLATFORM_TVOS:    return Triple::TvOS;
11480b57cec5SDimitry Andric   case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;
11490b57cec5SDimitry Andric   case MachO::PLATFORM_BRIDGEOS:         /* silence warning */ break;
11500b57cec5SDimitry Andric   case MachO::PLATFORM_MACCATALYST: return Triple::IOS;
11510b57cec5SDimitry Andric   case MachO::PLATFORM_IOSSIMULATOR:     /* silence warning */ break;
11520b57cec5SDimitry Andric   case MachO::PLATFORM_TVOSSIMULATOR:    /* silence warning */ break;
11530b57cec5SDimitry Andric   case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;
1154e8d8bef9SDimitry Andric   case MachO::PLATFORM_DRIVERKIT:        /* silence warning */ break;
11550b57cec5SDimitry Andric   }
11560b57cec5SDimitry Andric   llvm_unreachable("Invalid mach-o platform type");
11570b57cec5SDimitry Andric }
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric /// parseBuildVersion
11600b57cec5SDimitry Andric ///   ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion
11610b57cec5SDimitry Andric bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {
11620b57cec5SDimitry Andric   StringRef PlatformName;
11630b57cec5SDimitry Andric   SMLoc PlatformLoc = getTok().getLoc();
11640b57cec5SDimitry Andric   if (getParser().parseIdentifier(PlatformName))
11650b57cec5SDimitry Andric     return TokError("platform name expected");
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric   unsigned Platform = StringSwitch<unsigned>(PlatformName)
11680b57cec5SDimitry Andric     .Case("macos", MachO::PLATFORM_MACOS)
11690b57cec5SDimitry Andric     .Case("ios", MachO::PLATFORM_IOS)
11700b57cec5SDimitry Andric     .Case("tvos", MachO::PLATFORM_TVOS)
11710b57cec5SDimitry Andric     .Case("watchos", MachO::PLATFORM_WATCHOS)
11720b57cec5SDimitry Andric     .Case("macCatalyst", MachO::PLATFORM_MACCATALYST)
11730b57cec5SDimitry Andric     .Default(0);
11740b57cec5SDimitry Andric   if (Platform == 0)
11750b57cec5SDimitry Andric     return Error(PlatformLoc, "unknown platform name");
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   if (getLexer().isNot(AsmToken::Comma))
11780b57cec5SDimitry Andric     return TokError("version number required, comma expected");
11790b57cec5SDimitry Andric   Lex();
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   unsigned Major;
11820b57cec5SDimitry Andric   unsigned Minor;
11830b57cec5SDimitry Andric   unsigned Update;
11840b57cec5SDimitry Andric   if (parseVersion(&Major, &Minor, &Update))
11850b57cec5SDimitry Andric     return true;
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric   VersionTuple SDKVersion;
11880b57cec5SDimitry Andric   if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))
11890b57cec5SDimitry Andric     return true;
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric   if (parseToken(AsmToken::EndOfStatement))
11920b57cec5SDimitry Andric     return addErrorSuffix(" in '.build_version' directive");
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric   Triple::OSType ExpectedOS
11950b57cec5SDimitry Andric     = getOSTypeFromPlatform((MachO::PlatformType)Platform);
11960b57cec5SDimitry Andric   checkVersion(Directive, PlatformName, Loc, ExpectedOS);
11975ffd83dbSDimitry Andric   getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
11980b57cec5SDimitry Andric   return false;
11990b57cec5SDimitry Andric }
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric namespace llvm {
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric MCAsmParserExtension *createDarwinAsmParser() {
12050b57cec5SDimitry Andric   return new DarwinAsmParser;
12060b57cec5SDimitry Andric }
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric } // end llvm namespace
1209