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