Upgrade our copies of clang, llvm, lldb and compiler-rt to r311606 from

the upstream release_50 branch.

As of this version, lib/msun's trig test should also work correctly
again (see bug 220989 for more information).

PR:		220989
MFC after:	2 months
X-MFC-with:	r321369
This commit is contained in:
dim 2017-08-24 20:19:27 +00:00
parent c41928d204
commit b5e6330452
44 changed files with 537 additions and 2662 deletions

View File

@ -18,11 +18,20 @@
// } // }
// } // }
#if defined(COMPILER_RT_ARMHF_TARGET)
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS \
vmov d0, r0, r1 SEPARATOR \
vmov d1, r2, r3
#else
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS
#endif
#define DEFINE_AEABI_DCMP(cond) \ #define DEFINE_AEABI_DCMP(cond) \
.syntax unified SEPARATOR \ .syntax unified SEPARATOR \
.p2align 2 SEPARATOR \ .p2align 2 SEPARATOR \
DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \ DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
push { r4, lr } SEPARATOR \ push { r4, lr } SEPARATOR \
CONVERT_DCMP_ARGS_TO_DF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \ bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
cmp r0, #0 SEPARATOR \ cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \ b ## cond 1f SEPARATOR \

View File

@ -18,11 +18,20 @@
// } // }
// } // }
#if defined(COMPILER_RT_ARMHF_TARGET)
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS \
vmov s0, r0 SEPARATOR \
vmov s1, r1
#else
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS
#endif
#define DEFINE_AEABI_FCMP(cond) \ #define DEFINE_AEABI_FCMP(cond) \
.syntax unified SEPARATOR \ .syntax unified SEPARATOR \
.p2align 2 SEPARATOR \ .p2align 2 SEPARATOR \
DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \ DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
push { r4, lr } SEPARATOR \ push { r4, lr } SEPARATOR \
CONVERT_FCMP_ARGS_TO_SF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \ bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
cmp r0, #0 SEPARATOR \ cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \ b ## cond 1f SEPARATOR \

View File

@ -70,7 +70,7 @@ int SidelineThread::runSideline(void *Arg) {
// Set up a signal handler on an alternate stack for safety. // Set up a signal handler on an alternate stack for safety.
InternalScopedBuffer<char> StackMap(SigAltStackSize); InternalScopedBuffer<char> StackMap(SigAltStackSize);
struct sigaltstack SigAltStack; stack_t SigAltStack;
SigAltStack.ss_sp = StackMap.data(); SigAltStack.ss_sp = StackMap.data();
SigAltStack.ss_size = SigAltStackSize; SigAltStack.ss_size = SigAltStackSize;
SigAltStack.ss_flags = 0; SigAltStack.ss_flags = 0;

View File

@ -1,11 +1,11 @@
//===- InstrProfilingNameVar.c - profile name variable setup --------------===// /*===- InstrProfilingNameVar.c - profile name variable setup -------------===*\
// |*
// The LLVM Compiler Infrastructure |* The LLVM Compiler Infrastructure
// |*
// This file is distributed under the University of Illinois Open Source |* This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. |* License. See LICENSE.TXT for details.
// |*
//===----------------------------------------------------------------------===// \*===----------------------------------------------------------------------===*/
#include "InstrProfiling.h" #include "InstrProfiling.h"

View File

@ -85,7 +85,10 @@ namespace ISD {
/// If N is a BUILD_VECTOR node whose elements are all the same constant or /// If N is a BUILD_VECTOR node whose elements are all the same constant or
/// undefined, return true and return the constant value in \p SplatValue. /// undefined, return true and return the constant value in \p SplatValue.
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue); /// This sets \p SplatValue to the smallest possible splat unless AllowShrink
/// is set to false.
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue,
bool AllowShrink = true);
/// Return true if the specified node is a BUILD_VECTOR where all of the /// Return true if the specified node is a BUILD_VECTOR where all of the
/// elements are ~0 or undef. /// elements are ~0 or undef.

View File

@ -627,6 +627,7 @@ private:
SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N); SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N);
SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N); SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
SDValue ScalarizeVecOp_VSELECT(SDNode *N); SDValue ScalarizeVecOp_VSELECT(SDNode *N);
SDValue ScalarizeVecOp_VSETCC(SDNode *N);
SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo); SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo); SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo);

View File

@ -484,6 +484,9 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
case ISD::VSELECT: case ISD::VSELECT:
Res = ScalarizeVecOp_VSELECT(N); Res = ScalarizeVecOp_VSELECT(N);
break; break;
case ISD::SETCC:
Res = ScalarizeVecOp_VSETCC(N);
break;
case ISD::STORE: case ISD::STORE:
Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo); Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
break; break;
@ -560,6 +563,36 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) {
N->getOperand(2)); N->getOperand(2));
} }
/// If the operand is a vector that needs to be scalarized then the
/// result must be v1i1, so just convert to a scalar SETCC and wrap
/// with a scalar_to_vector since the res type is legal if we got here
SDValue DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode *N) {
assert(N->getValueType(0).isVector() &&
N->getOperand(0).getValueType().isVector() &&
"Operand types must be vectors");
assert(N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type");
EVT VT = N->getValueType(0);
SDValue LHS = GetScalarizedVector(N->getOperand(0));
SDValue RHS = GetScalarizedVector(N->getOperand(1));
EVT OpVT = N->getOperand(0).getValueType();
EVT NVT = VT.getVectorElementType();
SDLoc DL(N);
// Turn it into a scalar SETCC.
SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
N->getOperand(2));
// Vectors may have a different boolean contents to scalars. Promote the
// value appropriately.
ISD::NodeType ExtendCode =
TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
Res = DAG.getNode(ExtendCode, DL, NVT, Res);
return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
}
/// If the value to store is a vector that needs to be scalarized, it must be /// If the value to store is a vector that needs to be scalarized, it must be
/// <1 x ty>. Just store the element. /// <1 x ty>. Just store the element.
SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){ SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){

View File

@ -116,7 +116,8 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
// ISD Namespace // ISD Namespace
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) { bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal,
bool AllowShrink) {
auto *BV = dyn_cast<BuildVectorSDNode>(N); auto *BV = dyn_cast<BuildVectorSDNode>(N);
if (!BV) if (!BV)
return false; return false;
@ -124,9 +125,11 @@ bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
APInt SplatUndef; APInt SplatUndef;
unsigned SplatBitSize; unsigned SplatBitSize;
bool HasUndefs; bool HasUndefs;
EVT EltVT = N->getValueType(0).getVectorElementType(); unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs) && unsigned MinSplatBits = AllowShrink ? 0 : EltSize;
EltVT.getSizeInBits() >= SplatBitSize; return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs,
MinSplatBits) &&
EltSize >= SplatBitSize;
} }
// FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be // FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be

View File

