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

Generated by: LCOV version 1.13