summaryrefslogtreecommitdiff
path: root/devel/llvm60/files/clang
diff options
context:
space:
mode:
Diffstat (limited to 'devel/llvm60/files/clang')
-rw-r--r--devel/llvm60/files/clang/patch-fformat_extensions.diff44
-rw-r--r--devel/llvm60/files/clang/patch-fopenmp.diff14
-rw-r--r--devel/llvm60/files/clang/patch-head-r331066.diff40
-rw-r--r--devel/llvm60/files/clang/patch-head-r336227.diff42
-rw-r--r--devel/llvm60/files/clang/patch-head-r338697.diff104
-rw-r--r--devel/llvm60/files/clang/patch-head-r339019.diff30
-rw-r--r--devel/llvm60/files/clang/patch-stable12-r342281.diff834
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt32
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py14
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py11
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format32
-rw-r--r--devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer12
12 files changed, 1209 insertions, 0 deletions
diff --git a/devel/llvm60/files/clang/patch-fformat_extensions.diff b/devel/llvm60/files/clang/patch-fformat_extensions.diff
new file mode 100644
index 000000000000..69093d923b6f
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-fformat_extensions.diff
@@ -0,0 +1,44 @@
+diff -ruN tools/clang/include/clang/Basic/LangOptions.def tools/clang/include/clang/Basic/LangOptions.def
+--- tools/clang/include/clang/Basic/LangOptions.def 2015-07-30 22:47:41 UTC
++++ tools/clang/include/clang/Basic/LangOptions.def
+@@ -114,6 +114,7 @@
+ LANGOPT(RTTIData , 1, 1, "emit run-time type information data")
+ LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout")
+ LANGOPT(Freestanding, 1, 0, "freestanding implementation")
++LANGOPT(FormatExtensions , 1, 0, "FreeBSD format extensions")
+ LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
+ LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
+ LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
+diff -ruN tools/clang/include/clang/Driver/Options.td tools/clang/include/clang/Driver/Options.td
+--- tools/clang/include/clang/Driver/Options.td 2015-07-30 22:47:41 UTC
++++ tools/clang/include/clang/Driver/Options.td
+@@ -644,6 +644,8 @@
+
+ def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Assert that the compilation takes place in a freestanding environment">;
++def fformat_extensions: Flag<["-"], "fformat-extensions">, Group<f_Group>, Flags<[CC1Option]>,
++ HelpText<"Enable FreeBSD kernel specific format string extensions">;
+ def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Allow GNU-extension keywords regardless of language standard">;
+ def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>,
+--- tools/clang/lib/Driver/ToolChains/Clang.cpp.orig 2017-09-14 19:36:28.212240000 +0100
++++ tools/clang/lib/Driver/ToolChains/Clang.cpp 2017-09-14 19:35:59.296165000 +0100
+@@ -3202,6 +3202,7 @@
+
+ // Forward -f (flag) options which we can pass directly.
+ Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
++ Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
+ Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
+ Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
+ // Emulated TLS is enabled by default on Android and OpenBSD, and can be enabled
+diff -ruN tools/clang/lib/Frontend/CompilerInvocation.cpp tools/clang/lib/Frontend/CompilerInvocation.cpp
+--- tools/clang/lib/Frontend/CompilerInvocation.cpp 2015-07-30 22:47:41 UTC
++++ tools/clang/lib/Frontend/CompilerInvocation.cpp
+@@ -1543,6 +1543,7 @@
+ Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false);
+ Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
+ Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
++ Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions);
+ Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+ Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
+ Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
diff --git a/devel/llvm60/files/clang/patch-fopenmp.diff b/devel/llvm60/files/clang/patch-fopenmp.diff
new file mode 100644
index 000000000000..18932bd0d19c
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-fopenmp.diff
@@ -0,0 +1,14 @@
+--- tools/clang/lib/Driver/ToolChains/CommonArgs.cpp.orig 2017-05-10 17:18:56.000000000 +0000
++++ tools/clang/lib/Driver/ToolChains/CommonArgs.cpp 2017-05-10 23:01:17.087686000 +0000
+@@ -441,7 +441,10 @@
+
+ switch (TC.getDriver().getOpenMPRuntime(Args)) {
+ case Driver::OMPRT_OMP:
+- CmdArgs.push_back("-lomp");
++ if (TC.getTriple().getOS() != llvm::Triple::FreeBSD || TC.isCrossCompiling() || !llvm::sys::fs::exists("%%LLVM_PREFIX%%/lib/libomp.so"))
++ CmdArgs.push_back("-lomp");
++ else
++ CmdArgs.push_back("%%LLVM_PREFIX%%/lib/libomp.so");
+ break;
+ case Driver::OMPRT_GOMP:
+ CmdArgs.push_back("-lgomp");
diff --git a/devel/llvm60/files/clang/patch-head-r331066.diff b/devel/llvm60/files/clang/patch-head-r331066.diff
new file mode 100644
index 000000000000..7296a087bfb0
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r331066.diff
@@ -0,0 +1,40 @@
+r331066 | dim | 2018-03-16 19:04:13 +0100 (Fri, 16 Mar 2018) | 19 lines
+
+Pull in r321999 from upstream clang trunk (by Ivan A. Kosarev):
+
+ [CodeGen] Fix TBAA info for accesses to members of base classes
+
+ Resolves:
+ Bug 35724 - regression (r315984): fatal error: error in backend:
+ Broken function found (Did not see access type in access path!)
+ https://bugs.llvm.org/show_bug.cgi?id=35724
+
+ Differential Revision: https://reviews.llvm.org/D41547
+
+This fixes "Did not see access type in access path" fatal errors when
+building the devel/gdb port (version 8.1).
+
+Reported by: jbeich
+PR: 226658
+MFC after: 3 months
+X-MFC-With: r327952
+
+Index: tools/clang/lib/CodeGen/CGExpr.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CGExpr.cpp (revision 331065)
++++ tools/clang/lib/CodeGen/CGExpr.cpp (revision 331066)
+@@ -1034,8 +1034,12 @@ Address CodeGenFunction::EmitPointerWithAlignment(
+ // Derived-to-base conversions.
+ case CK_UncheckedDerivedToBase:
+ case CK_DerivedToBase: {
+- Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo,
+- TBAAInfo);
++ // TODO: Support accesses to members of base classes in TBAA. For now, we
++ // conservatively pretend that the complete object is of the base class
++ // type.
++ if (TBAAInfo)
++ *TBAAInfo = CGM.getTBAAAccessInfo(E->getType());
++ Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo);
+ auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl();
+ return GetAddressOfBaseClass(Addr, Derived,
+ CE->path_begin(), CE->path_end(),
diff --git a/devel/llvm60/files/clang/patch-head-r336227.diff b/devel/llvm60/files/clang/patch-head-r336227.diff
new file mode 100644
index 000000000000..fd543dc38489
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r336227.diff
@@ -0,0 +1,42 @@
+r336227 | dim | 2018-07-12 21:02:59 +0200 (Thu, 12 Jul 2018) | 27 lines
+
+Pull in r336008 from upstream clang trunk:
+
+ Request init/fini array on FreeBSD 12 and later
+
+ Summary:
+
+ It seems a bad idea to change the default in the middle of a release
+ branch due to possible changes in global ctor / dtor ordering between
+ .ctors and .init_array. With FreeBSD 11.0's release imminent lets
+ change the default now for FreeBSD 12 (the current development
+ stream) and later.
+
+ FreeBSD rtld has supported .init_array / .fini_array for many years.
+ As of Jan 1 2017 all supported FreeBSD releases and branches will
+ have support.
+
+ Reviewers: dim, brooks, arichardson
+
+ Reviewed By: dim, brooks, arichardson
+
+ Subscribers: bsdjhb, krytarowski, emaste, cfe-commits
+
+ Differential Revision: https://reviews.llvm.org/D24867
+
+Requested by: jhb
+MFC after: 3 days
+
+Index: tools/clang/lib/Driver/ToolChains/Gnu.cpp
+===================================================================
+--- tools/clang/lib/Driver/ToolChains/Gnu.cpp (revision 336226)
++++ tools/clang/lib/Driver/ToolChains/Gnu.cpp (revision 336227)
+@@ -2375,6 +2375,8 @@ void Generic_ELF::addClangTargetOptions(const ArgL
+ bool UseInitArrayDefault =
+ getTriple().getArch() == llvm::Triple::aarch64 ||
+ getTriple().getArch() == llvm::Triple::aarch64_be ||
++ (getTriple().getOS() == llvm::Triple::FreeBSD &&
++ getTriple().getOSMajorVersion() >= 12) ||
+ (getTriple().getOS() == llvm::Triple::Linux &&
+ ((!GCCInstallation.isValid() || !V.isOlderThan(4, 7, 0)) ||
+ getTriple().isAndroid())) ||
diff --git a/devel/llvm60/files/clang/patch-head-r338697.diff b/devel/llvm60/files/clang/patch-head-r338697.diff
new file mode 100644
index 000000000000..eb7f11e83fcf
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r338697.diff
@@ -0,0 +1,104 @@
+r338697 | dim | 2018-09-15 23:22:50 +0200 (Sat, 15 Sep 2018) | 21 lines
+
+Pull in r325478 from upstream clang trunk (by Ivan A. Kosarev):
+
+ [CodeGen] Initialize large arrays by copying from a global
+
+ Currently, clang compiles explicit initializers for array elements
+ into series of store instructions. For large arrays of built-in types
+ this results in bloated output code and significant amount of time
+ spent on the instruction selection phase. This patch fixes the issue
+ by initializing such arrays with global constants that store the
+ binary image of the initializer.
+
+ Differential Revision: https://reviews.llvm.org/D43181
+
+This should fix a compiler hang (and excessive memory usage) while
+building the science/rmg port.
+
+Approved by: re (kib)
+Reported by: yuri@tsoft.com
+See also: https://bugs.llvm.org/show_bug.cgi?id=38798
+MFC after: 3 days
+
+Index: tools/clang/lib/CodeGen/CGExprAgg.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CGExprAgg.cpp (revision 338696)
++++ tools/clang/lib/CodeGen/CGExprAgg.cpp (revision 338697)
+@@ -14,6 +14,7 @@
+ #include "CodeGenFunction.h"
+ #include "CGObjCRuntime.h"
+ #include "CodeGenModule.h"
++#include "ConstantEmitter.h"
+ #include "clang/AST/ASTContext.h"
+ #include "clang/AST/DeclCXX.h"
+ #include "clang/AST/DeclTemplate.h"
+@@ -85,7 +86,7 @@ class AggExprEmitter : public StmtVisitor<AggExprE
+ void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
+
+ void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
+- QualType elementType, InitListExpr *E);
++ QualType ArrayQTy, InitListExpr *E);
+
+ AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
+ if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
+@@ -392,12 +393,15 @@ static bool isTrivialFiller(Expr *E) {
+
+ /// \brief Emit initialization of an array from an initializer list.
+ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
+- QualType elementType, InitListExpr *E) {
++ QualType ArrayQTy, InitListExpr *E) {
+ uint64_t NumInitElements = E->getNumInits();
+
+ uint64_t NumArrayElements = AType->getNumElements();
+ assert(NumInitElements <= NumArrayElements);
+
++ QualType elementType =
++ CGF.getContext().getAsArrayType(ArrayQTy)->getElementType();
++
+ // DestPtr is an array*. Construct an elementType* by drilling
+ // down a level.
+ llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
+@@ -409,6 +413,29 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr
+ CharUnits elementAlign =
+ DestPtr.getAlignment().alignmentOfArrayElement(elementSize);
+
++ // Consider initializing the array by copying from a global. For this to be
++ // more efficient than per-element initialization, the size of the elements
++ // with explicit initializers should be large enough.
++ if (NumInitElements * elementSize.getQuantity() > 16 &&
++ elementType.isTriviallyCopyableType(CGF.getContext())) {
++ CodeGen::CodeGenModule &CGM = CGF.CGM;
++ ConstantEmitter Emitter(CGM);
++ LangAS AS = ArrayQTy.getAddressSpace();
++ if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
++ auto GV = new llvm::GlobalVariable(
++ CGM.getModule(), C->getType(),
++ CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true),
++ llvm::GlobalValue::PrivateLinkage, C, "constinit",
++ /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal,
++ CGM.getContext().getTargetAddressSpace(AS));
++ Emitter.finalize(GV);
++ CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy);
++ GV->setAlignment(Align.getQuantity());
++ EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align));
++ return;
++ }
++ }
++
+ // Exception safety requires us to destroy all the
+ // already-constructed members if an initializer throws.
+ // For that, we'll need an EH cleanup.
+@@ -1156,11 +1183,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExp
+
+ // Handle initialization of an array.
+ if (E->getType()->isArrayType()) {
+- QualType elementType =
+- CGF.getContext().getAsArrayType(E->getType())->getElementType();
+-
+ auto AType = cast<llvm::ArrayType>(Dest.getAddress().getElementType());
+- EmitArrayInit(Dest.getAddress(), AType, elementType, E);
++ EmitArrayInit(Dest.getAddress(), AType, E->getType(), E);
+ return;
+ }
+
diff --git a/devel/llvm60/files/clang/patch-head-r339019.diff b/devel/llvm60/files/clang/patch-head-r339019.diff
new file mode 100644
index 000000000000..240772d184c2
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-head-r339019.diff
@@ -0,0 +1,30 @@
+r339019 | emaste | 2018-09-29 22:01:23 +0200 (Sat, 29 Sep 2018) | 15 lines
+
+clang: allow ifunc resolvers to accept arguments
+
+Previously Clang required ifunc resolution functions to take no
+arguments, presumably because GCC documented ifunc resolvers as taking
+no arguments. However, GCC accepts resolvers accepting arguments, and
+our rtld passes CPU ID information (cpuid, hwcap, etc.) to ifunc
+resolvers. Just remove the check from the in-tree compiler for our in-
+tree compiler; a different (per-OS) approach may be required upstream.
+
+Reported by: mjg
+Approved by: re (rgrimes)
+MFC after: 1 week
+Relnotes: Yes
+Sponsored by: The FreeBSD Foundation
+
+Index: tools/clang/lib/CodeGen/CodeGenModule.cpp
+===================================================================
+--- tools/clang/lib/CodeGen/CodeGenModule.cpp (revision 339018)
++++ tools/clang/lib/CodeGen/CodeGenModule.cpp (revision 339019)
+@@ -321,8 +321,6 @@ void CodeGenModule::checkAliases() {
+ assert(FTy);
+ if (!FTy->getReturnType()->isPointerTy())
+ Diags.Report(Location, diag::err_ifunc_resolver_return);
+- if (FTy->getNumParams())
+- Diags.Report(Location, diag::err_ifunc_resolver_params);
+ }
+
+ llvm::Constant *Aliasee = Alias->getIndirectSymbol();
diff --git a/devel/llvm60/files/clang/patch-stable12-r342281.diff b/devel/llvm60/files/clang/patch-stable12-r342281.diff
new file mode 100644
index 000000000000..4a6e9f615889
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-stable12-r342281.diff
@@ -0,0 +1,834 @@
+r342281 | dim | 2018-12-20 19:28:53 +0100 (Thu, 20 Dec 2018) | 24 lines
+
+Pull in r329671 from upstream clang trunk (by Akira Hatanaka):
+
+ [ExprConstant] Use an AST node and a version number as a key to
+ create an APValue and retrieve it from map Temporaries.
+
+ The version number is needed when a single AST node is visited
+ multiple times and is used to create APValues that are required to be
+ distinct from each other (for example, MaterializeTemporaryExprs in
+ default arguments and VarDecls in loops).
+
+ rdar://problem/36505742
+
+ Differential Revision: https://reviews.llvm.org/D42776
+
+This should fix 'Assertion failed: (Result.isUninit() && "temporary
+created multiple times"), function createTemporary' errors (if
+assertions are enabled, otherwise the compiler internal state might go
+bad), when building the graphics/rawtherapee port.
+
+Direct commit to stable/11 and stable/12, since head already has clang
+7.0.1, which includes this change.
+
+PR: 234144
+
+Index: tools/clang/include/clang/AST/APValue.h
+===================================================================
+--- tools/clang/include/clang/AST/APValue.h (revision 342280)
++++ tools/clang/include/clang/AST/APValue.h (revision 342281)
+@@ -53,7 +53,58 @@ class APValue {
+ MemberPointer,
+ AddrLabelDiff
+ };
+- typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
++
++ class LValueBase {
++ public:
++ typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
++
++ LValueBase() : CallIndex(0), Version(0) {}
++
++ template <class T>
++ LValueBase(T P, unsigned I = 0, unsigned V = 0)
++ : Ptr(P), CallIndex(I), Version(V) {}
++
++ template <class T>
++ bool is() const { return Ptr.is<T>(); }
++
++ template <class T>
++ T get() const { return Ptr.get<T>(); }
++
++ template <class T>
++ T dyn_cast() const { return Ptr.dyn_cast<T>(); }
++
++ void *getOpaqueValue() const;
++
++ bool isNull() const;
++
++ explicit operator bool () const;
++
++ PtrTy getPointer() const {
++ return Ptr;
++ }
++
++ unsigned getCallIndex() const {
++ return CallIndex;
++ }
++
++ void setCallIndex(unsigned Index) {
++ CallIndex = Index;
++ }
++
++ unsigned getVersion() const {
++ return Version;
++ }
++
++ bool operator==(const LValueBase &Other) const {
++ return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
++ Version == Other.Version;
++ }
++
++ private:
++ PtrTy Ptr;
++ unsigned CallIndex, Version;
++ };
++
+ typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
+ union LValuePathEntry {
+ /// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
+@@ -135,15 +186,15 @@ class APValue {
+ }
+ APValue(const APValue &RHS);
+ APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
+- APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
++ APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
+ bool IsNullPtr = false)
+ : Kind(Uninitialized) {
+- MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
++ MakeLValue(); setLValue(B, O, N, IsNullPtr);
+ }
+ APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
+- bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
++ bool OnePastTheEnd, bool IsNullPtr = false)
+ : Kind(Uninitialized) {
+- MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
++ MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
+ }
+ APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
+ MakeArray(InitElts, Size);
+@@ -255,6 +306,7 @@ class APValue {
+ bool hasLValuePath() const;
+ ArrayRef<LValuePathEntry> getLValuePath() const;
+ unsigned getLValueCallIndex() const;
++ unsigned getLValueVersion() const;
+ bool isNullPointer() const;
+
+ APValue &getVectorElt(unsigned I) {
+@@ -376,10 +428,10 @@ class APValue {
+ ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
+ }
+ void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+- unsigned CallIndex, bool IsNullPtr);
++ bool IsNullPtr);
+ void setLValue(LValueBase B, const CharUnits &O,
+ ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
+- unsigned CallIndex, bool IsNullPtr);
++ bool IsNullPtr);
+ void setUnion(const FieldDecl *Field, const APValue &Value) {
+ assert(isUnion() && "Invalid accessor");
+ ((UnionData*)(char*)Data.buffer)->Field = Field;
+@@ -451,4 +503,14 @@ class APValue {
+
+ } // end namespace clang.
+
++namespace llvm {
++template<> struct DenseMapInfo<clang::APValue::LValueBase> {
++ static clang::APValue::LValueBase getEmptyKey();
++ static clang::APValue::LValueBase getTombstoneKey();
++ static unsigned getHashValue(const clang::APValue::LValueBase &Base);
++ static bool isEqual(const clang::APValue::LValueBase &LHS,
++ const clang::APValue::LValueBase &RHS);
++};
++}
++
+ #endif
+Index: tools/clang/lib/AST/APValue.cpp
+===================================================================
+--- tools/clang/lib/AST/APValue.cpp (revision 342280)
++++ tools/clang/lib/AST/APValue.cpp (revision 342281)
+@@ -23,14 +23,57 @@ using namespace clang;
+
+ namespace {
+ struct LVBase {
+- llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
++ APValue::LValueBase Base;
+ CharUnits Offset;
+ unsigned PathLength;
+- unsigned CallIndex;
+- bool IsNullPtr;
++ bool IsNullPtr : 1;
++ bool IsOnePastTheEnd : 1;
+ };
+ }
+
++void *APValue::LValueBase::getOpaqueValue() const {
++ return Ptr.getOpaqueValue();
++}
++
++bool APValue::LValueBase::isNull() const {
++ return Ptr.isNull();
++}
++
++APValue::LValueBase::operator bool () const {
++ return static_cast<bool>(Ptr);
++}
++
++clang::APValue::LValueBase
++llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
++ return clang::APValue::LValueBase(
++ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(),
++ DenseMapInfo<unsigned>::getEmptyKey(),
++ DenseMapInfo<unsigned>::getEmptyKey());
++}
++
++clang::APValue::LValueBase
++llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
++ return clang::APValue::LValueBase(
++ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(),
++ DenseMapInfo<unsigned>::getTombstoneKey(),
++ DenseMapInfo<unsigned>::getTombstoneKey());
++}
++
++unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
++ const clang::APValue::LValueBase &Base) {
++ llvm::FoldingSetNodeID ID;
++ ID.AddPointer(Base.getOpaqueValue());
++ ID.AddInteger(Base.getCallIndex());
++ ID.AddInteger(Base.getVersion());
++ return ID.ComputeHash();
++}
++
++bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
++ const clang::APValue::LValueBase &LHS,
++ const clang::APValue::LValueBase &RHS) {
++ return LHS == RHS;
++}
++
+ struct APValue::LV : LVBase {
+ static const unsigned InlinePathSpace =
+ (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
+@@ -150,11 +193,10 @@ APValue::APValue(const APValue &RHS) : Kind(Uninit
+ MakeLValue();
+ if (RHS.hasLValuePath())
+ setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
+- RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex(),
+- RHS.isNullPointer());
++ RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
+ else
+ setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
+- RHS.getLValueCallIndex(), RHS.isNullPointer());
++ RHS.isNullPointer());
+ break;
+ case Array:
+ MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
+@@ -552,12 +594,12 @@ std::string APValue::getAsString(ASTContext &Ctx,
+
+ const APValue::LValueBase APValue::getLValueBase() const {
+ assert(isLValue() && "Invalid accessor");
+- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
++ return ((const LV*)(const void*)Data.buffer)->Base;
+ }
+
+ bool APValue::isLValueOnePastTheEnd() const {
+ assert(isLValue() && "Invalid accessor");
+- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
++ return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
+ }
+
+ CharUnits &APValue::getLValueOffset() {
+@@ -578,9 +620,14 @@ ArrayRef<APValue::LValuePathEntry> APValue::getLVa
+
+ unsigned APValue::getLValueCallIndex() const {
+ assert(isLValue() && "Invalid accessor");
+- return ((const LV*)(const char*)Data.buffer)->CallIndex;
++ return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
+ }
+
++unsigned APValue::getLValueVersion() const {
++ assert(isLValue() && "Invalid accessor");
++ return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
++}
++
+ bool APValue::isNullPointer() const {
+ assert(isLValue() && "Invalid usage");
+ return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
+@@ -587,13 +634,12 @@ bool APValue::isNullPointer() const {
+ }
+
+ void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
+- unsigned CallIndex, bool IsNullPtr) {
++ bool IsNullPtr) {
+ assert(isLValue() && "Invalid accessor");
+ LV &LVal = *((LV*)(char*)Data.buffer);
+- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
+- LVal.BaseAndIsOnePastTheEnd.setInt(false);
++ LVal.Base = B;
++ LVal.IsOnePastTheEnd = false;
+ LVal.Offset = O;
+- LVal.CallIndex = CallIndex;
+ LVal.resizePath((unsigned)-1);
+ LVal.IsNullPtr = IsNullPtr;
+ }
+@@ -600,13 +646,12 @@ void APValue::setLValue(LValueBase B, const CharUn
+
+ void APValue::setLValue(LValueBase B, const CharUnits &O,
+ ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
+- unsigned CallIndex, bool IsNullPtr) {
++ bool IsNullPtr) {
+ assert(isLValue() && "Invalid accessor");
+ LV &LVal = *((LV*)(char*)Data.buffer);
+- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
+- LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
++ LVal.Base = B;
++ LVal.IsOnePastTheEnd = IsOnePastTheEnd;
+ LVal.Offset = O;
+- LVal.CallIndex = CallIndex;
+ LVal.resizePath(Path.size());
+ memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
+ LVal.IsNullPtr = IsNullPtr;
+Index: tools/clang/lib/AST/ExprConstant.cpp
+===================================================================
+--- tools/clang/lib/AST/ExprConstant.cpp (revision 342280)
++++ tools/clang/lib/AST/ExprConstant.cpp (revision 342281)
+@@ -446,8 +446,8 @@ namespace {
+
+ // Note that we intentionally use std::map here so that references to
+ // values are stable.
+- typedef std::map<const void*, APValue> MapTy;
+- typedef MapTy::const_iterator temp_iterator;
++ typedef std::pair<const void *, unsigned> MapKeyTy;
++ typedef std::map<MapKeyTy, APValue> MapTy;
+ /// Temporaries - Temporary lvalues materialized within this stack frame.
+ MapTy Temporaries;
+
+@@ -457,6 +457,20 @@ namespace {
+ /// Index - The call index of this call.
+ unsigned Index;
+
++ /// The stack of integers for tracking version numbers for temporaries.
++ SmallVector<unsigned, 2> TempVersionStack = {1};
++ unsigned CurTempVersion = TempVersionStack.back();
++
++ unsigned getTempVersion() const { return TempVersionStack.back(); }
++
++ void pushTempVersion() {
++ TempVersionStack.push_back(++CurTempVersion);
++ }
++
++ void popTempVersion() {
++ TempVersionStack.pop_back();
++ }
++
+ // FIXME: Adding this to every 'CallStackFrame' may have a nontrivial impact
+ // on the overall stack usage of deeply-recursing constexpr evaluataions.
+ // (We should cache this map rather than recomputing it repeatedly.)
+@@ -473,10 +487,36 @@ namespace {
+ APValue *Arguments);
+ ~CallStackFrame();
+
+- APValue *getTemporary(const void *Key) {
+- MapTy::iterator I = Temporaries.find(Key);
+- return I == Temporaries.end() ? nullptr : &I->second;
++ // Return the temporary for Key whose version number is Version.
++ APValue *getTemporary(const void *Key, unsigned Version) {
++ MapKeyTy KV(Key, Version);
++ auto LB = Temporaries.lower_bound(KV);
++ if (LB != Temporaries.end() && LB->first == KV)
++ return &LB->second;
++ // Pair (Key,Version) wasn't found in the map. Check that no elements
++ // in the map have 'Key' as their key.
++ assert((LB == Temporaries.end() || LB->first.first != Key) &&
++ (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
++ "Element with key 'Key' found in map");
++ return nullptr;
+ }
++
++ // Return the current temporary for Key in the map.
++ APValue *getCurrentTemporary(const void *Key) {
++ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX));
++ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
++ return &std::prev(UB)->second;
++ return nullptr;
++ }
++
++ // Return the version number of the current temporary for Key.
++ unsigned getCurrentTemporaryVersion(const void *Key) const {
++ auto UB = Temporaries.upper_bound(MapKeyTy(Key, UINT_MAX));
++ if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
++ return std::prev(UB)->first.second;
++ return 0;
++ }
++
+ APValue &createTemporary(const void *Key, bool IsLifetimeExtended);
+ };
+
+@@ -606,7 +646,8 @@ namespace {
+
+ /// EvaluatingObject - Pair of the AST node that an lvalue represents and
+ /// the call index that that lvalue was allocated in.
+- typedef std::pair<APValue::LValueBase, unsigned> EvaluatingObject;
++ typedef std::pair<APValue::LValueBase, std::pair<unsigned, unsigned>>
++ EvaluatingObject;
+
+ /// EvaluatingConstructors - Set of objects that are currently being
+ /// constructed.
+@@ -625,8 +666,10 @@ namespace {
+ }
+ };
+
+- bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex) {
+- return EvaluatingConstructors.count(EvaluatingObject(Decl, CallIndex));
++ bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex,
++ unsigned Version) {
++ return EvaluatingConstructors.count(
++ EvaluatingObject(Decl, {CallIndex, Version}));
+ }
+
+ /// The current array initialization index, if we're performing array
+@@ -722,7 +765,7 @@ namespace {
+ void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
+ EvaluatingDecl = Base;
+ EvaluatingDeclValue = &Value;
+- EvaluatingConstructors.insert({Base, 0});
++ EvaluatingConstructors.insert({Base, {0, 0}});
+ }
+
+ const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
+@@ -1086,11 +1129,16 @@ namespace {
+ unsigned OldStackSize;
+ public:
+ ScopeRAII(EvalInfo &Info)
+- : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
++ : Info(Info), OldStackSize(Info.CleanupStack.size()) {
++ // Push a new temporary version. This is needed to distinguish between
++ // temporaries created in different iterations of a loop.
++ Info.CurrentCall->pushTempVersion();
++ }
+ ~ScopeRAII() {
+ // Body moved to a static method to encourage the compiler to inline away
+ // instances of this class.
+ cleanup(Info, OldStackSize);
++ Info.CurrentCall->popTempVersion();
+ }
+ private:
+ static void cleanup(EvalInfo &Info, unsigned OldStackSize) {
+@@ -1170,7 +1218,8 @@ CallStackFrame::~CallStackFrame() {
+
+ APValue &CallStackFrame::createTemporary(const void *Key,
+ bool IsLifetimeExtended) {
+- APValue &Result = Temporaries[Key];
++ unsigned Version = Info.CurrentCall->getTempVersion();
++ APValue &Result = Temporaries[MapKeyTy(Key, Version)];
+ assert(Result.isUninit() && "temporary created multiple times");
+ Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
+ return Result;
+@@ -1262,27 +1311,27 @@ namespace {
+ struct LValue {
+ APValue::LValueBase Base;
+ CharUnits Offset;
+- unsigned InvalidBase : 1;
+- unsigned CallIndex : 31;
+ SubobjectDesignator Designator;
+- bool IsNullPtr;
++ bool IsNullPtr : 1;
++ bool InvalidBase : 1;
+
+ const APValue::LValueBase getLValueBase() const { return Base; }
+ CharUnits &getLValueOffset() { return Offset; }
+ const CharUnits &getLValueOffset() const { return Offset; }
+- unsigned getLValueCallIndex() const { return CallIndex; }
+ SubobjectDesignator &getLValueDesignator() { return Designator; }
+ const SubobjectDesignator &getLValueDesignator() const { return Designator;}
+ bool isNullPointer() const { return IsNullPtr;}
+
++ unsigned getLValueCallIndex() const { return Base.getCallIndex(); }
++ unsigned getLValueVersion() const { return Base.getVersion(); }
++
+ void moveInto(APValue &V) const {
+ if (Designator.Invalid)
+- V = APValue(Base, Offset, APValue::NoLValuePath(), CallIndex,
+- IsNullPtr);
++ V = APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
+ else {
+ assert(!InvalidBase && "APValues can't handle invalid LValue bases");
+ V = APValue(Base, Offset, Designator.Entries,
+- Designator.IsOnePastTheEnd, CallIndex, IsNullPtr);
++ Designator.IsOnePastTheEnd, IsNullPtr);
+ }
+ }
+ void setFrom(ASTContext &Ctx, const APValue &V) {
+@@ -1290,12 +1339,11 @@ namespace {
+ Base = V.getLValueBase();
+ Offset = V.getLValueOffset();
+ InvalidBase = false;
+- CallIndex = V.getLValueCallIndex();
+ Designator = SubobjectDesignator(Ctx, V);
+ IsNullPtr = V.isNullPointer();
+ }
+
+- void set(APValue::LValueBase B, unsigned I = 0, bool BInvalid = false) {
++ void set(APValue::LValueBase B, bool BInvalid = false) {
+ #ifndef NDEBUG
+ // We only allow a few types of invalid bases. Enforce that here.
+ if (BInvalid) {
+@@ -1308,7 +1356,6 @@ namespace {
+ Base = B;
+ Offset = CharUnits::fromQuantity(0);
+ InvalidBase = BInvalid;
+- CallIndex = I;
+ Designator = SubobjectDesignator(getType(B));
+ IsNullPtr = false;
+ }
+@@ -1317,13 +1364,12 @@ namespace {
+ Base = (Expr *)nullptr;
+ Offset = CharUnits::fromQuantity(TargetVal);
+ InvalidBase = false;
+- CallIndex = 0;
+ Designator = SubobjectDesignator(PointerTy->getPointeeType());
+ IsNullPtr = true;
+ }
+
+ void setInvalid(APValue::LValueBase B, unsigned I = 0) {
+- set(B, I, true);
++ set(B, true);
+ }
+
+ // Check that this LValue is not based on a null pointer. If it is, produce
+@@ -1525,6 +1571,15 @@ static bool EvaluateAsRValue(EvalInfo &Info, const
+ // Misc utilities
+ //===----------------------------------------------------------------------===//
+
++/// A helper function to create a temporary and set an LValue.
++template <class KeyTy>
++static APValue &createTemporary(const KeyTy *Key, bool IsLifetimeExtended,
++ LValue &LV, CallStackFrame &Frame) {
++ LV.set({Key, Frame.Info.CurrentCall->Index,
++ Frame.Info.CurrentCall->getTempVersion()});
++ return Frame.createTemporary(Key, IsLifetimeExtended);
++}
++
+ /// Negate an APSInt in place, converting it to a signed form if necessary, and
+ /// preserving its value (by extending by up to one bit as needed).
+ static void negateAsSigned(APSInt &Int) {
+@@ -1854,7 +1909,7 @@ static const ValueDecl *GetLValueBaseDecl(const LV
+ }
+
+ static bool IsLiteralLValue(const LValue &Value) {
+- if (Value.CallIndex)
++ if (Value.getLValueCallIndex())
+ return false;
+ const Expr *E = Value.Base.dyn_cast<const Expr*>();
+ return E && !isa<MaterializeTemporaryExpr>(E);
+@@ -2404,7 +2459,7 @@ static bool handleLValueToRValueConversion(EvalInf
+ /// \param Result Filled in with a pointer to the value of the variable.
+ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
+ const VarDecl *VD, CallStackFrame *Frame,
+- APValue *&Result) {
++ APValue *&Result, const LValue *LVal) {
+
+ // If this is a parameter to an active constexpr function call, perform
+ // argument substitution.
+@@ -2423,7 +2478,8 @@ static bool evaluateVarDeclInit(EvalInfo &Info, co
+
+ // If this is a local variable, dig out its value.
+ if (Frame) {
+- Result = Frame->getTemporary(VD);
++ Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
++ : Frame->getCurrentTemporary(VD);
+ if (!Result) {
+ // Assume variables referenced within a lambda's call operator that were
+ // not declared within the call operator are captures and during checking
+@@ -3000,8 +3056,8 @@ static CompleteObject findCompleteObject(EvalInfo
+ }
+
+ CallStackFrame *Frame = nullptr;
+- if (LVal.CallIndex) {
+- Frame = Info.getCallFrame(LVal.CallIndex);
++ if (LVal.getLValueCallIndex()) {
++ Frame = Info.getCallFrame(LVal.getLValueCallIndex());
+ if (!Frame) {
+ Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
+ << AK << LVal.Base.is<const ValueDecl*>();
+@@ -3113,7 +3169,7 @@ static CompleteObject findCompleteObject(EvalInfo
+ }
+ }
+
+- if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal))
++ if (!evaluateVarDeclInit(Info, E, VD, Frame, BaseVal, &LVal))
+ return CompleteObject();
+ } else {
+ const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
+@@ -3155,7 +3211,7 @@ static CompleteObject findCompleteObject(EvalInfo
+ return CompleteObject();
+ }
+ } else {
+- BaseVal = Frame->getTemporary(Base);
++ BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
+ assert(BaseVal && "missing value for temporary");
+ }
+
+@@ -3175,7 +3231,9 @@ static CompleteObject findCompleteObject(EvalInfo
+ // During the construction of an object, it is not yet 'const'.
+ // FIXME: This doesn't do quite the right thing for const subobjects of the
+ // object under construction.
+- if (Info.isEvaluatingConstructor(LVal.getLValueBase(), LVal.CallIndex)) {
++ if (Info.isEvaluatingConstructor(LVal.getLValueBase(),
++ LVal.getLValueCallIndex(),
++ LVal.getLValueVersion())) {
+ BaseType = Info.Ctx.getCanonicalType(BaseType);
+ BaseType.removeLocalConst();
+ }
+@@ -3212,7 +3270,7 @@ static bool handleLValueToRValueConversion(EvalInf
+
+ // Check for special cases where there is no existing APValue to look at.
+ const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
+- if (Base && !LVal.CallIndex && !Type.isVolatileQualified()) {
++ if (Base && !LVal.getLValueCallIndex() && !Type.isVolatileQualified()) {
+ if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(Base)) {
+ // In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the
+ // initializer until now for such expressions. Such an expression can't be
+@@ -3715,8 +3773,7 @@ static bool EvaluateVarDecl(EvalInfo &Info, const
+ return true;
+
+ LValue Result;
+- Result.set(VD, Info.CurrentCall->Index);
+- APValue &Val = Info.CurrentCall->createTemporary(VD, true);
++ APValue &Val = createTemporary(VD, true, Result, *Info.CurrentCall);
+
+ const Expr *InitE = VD->getInit();
+ if (!InitE) {
+@@ -3772,6 +3829,19 @@ struct StmtResult {
+ /// The location containing the result, if any (used to support RVO).
+ const LValue *Slot;
+ };
++
++struct TempVersionRAII {
++ CallStackFrame &Frame;
++
++ TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
++ Frame.pushTempVersion();
++ }
++
++ ~TempVersionRAII() {
++ Frame.popTempVersion();
++ }
++};
++
+ }
+
+ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
+@@ -4329,7 +4399,8 @@ static bool HandleConstructorCall(const Expr *E, c
+ }
+
+ EvalInfo::EvaluatingConstructorRAII EvalObj(
+- Info, {This.getLValueBase(), This.CallIndex});
++ Info, {This.getLValueBase(),
++ {This.getLValueCallIndex(), This.getLValueVersion()}});
+ CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
+
+ // FIXME: Creating an APValue just to hold a nonexistent return value is
+@@ -4578,9 +4649,12 @@ class ExprEvaluatorBase
+ { return StmtVisitorTy::Visit(E->getResultExpr()); }
+ bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
+ { return StmtVisitorTy::Visit(E->getReplacement()); }
+- bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
+- { return StmtVisitorTy::Visit(E->getExpr()); }
++ bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) {
++ TempVersionRAII RAII(*Info.CurrentCall);
++ return StmtVisitorTy::Visit(E->getExpr());
++ }
+ bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
++ TempVersionRAII RAII(*Info.CurrentCall);
+ // The initializer may not have been parsed yet, or might be erroneous.
+ if (!E->getExpr())
+ return Error(E);
+@@ -4658,7 +4732,7 @@ class ExprEvaluatorBase
+ }
+
+ bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
+- if (APValue *Value = Info.CurrentCall->getTemporary(E))
++ if (APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
+ return DerivedSuccess(*Value, E);
+
+ const Expr *Source = E->getSourceExpr();
+@@ -5216,7 +5290,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr
+
+ if (!VD->getType()->isReferenceType()) {
+ if (Frame) {
+- Result.set(VD, Frame->Index);
++ Result.set({VD, Frame->Index,
++ Info.CurrentCall->getCurrentTemporaryVersion(VD)});
+ return true;
+ }
+ return Success(VD);
+@@ -5223,7 +5298,7 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr
+ }
+
+ APValue *V;
+- if (!evaluateVarDeclInit(Info, E, VD, Frame, V))
++ if (!evaluateVarDeclInit(Info, E, VD, Frame, V, nullptr))
+ return false;
+ if (V->isUninit()) {
+ if (!Info.checkingPotentialConstantExpression())
+@@ -5255,9 +5330,8 @@ bool LValueExprEvaluator::VisitMaterializeTemporar
+ *Value = APValue();
+ Result.set(E);
+ } else {
+- Value = &Info.CurrentCall->
+- createTemporary(E, E->getStorageDuration() == SD_Automatic);
+- Result.set(E, Info.CurrentCall->Index);
++ Value = &createTemporary(E, E->getStorageDuration() == SD_Automatic, Result,
++ *Info.CurrentCall);
+ }
+
+ QualType Type = Inner->getType();
+@@ -5736,7 +5810,6 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas
+ Result.Base = (Expr*)nullptr;
+ Result.InvalidBase = false;
+ Result.Offset = CharUnits::fromQuantity(N);
+- Result.CallIndex = 0;
+ Result.Designator.setInvalid();
+ Result.IsNullPtr = false;
+ return true;
+@@ -5752,9 +5825,9 @@ bool PointerExprEvaluator::VisitCastExpr(const Cas
+ if (!evaluateLValue(SubExpr, Result))
+ return false;
+ } else {
+- Result.set(SubExpr, Info.CurrentCall->Index);
+- if (!EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr, false),
+- Info, Result, SubExpr))
++ APValue &Value = createTemporary(SubExpr, false, Result,
++ *Info.CurrentCall);
++ if (!EvaluateInPlace(Value, Info, Result, SubExpr))
+ return false;
+ }
+ // The result is a pointer to the first element of the array.
+@@ -6520,9 +6593,8 @@ class TemporaryExprEvaluator
+
+ /// Visit an expression which constructs the value of this temporary.
+ bool VisitConstructExpr(const Expr *E) {
+- Result.set(E, Info.CurrentCall->Index);
+- return EvaluateInPlace(Info.CurrentCall->createTemporary(E, false),
+- Info, Result, E);
++ APValue &Value = createTemporary(E, false, Result, *Info.CurrentCall);
++ return EvaluateInPlace(Value, Info, Result, E);
+ }
+
+ bool VisitCastExpr(const CastExpr *E) {
+@@ -8007,7 +8079,8 @@ static bool HasSameBase(const LValue &A, const LVa
+ }
+
+ return IsGlobalLValue(A.getLValueBase()) ||
+- A.getLValueCallIndex() == B.getLValueCallIndex();
++ (A.getLValueCallIndex() == B.getLValueCallIndex() &&
++ A.getLValueVersion() == B.getLValueVersion());
+ }
+
+ /// \brief Determine whether this is a pointer past the end of the complete
+@@ -9941,15 +10014,13 @@ static bool Evaluate(APValue &Result, EvalInfo &In
+ return true;
+ } else if (T->isArrayType()) {
+ LValue LV;
+- LV.set(E, Info.CurrentCall->Index);
+- APValue &Value = Info.CurrentCall->createTemporary(E, false);
++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
+ if (!EvaluateArray(E, LV, Value, Info))
+ return false;
+ Result = Value;
+ } else if (T->isRecordType()) {
+ LValue LV;
+- LV.set(E, Info.CurrentCall->Index);
+- APValue &Value = Info.CurrentCall->createTemporary(E, false);
++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
+ if (!EvaluateRecord(E, LV, Value, Info))
+ return false;
+ Result = Value;
+@@ -9963,8 +10034,7 @@ static bool Evaluate(APValue &Result, EvalInfo &In
+ QualType Unqual = T.getAtomicUnqualifiedType();
+ if (Unqual->isArrayType() || Unqual->isRecordType()) {
+ LValue LV;
+- LV.set(E, Info.CurrentCall->Index);
+- APValue &Value = Info.CurrentCall->createTemporary(E, false);
++ APValue &Value = createTemporary(E, false, LV, *Info.CurrentCall);
+ if (!EvaluateAtomic(E, &LV, Value, Info))
+ return false;
+ } else {
+@@ -10786,7 +10856,7 @@ bool Expr::isPotentialConstantExpr(const FunctionD
+ // is a temporary being used as the 'this' pointer.
+ LValue This;
+ ImplicitValueInitExpr VIE(RD ? Info.Ctx.getRecordType(RD) : Info.Ctx.IntTy);
+- This.set(&VIE, Info.CurrentCall->Index);
++ This.set({&VIE, Info.CurrentCall->Index});
+
+ ArrayRef<const Expr*> Args;
+
+Index: tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp
+===================================================================
+--- tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342280)
++++ tools/clang/test/SemaCXX/constant-expression-cxx1y.cpp (revision 342281)
+@@ -852,7 +852,6 @@ namespace Lifetime {
+ static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+ static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
+
+- // FIXME: This function should be treated as non-constant.
+ constexpr void lifetime_versus_loops() {
+ int *p = 0;
+ for (int i = 0; i != 2; ++i) {
+@@ -862,10 +861,10 @@ namespace Lifetime {
+ if (i)
+ // This modifies the 'n' from the previous iteration of the loop outside
+ // its lifetime.
+- ++*q;
++ ++*q; // expected-note {{increment of object outside its lifetime}}
+ }
+ }
+- static_assert((lifetime_versus_loops(), true), "");
++ static_assert((lifetime_versus_loops(), true), ""); // expected-error {{constant expression}} expected-note {{in call}}
+ }
+
+ namespace Bitfields {
+Index: tools/clang/test/SemaCXX/constexpr-default-arg.cpp
+===================================================================
+--- tools/clang/test/SemaCXX/constexpr-default-arg.cpp (nonexistent)
++++ tools/clang/test/SemaCXX/constexpr-default-arg.cpp (revision 342281)
+@@ -0,0 +1,38 @@
++// RUN: %clang_cc1 -std=c++1y -S -o - -emit-llvm -verify %s
++
++namespace default_arg_temporary {
++
++constexpr bool equals(const float& arg = 1.0f) {
++ return arg == 1.0f;
++}
++
++constexpr const int &x(const int &p = 0) {
++ return p;
++}
++
++struct S {
++ constexpr S(const int &a = 0) {}
++};
++
++void test_default_arg2() {
++ // This piece of code used to cause an assertion failure in
++ // CallStackFrame::createTemporary because the same MTE is used to initilize
++ // both elements of the array (see PR33140).
++ constexpr S s[2] = {};
++
++ // This piece of code used to cause an assertion failure in
++ // CallStackFrame::createTemporary because multiple CXXDefaultArgExpr share
++ // the same MTE (see PR33140).
++ static_assert(equals() && equals(), "");
++
++ // Test that constant expression evaluation produces distinct lvalues for
++ // each call.
++ static_assert(&x() != &x(), "");
++}
++
++// Check that multiple CXXDefaultInitExprs don't cause an assertion failure.
++struct A { int &&r = 0; }; // expected-warning {{binding reference member}} // expected-note {{reference member declared here}}
++struct B { A x, y; };
++B b = {};
++
++}
diff --git a/devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt b/devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt
new file mode 100644
index 000000000000..17043c6072cf
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_lib_Headers_CMakeLists.txt
@@ -0,0 +1,32 @@
+--- tools/clang/lib/Headers/CMakeLists.txt.orig
++++ tools/clang/lib/Headers/CMakeLists.txt
+@@ -56,7 +56,6 @@
+ intrin.h
+ inttypes.h
+ iso646.h
+- limits.h
+ lwpintrin.h
+ lzcntintrin.h
+ mm3dnow.h
+@@ -76,21 +75,13 @@
+ s390intrin.h
+ shaintrin.h
+ smmintrin.h
+- stdalign.h
+- stdarg.h
+- stdatomic.h
+- stdbool.h
+- stddef.h
+ __stddef_max_align_t.h
+- stdint.h
+- stdnoreturn.h
+ tbmintrin.h
+ tgmath.h
+ tmmintrin.h
+ unwind.h
+ vadefs.h
+ vaesintrin.h
+- varargs.h
+ vecintrin.h
+ vpclmulqdqintrin.h
+ wmmintrin.h
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py
new file mode 100644
index 000000000000..2c8909f1e1d1
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format-sublime.py
@@ -0,0 +1,14 @@
+
+$FreeBSD$
+
+--- tools/clang/tools/clang-format/clang-format-sublime.py.orig
++++ tools/clang/tools/clang-format/clang-format-sublime.py
+@@ -18,7 +18,7 @@
+ import subprocess
+
+ # Change this to the full path if clang-format is not on the path.
+-binary = 'clang-format'
++binary = 'clang-format%%LLVM_SUFFIX%%'
+
+ # Change this to format according to other formatting styles. See the output of
+ # 'clang-format --help' for a list of supported styles. The default looks for
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py
new file mode 100644
index 000000000000..2962d3f4cbcb
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_clang-format.py
@@ -0,0 +1,11 @@
+--- tools/clang/tools/clang-format/clang-format.py.orig 2015-09-08 20:44:00 UTC
++++ tools/clang/tools/clang-format/clang-format.py
+@@ -34,7 +34,7 @@ import vim
+
+ # set g:clang_format_path to the path to clang-format if it is not on the path
+ # Change this to the full path if clang-format is not on the path.
+-binary = 'clang-format'
++binary = 'clang-format%%LLVM_SUFFIX%%'
+ if vim.eval('exists("g:clang_format_path")') == "1":
+ binary = vim.eval('g:clang_format_path')
+
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format
new file mode 100644
index 000000000000..5c5ae3581228
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_clang-format_git-clang-format
@@ -0,0 +1,32 @@
+
+$FreeBSD$
+
+--- tools/clang/tools/clang-format/git-clang-format.orig
++++ tools/clang/tools/clang-format/git-clang-format
+@@ -90,7 +90,7 @@
+ usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=desc)
+ p.add_argument('--binary',
+- default=config.get('clangformat.binary', 'clang-format'),
++ default=config.get('clangformat.binary', 'clang-format%%LLVM_SUFFIX%%'),
+ help='path to clang-format'),
+ p.add_argument('--commit',
+ default=config.get('clangformat.commit', 'HEAD'),
+@@ -344,7 +344,7 @@
+
+
+ def run_clang_format_and_save_to_tree(changed_lines, revision=None,
+- binary='clang-format', style=None):
++ binary='clang-format%%LLVM_SUFFIX%%', style=None):
+ """Run clang-format on each file and save the result to a git tree.
+
+ Returns the object ID (SHA-1) of the created tree."""
+@@ -397,7 +397,7 @@
+
+
+ def clang_format_to_blob(filename, line_ranges, revision=None,
+- binary='clang-format', style=None):
++ binary='clang-format%%LLVM_SUFFIX%%', style=None):
+ """Run clang-format on the given file and save the result to a git blob.
+
+ Runs on the file in `revision` if not None, or on the file in the working
diff --git a/devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer b/devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer
new file mode 100644
index 000000000000..e1c65480ce2f
--- /dev/null
+++ b/devel/llvm60/files/clang/patch-tools_clang_tools_scan-build_libexec_ccc-analyzer
@@ -0,0 +1,12 @@
+--- tools/clang/tools/scan-build/libexec/ccc-analyzer.orig
++++ tools/clang/tools/scan-build/libexec/ccc-analyzer
+@@ -81,6 +81,9 @@
+ if (-x "/usr/bin/xcrun") {
+ $UseXCRUN = 1;
+ }
++} elsif (`uname -s` eq "FreeBSD\n") {
++ $DefaultCCompiler = 'cc';
++ $DefaultCXXCompiler = 'c++';
+ } else {
+ $DefaultCCompiler = 'gcc';
+ $DefaultCXXCompiler = 'g++';