@ -2239,14 +2239,14 @@ bool llvm::UpgradeDebugInfo(Module &M) {
} }
bool llvm::UpgradeModuleFlags(Module &M) { bool llvm::UpgradeModuleFlags(Module &M) {
const NamedMDNode *ModFlags = M.getModuleFlagsMetadata(); NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
if (!ModFlags) if (!ModFlags)
return false; return false;
bool HasObjCFlag = false, HasClassProperties = false; bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
MDNode *Op = ModFlags->getOperand(I); MDNode *Op = ModFlags->getOperand(I);
if (Op->getNumOperands() < 2) if (Op->getNumOperands() != 3)
continue; continue;
MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1)); MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
if (!ID) if (!ID)
@ -2255,7 +2255,24 @@ bool llvm::UpgradeModuleFlags(Module &M) {
HasObjCFlag = true; HasObjCFlag = true;
if (ID->getString() == "Objective-C Class Properties") if (ID->getString() == "Objective-C Class Properties")
HasClassProperties = true; HasClassProperties = true;
// Upgrade PIC/PIE Module Flags. The module flag behavior for these two
// field was Error and now they are Max.
if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") {
if (auto *Behavior =
mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
if (Behavior->getLimitedValue() == Module::Error) {
Type *Int32Ty = Type::getInt32Ty(M.getContext());
Metadata *Ops[3] = {
ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Max)),
MDString::get(M.getContext(), ID->getString()),
Op->getOperand(2)};
ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
Changed = true;
} }
}
}
}
// "Objective-C Class Properties" is recently added for Objective-C. We // "Objective-C Class Properties" is recently added for Objective-C. We
// upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module // upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module
// flag of value 0, so we can correclty downgrade this flag when trying to // flag of value 0, so we can correclty downgrade this flag when trying to
@ -2264,9 +2281,10 @@ bool llvm::UpgradeModuleFlags(Module &M) {
if (HasObjCFlag && !HasClassProperties) { if (HasObjCFlag && !HasClassProperties) {
M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties", M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties",
(uint32_t)0); (uint32_t)0);
return true; Changed = true;
} }
return false;
return Changed;
} }
static bool isOldLoopArgument(Metadata *MD) { static bool isOldLoopArgument(Metadata *MD) {

View File

@ -232,7 +232,13 @@ private:
for (;;) { for (;;) {
read(); read();
if (Tok.K == Identifier && Tok.Value[0] == '@') { if (Tok.K == Identifier && Tok.Value[0] == '@') {
Tok.Value.drop_front().getAsInteger(10, E.Ordinal); if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
// Not an ordinal modifier at all, but the next export (fastcall
// decorated) - complete the current one.
unget();
Info.Exports.push_back(E);
return Error::success();
}
read(); read();
if (Tok.K == KwNoname) { if (Tok.K == KwNoname) {
E.Noname = true; E.Noname = true;

View File

@ -5901,6 +5901,9 @@ static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
return false; return false;
for (unsigned i = 0; i < M.size(); i += NumElts) { for (unsigned i = 0; i < M.size(); i += NumElts) {
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1; WhichResult = M[i] == 0 ? 0 : 1;
for (unsigned j = 0; j < NumElts; ++j) { for (unsigned j = 0; j < NumElts; ++j) {
if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult) if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
@ -5932,6 +5935,9 @@ static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
unsigned Half = NumElts / 2; unsigned Half = NumElts / 2;
for (unsigned i = 0; i < M.size(); i += NumElts) { for (unsigned i = 0; i < M.size(); i += NumElts) {
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1; WhichResult = M[i] == 0 ? 0 : 1;
for (unsigned j = 0; j < NumElts; j += Half) { for (unsigned j = 0; j < NumElts; j += Half) {
unsigned Idx = WhichResult; unsigned Idx = WhichResult;
@ -5972,6 +5978,9 @@ static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
return false; return false;
for (unsigned i = 0; i < M.size(); i += NumElts) { for (unsigned i = 0; i < M.size(); i += NumElts) {
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1; WhichResult = M[i] == 0 ? 0 : 1;
unsigned Idx = WhichResult * NumElts / 2; unsigned Idx = WhichResult * NumElts / 2;
for (unsigned j = 0; j < NumElts; j += 2) { for (unsigned j = 0; j < NumElts; j += 2) {
@ -6005,6 +6014,9 @@ static bool isVZIP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
return false; return false;
for (unsigned i = 0; i < M.size(); i += NumElts) { for (unsigned i = 0; i < M.size(); i += NumElts) {
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1; WhichResult = M[i] == 0 ? 0 : 1;
unsigned Idx = WhichResult * NumElts / 2; unsigned Idx = WhichResult * NumElts / 2;
for (unsigned j = 0; j < NumElts; j += 2) { for (unsigned j = 0; j < NumElts; j += 2) {
@ -8793,6 +8805,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
.addReg(ARM::R4, RegState::Implicit | RegState::Kill) .addReg(ARM::R4, RegState::Implicit | RegState::Kill)
.addReg(ARM::R4, RegState::Implicit | RegState::Define) .addReg(ARM::R4, RegState::Implicit | RegState::Define)
.addReg(ARM::R12, .addReg(ARM::R12,
RegState::Implicit | RegState::Define | RegState::Dead)
.addReg(ARM::CPSR,
RegState::Implicit | RegState::Define | RegState::Dead); RegState::Implicit | RegState::Define | RegState::Dead);
break; break;
case CodeModel::Large: case CodeModel::Large:
@ -8808,6 +8822,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
.addReg(ARM::R4, RegState::Implicit | RegState::Kill) .addReg(ARM::R4, RegState::Implicit | RegState::Kill)
.addReg(ARM::R4, RegState::Implicit | RegState::Define) .addReg(ARM::R4, RegState::Implicit | RegState::Define)
.addReg(ARM::R12, .addReg(ARM::R12,
RegState::Implicit | RegState::Define | RegState::Dead)
.addReg(ARM::CPSR,
RegState::Implicit | RegState::Define | RegState::Dead); RegState::Implicit | RegState::Define | RegState::Dead);
break; break;
} }

View File

@ -29540,8 +29540,9 @@ static bool detectZextAbsDiff(const SDValue &Select, SDValue &Op0,
// In SetLT case, The second operand of the comparison can be either 1 or 0. // In SetLT case, The second operand of the comparison can be either 1 or 0.
APInt SplatVal; APInt SplatVal;
if ((CC == ISD::SETLT) && if ((CC == ISD::SETLT) &&
!((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal) && !((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal,
SplatVal == 1) || /*AllowShrink*/false) &&
SplatVal.isOneValue()) ||
(ISD::isBuildVectorAllZeros(SetCC.getOperand(1).getNode())))) (ISD::isBuildVectorAllZeros(SetCC.getOperand(1).getNode()))))
return false; return false;
@ -30628,6 +30629,9 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Byte blends are only available in AVX2 // Byte blends are only available in AVX2
if (VT == MVT::v32i8 && !Subtarget.hasAVX2()) if (VT == MVT::v32i8 && !Subtarget.hasAVX2())
return SDValue(); return SDValue();
// There are no 512-bit blend instructions that use sign bits.
if (VT.is512BitVector())
return SDValue();
assert(BitWidth >= 8 && BitWidth <= 64 && "Invalid mask size"); assert(BitWidth >= 8 && BitWidth <= 64 && "Invalid mask size");
APInt DemandedMask(APInt::getSignMask(BitWidth)); APInt DemandedMask(APInt::getSignMask(BitWidth));
@ -32058,7 +32062,8 @@ static SDValue combineAndMaskToShift(SDNode *N, SelectionDAG &DAG,
return SDValue(); return SDValue();
APInt SplatVal; APInt SplatVal;
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) || if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal,
/*AllowShrink*/false) ||
!SplatVal.isMask()) !SplatVal.isMask())
return SDValue(); return SDValue();
@ -32642,7 +32647,8 @@ static SDValue detectUSatPattern(SDValue In, EVT VT) {
"Unexpected types for truncate operation"); "Unexpected types for truncate operation");
APInt C; APInt C;
if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C)) { if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C,
/*AllowShrink*/false)) {
// C should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according // C should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according
// the element size of the destination type. // the element size of the destination type.
return C.isMask(VT.getScalarSizeInBits()) ? In.getOperand(0) : return C.isMask(VT.getScalarSizeInBits()) ? In.getOperand(0) :
@ -35346,7 +35352,8 @@ static SDValue combineIncDecVector(SDNode *N, SelectionDAG &DAG) {
SDNode *N1 = N->getOperand(1).getNode(); SDNode *N1 = N->getOperand(1).getNode();
APInt SplatVal; APInt SplatVal;
if (!ISD::isConstantSplatVector(N1, SplatVal) || !SplatVal.isOneValue()) if (!ISD::isConstantSplatVector(N1, SplatVal, /*AllowShrink*/false) ||
!SplatVal.isOneValue())
return SDValue(); return SDValue();
SDValue AllOnesVec = getOnesVector(VT, DAG, SDLoc(N)); SDValue AllOnesVec = getOnesVector(VT, DAG, SDLoc(N));

View File

@ -3619,7 +3619,7 @@ let Predicates = [HasVLX] in {
def : Pat<(alignedstore256 (v4f64 (extract_subvector def : Pat<(alignedstore256 (v4f64 (extract_subvector
(v8f64 VR512:$src), (iPTR 0))), addr:$dst), (v8f64 VR512:$src), (iPTR 0))), addr:$dst),
(VMOVAPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>; (VMOVAPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
def : Pat<(alignedstore (v8f32 (extract_subvector def : Pat<(alignedstore256 (v8f32 (extract_subvector
(v16f32 VR512:$src), (iPTR 0))), addr:$dst), (v16f32 VR512:$src), (iPTR 0))), addr:$dst),
(VMOVAPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>; (VMOVAPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
def : Pat<(alignedstore256 (v4i64 (extract_subvector def : Pat<(alignedstore256 (v4i64 (extract_subvector

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,22 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
if (Path.empty()) if (Path.empty())
Path = getImplibPath(Def->OutputFile); Path = getImplibPath(Def->OutputFile);
if (Machine == IMAGE_FILE_MACHINE_I386 && Args.getLastArg(OPT_k)) {
for (COFFShortExport& E : Def->Exports) {
if (E.isWeak() || (!E.Name.empty() && E.Name[0] == '?'))
continue;
E.SymbolName = E.Name;
// Trim off the trailing decoration. Symbols will always have a
// starting prefix here (either _ for cdecl/stdcall, @ for fastcall
// or ? for C++ functions). (Vectorcall functions also will end up having
// a prefix here, even if they shouldn't.)
E.Name = E.Name.substr(0, E.Name.find('@', 1));
// By making sure E.SymbolName != E.Name for decorated symbols,
// writeImportLibrary writes these symbols with the type
// IMPORT_NAME_UNDECORATE.
}
}
if (writeImportLibrary(Def->OutputFile, Path, Def->Exports, Machine, true)) if (writeImportLibrary(Def->OutputFile, Path, Def->Exports, Machine, true))
return 1; return 1;
return 0; return 0;

View File

@ -12,13 +12,13 @@ def D_long : JoinedOrSeparate<["--"], "dllname">, Alias<D>;
def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">; def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">;
def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>; def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>;
def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
def k_alias: Flag<["--"], "kill-at">, Alias<k>;
//============================================================================== //==============================================================================
// The flags below do nothing. They are defined only for dlltool compatibility. // The flags below do nothing. They are defined only for dlltool compatibility.
//============================================================================== //==============================================================================
def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
def k_alias: Flag<["--"], "kill-at">, Alias<k>;
def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">; def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">;
def S_alias: JoinedOrSeparate<["--"], "as">, Alias<S>; def S_alias: JoinedOrSeparate<["--"], "as">, Alias<S>;

View File

@ -155,8 +155,7 @@ public:
} }
bool runOnFunction(Function &F) override { bool runOnFunction(Function &F) override {
if (skipFunction(F)) // Don't skip optnone functions; atomics still need to be lowered.
return false;
FunctionAnalysisManager DummyFAM; FunctionAnalysisManager DummyFAM;
auto PA = Impl.run(F, DummyFAM); auto PA = Impl.run(F, DummyFAM);
return !PA.areAllPreserved(); return !PA.areAllPreserved();

View File

@ -1941,6 +1941,12 @@ Instruction *ReassociatePass::canonicalizeNegConstExpr(Instruction *I) {
if (!User->isCommutative() && User->getOperand(1) != I) if (!User->isCommutative() && User->getOperand(1) != I)
return nullptr; return nullptr;
// Don't canonicalize x + (-Constant * y) -> x - (Constant * y), if the
// resulting subtract will be broken up later. This can get us into an
// infinite loop during reassociation.
if (UserOpcode == Instruction::FAdd && ShouldBreakUpSubtract(User))
return nullptr;
// Change the sign of the constant. // Change the sign of the constant.
APFloat Val = CF->getValueAPF(); APFloat Val = CF->getValueAPF();
Val.changeSign(); Val.changeSign();

View File

@ -341,6 +341,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
SimplifyInstruction(NewInst, BB->getModule()->getDataLayout())) { SimplifyInstruction(NewInst, BB->getModule()->getDataLayout())) {
// On the off-chance that this simplifies to an instruction in the old // On the off-chance that this simplifies to an instruction in the old
// function, map it back into the new function. // function, map it back into the new function.
if (NewFunc != OldFunc)
if (Value *MappedV = VMap.lookup(V)) if (Value *MappedV = VMap.lookup(V))
V = MappedV; V = MappedV;

View File

@ -375,6 +375,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief These flags are \c true if a defaulted corresponding special /// \brief These flags are \c true if a defaulted corresponding special
/// member can't be fully analyzed without performing overload resolution. /// member can't be fully analyzed without performing overload resolution.
/// @{ /// @{
unsigned NeedOverloadResolutionForCopyConstructor : 1;
unsigned NeedOverloadResolutionForMoveConstructor : 1; unsigned NeedOverloadResolutionForMoveConstructor : 1;
unsigned NeedOverloadResolutionForMoveAssignment : 1; unsigned NeedOverloadResolutionForMoveAssignment : 1;
unsigned NeedOverloadResolutionForDestructor : 1; unsigned NeedOverloadResolutionForDestructor : 1;
@ -383,6 +384,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief These flags are \c true if an implicit defaulted corresponding /// \brief These flags are \c true if an implicit defaulted corresponding
/// special member would be defined as deleted. /// special member would be defined as deleted.
/// @{ /// @{
unsigned DefaultedCopyConstructorIsDeleted : 1;
unsigned DefaultedMoveConstructorIsDeleted : 1; unsigned DefaultedMoveConstructorIsDeleted : 1;
unsigned DefaultedMoveAssignmentIsDeleted : 1; unsigned DefaultedMoveAssignmentIsDeleted : 1;
unsigned DefaultedDestructorIsDeleted : 1; unsigned DefaultedDestructorIsDeleted : 1;
@ -415,6 +417,12 @@ class CXXRecordDecl : public RecordDecl {
/// constructor. /// constructor.
unsigned HasDefaultedDefaultConstructor : 1; unsigned HasDefaultedDefaultConstructor : 1;
/// \brief True if this class can be passed in a non-address-preserving
/// fashion (such as in registers) according to the C++ language rules.
/// This does not imply anything about how the ABI in use will actually
/// pass an object of this class.
unsigned CanPassInRegisters : 1;
/// \brief True if a defaulted default constructor for this class would /// \brief True if a defaulted default constructor for this class would
/// be constexpr. /// be constexpr.
unsigned DefaultedDefaultConstructorIsConstexpr : 1; unsigned DefaultedDefaultConstructorIsConstexpr : 1;
@ -811,18 +819,50 @@ public:
return data().FirstFriend.isValid(); return data().FirstFriend.isValid();
} }
/// \brief \c true if a defaulted copy constructor for this class would be
/// deleted.
bool defaultedCopyConstructorIsDeleted() const {
assert((!needsOverloadResolutionForCopyConstructor() ||
(data().DeclaredSpecialMembers & SMF_CopyConstructor)) &&
"this property has not yet been computed by Sema");
return data().DefaultedCopyConstructorIsDeleted;
}
/// \brief \c true if a defaulted move constructor for this class would be
/// deleted.
bool defaultedMoveConstructorIsDeleted() const {
assert((!needsOverloadResolutionForMoveConstructor() ||
(data().DeclaredSpecialMembers & SMF_MoveConstructor)) &&
"this property has not yet been computed by Sema");
return data().DefaultedMoveConstructorIsDeleted;
}
/// \brief \c true if a defaulted destructor for this class would be deleted.
bool defaultedDestructorIsDeleted() const {
return !data().DefaultedDestructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous copy constructor that is not deleted.
bool hasSimpleCopyConstructor() const {
return !hasUserDeclaredCopyConstructor() &&
!data().DefaultedCopyConstructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single, /// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous move constructor that is not deleted. /// accessible, unambiguous move constructor that is not deleted.
bool hasSimpleMoveConstructor() const { bool hasSimpleMoveConstructor() const {
return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() && return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
!data().DefaultedMoveConstructorIsDeleted; !data().DefaultedMoveConstructorIsDeleted;
} }
/// \brief \c true if we know for sure that this class has a single, /// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous move assignment operator that is not deleted. /// accessible, unambiguous move assignment operator that is not deleted.
bool hasSimpleMoveAssignment() const { bool hasSimpleMoveAssignment() const {
return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() && return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
!data().DefaultedMoveAssignmentIsDeleted; !data().DefaultedMoveAssignmentIsDeleted;
} }
/// \brief \c true if we know for sure that this class has an accessible /// \brief \c true if we know for sure that this class has an accessible
/// destructor that is not deleted. /// destructor that is not deleted.
bool hasSimpleDestructor() const { bool hasSimpleDestructor() const {
@ -878,7 +918,16 @@ public:
/// \brief Determine whether we need to eagerly declare a defaulted copy /// \brief Determine whether we need to eagerly declare a defaulted copy
/// constructor for this class. /// constructor for this class.
bool needsOverloadResolutionForCopyConstructor() const { bool needsOverloadResolutionForCopyConstructor() const {
return data().HasMutableFields; // C++17 [class.copy.ctor]p6:
// If the class definition declares a move constructor or move assignment
// operator, the implicitly declared copy constructor is defined as
// deleted.
// In MSVC mode, sometimes a declared move assignment does not delete an
// implicit copy constructor, so defer this choice to Sema.
if (data().UserDeclaredSpecialMembers &
(SMF_MoveConstructor | SMF_MoveAssignment))
return true;
return data().NeedOverloadResolutionForCopyConstructor;
} }
/// \brief Determine whether an implicit copy constructor for this type /// \brief Determine whether an implicit copy constructor for this type
@ -919,7 +968,16 @@ public:
needsImplicitMoveConstructor(); needsImplicitMoveConstructor();
} }
/// \brief Set that we attempted to declare an implicitly move /// \brief Set that we attempted to declare an implicit copy
/// constructor, but overload resolution failed so we deleted it.
void setImplicitCopyConstructorIsDeleted() {
assert((data().DefaultedCopyConstructorIsDeleted ||
needsOverloadResolutionForCopyConstructor()) &&
"Copy constructor should not be deleted");
data().DefaultedCopyConstructorIsDeleted = true;
}
/// \brief Set that we attempted to declare an implicit move
/// constructor, but overload resolution failed so we deleted it. /// constructor, but overload resolution failed so we deleted it.
void setImplicitMoveConstructorIsDeleted() { void setImplicitMoveConstructorIsDeleted() {
assert((data().DefaultedMoveConstructorIsDeleted || assert((data().DefaultedMoveConstructorIsDeleted ||
@ -1316,6 +1374,18 @@ public:
return data().HasIrrelevantDestructor; return data().HasIrrelevantDestructor;
} }
/// \brief Determine whether this class has at least one trivial, non-deleted
/// copy or move constructor.
bool canPassInRegisters() const {
return data().CanPassInRegisters;
}
/// \brief Set that we can pass this RecordDecl in registers.
// FIXME: This should be set as part of completeDefinition.
void setCanPassInRegisters(bool CanPass) {
data().CanPassInRegisters = CanPass;
}
/// \brief Determine whether this class has a non-literal or/ volatile type /// \brief Determine whether this class has a non-literal or/ volatile type
/// non-static data member or base class. /// non-static data member or base class.
bool hasNonLiteralTypeFieldsOrBases() const { bool hasNonLiteralTypeFieldsOrBases() const {

View File

@ -1048,10 +1048,6 @@ public:
/// which implicitly adds the builtin defines etc. /// which implicitly adds the builtin defines etc.
void EnterMainSourceFile(); void EnterMainSourceFile();
/// \brief After parser warm-up, initialize the conditional stack from
/// the preamble.
void replayPreambleConditionalStack();
/// \brief Inform the preprocessor callbacks that processing is complete. /// \brief Inform the preprocessor callbacks that processing is complete.
void EndSourceFile(); void EndSourceFile();
@ -2025,6 +2021,10 @@ public:
} }
private: private:
/// \brief After processing predefined file, initialize the conditional stack from
/// the preamble.
void replayPreambleConditionalStack();
// Macro handling. // Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
void HandleUndefDirective(); void HandleUndefDirective();

View File

@ -956,12 +956,16 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.HasUninitializedFields = FromData.HasUninitializedFields; ToData.HasUninitializedFields = FromData.HasUninitializedFields;
ToData.HasInheritedConstructor = FromData.HasInheritedConstructor; ToData.HasInheritedConstructor = FromData.HasInheritedConstructor;
ToData.HasInheritedAssignment = FromData.HasInheritedAssignment; ToData.HasInheritedAssignment = FromData.HasInheritedAssignment;
ToData.NeedOverloadResolutionForCopyConstructor
= FromData.NeedOverloadResolutionForCopyConstructor;
ToData.NeedOverloadResolutionForMoveConstructor ToData.NeedOverloadResolutionForMoveConstructor
= FromData.NeedOverloadResolutionForMoveConstructor; = FromData.NeedOverloadResolutionForMoveConstructor;
ToData.NeedOverloadResolutionForMoveAssignment ToData.NeedOverloadResolutionForMoveAssignment
= FromData.NeedOverloadResolutionForMoveAssignment; = FromData.NeedOverloadResolutionForMoveAssignment;
ToData.NeedOverloadResolutionForDestructor ToData.NeedOverloadResolutionForDestructor
= FromData.NeedOverloadResolutionForDestructor; = FromData.NeedOverloadResolutionForDestructor;
ToData.DefaultedCopyConstructorIsDeleted
= FromData.DefaultedCopyConstructorIsDeleted;
ToData.DefaultedMoveConstructorIsDeleted ToData.DefaultedMoveConstructorIsDeleted
= FromData.DefaultedMoveConstructorIsDeleted; = FromData.DefaultedMoveConstructorIsDeleted;
ToData.DefaultedMoveAssignmentIsDeleted ToData.DefaultedMoveAssignmentIsDeleted
@ -973,6 +977,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
= FromData.HasConstexprNonCopyMoveConstructor; = FromData.HasConstexprNonCopyMoveConstructor;
ToData.HasDefaultedDefaultConstructor ToData.HasDefaultedDefaultConstructor
= FromData.HasDefaultedDefaultConstructor; = FromData.HasDefaultedDefaultConstructor;
ToData.CanPassInRegisters = FromData.CanPassInRegisters;
ToData.DefaultedDefaultConstructorIsConstexpr ToData.DefaultedDefaultConstructorIsConstexpr
= FromData.DefaultedDefaultConstructorIsConstexpr; = FromData.DefaultedDefaultConstructorIsConstexpr;
ToData.HasConstexprDefaultConstructor ToData.HasConstexprDefaultConstructor

View File

@ -55,15 +55,18 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
HasOnlyCMembers(true), HasInClassInitializer(false), HasOnlyCMembers(true), HasInClassInitializer(false),
HasUninitializedReferenceMember(false), HasUninitializedFields(false), HasUninitializedReferenceMember(false), HasUninitializedFields(false),
HasInheritedConstructor(false), HasInheritedAssignment(false), HasInheritedConstructor(false), HasInheritedAssignment(false),
NeedOverloadResolutionForCopyConstructor(false),
NeedOverloadResolutionForMoveConstructor(false), NeedOverloadResolutionForMoveConstructor(false),
NeedOverloadResolutionForMoveAssignment(false), NeedOverloadResolutionForMoveAssignment(false),
NeedOverloadResolutionForDestructor(false), NeedOverloadResolutionForDestructor(false),
DefaultedCopyConstructorIsDeleted(false),
DefaultedMoveConstructorIsDeleted(false), DefaultedMoveConstructorIsDeleted(false),
DefaultedMoveAssignmentIsDeleted(false), DefaultedMoveAssignmentIsDeleted(false),
DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All), DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true), DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true),
HasConstexprNonCopyMoveConstructor(false), HasConstexprNonCopyMoveConstructor(false),
HasDefaultedDefaultConstructor(false), HasDefaultedDefaultConstructor(false),
CanPassInRegisters(true),
DefaultedDefaultConstructorIsConstexpr(true), DefaultedDefaultConstructorIsConstexpr(true),
HasConstexprDefaultConstructor(false), HasConstexprDefaultConstructor(false),
HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
@ -352,8 +355,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
setHasVolatileMember(true); setHasVolatileMember(true);
// Keep track of the presence of mutable fields. // Keep track of the presence of mutable fields.
if (BaseClassDecl->hasMutableFields()) if (BaseClassDecl->hasMutableFields()) {
data().HasMutableFields = true; data().HasMutableFields = true;
data().NeedOverloadResolutionForCopyConstructor = true;
}
if (BaseClassDecl->hasUninitializedReferenceMember()) if (BaseClassDecl->hasUninitializedReferenceMember())
data().HasUninitializedReferenceMember = true; data().HasUninitializedReferenceMember = true;
@ -406,6 +411,8 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
// -- a direct or virtual base class B that cannot be copied/moved [...] // -- a direct or virtual base class B that cannot be copied/moved [...]
// -- a non-static data member of class type M (or array thereof) // -- a non-static data member of class type M (or array thereof)
// that cannot be copied or moved [...] // that cannot be copied or moved [...]
if (!Subobj->hasSimpleCopyConstructor())
data().NeedOverloadResolutionForCopyConstructor = true;
if (!Subobj->hasSimpleMoveConstructor()) if (!Subobj->hasSimpleMoveConstructor())
data().NeedOverloadResolutionForMoveConstructor = true; data().NeedOverloadResolutionForMoveConstructor = true;
@ -426,6 +433,7 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
// -- any non-static data member has a type with a destructor // -- any non-static data member has a type with a destructor
// that is deleted or inaccessible from the defaulted [ctor or dtor]. // that is deleted or inaccessible from the defaulted [ctor or dtor].
if (!Subobj->hasSimpleDestructor()) { if (!Subobj->hasSimpleDestructor()) {
data().NeedOverloadResolutionForCopyConstructor = true;
data().NeedOverloadResolutionForMoveConstructor = true; data().NeedOverloadResolutionForMoveConstructor = true;
data().NeedOverloadResolutionForDestructor = true; data().NeedOverloadResolutionForDestructor = true;
} }
@ -711,8 +719,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().IsStandardLayout = false; data().IsStandardLayout = false;
// Keep track of the presence of mutable fields. // Keep track of the presence of mutable fields.
if (Field->isMutable()) if (Field->isMutable()) {
data().HasMutableFields = true; data().HasMutableFields = true;
data().NeedOverloadResolutionForCopyConstructor = true;
}
// C++11 [class.union]p8, DR1460: // C++11 [class.union]p8, DR1460:
// If X is a union, a non-static data member of X that is not an anonymous // If X is a union, a non-static data member of X that is not an anonymous
@ -756,6 +766,12 @@ void CXXRecordDecl::addedMember(Decl *D) {
// A standard-layout class is a class that: // A standard-layout class is a class that:
// -- has no non-static data members of type [...] reference, // -- has no non-static data members of type [...] reference,
data().IsStandardLayout = false; data().IsStandardLayout = false;
// C++1z [class.copy.ctor]p10:
// A defaulted copy constructor for a class X is defined as deleted if X has:
// -- a non-static data member of rvalue reference type
if (T->isRValueReferenceType())
data().DefaultedCopyConstructorIsDeleted = true;
} }
if (!Field->hasInClassInitializer() && !Field->isMutable()) { if (!Field->hasInClassInitializer() && !Field->isMutable()) {
@ -809,6 +825,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
// We may need to perform overload resolution to determine whether a // We may need to perform overload resolution to determine whether a
// field can be moved if it's const or volatile qualified. // field can be moved if it's const or volatile qualified.
if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) { if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
// We need to care about 'const' for the copy constructor because an
// implicit copy constructor might be declared with a non-const
// parameter.
data().NeedOverloadResolutionForCopyConstructor = true;
data().NeedOverloadResolutionForMoveConstructor = true; data().NeedOverloadResolutionForMoveConstructor = true;
data().NeedOverloadResolutionForMoveAssignment = true; data().NeedOverloadResolutionForMoveAssignment = true;
} }
@ -819,6 +839,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
// -- X is a union-like class that has a variant member with a // -- X is a union-like class that has a variant member with a
// non-trivial [corresponding special member] // non-trivial [corresponding special member]
if (isUnion()) { if (isUnion()) {
if (FieldRec->hasNonTrivialCopyConstructor())
data().DefaultedCopyConstructorIsDeleted = true;
if (FieldRec->hasNonTrivialMoveConstructor()) if (FieldRec->hasNonTrivialMoveConstructor())
data().DefaultedMoveConstructorIsDeleted = true; data().DefaultedMoveConstructorIsDeleted = true;
if (FieldRec->hasNonTrivialMoveAssignment()) if (FieldRec->hasNonTrivialMoveAssignment())
@ -830,6 +852,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
// For an anonymous union member, our overload resolution will perform // For an anonymous union member, our overload resolution will perform
// overload resolution for its members. // overload resolution for its members.
if (Field->isAnonymousStructOrUnion()) { if (Field->isAnonymousStructOrUnion()) {
data().NeedOverloadResolutionForCopyConstructor |=
FieldRec->data().NeedOverloadResolutionForCopyConstructor;
data().NeedOverloadResolutionForMoveConstructor |= data().NeedOverloadResolutionForMoveConstructor |=
FieldRec->data().NeedOverloadResolutionForMoveConstructor; FieldRec->data().NeedOverloadResolutionForMoveConstructor;
data().NeedOverloadResolutionForMoveAssignment |= data().NeedOverloadResolutionForMoveAssignment |=
@ -915,8 +939,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
} }
// Keep track of the presence of mutable fields. // Keep track of the presence of mutable fields.
if (FieldRec->hasMutableFields()) if (FieldRec->hasMutableFields()) {
data().HasMutableFields = true; data().HasMutableFields = true;
data().NeedOverloadResolutionForCopyConstructor = true;
}
// C++11 [class.copy]p13: // C++11 [class.copy]p13:
// If the implicitly-defined constructor would satisfy the // If the implicitly-defined constructor would satisfy the

View File

@ -30,38 +30,9 @@ void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
} }
bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const { bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
// If RD has a non-trivial move or copy constructor, we cannot copy the
// argument.
if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
return false;
// If RD has a non-trivial destructor, we cannot copy the argument.
if (RD->hasNonTrivialDestructor())
return false;
// We can only copy the argument if there exists at least one trivial, // We can only copy the argument if there exists at least one trivial,
// non-deleted copy or move constructor. // non-deleted copy or move constructor.
// FIXME: This assumes that all lazily declared copy and move constructors are return RD->canPassInRegisters();
// not deleted. This assumption might not be true in some corner cases.
bool CopyDeleted = false;
bool MoveDeleted = false;
for (const CXXConstructorDecl *CD : RD->ctors()) {
if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
assert(CD->isTrivial());
// We had at least one undeleted trivial copy or move ctor. Return
// directly.
if (!CD->isDeleted())
return true;
if (CD->isCopyConstructor())
CopyDeleted = true;
else
MoveDeleted = true;
}
}
// If all trivial copy and move constructors are deleted, we cannot copy the
// argument.
return !(CopyDeleted && MoveDeleted);
} }
llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) { llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {

View File

@ -63,11 +63,8 @@ public:
bool classifyReturnType(CGFunctionInfo &FI) const override; bool classifyReturnType(CGFunctionInfo &FI) const override;
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override { RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
// Structures with either a non-trivial destructor or a non-trivial // If C++ prohibits us from making a copy, pass by address.
// copy constructor are always indirect. if (!canCopyArgument(RD))
// FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
// special members.
if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
return RAA_Indirect; return RAA_Indirect;
return RAA_Default; return RAA_Default;
} }
@ -998,10 +995,8 @@ bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
if (!RD) if (!RD)
return false; return false;
// Return indirectly if we have a non-trivial copy ctor or non-trivial dtor. // If C++ prohibits us from making a copy, return by address.
// FIXME: Use canCopyArgument() when it is fixed to handle lazily declared if (!canCopyArgument(RD)) {
// special members.
if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType()); auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false); FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
return true; return true;

View File

@ -819,46 +819,44 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
return RAA_Default; return RAA_Default;
case llvm::Triple::x86_64: case llvm::Triple::x86_64:
// Win64 passes objects with non-trivial copy ctors indirectly. // If a class has a destructor, we'd really like to pass it indirectly
if (RD->hasNonTrivialCopyConstructor())
return RAA_Indirect;
// If an object has a destructor, we'd really like to pass it indirectly
// because it allows us to elide copies. Unfortunately, MSVC makes that // because it allows us to elide copies. Unfortunately, MSVC makes that
// impossible for small types, which it will pass in a single register or // impossible for small types, which it will pass in a single register or
// stack slot. Most objects with dtors are large-ish, so handle that early. // stack slot. Most objects with dtors are large-ish, so handle that early.
// We can't call out all large objects as being indirect because there are // We can't call out all large objects as being indirect because there are
// multiple x64 calling conventions and the C++ ABI code shouldn't dictate // multiple x64 calling conventions and the C++ ABI code shouldn't dictate
// how we pass large POD types. // how we pass large POD types.
//
// Note: This permits small classes with nontrivial destructors to be
// passed in registers, which is non-conforming.
if (RD->hasNonTrivialDestructor() && if (RD->hasNonTrivialDestructor() &&
getContext().getTypeSize(RD->getTypeForDecl()) > 64) getContext().getTypeSize(RD->getTypeForDecl()) > 64)
return RAA_Indirect; return RAA_Indirect;
// If this is true, the implicit copy constructor that Sema would have // If a class has at least one non-deleted, trivial copy constructor, it
// created would not be deleted. FIXME: We should provide a more direct way // is passed according to the C ABI. Otherwise, it is passed indirectly.
// for CodeGen to ask whether the constructor was deleted. //
if (!RD->hasUserDeclaredCopyConstructor() && // Note: This permits classes with non-trivial copy or move ctors to be
!RD->hasUserDeclaredMoveConstructor() && // passed in registers, so long as they *also* have a trivial copy ctor,
!RD->needsOverloadResolutionForMoveConstructor() && // which is non-conforming.
!RD->hasUserDeclaredMoveAssignment() && if (RD->needsImplicitCopyConstructor()) {
!RD->needsOverloadResolutionForMoveAssignment()) // If the copy ctor has not yet been declared, we can read its triviality
// off the AST.
if (!RD->defaultedCopyConstructorIsDeleted() &&
RD->hasTrivialCopyConstructor())
return RAA_Default; return RAA_Default;
} else {
// Otherwise, Sema should have created an implicit copy constructor if // Otherwise, we need to find the copy constructor(s) and ask.
// needed.
assert(!RD->needsImplicitCopyConstructor());
// We have to make sure the trivial copy constructor isn't deleted.
for (const CXXConstructorDecl *CD : RD->ctors()) { for (const CXXConstructorDecl *CD : RD->ctors()) {
if (CD->isCopyConstructor()) { if (CD->isCopyConstructor()) {
assert(CD->isTrivial()); // We had at least one nondeleted trivial copy ctor. Return directly.
// We had at least one undeleted trivial copy ctor. Return directly. if (!CD->isDeleted() && CD->isTrivial())
if (!CD->isDeleted())
return RAA_Default; return RAA_Default;
} }
} }
}
// The trivial copy constructor was deleted. Return indirectly. // We have no trivial, non-deleted copy constructor.
return RAA_Indirect; return RAA_Indirect;
} }

View File

@ -1837,7 +1837,12 @@ Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
} }
bool MachO::IsUnwindTablesDefault(const ArgList &Args) const { bool MachO::IsUnwindTablesDefault(const ArgList &Args) const {
return !UseSjLjExceptions(Args); // Unwind tables are not emitted if -fno-exceptions is supplied (except when
// targeting x86_64).
return getArch() == llvm::Triple::x86_64 ||
(!UseSjLjExceptions(Args) &&
Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true));
} }
bool MachO::UseDwarfDebugFlags() const { bool MachO::UseDwarfDebugFlags() const {

View File

@ -76,7 +76,7 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
// Check various environment variables to try and find a toolchain. // Check various environment variables to try and find a toolchain.
static bool findVCToolChainViaEnvironment(std::string &Path, static bool findVCToolChainViaEnvironment(std::string &Path,
bool &IsVS2017OrNewer) { MSVCToolChain::ToolsetLayout &VSLayout) {
// These variables are typically set by vcvarsall.bat // These variables are typically set by vcvarsall.bat
// when launching a developer command prompt. // when launching a developer command prompt.
if (llvm::Optional<std::string> VCToolsInstallDir = if (llvm::Optional<std::string> VCToolsInstallDir =
@ -84,7 +84,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
// This is only set by newer Visual Studios, and it leads straight to // This is only set by newer Visual Studios, and it leads straight to
// the toolchain directory. // the toolchain directory.
Path = std::move(*VCToolsInstallDir); Path = std::move(*VCToolsInstallDir);
IsVS2017OrNewer = true; VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
return true; return true;
} }
if (llvm::Optional<std::string> VCInstallDir = if (llvm::Optional<std::string> VCInstallDir =
@ -94,7 +94,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
// so this check has to appear second. // so this check has to appear second.
// In older Visual Studios, the VC directory is the toolchain. // In older Visual Studios, the VC directory is the toolchain.
Path = std::move(*VCInstallDir); Path = std::move(*VCInstallDir);
IsVS2017OrNewer = false; VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
return true; return true;
} }
@ -134,9 +134,16 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
} }
if (IsBin) { if (IsBin) {
llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath); llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
if (llvm::sys::path::filename(ParentPath) == "VC") { llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
if (ParentFilename == "VC") {
Path = ParentPath; Path = ParentPath;
IsVS2017OrNewer = false; VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
return true;
}
if (ParentFilename == "x86ret" || ParentFilename == "x86chk"
|| ParentFilename == "amd64ret" || ParentFilename == "amd64chk") {
Path = ParentPath;
VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
return true; return true;
} }
@ -165,7 +172,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
ToolChainPath = llvm::sys::path::parent_path(ToolChainPath); ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
Path = ToolChainPath; Path = ToolChainPath;
IsVS2017OrNewer = true; VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
return true; return true;
} }
@ -181,7 +188,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
// This is the preferred way to discover new Visual Studios, as they're no // This is the preferred way to discover new Visual Studios, as they're no
// longer listed in the registry. // longer listed in the registry.
static bool findVCToolChainViaSetupConfig(std::string &Path, static bool findVCToolChainViaSetupConfig(std::string &Path,
bool &IsVS2017OrNewer) { MSVCToolChain::ToolsetLayout &VSLayout) {
#if !defined(USE_MSVC_SETUP_API) #if !defined(USE_MSVC_SETUP_API)
return false; return false;
#else #else
@ -263,7 +270,7 @@ static bool findVCToolChainViaSetupConfig(std::string &Path,
return false; return false;
Path = ToolchainPath.str(); Path = ToolchainPath.str();
IsVS2017OrNewer = true; VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
return true; return true;
#endif #endif
} }
@ -272,7 +279,7 @@ static bool findVCToolChainViaSetupConfig(std::string &Path,
// a toolchain path. VS2017 and newer don't get added to the registry. // a toolchain path. VS2017 and newer don't get added to the registry.
// So if we find something here, we know that it's an older version. // So if we find something here, we know that it's an older version.
static bool findVCToolChainViaRegistry(std::string &Path, static bool findVCToolChainViaRegistry(std::string &Path,
bool &IsVS2017OrNewer) { MSVCToolChain::ToolsetLayout &VSLayout) {
std::string VSInstallPath; std::string VSInstallPath;
if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)", if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
"InstallDir", VSInstallPath, nullptr) || "InstallDir", VSInstallPath, nullptr) ||
@ -284,7 +291,7 @@ static bool findVCToolChainViaRegistry(std::string &Path,
llvm::sys::path::append(VCPath, "VC"); llvm::sys::path::append(VCPath, "VC");
Path = VCPath.str(); Path = VCPath.str();
IsVS2017OrNewer = false; VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
return true; return true;
} }
} }
@ -475,6 +482,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// native target bin directory. // native target bin directory.
// e.g. when compiling for x86 on an x64 host, PATH should start with: // e.g. when compiling for x86 on an x64 host, PATH should start with:
// /bin/HostX64/x86;/bin/HostX64/x64 // /bin/HostX64/x86;/bin/HostX64/x64
// This doesn't attempt to handle ToolsetLayout::DevDivInternal.
if (TC.getIsVS2017OrNewer() && if (TC.getIsVS2017OrNewer() &&
llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) { llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch(); auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
@ -677,9 +685,9 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
// what they want to use. // what they want to use.
// Failing that, just try to find the newest Visual Studio version we can // Failing that, just try to find the newest Visual Studio version we can
// and use its default VC toolchain. // and use its default VC toolchain.
findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) || findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) ||
findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) || findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) ||
findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer); findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
} }
Tool *MSVCToolChain::buildLinker() const { Tool *MSVCToolChain::buildLinker() const {
@ -766,6 +774,21 @@ static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
} }
} }
// Similar to the above function, but for DevDiv internal builds.
static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
using ArchType = llvm::Triple::ArchType;
switch (Arch) {
case ArchType::x86:
return "i386";
case ArchType::x86_64:
return "amd64";
case ArchType::arm:
return "arm";
default:
return "";
}
}
// Get the path to a specific subdirectory in the current toolchain for // Get the path to a specific subdirectory in the current toolchain for
// a given target architecture. // a given target architecture.
// VS2017 changed the VC toolchain layout, so this should be used instead // VS2017 changed the VC toolchain layout, so this should be used instead
@ -773,26 +796,40 @@ static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
std::string std::string
MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type, MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
llvm::Triple::ArchType TargetArch) const { llvm::Triple::ArchType TargetArch) const {
const char *SubdirName;
const char *IncludeName;
switch (VSLayout) {
case ToolsetLayout::OlderVS:
SubdirName = llvmArchToLegacyVCArch(TargetArch);
IncludeName = "include";
break;
case ToolsetLayout::VS2017OrNewer:
SubdirName = llvmArchToWindowsSDKArch(TargetArch);
IncludeName = "include";
break;
case ToolsetLayout::DevDivInternal:
SubdirName = llvmArchToDevDivInternalArch(TargetArch);
IncludeName = "inc";
break;
}
llvm::SmallString<256> Path(VCToolChainPath); llvm::SmallString<256> Path(VCToolChainPath);
switch (Type) { switch (Type) {
case SubDirectoryType::Bin: case SubDirectoryType::Bin:
if (IsVS2017OrNewer) { if (VSLayout == ToolsetLayout::VS2017OrNewer) {
bool HostIsX64 = const bool HostIsX64 =
llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit(); llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"), const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
llvmArchToWindowsSDKArch(TargetArch)); llvm::sys::path::append(Path, "bin", HostName, SubdirName);
} else { // OlderVS or DevDivInternal
} else { llvm::sys::path::append(Path, "bin", SubdirName);
llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
} }
break; break;
case SubDirectoryType::Include: case SubDirectoryType::Include:
llvm::sys::path::append(Path, "include"); llvm::sys::path::append(Path, IncludeName);
break; break;
case SubDirectoryType::Lib: case SubDirectoryType::Lib:
llvm::sys::path::append( llvm::sys::path::append(Path, "lib", SubdirName);
Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
: llvmArchToLegacyVCArch(TargetArch));
break; break;
} }
return Path.str(); return Path.str();

View File

@ -92,7 +92,12 @@ public:
return getSubDirectoryPath(Type, getArch()); return getSubDirectoryPath(Type, getArch());
} }
bool getIsVS2017OrNewer() const { return IsVS2017OrNewer; } enum class ToolsetLayout {
OlderVS,
VS2017OrNewer,
DevDivInternal,
};
bool getIsVS2017OrNewer() const { return VSLayout == ToolsetLayout::VS2017OrNewer; }
void void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
@ -130,7 +135,7 @@ protected:
Tool *buildAssembler() const override; Tool *buildAssembler() const override;
private: private:
std::string VCToolChainPath; std::string VCToolChainPath;
bool IsVS2017OrNewer = false; ToolsetLayout VSLayout = ToolsetLayout::OlderVS;
CudaInstallationDetector CudaInstallation; CudaInstallationDetector CudaInstallation;
}; };

View File

@ -472,9 +472,14 @@ void WhitespaceManager::alignTrailingComments() {
continue; continue;
unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn; unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
unsigned ChangeMaxColumn = Style.ColumnLimit >= Changes[i].TokenLength unsigned ChangeMaxColumn;
? Style.ColumnLimit - Changes[i].TokenLength
: ChangeMinColumn; if (Style.ColumnLimit == 0)
ChangeMaxColumn = UINT_MAX;
else if (Style.ColumnLimit >= Changes[i].TokenLength)
ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
else
ChangeMaxColumn = ChangeMinColumn;
// If we don't create a replacement for this change, we have to consider // If we don't create a replacement for this change, we have to consider
// it to be immovable. // it to be immovable.

View File

@ -76,13 +76,7 @@ typedef intptr_t _sleb128_t;
typedef uintptr_t _uleb128_t; typedef uintptr_t _uleb128_t;
struct _Unwind_Context; struct _Unwind_Context;
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
struct _Unwind_Control_Block;
typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
#else
struct _Unwind_Exception; struct _Unwind_Exception;
typedef struct _Unwind_Exception _Unwind_Exception;
#endif
typedef enum { typedef enum {
_URC_NO_REASON = 0, _URC_NO_REASON = 0,
#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
@ -115,42 +109,8 @@ typedef enum {
} _Unwind_Action; } _Unwind_Action;
typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code, typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
_Unwind_Exception *); struct _Unwind_Exception *);
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
typedef struct _Unwind_Control_Block _Unwind_Control_Block;
typedef uint32_t _Unwind_EHT_Header;
struct _Unwind_Control_Block {
uint64_t exception_class;
void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *);
/* unwinder cache (private fields for the unwinder's use) */
struct {
uint32_t reserved1; /* forced unwind stop function, 0 if not forced */
uint32_t reserved2; /* personality routine */
uint32_t reserved3; /* callsite */
uint32_t reserved4; /* forced unwind stop argument */
uint32_t reserved5;
} unwinder_cache;
/* propagation barrier cache (valid after phase 1) */
struct {
uint32_t sp;
uint32_t bitpattern[5];
} barrier_cache;
/* cleanup cache (preserved over cleanup) */
struct {
uint32_t bitpattern[4];
} cleanup_cache;
/* personality cache (for personality's benefit) */
struct {
uint32_t fnstart; /* function start address */
_Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */
uint32_t additional; /* additional data */
uint32_t reserved1;
} pr_cache;
long long int : 0; /* force alignment of next item to 8-byte boundary */
};
#else
struct _Unwind_Exception { struct _Unwind_Exception {
_Unwind_Exception_Class exception_class; _Unwind_Exception_Class exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup; _Unwind_Exception_Cleanup_Fn exception_cleanup;
@ -160,24 +120,23 @@ struct _Unwind_Exception {
* aligned". GCC has interpreted this to mean "use the maximum useful * aligned". GCC has interpreted this to mean "use the maximum useful
* alignment for the target"; so do we. */ * alignment for the target"; so do we. */
} __attribute__((__aligned__)); } __attribute__((__aligned__));
#endif
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action, typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action,
_Unwind_Exception_Class, _Unwind_Exception_Class,
_Unwind_Exception *, struct _Unwind_Exception *,
struct _Unwind_Context *, struct _Unwind_Context *,
void *); void *);
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(int, _Unwind_Action, typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
_Unwind_Exception_Class, int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
_Unwind_Exception *,
struct _Unwind_Context *); struct _Unwind_Context *);
typedef _Unwind_Personality_Fn __personality_routine; typedef _Unwind_Personality_Fn __personality_routine;
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
void *); void *);
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___)) #if defined(__arm__) && !defined(__APPLE__)
typedef enum { typedef enum {
_UVRSC_CORE = 0, /* integer register */ _UVRSC_CORE = 0, /* integer register */
_UVRSC_VFP = 1, /* vfp */ _UVRSC_VFP = 1, /* vfp */
@ -199,12 +158,14 @@ typedef enum {
_UVRSR_FAILED = 2 _UVRSR_FAILED = 2
} _Unwind_VRS_Result; } _Unwind_VRS_Result;
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__ARM_DWARF_EH__)
typedef uint32_t _Unwind_State; typedef uint32_t _Unwind_State;
#define _US_VIRTUAL_UNWIND_FRAME ((_Unwind_State)0) #define _US_VIRTUAL_UNWIND_FRAME ((_Unwind_State)0)
#define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1) #define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1)
#define _US_UNWIND_FRAME_RESUME ((_Unwind_State)2) #define _US_UNWIND_FRAME_RESUME ((_Unwind_State)2)
#define _US_ACTION_MASK ((_Unwind_State)3) #define _US_ACTION_MASK ((_Unwind_State)3)
#define _US_FORCE_UNWIND ((_Unwind_State)8) #define _US_FORCE_UNWIND ((_Unwind_State)8)
#endif
_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context, _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,
_Unwind_VRS_RegClass __regclass, _Unwind_VRS_RegClass __regclass,
@ -263,12 +224,13 @@ _Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *);
/* DWARF EH functions; currently not available on Darwin/ARM */ /* DWARF EH functions; currently not available on Darwin/ARM */
#if !defined(__APPLE__) || !defined(__arm__) #if !defined(__APPLE__) || !defined(__arm__)
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *);
_Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception *, _Unwind_Stop_Fn, _Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *);
void *); _Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *,
void _Unwind_DeleteException(_Unwind_Exception *); _Unwind_Stop_Fn, void *);
void _Unwind_Resume(_Unwind_Exception *); void _Unwind_DeleteException(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception *); void _Unwind_Resume(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *);
#endif #endif
@ -279,11 +241,11 @@ typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t;
void _Unwind_SjLj_Register(_Unwind_FunctionContext_t); void _Unwind_SjLj_Register(_Unwind_FunctionContext_t);
void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t); void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t);
_Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception *); _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *, _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *,
_Unwind_Stop_Fn, void *); _Unwind_Stop_Fn, void *);
void _Unwind_SjLj_Resume(_Unwind_Exception *); void _Unwind_SjLj_Resume(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *); _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *);
void *_Unwind_FindEnclosingFunction(void *); void *_Unwind_FindEnclosingFunction(void *);

