summaryrefslogtreecommitdiffstats
path: root/contrib/llvm
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2016-02-13 15:58:51 +0000
committerdim <dim@FreeBSD.org>2016-02-13 15:58:51 +0000
commit7024e27ddea8cff63ccd142987756cba5001628d (patch)
tree788dd2f48fde34dee962a966ebc3d94510e29a47 /contrib/llvm
parent0fcbd80cfc7cfbf997f34115b7b17d8c679c71fc (diff)
parent97a7b8a20a989eb4cf3d9465e1451de6cd05fa41 (diff)
downloadFreeBSD-src-7024e27ddea8cff63ccd142987756cba5001628d.zip
FreeBSD-src-7024e27ddea8cff63ccd142987756cba5001628d.tar.gz
Update llvm, clang and lldb to release_38 branch r260756.
Diffstat (limited to 'contrib/llvm')
-rw-r--r--contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td2
-rw-r--r--contrib/llvm/include/llvm/IR/Value.h4
-rw-r--r--contrib/llvm/lib/Analysis/DemandedBits.cpp7
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp5
-rw-r--r--contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp55
-rw-r--r--contrib/llvm/lib/IR/Value.cpp4
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64.td4
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp3
-rw-r--r--contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td359
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/AMDGPU.td3
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h3
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/Processors.td12
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp9
-rw-r--r--contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp3
-rw-r--r--contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp4
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp18
-rw-r--r--contrib/llvm/lib/Target/PowerPC/PPCInstrAltivec.td2
-rw-r--r--contrib/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp2
-rw-r--r--contrib/llvm/lib/Target/X86/X86ISelLowering.cpp65
-rw-r--r--contrib/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp2
-rw-r--r--contrib/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp3
-rw-r--r--contrib/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp18
-rw-r--r--contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp12
-rw-r--r--contrib/llvm/tools/clang/include/clang/Sema/Sema.h20
-rw-r--r--contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp1367
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/Address.h20
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp17
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp226
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/Tools.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp19
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp290
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp134
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp25
-rw-r--r--contrib/llvm/tools/lldb/include/lldb/API/SBInstruction.h3
-rw-r--r--contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h19
-rw-r--r--contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h1
-rw-r--r--contrib/llvm/tools/lldb/source/API/SBInstruction.cpp8
-rw-r--r--contrib/llvm/tools/lldb/source/Core/Module.cpp13
-rw-r--r--contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp15
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp15
-rw-r--r--contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp151
-rw-r--r--contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp20
-rw-r--r--contrib/llvm/tools/lldb/source/Target/Target.cpp18
46 files changed, 1875 insertions, 1119 deletions
diff --git a/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 06dfc32..5512b10 100644
--- a/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/contrib/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -484,7 +484,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_ppc_altivec_vpkswss : GCCBuiltin<"__builtin_altivec_vpkswss">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
diff --git a/contrib/llvm/include/llvm/IR/Value.h b/contrib/llvm/include/llvm/IR/Value.h
index bb7ff27..8918dcd 100644
--- a/contrib/llvm/include/llvm/IR/Value.h
+++ b/contrib/llvm/include/llvm/IR/Value.h
@@ -280,11 +280,7 @@ public:
// when using them since you might not get all uses.
// The methods that don't start with materialized_ assert that modules is
// fully materialized.
-#ifdef NDEBUG
- void assertModuleIsMaterialized() const {}
-#else
void assertModuleIsMaterialized() const;
-#endif
bool use_empty() const {
assertModuleIsMaterialized();
diff --git a/contrib/llvm/lib/Analysis/DemandedBits.cpp b/contrib/llvm/lib/Analysis/DemandedBits.cpp
index 143d0b7..6f92ba6 100644
--- a/contrib/llvm/lib/Analysis/DemandedBits.cpp
+++ b/contrib/llvm/lib/Analysis/DemandedBits.cpp
@@ -242,13 +242,6 @@ void DemandedBits::determineLiveOperandBits(
if (OperandNo != 0)
AB = AOut;
break;
- case Instruction::ICmp:
- // Count the number of leading zeroes in each operand.
- ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
- auto NumLeadingZeroes = std::min(KnownZero.countLeadingOnes(),
- KnownZero2.countLeadingOnes());
- AB = ~APInt::getHighBitsSet(BitWidth, NumLeadingZeroes);
- break;
}
}
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 4171657..5633aa4 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -555,6 +555,11 @@ bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
return true;
O << -MO.getImm();
return false;
+ case 's': // The GCC deprecated s modifier
+ if (MO.getType() != MachineOperand::MO_Immediate)
+ return true;
+ O << ((32 - MO.getImm()) & 31);
+ return false;
}
}
return true;
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index ae62b6b..f56c8e4 100644
--- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -793,16 +793,27 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
}
-/// Determine whether two variable pieces overlap.
-static bool piecesOverlap(const DIExpression *P1, const DIExpression *P2) {
- if (!P1->isBitPiece() || !P2->isBitPiece())
- return true;
+// Determine the relative position of the pieces described by P1 and P2.
+// Returns -1 if P1 is entirely before P2, 0 if P1 and P2 overlap,
+// 1 if P1 is entirely after P2.
+static int pieceCmp(const DIExpression *P1, const DIExpression *P2) {
unsigned l1 = P1->getBitPieceOffset();
unsigned l2 = P2->getBitPieceOffset();
unsigned r1 = l1 + P1->getBitPieceSize();
unsigned r2 = l2 + P2->getBitPieceSize();
- // True where [l1,r1[ and [r1,r2[ overlap.
- return (l1 < r2) && (l2 < r1);
+ if (r1 <= l2)
+ return -1;
+ else if (r2 <= l1)
+ return 1;
+ else
+ return 0;
+}
+
+/// Determine whether two variable pieces overlap.
+static bool piecesOverlap(const DIExpression *P1, const DIExpression *P2) {
+ if (!P1->isBitPiece() || !P2->isBitPiece())
+ return true;
+ return pieceCmp(P1, P2) == 0;
}
/// \brief If this and Next are describing different pieces of the same
@@ -811,14 +822,32 @@ static bool piecesOverlap(const DIExpression *P1, const DIExpression *P2) {
/// Return true if the merge was successful.
bool DebugLocEntry::MergeValues(const DebugLocEntry &Next) {
if (Begin == Next.Begin) {
- auto *Expr = cast_or_null<DIExpression>(Values[0].Expression);
- auto *NextExpr = cast_or_null<DIExpression>(Next.Values[0].Expression);
- if (Expr->isBitPiece() && NextExpr->isBitPiece() &&
- !piecesOverlap(Expr, NextExpr)) {
- addValues(Next.Values);
- End = Next.End;
- return true;
+ auto *FirstExpr = cast<DIExpression>(Values[0].Expression);
+ auto *FirstNextExpr = cast<DIExpression>(Next.Values[0].Expression);
+ if (!FirstExpr->isBitPiece() || !FirstNextExpr->isBitPiece())
+ return false;
+
+ // We can only merge entries if none of the pieces overlap any others.
+ // In doing so, we can take advantage of the fact that both lists are
+ // sorted.
+ for (unsigned i = 0, j = 0; i < Values.size(); ++i) {
+ for (; j < Next.Values.size(); ++j) {
+ int res = pieceCmp(cast<DIExpression>(Values[i].Expression),
+ cast<DIExpression>(Next.Values[j].Expression));
+ if (res == 0) // The two expressions overlap, we can't merge.
+ return false;
+ // Values[i] is entirely before Next.Values[j],
+ // so go back to the next entry of Values.
+ else if (res == -1)
+ break;
+ // Next.Values[j] is entirely before Values[i], so go on to the
+ // next entry of Next.Values.
+ }
}
+
+ addValues(Next.Values);
+ End = Next.End;
+ return true;
}
return false;
}
diff --git a/contrib/llvm/lib/IR/Value.cpp b/contrib/llvm/lib/IR/Value.cpp
index eb9deb6..4d224a0 100644
--- a/contrib/llvm/lib/IR/Value.cpp
+++ b/contrib/llvm/lib/IR/Value.cpp
@@ -313,8 +313,8 @@ void Value::takeName(Value *V) {
ST->reinsertValue(this);
}
-#ifndef NDEBUG
void Value::assertModuleIsMaterialized() const {
+#ifndef NDEBUG
const GlobalValue *GV = dyn_cast<GlobalValue>(this);
if (!GV)
return;
@@ -322,8 +322,10 @@ void Value::assertModuleIsMaterialized() const {
if (!M)
return;
assert(M->isMaterialized());
+#endif
}
+#ifndef NDEBUG
static bool contains(SmallPtrSetImpl<ConstantExpr *> &Cache, ConstantExpr *Expr,
Constant *C) {
if (!Cache.insert(Expr).second)
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64.td b/contrib/llvm/lib/Target/AArch64/AArch64.td
index 46ef2c1..cd3e84d 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64.td
+++ b/contrib/llvm/lib/Target/AArch64/AArch64.td
@@ -90,6 +90,7 @@ def AArch64InstrInfo : InstrInfo;
include "AArch64SchedA53.td"
include "AArch64SchedA57.td"
include "AArch64SchedCyclone.td"
+include "AArch64SchedM1.td"
def ProcA35 : SubtargetFeature<"a35", "ARMProcFamily", "CortexA35",
"Cortex-A35 ARM processors",
@@ -144,8 +145,7 @@ def : ProcessorModel<"cortex-a57", CortexA57Model, [ProcA57]>;
// FIXME: Cortex-A72 is currently modelled as an Cortex-A57.
def : ProcessorModel<"cortex-a72", CortexA57Model, [ProcA57]>;
def : ProcessorModel<"cyclone", CycloneModel, [ProcCyclone]>;
-// FIXME: Exynos-M1 is currently modelled without a specific SchedModel.
-def : ProcessorModel<"exynos-m1", NoSchedModel, [ProcExynosM1]>;
+def : ProcessorModel<"exynos-m1", ExynosM1Model, [ProcExynosM1]>;
//===----------------------------------------------------------------------===//
// Assembly parser
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 9b73c5e..92cf1cd 100644
--- a/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -6689,6 +6689,9 @@ SDValue AArch64TargetLowering::LowerVSETCC(SDValue Op,
return DAG.getSExtOrTrunc(Cmp, dl, Op.getValueType());
}
+ if (LHS.getValueType().getVectorElementType() == MVT::f16)
+ return SDValue();
+
assert(LHS.getValueType().getVectorElementType() == MVT::f32 ||
LHS.getValueType().getVectorElementType() == MVT::f64);
diff --git a/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td b/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td
new file mode 100644
index 0000000..6525628
--- /dev/null
+++ b/contrib/llvm/lib/Target/AArch64/AArch64SchedM1.td
@@ -0,0 +1,359 @@
+//=- AArch64SchedM1.td - Samsung Exynos-M1 Scheduling Defs ---*- tablegen -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the machine model for Samsung Exynos-M1 to support
+// instruction scheduling and other instruction cost heuristics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// The Exynos-M1 is a traditional superscalar microprocessor with a
+// 4-wide in-order stage for decode and dispatch and a wider issue stage.
+// The execution units and loads and stores are out-of-order.
+
+def ExynosM1Model : SchedMachineModel {
+ let IssueWidth = 4; // Up to 4 uops per cycle.
+ let MinLatency = 0; // OoO.
+ let MicroOpBufferSize = 96; // ROB size.
+ let LoopMicroOpBufferSize = 32; // Instruction queue size.
+ let LoadLatency = 4; // Optimistic load cases.
+ let MispredictPenalty = 14; // Minimum branch misprediction penalty.
+ let CompleteModel = 0; // Use the default model otherwise.
+}
+
+//===----------------------------------------------------------------------===//
+// Define each kind of processor resource and number available on the Exynos-M1,
+// which has 9 pipelines, each with its own queue with out-of-order dispatch.
+
+def M1UnitA : ProcResource<2>; // Simple integer
+def M1UnitC : ProcResource<1>; // Simple and complex integer
+def M1UnitB : ProcResource<2>; // Branch
+def M1UnitL : ProcResource<1>; // Load
+def M1UnitS : ProcResource<1>; // Store
+def M1PipeF0 : ProcResource<1>; // FP #0
+def M1PipeF1 : ProcResource<1>; // FP #1
+
+let Super = M1PipeF0 in {
+ def M1UnitFMAC : ProcResource<1>; // FP multiplication
+ def M1UnitFCVT : ProcResource<1>; // FP conversion
+ def M1UnitNAL0 : ProcResource<1>; // Simple vector.
+ def M1UnitNMISC : ProcResource<1>; // Miscellanea
+ def M1UnitNCRYPT : ProcResource<1>; // Cryptographic
+}
+
+let Super = M1PipeF1 in {
+ def M1UnitFADD : ProcResource<1>; // Simple FP
+ let BufferSize = 1 in
+ def M1UnitFVAR : ProcResource<1>; // FP division & square root (serialized)
+ def M1UnitNAL1 : ProcResource<1>; // Simple vector.
+ def M1UnitFST : ProcResource<1>; // FP store
+}
+
+let SchedModel = ExynosM1Model in {
+ def M1UnitALU : ProcResGroup<[M1UnitA,
+ M1UnitC]>; // All simple integer.
+ def M1UnitNALU : ProcResGroup<[M1UnitNAL0,
+ M1UnitNAL1]>; // All simple vector.
+}
+
+let SchedModel = ExynosM1Model in {
+
+//===----------------------------------------------------------------------===//
+// Coarse scheduling model for the Exynos-M1.
+
+// Branch instructions.
+// TODO: Non-conditional direct branches take zero cycles and units.
+def : WriteRes<WriteBr, [M1UnitB]> { let Latency = 1; }
+def : WriteRes<WriteBrReg, [M1UnitC]> { let Latency = 1; }
+// TODO: Branch and link is much different.
+
+// Arithmetic and logical integer instructions.
+def : WriteRes<WriteI, [M1UnitALU]> { let Latency = 1; }
+// TODO: Shift over 3 and some extensions take 2 cycles.
+def : WriteRes<WriteISReg, [M1UnitALU]> { let Latency = 1; }
+def : WriteRes<WriteIEReg, [M1UnitALU]> { let Latency = 1; }
+def : WriteRes<WriteIS, [M1UnitALU]> { let Latency = 1; }
+
+// Move instructions.
+def : WriteRes<WriteImm, [M1UnitALU]> { let Latency = 1; }
+
+// Divide and multiply instructions.
+// TODO: Division blocks the divider inside C.
+def : WriteRes<WriteID32, [M1UnitC]> { let Latency = 13; }
+def : WriteRes<WriteID64, [M1UnitC]> { let Latency = 21; }
+// TODO: Long multiplication take 5 cycles and also the ALU.
+// TODO: Multiplication with accumulation can be advanced.
+def : WriteRes<WriteIM32, [M1UnitC]> { let Latency = 3; }
+// TODO: 64-bit multiplication has a throughput of 1/2.
+def : WriteRes<WriteIM64, [M1UnitC]> { let Latency = 4; }
+
+// Miscellaneous instructions.
+def : WriteRes<WriteExtr, [M1UnitALU,
+ M1UnitALU]> { let Latency = 2; }
+
+// TODO: The latency for the post or pre register is 1 cycle.
+def : WriteRes<WriteAdr, []> { let Latency = 0; }
+
+// Load instructions.
+def : WriteRes<WriteLD, [M1UnitL]> { let Latency = 4; }
+// TODO: Extended address requires also the ALU.
+def : WriteRes<WriteLDIdx, [M1UnitL]> { let Latency = 5; }
+def : WriteRes<WriteLDHi, [M1UnitALU]> { let Latency = 4; }
+
+// Store instructions.
+def : WriteRes<WriteST, [M1UnitS]> { let Latency = 1; }
+// TODO: Extended address requires also the ALU.
+def : WriteRes<WriteSTIdx, [M1UnitS]> { let Latency = 1; }
+def : WriteRes<WriteSTP, [M1UnitS]> { let Latency = 1; }
+def : WriteRes<WriteSTX, [M1UnitS]> { let Latency = 1; }
+
+// FP data instructions.
+def : WriteRes<WriteF, [M1UnitFADD]> { let Latency = 3; }
+// TODO: FCCMP is much different.
+def : WriteRes<WriteFCmp, [M1UnitNMISC]> { let Latency = 4; }
+// TODO: DP takes longer.
+def : WriteRes<WriteFDiv, [M1UnitFVAR]> { let Latency = 15; }
+// TODO: MACC takes longer.
+def : WriteRes<WriteFMul, [M1UnitFMAC]> { let Latency = 4; }
+
+// FP miscellaneous instructions.
+// TODO: Conversion between register files is much different.
+def : WriteRes<WriteFCvt, [M1UnitFCVT]> { let Latency = 3; }
+def : WriteRes<WriteFImm, [M1UnitNALU]> { let Latency = 1; }
+// TODO: Copy from FPR to GPR is much different.
+def : WriteRes<WriteFCopy, [M1UnitS]> { let Latency = 4; }
+
+// FP load instructions.
+// TODO: ASIMD loads are much different.
+def : WriteRes<WriteVLD, [M1UnitL]> { let Latency = 5; }
+
+// FP store instructions.
+// TODO: ASIMD stores are much different.
+def : WriteRes<WriteVST, [M1UnitS, M1UnitFST]> { let Latency = 1; }
+
+// ASIMD FP instructions.
+// TODO: Other operations are much different.
+def : WriteRes<WriteV, [M1UnitFADD]> { let Latency = 3; }
+
+// Other miscellaneous instructions.
+def : WriteRes<WriteSys, []> { let Latency = 1; }
+def : WriteRes<WriteBarrier, []> { let Latency = 1; }
+def : WriteRes<WriteHint, []> { let Latency = 1; }
+
+//===----------------------------------------------------------------------===//
+// Fast forwarding.
+
+// TODO: Add FP register forwarding rules.
+
+def : ReadAdvance<ReadI, 0>;
+def : ReadAdvance<ReadISReg, 0>;
+def : ReadAdvance<ReadIEReg, 0>;
+def : ReadAdvance<ReadIM, 0>;
+// Integer multiply-accumulate.
+// TODO: The forwarding for WriteIM64 saves actually 3 cycles.
+def : ReadAdvance<ReadIMA, 2, [WriteIM32, WriteIM64]>;
+def : ReadAdvance<ReadID, 0>;
+def : ReadAdvance<ReadExtrHi, 0>;
+def : ReadAdvance<ReadAdrBase, 0>;
+def : ReadAdvance<ReadVLD, 0>;
+
+//===----------------------------------------------------------------------===//
+// Finer scheduling model for the Exynos-M1.
+
+def M1WriteNEONA : SchedWriteRes<[M1UnitNALU,
+ M1UnitNALU,
+ M1UnitFADD]> { let Latency = 9; }
+def M1WriteNEONB : SchedWriteRes<[M1UnitNALU,
+ M1UnitFST]> { let Latency = 5; }
+def M1WriteNEONC : SchedWriteRes<[M1UnitNALU,
+ M1UnitFST]> { let Latency = 6; }
+def M1WriteNEOND : SchedWriteRes<[M1UnitNALU,
+ M1UnitFST,
+ M1UnitL]> { let Latency = 10; }
+def M1WriteNEONE : SchedWriteRes<[M1UnitFCVT,
+ M1UnitFST]> { let Latency = 8; }
+def M1WriteNEONF : SchedWriteRes<[M1UnitFCVT,
+ M1UnitFST,
+ M1UnitL]> { let Latency = 13; }
+def M1WriteNEONG : SchedWriteRes<[M1UnitNMISC,
+ M1UnitFST]> { let Latency = 6; }
+def M1WriteNEONH : SchedWriteRes<[M1UnitNALU,
+ M1UnitFST]> { let Latency = 3; }
+def M1WriteNEONI : SchedWriteRes<[M1UnitFST,
+ M1UnitL]> { let Latency = 9; }
+def M1WriteALU1 : SchedWriteRes<[M1UnitALU]> { let Latency = 1; }
+def M1WriteB : SchedWriteRes<[M1UnitB]> { let Latency = 1; }
+// FIXME: This is the worst case, conditional branch and link.
+def M1WriteBL : SchedWriteRes<[M1UnitB,
+ M1UnitALU]> { let Latency = 1; }
+// FIXME: This is the worst case, when using LR.
+def M1WriteBLR : SchedWriteRes<[M1UnitB,
+ M1UnitALU,
+ M1UnitALU]> { let Latency = 2; }
+def M1WriteC1 : SchedWriteRes<[M1UnitC]> { let Latency = 1; }
+def M1WriteC2 : SchedWriteRes<[M1UnitC]> { let Latency = 2; }
+def M1WriteFADD3 : SchedWriteRes<[M1UnitFADD]> { let Latency = 3; }
+def M1WriteFCVT3 : SchedWriteRes<[M1UnitFCVT]> { let Latency = 3; }
+def M1WriteFCVT4 : SchedWriteRes<[M1UnitFCVT]> { let Latency = 4; }
+def M1WriteFMAC4 : SchedWriteRes<[M1UnitFMAC]> { let Latency = 4; }
+def M1WriteFMAC5 : SchedWriteRes<[M1UnitFMAC]> { let Latency = 5; }
+def M1WriteFVAR15 : SchedWriteRes<[M1UnitFVAR]> { let Latency = 15; }
+def M1WriteFVAR23 : SchedWriteRes<[M1UnitFVAR]> { let Latency = 23; }
+def M1WriteNALU1 : SchedWriteRes<[M1UnitNALU]> { let Latency = 1; }
+def M1WriteNALU2 : SchedWriteRes<[M1UnitNALU]> { let Latency = 2; }
+def M1WriteNAL11 : SchedWriteRes<[M1UnitNAL1]> { let Latency = 1; }
+def M1WriteNAL12 : SchedWriteRes<[M1UnitNAL1]> { let Latency = 2; }
+def M1WriteNAL13 : SchedWriteRes<[M1UnitNAL1]> { let Latency = 3; }
+def M1WriteNCRYPT1 : SchedWriteRes<[M1UnitNCRYPT]> { let Latency = 1; }
+def M1WriteNCRYPT5 : SchedWriteRes<[M1UnitNCRYPT]> { let Latency = 5; }
+def M1WriteNMISC1 : SchedWriteRes<[M1UnitNMISC]> { let Latency = 1; }
+def M1WriteNMISC2 : SchedWriteRes<[M1UnitNMISC]> { let Latency = 2; }
+def M1WriteNMISC3 : SchedWriteRes<[M1UnitNMISC]> { let Latency = 3; }
+def M1WriteNMISC4 : SchedWriteRes<[M1UnitNMISC]> { let Latency = 4; }
+def M1WriteS4 : SchedWriteRes<[M1UnitS]> { let Latency = 4; }
+def M1WriteTB : SchedWriteRes<[M1UnitC,
+ M1UnitALU]> { let Latency = 2; }
+
+// Branch instructions
+def : InstRW<[M1WriteB ], (instrs Bcc)>;
+def : InstRW<[M1WriteBL], (instrs BL)>;
+def : InstRW<[M1WriteBLR], (instrs BLR)>;
+def : InstRW<[M1WriteC1], (instregex "^CBN?Z[WX]")>;
+def : InstRW<[M1WriteTB], (instregex "^TBN?Z[WX]")>;
+
+// Arithmetic and logical integer instructions.
+def : InstRW<[M1WriteALU1], (instrs COPY)>;
+
+// Divide and multiply instructions.
+
+// Miscellaneous instructions.
+
+// Load instructions.
+
+// Store instructions.
+
+// FP data instructions.
+def : InstRW<[M1WriteNALU1], (instregex "^F(ABS|NEG)[DS]r")>;
+def : InstRW<[M1WriteFADD3], (instregex "^F(ADD|SUB)[DS]rr")>;
+def : InstRW<[M1WriteNEONG], (instregex "^FCCMPE?[DS]rr")>;
+def : InstRW<[M1WriteNMISC4], (instregex "^FCMPE?[DS]r")>;
+def : InstRW<[M1WriteFVAR15], (instrs FDIVSrr)>;
+def : InstRW<[M1WriteFVAR23], (instrs FDIVDrr)>;
+def : InstRW<[M1WriteNMISC2], (instregex "^F(MAX|MIN).+rr")>;
+def : InstRW<[M1WriteFMAC4], (instregex "^FN?MUL[DS]rr")>;
+def : InstRW<[M1WriteFMAC5], (instregex "^FN?M(ADD|SUB)[DS]rrr")>;
+def : InstRW<[M1WriteFCVT3], (instregex "^FRINT.+r")>;
+def : InstRW<[M1WriteNEONH], (instregex "^FCSEL[DS]rrr")>;
+def : InstRW<[M1WriteFVAR15], (instrs FSQRTSr)>;
+def : InstRW<[M1WriteFVAR23], (instrs FSQRTDr)>;
+
+// FP miscellaneous instructions.
+def : InstRW<[M1WriteFCVT3], (instregex "^FCVT[DS][DS]r")>;
+def : InstRW<[M1WriteNEONF], (instregex "^[FSU]CVT[AMNPZ][SU](_Int)?[SU]?[XW]?[DS]?[rds]i?")>;
+def : InstRW<[M1WriteNEONE], (instregex "^[SU]CVTF[SU]")>;
+def : InstRW<[M1WriteNALU1], (instregex "^FMOV[DS][ir]")>;
+def : InstRW<[M1WriteS4], (instregex "^FMOV[WX][DS](High)?r")>;
+def : InstRW<[M1WriteNEONI], (instregex "^FMOV[DS][WX](High)?r")>;
+
+// FP load instructions.
+
+// FP store instructions.
+
+// ASIMD instructions.
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU]ABAL?v")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^[SU]ABDL?v")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^(SQ)?ABSv")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^SQNEGv")>;
+def : InstRW<[M1WriteNALU1], (instregex "^(ADD|NEG|SUB)v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU]?H(ADD|SUB)v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU]?AD[AD](L|LP|P|W)V?2?v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU]?SUB[LW]2?v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^R?(ADD|SUB)HN?2?v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU]+Q(ADD|SUB)v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU]RHADDv")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^CM(EQ|GE|GT|HI|HS|LE|LT)v")>;
+def : InstRW<[M1WriteNALU1], (instregex "^CMTSTv")>;
+def : InstRW<[M1WriteNALU1], (instregex "^(AND|BIC|EOR|MVNI|NOT|ORN|ORR)v")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^[SU](MIN|MAX)v")>;
+def : InstRW<[M1WriteNMISC2], (instregex "^[SU](MIN|MAX)Pv")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^[SU](MIN|MAX)Vv")>;
+def : InstRW<[M1WriteNMISC4], (instregex "^(MUL|SQR?DMULH)v")>;
+def : InstRW<[M1WriteNMISC4], (instregex "^ML[AS]v")>;
+def : InstRW<[M1WriteNMISC4], (instregex "^(S|U|SQD|SQRD)ML[AS][HL]v")>;
+def : InstRW<[M1WriteNMISC4], (instregex "^(S|U|SQD)MULLv")>;
+def : InstRW<[M1WriteNAL13], (instregex "^(S|SR|U|UR)SRAv")>;
+def : InstRW<[M1WriteNALU1], (instregex "^[SU]?SH(L|LL|R)2?v")>;
+def : InstRW<[M1WriteNALU1], (instregex "^S[LR]Iv")>;
+def : InstRW<[M1WriteNAL13], (instregex "^[SU]?(Q|QR|R)?SHR(N|U|UN)?2?v")>;
+def : InstRW<[M1WriteNAL13], (instregex "^[SU](Q|QR|R)SHLU?v")>;
+
+// ASIMD FP instructions.
+def : InstRW<[M1WriteNALU1], (instregex "^F(ABS|NEG)v")>;
+def : InstRW<[M1WriteNMISC3], (instregex "^F(ABD|ADD|SUB)v")>;
+def : InstRW<[M1WriteNEONA], (instregex "^FADDP")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^F(AC|CM)(EQ|GE|GT|LE|LT)v[^1]")>;
+def : InstRW<[M1WriteFCVT3], (instregex "^[FVSU]CVTX?[AFLMNPZ][SU]?(_Int)?v")>;
+def : InstRW<[M1WriteFVAR15], (instregex "FDIVv.f32")>;
+def : InstRW<[M1WriteFVAR23], (instregex "FDIVv2f64")>;
+def : InstRW<[M1WriteFVAR15], (instregex "FSQRTv.f32")>;
+def : InstRW<[M1WriteFVAR23], (instregex "FSQRTv2f64")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^F(MAX|MIN)(NM)?V?v")>;
+def : InstRW<[M1WriteNMISC2], (instregex "^F(MAX|MIN)(NM)?Pv")>;
+def : InstRW<[M1WriteFMAC4], (instregex "^FMULX?v")>;
+def : InstRW<[M1WriteFMAC5], (instregex "^FML[AS]v")>;
+def : InstRW<[M1WriteFCVT3], (instregex "^FRINT[AIMNPXZ]v")>;
+
+// ASIMD miscellaneous instructions.
+def : InstRW<[M1WriteNALU1], (instregex "^RBITv")>;
+def : InstRW<[M1WriteNAL11], (instregex "^(BIF|BIT|BSL)v")>;
+def : InstRW<[M1WriteNALU1], (instregex "^CPY")>;
+def : InstRW<[M1WriteNEONB], (instregex "^DUPv.+gpr")>;
+def : InstRW<[M1WriteNALU1], (instregex "^DUPv.+lane")>;
+def : InstRW<[M1WriteNAL13], (instregex "^[SU]?Q?XTU?Nv")>;
+def : InstRW<[M1WriteNEONC], (instregex "^INSv.+gpr")>;
+def : InstRW<[M1WriteFCVT4], (instregex "^[FU](RECP|RSQRT)Ev")>;
+def : InstRW<[M1WriteNMISC1], (instregex "^[FU](RECP|RSQRT)Xv")>;
+def : InstRW<[M1WriteFMAC5], (instregex "^F(RECP|RSQRT)Sv")>;
+def : InstRW<[M1WriteNALU1], (instregex "^REV(16|32|64)v")>;
+def : InstRW<[M1WriteNAL11], (instregex "^TB[LX]v8i8One")>;
+def : InstRW<[WriteSequence<[M1WriteNAL11], 2>],
+ (instregex "^TB[LX]v8i8Two")>;
+def : InstRW<[WriteSequence<[M1WriteNAL11], 3>],
+ (instregex "^TB[LX]v8i8Three")>;
+def : InstRW<[WriteSequence<[M1WriteNAL11], 4>],
+ (instregex "^TB[LX]v8i8Four")>;
+def : InstRW<[M1WriteNAL12], (instregex "^TB[LX]v16i8One")>;
+def : InstRW<[WriteSequence<[M1WriteNAL12], 2>],
+ (instregex "^TB[LX]v16i8Two")>;
+def : InstRW<[WriteSequence<[M1WriteNAL12], 3>],
+ (instregex "^TB[LX]v16i8Three")>;
+def : InstRW<[WriteSequence<[M1WriteNAL12], 4>],
+ (instregex "^TB[LX]v16i8Four")>;
+def : InstRW<[M1WriteNEOND], (instregex "^[SU]MOVv")>;
+def : InstRW<[M1WriteNALU1], (instregex "^INSv.+lane")>;
+def : InstRW<[M1WriteNALU1], (instregex "^(TRN|UZP)(1|2)(v8i8|v4i16|v2i32)")>;
+def : InstRW<[M1WriteNALU2], (instregex "^(TRN|UZP)(1|2)(v16i8|v8i16|v4i32|v2i64)")>;
+def : InstRW<[M1WriteNALU1], (instregex "^ZIP(1|2)v")>;
+
+// ASIMD load instructions.
+
+// ASIMD store instructions.
+
+// Cryptography instructions.
+def : InstRW<[M1WriteNCRYPT1], (instregex "^AES")>;
+def : InstRW<[M1WriteNCRYPT1], (instregex "^PMUL")>;
+def : InstRW<[M1WriteNCRYPT1], (instregex "^SHA1(H|SU)")>;
+def : InstRW<[M1WriteNCRYPT5], (instregex "^SHA1[CMP]")>;
+def : InstRW<[M1WriteNCRYPT1], (instregex "^SHA256SU0")>;
+def : InstRW<[M1WriteNCRYPT5], (instregex "^SHA256(H|SU1)")>;
+
+// CRC instructions.
+def : InstRW<[M1WriteC2], (instregex "^CRC32")>;
+
+} // SchedModel = ExynosM1Model
diff --git a/contrib/llvm/lib/Target/AMDGPU/AMDGPU.td b/contrib/llvm/lib/Target/AMDGPU/AMDGPU.td
index 79c6604..844d89c 100644
--- a/contrib/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/contrib/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -183,6 +183,7 @@ def FeatureISAVersion7_0_0 : SubtargetFeatureISAVersion <7,0,0>;
def FeatureISAVersion7_0_1 : SubtargetFeatureISAVersion <7,0,1>;
def FeatureISAVersion8_0_0 : SubtargetFeatureISAVersion <8,0,0>;
def FeatureISAVersion8_0_1 : SubtargetFeatureISAVersion <8,0,1>;
+def FeatureISAVersion8_0_3 : SubtargetFeatureISAVersion <8,0,3>;
class SubtargetFeatureLocalMemorySize <int Value> : SubtargetFeature<
"localmemorysize"#Value,
@@ -252,7 +253,7 @@ def FeatureSeaIslands : SubtargetFeatureGeneration<"SEA_ISLANDS",
def FeatureVolcanicIslands : SubtargetFeatureGeneration<"VOLCANIC_ISLANDS",
[Feature64BitPtr, FeatureFP64, FeatureLocalMemorySize65536,
FeatureWavefrontSize64, FeatureFlatAddressSpace, FeatureGCN,
- FeatureGCN3Encoding, FeatureCIInsts, FeatureLDSBankCount32]>;
+ FeatureGCN3Encoding, FeatureCIInsts]>;
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h b/contrib/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h
index 4796e9e..49c94f1 100644
--- a/contrib/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h
+++ b/contrib/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h
@@ -53,7 +53,8 @@ public:
ISAVersion7_0_0,
ISAVersion7_0_1,
ISAVersion8_0_0,
- ISAVersion8_0_1
+ ISAVersion8_0_1,
+ ISAVersion8_0_3
};
private:
diff --git a/contrib/llvm/lib/Target/AMDGPU/Processors.td b/contrib/llvm/lib/Target/AMDGPU/Processors.td
index a1584a2..4300d97 100644
--- a/contrib/llvm/lib/Target/AMDGPU/Processors.td
+++ b/contrib/llvm/lib/Target/AMDGPU/Processors.td
@@ -128,21 +128,23 @@ def : ProcessorModel<"mullins", SIQuarterSpeedModel,
//===----------------------------------------------------------------------===//
def : ProcessorModel<"tonga", SIQuarterSpeedModel,
- [FeatureVolcanicIslands, FeatureSGPRInitBug, FeatureISAVersion8_0_0]
+ [FeatureVolcanicIslands, FeatureSGPRInitBug, FeatureISAVersion8_0_0,
+ FeatureLDSBankCount32]
>;
def : ProcessorModel<"iceland", SIQuarterSpeedModel,
- [FeatureVolcanicIslands, FeatureSGPRInitBug, FeatureISAVersion8_0_0]
+ [FeatureVolcanicIslands, FeatureSGPRInitBug, FeatureISAVersion8_0_0,
+ FeatureLDSBankCount32]
>;
def : ProcessorModel<"carrizo", SIQuarterSpeedModel,
- [FeatureVolcanicIslands, FeatureISAVersion8_0_1]
+ [FeatureVolcanicIslands, FeatureISAVersion8_0_1, FeatureLDSBankCount32]
>;
def : ProcessorModel<"fiji", SIQuarterSpeedModel,
- [FeatureVolcanicIslands, FeatureISAVersion8_0_1]
+ [FeatureVolcanicIslands, FeatureISAVersion8_0_3, FeatureLDSBankCount32]
>;
def : ProcessorModel<"stoney", SIQuarterSpeedModel,
- [FeatureVolcanicIslands, FeatureISAVersion8_0_1]
+ [FeatureVolcanicIslands, FeatureISAVersion8_0_1, FeatureLDSBankCount16]
>;
diff --git a/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 609f5e7..025ed2b 100644
--- a/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -234,6 +234,7 @@ void SIRegisterInfo::buildScratchLoadStore(MachineBasicBlock::iterator MI,
bool IsLoad = TII->get(LoadStoreOp).mayLoad();
bool RanOutOfSGPRs = false;
+ bool Scavenged = false;
unsigned SOffset = ScratchOffset;
unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode());
@@ -244,6 +245,8 @@ void SIRegisterInfo::buildScratchLoadStore(MachineBasicBlock::iterator MI,
if (SOffset == AMDGPU::NoRegister) {
RanOutOfSGPRs = true;
SOffset = AMDGPU::SGPR0;
+ } else {
+ Scavenged = true;
}
BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_U32), SOffset)
.addReg(ScratchOffset)
@@ -259,10 +262,14 @@ void SIRegisterInfo::buildScratchLoadStore(MachineBasicBlock::iterator MI,
getPhysRegSubReg(Value, &AMDGPU::VGPR_32RegClass, i) :
Value;
+ unsigned SOffsetRegState = 0;
+ if (i + 1 == e && Scavenged)
+ SOffsetRegState |= RegState::Kill;
+
BuildMI(*MBB, MI, DL, TII->get(LoadStoreOp))
.addReg(SubReg, getDefRegState(IsLoad))
.addReg(ScratchRsrcReg)
- .addReg(SOffset)
+ .addReg(SOffset, SOffsetRegState)
.addImm(Offset)
.addImm(0) // glc
.addImm(0) // slc
diff --git a/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 3b4c235..1f5deae 100644
--- a/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/contrib/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -41,6 +41,9 @@ IsaVersion getIsaVersion(const FeatureBitset &Features) {
if (Features.test(FeatureISAVersion8_0_1))
return {8, 0, 1};
+ if (Features.test(FeatureISAVersion8_0_3))
+ return {8, 0, 3};
+
return {0, 0, 0};
}
diff --git a/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index dfbb969..6e7edbf 100644
--- a/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/contrib/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -747,7 +747,7 @@ bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset,
// If Offset is a multiply-by-constant and it's profitable to extract a shift
// and use it in a shifted operand do so.
- if (Offset.getOpcode() == ISD::MUL) {
+ if (Offset.getOpcode() == ISD::MUL && N.hasOneUse()) {
unsigned PowerOfTwo = 0;
SDValue NewMulConst;
if (canExtractShiftFromMul(Offset, 31, PowerOfTwo, NewMulConst)) {
@@ -1422,7 +1422,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N,
// If OffReg is a multiply-by-constant and it's profitable to extract a shift
// and use it in a shifted operand do so.
- if (OffReg.getOpcode() == ISD::MUL) {
+ if (OffReg.getOpcode() == ISD::MUL && N.hasOneUse()) {
unsigned PowerOfTwo = 0;
SDValue NewMulConst;
if (canExtractShiftFromMul(OffReg, 3, PowerOfTwo, NewMulConst)) {
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
index b451ebf..16dcd46 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
+++ b/contrib/llvm/lib/Target/PowerPC/PPCFastISel.cpp
@@ -1615,7 +1615,7 @@ bool PPCFastISel::SelectRet(const Instruction *I) {
// extension rather than sign extension. Make sure we pass the return
// value extension property to integer materialization.
unsigned SrcReg =
- PPCMaterializeInt(CI, MVT::i64, VA.getLocInfo() == CCValAssign::SExt);
+ PPCMaterializeInt(CI, MVT::i64, VA.getLocInfo() != CCValAssign::ZExt);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);
@@ -2091,25 +2091,21 @@ unsigned PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT,
const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
&PPC::GPRCRegClass);
+ int64_t Imm = UseSExt ? CI->getSExtValue() : CI->getZExtValue();
// If the constant is in range, use a load-immediate.
- if (UseSExt && isInt<16>(CI->getSExtValue())) {
+ // Since LI will sign extend the constant we need to make sure that for
+ // our zeroext constants that the sign extended constant fits into 16-bits -
+ // a range of 0..0x7fff.
+ if (isInt<16>(Imm)) {
unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
unsigned ImmReg = createResultReg(RC);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg)
- .addImm(CI->getSExtValue());
- return ImmReg;
- } else if (!UseSExt && isUInt<16>(CI->getZExtValue())) {
- unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
- unsigned ImmReg = createResultReg(RC);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg)
- .addImm(CI->getZExtValue());
+ .addImm(Imm);
return ImmReg;
}
// Construct the constant piecewise.
- int64_t Imm = CI->getZExtValue();
-
if (VT == MVT::i64)
return PPCMaterialize64BitInt(Imm, RC);
else if (VT == MVT::i32)
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/contrib/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index cb0271f..5367468 100644
--- a/contrib/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/contrib/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -736,7 +736,7 @@ def VPKSHSS : VX1_Int_Ty2<398, "vpkshss", int_ppc_altivec_vpkshss,
def VPKSHUS : VX1_Int_Ty2<270, "vpkshus", int_ppc_altivec_vpkshus,
v16i8, v8i16>;
def VPKSWSS : VX1_Int_Ty2<462, "vpkswss", int_ppc_altivec_vpkswss,
- v16i8, v4i32>;
+ v8i16, v4i32>;
def VPKSWUS : VX1_Int_Ty2<334, "vpkswus", int_ppc_altivec_vpkswus,
v8i16, v4i32>;
def VPKUHUM : VXForm_1<14, (outs vrrc:$vD), (ins vrrc:$vA, vrrc:$vB),
diff --git a/contrib/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/contrib/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index ee73267..b0a6127 100644
--- a/contrib/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/contrib/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1849,7 +1849,7 @@ static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask,
if (CCMask == SystemZ::CCMASK_CMP_NE)
return SystemZ::CCMASK_TM_SOME_1;
}
- if (EffectivelyUnsigned && CmpVal <= Low) {
+ if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <= Low) {
if (CCMask == SystemZ::CCMASK_CMP_LT)
return SystemZ::CCMASK_TM_ALL_0;
if (CCMask == SystemZ::CCMASK_CMP_GE)
diff --git a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
index 34f3919..c12a3ed 100644
--- a/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/contrib/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1335,6 +1335,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::BR_CC, MVT::i1, Expand);
setOperationAction(ISD::SETCC, MVT::i1, Custom);
+ setOperationAction(ISD::SETCCE, MVT::i1, Custom);
setOperationAction(ISD::SELECT_CC, MVT::i1, Expand);
setOperationAction(ISD::XOR, MVT::i1, Legal);
setOperationAction(ISD::OR, MVT::i1, Legal);
@@ -14975,8 +14976,11 @@ SDValue X86TargetLowering::LowerSETCCE(SDValue Op, SelectionDAG &DAG) const {
assert(Carry.getOpcode() != ISD::CARRY_FALSE);
SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
SDValue Cmp = DAG.getNode(X86ISD::SBB, DL, VTs, LHS, RHS, Carry);
- return DAG.getNode(X86ISD::SETCC, DL, Op.getValueType(),
- DAG.getConstant(CC, DL, MVT::i8), Cmp.getValue(1));
+ SDValue SetCC = DAG.getNode(X86ISD::SETCC, DL, MVT::i8,
+ DAG.getConstant(CC, DL, MVT::i8), Cmp.getValue(1));
+ if (Op.getSimpleValueType() == MVT::i1)
+ return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);
+ return SetCC;
}
// isX86LogicalCmp - Return true if opcode is a X86 logical comparison.
@@ -16315,6 +16319,11 @@ static SDValue getMaskNode(SDValue Mask, MVT MaskVT,
const X86Subtarget *Subtarget,
SelectionDAG &DAG, SDLoc dl) {
+ if (isAllOnesConstant(Mask))
+ return DAG.getTargetConstant(1, dl, MaskVT);
+ if (X86::isZeroNode(Mask))
+ return DAG.getTargetConstant(0, dl, MaskVT);
+
if (MaskVT.bitsGT(Mask.getSimpleValueType())) {
// Mask should be extended
Mask = DAG.getNode(ISD::ANY_EXTEND, dl,
@@ -17203,26 +17212,14 @@ static SDValue getGatherNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl, MVT::i8);
MVT MaskVT = MVT::getVectorVT(MVT::i1,
Index.getSimpleValueType().getVectorNumElements());
- SDValue MaskInReg;
- ConstantSDNode *MaskC = dyn_cast<ConstantSDNode>(Mask);
- if (MaskC)
- MaskInReg = DAG.getTargetConstant(MaskC->getSExtValue(), dl, MaskVT);
- else {
- MVT BitcastVT = MVT::getVectorVT(MVT::i1,
- Mask.getSimpleValueType().getSizeInBits());
- // In case when MaskVT equals v2i1 or v4i1, low 2 or 4 elements
- // are extracted by EXTRACT_SUBVECTOR.
- MaskInReg = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MaskVT,
- DAG.getBitcast(BitcastVT, Mask),
- DAG.getIntPtrConstant(0, dl));
- }
+ SDValue VMask = getMaskNode(Mask, MaskVT, Subtarget, DAG, dl);
SDVTList VTs = DAG.getVTList(Op.getValueType(), MaskVT, MVT::Other);
SDValue Disp = DAG.getTargetConstant(0, dl, MVT::i32);
SDValue Segment = DAG.getRegister(0, MVT::i32);
if (Src.getOpcode() == ISD::UNDEF)
Src = getZeroVector(Op.getSimpleValueType(), Subtarget, DAG, dl);
- SDValue Ops[] = {Src, MaskInReg, Base, Scale, Index, Disp, Segment, Chain};
+ SDValue Ops[] = {Src, VMask, Base, Scale, Index, Disp, Segment, Chain};
SDNode *Res = DAG.getMachineNode(Opc, dl, VTs, Ops);
SDValue RetOps[] = { SDValue(Res, 0), SDValue(Res, 2) };
return DAG.getMergeValues(RetOps, dl);
@@ -17230,7 +17227,8 @@ static SDValue getGatherNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
static SDValue getScatterNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
SDValue Src, SDValue Mask, SDValue Base,
- SDValue Index, SDValue ScaleOp, SDValue Chain) {
+ SDValue Index, SDValue ScaleOp, SDValue Chain,
+ const X86Subtarget &Subtarget) {
SDLoc dl(Op);
auto *C = cast<ConstantSDNode>(ScaleOp);
SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl, MVT::i8);
@@ -17238,29 +17236,18 @@ static SDValue getScatterNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
SDValue Segment = DAG.getRegister(0, MVT::i32);
MVT MaskVT = MVT::getVectorVT(MVT::i1,
Index.getSimpleValueType().getVectorNumElements());
- SDValue MaskInReg;
- ConstantSDNode *MaskC = dyn_cast<ConstantSDNode>(Mask);
- if (MaskC)
- MaskInReg = DAG.getTargetConstant(MaskC->getSExtValue(), dl, MaskVT);
- else {
- MVT BitcastVT = MVT::getVectorVT(MVT::i1,
- Mask.getSimpleValueType().getSizeInBits());
- // In case when MaskVT equals v2i1 or v4i1, low 2 or 4 elements
- // are extracted by EXTRACT_SUBVECTOR.
- MaskInReg = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, MaskVT,
- DAG.getBitcast(BitcastVT, Mask),
- DAG.getIntPtrConstant(0, dl));
- }
+ SDValue VMask = getMaskNode(Mask, MaskVT, &Subtarget, DAG, dl);
SDVTList VTs = DAG.getVTList(MaskVT, MVT::Other);
- SDValue Ops[] = {Base, Scale, Index, Disp, Segment, MaskInReg, Src, Chain};
+ SDValue Ops[] = {Base, Scale, Index, Disp, Segment, VMask, Src, Chain};
SDNode *Res = DAG.getMachineNode(Opc, dl, VTs, Ops);
return SDValue(Res, 1);
}
static SDValue getPrefetchNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
SDValue Mask, SDValue Base, SDValue Index,
- SDValue ScaleOp, SDValue Chain) {
+ SDValue ScaleOp, SDValue Chain,
+ const X86Subtarget &Subtarget) {
SDLoc dl(Op);
auto *C = cast<ConstantSDNode>(ScaleOp);
SDValue Scale = DAG.getTargetConstant(C->getZExtValue(), dl, MVT::i8);
@@ -17268,14 +17255,9 @@ static SDValue getPrefetchNode(unsigned Opc, SDValue Op, SelectionDAG &DAG,
SDValue Segment = DAG.getRegister(0, MVT::i32);
MVT MaskVT =
MVT::getVectorVT(MVT::i1, Index.getSimpleValueType().getVectorNumElements());
- SDValue MaskInReg;
- ConstantSDNode *MaskC = dyn_cast<ConstantSDNode>(Mask);
- if (MaskC)
- MaskInReg = DAG.getTargetConstant(MaskC->getSExtValue(), dl, MaskVT);
- else
- MaskInReg = DAG.getBitcast(MaskVT, Mask);
+ SDValue VMask = getMaskNode(Mask, MaskVT, &Subtarget, DAG, dl);
//SDVTList VTs = DAG.getVTList(MVT::Other);
- SDValue Ops[] = {MaskInReg, Base, Scale, Index, Disp, Segment, Chain};
+ SDValue Ops[] = {VMask, Base, Scale, Index, Disp, Segment, Chain};
SDNode *Res = DAG.getMachineNode(Opc, dl, MVT::Other, Ops);
return SDValue(Res, 0);
}
@@ -17509,7 +17491,7 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget *Subtarget,
SDValue Src = Op.getOperand(5);
SDValue Scale = Op.getOperand(6);
return getScatterNode(IntrData->Opc0, Op, DAG, Src, Mask, Base, Index,
- Scale, Chain);
+ Scale, Chain, *Subtarget);
}
case PREFETCH: {
SDValue Hint = Op.getOperand(6);
@@ -17521,7 +17503,8 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget *Subtarget,
SDValue Index = Op.getOperand(3);
SDValue Base = Op.getOperand(4);
SDValue Scale = Op.getOperand(5);
- return getPrefetchNode(Opcode, Op, DAG, Mask, Base, Index, Scale, Chain);
+ return getPrefetchNode(Opcode, Op, DAG, Mask, Base, Index, Scale, Chain,
+ *Subtarget);
}
// Read Time Stamp Counter (RDTSC) and Processor ID (RDTSCP).
case RDTSC: {
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index c0786af..d9311a3 100644
--- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3560,7 +3560,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
BO1->getOperand(0));
}
- if (CI->isMaxValue(true)) {
+ if (BO0->getOpcode() == Instruction::Xor && CI->isMaxValue(true)) {
ICmpInst::Predicate Pred = I.isSigned()
? I.getUnsignedPredicate()
: I.getSignedPredicate();
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 47406b9..dd2889d 100644
--- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -557,7 +557,8 @@ static Instruction *unpackLoadToAggregate(InstCombiner &IC, LoadInst &LI) {
ConstantInt::get(IdxType, i),
};
auto *Ptr = IC.Builder->CreateInBoundsGEP(ST, Addr, makeArrayRef(Indices), EltName);
- auto *L = IC.Builder->CreateLoad(ST->getTypeAtIndex(i), Ptr, LoadName);
+ auto *L = IC.Builder->CreateAlignedLoad(Ptr, LI.getAlignment(),
+ LoadName);
V = IC.Builder->CreateInsertValue(V, L, i);
}
diff --git a/contrib/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/contrib/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 5cde31a..bc4c0eb 100644
--- a/contrib/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/contrib/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -380,6 +380,23 @@ static void replaceExtractElements(InsertElementInst *InsElt,
ExtendMask.push_back(UndefValue::get(IntType));
Value *ExtVecOp = ExtElt->getVectorOperand();
+ auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
+ BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
+ ? ExtVecOpInst->getParent()
+ : ExtElt->getParent();
+
+ // TODO: This restriction matches the basic block check below when creating
+ // new extractelement instructions. If that limitation is removed, this one
+ // could also be removed. But for now, we just bail out to ensure that we
+ // will replace the extractelement instruction that is feeding our
+ // insertelement instruction. This allows the insertelement to then be
+ // replaced by a shufflevector. If the insertelement is not replaced, we can
+ // induce infinite looping because there's an optimization for extractelement
+ // that will delete our widening shuffle. This would trigger another attempt
+ // here to create that shuffle, and we spin forever.
+ if (InsertionBlock != InsElt->getParent())
+ return;
+
auto *WideVec = new ShuffleVectorInst(ExtVecOp, UndefValue::get(ExtVecType),
ConstantVector::get(ExtendMask));
@@ -387,7 +404,6 @@ static void replaceExtractElements(InsertElementInst *InsElt,
// (as long as it's not a PHI) or at the start of the basic block of the
// extract, so any subsequent extracts in the same basic block can use it.
// TODO: Insert before the earliest ExtractElementInst that is replaced.
- auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
if (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
WideVec->insertAfter(ExtVecOpInst);
else
diff --git a/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 3125a2c..e484b69 100644
--- a/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/contrib/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -90,6 +90,11 @@ static cl::opt<bool> SpeculateOneExpensiveInst(
cl::desc("Allow exactly one expensive instruction to be speculatively "
"executed"));
+static cl::opt<unsigned> MaxSpeculationDepth(
+ "max-speculation-depth", cl::Hidden, cl::init(10),
+ cl::desc("Limit maximum recursion depth when calculating costs of "
+ "speculatively executed instructions"));
+
STATISTIC(NumBitMaps, "Number of switch instructions turned into bitmaps");
STATISTIC(NumLinearMaps, "Number of switch instructions turned into linear mapping");
STATISTIC(NumLookupTables, "Number of switch instructions turned into lookup tables");
@@ -269,6 +274,13 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
unsigned &CostRemaining,
const TargetTransformInfo &TTI,
unsigned Depth = 0) {
+ // It is possible to hit a zero-cost cycle (phi/gep instructions for example),
+ // so limit the recursion depth.
+ // TODO: While this recursion limit does prevent pathological behavior, it
+ // would be better to track visited instructions to avoid cycles.
+ if (Depth == MaxSpeculationDepth)
+ return false;
+
Instruction *I = dyn_cast<Instruction>(V);
if (!I) {
// Non-instructions all dominate instructions, but not all constantexprs
diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h
index ffe1ff3..29aa642 100644
--- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h
+++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h
@@ -2229,7 +2229,8 @@ public:
bool CheckPointerConversion(Expr *From, QualType ToType,
CastKind &Kind,
CXXCastPath& BasePath,
- bool IgnoreBaseAccess);
+ bool IgnoreBaseAccess,
+ bool Diagnose = true);
bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
bool InOverloadResolution,
QualType &ConvertedType);
@@ -5388,7 +5389,8 @@ public:
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name,
- CXXCastPath *BasePath);
+ CXXCastPath *BasePath,
+ bool IgnoreAccess = false);
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
@@ -7514,14 +7516,15 @@ public:
ObjCMethodDecl *&ClassMethod,
ObjCMethodDecl *&InstanceMethod,
TypedefNameDecl *&TDNDecl,
- bool CfToNs);
-
+ bool CfToNs, bool Diagnose = true);
+
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
QualType DestType, QualType SrcType,
- Expr *&SrcExpr);
-
- bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
-
+ Expr *&SrcExpr, bool Diagnose = true);
+
+ bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr,
+ bool Diagnose = true);
+
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
/// \brief Check whether the given new method is a valid override of the
@@ -8613,6 +8616,7 @@ public:
ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
QualType castType, Expr *&op,
CheckedConversionKind CCK,
+ bool Diagnose = true,
bool DiagnoseCFAudited = false,
BinaryOperatorKind Opc = BO_PtrMemD
);
diff --git a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
index 0ab1fa7..2ab5a32 100644
--- a/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/ASTDiagnostic.cpp
@@ -473,14 +473,14 @@ class TemplateDiff {
/// ShowColor - Diagnostics support color, so bolding will be used.
bool ShowColor;
- /// FromType - When single type printing is selected, this is the type to be
- /// be printed. When tree printing is selected, this type will show up first
- /// in the tree.
- QualType FromType;
+ /// FromTemplateType - When single type printing is selected, this is the
+ /// type to be be printed. When tree printing is selected, this type will
+ /// show up first in the tree.
+ QualType FromTemplateType;
- /// ToType - The type that FromType is compared to. Only in tree printing
- /// will this type be outputed.
- QualType ToType;
+ /// ToTemplateType - The type that FromType is compared to. Only in tree
+ /// printing will this type be outputed.
+ QualType ToTemplateType;
/// OS - The stream used to construct the output strings.
raw_ostream &OS;
@@ -491,82 +491,70 @@ class TemplateDiff {
/// DiffTree - A tree representation the differences between two types.
class DiffTree {
public:
- /// DiffKind - The difference in a DiffNode and which fields are used.
+ /// DiffKind - The difference in a DiffNode. Fields of
+ /// TemplateArgumentInfo needed by each difference can be found in the
+ /// Set* and Get* functions.
enum DiffKind {
/// Incomplete or invalid node.
Invalid,
- /// Another level of templates, uses TemplateDecl and Qualifiers
+ /// Another level of templates, requires that
Template,
- /// Type difference, uses QualType
+ /// Type difference, all type differences except those falling under
+ /// the Template difference.
Type,
- /// Expression difference, uses Expr
+ /// Expression difference, this is only when both arguments are
+ /// expressions. If one argument is an expression and the other is
+ /// Integer or Declaration, then use that diff type instead.
Expression,
- /// Template argument difference, uses TemplateDecl
+ /// Template argument difference
TemplateTemplate,
- /// Integer difference, uses APSInt and Expr
+ /// Integer difference
Integer,
- /// Declaration difference, uses ValueDecl
- Declaration
+ /// Declaration difference, nullptr arguments are included here
+ Declaration,
+ /// One argument being integer and the other being declaration
+ FromIntegerAndToDeclaration,
+ FromDeclarationAndToInteger
};
+
private:
+ /// TemplateArgumentInfo - All the information needed to pretty print
+ /// a template argument. See the Set* and Get* functions to see which
+ /// fields are used for each DiffKind.
+ struct TemplateArgumentInfo {
+ QualType ArgType;
+ Qualifiers Qual;
+ llvm::APSInt Val;
+ bool IsValidInt = false;
+ Expr *ArgExpr = nullptr;
+ TemplateDecl *TD = nullptr;
+ ValueDecl *VD = nullptr;
+ bool NeedAddressOf = false;
+ bool IsNullPtr = false;
+ bool IsDefault = false;
+ };
+
/// DiffNode - The root node stores the original type. Each child node
/// stores template arguments of their parents. For templated types, the
/// template decl is also stored.
struct DiffNode {
- DiffKind Kind;
+ DiffKind Kind = Invalid;
/// NextNode - The index of the next sibling node or 0.
- unsigned NextNode;
+ unsigned NextNode = 0;
/// ChildNode - The index of the first child node or 0.
- unsigned ChildNode;
+ unsigned ChildNode = 0;
/// ParentNode - The index of the parent node.
- unsigned ParentNode;
-
- /// FromType, ToType - The type arguments.
- QualType FromType, ToType;
-
- /// FromExpr, ToExpr - The expression arguments.
- Expr *FromExpr, *ToExpr;
-
- /// FromNullPtr, ToNullPtr - If the template argument is a nullptr
- bool FromNullPtr, ToNullPtr;
-
- /// FromTD, ToTD - The template decl for template template
- /// arguments or the type arguments that are templates.
- TemplateDecl *FromTD, *ToTD;
-
- /// FromQual, ToQual - Qualifiers for template types.
- Qualifiers FromQual, ToQual;
+ unsigned ParentNode = 0;
- /// FromInt, ToInt - APSInt's for integral arguments.
- llvm::APSInt FromInt, ToInt;
-
- /// IsValidFromInt, IsValidToInt - Whether the APSInt's are valid.
- bool IsValidFromInt, IsValidToInt;
-
- /// FromValueDecl, ToValueDecl - Whether the argument is a decl.
- ValueDecl *FromValueDecl, *ToValueDecl;
-
- /// FromAddressOf, ToAddressOf - Whether the ValueDecl needs an address of
- /// operator before it.
- bool FromAddressOf, ToAddressOf;
-
- /// FromDefault, ToDefault - Whether the argument is a default argument.
- bool FromDefault, ToDefault;
+ TemplateArgumentInfo FromArgInfo, ToArgInfo;
/// Same - Whether the two arguments evaluate to the same value.
- bool Same;
-
- DiffNode(unsigned ParentNode = 0)
- : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
- FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
- FromNullPtr(false), ToNullPtr(false),
- FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),
- IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),
- FromAddressOf(false), ToAddressOf(false), FromDefault(false),
- ToDefault(false), Same(false) {}
+ bool Same = false;
+
+ DiffNode(unsigned ParentNode = 0) : ParentNode(ParentNode) {}
};
/// FlatTree - A flattened tree used to store the DiffNodes.
@@ -581,54 +569,127 @@ class TemplateDiff {
/// ReadNode - The index of the current node being read.
unsigned ReadNode;
-
+
public:
DiffTree() :
CurrentNode(0), NextFreeNode(1) {
FlatTree.push_back(DiffNode());
}
- // Node writing functions.
- /// SetNode - Sets FromTD and ToTD of the current node.
- void SetNode(TemplateDecl *FromTD, TemplateDecl *ToTD) {
- FlatTree[CurrentNode].FromTD = FromTD;
- FlatTree[CurrentNode].ToTD = ToTD;
+ // Node writing functions, one for each valid DiffKind element.
+ void SetTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
+ Qualifiers FromQual, Qualifiers ToQual,
+ bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Template;
+ FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
+ FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
+ FlatTree[CurrentNode].FromArgInfo.Qual = FromQual;
+ FlatTree[CurrentNode].ToArgInfo.Qual = ToQual;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetTypeDiff(QualType FromType, QualType ToType, bool FromDefault,
+ bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Type;
+ FlatTree[CurrentNode].FromArgInfo.ArgType = FromType;
+ FlatTree[CurrentNode].ToArgInfo.ArgType = ToType;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetExpressionDiff(Expr *FromExpr, Expr *ToExpr, bool FromDefault,
+ bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Expression;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetTemplateTemplateDiff(TemplateDecl *FromTD, TemplateDecl *ToTD,
+ bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = TemplateTemplate;
+ FlatTree[CurrentNode].FromArgInfo.TD = FromTD;
+ FlatTree[CurrentNode].ToArgInfo.TD = ToTD;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetIntegerDiff(llvm::APSInt FromInt, llvm::APSInt ToInt,
+ bool IsValidFromInt, bool IsValidToInt,
+ QualType FromIntType, QualType ToIntType,
+ Expr *FromExpr, Expr *ToExpr, bool FromDefault,
+ bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Integer;
+ FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
+ FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
+ FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
+ FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
+ FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
+ FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetDeclarationDiff(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
+ bool FromAddressOf, bool ToAddressOf,
+ bool FromNullPtr, bool ToNullPtr, Expr *FromExpr,
+ Expr *ToExpr, bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = Declaration;
+ FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
+ FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
+ FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
+ FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
+ FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
+ FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetFromDeclarationAndToIntegerDiff(
+ ValueDecl *FromValueDecl, bool FromAddressOf, bool FromNullPtr,
+ Expr *FromExpr, llvm::APSInt ToInt, bool IsValidToInt,
+ QualType ToIntType, Expr *ToExpr, bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = FromDeclarationAndToInteger;
+ FlatTree[CurrentNode].FromArgInfo.VD = FromValueDecl;
+ FlatTree[CurrentNode].FromArgInfo.NeedAddressOf = FromAddressOf;
+ FlatTree[CurrentNode].FromArgInfo.IsNullPtr = FromNullPtr;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.Val = ToInt;
+ FlatTree[CurrentNode].ToArgInfo.IsValidInt = IsValidToInt;
+ FlatTree[CurrentNode].ToArgInfo.ArgType = ToIntType;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
+ }
+
+ void SetFromIntegerAndToDeclarationDiff(
+ llvm::APSInt FromInt, bool IsValidFromInt, QualType FromIntType,
+ Expr *FromExpr, ValueDecl *ToValueDecl, bool ToAddressOf,
+ bool ToNullPtr, Expr *ToExpr, bool FromDefault, bool ToDefault) {
+ assert(FlatTree[CurrentNode].Kind == Invalid && "Node is not empty.");
+ FlatTree[CurrentNode].Kind = FromIntegerAndToDeclaration;
+ FlatTree[CurrentNode].FromArgInfo.Val = FromInt;
+ FlatTree[CurrentNode].FromArgInfo.IsValidInt = IsValidFromInt;
+ FlatTree[CurrentNode].FromArgInfo.ArgType = FromIntType;
+ FlatTree[CurrentNode].FromArgInfo.ArgExpr = FromExpr;
+ FlatTree[CurrentNode].ToArgInfo.VD = ToValueDecl;
+ FlatTree[CurrentNode].ToArgInfo.NeedAddressOf = ToAddressOf;
+ FlatTree[CurrentNode].ToArgInfo.IsNullPtr = ToNullPtr;
+ FlatTree[CurrentNode].ToArgInfo.ArgExpr = ToExpr;
+ SetDefault(FromDefault, ToDefault);
}
- /// SetNode - Sets FromType and ToType of the current node.
- void SetNode(QualType FromType, QualType ToType) {
- FlatTree[CurrentNode].FromType = FromType;
- FlatTree[CurrentNode].ToType = ToType;
- }
-
- /// SetNode - Set FromExpr and ToExpr of the current node.
- void SetNode(Expr *FromExpr, Expr *ToExpr) {
- FlatTree[CurrentNode].FromExpr = FromExpr;
- FlatTree[CurrentNode].ToExpr = ToExpr;
- }
-
- /// SetNode - Set FromInt and ToInt of the current node.
- void SetNode(llvm::APSInt FromInt, llvm::APSInt ToInt,
- bool IsValidFromInt, bool IsValidToInt) {
- FlatTree[CurrentNode].FromInt = FromInt;
- FlatTree[CurrentNode].ToInt = ToInt;
- FlatTree[CurrentNode].IsValidFromInt = IsValidFromInt;
- FlatTree[CurrentNode].IsValidToInt = IsValidToInt;
- }
-
- /// SetNode - Set FromQual and ToQual of the current node.
- void SetNode(Qualifiers FromQual, Qualifiers ToQual) {
- FlatTree[CurrentNode].FromQual = FromQual;
- FlatTree[CurrentNode].ToQual = ToQual;
- }
-
- /// SetNode - Set FromValueDecl and ToValueDecl of the current node.
- void SetNode(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
- bool FromAddressOf, bool ToAddressOf) {
- FlatTree[CurrentNode].FromValueDecl = FromValueDecl;
- FlatTree[CurrentNode].ToValueDecl = ToValueDecl;
- FlatTree[CurrentNode].FromAddressOf = FromAddressOf;
- FlatTree[CurrentNode].ToAddressOf = ToAddressOf;
+ /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
+ void SetDefault(bool FromDefault, bool ToDefault) {
+ assert((!FromDefault || !ToDefault) && "Both arguments cannot be default.");
+ FlatTree[CurrentNode].FromArgInfo.IsDefault = FromDefault;
+ FlatTree[CurrentNode].ToArgInfo.IsDefault = ToDefault;
}
/// SetSame - Sets the same flag of the current node.
@@ -636,18 +697,6 @@ class TemplateDiff {
FlatTree[CurrentNode].Same = Same;
}
- /// SetNullPtr - Sets the NullPtr flags of the current node.
- void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {
- FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
- FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
- }
-
- /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
- void SetDefault(bool FromDefault, bool ToDefault) {
- FlatTree[CurrentNode].FromDefault = FromDefault;
- FlatTree[CurrentNode].ToDefault = ToDefault;
- }
-
/// SetKind - Sets the current node's type.
void SetKind(DiffKind Kind) {
FlatTree[CurrentNode].Kind = Kind;
@@ -655,12 +704,16 @@ class TemplateDiff {
/// Up - Changes the node to the parent of the current node.
void Up() {
+ assert(FlatTree[CurrentNode].Kind != Invalid &&
+ "Cannot exit node before setting node information.");
CurrentNode = FlatTree[CurrentNode].ParentNode;
}
/// AddNode - Adds a child node to the current node, then sets that node
/// node as the current node.
void AddNode() {
+ assert(FlatTree[CurrentNode].Kind == Template &&
+ "Only Template nodes can have children nodes.");
FlatTree.push_back(DiffNode(CurrentNode));
DiffNode &Node = FlatTree[CurrentNode];
if (Node.ChildNode == 0) {
@@ -692,46 +745,103 @@ class TemplateDiff {
ReadNode = FlatTree[ReadNode].ParentNode;
}
- /// GetNode - Gets the FromType and ToType.
- void GetNode(QualType &FromType, QualType &ToType) {
- FromType = FlatTree[ReadNode].FromType;
- ToType = FlatTree[ReadNode].ToType;
+ void GetTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD,
+ Qualifiers &FromQual, Qualifiers &ToQual) {
+ assert(FlatTree[ReadNode].Kind == Template && "Unexpected kind.");
+ FromTD = FlatTree[ReadNode].FromArgInfo.TD;
+ ToTD = FlatTree[ReadNode].ToArgInfo.TD;
+ FromQual = FlatTree[ReadNode].FromArgInfo.Qual;
+ ToQual = FlatTree[ReadNode].ToArgInfo.Qual;
+ }
+
+ void GetTypeDiff(QualType &FromType, QualType &ToType) {
+ assert(FlatTree[ReadNode].Kind == Type && "Unexpected kind");
+ FromType = FlatTree[ReadNode].FromArgInfo.ArgType;
+ ToType = FlatTree[ReadNode].ToArgInfo.ArgType;
+ }
+
+ void GetExpressionDiff(Expr *&FromExpr, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == Expression && "Unexpected kind");
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetTemplateTemplateDiff(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
+ assert(FlatTree[ReadNode].Kind == TemplateTemplate && "Unexpected kind.");
+ FromTD = FlatTree[ReadNode].FromArgInfo.TD;
+ ToTD = FlatTree[ReadNode].ToArgInfo.TD;
+ }
+
+ void GetIntegerDiff(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
+ bool &IsValidFromInt, bool &IsValidToInt,
+ QualType &FromIntType, QualType &ToIntType,
+ Expr *&FromExpr, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == Integer && "Unexpected kind.");
+ FromInt = FlatTree[ReadNode].FromArgInfo.Val;
+ ToInt = FlatTree[ReadNode].ToArgInfo.Val;
+ IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
+ IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
+ FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
+ ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetDeclarationDiff(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
+ bool &FromAddressOf, bool &ToAddressOf,
+ bool &FromNullPtr, bool &ToNullPtr, Expr *&FromExpr,
+ Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == Declaration && "Unexpected kind.");
+ FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
+ ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
+ FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
+ ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
+ FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
+ ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetFromDeclarationAndToIntegerDiff(
+ ValueDecl *&FromValueDecl, bool &FromAddressOf, bool &FromNullPtr,
+ Expr *&FromExpr, llvm::APSInt &ToInt, bool &IsValidToInt,
+ QualType &ToIntType, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == FromDeclarationAndToInteger &&
+ "Unexpected kind.");
+ FromValueDecl = FlatTree[ReadNode].FromArgInfo.VD;
+ FromAddressOf = FlatTree[ReadNode].FromArgInfo.NeedAddressOf;
+ FromNullPtr = FlatTree[ReadNode].FromArgInfo.IsNullPtr;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToInt = FlatTree[ReadNode].ToArgInfo.Val;
+ IsValidToInt = FlatTree[ReadNode].ToArgInfo.IsValidInt;
+ ToIntType = FlatTree[ReadNode].ToArgInfo.ArgType;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
+ }
+
+ void GetFromIntegerAndToDeclarationDiff(
+ llvm::APSInt &FromInt, bool &IsValidFromInt, QualType &FromIntType,
+ Expr *&FromExpr, ValueDecl *&ToValueDecl, bool &ToAddressOf,
+ bool &ToNullPtr, Expr *&ToExpr) {
+ assert(FlatTree[ReadNode].Kind == FromIntegerAndToDeclaration &&
+ "Unexpected kind.");
+ FromInt = FlatTree[ReadNode].FromArgInfo.Val;
+ IsValidFromInt = FlatTree[ReadNode].FromArgInfo.IsValidInt;
+ FromIntType = FlatTree[ReadNode].FromArgInfo.ArgType;
+ FromExpr = FlatTree[ReadNode].FromArgInfo.ArgExpr;
+ ToValueDecl = FlatTree[ReadNode].ToArgInfo.VD;
+ ToAddressOf = FlatTree[ReadNode].ToArgInfo.NeedAddressOf;
+ ToNullPtr = FlatTree[ReadNode].ToArgInfo.IsNullPtr;
+ ToExpr = FlatTree[ReadNode].ToArgInfo.ArgExpr;
}
- /// GetNode - Gets the FromExpr and ToExpr.
- void GetNode(Expr *&FromExpr, Expr *&ToExpr) {
- FromExpr = FlatTree[ReadNode].FromExpr;
- ToExpr = FlatTree[ReadNode].ToExpr;
- }
-
- /// GetNode - Gets the FromTD and ToTD.
- void GetNode(TemplateDecl *&FromTD, TemplateDecl *&ToTD) {
- FromTD = FlatTree[ReadNode].FromTD;
- ToTD = FlatTree[ReadNode].ToTD;
- }
-
- /// GetNode - Gets the FromInt and ToInt.
- void GetNode(llvm::APSInt &FromInt, llvm::APSInt &ToInt,
- bool &IsValidFromInt, bool &IsValidToInt) {
- FromInt = FlatTree[ReadNode].FromInt;
- ToInt = FlatTree[ReadNode].ToInt;
- IsValidFromInt = FlatTree[ReadNode].IsValidFromInt;
- IsValidToInt = FlatTree[ReadNode].IsValidToInt;
- }
-
- /// GetNode - Gets the FromQual and ToQual.
- void GetNode(Qualifiers &FromQual, Qualifiers &ToQual) {
- FromQual = FlatTree[ReadNode].FromQual;
- ToQual = FlatTree[ReadNode].ToQual;
+ /// FromDefault - Return true if the from argument is the default.
+ bool FromDefault() {
+ return FlatTree[ReadNode].FromArgInfo.IsDefault;
}
- /// GetNode - Gets the FromValueDecl and ToValueDecl.
- void GetNode(ValueDecl *&FromValueDecl, ValueDecl *&ToValueDecl,
- bool &FromAddressOf, bool &ToAddressOf) {
- FromValueDecl = FlatTree[ReadNode].FromValueDecl;
- ToValueDecl = FlatTree[ReadNode].ToValueDecl;
- FromAddressOf = FlatTree[ReadNode].FromAddressOf;
- ToAddressOf = FlatTree[ReadNode].ToAddressOf;
+ /// ToDefault - Return true if the to argument is the default.
+ bool ToDefault() {
+ return FlatTree[ReadNode].ToArgInfo.IsDefault;
}
/// NodeIsSame - Returns true the arguments are the same.
@@ -764,26 +874,6 @@ class TemplateDiff {
return FlatTree[ReadNode].NextNode != 0;
}
- /// FromNullPtr - Returns true if the from argument is null.
- bool FromNullPtr() {
- return FlatTree[ReadNode].FromNullPtr;
- }
-
- /// ToNullPtr - Returns true if the to argument is null.
- bool ToNullPtr() {
- return FlatTree[ReadNode].ToNullPtr;
- }
-
- /// FromDefault - Return true if the from argument is the default.
- bool FromDefault() {
- return FlatTree[ReadNode].FromDefault;
- }
-
- /// ToDefault - Return true if the to argument is the default.
- bool ToDefault() {
- return FlatTree[ReadNode].ToDefault;
- }
-
/// Empty - Returns true if the tree has no information.
bool Empty() {
return GetKind() == Invalid;
@@ -797,102 +887,128 @@ class TemplateDiff {
DiffTree Tree;
- /// TSTiterator - an iterator that is used to enter a
- /// TemplateSpecializationType and read TemplateArguments inside template
- /// parameter packs in order with the rest of the TemplateArguments.
- struct TSTiterator {
+ /// TSTiterator - a pair of iterators that walks the
+ /// TemplateSpecializationType and the desugared TemplateSpecializationType.
+ /// The deseguared TemplateArgument should provide the canonical argument
+ /// for comparisons.
+ class TSTiterator {
typedef const TemplateArgument& reference;
typedef const TemplateArgument* pointer;
- /// TST - the template specialization whose arguments this iterator
- /// traverse over.
- const TemplateSpecializationType *TST;
+ /// InternalIterator - an iterator that is used to enter a
+ /// TemplateSpecializationType and read TemplateArguments inside template
+ /// parameter packs in order with the rest of the TemplateArguments.
+ struct InternalIterator {
+ /// TST - the template specialization whose arguments this iterator
+ /// traverse over.
+ const TemplateSpecializationType *TST;
- /// DesugarTST - desugared template specialization used to extract
- /// default argument information
- const TemplateSpecializationType *DesugarTST;
+ /// Index - the index of the template argument in TST.
+ unsigned Index;
- /// Index - the index of the template argument in TST.
- unsigned Index;
+ /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA
+ /// points to a TemplateArgument within a parameter pack.
+ TemplateArgument::pack_iterator CurrentTA;
- /// CurrentTA - if CurrentTA is not the same as EndTA, then CurrentTA
- /// points to a TemplateArgument within a parameter pack.
- TemplateArgument::pack_iterator CurrentTA;
+ /// EndTA - the end iterator of a parameter pack
+ TemplateArgument::pack_iterator EndTA;
- /// EndTA - the end iterator of a parameter pack
- TemplateArgument::pack_iterator EndTA;
+ /// InternalIterator - Constructs an iterator and sets it to the first
+ /// template argument.
+ InternalIterator(const TemplateSpecializationType *TST)
+ : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
+ if (isEnd()) return;
- /// TSTiterator - Constructs an iterator and sets it to the first template
- /// argument.
- TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
- : TST(TST),
- DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())),
- Index(0), CurrentTA(nullptr), EndTA(nullptr) {
- if (isEnd()) return;
+ // Set to first template argument. If not a parameter pack, done.
+ TemplateArgument TA = TST->getArg(0);
+ if (TA.getKind() != TemplateArgument::Pack) return;
- // Set to first template argument. If not a parameter pack, done.
- TemplateArgument TA = TST->getArg(0);
- if (TA.getKind() != TemplateArgument::Pack) return;
+ // Start looking into the parameter pack.
+ CurrentTA = TA.pack_begin();
+ EndTA = TA.pack_end();
- // Start looking into the parameter pack.
- CurrentTA = TA.pack_begin();
- EndTA = TA.pack_end();
+ // Found a valid template argument.
+ if (CurrentTA != EndTA) return;
- // Found a valid template argument.
- if (CurrentTA != EndTA) return;
+ // Parameter pack is empty, use the increment to get to a valid
+ // template argument.
+ ++(*this);
+ }
- // Parameter pack is empty, use the increment to get to a valid
- // template argument.
- ++(*this);
- }
+ /// isEnd - Returns true if the iterator is one past the end.
+ bool isEnd() const {
+ return Index >= TST->getNumArgs();
+ }
- /// isEnd - Returns true if the iterator is one past the end.
- bool isEnd() const {
- return Index >= TST->getNumArgs();
- }
+ /// &operator++ - Increment the iterator to the next template argument.
+ InternalIterator &operator++() {
+ if (isEnd()) {
+ return *this;
+ }
- /// &operator++ - Increment the iterator to the next template argument.
- TSTiterator &operator++() {
- // After the end, Index should be the default argument position in
- // DesugarTST, if it exists.
- if (isEnd()) {
- ++Index;
+ // If in a parameter pack, advance in the parameter pack.
+ if (CurrentTA != EndTA) {
+ ++CurrentTA;
+ if (CurrentTA != EndTA)
+ return *this;
+ }
+
+ // Loop until a template argument is found, or the end is reached.
+ while (true) {
+ // Advance to the next template argument. Break if reached the end.
+ if (++Index == TST->getNumArgs())
+ break;
+
+ // If the TemplateArgument is not a parameter pack, done.
+ TemplateArgument TA = TST->getArg(Index);
+ if (TA.getKind() != TemplateArgument::Pack)
+ break;
+
+ // Handle parameter packs.
+ CurrentTA = TA.pack_begin();
+ EndTA = TA.pack_end();
+
+ // If the parameter pack is empty, try to advance again.
+ if (CurrentTA != EndTA)
+ break;
+ }
return *this;
}
- // If in a parameter pack, advance in the parameter pack.
- if (CurrentTA != EndTA) {
- ++CurrentTA;
- if (CurrentTA != EndTA)
- return *this;
+ /// operator* - Returns the appropriate TemplateArgument.
+ reference operator*() const {
+ assert(!isEnd() && "Index exceeds number of arguments.");
+ if (CurrentTA == EndTA)
+ return TST->getArg(Index);
+ else
+ return *CurrentTA;
}
- // Loop until a template argument is found, or the end is reached.
- while (true) {
- // Advance to the next template argument. Break if reached the end.
- if (++Index == TST->getNumArgs()) break;
+ /// operator-> - Allow access to the underlying TemplateArgument.
+ pointer operator->() const {
+ return &operator*();
+ }
+ };
- // If the TemplateArgument is not a parameter pack, done.
- TemplateArgument TA = TST->getArg(Index);
- if (TA.getKind() != TemplateArgument::Pack) break;
+ InternalIterator SugaredIterator;
+ InternalIterator DesugaredIterator;
- // Handle parameter packs.
- CurrentTA = TA.pack_begin();
- EndTA = TA.pack_end();
+ public:
+ TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
+ : SugaredIterator(TST),
+ DesugaredIterator(
+ GetTemplateSpecializationType(Context, TST->desugar())) {}
- // If the parameter pack is empty, try to advance again.
- if (CurrentTA != EndTA) break;
- }
+ /// &operator++ - Increment the iterator to the next template argument.
+ TSTiterator &operator++() {
+ ++SugaredIterator;
+ ++DesugaredIterator;
return *this;
}
/// operator* - Returns the appropriate TemplateArgument.
reference operator*() const {
- assert(!isEnd() && "Index exceeds number of arguments.");
- if (CurrentTA == EndTA)
- return TST->getArg(Index);
- else
- return *CurrentTA;
+ return *SugaredIterator;
}
/// operator-> - Allow access to the underlying TemplateArgument.
@@ -900,16 +1016,27 @@ class TemplateDiff {
return &operator*();
}
- /// getDesugar - Returns the deduced template argument from DesguarTST
- reference getDesugar() const {
- return DesugarTST->getArg(Index);
+ /// isEnd - Returns true if no more TemplateArguments are available.
+ bool isEnd() const {
+ return SugaredIterator.isEnd();
+ }
+
+ /// hasDesugaredTA - Returns true if there is another TemplateArgument
+ /// available.
+ bool hasDesugaredTA() const {
+ return !DesugaredIterator.isEnd();
+ }
+
+ /// getDesugaredTA - Returns the desugared TemplateArgument.
+ reference getDesugaredTA() const {
+ return *DesugaredIterator;
}
};
// These functions build up the template diff tree, including functions to
- // retrieve and compare template arguments.
+ // retrieve and compare template arguments.
- static const TemplateSpecializationType * GetTemplateSpecializationType(
+ static const TemplateSpecializationType *GetTemplateSpecializationType(
ASTContext &Context, QualType Ty) {
if (const TemplateSpecializationType *TST =
Ty->getAs<TemplateSpecializationType>())
@@ -935,108 +1062,136 @@ class TemplateDiff {
return Ty->getAs<TemplateSpecializationType>();
}
- /// DiffTypes - Fills a DiffNode with information about a type difference.
- void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter,
- TemplateTypeParmDecl *FromDefaultTypeDecl,
- TemplateTypeParmDecl *ToDefaultTypeDecl) {
- QualType FromType = GetType(FromIter, FromDefaultTypeDecl);
- QualType ToType = GetType(ToIter, ToDefaultTypeDecl);
-
- Tree.SetNode(FromType, ToType);
- Tree.SetDefault(FromIter.isEnd() && !FromType.isNull(),
- ToIter.isEnd() && !ToType.isNull());
- Tree.SetKind(DiffTree::Type);
+ /// Returns true if the DiffType is Type and false for Template.
+ static bool OnlyPerformTypeDiff(ASTContext &Context, QualType FromType,
+ QualType ToType,
+ const TemplateSpecializationType *&FromArgTST,
+ const TemplateSpecializationType *&ToArgTST) {
if (FromType.isNull() || ToType.isNull())
- return;
+ return true;
- if (Context.hasSameType(FromType, ToType)) {
- Tree.SetSame(true);
- return;
- }
+ if (Context.hasSameType(FromType, ToType))
+ return true;
- const TemplateSpecializationType *FromArgTST =
- GetTemplateSpecializationType(Context, FromType);
- if (!FromArgTST)
- return;
+ FromArgTST = GetTemplateSpecializationType(Context, FromType);
+ ToArgTST = GetTemplateSpecializationType(Context, ToType);
- const TemplateSpecializationType *ToArgTST =
- GetTemplateSpecializationType(Context, ToType);
- if (!ToArgTST)
- return;
+ if (!FromArgTST || !ToArgTST)
+ return true;
if (!hasSameTemplate(FromArgTST, ToArgTST))
- return;
+ return true;
- Qualifiers FromQual = FromType.getQualifiers(),
- ToQual = ToType.getQualifiers();
- FromQual -= QualType(FromArgTST, 0).getQualifiers();
- ToQual -= QualType(ToArgTST, 0).getQualifiers();
- Tree.SetNode(FromArgTST->getTemplateName().getAsTemplateDecl(),
- ToArgTST->getTemplateName().getAsTemplateDecl());
- Tree.SetNode(FromQual, ToQual);
- Tree.SetKind(DiffTree::Template);
- DiffTemplate(FromArgTST, ToArgTST);
+ return false;
+ }
+
+ /// DiffTypes - Fills a DiffNode with information about a type difference.
+ void DiffTypes(const TSTiterator &FromIter, const TSTiterator &ToIter) {
+ QualType FromType = GetType(FromIter);
+ QualType ToType = GetType(ToIter);
+
+ bool FromDefault = FromIter.isEnd() && !FromType.isNull();
+ bool ToDefault = ToIter.isEnd() && !ToType.isNull();
+
+ const TemplateSpecializationType *FromArgTST = nullptr;
+ const TemplateSpecializationType *ToArgTST = nullptr;
+ if (OnlyPerformTypeDiff(Context, FromType, ToType, FromArgTST, ToArgTST)) {
+ Tree.SetTypeDiff(FromType, ToType, FromDefault, ToDefault);
+ Tree.SetSame(!FromType.isNull() && !ToType.isNull() &&
+ Context.hasSameType(FromType, ToType));
+ } else {
+ assert(FromArgTST && ToArgTST &&
+ "Both template specializations need to be valid.");
+ Qualifiers FromQual = FromType.getQualifiers(),
+ ToQual = ToType.getQualifiers();
+ FromQual -= QualType(FromArgTST, 0).getQualifiers();
+ ToQual -= QualType(ToArgTST, 0).getQualifiers();
+ Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(),
+ ToArgTST->getTemplateName().getAsTemplateDecl(),
+ FromQual, ToQual, FromDefault, ToDefault);
+ DiffTemplate(FromArgTST, ToArgTST);
+ }
}
/// DiffTemplateTemplates - Fills a DiffNode with information about a
/// template template difference.
void DiffTemplateTemplates(const TSTiterator &FromIter,
- const TSTiterator &ToIter,
- TemplateTemplateParmDecl *FromDefaultTemplateDecl,
- TemplateTemplateParmDecl *ToDefaultTemplateDecl) {
- TemplateDecl *FromDecl = GetTemplateDecl(FromIter, FromDefaultTemplateDecl);
- TemplateDecl *ToDecl = GetTemplateDecl(ToIter, ToDefaultTemplateDecl);
- Tree.SetNode(FromDecl, ToDecl);
+ const TSTiterator &ToIter) {
+ TemplateDecl *FromDecl = GetTemplateDecl(FromIter);
+ TemplateDecl *ToDecl = GetTemplateDecl(ToIter);
+ Tree.SetTemplateTemplateDiff(FromDecl, ToDecl, FromIter.isEnd() && FromDecl,
+ ToIter.isEnd() && ToDecl);
Tree.SetSame(FromDecl && ToDecl &&
FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
- Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);
- Tree.SetKind(DiffTree::TemplateTemplate);
}
/// InitializeNonTypeDiffVariables - Helper function for DiffNonTypes
- static void InitializeNonTypeDiffVariables(
- ASTContext &Context, const TSTiterator &Iter,
- NonTypeTemplateParmDecl *Default, bool &HasInt, bool &HasValueDecl,
- bool &IsNullPtr, Expr *&E, llvm::APSInt &Value, ValueDecl *&VD) {
- HasInt = !Iter.isEnd() && Iter->getKind() == TemplateArgument::Integral;
-
- HasValueDecl =
- !Iter.isEnd() && Iter->getKind() == TemplateArgument::Declaration;
-
- IsNullPtr = !Iter.isEnd() && Iter->getKind() == TemplateArgument::NullPtr;
-
- if (HasInt)
- Value = Iter->getAsIntegral();
- else if (HasValueDecl)
- VD = Iter->getAsDecl();
- else if (!IsNullPtr)
- E = GetExpr(Iter, Default);
-
- if (E && Default->getType()->isPointerType())
- IsNullPtr = CheckForNullPtr(Context, E);
- }
-
- /// NeedsAddressOf - Helper function for DiffNonTypes. Returns true if the
- /// ValueDecl needs a '&' when printed.
- static bool NeedsAddressOf(ValueDecl *VD, Expr *E,
- NonTypeTemplateParmDecl *Default) {
- if (!VD)
- return false;
-
- if (E) {
- if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) {
- if (UO->getOpcode() == UO_AddrOf) {
- return true;
+ static void InitializeNonTypeDiffVariables(ASTContext &Context,
+ const TSTiterator &Iter,
+ NonTypeTemplateParmDecl *Default,
+ llvm::APSInt &Value, bool &HasInt,
+ QualType &IntType, bool &IsNullPtr,
+ Expr *&E, ValueDecl *&VD,
+ bool &NeedAddressOf) {
+ if (!Iter.isEnd()) {
+ switch (Iter->getKind()) {
+ default:
+ llvm_unreachable("unknown ArgumentKind");
+ case TemplateArgument::Integral:
+ Value = Iter->getAsIntegral();
+ HasInt = true;
+ IntType = Iter->getIntegralType();
+ return;
+ case TemplateArgument::Declaration: {
+ VD = Iter->getAsDecl();
+ QualType ArgType = Iter->getParamTypeForDecl();
+ QualType VDType = VD->getType();
+ if (ArgType->isPointerType() &&
+ Context.hasSameType(ArgType->getPointeeType(), VDType))
+ NeedAddressOf = true;
+ return;
}
+ case TemplateArgument::NullPtr:
+ IsNullPtr = true;
+ return;
+ case TemplateArgument::Expression:
+ E = Iter->getAsExpr();
}
- return false;
+ } else if (!Default->isParameterPack()) {
+ E = Default->getDefaultArgument();
}
- if (!Default->getType()->isReferenceType()) {
- return true;
- }
+ if (!Iter.hasDesugaredTA()) return;
- return false;
+ const TemplateArgument& TA = Iter.getDesugaredTA();
+ switch (TA.getKind()) {
+ default:
+ llvm_unreachable("unknown ArgumentKind");
+ case TemplateArgument::Integral:
+ Value = TA.getAsIntegral();
+ HasInt = true;
+ IntType = TA.getIntegralType();
+ return;
+ case TemplateArgument::Declaration: {
+ VD = TA.getAsDecl();
+ QualType ArgType = TA.getParamTypeForDecl();
+ QualType VDType = VD->getType();
+ if (ArgType->isPointerType() &&
+ Context.hasSameType(ArgType->getPointeeType(), VDType))
+ NeedAddressOf = true;
+ return;
+ }
+ case TemplateArgument::NullPtr:
+ IsNullPtr = true;
+ return;
+ case TemplateArgument::Expression:
+ // TODO: Sometimes, the desugared template argument Expr differs from
+ // the sugared template argument Expr. It may be useful in the future
+ // but for now, it is just discarded.
+ if (!E)
+ E = TA.getAsExpr();
+ return;
+ }
}
/// DiffNonTypes - Handles any template parameters not handled by DiffTypes
@@ -1046,85 +1201,68 @@ class TemplateDiff {
NonTypeTemplateParmDecl *ToDefaultNonTypeDecl) {
Expr *FromExpr = nullptr, *ToExpr = nullptr;
llvm::APSInt FromInt, ToInt;
+ QualType FromIntType, ToIntType;
ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
- bool HasFromInt = false, HasToInt = false, HasFromValueDecl = false,
- HasToValueDecl = false, FromNullPtr = false, ToNullPtr = false;
- InitializeNonTypeDiffVariables(Context, FromIter, FromDefaultNonTypeDecl,
- HasFromInt, HasFromValueDecl, FromNullPtr,
- FromExpr, FromInt, FromValueDecl);
- InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl,
- HasToInt, HasToValueDecl, ToNullPtr,
- ToExpr, ToInt, ToValueDecl);
-
- assert(((!HasFromInt && !HasToInt) ||
- (!HasFromValueDecl && !HasToValueDecl)) &&
- "Template argument cannot be both integer and declaration");
-
- if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
- Tree.SetNode(FromExpr, ToExpr);
- Tree.SetDefault(FromIter.isEnd() && FromExpr, ToIter.isEnd() && ToExpr);
- if (FromDefaultNonTypeDecl->getType()->isIntegralOrEnumerationType()) {
- if (FromExpr)
- HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,
- FromDefaultNonTypeDecl->getType());
- if (ToExpr)
- HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,
- ToDefaultNonTypeDecl->getType());
- }
- if (HasFromInt && HasToInt) {
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
- Tree.SetSame(FromInt == ToInt);
- Tree.SetKind(DiffTree::Integer);
- } else if (HasFromInt || HasToInt) {
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
- Tree.SetSame(false);
- Tree.SetKind(DiffTree::Integer);
- } else {
- Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr) ||
- (FromNullPtr && ToNullPtr));
- Tree.SetNullPtr(FromNullPtr, ToNullPtr);
- Tree.SetKind(DiffTree::Expression);
- }
+ bool HasFromInt = false, HasToInt = false, FromNullPtr = false,
+ ToNullPtr = false, NeedFromAddressOf = false, NeedToAddressOf = false;
+ InitializeNonTypeDiffVariables(
+ Context, FromIter, FromDefaultNonTypeDecl, FromInt, HasFromInt,
+ FromIntType, FromNullPtr, FromExpr, FromValueDecl, NeedFromAddressOf);
+ InitializeNonTypeDiffVariables(Context, ToIter, ToDefaultNonTypeDecl, ToInt,
+ HasToInt, ToIntType, ToNullPtr, ToExpr,
+ ToValueDecl, NeedToAddressOf);
+
+ bool FromDefault = FromIter.isEnd() &&
+ (FromExpr || FromValueDecl || HasFromInt || FromNullPtr);
+ bool ToDefault = ToIter.isEnd() &&
+ (ToExpr || ToValueDecl || HasToInt || ToNullPtr);
+
+ bool FromDeclaration = FromValueDecl || FromNullPtr;
+ bool ToDeclaration = ToValueDecl || ToNullPtr;
+
+ if (FromDeclaration && HasToInt) {
+ Tree.SetFromDeclarationAndToIntegerDiff(
+ FromValueDecl, NeedFromAddressOf, FromNullPtr, FromExpr, ToInt,
+ HasToInt, ToIntType, ToExpr, FromDefault, ToDefault);
+ Tree.SetSame(false);
+ return;
+
+ }
+
+ if (HasFromInt && ToDeclaration) {
+ Tree.SetFromIntegerAndToDeclarationDiff(
+ FromInt, HasFromInt, FromIntType, FromExpr, ToValueDecl,
+ NeedToAddressOf, ToNullPtr, ToExpr, FromDefault, ToDefault);
+ Tree.SetSame(false);
return;
}
if (HasFromInt || HasToInt) {
- if (!HasFromInt && FromExpr)
- HasFromInt = GetInt(Context, FromIter, FromExpr, FromInt,
- FromDefaultNonTypeDecl->getType());
- if (!HasToInt && ToExpr)
- HasToInt = GetInt(Context, ToIter, ToExpr, ToInt,
- ToDefaultNonTypeDecl->getType());
- Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+ Tree.SetIntegerDiff(FromInt, ToInt, HasFromInt, HasToInt, FromIntType,
+ ToIntType, FromExpr, ToExpr, FromDefault, ToDefault);
if (HasFromInt && HasToInt) {
- Tree.SetSame(FromInt == ToInt);
- } else {
- Tree.SetSame(false);
+ Tree.SetSame(Context.hasSameType(FromIntType, ToIntType) &&
+ FromInt == ToInt);
}
- Tree.SetDefault(FromIter.isEnd() && HasFromInt,
- ToIter.isEnd() && HasToInt);
- Tree.SetKind(DiffTree::Integer);
return;
}
- if (!HasFromValueDecl && FromExpr)
- FromValueDecl = GetValueDecl(FromIter, FromExpr);
- if (!HasToValueDecl && ToExpr)
- ToValueDecl = GetValueDecl(ToIter, ToExpr);
-
- bool FromAddressOf =
- NeedsAddressOf(FromValueDecl, FromExpr, FromDefaultNonTypeDecl);
- bool ToAddressOf =
- NeedsAddressOf(ToValueDecl, ToExpr, ToDefaultNonTypeDecl);
-
- Tree.SetNullPtr(FromNullPtr, ToNullPtr);
- Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
- Tree.SetSame(FromValueDecl && ToValueDecl &&
- FromValueDecl->getCanonicalDecl() ==
- ToValueDecl->getCanonicalDecl());
- Tree.SetDefault(FromIter.isEnd() && FromValueDecl,
- ToIter.isEnd() && ToValueDecl);
- Tree.SetKind(DiffTree::Declaration);
+ if (FromDeclaration || ToDeclaration) {
+ Tree.SetDeclarationDiff(FromValueDecl, ToValueDecl, NeedFromAddressOf,
+ NeedToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
+ ToExpr, FromDefault, ToDefault);
+ bool BothNull = FromNullPtr && ToNullPtr;
+ bool SameValueDecl =
+ FromValueDecl && ToValueDecl &&
+ NeedFromAddressOf == NeedToAddressOf &&
+ FromValueDecl->getCanonicalDecl() == ToValueDecl->getCanonicalDecl();
+ Tree.SetSame(BothNull || SameValueDecl);
+ return;
+ }
+
+ assert((FromExpr || ToExpr) && "Both template arguments cannot be empty.");
+ Tree.SetExpressionDiff(FromExpr, ToExpr, FromDefault, ToDefault);
+ Tree.SetSame(IsEqualExpr(Context, FromExpr, ToExpr));
}
/// DiffTemplate - recursively visits template arguments and stores the
@@ -1149,28 +1287,23 @@ class TemplateDiff {
NamedDecl *FromParamND = ParamsFrom->getParam(FromParamIndex);
NamedDecl *ToParamND = ParamsTo->getParam(ToParamIndex);
- TemplateTypeParmDecl *FromDefaultTypeDecl =
- dyn_cast<TemplateTypeParmDecl>(FromParamND);
- TemplateTypeParmDecl *ToDefaultTypeDecl =
- dyn_cast<TemplateTypeParmDecl>(ToParamND);
- if (FromDefaultTypeDecl && ToDefaultTypeDecl)
- DiffTypes(FromIter, ToIter, FromDefaultTypeDecl, ToDefaultTypeDecl);
-
- TemplateTemplateParmDecl *FromDefaultTemplateDecl =
- dyn_cast<TemplateTemplateParmDecl>(FromParamND);
- TemplateTemplateParmDecl *ToDefaultTemplateDecl =
- dyn_cast<TemplateTemplateParmDecl>(ToParamND);
- if (FromDefaultTemplateDecl && ToDefaultTemplateDecl)
- DiffTemplateTemplates(FromIter, ToIter, FromDefaultTemplateDecl,
- ToDefaultTemplateDecl);
-
- NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
- dyn_cast<NonTypeTemplateParmDecl>(FromParamND);
- NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
- dyn_cast<NonTypeTemplateParmDecl>(ToParamND);
- if (FromDefaultNonTypeDecl && ToDefaultNonTypeDecl)
+ assert(FromParamND->getKind() == ToParamND->getKind() &&
+ "Parameter Decl are not the same kind.");
+
+ if (isa<TemplateTypeParmDecl>(FromParamND)) {
+ DiffTypes(FromIter, ToIter);
+ } else if (isa<TemplateTemplateParmDecl>(FromParamND)) {
+ DiffTemplateTemplates(FromIter, ToIter);
+ } else if (isa<NonTypeTemplateParmDecl>(FromParamND)) {
+ NonTypeTemplateParmDecl *FromDefaultNonTypeDecl =
+ cast<NonTypeTemplateParmDecl>(FromParamND);
+ NonTypeTemplateParmDecl *ToDefaultNonTypeDecl =
+ cast<NonTypeTemplateParmDecl>(ToParamND);
DiffNonTypes(FromIter, ToIter, FromDefaultNonTypeDecl,
ToDefaultNonTypeDecl);
+ } else {
+ llvm_unreachable("Unexpected Decl type.");
+ }
++FromIter;
++ToIter;
@@ -1239,140 +1372,27 @@ class TemplateDiff {
/// GetType - Retrieves the template type arguments, including default
/// arguments.
- static QualType GetType(const TSTiterator &Iter,
- TemplateTypeParmDecl *DefaultTTPD) {
- bool isVariadic = DefaultTTPD->isParameterPack();
-
+ static QualType GetType(const TSTiterator &Iter) {
if (!Iter.isEnd())
return Iter->getAsType();
- if (isVariadic)
- return QualType();
-
- QualType ArgType = DefaultTTPD->getDefaultArgument();
- if (ArgType->isDependentType())
- return Iter.getDesugar().getAsType();
-
- return ArgType;
- }
-
- /// GetExpr - Retrieves the template expression argument, including default
- /// arguments.
- static Expr *GetExpr(const TSTiterator &Iter,
- NonTypeTemplateParmDecl *DefaultNTTPD) {
- Expr *ArgExpr = nullptr;
- bool isVariadic = DefaultNTTPD->isParameterPack();
-
- if (!Iter.isEnd())
- ArgExpr = Iter->getAsExpr();
- else if (!isVariadic)
- ArgExpr = DefaultNTTPD->getDefaultArgument();
-
- if (ArgExpr)
- while (SubstNonTypeTemplateParmExpr *SNTTPE =
- dyn_cast<SubstNonTypeTemplateParmExpr>(ArgExpr))
- ArgExpr = SNTTPE->getReplacement();
-
- return ArgExpr;
- }
-
- /// GetInt - Retrieves the template integer argument, including evaluating
- /// default arguments. If the value comes from an expression, extend the
- /// APSInt to size of IntegerType to match the behavior in
- /// Sema::CheckTemplateArgument
- static bool GetInt(ASTContext &Context, const TSTiterator &Iter,
- Expr *ArgExpr, llvm::APSInt &Int, QualType IntegerType) {
- // Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument, otherwise expression needs to
- // be evaluatable.
- if (Iter.isEnd() && ArgExpr->isValueDependent()) {
- switch (Iter.getDesugar().getKind()) {
- case TemplateArgument::Integral:
- Int = Iter.getDesugar().getAsIntegral();
- return true;
- case TemplateArgument::Expression:
- ArgExpr = Iter.getDesugar().getAsExpr();
- Int = ArgExpr->EvaluateKnownConstInt(Context);
- Int = Int.extOrTrunc(Context.getTypeSize(IntegerType));
- return true;
- default:
- llvm_unreachable("Unexpected template argument kind");
- }
- } else if (ArgExpr->isEvaluatable(Context)) {
- Int = ArgExpr->EvaluateKnownConstInt(Context);
- Int = Int.extOrTrunc(Context.getTypeSize(IntegerType));
- return true;
- }
-
- return false;
- }
-
- /// GetValueDecl - Retrieves the template Decl argument, including
- /// default expression argument.
- static ValueDecl *GetValueDecl(const TSTiterator &Iter, Expr *ArgExpr) {
- // Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (Iter.isEnd() && ArgExpr->isValueDependent())
- switch (Iter.getDesugar().getKind()) {
- case TemplateArgument::Declaration:
- return Iter.getDesugar().getAsDecl();
- case TemplateArgument::Expression:
- ArgExpr = Iter.getDesugar().getAsExpr();
- return cast<DeclRefExpr>(ArgExpr)->getDecl();
- default:
- llvm_unreachable("Unexpected template argument kind");
- }
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
- if (!DRE) {
- UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens());
- if (!UO)
- return nullptr;
- DRE = cast<DeclRefExpr>(UO->getSubExpr());
- }
-
- return DRE->getDecl();
- }
-
- /// CheckForNullPtr - returns true if the expression can be evaluated as
- /// a null pointer
- static bool CheckForNullPtr(ASTContext &Context, Expr *E) {
- assert(E && "Expected expression");
-
- E = E->IgnoreParenCasts();
- if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
- return true;
-
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
- if (!DRE)
- return false;
-
- VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
- if (!VD || !VD->hasInit())
- return false;
-
- return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant(
- Context, Expr::NPC_ValueDependentIsNull);
+ if (Iter.hasDesugaredTA())
+ return Iter.getDesugaredTA().getAsType();
+ return QualType();
}
/// GetTemplateDecl - Retrieves the template template arguments, including
/// default arguments.
- static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter,
- TemplateTemplateParmDecl *DefaultTTPD) {
- bool isVariadic = DefaultTTPD->isParameterPack();
-
- TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument();
- TemplateDecl *DefaultTD = nullptr;
- if (TA.getKind() != TemplateArgument::Null)
- DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
-
+ static TemplateDecl *GetTemplateDecl(const TSTiterator &Iter) {
if (!Iter.isEnd())
return Iter->getAsTemplate().getAsTemplateDecl();
- if (!isVariadic)
- return DefaultTD;
-
+ if (Iter.hasDesugaredTA())
+ return Iter.getDesugaredTA().getAsTemplate().getAsTemplateDecl();
return nullptr;
}
- /// IsEqualExpr - Returns true if the expressions evaluate to the same value.
+ /// IsEqualExpr - Returns true if the expressions are the same in regards to
+ /// template arguments. These expressions are dependent, so profile them
+ /// instead of trying to evaluate them.
static bool IsEqualExpr(ASTContext &Context, Expr *FromExpr, Expr *ToExpr) {
if (FromExpr == ToExpr)
return true;
@@ -1380,47 +1400,10 @@ class TemplateDiff {
if (!FromExpr || !ToExpr)
return false;
- DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()),
- *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens());
-
- if (FromDRE || ToDRE) {
- if (!FromDRE || !ToDRE)
- return false;
- return FromDRE->getDecl() == ToDRE->getDecl();
- }
-
- Expr::EvalResult FromResult, ToResult;
- if (!FromExpr->EvaluateAsRValue(FromResult, Context) ||
- !ToExpr->EvaluateAsRValue(ToResult, Context)) {
- llvm::FoldingSetNodeID FromID, ToID;
- FromExpr->Profile(FromID, Context, true);
- ToExpr->Profile(ToID, Context, true);
- return FromID == ToID;
- }
-
- APValue &FromVal = FromResult.Val;
- APValue &ToVal = ToResult.Val;
-
- if (FromVal.getKind() != ToVal.getKind()) return false;
-
- switch (FromVal.getKind()) {
- case APValue::Int:
- return FromVal.getInt() == ToVal.getInt();
- case APValue::LValue: {
- APValue::LValueBase FromBase = FromVal.getLValueBase();
- APValue::LValueBase ToBase = ToVal.getLValueBase();
- if (FromBase.isNull() && ToBase.isNull())
- return true;
- if (FromBase.isNull() || ToBase.isNull())
- return false;
- return FromBase.get<const ValueDecl*>() ==
- ToBase.get<const ValueDecl*>();
- }
- case APValue::MemberPointer:
- return FromVal.getMemberPointerDecl() == ToVal.getMemberPointerDecl();
- default:
- llvm_unreachable("Unknown template argument expression.");
- }
+ llvm::FoldingSetNodeID FromID, ToID;
+ FromExpr->Profile(FromID, Context, true);
+ ToExpr->Profile(ToID, Context, true);
+ return FromID == ToID;
}
// These functions converts the tree representation of the template
@@ -1442,21 +1425,21 @@ class TemplateDiff {
llvm_unreachable("Template diffing failed with bad DiffNode");
case DiffTree::Type: {
QualType FromType, ToType;
- Tree.GetNode(FromType, ToType);
+ Tree.GetTypeDiff(FromType, ToType);
PrintTypeNames(FromType, ToType, Tree.FromDefault(), Tree.ToDefault(),
Tree.NodeIsSame());
return;
}
case DiffTree::Expression: {
Expr *FromExpr, *ToExpr;
- Tree.GetNode(FromExpr, ToExpr);
- PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
- Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+ Tree.GetExpressionDiff(FromExpr, ToExpr);
+ PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
+ Tree.NodeIsSame());
return;
}
case DiffTree::TemplateTemplate: {
TemplateDecl *FromTD, *ToTD;
- Tree.GetNode(FromTD, ToTD);
+ Tree.GetTemplateTemplateDiff(FromTD, ToTD);
PrintTemplateTemplate(FromTD, ToTD, Tree.FromDefault(),
Tree.ToDefault(), Tree.NodeIsSame());
return;
@@ -1465,26 +1448,70 @@ class TemplateDiff {
llvm::APSInt FromInt, ToInt;
Expr *FromExpr, *ToExpr;
bool IsValidFromInt, IsValidToInt;
- Tree.GetNode(FromExpr, ToExpr);
- Tree.GetNode(FromInt, ToInt, IsValidFromInt, IsValidToInt);
- PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt,
- FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
- Tree.NodeIsSame());
+ QualType FromIntType, ToIntType;
+ Tree.GetIntegerDiff(FromInt, ToInt, IsValidFromInt, IsValidToInt,
+ FromIntType, ToIntType, FromExpr, ToExpr);
+ PrintAPSInt(FromInt, ToInt, IsValidFromInt, IsValidToInt, FromIntType,
+ ToIntType, FromExpr, ToExpr, Tree.FromDefault(),
+ Tree.ToDefault(), Tree.NodeIsSame());
return;
}
case DiffTree::Declaration: {
ValueDecl *FromValueDecl, *ToValueDecl;
bool FromAddressOf, ToAddressOf;
- Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
+ bool FromNullPtr, ToNullPtr;
+ Expr *FromExpr, *ToExpr;
+ Tree.GetDeclarationDiff(FromValueDecl, ToValueDecl, FromAddressOf,
+ ToAddressOf, FromNullPtr, ToNullPtr, FromExpr,
+ ToExpr);
PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
- Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
- Tree.ToDefault(), Tree.NodeIsSame());
+ FromNullPtr, ToNullPtr, FromExpr, ToExpr,
+ Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+ return;
+ }
+ case DiffTree::FromDeclarationAndToInteger: {
+ ValueDecl *FromValueDecl;
+ bool FromAddressOf;
+ bool FromNullPtr;
+ Expr *FromExpr;
+ llvm::APSInt ToInt;
+ bool IsValidToInt;
+ QualType ToIntType;
+ Expr *ToExpr;
+ Tree.GetFromDeclarationAndToIntegerDiff(
+ FromValueDecl, FromAddressOf, FromNullPtr, FromExpr, ToInt,
+ IsValidToInt, ToIntType, ToExpr);
+ assert((FromValueDecl || FromNullPtr) && IsValidToInt);
+ PrintValueDeclAndInteger(FromValueDecl, FromAddressOf, FromNullPtr,
+ FromExpr, Tree.FromDefault(), ToInt, ToIntType,
+ ToExpr, Tree.ToDefault());
+ return;
+ }
+ case DiffTree::FromIntegerAndToDeclaration: {
+ llvm::APSInt FromInt;
+ bool IsValidFromInt;
+ QualType FromIntType;
+ Expr *FromExpr;
+ ValueDecl *ToValueDecl;
+ bool ToAddressOf;
+ bool ToNullPtr;
+ Expr *ToExpr;
+ Tree.GetFromIntegerAndToDeclarationDiff(
+ FromInt, IsValidFromInt, FromIntType, FromExpr, ToValueDecl,
+ ToAddressOf, ToNullPtr, ToExpr);
+ assert(IsValidFromInt && (ToValueDecl || ToNullPtr));
+ PrintIntegerAndValueDecl(FromInt, FromIntType, FromExpr,
+ Tree.FromDefault(), ToValueDecl, ToAddressOf,
+ ToNullPtr, ToExpr, Tree.ToDefault());
return;
}
case DiffTree::Template: {
// Node is root of template. Recurse on children.
TemplateDecl *FromTD, *ToTD;
- Tree.GetNode(FromTD, ToTD);
+ Qualifiers FromQual, ToQual;
+ Tree.GetTemplateDiff(FromTD, ToTD, FromQual, ToQual);
+
+ PrintQualifiers(FromQual, ToQual);
if (!Tree.HasChildren()) {
// If we're dealing with a template specialization with zero
@@ -1493,11 +1520,7 @@ class TemplateDiff {
return;
}
- Qualifiers FromQual, ToQual;
- Tree.GetNode(FromQual, ToQual);
- PrintQualifiers(FromQual, ToQual);
-
- OS << FromTD->getNameAsString() << '<';
+ OS << FromTD->getNameAsString() << '<';
Tree.MoveToChild();
unsigned NumElideArgs = 0;
do {
@@ -1604,40 +1627,36 @@ class TemplateDiff {
/// PrintExpr - Prints out the expr template arguments, highlighting argument
/// differences.
- void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr,
- bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) {
+ void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromDefault,
+ bool ToDefault, bool Same) {
assert((FromExpr || ToExpr) &&
"Only one template argument may be missing.");
if (Same) {
- PrintExpr(FromExpr, FromNullPtr);
+ PrintExpr(FromExpr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- PrintExpr(FromExpr, FromNullPtr);
+ PrintExpr(FromExpr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- PrintExpr(FromExpr, FromNullPtr);
+ PrintExpr(FromExpr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- PrintExpr(ToExpr, ToNullPtr);
+ PrintExpr(ToExpr);
Unbold();
OS << ']';
}
}
/// PrintExpr - Actual formatting and printing of expressions.
- void PrintExpr(const Expr *E, bool NullPtr = false) {
+ void PrintExpr(const Expr *E) {
if (E) {
E->printPretty(OS, nullptr, Policy);
return;
}
- if (NullPtr) {
- OS << "nullptr";
- return;
- }
OS << "(no argument)";
}
@@ -1677,28 +1696,40 @@ class TemplateDiff {
/// PrintAPSInt - Handles printing of integral arguments, highlighting
/// argument differences.
void PrintAPSInt(llvm::APSInt FromInt, llvm::APSInt ToInt,
- bool IsValidFromInt, bool IsValidToInt, Expr *FromExpr,
- Expr *ToExpr, bool FromDefault, bool ToDefault, bool Same) {
+ bool IsValidFromInt, bool IsValidToInt, QualType FromIntType,
+ QualType ToIntType, Expr *FromExpr, Expr *ToExpr,
+ bool FromDefault, bool ToDefault, bool Same) {
assert((IsValidFromInt || IsValidToInt) &&
"Only one integral argument may be missing.");
if (Same) {
- OS << FromInt.toString(10);
- } else if (!PrintTree) {
+ if (FromIntType->isBooleanType()) {
+ OS << ((FromInt == 0) ? "false" : "true");
+ } else {
+ OS << FromInt.toString(10);
+ }
+ return;
+ }
+
+ bool PrintType = IsValidFromInt && IsValidToInt &&
+ !Context.hasSameType(FromIntType, ToIntType);
+
+ if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
- PrintAPSInt(FromInt, FromExpr, IsValidFromInt);
+ PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
} else {
OS << (FromDefault ? "[(default) " : "[");
- PrintAPSInt(FromInt, FromExpr, IsValidFromInt);
+ PrintAPSInt(FromInt, FromExpr, IsValidFromInt, FromIntType, PrintType);
OS << " != " << (ToDefault ? "(default) " : "");
- PrintAPSInt(ToInt, ToExpr, IsValidToInt);
+ PrintAPSInt(ToInt, ToExpr, IsValidToInt, ToIntType, PrintType);
OS << ']';
}
}
/// PrintAPSInt - If valid, print the APSInt. If the expression is
/// gives more information, print it too.
- void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid) {
+ void PrintAPSInt(llvm::APSInt Val, Expr *E, bool Valid, QualType IntType,
+ bool PrintType) {
Bold();
if (Valid) {
if (HasExtraInfo(E)) {
@@ -1707,7 +1738,20 @@ class TemplateDiff {
OS << " aka ";
Bold();
}
- OS << Val.toString(10);
+ if (PrintType) {
+ Unbold();
+ OS << "(";
+ Bold();
+ IntType.print(OS, Context.getPrintingPolicy());
+ Unbold();
+ OS << ") ";
+ Bold();
+ }
+ if (IntType->isBooleanType()) {
+ OS << ((Val == 0) ? "false" : "true");
+ } else {
+ OS << Val.toString(10);
+ }
} else if (E) {
PrintExpr(E);
} else {
@@ -1716,8 +1760,8 @@ class TemplateDiff {
Unbold();
}
- /// HasExtraInfo - Returns true if E is not an integer literal or the
- /// negation of an integer literal
+ /// HasExtraInfo - Returns true if E is not an integer literal, the
+ /// negation of an integer literal, or a boolean literal.
bool HasExtraInfo(Expr *E) {
if (!E) return false;
@@ -1730,10 +1774,13 @@ class TemplateDiff {
if (isa<IntegerLiteral>(UO->getSubExpr()))
return false;
+ if (isa<CXXBoolLiteralExpr>(E))
+ return false;
+
return true;
}
- void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) {
+ void PrintValueDecl(ValueDecl *VD, bool AddressOf, Expr *E, bool NullPtr) {
if (VD) {
if (AddressOf)
OS << "&";
@@ -1742,6 +1789,17 @@ class TemplateDiff {
}
if (NullPtr) {
+ if (E && !isa<CXXNullPtrLiteralExpr>(E)) {
+ PrintExpr(E);
+ if (IsBold) {
+ Unbold();
+ OS << " aka ";
+ Bold();
+ } else {
+ OS << " aka ";
+ }
+ }
+
OS << "nullptr";
return;
}
@@ -1753,30 +1811,72 @@ class TemplateDiff {
/// argument differences.
void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
- bool ToNullPtr, bool FromDefault, bool ToDefault,
- bool Same) {
+ bool ToNullPtr, Expr *FromExpr, Expr *ToExpr,
+ bool FromDefault, bool ToDefault, bool Same) {
assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
"Only one Decl argument may be NULL");
if (Same) {
- PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromExpr, FromNullPtr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
+ PrintValueDecl(ToValueDecl, ToAddressOf, ToExpr, ToNullPtr);
+ Unbold();
+ OS << ']';
+ }
+
+ }
+
+ /// PrintValueDeclAndInteger - Uses the print functions for ValueDecl and
+ /// APSInt to print a mixed difference.
+ void PrintValueDeclAndInteger(ValueDecl *VD, bool NeedAddressOf,
+ bool IsNullPtr, Expr *VDExpr, bool DefaultDecl,
+ llvm::APSInt Val, QualType IntType,
+ Expr *IntExpr, bool DefaultInt) {
+ if (!PrintTree) {
+ OS << (DefaultDecl ? "(default) " : "");
+ Bold();
+ PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
Unbold();
+ } else {
+ OS << (DefaultDecl ? "[(default) " : "[");
+ Bold();
+ PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
+ Unbold();
+ OS << " != " << (DefaultInt ? "(default) " : "");
+ PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
OS << ']';
}
+ }
+ /// PrintIntegerAndValueDecl - Uses the print functions for APSInt and
+ /// ValueDecl to print a mixed difference.
+ void PrintIntegerAndValueDecl(llvm::APSInt Val, QualType IntType,
+ Expr *IntExpr, bool DefaultInt, ValueDecl *VD,
+ bool NeedAddressOf, bool IsNullPtr,
+ Expr *VDExpr, bool DefaultDecl) {
+ if (!PrintTree) {
+ OS << (DefaultInt ? "(default) " : "");
+ PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
+ } else {
+ OS << (DefaultInt ? "[(default) " : "[");
+ PrintAPSInt(Val, IntExpr, true /*Valid*/, IntType, false /*PrintType*/);
+ OS << " != " << (DefaultDecl ? "(default) " : "");
+ Bold();
+ PrintValueDecl(VD, NeedAddressOf, VDExpr, IsNullPtr);
+ Unbold();
+ OS << ']';
+ }
}
// Prints the appropriate placeholder for elided template arguments.
@@ -1866,21 +1966,21 @@ public:
PrintTree(PrintTree),
ShowColor(ShowColor),
// When printing a single type, the FromType is the one printed.
- FromType(PrintFromType ? FromType : ToType),
- ToType(PrintFromType ? ToType : FromType),
+ FromTemplateType(PrintFromType ? FromType : ToType),
+ ToTemplateType(PrintFromType ? ToType : FromType),
OS(OS),
IsBold(false) {
}
/// DiffTemplate - Start the template type diffing.
void DiffTemplate() {
- Qualifiers FromQual = FromType.getQualifiers(),
- ToQual = ToType.getQualifiers();
+ Qualifiers FromQual = FromTemplateType.getQualifiers(),
+ ToQual = ToTemplateType.getQualifiers();
const TemplateSpecializationType *FromOrigTST =
- GetTemplateSpecializationType(Context, FromType);
+ GetTemplateSpecializationType(Context, FromTemplateType);
const TemplateSpecializationType *ToOrigTST =
- GetTemplateSpecializationType(Context, ToType);
+ GetTemplateSpecializationType(Context, ToTemplateType);
// Only checking templates.
if (!FromOrigTST || !ToOrigTST)
@@ -1893,13 +1993,12 @@ public:
FromQual -= QualType(FromOrigTST, 0).getQualifiers();
ToQual -= QualType(ToOrigTST, 0).getQualifiers();
- Tree.SetNode(FromType, ToType);
- Tree.SetNode(FromQual, ToQual);
- Tree.SetKind(DiffTree::Template);
// Same base template, but different arguments.
- Tree.SetNode(FromOrigTST->getTemplateName().getAsTemplateDecl(),
- ToOrigTST->getTemplateName().getAsTemplateDecl());
+ Tree.SetTemplateDiff(FromOrigTST->getTemplateName().getAsTemplateDecl(),
+ ToOrigTST->getTemplateName().getAsTemplateDecl(),
+ FromQual, ToQual, false /*FromDefault*/,
+ false /*ToDefault*/);
DiffTemplate(FromOrigTST, ToOrigTST);
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 1bc6c51..4f0b124 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -6151,6 +6151,12 @@ public:
Builder.defineMacro("__s390x__");
Builder.defineMacro("__zarch__");
Builder.defineMacro("__LONG_DOUBLE_128__");
+
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+
if (HasTransactionalExecution)
Builder.defineMacro("__HTM__");
if (Opts.ZVector)
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/Address.h b/contrib/llvm/tools/clang/lib/CodeGen/Address.h
index 9d145fa..3343080 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/Address.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/Address.h
@@ -104,23 +104,15 @@ public:
};
}
-}
-namespace llvm {
- // Present a minimal LLVM-like casting interface.
- template <class U> inline U cast(clang::CodeGen::Address addr) {
- return U::castImpl(addr);
- }
- template <class U> inline bool isa(clang::CodeGen::Address addr) {
- return U::isaImpl(addr);
- }
+// Present a minimal LLVM-like casting interface.
+template <class U> inline U cast(CodeGen::Address addr) {
+ return U::castImpl(addr);
+}
+template <class U> inline bool isa(CodeGen::Address addr) {
+ return U::isaImpl(addr);
}
-namespace clang {
- // Make our custom isa and cast available in namespace clang, to mirror
- // what we do for LLVM's versions in Basic/LLVM.h.
- using llvm::isa;
- using llvm::cast;
}
#endif
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 015a739..5cfacac 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -483,7 +483,7 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
if (ThreadID != nullptr)
return ThreadID;
}
- if (auto OMPRegionInfo =
+ if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
if (OMPRegionInfo->getThreadIDVariable()) {
// Check if this an outlined function with thread id passed as argument.
@@ -1356,7 +1356,7 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
// return the address of that temp.
Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
SourceLocation Loc) {
- if (auto OMPRegionInfo =
+ if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
if (OMPRegionInfo->getThreadIDVariable())
return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
@@ -1717,15 +1717,10 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
}
// Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
// thread_id);
- auto *OMPRegionInfo =
- dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
- // Do not emit barrier call in the single directive emitted in some rare cases
- // for sections directives.
- if (OMPRegionInfo && OMPRegionInfo->getDirectiveKind() == OMPD_single)
- return;
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
getThreadID(CGF, Loc)};
- if (OMPRegionInfo) {
+ if (auto *OMPRegionInfo =
+ dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
auto *Result = CGF.EmitRuntimeCall(
createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
@@ -3649,8 +3644,6 @@ void CGOpenMPRuntime::emitCancellationPointCall(
// global_tid, kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
- if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
- return;
if (OMPRegionInfo->hasCancel()) {
llvm::Value *Args[] = {
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
@@ -3687,8 +3680,6 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
// kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
- if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
- return;
auto &&ThenGen = [this, Loc, CancelRegion,
OMPRegionInfo](CodeGenFunction &CGF) {
llvm::Value *Args[] = {
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 6855512..59821a8 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1657,50 +1657,51 @@ OpenMPDirectiveKind
CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
auto *CS = dyn_cast<CompoundStmt>(Stmt);
- if (CS && CS->size() > 1) {
- bool HasLastprivates = false;
- auto &&CodeGen = [&S, CS, &HasLastprivates](CodeGenFunction &CGF) {
- auto &C = CGF.CGM.getContext();
- auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
- // Emit helper vars inits.
- LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
- CGF.Builder.getInt32(0));
- auto *GlobalUBVal = CGF.Builder.getInt32(CS->size() - 1);
- LValue UB =
- createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
- LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
- CGF.Builder.getInt32(1));
- LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
- CGF.Builder.getInt32(0));
- // Loop counter.
- LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
- OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
- CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
- OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
- CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
- // Generate condition for loop.
- BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
- OK_Ordinary, S.getLocStart(),
- /*fpContractable=*/false);
- // Increment for loop counter.
- UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue,
- OK_Ordinary, S.getLocStart());
- auto BodyGen = [CS, &S, &IV](CodeGenFunction &CGF) {
- // Iterate through all sections and emit a switch construct:
- // switch (IV) {
- // case 0:
- // <SectionStmt[0]>;
- // break;
- // ...
- // case <NumSection> - 1:
- // <SectionStmt[<NumSection> - 1]>;
- // break;
- // }
- // .omp.sections.exit:
- auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
- auto *SwitchStmt = CGF.Builder.CreateSwitch(
- CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
- CS->size());
+ bool HasLastprivates = false;
+ auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF) {
+ auto &C = CGF.CGM.getContext();
+ auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
+ // Emit helper vars inits.
+ LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
+ CGF.Builder.getInt32(0));
+ auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1)
+ : CGF.Builder.getInt32(0);
+ LValue UB =
+ createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
+ LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
+ CGF.Builder.getInt32(1));
+ LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
+ CGF.Builder.getInt32(0));
+ // Loop counter.
+ LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
+ OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
+ CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
+ OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
+ CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
+ // Generate condition for loop.
+ BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
+ OK_Ordinary, S.getLocStart(),
+ /*fpContractable=*/false);
+ // Increment for loop counter.
+ UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
+ S.getLocStart());
+ auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) {
+ // Iterate through all sections and emit a switch construct:
+ // switch (IV) {
+ // case 0:
+ // <SectionStmt[0]>;
+ // break;
+ // ...
+ // case <NumSection> - 1:
+ // <SectionStmt[<NumSection> - 1]>;
+ // break;
+ // }
+ // .omp.sections.exit:
+ auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
+ auto *SwitchStmt = CGF.Builder.CreateSwitch(
+ CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
+ CS == nullptr ? 1 : CS->size());
+ if (CS) {
unsigned CaseNumber = 0;
for (auto *SubStmt : CS->children()) {
auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
@@ -1710,99 +1711,72 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
CGF.EmitBranch(ExitBB);
++CaseNumber;
}
- CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
- };
-
- CodeGenFunction::OMPPrivateScope LoopScope(CGF);
- if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
- // Emit implicit barrier to synchronize threads and avoid data races on
- // initialization of firstprivate variables.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(
- CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
- /*ForceSimpleCall=*/true);
+ } else {
+ auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
+ CGF.EmitBlock(CaseBB);
+ SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
+ CGF.EmitStmt(Stmt);
+ CGF.EmitBranch(ExitBB);
}
- CGF.EmitOMPPrivateClause(S, LoopScope);
- HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
- CGF.EmitOMPReductionClauseInit(S, LoopScope);
- (void)LoopScope.Privatize();
-
- // Emit static non-chunked loop.
- CGF.CGM.getOpenMPRuntime().emitForStaticInit(
- CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
- /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(),
- LB.getAddress(), UB.getAddress(), ST.getAddress());
- // UB = min(UB, GlobalUB);
- auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
- auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
- CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
- CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
- // IV = LB;
- CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
- // while (idx <= UB) { BODY; ++idx; }
- CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
- [](CodeGenFunction &) {});
- // Tell the runtime we are done.
- CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
- CGF.EmitOMPReductionClauseFinal(S);
-
- // Emit final copy of the lastprivate variables if IsLastIter != 0.
- if (HasLastprivates)
- CGF.EmitOMPLastprivateClauseFinal(
- S, CGF.Builder.CreateIsNotNull(
- CGF.EmitLoadOfScalar(IL, S.getLocStart())));
+ CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
};
- bool HasCancel = false;
- if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
- HasCancel = OSD->hasCancel();
- else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
- HasCancel = OPSD->hasCancel();
- CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
- HasCancel);
- // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
- // clause. Otherwise the barrier will be generated by the codegen for the
- // directive.
- if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
+ CodeGenFunction::OMPPrivateScope LoopScope(CGF);
+ if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
- OMPD_unknown);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
}
- return OMPD_sections;
- }
- // If only one section is found - no need to generate loop, emit as a single
- // region.
- bool HasFirstprivates;
- // No need to generate reductions for sections with single section region, we
- // can use original shared variables for all operations.
- bool HasReductions = S.hasClausesOfKind<OMPReductionClause>();
- // No need to generate lastprivates for sections with single section region,
- // we can use original shared variable for all calculations with barrier at
- // the end of the sections.
- bool HasLastprivates = S.hasClausesOfKind<OMPLastprivateClause>();
- auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) {
- CodeGenFunction::OMPPrivateScope SingleScope(CGF);
- HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
- CGF.EmitOMPPrivateClause(S, SingleScope);
- (void)SingleScope.Privatize();
+ CGF.EmitOMPPrivateClause(S, LoopScope);
+ HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
+ CGF.EmitOMPReductionClauseInit(S, LoopScope);
+ (void)LoopScope.Privatize();
+
+ // Emit static non-chunked loop.
+ CGF.CGM.getOpenMPRuntime().emitForStaticInit(
+ CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
+ /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(),
+ UB.getAddress(), ST.getAddress());
+ // UB = min(UB, GlobalUB);
+ auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
+ auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
+ CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
+ CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
+ // IV = LB;
+ CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
+ // while (idx <= UB) { BODY; ++idx; }
+ CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
+ [](CodeGenFunction &) {});
+ // Tell the runtime we are done.
+ CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
+ CGF.EmitOMPReductionClauseFinal(S);
- CGF.EmitStmt(Stmt);
+ // Emit final copy of the lastprivate variables if IsLastIter != 0.
+ if (HasLastprivates)
+ CGF.EmitOMPLastprivateClauseFinal(
+ S, CGF.Builder.CreateIsNotNull(
+ CGF.EmitLoadOfScalar(IL, S.getLocStart())));
};
- CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
- llvm::None, llvm::None, llvm::None,
- llvm::None);
- // Emit barrier for firstprivates, lastprivates or reductions only if
- // 'sections' directive has 'nowait' clause. Otherwise the barrier will be
- // generated by the codegen for the directive.
- if ((HasFirstprivates || HasLastprivates || HasReductions) &&
- S.getSingleClause<OMPNowaitClause>()) {
+
+ bool HasCancel = false;
+ if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
+ HasCancel = OSD->hasCancel();
+ else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
+ HasCancel = OPSD->hasCancel();
+ CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
+ HasCancel);
+ // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
+ // clause. Otherwise the barrier will be generated by the codegen for the
+ // directive.
+ if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown,
- /*EmitChecks=*/false,
- /*ForceSimpleCall=*/true);
+ CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
+ OMPD_unknown);
}
- return OMPD_single;
+ return OMPD_sections;
}
void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
index beede2e..b669353 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp
@@ -3233,6 +3233,8 @@ ToolChain::CXXStdlibType NetBSD::GetCXXStdlibType(const ArgList &Args) const {
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
return ToolChain::CST_Libcxx;
diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
index 5a2dbd3..b7ac24f 100644
--- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp
@@ -8317,6 +8317,8 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcv9:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
useLibgcc = false;
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
index 11f2329..82d81a8 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1742,13 +1742,18 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
/// otherwise. Loc is the location where this routine should point to
/// if there is an error, and Range is the source range to highlight
/// if there is an error.
+///
+/// If either InaccessibleBaseID or AmbigiousBaseConvID are 0, then the
+/// diagnostic for the respective type of error will be suppressed, but the
+/// check for ill-formed code will still be performed.
bool
Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
unsigned InaccessibleBaseID,
unsigned AmbigiousBaseConvID,
SourceLocation Loc, SourceRange Range,
DeclarationName Name,
- CXXCastPath *BasePath) {
+ CXXCastPath *BasePath,
+ bool IgnoreAccess) {
// First, determine whether the path from Derived to Base is
// ambiguous. This is slightly more expensive than checking whether
// the Derived to Base conversion exists, because here we need to
@@ -1761,7 +1766,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
(void)DerivationOkay;
if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) {
- if (InaccessibleBaseID) {
+ if (!IgnoreAccess) {
// Check that the base class can be accessed.
switch (CheckBaseClassAccess(Loc, Base, Derived, Paths.front(),
InaccessibleBaseID)) {
@@ -1810,12 +1815,10 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
SourceLocation Loc, SourceRange Range,
CXXCastPath *BasePath,
bool IgnoreAccess) {
- return CheckDerivedToBaseConversion(Derived, Base,
- IgnoreAccess ? 0
- : diag::err_upcast_to_inaccessible_base,
- diag::err_ambiguous_derived_to_base_conv,
- Loc, Range, DeclarationName(),
- BasePath);
+ return CheckDerivedToBaseConversion(
+ Derived, Base, diag::err_upcast_to_inaccessible_base,
+ diag::err_ambiguous_derived_to_base_conv, Loc, Range, DeclarationName(),
+ BasePath, IgnoreAccess);
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
index 3e89af6..ebf7981 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
@@ -3748,6 +3748,128 @@ bool Sema::CheckVecStepExpr(Expr *E) {
return CheckUnaryExprOrTypeTraitOperand(E, UETT_VecStep);
}
+static void captureVariablyModifiedType(ASTContext &Context, QualType T,
+ CapturingScopeInfo *CSI) {
+ assert(T->isVariablyModifiedType());
+ assert(CSI != nullptr);
+
+ // We're going to walk down into the type and look for VLA expressions.
+ do {
+ const Type *Ty = T.getTypePtr();
+ switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+ T = QualType();
+ break;
+ // These types are never variably-modified.
+ case Type::Builtin:
+ case Type::Complex:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::Record:
+ case Type::Enum:
+ case Type::Elaborated:
+ case Type::TemplateSpecialization:
+ case Type::ObjCObject:
+ case Type::ObjCInterface:
+ case Type::ObjCObjectPointer:
+ case Type::Pipe:
+ llvm_unreachable("type class is never variably-modified!");
+ case Type::Adjusted:
+ T = cast<AdjustedType>(Ty)->getOriginalType();
+ break;
+ case Type::Decayed:
+ T = cast<DecayedType>(Ty)->getPointeeType();
+ break;
+ case Type::Pointer:
+ T = cast<PointerType>(Ty)->getPointeeType();
+ break;
+ case Type::BlockPointer:
+ T = cast<BlockPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::LValueReference:
+ case Type::RValueReference:
+ T = cast<ReferenceType>(Ty)->getPointeeType();
+ break;
+ case Type::MemberPointer:
+ T = cast<MemberPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ // Losing element qualification here is fine.
+ T = cast<ArrayType>(Ty)->getElementType();
+ break;
+ case Type::VariableArray: {
+ // Losing element qualification here is fine.
+ const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
+
+ // Unknown size indication requires no size computation.
+ // Otherwise, evaluate and record it.
+ if (auto Size = VAT->getSizeExpr()) {
+ if (!CSI->isVLATypeCaptured(VAT)) {
+ RecordDecl *CapRecord = nullptr;
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+ CapRecord = LSI->Lambda;
+ } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+ CapRecord = CRSI->TheRecordDecl;
+ }
+ if (CapRecord) {
+ auto ExprLoc = Size->getExprLoc();
+ auto SizeType = Context.getSizeType();
+ // Build the non-static data member.
+ auto Field =
+ FieldDecl::Create(Context, CapRecord, ExprLoc, ExprLoc,
+ /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
+ /*BW*/ nullptr, /*Mutable*/ false,
+ /*InitStyle*/ ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ Field->setCapturedVLAType(VAT);
+ CapRecord->addDecl(Field);
+
+ CSI->addVLATypeCapture(ExprLoc, SizeType);
+ }
+ }
+ }
+ T = VAT->getElementType();
+ break;
+ }
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ T = cast<FunctionType>(Ty)->getReturnType();
+ break;
+ case Type::Paren:
+ case Type::TypeOf:
+ case Type::UnaryTransform:
+ case Type::Attributed:
+ case Type::SubstTemplateTypeParm:
+ case Type::PackExpansion:
+ // Keep walking after single level desugaring.
+ T = T.getSingleStepDesugaredType(Context);
+ break;
+ case Type::Typedef:
+ T = cast<TypedefType>(Ty)->desugar();
+ break;
+ case Type::Decltype:
+ T = cast<DecltypeType>(Ty)->desugar();
+ break;
+ case Type::Auto:
+ T = cast<AutoType>(Ty)->getDeducedType();
+ break;
+ case Type::TypeOfExpr:
+ T = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
+ break;
+ case Type::Atomic:
+ T = cast<AtomicType>(Ty)->getValueType();
+ break;
+ }
+ } while (!T.isNull() && T->isVariablyModifiedType());
+}
+
/// \brief Build a sizeof or alignof expression given a type operand.
ExprResult
Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
@@ -3763,6 +3885,20 @@ Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
CheckUnaryExprOrTypeTraitOperand(T, OpLoc, R, ExprKind))
return ExprError();
+ if (T->isVariablyModifiedType() && FunctionScopes.size() > 1) {
+ if (auto *TT = T->getAs<TypedefType>()) {
+ if (auto *CSI = dyn_cast<CapturingScopeInfo>(FunctionScopes.back())) {
+ DeclContext *DC = nullptr;
+ if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI))
+ DC = LSI->CallOperator;
+ else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI))
+ DC = CRSI->TheCapturedDecl;
+ if (DC && TT->getDecl()->getDeclContext() != DC)
+ captureVariablyModifiedType(Context, T, CSI);
+ }
+ }
+ }
+
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
@@ -7354,11 +7490,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
LHSType->isBlockPointerType()) &&
RHS.get()->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- CastKind Kind;
- CXXCastPath Path;
- CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
- if (ConvertRHS)
- RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
+ if (Diagnose || ConvertRHS) {
+ CastKind Kind;
+ CXXCastPath Path;
+ CheckPointerConversion(RHS.get(), LHSType, Kind, Path,
+ /*IgnoreBaseAccess=*/false, Diagnose);
+ if (ConvertRHS)
+ RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
+ }
return Compatible;
}
@@ -7376,8 +7515,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
}
Expr *PRE = RHS.get()->IgnoreParenCasts();
- if (ObjCProtocolExpr *OPE = dyn_cast<ObjCProtocolExpr>(PRE)) {
- ObjCProtocolDecl *PDecl = OPE->getProtocol();
+ if (Diagnose && isa<ObjCProtocolExpr>(PRE)) {
+ ObjCProtocolDecl *PDecl = cast<ObjCProtocolExpr>(PRE)->getProtocol();
if (PDecl && !PDecl->hasDefinition()) {
Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl->getName();
Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
@@ -7399,11 +7538,11 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
- DiagnoseCFAudited);
+ Diagnose, DiagnoseCFAudited);
if (getLangOpts().ObjC1 &&
- (CheckObjCBridgeRelatedConversions(E->getLocStart(),
- LHSType, E->getType(), E) ||
- ConversionToObjCStringLiteralCheck(LHSType, E))) {
+ (CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType,
+ E->getType(), E, Diagnose) ||
+ ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) {
RHS = E;
return Compatible;
}
@@ -8961,8 +9100,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
else {
Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount)
- CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
- Opc);
+ CheckObjCARCConversion(SourceRange(), LHSType, E,
+ CCK_ImplicitConversion, /*Diagnose=*/true,
+ /*DiagnoseCFAudited=*/false, Opc);
RHS = ImpCastExprToType(E, LHSType,
LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
}
@@ -11830,8 +11970,8 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
return new (Context) GNUNullExpr(Ty, TokenLoc);
}
-bool
-Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
+bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp,
+ bool Diagnose) {
if (!getLangOpts().ObjC1)
return false;
@@ -11857,8 +11997,9 @@ Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
if (!SL || !SL->isAscii())
return false;
- Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
- << FixItHint::CreateInsertion(SL->getLocStart(), "@");
+ if (Diagnose)
+ Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
+ << FixItHint::CreateInsertion(SL->getLocStart(), "@");
Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
return true;
}
@@ -13139,120 +13280,7 @@ bool Sema::tryCaptureVariable(
QualType QTy = Var->getType();
if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var))
QTy = PVD->getOriginalType();
- do {
- const Type *Ty = QTy.getTypePtr();
- switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base)
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
- QTy = QualType();
- break;
- // These types are never variably-modified.
- case Type::Builtin:
- case Type::Complex:
- case Type::Vector:
- case Type::ExtVector:
- case Type::Record:
- case Type::Enum:
- case Type::Elaborated:
- case Type::TemplateSpecialization:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- case Type::ObjCObjectPointer:
- case Type::Pipe:
- llvm_unreachable("type class is never variably-modified!");
- case Type::Adjusted:
- QTy = cast<AdjustedType>(Ty)->getOriginalType();
- break;
- case Type::Decayed:
- QTy = cast<DecayedType>(Ty)->getPointeeType();
- break;
- case Type::Pointer:
- QTy = cast<PointerType>(Ty)->getPointeeType();
- break;
- case Type::BlockPointer:
- QTy = cast<BlockPointerType>(Ty)->getPointeeType();
- break;
- case Type::LValueReference:
- case Type::RValueReference:
- QTy = cast<ReferenceType>(Ty)->getPointeeType();
- break;
- case Type::MemberPointer:
- QTy = cast<MemberPointerType>(Ty)->getPointeeType();
- break;
- case Type::ConstantArray:
- case Type::IncompleteArray:
- // Losing element qualification here is fine.
- QTy = cast<ArrayType>(Ty)->getElementType();
- break;
- case Type::VariableArray: {
- // Losing element qualification here is fine.
- const VariableArrayType *VAT = cast<VariableArrayType>(Ty);
-
- // Unknown size indication requires no size computation.
- // Otherwise, evaluate and record it.
- if (auto Size = VAT->getSizeExpr()) {
- if (!CSI->isVLATypeCaptured(VAT)) {
- RecordDecl *CapRecord = nullptr;
- if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
- CapRecord = LSI->Lambda;
- } else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
- CapRecord = CRSI->TheRecordDecl;
- }
- if (CapRecord) {
- auto ExprLoc = Size->getExprLoc();
- auto SizeType = Context.getSizeType();
- // Build the non-static data member.
- auto Field = FieldDecl::Create(
- Context, CapRecord, ExprLoc, ExprLoc,
- /*Id*/ nullptr, SizeType, /*TInfo*/ nullptr,
- /*BW*/ nullptr, /*Mutable*/ false,
- /*InitStyle*/ ICIS_NoInit);
- Field->setImplicit(true);
- Field->setAccess(AS_private);
- Field->setCapturedVLAType(VAT);
- CapRecord->addDecl(Field);
-
- CSI->addVLATypeCapture(ExprLoc, SizeType);
- }
- }
- }
- QTy = VAT->getElementType();
- break;
- }
- case Type::FunctionProto:
- case Type::FunctionNoProto:
- QTy = cast<FunctionType>(Ty)->getReturnType();
- break;
- case Type::Paren:
- case Type::TypeOf:
- case Type::UnaryTransform:
- case Type::Attributed:
- case Type::SubstTemplateTypeParm:
- case Type::PackExpansion:
- // Keep walking after single level desugaring.
- QTy = QTy.getSingleStepDesugaredType(getASTContext());
- break;
- case Type::Typedef:
- QTy = cast<TypedefType>(Ty)->desugar();
- break;
- case Type::Decltype:
- QTy = cast<DecltypeType>(Ty)->desugar();
- break;
- case Type::Auto:
- QTy = cast<AutoType>(Ty)->getDeducedType();
- break;
- case Type::TypeOfExpr:
- QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
- break;
- case Type::Atomic:
- QTy = cast<AtomicType>(Ty)->getValueType();
- break;
- }
- } while (!QTy.isNull() && QTy->isVariablyModifiedType());
+ captureVariablyModifiedType(Context, QTy, CSI);
}
if (getLangOpts().OpenMP) {
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
index 1d86ca3..c1fb906 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
@@ -3816,7 +3816,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
ObjCMethodDecl *&ClassMethod,
ObjCMethodDecl *&InstanceMethod,
TypedefNameDecl *&TDNDecl,
- bool CfToNs) {
+ bool CfToNs, bool Diagnose) {
QualType T = CfToNs ? SrcType : DestType;
ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
if (!ObjCBAttr)
@@ -3832,20 +3832,24 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
LookupResult R(*this, DeclarationName(RCId), SourceLocation(),
Sema::LookupOrdinaryName);
if (!LookupName(R, TUScope)) {
- Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
- << SrcType << DestType;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
+ << SrcType << DestType;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
return false;
}
Target = R.getFoundDecl();
if (Target && isa<ObjCInterfaceDecl>(Target))
RelatedClass = cast<ObjCInterfaceDecl>(Target);
else {
- Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
- << SrcType << DestType;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- if (Target)
- Diag(Target->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
+ << SrcType << DestType;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Target)
+ Diag(Target->getLocStart(), diag::note_declared_at);
+ }
return false;
}
@@ -3854,9 +3858,11 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
Selector Sel = Context.Selectors.getUnarySelector(CMId);
ClassMethod = RelatedClass->lookupMethod(Sel, false);
if (!ClassMethod) {
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << Sel << false;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << Sel << false;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
return false;
}
}
@@ -3866,9 +3872,11 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
Selector Sel = Context.Selectors.getNullarySelector(IMId);
InstanceMethod = RelatedClass->lookupMethod(Sel, true);
if (!InstanceMethod) {
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << Sel << true;
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << Sel << true;
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
return false;
}
}
@@ -3878,7 +3886,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
bool
Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
QualType DestType, QualType SrcType,
- Expr *&SrcExpr) {
+ Expr *&SrcExpr, bool Diagnose) {
ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
@@ -3891,27 +3899,29 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
ObjCMethodDecl *InstanceMethod = nullptr;
TypedefNameDecl *TDNDecl = nullptr;
if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
- ClassMethod, InstanceMethod, TDNDecl, CfToNs))
+ ClassMethod, InstanceMethod, TDNDecl,
+ CfToNs, Diagnose))
return false;
if (CfToNs) {
// Implicit conversion from CF to ObjC object is needed.
if (ClassMethod) {
- std::string ExpressionString = "[";
- ExpressionString += RelatedClass->getNameAsString();
- ExpressionString += " ";
- ExpressionString += ClassMethod->getSelector().getAsString();
- SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
- // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << ClassMethod->getSelector() << false
- << FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
- << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
- Diag(RelatedClass->getLocStart(), diag::note_declared_at);
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ if (Diagnose) {
+ std::string ExpressionString = "[";
+ ExpressionString += RelatedClass->getNameAsString();
+ ExpressionString += " ";
+ ExpressionString += ClassMethod->getSelector().getAsString();
+ SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
+ // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << ClassMethod->getSelector() << false
+ << FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
+ << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
+ Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
- QualType receiverType =
- Context.getObjCInterfaceType(RelatedClass);
+ QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
// Argument.
Expr *args[] = { SrcExpr };
ExprResult msg = BuildClassMessageImplicit(receiverType, false,
@@ -3925,30 +3935,34 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
else {
// Implicit conversion from ObjC type to CF object is needed.
if (InstanceMethod) {
- std::string ExpressionString;
- SourceLocation SrcExprEndLoc = getLocForEndOfToken(SrcExpr->getLocEnd());
- if (InstanceMethod->isPropertyAccessor())
- if (const ObjCPropertyDecl *PDecl = InstanceMethod->findPropertyDecl()) {
- // fixit: ObjectExpr.propertyname when it is aproperty accessor.
- ExpressionString = ".";
- ExpressionString += PDecl->getNameAsString();
+ if (Diagnose) {
+ std::string ExpressionString;
+ SourceLocation SrcExprEndLoc =
+ getLocForEndOfToken(SrcExpr->getLocEnd());
+ if (InstanceMethod->isPropertyAccessor())
+ if (const ObjCPropertyDecl *PDecl =
+ InstanceMethod->findPropertyDecl()) {
+ // fixit: ObjectExpr.propertyname when it is aproperty accessor.
+ ExpressionString = ".";
+ ExpressionString += PDecl->getNameAsString();
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << InstanceMethod->getSelector() << true
+ << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+ }
+ if (ExpressionString.empty()) {
+ // Provide a fixit: [ObjectExpr InstanceMethod]
+ ExpressionString = " ";
+ ExpressionString += InstanceMethod->getSelector().getAsString();
+ ExpressionString += "]";
+
Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << InstanceMethod->getSelector() << true
- << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+ << SrcType << DestType << InstanceMethod->getSelector() << true
+ << FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
+ << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
}
- if (ExpressionString.empty()) {
- // Provide a fixit: [ObjectExpr InstanceMethod]
- ExpressionString = " ";
- ExpressionString += InstanceMethod->getSelector().getAsString();
- ExpressionString += "]";
-
- Diag(Loc, diag::err_objc_bridged_related_known_method)
- << SrcType << DestType << InstanceMethod->getSelector() << true
- << FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
- << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+ Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
}
- Diag(RelatedClass->getLocStart(), diag::note_declared_at);
- Diag(TDNDecl->getLocStart(), diag::note_declared_at);
ExprResult msg =
BuildInstanceMessageImplicit(SrcExpr, SrcType,
@@ -3965,6 +3979,7 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
Sema::ARCConversionResult
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
Expr *&castExpr, CheckedConversionKind CCK,
+ bool Diagnose,
bool DiagnoseCFAudited,
BinaryOperatorKind Opc) {
QualType castExprType = castExpr->getType();
@@ -3980,9 +3995,9 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
if (exprACTC == castACTC) {
// check for viablity and report error if casting an rvalue to a
// life-time qualifier.
- if ((castACTC == ACTC_retainable) &&
+ if (Diagnose && castACTC == ACTC_retainable &&
(CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
- (castType != castExprType)) {
+ castType != castExprType) {
const Type *DT = castType.getTypePtr();
QualType QDT = castType;
// We desugar some types but not others. We ignore those
@@ -4051,19 +4066,20 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
// to 'NSString *'. Let caller issue a normal mismatched diagnostic with
// suitable fix-it.
if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
- ConversionToObjCStringLiteralCheck(castType, castExpr))
+ ConversionToObjCStringLiteralCheck(castType, castExpr, Diagnose))
return ACR_okay;
// Do not issue "bridge cast" diagnostic when implicit casting
// a retainable object to a CF type parameter belonging to an audited
// CF API function. Let caller issue a normal type mismatched diagnostic
// instead.
- if (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
- castACTC != ACTC_coreFoundation)
+ if (Diagnose &&
+ (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
+ castACTC != ACTC_coreFoundation))
if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
(Opc == BO_NE || Opc == BO_EQ)))
- diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
- castExpr, castExpr, exprACTC, CCK);
+ diagnoseObjCARCConversion(*this, castRange, castType, castACTC, castExpr,
+ castExpr, exprACTC, CCK);
return ACR_okay;
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
index 663da0c..d6a0ff7 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
@@ -2687,15 +2687,16 @@ bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
CastKind &Kind,
CXXCastPath& BasePath,
- bool IgnoreBaseAccess) {
+ bool IgnoreBaseAccess,
+ bool Diagnose) {
QualType FromType = From->getType();
bool IsCStyleOrFunctionalCast = IgnoreBaseAccess;
Kind = CK_BitCast;
- if (!IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
+ if (Diagnose && !IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) ==
- Expr::NPCK_ZeroExpression) {
+ Expr::NPCK_ZeroExpression) {
if (Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy))
DiagRuntimeBehavior(From->getExprLoc(), From,
PDiag(diag::warn_impcast_bool_to_null_pointer)
@@ -2713,18 +2714,24 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
!Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) {
// We must have a derived-to-base conversion. Check an
// ambiguous or inaccessible conversion.
- if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
- From->getExprLoc(),
- From->getSourceRange(), &BasePath,
- IgnoreBaseAccess))
+ unsigned InaccessibleID = 0;
+ unsigned AmbigiousID = 0;
+ if (Diagnose) {
+ InaccessibleID = diag::err_upcast_to_inaccessible_base;
+ AmbigiousID = diag::err_ambiguous_derived_to_base_conv;
+ }
+ if (CheckDerivedToBaseConversion(
+ FromPointeeType, ToPointeeType, InaccessibleID, AmbigiousID,
+ From->getExprLoc(), From->getSourceRange(), DeclarationName(),
+ &BasePath, IgnoreBaseAccess))
return true;
// The conversion was successful.
Kind = CK_DerivedToBase;
}
- if (!IsCStyleOrFunctionalCast && FromPointeeType->isFunctionType() &&
- ToPointeeType->isVoidType()) {
+ if (Diagnose && !IsCStyleOrFunctionalCast &&
+ FromPointeeType->isFunctionType() && ToPointeeType->isVoidType()) {
assert(getLangOpts().MSVCCompat &&
"this should only be possible with MSVCCompat!");
Diag(From->getExprLoc(), diag::ext_ms_impcast_fn_obj)
diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBInstruction.h b/contrib/llvm/tools/lldb/include/lldb/API/SBInstruction.h
index c4bded5..2bacc2b 100644
--- a/contrib/llvm/tools/lldb/include/lldb/API/SBInstruction.h
+++ b/contrib/llvm/tools/lldb/include/lldb/API/SBInstruction.h
@@ -60,6 +60,9 @@ public:
bool
DoesBranch ();
+ bool
+ HasDelaySlot ();
+
void
Print (FILE *out);
diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h b/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h
index b2e3f06..28d3083 100644
--- a/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h
+++ b/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h
@@ -1216,6 +1216,25 @@ namespace lldb_private {
}
return UINT32_MAX;
}
+
+ uint32_t
+ FindEntryIndexesThatContain(B addr, std::vector<uint32_t> &indexes) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+
+ if (!m_entries.empty())
+ {
+ typename Collection::const_iterator pos;
+ for (const auto &entry : m_entries)
+ {
+ if (entry.Contains(addr))
+ indexes.push_back(entry.data);
+ }
+ }
+ return indexes.size() ;
+ }
Entry *
FindEntryThatContains (B addr)
diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h
index cf28c7e..130f02c 100644
--- a/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h
+++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h
@@ -81,6 +81,7 @@ public:
Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
+ void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
void CalculateSymbolSizes ();
diff --git a/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp
index 36be948..a17f3f8 100644
--- a/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp
+++ b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp
@@ -160,6 +160,14 @@ SBInstruction::DoesBranch ()
return false;
}
+bool
+SBInstruction::HasDelaySlot ()
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->HasDelaySlot ();
+ return false;
+}
+
void
SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp)
{
diff --git a/contrib/llvm/tools/lldb/source/Core/Module.cpp b/contrib/llvm/tools/lldb/source/Core/Module.cpp
index 833540e..a29456f 100644
--- a/contrib/llvm/tools/lldb/source/Core/Module.cpp
+++ b/contrib/llvm/tools/lldb/source/Core/Module.cpp
@@ -559,7 +559,18 @@ Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve
Symtab *symtab = sym_vendor->GetSymtab();
if (symtab && so_addr.IsSectionOffset())
{
- sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
+ Symbol *matching_symbol = nullptr;
+
+ symtab->ForEachSymbolContainingFileAddress(so_addr.GetFileAddress(),
+ [&matching_symbol](Symbol *symbol) -> bool {
+ if (symbol->GetType() != eSymbolTypeInvalid)
+ {
+ matching_symbol = symbol;
+ return false; // Stop iterating
+ }
+ return true; // Keep iterating
+ });
+ sc.symbol = matching_symbol;
if (!sc.symbol &&
resolve_scope & eSymbolContextFunction && !(resolved_flags & eSymbolContextFunction))
{
diff --git a/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp b/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp
index 30d7f63..64fdb08 100644
--- a/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp
+++ b/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp
@@ -35,12 +35,12 @@ using namespace lldb_private;
static char ID;
-#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
+#define VALID_POINTER_CHECK_NAME "_$__lldb_valid_pointer_check"
#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
static const char g_valid_pointer_check_text[] =
"extern \"C\" void\n"
-"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
+"_$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
"{\n"
" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
"}";
diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index 3c7e949..1b77946 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -242,16 +242,27 @@ ABISysV_mips::PrepareTrivialCall (Thread &thread,
const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+
+ /* Write r0 with 0, in case we are stopped in syscall,
+ * such setting prevents automatic decrement of the PC.
+ * This clears the bug 23659 for MIPS.
+ */
+ if (!reg_ctx->WriteRegisterFromUnsigned (r0_info, (uint64_t)0))
+ return false;
+
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
return false;
if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index e3da363..8226ef1 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -207,16 +207,27 @@ ABISysV_mips64::PrepareTrivialCall (Thread &thread,
const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
if (log)
- log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
+ log->Printf("Writing R0: 0x%" PRIx64, (uint64_t)0);
+
+ /* Write r0 with 0, in case we are stopped in syscall,
+ * such setting prevents automatic decrement of the PC.
+ * This clears the bug 23659 for MIPS.
+ */
+ if (!reg_ctx->WriteRegisterFromUnsigned (r0_info, (uint64_t)0))
+ return false;
+
+ if (log)
+ log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
// Set "sp" to the requested value
if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
return false;
if (log)
- log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
+ log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
// Set "ra" to the return address
if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_info, return_addr))
diff --git a/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp
index 4ba51f7..1993f23 100644
--- a/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp
+++ b/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp
@@ -13,6 +13,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamFile.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/StringPrinter.h"
@@ -1268,13 +1269,115 @@ GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const
//----------------------------------------------------------------------
// Dumping types
//----------------------------------------------------------------------
+#define DEPTH_INCREMENT 2
+
void
GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
- const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
+ const DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size,
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
bool verbose, uint32_t depth)
{
- assert(false);
+ if (IsTypedefType(type))
+ type = GetTypedefedType(type).GetOpaqueQualType();
+ if (!type)
+ return;
+ GoType *t = static_cast<GoType *>(type);
+
+ if (GoStruct *st = t->GetStruct())
+ {
+ if (GetCompleteType(type))
+ {
+ uint32_t field_idx = 0;
+ for (auto* field = st->GetField(field_idx); field != nullptr; field_idx++)
+ {
+ // Print the starting squiggly bracket (if this is the
+ // first member) or comma (for member 2 and beyond) for
+ // the struct/union/class member.
+ if (field_idx == 0)
+ s->PutChar('{');
+ else
+ s->PutChar(',');
+
+ // Indent
+ s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
+
+ // Print the member type if requested
+ if (show_types)
+ {
+ ConstString field_type_name = field->m_type.GetTypeName();
+ s->Printf("(%s) ", field_type_name.AsCString());
+ }
+ // Print the member name and equal sign
+ s->Printf("%s = ", field->m_name.AsCString());
+
+
+ // Dump the value of the member
+ CompilerType field_type = field->m_type;
+ field_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ field_type.GetFormat(), // The format with which to display the member
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + field->m_byte_offset,// Offset into "data" where to grab value from
+ field->m_type.GetByteSize(exe_ctx->GetBestExecutionContextScope()), // Size of this type in bytes
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have children
+ }
+
+ // Indent the trailing squiggly bracket
+ if (field_idx > 0)
+ s->Printf("\n%*s}", depth, "");
+
+ }
+ }
+
+ if (GoArray *a = t->GetArray()) {
+ CompilerType element_clang_type = a->GetElementType();
+ lldb::Format element_format = element_clang_type.GetFormat();
+ uint32_t element_byte_size = element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope());
+
+ uint64_t element_idx;
+ for (element_idx = 0; element_idx < a->GetLength(); ++element_idx)
+ {
+ // Print the starting squiggly bracket (if this is the
+ // first member) or comman (for member 2 and beyong) for
+ // the struct/union/class member.
+ if (element_idx == 0)
+ s->PutChar('{');
+ else
+ s->PutChar(',');
+
+ // Indent and print the index
+ s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "", element_idx);
+
+ // Figure out the field offset within the current struct/union/class type
+ uint64_t element_offset = element_idx * element_byte_size;
+
+ // Dump the value of the member
+ element_clang_type.DumpValue (exe_ctx,
+ s, // Stream to dump to
+ element_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset + element_offset,// Offset into "data" where to grab value from
+ element_byte_size, // Size of this type in bytes
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth + DEPTH_INCREMENT); // Scope depth for any types that have children
+ }
+
+ // Indent the trailing squiggly bracket
+ if (element_idx > 0)
+ s->Printf("\n%*s}", depth, "");
+ }
+
+ if (show_summary)
+ DumpSummary (type, exe_ctx, s, data, data_byte_offset, data_byte_size);
}
bool
@@ -1371,19 +1474,55 @@ void
GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size)
{
- assert(false);
+ if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind())
+ {
+ // TODO(ribrdb): read length and data
+ }
}
void
GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
{
- assert(false);
-} // Dump to stdout
+ // Dump to stdout
+ StreamFile s (stdout, false);
+ DumpTypeDescription (type, &s);
+}
void
GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
{
- assert(false);
+ if (!type)
+ return;
+ ConstString name = GetTypeName(type);
+ GoType *t = static_cast<GoType *>(type);
+
+ if (GoStruct *st = t->GetStruct())
+ {
+ if (GetCompleteType(type))
+ {
+ if (NULL == strchr(name.AsCString(), '{'))
+ s->Printf("type %s ", name.AsCString());
+ s->PutCString("struct {");
+ if (st->GetNumFields() == 0) {
+ s->PutChar('}');
+ return;
+ }
+ s->IndentMore();
+ uint32_t field_idx = 0;
+ for (auto* field = st->GetField(field_idx); field != nullptr; field_idx++)
+ {
+ s->PutChar('\n');
+ s->Indent();
+ s->Printf("%s %s", field->m_name.AsCString(), field->m_type.GetTypeName().AsCString());
+ }
+ s->IndentLess();
+ s->PutChar('\n');
+ s->Indent("}");
+ return;
+ }
+ }
+
+ s->PutCString(name.AsCString());
}
CompilerType
diff --git a/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp b/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp
index b20504a..709d899 100644
--- a/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp
+++ b/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp
@@ -1071,6 +1071,26 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
}
void
+Symtab::ForEachSymbolContainingFileAddress(addr_t file_addr, std::function<bool(Symbol *)> const &callback)
+{
+ Mutex::Locker locker (m_mutex);
+
+ if (!m_file_addr_to_index_computed)
+ InitAddressIndexes();
+
+ std::vector<uint32_t> all_addr_indexes;
+
+ // Get all symbols with file_addr
+ const size_t addr_match_count = m_file_addr_to_index.FindEntryIndexesThatContain(file_addr, all_addr_indexes);
+
+ for (size_t i = 0; i < addr_match_count; ++i)
+ {
+ if (!callback(SymbolAtIndex(all_addr_indexes[i])))
+ break;
+ }
+}
+
+void
Symtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
{
// No need to protect this call using m_mutex all other method calls are
diff --git a/contrib/llvm/tools/lldb/source/Target/Target.cpp b/contrib/llvm/tools/lldb/source/Target/Target.cpp
index d2aa1ba..21e4291 100644
--- a/contrib/llvm/tools/lldb/source/Target/Target.cpp
+++ b/contrib/llvm/tools/lldb/source/Target/Target.cpp
@@ -2442,18 +2442,18 @@ Target::GetBreakableLoadAddress (lldb::addr_t addr)
SymbolContext sc;
uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, resolve_scope, sc);
+ Address sym_addr;
if (sc.function)
- {
- function_start = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(this);
- if (function_start == LLDB_INVALID_ADDRESS)
- function_start = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
- }
+ sym_addr = sc.function->GetAddressRange().GetBaseAddress();
else if (sc.symbol)
- {
- Address sym_addr = sc.symbol->GetAddress();
+ sym_addr = sc.symbol->GetAddress();
+
+ function_start = sym_addr.GetLoadAddress(this);
+ if (function_start == LLDB_INVALID_ADDRESS)
function_start = sym_addr.GetFileAddress();
- }
- current_offset = addr - function_start;
+
+ if (function_start)
+ current_offset = addr - function_start;
}
// If breakpoint address is start of function then we dont have to do anything.
OpenPOWER on IntegriCloud