components/llvm/patches/020-21874221-clang-llvm-sparc-assembler.patch
author Stefan Teleman <stefan.teleman@oracle.com>
Wed, 10 Feb 2016 11:54:12 -0800
changeset 5434 9f55c805ce9d
permissions -rw-r--r--
PSARC/2013/188 Clang/LLVM 15777690 clang/llvm compiler infrastructure in Solaris 21851513 severe memory corruption in the LLVM command-line parsing module 22031298 toxic bugs in LLVM ilist/plist end up eliminating entire MachineBasicBlocks 22065707 LLVM SPARC assembler generator emits wrong ELF Section flags 22346218 LLVM's assembler printer on SPARC needs a lot of work 21870061 partial template specializations in CommandLine.h are buggy 21874261 the Google Test Harness doesn't know how to count threads in Solaris 21697459 memory corruption in LLVM IR Code Generator 21341968 llc on SPARC should not need to be passed -march=sparc or -march=sparcv9 21870103 TableGen makes incorrect assumptions about anonymous namespace instantiation 21870087 naming convention for the InputFile key is inconsistent across LLVM utilities 21870099 128 bytes for a filesystem path is definitely not enough 21870067 lli makes incorrect assumptions about anonymous namespace instantiation order 21870065 llc makes incorrect assumptions about anonymous namespace instantiation order 21870283 llvm::sys::Process::GetArgumentVector should overload for std::vector 21874221 clang C++ does not properly initialize the C++ Standard Library's iostreams

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