LCOV - code coverage report
Current view: top level - lib/MC/MCParser - DarwinAsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 344 420 81.9 %
Date: 2018-07-13 00:08:38 Functions: 64 71 90.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13