View File

@ -458,10 +458,16 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs); SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs);
} }
bool ExitedFromPredefinesFile = false;
FileID ExitedFID; FileID ExitedFID;
if (Callbacks && !isEndOfMacro && CurPPLexer) if (!isEndOfMacro && CurPPLexer) {
ExitedFID = CurPPLexer->getFileID(); ExitedFID = CurPPLexer->getFileID();
assert(PredefinesFileID.isValid() &&
"HandleEndOfFile is called before PredefinesFileId is set");
ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);
}
if (LeavingSubmodule) { if (LeavingSubmodule) {
// We're done with this submodule. // We're done with this submodule.
Module *M = LeaveSubmodule(/*ForPragma*/false); Module *M = LeaveSubmodule(/*ForPragma*/false);
@ -489,6 +495,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
PPCallbacks::ExitFile, FileType, ExitedFID); PPCallbacks::ExitFile, FileType, ExitedFID);
} }
// Restore conditional stack from the preamble right after exiting from the
// predefines file.
if (ExitedFromPredefinesFile)
replayPreambleConditionalStack();
// Client should lex another token unless we generated an EOM. // Client should lex another token unless we generated an EOM.
return LeavingSubmodule; return LeavingSubmodule;
} }

View File

@ -540,6 +540,8 @@ void Preprocessor::EnterMainSourceFile() {
void Preprocessor::replayPreambleConditionalStack() { void Preprocessor::replayPreambleConditionalStack() {
// Restore the conditional stack from the preamble, if there is one. // Restore the conditional stack from the preamble, if there is one.
if (PreambleConditionalStack.isReplaying()) { if (PreambleConditionalStack.isReplaying()) {
assert(CurPPLexer &&
"CurPPLexer is null when calling replayPreambleConditionalStack.");
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack());
PreambleConditionalStack.doneReplaying(); PreambleConditionalStack.doneReplaying();
} }

View File

@ -516,8 +516,6 @@ void Parser::Initialize() {
// Prime the lexer look-ahead. // Prime the lexer look-ahead.
ConsumeToken(); ConsumeToken();
PP.replayPreambleConditionalStack();
} }
void Parser::LateTemplateParserCleanupCallback(void *P) { void Parser::LateTemplateParserCleanupCallback(void *P) {

View File

@ -5726,6 +5726,53 @@ static void DefineImplicitSpecialMember(Sema &S, CXXMethodDecl *MD,
} }
} }
/// Determine whether a type is permitted to be passed or returned in
/// registers, per C++ [class.temporary]p3.
static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl *D) {
if (D->isDependentType() || D->isInvalidDecl())
return false;
// Per C++ [class.temporary]p3, the relevant condition is:
// each copy constructor, move constructor, and destructor of X is
// either trivial or deleted, and X has at least one non-deleted copy
// or move constructor
bool HasNonDeletedCopyOrMove = false;
if (D->needsImplicitCopyConstructor() &&
!D->defaultedCopyConstructorIsDeleted()) {
if (!D->hasTrivialCopyConstructor())
return false;
HasNonDeletedCopyOrMove = true;
}
if (S.getLangOpts().CPlusPlus11 && D->needsImplicitMoveConstructor() &&
!D->defaultedMoveConstructorIsDeleted()) {
if (!D->hasTrivialMoveConstructor())
return false;
HasNonDeletedCopyOrMove = true;
}
if (D->needsImplicitDestructor() && !D->defaultedDestructorIsDeleted() &&
!D->hasTrivialDestructor())
return false;
for (const CXXMethodDecl *MD : D->methods()) {
if (MD->isDeleted())
continue;
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
if (CD && CD->isCopyOrMoveConstructor())
HasNonDeletedCopyOrMove = true;
else if (!isa<CXXDestructorDecl>(MD))
continue;
if (!MD->isTrivial())
return false;
}
return HasNonDeletedCopyOrMove;
}
/// \brief Perform semantic checks on a class definition that has been /// \brief Perform semantic checks on a class definition that has been
/// completing, introducing implicitly-declared members, checking for /// completing, introducing implicitly-declared members, checking for
/// abstract types, etc. /// abstract types, etc.
@ -5870,6 +5917,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
} }
checkClassLevelDLLAttribute(Record); checkClassLevelDLLAttribute(Record);
Record->setCanPassInRegisters(computeCanPassInRegisters(*this, Record));
} }
/// Look up the special member function that would be called by a special /// Look up the special member function that would be called by a special
@ -7496,8 +7545,7 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
reinterpret_cast<Decl**>(FieldCollector->getCurFields()), reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
FieldCollector->getCurNumFields()), LBrac, RBrac, AttrList); FieldCollector->getCurNumFields()), LBrac, RBrac, AttrList);
CheckCompletedCXXClass( CheckCompletedCXXClass(dyn_cast_or_null<CXXRecordDecl>(TagDecl));
dyn_cast_or_null<CXXRecordDecl>(TagDecl));
} }
/// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared /// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared
@ -11929,8 +11977,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
Scope *S = getScopeForContext(ClassDecl); Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyConstructor); CheckImplicitSpecialMemberDeclaration(S, CopyConstructor);
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) {
ClassDecl->setImplicitCopyConstructorIsDeleted();
SetDeclDeleted(CopyConstructor, ClassLoc); SetDeclDeleted(CopyConstructor, ClassLoc);
}
if (S) if (S)
PushOnScopeChains(CopyConstructor, S, false); PushOnScopeChains(CopyConstructor, S, false);

