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,