LLVM API Documentation

DarwinAsmParser.cpp
Go to the documentation of this file.
00001 //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
00011 #include "llvm/ADT/StringRef.h"
00012 #include "llvm/ADT/StringSwitch.h"
00013 #include "llvm/ADT/Twine.h"
00014 #include "llvm/MC/MCContext.h"
00015 #include "llvm/MC/MCParser/MCAsmLexer.h"
00016 #include "llvm/MC/MCParser/MCAsmParser.h"
00017 #include "llvm/MC/MCSectionMachO.h"
00018 #include "llvm/MC/MCStreamer.h"
00019 #include "llvm/MC/MCSymbol.h"
00020 #include "llvm/Support/FileSystem.h"
00021 #include "llvm/Support/MemoryBuffer.h"
00022 #include "llvm/Support/SourceMgr.h"
00023 using namespace llvm;
00024 
00025 namespace {
00026 
00027 /// \brief Implementation of directive handling which is shared across all
00028 /// Darwin targets.
00029 class DarwinAsmParser : public MCAsmParserExtension {
00030   template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
00031   void addDirectiveHandler(StringRef Directive) {
00032     MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
00033         this, HandleDirective<DarwinAsmParser, HandlerMethod>);
00034     getParser().addDirectiveHandler(Directive, Handler);
00035   }
00036 
00037   bool parseSectionSwitch(const char *Segment, const char *Section,
00038                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
00039                           unsigned StubSize = 0);
00040 
00041 public:
00042   DarwinAsmParser() {}
00043 
00044   void Initialize(MCAsmParser &Parser) override {
00045     // Call the base implementation.
00046     this->MCAsmParserExtension::Initialize(Parser);
00047 
00048     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
00049     addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
00050       ".indirect_symbol");
00051     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
00052     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
00053       ".subsections_via_symbols");
00054     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
00055     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
00056     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
00057     addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
00058       ".pushsection");
00059     addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
00060       ".popsection");
00061     addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
00062     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
00063       ".secure_log_unique");
00064     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
00065       ".secure_log_reset");
00066     addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
00067     addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
00068 
00069     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
00070       ".data_region");
00071     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
00072       ".end_data_region");
00073 
00074     // Special section directives.
00075     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
00076     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
00077     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
00078       ".const_data");
00079     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
00080       ".constructor");
00081     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
00082       ".cstring");
00083     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
00084     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
00085       ".destructor");
00086     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
00087     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
00088       ".fvmlib_init0");
00089     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
00090       ".fvmlib_init1");
00091     addDirectiveHandler<
00092       &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
00093         ".lazy_symbol_pointer");
00094     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
00095       ".linker_option");
00096     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
00097       ".literal16");
00098     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
00099       ".literal4");
00100     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
00101       ".literal8");
00102     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
00103       ".mod_init_func");
00104     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
00105       ".mod_term_func");
00106     addDirectiveHandler<
00107       &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
00108         ".non_lazy_symbol_pointer");
00109     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
00110       ".objc_cat_cls_meth");
00111     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
00112       ".objc_cat_inst_meth");
00113     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
00114       ".objc_category");
00115     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
00116       ".objc_class");
00117     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
00118       ".objc_class_names");
00119     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
00120       ".objc_class_vars");
00121     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
00122       ".objc_cls_meth");
00123     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
00124       ".objc_cls_refs");
00125     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
00126       ".objc_inst_meth");
00127     addDirectiveHandler<
00128       &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
00129         ".objc_instance_vars");
00130     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
00131       ".objc_message_refs");
00132     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
00133       ".objc_meta_class");
00134     addDirectiveHandler<
00135       &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
00136         ".objc_meth_var_names");
00137     addDirectiveHandler<
00138       &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
00139         ".objc_meth_var_types");
00140     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
00141       ".objc_module_info");
00142     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
00143       ".objc_protocol");
00144     addDirectiveHandler<
00145       &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
00146         ".objc_selector_strs");
00147     addDirectiveHandler<
00148       &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
00149         ".objc_string_object");
00150     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
00151       ".objc_symbols");
00152     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
00153       ".picsymbol_stub");
00154     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
00155       ".static_const");
00156     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
00157       ".static_data");
00158     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
00159       ".symbol_stub");
00160     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
00161     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
00162     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
00163       ".thread_init_func");
00164     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
00165 
00166     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
00167     addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
00168     addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
00169       ".macosx_version_min");
00170   }
00171 
00172   bool parseDirectiveDesc(StringRef, SMLoc);
00173   bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
00174   bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
00175   bool parseDirectiveLsym(StringRef, SMLoc);
00176   bool parseDirectiveLinkerOption(StringRef, SMLoc);
00177   bool parseDirectiveSection(StringRef, SMLoc);
00178   bool parseDirectivePushSection(StringRef, SMLoc);
00179   bool parseDirectivePopSection(StringRef, SMLoc);
00180   bool parseDirectivePrevious(StringRef, SMLoc);
00181   bool parseDirectiveSecureLogReset(StringRef, SMLoc);
00182   bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
00183   bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
00184   bool parseDirectiveTBSS(StringRef, SMLoc);
00185   bool parseDirectiveZerofill(StringRef, SMLoc);
00186   bool parseDirectiveDataRegion(StringRef, SMLoc);
00187   bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
00188 
00189   // Named Section Directive
00190   bool parseSectionDirectiveBss(StringRef, SMLoc) {
00191     return parseSectionSwitch("__DATA", "__bss");
00192   }
00193 
00194   bool parseSectionDirectiveConst(StringRef, SMLoc) {
00195     return parseSectionSwitch("__TEXT", "__const");
00196   }
00197   bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
00198     return parseSectionSwitch("__TEXT", "__static_const");
00199   }
00200   bool parseSectionDirectiveCString(StringRef, SMLoc) {
00201     return parseSectionSwitch("__TEXT","__cstring",
00202                               MachO::S_CSTRING_LITERALS);
00203   }
00204   bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
00205     return parseSectionSwitch("__TEXT", "__literal4",
00206                               MachO::S_4BYTE_LITERALS, 4);
00207   }
00208   bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
00209     return parseSectionSwitch("__TEXT", "__literal8",
00210                               MachO::S_8BYTE_LITERALS, 8);
00211   }
00212   bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
00213     return parseSectionSwitch("__TEXT","__literal16",
00214                               MachO::S_16BYTE_LITERALS, 16);
00215   }
00216   bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
00217     return parseSectionSwitch("__TEXT","__constructor");
00218   }
00219   bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
00220     return parseSectionSwitch("__TEXT","__destructor");
00221   }
00222   bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
00223     return parseSectionSwitch("__TEXT","__fvmlib_init0");
00224   }
00225   bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
00226     return parseSectionSwitch("__TEXT","__fvmlib_init1");
00227   }
00228   bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
00229     return parseSectionSwitch("__TEXT","__symbol_stub",
00230                               MachO::S_SYMBOL_STUBS |
00231                               MachO::S_ATTR_PURE_INSTRUCTIONS,
00232                               // FIXME: Different on PPC and ARM.
00233                               0, 16);
00234   }
00235   bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
00236     return parseSectionSwitch("__TEXT","__picsymbol_stub",
00237                               MachO::S_SYMBOL_STUBS |
00238                               MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
00239   }
00240   bool parseSectionDirectiveData(StringRef, SMLoc) {
00241     return parseSectionSwitch("__DATA", "__data");
00242   }
00243   bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
00244     return parseSectionSwitch("__DATA", "__static_data");
00245   }
00246   bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
00247     return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
00248                               MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
00249   }
00250   bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
00251     return parseSectionSwitch("__DATA", "__la_symbol_ptr",
00252                               MachO::S_LAZY_SYMBOL_POINTERS, 4);
00253   }
00254   bool parseSectionDirectiveDyld(StringRef, SMLoc) {
00255     return parseSectionSwitch("__DATA", "__dyld");
00256   }
00257   bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
00258     return parseSectionSwitch("__DATA", "__mod_init_func",
00259                               MachO::S_MOD_INIT_FUNC_POINTERS, 4);
00260   }
00261   bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
00262     return parseSectionSwitch("__DATA", "__mod_term_func",
00263                               MachO::S_MOD_TERM_FUNC_POINTERS, 4);
00264   }
00265   bool parseSectionDirectiveConstData(StringRef, SMLoc) {
00266     return parseSectionSwitch("__DATA", "__const");
00267   }
00268   bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
00269     return parseSectionSwitch("__OBJC", "__class",
00270                               MachO::S_ATTR_NO_DEAD_STRIP);
00271   }
00272   bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
00273     return parseSectionSwitch("__OBJC", "__meta_class",
00274                               MachO::S_ATTR_NO_DEAD_STRIP);
00275   }
00276   bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
00277     return parseSectionSwitch("__OBJC", "__cat_cls_meth",
00278                               MachO::S_ATTR_NO_DEAD_STRIP);
00279   }
00280   bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
00281     return parseSectionSwitch("__OBJC", "__cat_inst_meth",
00282                               MachO::S_ATTR_NO_DEAD_STRIP);
00283   }
00284   bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
00285     return parseSectionSwitch("__OBJC", "__protocol",
00286                               MachO::S_ATTR_NO_DEAD_STRIP);
00287   }
00288   bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
00289     return parseSectionSwitch("__OBJC", "__string_object",
00290                               MachO::S_ATTR_NO_DEAD_STRIP);
00291   }
00292   bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
00293     return parseSectionSwitch("__OBJC", "__cls_meth",
00294                               MachO::S_ATTR_NO_DEAD_STRIP);
00295   }
00296   bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
00297     return parseSectionSwitch("__OBJC", "__inst_meth",
00298                               MachO::S_ATTR_NO_DEAD_STRIP);
00299   }
00300   bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
00301     return parseSectionSwitch("__OBJC", "__cls_refs",
00302                               MachO::S_ATTR_NO_DEAD_STRIP |
00303                               MachO::S_LITERAL_POINTERS, 4);
00304   }
00305   bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
00306     return parseSectionSwitch("__OBJC", "__message_refs",
00307                               MachO::S_ATTR_NO_DEAD_STRIP |
00308                               MachO::S_LITERAL_POINTERS, 4);
00309   }
00310   bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
00311     return parseSectionSwitch("__OBJC", "__symbols",
00312                               MachO::S_ATTR_NO_DEAD_STRIP);
00313   }
00314   bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
00315     return parseSectionSwitch("__OBJC", "__category",
00316                               MachO::S_ATTR_NO_DEAD_STRIP);
00317   }
00318   bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
00319     return parseSectionSwitch("__OBJC", "__class_vars",
00320                               MachO::S_ATTR_NO_DEAD_STRIP);
00321   }
00322   bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
00323     return parseSectionSwitch("__OBJC", "__instance_vars",
00324                               MachO::S_ATTR_NO_DEAD_STRIP);
00325   }
00326   bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
00327     return parseSectionSwitch("__OBJC", "__module_info",
00328                               MachO::S_ATTR_NO_DEAD_STRIP);
00329   }
00330   bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
00331     return parseSectionSwitch("__TEXT", "__cstring",
00332                               MachO::S_CSTRING_LITERALS);
00333   }
00334   bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
00335     return parseSectionSwitch("__TEXT", "__cstring",
00336                               MachO::S_CSTRING_LITERALS);
00337   }
00338   bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
00339     return parseSectionSwitch("__TEXT", "__cstring",
00340                               MachO::S_CSTRING_LITERALS);
00341   }
00342   bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
00343     return parseSectionSwitch("__OBJC", "__selector_strs",
00344                               MachO::S_CSTRING_LITERALS);
00345   }
00346   bool parseSectionDirectiveTData(StringRef, SMLoc) {
00347     return parseSectionSwitch("__DATA", "__thread_data",
00348                               MachO::S_THREAD_LOCAL_REGULAR);
00349   }
00350   bool parseSectionDirectiveText(StringRef, SMLoc) {
00351     return parseSectionSwitch("__TEXT", "__text",
00352                               MachO::S_ATTR_PURE_INSTRUCTIONS);
00353   }
00354   bool parseSectionDirectiveTLV(StringRef, SMLoc) {
00355     return parseSectionSwitch("__DATA", "__thread_vars",
00356                               MachO::S_THREAD_LOCAL_VARIABLES);
00357   }
00358   bool parseSectionDirectiveIdent(StringRef, SMLoc) {
00359     // Darwin silently ignores the .ident directive.
00360     getParser().eatToEndOfStatement();
00361     return false;
00362   }
00363   bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
00364     return parseSectionSwitch("__DATA", "__thread_init",
00365                          MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
00366   }
00367   bool parseVersionMin(StringRef, SMLoc);
00368 
00369 };
00370 
00371 } // end anonymous namespace
00372 
00373 bool DarwinAsmParser::parseSectionSwitch(const char *Segment,
00374                                          const char *Section,
00375                                          unsigned TAA, unsigned Align,
00376                                          unsigned StubSize) {
00377   if (getLexer().isNot(AsmToken::EndOfStatement))
00378     return TokError("unexpected token in section switching directive");
00379   Lex();
00380 
00381   // FIXME: Arch specific.
00382   bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
00383   getStreamer().SwitchSection(getContext().getMachOSection(
00384                                 Segment, Section, TAA, StubSize,
00385                                 isText ? SectionKind::getText()
00386                                        : SectionKind::getDataRel()));
00387 
00388   // Set the implicit alignment, if any.
00389   //
00390   // FIXME: This isn't really what 'as' does; I think it just uses the implicit
00391   // alignment on the section (e.g., if one manually inserts bytes into the
00392   // section, then just issuing the section switch directive will not realign
00393   // the section. However, this is arguably more reasonable behavior, and there
00394   // is no good reason for someone to intentionally emit incorrectly sized
00395   // values into the implicitly aligned sections.
00396   if (Align)
00397     getStreamer().EmitValueToAlignment(Align);
00398 
00399   return false;
00400 }
00401 
00402 /// parseDirectiveDesc
00403 ///  ::= .desc identifier , expression
00404 bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
00405   StringRef Name;
00406   if (getParser().parseIdentifier(Name))
00407     return TokError("expected identifier in directive");
00408 
00409   // Handle the identifier as the key symbol.
00410   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
00411 
00412   if (getLexer().isNot(AsmToken::Comma))
00413     return TokError("unexpected token in '.desc' directive");
00414   Lex();
00415 
00416   int64_t DescValue;
00417   if (getParser().parseAbsoluteExpression(DescValue))
00418     return true;
00419 
00420   if (getLexer().isNot(AsmToken::EndOfStatement))
00421     return TokError("unexpected token in '.desc' directive");
00422 
00423   Lex();
00424 
00425   // Set the n_desc field of this Symbol to this DescValue
00426   getStreamer().EmitSymbolDesc(Sym, DescValue);
00427 
00428   return false;
00429 }
00430 
00431 /// parseDirectiveIndirectSymbol
00432 ///  ::= .indirect_symbol identifier
00433 bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
00434   const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
00435                                        getStreamer().getCurrentSection().first);
00436   MachO::SectionType SectionType = Current->getType();
00437   if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
00438       SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
00439       SectionType != MachO::S_SYMBOL_STUBS)
00440     return Error(Loc, "indirect symbol not in a symbol pointer or stub "
00441                       "section");
00442 
00443   StringRef Name;
00444   if (getParser().parseIdentifier(Name))
00445     return TokError("expected identifier in .indirect_symbol directive");
00446 
00447   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
00448 
00449   // Assembler local symbols don't make any sense here. Complain loudly.
00450   if (Sym->isTemporary())
00451     return TokError("non-local symbol required in directive");
00452 
00453   if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
00454     return TokError("unable to emit indirect symbol attribute for: " + Name);
00455 
00456   if (getLexer().isNot(AsmToken::EndOfStatement))
00457     return TokError("unexpected token in '.indirect_symbol' directive");
00458 
00459   Lex();
00460 
00461   return false;
00462 }
00463 
00464 /// parseDirectiveDumpOrLoad
00465 ///  ::= ( .dump | .load ) "filename"
00466 bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
00467                                                SMLoc IDLoc) {
00468   bool IsDump = Directive == ".dump";
00469   if (getLexer().isNot(AsmToken::String))
00470     return TokError("expected string in '.dump' or '.load' directive");
00471 
00472   Lex();
00473 
00474   if (getLexer().isNot(AsmToken::EndOfStatement))
00475     return TokError("unexpected token in '.dump' or '.load' directive");
00476 
00477   Lex();
00478 
00479   // FIXME: If/when .dump and .load are implemented they will be done in the
00480   // the assembly parser and not have any need for an MCStreamer API.
00481   if (IsDump)
00482     return Warning(IDLoc, "ignoring directive .dump for now");
00483   else
00484     return Warning(IDLoc, "ignoring directive .load for now");
00485 }
00486 
00487 /// ParseDirectiveLinkerOption
00488 ///  ::= .linker_option "string" ( , "string" )*
00489 bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
00490   SmallVector<std::string, 4> Args;
00491   for (;;) {
00492     if (getLexer().isNot(AsmToken::String))
00493       return TokError("expected string in '" + Twine(IDVal) + "' directive");
00494 
00495     std::string Data;
00496     if (getParser().parseEscapedString(Data))
00497       return true;
00498 
00499     Args.push_back(Data);
00500 
00501     Lex();
00502     if (getLexer().is(AsmToken::EndOfStatement))
00503       break;
00504 
00505     if (getLexer().isNot(AsmToken::Comma))
00506       return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
00507     Lex();
00508   }
00509 
00510   getStreamer().EmitLinkerOptions(Args);
00511   return false;
00512 }
00513 
00514 /// parseDirectiveLsym
00515 ///  ::= .lsym identifier , expression
00516 bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
00517   StringRef Name;
00518   if (getParser().parseIdentifier(Name))
00519     return TokError("expected identifier in directive");
00520 
00521   // Handle the identifier as the key symbol.
00522   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
00523 
00524   if (getLexer().isNot(AsmToken::Comma))
00525     return TokError("unexpected token in '.lsym' directive");
00526   Lex();
00527 
00528   const MCExpr *Value;
00529   if (getParser().parseExpression(Value))
00530     return true;
00531 
00532   if (getLexer().isNot(AsmToken::EndOfStatement))
00533     return TokError("unexpected token in '.lsym' directive");
00534 
00535   Lex();
00536 
00537   // We don't currently support this directive.
00538   //
00539   // FIXME: Diagnostic location!
00540   (void) Sym;
00541   return TokError("directive '.lsym' is unsupported");
00542 }
00543 
00544 /// parseDirectiveSection:
00545 ///   ::= .section identifier (',' identifier)*
00546 bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
00547   SMLoc Loc = getLexer().getLoc();
00548 
00549   StringRef SectionName;
00550   if (getParser().parseIdentifier(SectionName))
00551     return Error(Loc, "expected identifier after '.section' directive");
00552 
00553   // Verify there is a following comma.
00554   if (!getLexer().is(AsmToken::Comma))
00555     return TokError("unexpected token in '.section' directive");
00556 
00557   std::string SectionSpec = SectionName;
00558   SectionSpec += ",";
00559 
00560   // Add all the tokens until the end of the line, ParseSectionSpecifier will
00561   // handle this.
00562   StringRef EOL = getLexer().LexUntilEndOfStatement();
00563   SectionSpec.append(EOL.begin(), EOL.end());
00564 
00565   Lex();
00566   if (getLexer().isNot(AsmToken::EndOfStatement))
00567     return TokError("unexpected token in '.section' directive");
00568   Lex();
00569 
00570 
00571   StringRef Segment, Section;
00572   unsigned StubSize;
00573   unsigned TAA;
00574   bool TAAParsed;
00575   std::string ErrorStr =
00576     MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
00577                                           TAA, TAAParsed, StubSize);
00578 
00579   if (!ErrorStr.empty())
00580     return Error(Loc, ErrorStr.c_str());
00581 
00582   // FIXME: Arch specific.
00583   bool isText = Segment == "__TEXT";  // FIXME: Hack.
00584   getStreamer().SwitchSection(getContext().getMachOSection(
00585                                 Segment, Section, TAA, StubSize,
00586                                 isText ? SectionKind::getText()
00587                                 : SectionKind::getDataRel()));
00588   return false;
00589 }
00590 
00591 /// ParseDirectivePushSection:
00592 ///   ::= .pushsection identifier (',' identifier)*
00593 bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
00594   getStreamer().PushSection();
00595 
00596   if (parseDirectiveSection(S, Loc)) {
00597     getStreamer().PopSection();
00598     return true;
00599   }
00600 
00601   return false;
00602 }
00603 
00604 /// ParseDirectivePopSection:
00605 ///   ::= .popsection
00606 bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
00607   if (!getStreamer().PopSection())
00608     return TokError(".popsection without corresponding .pushsection");
00609   return false;
00610 }
00611 
00612 /// ParseDirectivePrevious:
00613 ///   ::= .previous
00614 bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
00615   MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
00616   if (!PreviousSection.first)
00617     return TokError(".previous without corresponding .section");
00618   getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
00619   return false;
00620 }
00621 
00622 /// ParseDirectiveSecureLogUnique
00623 ///  ::= .secure_log_unique ... message ...
00624 bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
00625   StringRef LogMessage = getParser().parseStringToEndOfStatement();
00626   if (getLexer().isNot(AsmToken::EndOfStatement))
00627     return TokError("unexpected token in '.secure_log_unique' directive");
00628 
00629   if (getContext().getSecureLogUsed() != false)
00630     return Error(IDLoc, ".secure_log_unique specified multiple times");
00631 
00632   // Get the secure log path.
00633   const char *SecureLogFile = getContext().getSecureLogFile();
00634   if (!SecureLogFile)
00635     return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
00636                  "environment variable unset.");
00637 
00638   // Open the secure log file if we haven't already.
00639   raw_ostream *OS = getContext().getSecureLog();
00640   if (!OS) {
00641     std::error_code EC;
00642     OS = new raw_fd_ostream(SecureLogFile, EC,
00643                             sys::fs::F_Append | sys::fs::F_Text);
00644     if (EC) {
00645        delete OS;
00646        return Error(IDLoc, Twine("can't open secure log file: ") +
00647                                SecureLogFile + " (" + EC.message() + ")");
00648     }
00649     getContext().setSecureLog(OS);
00650   }
00651 
00652   // Write the message.
00653   unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
00654   *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
00655       << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
00656       << LogMessage + "\n";
00657 
00658   getContext().setSecureLogUsed(true);
00659 
00660   return false;
00661 }
00662 
00663 /// ParseDirectiveSecureLogReset
00664 ///  ::= .secure_log_reset
00665 bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
00666   if (getLexer().isNot(AsmToken::EndOfStatement))
00667     return TokError("unexpected token in '.secure_log_reset' directive");
00668 
00669   Lex();
00670 
00671   getContext().setSecureLogUsed(false);
00672 
00673   return false;
00674 }
00675 
00676 /// parseDirectiveSubsectionsViaSymbols
00677 ///  ::= .subsections_via_symbols
00678 bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
00679   if (getLexer().isNot(AsmToken::EndOfStatement))
00680     return TokError("unexpected token in '.subsections_via_symbols' directive");
00681 
00682   Lex();
00683 
00684   getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
00685 
00686   return false;
00687 }
00688 
00689 /// ParseDirectiveTBSS
00690 ///  ::= .tbss identifier, size, align
00691 bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
00692   SMLoc IDLoc = getLexer().getLoc();
00693   StringRef Name;
00694   if (getParser().parseIdentifier(Name))
00695     return TokError("expected identifier in directive");
00696 
00697   // Handle the identifier as the key symbol.
00698   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
00699 
00700   if (getLexer().isNot(AsmToken::Comma))
00701     return TokError("unexpected token in directive");
00702   Lex();
00703 
00704   int64_t Size;
00705   SMLoc SizeLoc = getLexer().getLoc();
00706   if (getParser().parseAbsoluteExpression(Size))
00707     return true;
00708 
00709   int64_t Pow2Alignment = 0;
00710   SMLoc Pow2AlignmentLoc;
00711   if (getLexer().is(AsmToken::Comma)) {
00712     Lex();
00713     Pow2AlignmentLoc = getLexer().getLoc();
00714     if (getParser().parseAbsoluteExpression(Pow2Alignment))
00715       return true;
00716   }
00717 
00718   if (getLexer().isNot(AsmToken::EndOfStatement))
00719     return TokError("unexpected token in '.tbss' directive");
00720 
00721   Lex();
00722 
00723   if (Size < 0)
00724     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
00725                  "zero");
00726 
00727   // FIXME: Diagnose overflow.
00728   if (Pow2Alignment < 0)
00729     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
00730                  "than zero");
00731 
00732   if (!Sym->isUndefined())
00733     return Error(IDLoc, "invalid symbol redefinition");
00734 
00735   getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
00736                                  "__DATA", "__thread_bss",
00737                                  MachO::S_THREAD_LOCAL_ZEROFILL,
00738                                  0, SectionKind::getThreadBSS()),
00739                                Sym, Size, 1 << Pow2Alignment);
00740 
00741   return false;
00742 }
00743 
00744 /// ParseDirectiveZerofill
00745 ///  ::= .zerofill segname , sectname [, identifier , size_expression [
00746 ///      , align_expression ]]
00747 bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
00748   StringRef Segment;
00749   if (getParser().parseIdentifier(Segment))
00750     return TokError("expected segment name after '.zerofill' directive");
00751 
00752   if (getLexer().isNot(AsmToken::Comma))
00753     return TokError("unexpected token in directive");
00754   Lex();
00755 
00756   StringRef Section;
00757   if (getParser().parseIdentifier(Section))
00758     return TokError("expected section name after comma in '.zerofill' "
00759                     "directive");
00760 
00761   // If this is the end of the line all that was wanted was to create the
00762   // the section but with no symbol.
00763   if (getLexer().is(AsmToken::EndOfStatement)) {
00764     // Create the zerofill section but no symbol
00765     getStreamer().EmitZerofill(getContext().getMachOSection(
00766                                  Segment, Section, MachO::S_ZEROFILL,
00767                                  0, SectionKind::getBSS()));
00768     return false;
00769   }
00770 
00771   if (getLexer().isNot(AsmToken::Comma))
00772     return TokError("unexpected token in directive");
00773   Lex();
00774 
00775   SMLoc IDLoc = getLexer().getLoc();
00776   StringRef IDStr;
00777   if (getParser().parseIdentifier(IDStr))
00778     return TokError("expected identifier in directive");
00779 
00780   // handle the identifier as the key symbol.
00781   MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
00782 
00783   if (getLexer().isNot(AsmToken::Comma))
00784     return TokError("unexpected token in directive");
00785   Lex();
00786 
00787   int64_t Size;
00788   SMLoc SizeLoc = getLexer().getLoc();
00789   if (getParser().parseAbsoluteExpression(Size))
00790     return true;
00791 
00792   int64_t Pow2Alignment = 0;
00793   SMLoc Pow2AlignmentLoc;
00794   if (getLexer().is(AsmToken::Comma)) {
00795     Lex();
00796     Pow2AlignmentLoc = getLexer().getLoc();
00797     if (getParser().parseAbsoluteExpression(Pow2Alignment))
00798       return true;
00799   }
00800 
00801   if (getLexer().isNot(AsmToken::EndOfStatement))
00802     return TokError("unexpected token in '.zerofill' directive");
00803 
00804   Lex();
00805 
00806   if (Size < 0)
00807     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
00808                  "than zero");
00809 
00810   // NOTE: The alignment in the directive is a power of 2 value, the assembler
00811   // may internally end up wanting an alignment in bytes.
00812   // FIXME: Diagnose overflow.
00813   if (Pow2Alignment < 0)
00814     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
00815                  "can't be less than zero");
00816 
00817   if (!Sym->isUndefined())
00818     return Error(IDLoc, "invalid symbol redefinition");
00819 
00820   // Create the zerofill Symbol with Size and Pow2Alignment
00821   //
00822   // FIXME: Arch specific.
00823   getStreamer().EmitZerofill(getContext().getMachOSection(
00824                                Segment, Section, MachO::S_ZEROFILL,
00825                                0, SectionKind::getBSS()),
00826                              Sym, Size, 1 << Pow2Alignment);
00827 
00828   return false;
00829 }
00830 
00831 /// ParseDirectiveDataRegion
00832 ///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
00833 bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
00834   if (getLexer().is(AsmToken::EndOfStatement)) {
00835     Lex();
00836     getStreamer().EmitDataRegion(MCDR_DataRegion);
00837     return false;
00838   }
00839   StringRef RegionType;
00840   SMLoc Loc = getParser().getTok().getLoc();
00841   if (getParser().parseIdentifier(RegionType))
00842     return TokError("expected region type after '.data_region' directive");
00843   int Kind = StringSwitch<int>(RegionType)
00844     .Case("jt8", MCDR_DataRegionJT8)
00845     .Case("jt16", MCDR_DataRegionJT16)
00846     .Case("jt32", MCDR_DataRegionJT32)
00847     .Default(-1);
00848   if (Kind == -1)
00849     return Error(Loc, "unknown region type in '.data_region' directive");
00850   Lex();
00851 
00852   getStreamer().EmitDataRegion((MCDataRegionType)Kind);
00853   return false;
00854 }
00855 
00856 /// ParseDirectiveDataRegionEnd
00857 ///  ::= .end_data_region
00858 bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
00859   if (getLexer().isNot(AsmToken::EndOfStatement))
00860     return TokError("unexpected token in '.end_data_region' directive");
00861 
00862   Lex();
00863   getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
00864   return false;
00865 }
00866 
00867 /// parseVersionMin
00868 ///  ::= .ios_version_min major,minor[,update]
00869 ///  ::= .macosx_version_min major,minor[,update]
00870 bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
00871   int64_t Major = 0, Minor = 0, Update = 0;
00872   int Kind = StringSwitch<int>(Directive)
00873     .Case(".ios_version_min", MCVM_IOSVersionMin)
00874     .Case(".macosx_version_min", MCVM_OSXVersionMin);
00875   // Get the major version number.
00876   if (getLexer().isNot(AsmToken::Integer))
00877     return TokError("invalid OS major version number");
00878   Major = getLexer().getTok().getIntVal();
00879   if (Major > 65535 || Major <= 0)
00880     return TokError("invalid OS major version number");
00881   Lex();
00882   if (getLexer().isNot(AsmToken::Comma))
00883     return TokError("minor OS version number required, comma expected");
00884   Lex();
00885   // Get the minor version number.
00886   if (getLexer().isNot(AsmToken::Integer))
00887     return TokError("invalid OS minor version number");
00888   Minor = getLexer().getTok().getIntVal();
00889   if (Minor > 255 || Minor < 0)
00890     return TokError("invalid OS minor version number");
00891   Lex();
00892   // Get the update level, if specified
00893   if (getLexer().isNot(AsmToken::EndOfStatement)) {
00894     if (getLexer().isNot(AsmToken::Comma))
00895       return TokError("invalid update specifier, comma expected");
00896     Lex();
00897     if (getLexer().isNot(AsmToken::Integer))
00898       return TokError("invalid OS update number");
00899     Update = getLexer().getTok().getIntVal();
00900   if (Update > 255 || Update < 0)
00901     return TokError("invalid OS update number");
00902     Lex();
00903   }
00904 
00905   // We've parsed a correct version specifier, so send it to the streamer.
00906   getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
00907 
00908   return false;
00909 }
00910 
00911 namespace llvm {
00912 
00913 MCAsmParserExtension *createDarwinAsmParser() {
00914   return new DarwinAsmParser;
00915 }
00916 
00917 } // end llvm namespace