components/llvm/patches/020-21874221-clang-llvm-sparc-assembler.patch
author John Beck <John.Beck@Oracle.COM>
Thu, 21 Jul 2016 12:51:35 -0700
changeset 6445 0edecb568b2e
parent 5434 9f55c805ce9d
permissions -rw-r--r--
23858073 Upgrade Python 2.7 line to 2.7.12

# - 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,