components/llvm/patches/020-21874221-clang-llvm-sparc-assembler.patch
changeset 5434 9f55c805ce9d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/llvm/patches/020-21874221-clang-llvm-sparc-assembler.patch	Wed Feb 10 11:54:12 2016 -0800
@@ -0,0 +1,1274 @@
+# - https://llvm.org/bugs/show_bug.cgi?id=22623
+# - 22346218 - LLVM's assembler printer on SPARC needs a lot of work
+# - 21874221 - clang C++ does not properly initialize the C++
+# Standard Library's iostreams
+# - 22582382 - Sun ld .init_array/.fini_array handling is incompatible
+# with the GNU Toolchain
+# - 22065707 - LLVM SPARC assembler generator emits wrong ELF Section flags
+# For upstream - maybe.
+--- include/llvm/MC/MCStreamer.h	2014-12-05 18:14:41.000000000 -0800
++++ include/llvm/MC/MCStreamer.h	2015-12-09 15:14:25.413937273 -0800
+@@ -478,6 +478,13 @@
+   ///
+   virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+ 
++  /// EmitELFSize - Emit an ELF .size directive.
++  ///
++  /// This corresponds to an assembler statement such as:
++  ///  .size symbol, expression, but without a temp .label.
++  ///
++  virtual void EmitELFSize(StringRef Name);
++
+   /// \brief Emit a Linker Optimization Hint (LOH) directive.
+   /// \param Args - Arguments of the LOH.
+   virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
+--- include/llvm/MC/MCSymbol.h	2014-12-24 02:27:50.000000000 -0800
++++ include/llvm/MC/MCSymbol.h	2015-12-09 14:05:18.864224028 -0800
+@@ -51,23 +51,25 @@
+     /// IsTemporary - True if this is an assembler temporary label, which
+     /// typically does not survive in the .o file's symbol table.  Usually
+     /// "Lfoo" or ".foo".
+-    unsigned IsTemporary : 1;
++    bool IsTemporary;
+ 
+     /// \brief True if this symbol can be redefined.
+-    unsigned IsRedefinable : 1;
++    bool IsRedefinable;
+ 
+     /// IsUsed - True if this symbol has been used.
+-    mutable unsigned IsUsed : 1;
++    mutable bool IsUsed;
+ 
+-  private:  // MCContext creates and uniques these.
++  protected:  // MCContext creates and uniques these.
+     friend class MCExpr;
+     friend class MCContext;
++
+     MCSymbol(StringRef name, bool isTemporary)
+       : Name(name), Section(nullptr), Value(nullptr),
+-        IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {}
++      IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {}
+ 
+     MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
+     void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION;
++
+   public:
+     /// getName - Get the symbol name.
+     StringRef getName() const { return Name; }
+--- lib/MC/MCAsmStreamer.cpp	2015-01-14 03:23:27.000000000 -0800
++++ lib/MC/MCAsmStreamer.cpp	2015-12-09 15:14:32.728543403 -0800
+@@ -40,17 +40,18 @@
+ protected:
+   formatted_raw_ostream &OS;
+   const MCAsmInfo *MAI;
++
+ private:
+   std::unique_ptr<MCInstPrinter> InstPrinter;
+   std::unique_ptr<MCCodeEmitter> Emitter;
+   std::unique_ptr<MCAsmBackend> AsmBackend;
+ 
+-  SmallString<128> CommentToEmit;
++  SmallString<256> CommentToEmit;
+   raw_svector_ostream CommentStream;
+ 
+-  unsigned IsVerboseAsm : 1;
+-  unsigned ShowInst : 1;
+-  unsigned UseDwarfDirectory : 1;
++  bool IsVerboseAsm;
++  bool ShowInst;
++  bool UseDwarfDirectory;
+ 
+   void EmitRegisterName(int64_t Register);
+   void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+@@ -61,10 +62,10 @@
+                 bool isVerboseAsm, bool useDwarfDirectory,
+                 MCInstPrinter *printer, MCCodeEmitter *emitter,
+                 MCAsmBackend *asmbackend, bool showInst)
+-      : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
+-        InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
+-        CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
+-        ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
++    : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
++    InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
++    CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
++    ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) {
+     if (InstPrinter && IsVerboseAsm)
+       InstPrinter->setCommentStream(CommentStream);
+   }
+@@ -75,8 +76,10 @@
+       OS << '\n';
+       return;
+     }
++
+     EmitCommentsAndEOL();
+   }
++
+   void EmitCommentsAndEOL();
+ 
+   /// isVerboseAsm - Return true if this streamer supports verbose assembly at
+@@ -139,6 +142,7 @@
+   void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
+   void EmitCOFFSecRel32(MCSymbol const *Symbol) override;
+   void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
++  void EmitELFSize(StringRef Name) override;
+   void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                         unsigned ByteAlignment) override;
+ 
+@@ -501,6 +505,11 @@
+   OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
+ }
+ 
++void MCAsmStreamer::EmitELFSize(StringRef Name) {
++  assert(MAI->hasDotTypeDotSizeDirective());
++  OS << "\t.size\t" << Name << ", .-" << Name << '\n';
++}
++
+ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                                      unsigned ByteAlignment) {
+   // Common symbols do not belong to any actual section.
+@@ -843,7 +852,7 @@
+   if (NumFiles == Table.getMCDwarfFiles().size())
+     return FileNo;
+ 
+-  SmallString<128> FullPathName;
++  SmallString<PATH_MAX> FullPathName;
+ 
+   if (!UseDwarfDirectory && !Directory.empty()) {
+     if (sys::path::is_absolute(Filename))
+--- lib/MC/MCSectionELF.cpp	2014-10-09 14:23:39.000000000 -0700
++++ lib/MC/MCSectionELF.cpp	2016-01-21 10:12:17.006210825 -0800
+@@ -59,8 +59,10 @@
+                                         raw_ostream &OS,
+                                         const MCExpr *Subsection) const {
+ 
++  StringRef SectionName = getSectionName();
++
+   if (ShouldOmitSectionDirective(SectionName, MAI)) {
+-    OS << '\t' << getSectionName();
++    OS << '\t' << SectionName;
+     if (Subsection)
+       OS << '\t' << *Subsection;
+     OS << '\n';
+@@ -68,35 +70,20 @@
+   }
+ 
+   OS << "\t.section\t";
+-  printName(OS, getSectionName());
+-
+-  // Handle the weird solaris syntax if desired.
+-  if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
+-      !(Flags & ELF::SHF_MERGE)) {
+-    if (Flags & ELF::SHF_ALLOC)
+-      OS << ",#alloc";
+-    if (Flags & ELF::SHF_EXECINSTR)
+-      OS << ",#execinstr";
+-    if (Flags & ELF::SHF_WRITE)
+-      OS << ",#write";
+-    if (Flags & ELF::SHF_EXCLUDE)
+-      OS << ",#exclude";
+-    if (Flags & ELF::SHF_TLS)
+-      OS << ",#tls";
+-    OS << '\n';
+-    return;
+-  }
++  printName(OS, SectionName);
+ 
+   OS << ",\"";
+   if (Flags & ELF::SHF_ALLOC)
+     OS << 'a';
+   if (Flags & ELF::SHF_EXCLUDE)
+     OS << 'e';
+-  if (Flags & ELF::SHF_EXECINSTR)
++  if ((Flags & ELF::SHF_EXECINSTR) && (Type != ELF::SHT_INIT_ARRAY) &&
++      (Type != ELF::SHT_FINI_ARRAY) && (Type != ELF::SHT_PREINIT_ARRAY))
+     OS << 'x';
+   if (Flags & ELF::SHF_GROUP)
+     OS << 'G';
+-  if (Flags & ELF::SHF_WRITE)
++  if ((Flags & ELF::SHF_WRITE) || (Type == ELF::SHT_INIT_ARRAY) ||
++      (Type == ELF::SHT_FINI_ARRAY) || (Type == ELF::SHT_PREINIT_ARRAY))
+     OS << 'w';
+   if (Flags & ELF::SHF_MERGE)
+     OS << 'M';
+@@ -144,6 +131,7 @@
+     printName(OS, Group->getName());
+     OS << ",comdat";
+   }
++
+   OS << '\n';
+ 
+   if (Subsection)
+--- lib/MC/MCStreamer.cpp	2014-11-03 04:19:03.000000000 -0800
++++ lib/MC/MCStreamer.cpp	2015-12-09 15:15:14.428496845 -0800
+@@ -636,6 +636,7 @@
+ void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {}
+ void MCStreamer::EmitCOFFSymbolType(int Type) {}
+ void MCStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
++void MCStreamer::EmitELFSize(StringRef Name) {}
+ void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+                                        unsigned ByteAlignment) {}
+ void MCStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+--- tools/clang/lib/CodeGen/CGBlocks.cpp	2015-10-05 11:01:32.352334965 -0700
++++ tools/clang/lib/CodeGen/CGBlocks.cpp	2015-12-07 15:24:59.295683990 -0800
+@@ -1248,8 +1248,8 @@
+ 
+         DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointerDbgLoc,
+                                               Builder, blockInfo,
+-                                              entry_ptr == entry->end()
+-                                              ? nullptr : entry_ptr);
++                                              entry_ptr == entry->end() ?
++                                              nullptr : &*entry_ptr);
+       }
+     }
+     // Recover location if it was changed in the above loop.
+--- tools/clang/lib/CodeGen/CGCall.cpp	2015-10-05 11:01:32.348582888 -0700
++++ tools/clang/lib/CodeGen/CGCall.cpp	2015-12-07 15:26:25.691201743 -0800
+@@ -2230,7 +2230,7 @@
+     if (RetAI.getInAllocaSRet()) {
+       llvm::Function::arg_iterator EI = CurFn->arg_end();
+       --EI;
+-      llvm::Value *ArgStruct = EI;
++      llvm::Value *ArgStruct = &*EI;
+       llvm::Value *SRet =
+           Builder.CreateStructGEP(ArgStruct, RetAI.getInAllocaFieldIndex());
+       RV = Builder.CreateLoad(SRet, "sret");
+@@ -2246,7 +2246,7 @@
+       ComplexPairTy RT =
+         EmitLoadOfComplex(MakeNaturalAlignAddrLValue(ReturnValue, RetTy),
+                           EndLoc);
+-      EmitStoreOfComplex(RT, MakeNaturalAlignAddrLValue(AI, RetTy),
++      EmitStoreOfComplex(RT, MakeNaturalAlignAddrLValue(&*AI, RetTy),
+                          /*isInit*/ true);
+       break;
+     }
+@@ -2255,7 +2255,7 @@
+       break;
+     case TEK_Scalar:
+       EmitStoreOfScalar(Builder.CreateLoad(ReturnValue),
+-                        MakeNaturalAlignAddrLValue(AI, RetTy),
++                        MakeNaturalAlignAddrLValue(&*AI, RetTy),
+                         /*isInit*/ true);
+       break;
+     }
+--- tools/clang/lib/CodeGen/CGDeclCXX.cpp	2015-10-05 11:01:32.000000000 -0700
++++ tools/clang/lib/CodeGen/CGDeclCXX.cpp	2016-02-01 09:42:57.409779098 -0800
+@@ -23,6 +23,8 @@
+ using namespace clang;
+ using namespace CodeGen;
+ 
++static unsigned InitPriority = 128;
++
+ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
+                          llvm::Constant *DeclPtr) {
+   assert(D.hasGlobalStorage() && "VarDecl must have global storage!");
+@@ -137,9 +139,9 @@
+                                                bool PerformInit) {
+ 
+   const Expr *Init = D.getInit();
+-  QualType T = D.getType();
++  QualType QT = D.getType();
+ 
+-  if (!T->isReferenceType()) {
++  if (!QT->isReferenceType()) {
+     if (getLangOpts().OpenMP && D.hasAttr<OMPThreadPrivateDeclAttr>())
+       (void)CGM.getOpenMPRuntime().EmitOMPThreadPrivateVarDefinition(
+           &D, DeclPtr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
+@@ -157,7 +159,7 @@
+          "destruction for reference");
+   unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
+   RValue RV = EmitReferenceBindingToExpr(Init);
+-  EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T);
++  EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, QT);
+ }
+ 
+ /// Create a stub function, suitable for being passed to atexit,
+@@ -166,22 +168,25 @@
+                                                   llvm::Constant *dtor,
+                                                   llvm::Constant *addr) {
+   // Get the destructor function type, void(*)(void).
+-  llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);
+-  SmallString<256> FnName;
++  llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
++  SmallString<512> FnName;
+   {
+     llvm::raw_svector_ostream Out(FnName);
+     CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
+   }
+-  llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(ty, FnName.str(),
+-                                                              VD.getLocation());
++
++  llvm::Function *Fn =
++    CGM.CreateGlobalInitOrDestructFunction(FTy, FnName.str(),
++                                           VD.getLocation());
+ 
+   CodeGenFunction CGF(CGM);
+ 
+-  CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn,
+-                    CGM.getTypes().arrangeNullaryFunction(), FunctionArgList());
++  CGF.StartFunction(&VD, CGM.getContext().VoidTy, Fn,
++                    CGM.getTypes().arrangeNullaryFunction(),
++                    FunctionArgList());
+ 
+   llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
+- 
++
+  // Make sure the call and the callee agree on calling convention.
+   if (llvm::Function *dtorFn =
+         dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
+@@ -189,7 +194,7 @@
+ 
+   CGF.FinishFunction();
+ 
+-  return fn;
++  return Fn;
+ }
+ 
+ /// Register a global destructor using the C atexit runtime function.
+@@ -203,12 +208,12 @@
+   llvm::FunctionType *atexitTy =
+     llvm::FunctionType::get(IntTy, dtorStub->getType(), false);
+ 
+-  llvm::Constant *atexit =
++  llvm::Constant *atExit =
+     CGM.CreateRuntimeFunction(atexitTy, "atexit");
+-  if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
++  if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atExit))
+     atexitFn->setDoesNotThrow();
+ 
+-  EmitNounwindRuntimeCall(atexit, dtorStub);
++  EmitNounwindRuntimeCall(atExit, dtorStub);
+ }
+ 
+ void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
+@@ -225,15 +230,29 @@
+   CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
+ }
+ 
+-llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction(
+-    llvm::FunctionType *FTy, const Twine &Name, SourceLocation Loc, bool TLS) {
++llvm::Function*
++CodeGenModule::CreateGlobalInitOrDestructFunction(llvm::FunctionType *FTy,
++                                                  const Twine &Name,
++                                                  SourceLocation Loc,
++                                                  bool TLS) {
+   llvm::Function *Fn =
+     llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+                            Name, &getModule());
++
++  // Set the section if needed.
+   if (!getLangOpts().AppleKext && !TLS) {
+-    // Set the section if needed.
+-    if (const char *Section = getTarget().getStaticInitSectionSpecifier())
+-      Fn->setSection(Section);
++    if (const char *Section = getTarget().getStaticInitSectionSpecifier()) {
++      if (getTriple().getOS() == llvm::Triple::Solaris) {
++        std::string FNm = Fn->getName().str();
++        if ((FNm.find("_GLOBAL__sub_I_") != std::string::npos) &&
++            !CodeGenOpts.UseInitArray)
++          Fn->setSection(Section);
++        else
++          Fn->setSection(".text");
++      } else {
++        Fn->setSection(Section);
++      }
++    }
+   }
+ 
+   Fn->setCallingConv(getRuntimeCC());
+@@ -241,13 +260,16 @@
+   if (!getLangOpts().Exceptions)
+     Fn->setDoesNotThrow();
+ 
+-  if (!isInSanitizerBlacklist(Fn, Loc)) {
+-    if (getLangOpts().Sanitize.has(SanitizerKind::Address))
+-      Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+-    if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
+-      Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+-    if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
+-      Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
++  // Solaris does not yet support the Sanitizer Libraries.
++  if (getTriple().getOS() != llvm::Triple::Solaris) {
++    if (!isInSanitizerBlacklist(Fn, Loc)) {
++      if (getLangOpts().Sanitize.has(SanitizerKind::Address))
++        Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
++      if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
++        Fn->addFnAttr(llvm::Attribute::SanitizeThread);
++      if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
++        Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
++    }
+   }
+ 
+   return Fn;
+@@ -260,9 +282,21 @@
+                                           llvm::GlobalVariable *GV,
+                                           llvm::Function *InitFunc,
+                                           InitSegAttr *ISA) {
+-  llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(
+-      TheModule, InitFunc->getType(), /*isConstant=*/true,
+-      llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");
++  std::string GVN("__cxx_init_fn_ptr");
++  if (getTriple().getOS() == llvm::Triple::Solaris) {
++    GVN += "_";
++    GVN += std::to_string(InitPriority++);
++  }
++
++  llvm::GlobalVariable *PtrArray = nullptr;
++
++  PtrArray = new llvm::GlobalVariable(TheModule, InitFunc->getType(),
++                                      /*isConstant=*/ true,
++                                      llvm::GlobalValue::PrivateLinkage,
++                                      InitFunc, GVN);
++
++  assert(PtrArray && "Invalid Function Pointer Array!");
++
+   PtrArray->setSection(ISA->getSection());
+   addUsedGlobal(PtrArray);
+ 
+@@ -283,22 +317,76 @@
+ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
+                                             llvm::GlobalVariable *Addr,
+                                             bool PerformInit) {
+-  llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
++  llvm::FunctionType *FTy = nullptr;
++  std::vector<llvm::Type*> ArgsVec;
++
++  if (getTriple().getOS() == llvm::Triple::Solaris) {
++    ArgsVec.push_back(IntTy);
++    ArgsVec.push_back(IntTy);
++    FTy = llvm::FunctionType::get(VoidTy, ArgsVec, false);
++  } else {
++    FTy = llvm::FunctionType::get(VoidTy, false);
++  }
++
+   SmallString<256> FnName;
+   {
+     llvm::raw_svector_ostream Out(FnName);
+-    getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
++    if (getTriple().getOS() == llvm::Triple::Solaris)
++      getCXXABI().getMangleContext().mangleGCCDynamicInitializer(D, Out);
++    else
++      getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
+   }
+ 
+   // Create a variable initialization function.
+   llvm::Function *Fn =
+       CreateGlobalInitOrDestructFunction(FTy, FnName.str(), D->getLocation());
++  Fn->setDoesNotThrow();
+ 
+   auto *ISA = D->getAttr<InitSegAttr>();
+-  CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
+-                                                          PerformInit);
+ 
+-  llvm::GlobalVariable *COMDATKey =
++  if (getTriple().getOS() == llvm::Triple::Solaris) {
++    ASTContext &Ctx = getContext();
++    auto *IPA = D->getAttr<InitPriorityAttr>();
++    if (!IPA) {
++      IPA = InitPriorityAttr::CreateImplicit(Ctx, /* InitPriority */ 65535);
++      VarDecl *DD = const_cast<VarDecl*>(D);
++      DD->addAttr(IPA);
++    }
++
++    if (!ISA && CodeGenOpts.UseInitArray) {
++      ISA = InitSegAttr::CreateImplicit(Ctx, PerformInit ?
++                                        StringRef(".init_array") :
++                                        StringRef(".fini_array"));
++      VarDecl *DD = const_cast<VarDecl*>(D);
++      DD->addAttr(ISA);
++    }
++  }
++
++  FunctionArgList ArgList;
++  ASTContext &Ctx = getContext();
++  // We cannot allocate these dynamically because of a very ill-conceived
++  // operator new overload in DeclBase.h.
++  ImplicitParamDecl IAFirst(Ctx, /*DC=*/ nullptr, D->getLocation(),
++                            /*Id=*/ nullptr, Ctx.UnsignedIntTy);
++  ImplicitParamDecl IASecond(Ctx, /*DC=*/ nullptr, D->getLocation(),
++                             /*Id=*/ nullptr, Ctx.UnsignedIntTy);
++
++  if (getTriple().getOS() == llvm::Triple::Solaris) {
++    // Add Parameters to the Function ArgumentList on Solaris
++    // for compatibility with the GCC C++ Runtime.
++    ArgList.push_back(&IAFirst);
++    ArgList.push_back(&IASecond);
++  }
++
++  CodeGenFunction CGF(*this);
++  CGF.GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, PerformInit, ArgList);
++
++  llvm::GlobalVariable *COMDATKey;
++
++  if (getTriple().getOS() == llvm::Triple::Solaris)
++    COMDATKey = D->isExternallyVisible() ? Addr : nullptr;
++  else
++    COMDATKey =
+       supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr;
+ 
+   if (D->getTLSKind()) {
+@@ -370,7 +458,6 @@
+ 
+   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
+ 
+-
+   // Create our global initialization function.
+   if (!PrioritizedCXXGlobalInits.empty()) {
+     SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
+@@ -391,9 +478,10 @@
+       // sure the function names are also ordered as priorities.
+       std::string PrioritySuffix = llvm::utostr(Priority);
+       // Priority is always <= 65535 (enforced by sema).
+-      PrioritySuffix = std::string(6-PrioritySuffix.size(), '0')+PrioritySuffix;
+-      llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
+-          FTy, "_GLOBAL__I_" + PrioritySuffix);
++      PrioritySuffix =
++        std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix;
++      llvm::Function *Fn =
++        CreateGlobalInitOrDestructFunction(FTy, "_GLOBAL__I_" + PrioritySuffix);
+ 
+       for (; I < PrioE; ++I)
+         LocalCXXGlobalInits.push_back(I->second);
+@@ -403,7 +491,7 @@
+     }
+   }
+ 
+-  SmallString<128> FileName;
++  SmallString<PATH_MAX> FileName;
+   SourceManager &SM = Context.getSourceManager();
+   if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
+     // Include the filename in the symbol name. Including "sub_" matches gcc and
+@@ -417,14 +505,15 @@
+   for (size_t i = 0; i < FileName.size(); ++i) {
+     // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+     // to be the set of C preprocessing numbers.
+-    if (!isPreprocessingNumberBody(FileName[i]))
++    if (!isPreprocessingNumberBody(FileName[i]) || (FileName[i] == '.'))
+       FileName[i] = '_';
+   }
+ 
+   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
+       FTy, llvm::Twine("_GLOBAL__sub_I_", FileName));
+ 
+-  CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
++  CodeGenFunction CGF(*this);
++  CGF.GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
+   AddGlobalCtor(Fn);
+ 
+   CXXGlobalInits.clear();
+@@ -445,28 +534,43 @@
+ }
+ 
+ /// Emit the code necessary to initialize the given global variable.
+-void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
+-                                                       const VarDecl *D,
+-                                                 llvm::GlobalVariable *Addr,
+-                                                       bool PerformInit) {
++void
++CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
++                                                  const VarDecl *D,
++                                                  llvm::GlobalVariable *Addr,
++                                                  bool PerformInit,
++                                                  FunctionArgList ArgList) {
+   // Check if we need to emit debug info for variable initializer.
+   if (D->hasAttr<NoDebugAttr>())
+     DebugInfo = nullptr; // disable debug info indefinitely for this function
+ 
+   CurEHLocation = D->getLocStart();
++  ASTContext &Ctx = getContext();
+ 
+-  StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,
+-                getTypes().arrangeNullaryFunction(),
+-                FunctionArgList(), D->getLocation(),
++  FunctionType::ExtInfo ExtInfo;
++  const CGFunctionInfo &FuncInfo =
++    getTypes().arrangeFreeFunctionDeclaration(Ctx.VoidTy, ArgList,
++                                              ExtInfo, /*IsVariadic=*/ false);
++  GlobalDecl GD(D);
++
++  StartFunction(GD, Ctx.VoidTy, Fn, FuncInfo, ArgList, D->getLocation(),
+                 D->getInit()->getExprLoc());
+ 
+-  // Use guarded initialization if the global variable is weak. This
+-  // occurs for, e.g., instantiated static data members and
+-  // definitions explicitly marked weak.
+-  if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
+-    EmitCXXGuardedInit(*D, Addr, PerformInit);
++  if (CGM.getTriple().getOS() == llvm::Triple::Solaris) {
++    if (Addr->hasWeakLinkage()) {
++      EmitCXXGuardedInit(*D, Addr, PerformInit);
++    } else {
++      EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
++    }
+   } else {
+-    EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
++    // Use guarded initialization if the global variable is weak. This
++    // occurs for, e.g., instantiated static data members and
++    // definitions explicitly marked weak.
++    if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
++      EmitCXXGuardedInit(*D, Addr, PerformInit);
++    } else {
++      EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
++    }
+   }
+ 
+   FinishFunction();
+@@ -476,10 +580,21 @@
+ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
+                                            ArrayRef<llvm::Function *> Decls,
+                                            llvm::GlobalVariable *Guard) {
++  llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
++  ASTContext &Ctx = getContext();
++  llvm::LLVMContext &LLVMCtx = CGM.getLLVMContext();
++
+   {
+     ApplyDebugLocation NL(*this);
+-    StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
+-                  getTypes().arrangeNullaryFunction(), FunctionArgList());
++
++    FunctionArgList ArgList;
++    FunctionType::ExtInfo ExtInfo;
++    const CGFunctionInfo &FuncInfo =
++      getTypes().arrangeFreeFunctionDeclaration(Ctx.VoidTy, ArgList,
++                                                ExtInfo,
++                                                /*IsVariadic=*/ false);
++    StartFunction(GlobalDecl(), Ctx.VoidTy, Fn, FuncInfo, ArgList);
++
+     // Emit an artificial location for this function.
+     ArtificialLocation AL(*this);
+ 
+@@ -509,9 +624,27 @@
+       EmitObjCAutoreleasePoolCleanup(token);
+     }
+ 
+-    for (unsigned i = 0, e = Decls.size(); i != e; ++i)
+-      if (Decls[i])
+-        EmitRuntimeCall(Decls[i]);
++    for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
++      if (llvm::Function *FV = Decls[i]) {
++        if (CGM.getTriple().getOS() == llvm::Triple::Solaris) {
++          llvm::Value *Values[2] = { nullptr, nullptr };
++          Values[0] =
++            llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), 1);
++          Values[1] =
++            llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), 65535);
++          ArrayRef<llvm::Value*> ArgValues = llvm::makeArrayRef(Values);
++          llvm::CallInst *CI = EmitRuntimeCall(FV, ArgValues);
++#ifndef NDEBUG
++          llvm::Function *CIF = CI->getCalledFunction();
++          assert (CIF && "Invalid function returned in CallInst!");
++#else
++          (void) CI;
++#endif
++        } else {
++          EmitRuntimeCall(Decls[i]);
++        }
++      }
++    }
+ 
+     Scope.ForceCleanup();
+ 
+@@ -569,8 +702,8 @@
+   StartFunction(VD, getContext().VoidTy, fn, FI, args);
+ 
+   emitDestroy(addr, type, destroyer, useEHCleanupForArray);
+-  
++
+   FinishFunction();
+-  
++
+   return fn;
+ }
+--- tools/clang/lib/CodeGen/CGExprScalar.cpp	2015-10-05 11:01:32.351864633 -0700
++++ tools/clang/lib/CodeGen/CGExprScalar.cpp	2015-12-07 16:39:38.372167280 -0800
+@@ -2319,9 +2319,9 @@
+ 
+   // Branch in case of overflow.
+   llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
+-  llvm::Function::iterator insertPt = initialBB;
++  llvm::Function::iterator insertPt = initialBB->getIterator();
+   llvm::BasicBlock *continueBB = CGF.createBasicBlock("nooverflow", CGF.CurFn,
+-                                                      std::next(insertPt));
++                                                      &*std::next(insertPt));
+   llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
+ 
+   Builder.CreateCondBr(overflow, overflowBB, continueBB);
+--- tools/clang/lib/CodeGen/CGExpr.cpp	2015-10-05 11:01:32.356618553 -0700
++++ tools/clang/lib/CodeGen/CGExpr.cpp	2015-12-07 16:36:56.944848497 -0800
+@@ -64,7 +64,7 @@
+                                      llvm::Value *Init) {
+   auto *Store = new llvm::StoreInst(Init, Var);
+   llvm::BasicBlock *Block = AllocaInsertPt->getParent();
+-  Block->getInstList().insertAfter(&*AllocaInsertPt, Store);
++  Block->getInstList().insertAfter(AllocaInsertPt->getIterator(), Store);
+ }
+ 
+ llvm::AllocaInst *CodeGenFunction::CreateIRTemp(QualType Ty,
+--- tools/clang/lib/CodeGen/CGStmt.cpp	2015-10-05 11:01:32.627209320 -0700
++++ tools/clang/lib/CodeGen/CGStmt.cpp	2015-12-07 16:52:55.040873133 -0800
+@@ -329,7 +329,7 @@
+     return;
+ 
+   // Can only simplify empty blocks.
+-  if (BI != BB->begin())
++  if (BI->getIterator() != BB->begin())
+     return;
+ 
+   BB->replaceAllUsesWith(BI->getSuccessor(0));
+@@ -351,7 +351,7 @@
+   // Place the block after the current block, if possible, or else at
+   // the end of the function.
+   if (CurBB && CurBB->getParent())
+-    CurFn->getBasicBlockList().insertAfter(CurBB, BB);
++    CurFn->getBasicBlockList().insertAfter(CurBB->getIterator(), BB);
+   else
+     CurFn->getBasicBlockList().push_back(BB);
+   Builder.SetInsertPoint(BB);
+@@ -378,7 +378,8 @@
+   bool inserted = false;
+   for (llvm::User *u : block->users()) {
+     if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
+-      CurFn->getBasicBlockList().insertAfter(insn->getParent(), block);
++      CurFn->getBasicBlockList().insertAfter(insn->getParent()->getIterator(),
++                                             block);
+       inserted = true;
+       break;
+     }
+--- tools/clang/lib/CodeGen/CGVTables.cpp	2015-10-05 11:01:32.353244828 -0700
++++ tools/clang/lib/CodeGen/CGVTables.cpp	2015-12-07 17:11:22.736212205 -0800
+@@ -158,12 +158,16 @@
+   // Find the first store of "this", which will be to the alloca associated
+   // with "this".
+   llvm::Value *ThisPtr = &*AI;
+-  llvm::BasicBlock *EntryBB = Fn->begin();
++  llvm::BasicBlock *EntryBB = &Fn->front();
+   llvm::Instruction *ThisStore =
+-      std::find_if(EntryBB->begin(), EntryBB->end(), [&](llvm::Instruction &I) {
+-    return isa<llvm::StoreInst>(I) && I.getOperand(0) == ThisPtr;
+-  });
++      &*std::find_if(EntryBB->begin(), EntryBB->end(), [&](llvm::Instruction &I)
++                     {
++                     return isa<llvm::StoreInst>(I) &&
++                     I.getOperand(0) == ThisPtr;
++                     });
++
+   assert(ThisStore && "Store of this should be in entry block?");
++
+   // Adjust "this", if necessary.
+   Builder.SetInsertPoint(ThisStore);
+   llvm::Value *AdjustedThisPtr =
+--- tools/clang/lib/CodeGen/CodeGenFunction.cpp	2015-10-05 11:01:32.357401838 -0700
++++ tools/clang/lib/CodeGen/CodeGenFunction.cpp	2015-12-07 17:13:22.309802713 -0800
+@@ -672,14 +672,14 @@
+     auto AI = CurFn->arg_begin();
+     if (CurFnInfo->getReturnInfo().isSRetAfterThis())
+       ++AI;
+-    ReturnValue = AI;
++    ReturnValue = &*AI;
+   } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca &&
+              !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
+     // Load the sret pointer from the argument struct and return into that.
+     unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
+     llvm::Function::arg_iterator EI = CurFn->arg_end();
+     --EI;
+-    llvm::Value *Addr = Builder.CreateStructGEP(EI, Idx);
++    llvm::Value *Addr = Builder.CreateStructGEP(&*EI, Idx);
+     ReturnValue = Builder.CreateLoad(Addr, "agg.result");
+   } else {
+     ReturnValue = CreateIRTemp(RetTy, "retval");
+--- tools/clang/lib/CodeGen/CodeGenFunction.h	2015-10-05 11:01:32.347172460 -0700
++++ tools/clang/lib/CodeGen/CodeGenFunction.h	2015-10-14 18:25:20.000000000 -0700
+@@ -2572,10 +2572,11 @@
+   void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
+                                         const VarDecl *D,
+                                         llvm::GlobalVariable *Addr,
+-                                        bool PerformInit);
++                                        bool PerformInit,
++                                        FunctionArgList ArgList);
+ 
+   void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
+-  
++
+   void EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, llvm::Value *Src,
+                                   const Expr *Exp);
+ 
+--- tools/clang/lib/CodeGen/CodeGenModule.cpp	2015-10-05 11:01:32.354174460 -0700
++++ tools/clang/lib/CodeGen/CodeGenModule.cpp	2016-02-01 09:44:08.493171103 -0800
+@@ -228,7 +228,8 @@
+     OldF->replaceAllUsesWith(Replacement);
+     if (NewF) {
+       NewF->removeFromParent();
+-      OldF->getParent()->getFunctionList().insertAfter(OldF, NewF);
++      OldF->getParent()->getFunctionList().insertAfter(OldF->getIterator(),
++                                                       NewF);
+     }
+     OldF->eraseFromParent();
+   }
+@@ -272,8 +273,16 @@
+       Error = true;
+       Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
+     } else if (GV->isDeclaration()) {
+-      Error = true;
+-      Diags.Report(AA->getLocation(), diag::err_alias_to_undefined);
++      clang::Linkage L = D->getFormalLinkage();
++      const auto *FD = cast<FunctionDecl>(D);
++
++      if (!FD && ((L != clang::ExternalLinkage) &&
++                  (L != clang::UniqueExternalLinkage) &&
++                  (L != clang::InternalLinkage) &&
++                  (L != clang::VisibleNoLinkage))) {
++        Error = true;
++        Diags.Report(AA->getLocation(), diag::err_alias_to_undefined);
++      }
+     }
+ 
+     llvm::Constant *Aliasee = Alias->getAliasee();
+@@ -1310,10 +1319,7 @@
+ 
+ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
+   const auto *Global = cast<ValueDecl>(GD.getDecl());
+-
+-  // Weak references don't produce any output by themselves.
+-  if (Global->hasAttr<WeakRefAttr>())
+-    return;
++  assert(Global && "Cast to ValueDecl yields nullptr!");
+ 
+   // If this is an alias definition (which otherwise looks like a declaration)
+   // emit it now.
+@@ -1485,16 +1491,11 @@
+ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
+   const auto *D = cast<ValueDecl>(GD.getDecl());
+ 
+-  PrettyStackTraceDecl CrashInfo(const_cast<ValueDecl *>(D), D->getLocation(), 
++  PrettyStackTraceDecl CrashInfo(const_cast<ValueDecl *>(D), D->getLocation(),
+                                  Context.getSourceManager(),
+                                  "Generating code for declaration");
+-  
+-  if (isa<FunctionDecl>(D)) {
+-    // At -O0, don't generate IR for functions with available_externally 
+-    // linkage.
+-    if (!shouldEmitFunction(GD))
+-      return;
+ 
++  if (isa<FunctionDecl>(D)) {
+     if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) {
+       CompleteDIClassType(Method);
+       // Make sure to emit the definition(s) before we emit the thunks.
+@@ -1512,13 +1513,18 @@
+       return;
+     }
+ 
+-    return EmitGlobalFunctionDefinition(GD, GV);
++    EmitGlobalFunctionDefinition(GD, GV);
++    return;
++  }
++
++  if (const auto *VD = dyn_cast<VarDecl>(D)) {
++    EmitGlobalVarDefinition(VD);
++    return;
+   }
+ 
+-  if (const auto *VD = dyn_cast<VarDecl>(D))
+-    return EmitGlobalVarDefinition(VD);
+-  
+-  llvm_unreachable("Invalid argument to EmitGlobalDefinition()");
++  llvm::errs() << __PRETTY_FUNCTION__
++    << ": Invalid argument to EmitGlobalDefinition()!\n";
++  return;
+ }
+ 
+ /// GetOrCreateLLVMFunction - If the specified mangled name is not in the
+--- tools/clang/lib/CodeGen/CodeGenModule.h	2015-10-05 11:01:32.344046428 -0700
++++ tools/clang/lib/CodeGen/CodeGenModule.h	2015-10-20 21:11:16.000000000 -0700
+@@ -692,7 +692,8 @@
+                                     llvm::GlobalValue::LinkageTypes Linkage);
+ 
+   llvm::Function *
+-  CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name,
++  CreateGlobalInitOrDestructFunction(llvm::FunctionType *FTy,
++                                     const Twine &Name,
+                                      SourceLocation Loc = SourceLocation(),
+                                      bool TLS = false);
+ 
+--- tools/clang/lib/CodeGen/CodeGenPGO.cpp	2015-10-05 11:01:32.349650190 -0700
++++ tools/clang/lib/CodeGen/CodeGenPGO.cpp	2015-12-08 07:11:06.067357170 -0800
+@@ -788,8 +788,10 @@
+ void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
+   if (!CGM.getCodeGenOpts().ProfileInstrGenerate || !RegionCounterMap)
+     return;
+-  if (!Builder.GetInsertPoint())
++
++  if (!Builder.GetInsertBlock())
+     return;
++
+   auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+   Builder.CreateCall4(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
+                       llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
+--- tools/clang/lib/Driver/ToolChains.cpp	2016-02-01 14:47:49.483365583 -0800
++++ tools/clang/lib/Driver/ToolChains.cpp	2016-02-01 09:12:57.596182227 -0800
+@@ -2918,6 +2918,11 @@
+   const llvm::Triple& TT = getTriple();
+   llvm::Triple::ArchType Arch = TT.getArch();
+ 
++  if (Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array)) {
++    CC1Args.push_back("-fuse-init-array");
++    DriverArgs.ClaimAllArgs(options::OPT_fuse_init_array);
++  }
++
+   if (Arg *A = DriverArgs.getLastArg(options::OPT_mtune_EQ)) {
+     StringRef V = A->getValue();
+     if (!V.empty())
+--- tools/clang/lib/Driver/ToolChains.cpp	2016-02-01 18:49:01.325382261 -0800
++++ tools/clang/lib/Driver/ToolChains.cpp	2016-02-01 19:59:25.420298464 -0800
+@@ -3012,13 +3012,22 @@
+ 
+ void Solaris::findGCCMajorMinorMicro(const llvm::Triple& T) const {
+   // FIXME: Add 5.2.0 after testing the ABI.
+-  static const char* const GCCMMM[] = { "4.8.2", "4.8.5", "4.9.3" };
++  static const char* const GCCMMM[] = { "4.8.2", "4.9.3", "4.9.4" };
+ 
+   const char* P;
+   std::string Path;
+   std::string TripleString = llvm::sys::getDefaultTargetTriple();
+   llvm::Triple::ArchType Arch = T.getArch();
+ 
++  // GCC4 on Solaris is multilib 32/64.
++  // GCC5 (not supported here yet) on Solaris is multilib 64/32.
++  if (GCCMajorMinor[0] == '4') {
++    if (TripleString.find("x86_64") != std::string::npos)
++      TripleString.replace(0U, 6U, std::string("i386"));
++    else if (TripleString.find("sparcv9") != std::string::npos)
++      TripleString.replace(0U, 7U, std::string("sparc"));
++  }
++
+   if (UseMediatedGCCToolChainPath) {
+     // FIXME: IMPLEMENT.
+     // Needs spec.
+--- tools/clang/lib/Driver/Tools.cpp	2015-10-12 22:12:01.440488058 -0700
++++ tools/clang/lib/Driver/Tools.cpp	2016-02-01 10:32:24.767483623 -0800
+@@ -45,6 +45,10 @@
+ using namespace clang;
+ using namespace llvm::opt;
+ 
++#if defined(LLVM_ON_UNIX)
++#include <sys/utsname.h>
++#endif
++
+ static void addAssemblerKPIC(const ArgList &Args, ArgStringList &CmdArgs) {
+   Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+                                     options::OPT_fpic, options::OPT_fno_pic,
+@@ -4595,8 +4599,10 @@
+   // nice to enable this when doing a crashdump for modules as well.
+   if (Args.hasFlag(options::OPT_frewrite_includes,
+                    options::OPT_fno_rewrite_includes, false) ||
+-      (C.isForDiagnostics() && !HaveModules))
+-    CmdArgs.push_back("-frewrite-includes");
++      (C.isForDiagnostics() && !HaveModules)) {
++    if (getToolChain().getTriple().getOS() != llvm::Triple::Solaris)
++      CmdArgs.push_back("-frewrite-includes");
++  }
+ 
+   // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
+   if (Arg *A = Args.getLastArg(options::OPT_traditional,
+@@ -6379,6 +6385,8 @@
+ 
+   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+                        options::OPT_Xassembler);
++  Args.ClaimAllArgs(options::OPT_Wa_COMMA);
++  Args.ClaimAllArgs(options::OPT_Xassembler);
+ 
+   for (const auto &II : Inputs) {
+     if (II.getType() == types::TY_LLVM_IR ||
+@@ -6517,6 +6525,11 @@
+   ArgStringList CmdArgs;
+ 
+   CmdArgs.push_back(Args.MakeArgString("-zignore"));
++  CmdArgs.push_back(Args.MakeArgString("-zrelax=common"));
++  CmdArgs.push_back(Args.MakeArgString("-zrelax=secadj"));
++  CmdArgs.push_back(Args.MakeArgString("-zrelax=transtls"));
++  if (D.CCCIsCXX())
++    CmdArgs.push_back(Args.MakeArgString("-zrelax=comdat"));
+ 
+   Arg *PIEArg = Args.getLastArg(options::OPT_fPIE, options::OPT_fpie);
+   if (PIEArg) {
+@@ -6527,7 +6540,7 @@
+       CmdArgs.push_back(Args.MakeArgString("-ztextwarn"));
+       CmdArgs.push_back(Args.MakeArgString("-ztype=pie"));
+       CmdArgs.push_back(Args.MakeArgString("-zaslr=enable"));
+-  }
++    }
+   }
+ 
+   // Silence warning for "-g: argument not used during compilation
+@@ -6656,10 +6669,21 @@
+   if (!Args.hasArg(options::OPT_nostdlib) &&
+       !Args.hasArg(options::OPT_nostartfiles)) {
+     if (!Args.hasArg(options::OPT_shared)) {
++      std::string UNM = "5.12";
++
++#if defined(LLVM_ON_UNIX) // Because Windows?
++      struct utsname UTS;
++      if (::uname(&UTS) == 0)
++        UNM = UTS.version;
++#endif
++
+       switch (Arch) {
+       case llvm::Triple::sparc:
+       case llvm::Triple::sparcv9:
+-        crt1o = GCCLibPath;
++        if (UNM == "5.12")
++          crt1o = LibPath;
++        else
++          crt1o = GCCLibPath;
+         break;
+       case llvm::Triple::x86:
+       case llvm::Triple::x86_64:
+@@ -6754,7 +6778,8 @@
+           CXAFinalize = *B + "/cxa_finalize.o";
+         }
+ 
+-        if (llvm::sys::fs::exists(CXAFinalize.c_str()))
++        HasSystemCXAFinalize = llvm::sys::fs::exists(CXAFinalize.c_str());
++        if (D.CCCIsCXX() && HasSystemCXAFinalize)
+           CmdArgs.push_back(Args.MakeArgString(CXAFinalize.c_str()));
+       }
+     }
+@@ -6784,8 +6809,10 @@
+   // Itanium C++ ABI.
+   if (D.CCCIsCXX()) {
+     if (!Args.hasArg(options::OPT_shared)) {
+-      const char* zfiniarray = "-zfiniarray=__cxa_finalize";
+-      CmdArgs.push_back(Args.MakeArgString(zfiniarray));
++      if (HasSystemCXAFinalize) {
++        const char* zfiniarray = "-zfiniarray=__cxa_finalize";
++        CmdArgs.push_back(Args.MakeArgString(zfiniarray));
++      }
+     }
+   }
+ 
+@@ -6843,6 +6870,9 @@
+ 
+   addProfileRT(TC, Args, CmdArgs);
+ 
++  Args.ClaimAllArgs(options::OPT_Wl_COMMA);
++  Args.ClaimAllArgs(options::OPT_Xlinker);
++
+   C.addCommand(llvm::make_unique<Command>(JA, *this,
+                                           Args.MakeArgString(Linker),
+                                           CmdArgs));
+--- tools/clang/lib/Basic/Targets.cpp	2015-10-27 10:02:43.744975392 -0700
++++ tools/clang/lib/Basic/Targets.cpp	2016-02-01 08:33:09.756656790 -0800
+@@ -537,6 +537,10 @@
+     Builder.defineMacro("__ELF__");
+     Builder.defineMacro("__svr4__");
+     Builder.defineMacro("__SVR4");
++    Builder.defineMacro("__SunOS", "1");
++
++    if (Opts.CPlusPlus || Opts.CPlusPlus11 || Opts.CPlusPlus14)
++      Builder.defineMacro("__GTHREADS", "1");
+ 
+     if (Opts.C99 || Opts.CPlusPlus11) {
+       if (Opts.C99) {
+@@ -549,39 +553,51 @@
+       Builder.defineMacro("__C99FEATURES__", "1");
+     }
+ 
+-    if (Opts.CPlusPlus11)
+-      Builder.defineMacro("__cplusplus", "201103L");
+-    else if (Opts.CPlusPlus14)
+-      Builder.defineMacro("__cplusplus", "201402L");
++    if (Opts.CPlusPlus11 || Opts.CPlusPlus14) {
++      Builder.defineMacro("__STDCPP_STRICT_POINTER_SAFETY__", "1");
++      Builder.defineMacro("__STDCPP_THREADS__", "1");
++    }
+ 
+     if (Opts.CPlusPlus11) {
+-      Builder.defineMacro("_STDC_C11", "1");
++      Builder.defineMacro("__STDC_ISO_10646__", "201011L");
++      Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
+       Builder.defineMacro("_STDC_C11_BCI", "1");
+       Builder.defineMacro("__XPG7_THREAD_MODEL__", "1");
+       Builder.defineMacro("_XPG7", "1");
+       Builder.defineMacro("_XOPEN_SOURCE", "700");
+     } else if (Opts.C11 || Opts.CPlusPlus14) {
++      Builder.defineMacro("__STDC_HOSTED__", "1");
+       Builder.defineMacro("__STDC_VERSION__", "201112L");
+       Builder.defineMacro("_STDC_C11", "1");
+       Builder.defineMacro("_STDC_C11_BCI", "1");
++      Builder.defineMacro("__STDC_ISO_10646__", "201011L");
++      Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
++      Builder.defineMacro("__STDC_LIB_EXT1__", "201112L");
++      Builder.defineMacro("__STDC_UTF_16__", "1");
++      Builder.defineMacro("__STDC_UTF_32__", "1");
+       Builder.defineMacro("__XPG7_THREAD_MODEL__", "1");
++
++      if (Opts.C11) {
++        Builder.defineMacro("__STDC_ANALYZABLE", "1");
++        Builder.defineMacro("__STDC_IEC_559__", "1");
++        Builder.defineMacro("__STDC_IEC_559_COMPLEX__", "1");
++      }
++
+       Builder.defineMacro("_XPG7", "1");
+       Builder.defineMacro("_XOPEN_SOURCE", "700");
+     } else {
+       Builder.defineMacro("_XOPEN_SOURCE", "500");
+       Builder.defineMacro("__STDC_VERSION__", "199409L");
+-      if (Opts.CPlusPlus && !Opts.CPlusPlus11 && !Opts.CPlusPlus14)
+-        Builder.defineMacro("__cplusplus", "199711L");
+     }
+ 
+     if ((Triple.getArchName() == "i386") || (Triple.getArchName() == "sparc"))
+     Builder.defineMacro("_LARGEFILE_SOURCE");
+     else if ((Triple.getArchName() == "x86_64") ||
+              (Triple.getArchName() == "sparcv9"))
+-    Builder.defineMacro("_LARGEFILE64_SOURCE");
++      Builder.defineMacro("_LARGEFILE64_SOURCE", "1");
+ 
+     Builder.defineMacro("__EXTENSIONS__", "1");
+-    Builder.defineMacro("_REENTRANT");
++    Builder.defineMacro("_REENTRANT", "1");
+   }
+ 
+ public:
+@@ -590,6 +606,10 @@
+     this->WCharType = this->SignedInt;
+     // FIXME: WIntType should be SignedLong
+   }
++
++  virtual const char *getStaticInitSectionSpecifier() const override {
++    return ".init";
++  }
+ };
+ 
+ // Windows target
+--- tools/clang/include/clang/AST/Mangle.h	2014-09-16 08:18:21.000000000 -0700
++++ tools/clang/include/clang/AST/Mangle.h	2015-10-21 08:10:11.000000000 -0700
+@@ -129,6 +129,8 @@
+ 
+   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
+ 
++  virtual void mangleGCCDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
++
+   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
+                                              raw_ostream &) = 0;
+ 
+--- tools/clang/lib/AST/ItaniumMangle.cpp	2015-10-05 11:01:32.264807353 -0700
++++ tools/clang/lib/AST/ItaniumMangle.cpp	2016-01-22 19:21:46.574349928 -0800
+@@ -154,6 +154,7 @@
+   void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &) override;
+   void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) override;
+   void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
++  void mangleGCCDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
+   void mangleDynamicAtExitDestructor(const VarDecl *D,
+                                      raw_ostream &Out) override;
+   void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &) override;
+@@ -3834,6 +3835,17 @@
+   Out << "__cxx_global_var_init";
+ }
+ 
++void ItaniumMangleContextImpl::mangleGCCDynamicInitializer(const VarDecl *MD,
++                                                           raw_ostream &Out) {
++  static unsigned SEQ = 0UL;
++
++  // Mangle GCC's __static_initialiation_and_destruction_<X>
++  // .init_array function.
++  Out << "_Z41" << "__static_initialization_and_destruction_"
++    << SEQ << "ii";
++  ++SEQ;
++}
++
+ void ItaniumMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
+                                                              raw_ostream &Out) {
+   // Prefix the mangling of D with __dtor_.
+--- tools/clang/lib/AST/MicrosoftMangle.cpp	2014-12-21 22:24:49.000000000 -0800
++++ tools/clang/lib/AST/MicrosoftMangle.cpp	2015-10-21 08:12:50.000000000 -0700
+@@ -132,6 +132,7 @@
+                                 raw_ostream &) override;
+   void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
+   void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
++  void mangleGCCDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
+   void mangleDynamicAtExitDestructor(const VarDecl *D,
+                                      raw_ostream &Out) override;
+   void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
+@@ -2407,6 +2408,11 @@
+   mangleInitFiniStub(D, Out, 'E');
+ }
+ 
++void MicrosoftMangleContextImpl::mangleGCCDynamicInitializer(const VarDecl *D,
++                                                             raw_ostream &Out) {
++  mangleDynamicInitializer(D, Out);
++}
++
+ void
+ MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
+                                                           raw_ostream &Out) {
+--- tools/clang/lib/Frontend/InitPreprocessor.cpp	2016-02-02 07:35:41.701519177 -0800
++++ tools/clang/lib/Frontend/InitPreprocessor.cpp	2016-02-02 08:45:58.127181898 -0800
+@@ -476,9 +476,16 @@
+   if (!LangOpts.MSVCCompat) {
+     // Currently claim to be compatible with GCC 4.2.1-5621, but only if we're
+     // not compiling for MSVC compatibility
++    if (TI.getTriple().getOS() == llvm::Triple::Solaris) {
++      Builder.defineMacro("__GNUC_MINOR__", "8");
++      Builder.defineMacro("__GNUC_PATCHLEVEL__", "0");
++    } else {
+     Builder.defineMacro("__GNUC_MINOR__", "2");
+     Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
++    }
++
+     Builder.defineMacro("__GNUC__", "4");
++
+     // GCC provides a number of C++ ABI Versions in:
+     // ${top_srcdir}/gcc/c-family/c-cppbuiltin.c
+     // Currently valid GXX ABI Versions are documented here:
+--- tools/clang/lib/Driver/ToolChains.cpp	2016-02-02 07:35:42.102842090 -0800
++++ tools/clang/lib/Driver/ToolChains.cpp	2016-02-02 09:01:01.559630875 -0800
+@@ -2923,6 +2923,11 @@
+     DriverArgs.ClaimAllArgs(options::OPT_fuse_init_array);
+   }
+ 
++  if (DriverArgs.getLastArg(options::OPT_fabi_version_EQ) == nullptr)
++    CC1Args.push_back("-fabi-version=4");
++  else
++    DriverArgs.ClaimAllArgs(options::OPT_fabi_version_EQ);
++
+   if (Arg *A = DriverArgs.getLastArg(options::OPT_mtune_EQ)) {
+     StringRef V = A->getValue();
+     if (!V.empty())
+@@ -2931,7 +2936,7 @@
+     // FIXME: Impplement SPARC target features.
+     CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+     if (Arch == llvm::Triple::sparc || Arch == llvm::Triple::sparcv9) {
+-      std::string S = "mtune=";
++      std::string S = "-mtune=";
+       S += mtune;
+       CC1Args.push_back(DriverArgs.MakeArgString(S.c_str()));
+     } else {
+@@ -2947,7 +2952,7 @@
+     CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+ 
+     if ((Arch == llvm::Triple::sparc) || (Arch == llvm::Triple::sparcv9)) {
+-      std::string S = "march=";
++      std::string S = "-march=";
+       S += mtune;
+       CC1Args.push_back(DriverArgs.MakeArgString(S.c_str()));
+     } else {
+@@ -2965,7 +2970,7 @@
+     }
+ 
+     CC1Args.push_back(DriverArgs.MakeArgString("-target-feature"));
+-    std::string S = "mcpu=";
++    std::string S = "-mcpu=";
+     S += mcpu;
+     CC1Args.push_back(DriverArgs.MakeArgString(S.c_str()));
+ 
+--- tools/clang/lib/Driver/Tools.cpp	2016-02-02 07:35:42.107579301 -0800
++++ tools/clang/lib/Driver/Tools.cpp	2016-02-02 09:00:08.889301970 -0800
+@@ -3000,6 +3000,8 @@
+     StringRef v = A->getValue();
+     CmdArgs.push_back(Args.MakeArgString("-fabi-version=" + v));
+     A->claim();
++  } else {
++    CmdArgs.push_back(Args.MakeArgString("-fabi-version=4"));
+   }
+ 
+   if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,