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