View File

@ -872,7 +872,7 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
} }
QualType RHSType = S.Context.getCanonicalType(Property->getType()); QualType RHSType = S.Context.getCanonicalType(Property->getType());
unsigned OriginalAttributes = Property->getPropertyAttributes(); unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
enum MismatchKind { enum MismatchKind {
IncompatibleType = 0, IncompatibleType = 0,
HasNoExpectedAttribute, HasNoExpectedAttribute,
@ -890,7 +890,7 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
SmallVector<MismatchingProperty, 4> Mismatches; SmallVector<MismatchingProperty, 4> Mismatches;
for (ObjCPropertyDecl *Prop : Properties) { for (ObjCPropertyDecl *Prop : Properties) {
// Verify the property attributes. // Verify the property attributes.
unsigned Attr = Prop->getPropertyAttributes(); unsigned Attr = Prop->getPropertyAttributesAsWritten();
if (Attr != OriginalAttributes) { if (Attr != OriginalAttributes) {
auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) { auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute

View File

@ -1559,9 +1559,11 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasUninitializedFields = Record.readInt(); Data.HasUninitializedFields = Record.readInt();
Data.HasInheritedConstructor = Record.readInt(); Data.HasInheritedConstructor = Record.readInt();
Data.HasInheritedAssignment = Record.readInt(); Data.HasInheritedAssignment = Record.readInt();
Data.NeedOverloadResolutionForCopyConstructor = Record.readInt();
Data.NeedOverloadResolutionForMoveConstructor = Record.readInt(); Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
Data.NeedOverloadResolutionForMoveAssignment = Record.readInt(); Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
Data.NeedOverloadResolutionForDestructor = Record.readInt(); Data.NeedOverloadResolutionForDestructor = Record.readInt();
Data.DefaultedCopyConstructorIsDeleted = Record.readInt();
Data.DefaultedMoveConstructorIsDeleted = Record.readInt(); Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
Data.DefaultedMoveAssignmentIsDeleted = Record.readInt(); Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
Data.DefaultedDestructorIsDeleted = Record.readInt(); Data.DefaultedDestructorIsDeleted = Record.readInt();
@ -1570,6 +1572,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasIrrelevantDestructor = Record.readInt(); Data.HasIrrelevantDestructor = Record.readInt();
Data.HasConstexprNonCopyMoveConstructor = Record.readInt(); Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
Data.HasDefaultedDefaultConstructor = Record.readInt(); Data.HasDefaultedDefaultConstructor = Record.readInt();
Data.CanPassInRegisters = Record.readInt();
Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt(); Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
Data.HasConstexprDefaultConstructor = Record.readInt(); Data.HasConstexprDefaultConstructor = Record.readInt();
Data.HasNonLiteralTypeFieldsOrBases = Record.readInt(); Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
@ -1697,9 +1700,11 @@ void ASTDeclReader::MergeDefinitionData(
MATCH_FIELD(HasUninitializedFields) MATCH_FIELD(HasUninitializedFields)
MATCH_FIELD(HasInheritedConstructor) MATCH_FIELD(HasInheritedConstructor)
MATCH_FIELD(HasInheritedAssignment) MATCH_FIELD(HasInheritedAssignment)
MATCH_FIELD(NeedOverloadResolutionForCopyConstructor)
MATCH_FIELD(NeedOverloadResolutionForMoveConstructor) MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
MATCH_FIELD(NeedOverloadResolutionForMoveAssignment) MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
MATCH_FIELD(NeedOverloadResolutionForDestructor) MATCH_FIELD(NeedOverloadResolutionForDestructor)
MATCH_FIELD(DefaultedCopyConstructorIsDeleted)
MATCH_FIELD(DefaultedMoveConstructorIsDeleted) MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
MATCH_FIELD(DefaultedMoveAssignmentIsDeleted) MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
MATCH_FIELD(DefaultedDestructorIsDeleted) MATCH_FIELD(DefaultedDestructorIsDeleted)
@ -1708,6 +1713,7 @@ void ASTDeclReader::MergeDefinitionData(
MATCH_FIELD(HasIrrelevantDestructor) MATCH_FIELD(HasIrrelevantDestructor)
OR_FIELD(HasConstexprNonCopyMoveConstructor) OR_FIELD(HasConstexprNonCopyMoveConstructor)
OR_FIELD(HasDefaultedDefaultConstructor) OR_FIELD(HasDefaultedDefaultConstructor)
MATCH_FIELD(CanPassInRegisters)
MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr) MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
OR_FIELD(HasConstexprDefaultConstructor) OR_FIELD(HasConstexprDefaultConstructor)
MATCH_FIELD(HasNonLiteralTypeFieldsOrBases) MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)

View File

@ -5874,9 +5874,11 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
Record->push_back(Data.HasUninitializedFields); Record->push_back(Data.HasUninitializedFields);
Record->push_back(Data.HasInheritedConstructor); Record->push_back(Data.HasInheritedConstructor);
Record->push_back(Data.HasInheritedAssignment); Record->push_back(Data.HasInheritedAssignment);
Record->push_back(Data.NeedOverloadResolutionForCopyConstructor);
Record->push_back(Data.NeedOverloadResolutionForMoveConstructor); Record->push_back(Data.NeedOverloadResolutionForMoveConstructor);
Record->push_back(Data.NeedOverloadResolutionForMoveAssignment); Record->push_back(Data.NeedOverloadResolutionForMoveAssignment);
Record->push_back(Data.NeedOverloadResolutionForDestructor); Record->push_back(Data.NeedOverloadResolutionForDestructor);
Record->push_back(Data.DefaultedCopyConstructorIsDeleted);
Record->push_back(Data.DefaultedMoveConstructorIsDeleted); Record->push_back(Data.DefaultedMoveConstructorIsDeleted);
Record->push_back(Data.DefaultedMoveAssignmentIsDeleted); Record->push_back(Data.DefaultedMoveAssignmentIsDeleted);
Record->push_back(Data.DefaultedDestructorIsDeleted); Record->push_back(Data.DefaultedDestructorIsDeleted);
@ -5885,6 +5887,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
Record->push_back(Data.HasIrrelevantDestructor); Record->push_back(Data.HasIrrelevantDestructor);
Record->push_back(Data.HasConstexprNonCopyMoveConstructor); Record->push_back(Data.HasConstexprNonCopyMoveConstructor);
Record->push_back(Data.HasDefaultedDefaultConstructor); Record->push_back(Data.HasDefaultedDefaultConstructor);
Record->push_back(Data.CanPassInRegisters);
Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr); Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr);
Record->push_back(Data.HasConstexprDefaultConstructor); Record->push_back(Data.HasConstexprDefaultConstructor);
Record->push_back(Data.HasNonLiteralTypeFieldsOrBases); Record->push_back(Data.HasNonLiteralTypeFieldsOrBases);

View File

@ -409,6 +409,19 @@ public: // Part of public interface to class.
// BindDefault is only used to initialize a region with a default value. // BindDefault is only used to initialize a region with a default value.
StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override { StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override {
// FIXME: The offsets of empty bases can be tricky because of
// of the so called "empty base class optimization".
// If a base class has been optimized out
// we should not try to create a binding, otherwise we should.
// Unfortunately, at the moment ASTRecordLayout doesn't expose
// the actual sizes of the empty bases
// and trying to infer them from offsets/alignments
// seems to be error-prone and non-trivial because of the trailing padding.
// As a temporary mitigation we don't create bindings for empty bases.
if (R->getKind() == MemRegion::CXXBaseObjectRegionKind &&
cast<CXXBaseObjectRegion>(R)->getDecl()->isEmpty())
return StoreRef(store, *this);
RegionBindingsRef B = getRegionBindings(store); RegionBindingsRef B = getRegionBindings(store);
assert(!B.lookup(R, BindingKey::Direct)); assert(!B.lookup(R, BindingKey::Direct));

View File

@ -36,8 +36,7 @@ struct GPR {
struct FPR_i386 { struct FPR_i386 {
uint16_t fctrl; // FPU Control Word (fcw) uint16_t fctrl; // FPU Control Word (fcw)
uint16_t fstat; // FPU Status Word (fsw) uint16_t fstat; // FPU Status Word (fsw)
uint8_t ftag; // FPU Tag Word (ftw) uint16_t ftag; // FPU Tag Word (ftw)
uint8_t reserved_1; // Reserved
uint16_t fop; // Last Instruction Opcode (fop) uint16_t fop; // Last Instruction Opcode (fop)
union { union {
struct { struct {

View File

@ -257,8 +257,7 @@ struct XMMReg {
struct FXSAVE { struct FXSAVE {
uint16_t fctrl; // FPU Control Word (fcw) uint16_t fctrl; // FPU Control Word (fcw)
uint16_t fstat; // FPU Status Word (fsw) uint16_t fstat; // FPU Status Word (fsw)
uint8_t ftag; // FPU Tag Word (ftw) uint16_t ftag; // FPU Tag Word (ftw)
uint8_t reserved_1; // Reserved
uint16_t fop; // Last Instruction Opcode (fop) uint16_t fop; // Last Instruction Opcode (fop)
union { union {
struct { struct {

View File

@ -8,4 +8,4 @@
#define CLANG_VENDOR "FreeBSD " #define CLANG_VENDOR "FreeBSD "
#define SVN_REVISION "311219" #define SVN_REVISION "311606"

View File

@ -4,5 +4,5 @@
#define LLD_VERSION_STRING "5.0.0" #define LLD_VERSION_STRING "5.0.0"
#define LLD_VERSION_MAJOR 5 #define LLD_VERSION_MAJOR 5
#define LLD_VERSION_MINOR 0 #define LLD_VERSION_MINOR 0
#define LLD_REVISION_STRING "311219" #define LLD_REVISION_STRING "311606"
#define LLD_REPOSITORY_STRING "FreeBSD" #define LLD_REPOSITORY_STRING "FreeBSD"

View File

@ -1,2 +1,2 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
#define LLVM_REVISION "svn-r311219" #define LLVM_REVISION "svn-r311606"