summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGAtomic.cpp1
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp106
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp100
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp88
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp114
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.h305
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGException.cpp358
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp22
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp36
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp92
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h9
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayout.h12
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp12
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp26
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp25
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h77
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp5
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp34
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp193
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp10
27 files changed, 1089 insertions, 577 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp b/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
index 0bccad0..afcb9e5 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
@@ -292,6 +292,7 @@ void EmitAssemblyHelper::CreatePasses() {
PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
+ PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
@@ -454,8 +455,6 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
BackendArgs.push_back("-limit-float-precision");
BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
}
- if (llvm::TimePassesIsEnabled)
- BackendArgs.push_back("-time-passes");
for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
BackendArgs.push_back(nullptr);
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGAtomic.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGAtomic.cpp
index da82249..9839617 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGAtomic.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGAtomic.cpp
@@ -93,6 +93,7 @@ namespace {
BFI = OrigBFI;
BFI.Offset = Offset;
BFI.StorageSize = AtomicSizeInBits;
+ BFI.StorageOffset += OffsetInChars;
LVal = LValue::MakeBitfield(Addr, BFI, lvalue.getType(),
lvalue.getAlignment());
LVal.setTBAAInfo(lvalue.getTBAAInfo());
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp
index 2ec909b..9e53870 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGBuiltin.cpp
@@ -535,7 +535,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
}
case Builtin::BI__builtin_readcyclecounter: {
Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
- return RValue::get(Builder.CreateCall(F, {}));
+ return RValue::get(Builder.CreateCall(F));
}
case Builtin::BI__builtin___clear_cache: {
Value *Begin = EmitScalarExpr(E->getArg(0));
@@ -923,7 +923,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
}
case Builtin::BI__builtin_unwind_init: {
Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
- return RValue::get(Builder.CreateCall(F, {}));
+ return RValue::get(Builder.CreateCall(F));
}
case Builtin::BI__builtin_extend_pointer: {
// Extends a pointer to the size of an _Unwind_Word, which is
@@ -962,7 +962,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
// Store the stack pointer to the setjmp buffer.
Value *StackAddr =
- Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave), {});
+ Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
Value *StackSaveSlot =
Builder.CreateGEP(Buf, ConstantInt::get(Int32Ty, 2));
Builder.CreateStore(StackAddr, StackSaveSlot);
@@ -3399,7 +3399,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
: InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "",
/*SideEffects=*/true);
- return Builder.CreateCall(Emit, {});
+ return Builder.CreateCall(Emit);
}
if (BuiltinID == ARM::BI__builtin_arm_dbg) {
@@ -3543,7 +3543,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
if (BuiltinID == ARM::BI__builtin_arm_clrex) {
Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
- return Builder.CreateCall(F, {});
+ return Builder.CreateCall(F);
}
// CRC32
@@ -4339,7 +4339,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
- return Builder.CreateCall(F, {});
+ return Builder.CreateCall(F);
}
// CRC32
@@ -6375,7 +6375,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
break;
}
- Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID), {});
+ Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
Builder.CreateStore(Builder.CreateExtractValue(Call, 0), Ops[0]);
return Builder.CreateExtractValue(Call, 1);
}
@@ -6633,14 +6633,104 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
llvm::Function *F = CGM.getIntrinsic(ID);
return Builder.CreateCall(F, Ops, "");
}
+ // Square root
+ case PPC::BI__builtin_vsx_xvsqrtsp:
+ case PPC::BI__builtin_vsx_xvsqrtdp: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ ID = Intrinsic::sqrt;
+ llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
+ return Builder.CreateCall(F, X);
+ }
+ // Count leading zeros
+ case PPC::BI__builtin_altivec_vclzb:
+ case PPC::BI__builtin_altivec_vclzh:
+ case PPC::BI__builtin_altivec_vclzw:
+ case PPC::BI__builtin_altivec_vclzd: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
+ return Builder.CreateCall(F, {X, Undef});
+ }
+ // Copy sign
+ case PPC::BI__builtin_vsx_xvcpsgnsp:
+ case PPC::BI__builtin_vsx_xvcpsgndp: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ ID = Intrinsic::copysign;
+ llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
+ return Builder.CreateCall(F, {X, Y});
+ }
+ // Rounding/truncation
case PPC::BI__builtin_vsx_xvrspip:
case PPC::BI__builtin_vsx_xvrdpip:
+ case PPC::BI__builtin_vsx_xvrdpim:
+ case PPC::BI__builtin_vsx_xvrspim:
+ case PPC::BI__builtin_vsx_xvrdpi:
+ case PPC::BI__builtin_vsx_xvrspi:
+ case PPC::BI__builtin_vsx_xvrdpic:
+ case PPC::BI__builtin_vsx_xvrspic:
+ case PPC::BI__builtin_vsx_xvrdpiz:
+ case PPC::BI__builtin_vsx_xvrspiz: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
- ID = Intrinsic::ceil;
+ if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspim)
+ ID = Intrinsic::floor;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspi)
+ ID = Intrinsic::round;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspic)
+ ID = Intrinsic::nearbyint;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspip)
+ ID = Intrinsic::ceil;
+ else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
+ BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
+ ID = Intrinsic::trunc;
llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
return Builder.CreateCall(F, X);
}
+ // FMA variations
+ case PPC::BI__builtin_vsx_xvmaddadp:
+ case PPC::BI__builtin_vsx_xvmaddasp:
+ case PPC::BI__builtin_vsx_xvnmaddadp:
+ case PPC::BI__builtin_vsx_xvnmaddasp:
+ case PPC::BI__builtin_vsx_xvmsubadp:
+ case PPC::BI__builtin_vsx_xvmsubasp:
+ case PPC::BI__builtin_vsx_xvnmsubadp:
+ case PPC::BI__builtin_vsx_xvnmsubasp: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ Value *Z = EmitScalarExpr(E->getArg(2));
+ Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
+ switch (BuiltinID) {
+ case PPC::BI__builtin_vsx_xvmaddadp:
+ case PPC::BI__builtin_vsx_xvmaddasp:
+ return Builder.CreateCall(F, {X, Y, Z});
+ case PPC::BI__builtin_vsx_xvnmaddadp:
+ case PPC::BI__builtin_vsx_xvnmaddasp:
+ return Builder.CreateFSub(Zero,
+ Builder.CreateCall(F, {X, Y, Z}), "sub");
+ case PPC::BI__builtin_vsx_xvmsubadp:
+ case PPC::BI__builtin_vsx_xvmsubasp:
+ return Builder.CreateCall(F,
+ {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
+ case PPC::BI__builtin_vsx_xvnmsubadp:
+ case PPC::BI__builtin_vsx_xvnmsubasp:
+ Value *FsubRes =
+ Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
+ return Builder.CreateFSub(Zero, FsubRes, "sub");
+ }
+ llvm_unreachable("Unknown FMA operation");
+ return nullptr; // Suppress no-return warning
+ }
+ }
}
// Emit an intrinsic that has 1 float or double.
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp
index 0535c05..3e4d7f3 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGCall.cpp
@@ -912,20 +912,21 @@ static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val,
/// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
-/// a pointer to an object of type \arg Ty.
+/// a pointer to an object of type \arg Ty, known to be aligned to
+/// \arg SrcAlign bytes.
///
/// This safely handles the case when the src type is smaller than the
/// destination type; in this situation the values of bits which not
/// present in the src are undefined.
static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
- llvm::Type *Ty,
+ llvm::Type *Ty, CharUnits SrcAlign,
CodeGenFunction &CGF) {
llvm::Type *SrcTy =
cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
// If SrcTy and Ty are the same, just do a load.
if (SrcTy == Ty)
- return CGF.Builder.CreateLoad(SrcPtr);
+ return CGF.Builder.CreateAlignedLoad(SrcPtr, SrcAlign.getQuantity());
uint64_t DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty);
@@ -940,7 +941,8 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
// extension or truncation to the desired type.
if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
(isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
- llvm::LoadInst *Load = CGF.Builder.CreateLoad(SrcPtr);
+ llvm::LoadInst *Load =
+ CGF.Builder.CreateAlignedLoad(SrcPtr, SrcAlign.getQuantity());
return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF);
}
@@ -954,23 +956,20 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
// to that information.
llvm::Value *Casted =
CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty));
- llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted);
- // FIXME: Use better alignment / avoid requiring aligned load.
- Load->setAlignment(1);
- return Load;
+ return CGF.Builder.CreateAlignedLoad(Casted, SrcAlign.getQuantity());
}
// Otherwise do coercion through memory. This is stupid, but
// simple.
- llvm::Value *Tmp = CGF.CreateTempAlloca(Ty);
+ llvm::AllocaInst *Tmp = CGF.CreateTempAlloca(Ty);
+ Tmp->setAlignment(SrcAlign.getQuantity());
llvm::Type *I8PtrTy = CGF.Builder.getInt8PtrTy();
llvm::Value *Casted = CGF.Builder.CreateBitCast(Tmp, I8PtrTy);
llvm::Value *SrcCasted = CGF.Builder.CreateBitCast(SrcPtr, I8PtrTy);
- // FIXME: Use better alignment.
CGF.Builder.CreateMemCpy(Casted, SrcCasted,
llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize),
- 1, false);
- return CGF.Builder.CreateLoad(Tmp);
+ SrcAlign.getQuantity(), false);
+ return CGF.Builder.CreateAlignedLoad(Tmp, SrcAlign.getQuantity());
}
// Function to store a first-class aggregate into memory. We prefer to
@@ -979,39 +978,45 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
// FIXME: Do we need to recurse here?
static void BuildAggStore(CodeGenFunction &CGF, llvm::Value *Val,
llvm::Value *DestPtr, bool DestIsVolatile,
- bool LowAlignment) {
+ CharUnits DestAlign) {
// Prefer scalar stores to first-class aggregate stores.
if (llvm::StructType *STy =
dyn_cast<llvm::StructType>(Val->getType())) {
+ const llvm::StructLayout *Layout =
+ CGF.CGM.getDataLayout().getStructLayout(STy);
+
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
llvm::Value *EltPtr = CGF.Builder.CreateConstGEP2_32(STy, DestPtr, 0, i);
llvm::Value *Elt = CGF.Builder.CreateExtractValue(Val, i);
- llvm::StoreInst *SI = CGF.Builder.CreateStore(Elt, EltPtr,
- DestIsVolatile);
- if (LowAlignment)
- SI->setAlignment(1);
+ uint64_t EltOffset = Layout->getElementOffset(i);
+ CharUnits EltAlign =
+ DestAlign.alignmentAtOffset(CharUnits::fromQuantity(EltOffset));
+ CGF.Builder.CreateAlignedStore(Elt, EltPtr, EltAlign.getQuantity(),
+ DestIsVolatile);
}
} else {
- llvm::StoreInst *SI = CGF.Builder.CreateStore(Val, DestPtr, DestIsVolatile);
- if (LowAlignment)
- SI->setAlignment(1);
+ CGF.Builder.CreateAlignedStore(Val, DestPtr, DestAlign.getQuantity(),
+ DestIsVolatile);
}
}
/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src,
-/// where the source and destination may have different types.
+/// where the source and destination may have different types. The
+/// destination is known to be aligned to \arg DstAlign bytes.
///
/// This safely handles the case when the src type is larger than the
/// destination type; the upper bits of the src will be lost.
static void CreateCoercedStore(llvm::Value *Src,
llvm::Value *DstPtr,
bool DstIsVolatile,
+ CharUnits DstAlign,
CodeGenFunction &CGF) {
llvm::Type *SrcTy = Src->getType();
llvm::Type *DstTy =
cast<llvm::PointerType>(DstPtr->getType())->getElementType();
if (SrcTy == DstTy) {
- CGF.Builder.CreateStore(Src, DstPtr, DstIsVolatile);
+ CGF.Builder.CreateAlignedStore(Src, DstPtr, DstAlign.getQuantity(),
+ DstIsVolatile);
return;
}
@@ -1027,7 +1032,8 @@ static void CreateCoercedStore(llvm::Value *Src,
if ((isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy)) &&
(isa<llvm::IntegerType>(DstTy) || isa<llvm::PointerType>(DstTy))) {
Src = CoerceIntOrPtrToIntOrPtr(Src, DstTy, CGF);
- CGF.Builder.CreateStore(Src, DstPtr, DstIsVolatile);
+ CGF.Builder.CreateAlignedStore(Src, DstPtr, DstAlign.getQuantity(),
+ DstIsVolatile);
return;
}
@@ -1037,8 +1043,7 @@ static void CreateCoercedStore(llvm::Value *Src,
if (SrcSize <= DstSize) {
llvm::Value *Casted =
CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy));
- // FIXME: Use better alignment / avoid requiring aligned store.
- BuildAggStore(CGF, Src, Casted, DstIsVolatile, true);
+ BuildAggStore(CGF, Src, Casted, DstIsVolatile, DstAlign);
} else {
// Otherwise do coercion through memory. This is stupid, but
// simple.
@@ -1049,15 +1054,15 @@ static void CreateCoercedStore(llvm::Value *Src,
//
// FIXME: Assert that we aren't truncating non-padding bits when have access
// to that information.
- llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy);
- CGF.Builder.CreateStore(Src, Tmp);
+ llvm::AllocaInst *Tmp = CGF.CreateTempAlloca(SrcTy);
+ Tmp->setAlignment(DstAlign.getQuantity());
+ CGF.Builder.CreateAlignedStore(Src, Tmp, DstAlign.getQuantity());
llvm::Type *I8PtrTy = CGF.Builder.getInt8PtrTy();
llvm::Value *Casted = CGF.Builder.CreateBitCast(Tmp, I8PtrTy);
llvm::Value *DstCasted = CGF.Builder.CreateBitCast(DstPtr, I8PtrTy);
- // FIXME: Use better alignment.
CGF.Builder.CreateMemCpy(DstCasted, Casted,
llvm::ConstantInt::get(CGF.IntPtrTy, DstSize),
- 1, false);
+ DstAlign.getQuantity(), false);
}
}
@@ -1506,7 +1511,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
if (FD) {
- if (const TargetAttr *TD = FD->getAttr<TargetAttr>()) {
+ if (const auto *TD = FD->getAttr<TargetAttr>()) {
StringRef FeaturesStr = TD->getFeatures();
SmallVector<StringRef, 1> AttrFeatures;
FeaturesStr.split(AttrFeatures, ",");
@@ -1514,9 +1519,13 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
// Grab the various features and prepend a "+" to turn on the feature to
// the backend and add them to our existing set of features.
for (auto &Feature : AttrFeatures) {
+ // Go ahead and trim whitespace rather than either erroring or
+ // accepting it weirdly.
+ Feature = Feature.trim();
+
// While we're here iterating check for a different target cpu.
if (Feature.startswith("arch="))
- TargetCPU = Feature.split("=").second;
+ TargetCPU = Feature.split("=").second.trim();
else if (Feature.startswith("tune="))
// We don't support cpu tuning this way currently.
;
@@ -1992,6 +2001,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
Alloca->setAlignment(AlignmentToUse);
llvm::Value *V = Alloca;
llvm::Value *Ptr = V; // Pointer to store into.
+ CharUnits PtrAlign = CharUnits::fromQuantity(AlignmentToUse);
// If the value is offset in memory, apply the offset now.
if (unsigned Offs = ArgI.getDirectOffset()) {
@@ -1999,6 +2009,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
Ptr = Builder.CreateConstGEP1_32(Builder.getInt8Ty(), Ptr, Offs);
Ptr = Builder.CreateBitCast(Ptr,
llvm::PointerType::getUnqual(ArgI.getCoerceToType()));
+ PtrAlign = PtrAlign.alignmentAtOffset(CharUnits::fromQuantity(Offs));
}
// Fast-isel and the optimizer generally like scalar values better than
@@ -2043,7 +2054,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
assert(NumIRArgs == 1);
auto AI = FnArgs[FirstIRArg];
AI->setName(Arg->getName() + ".coerce");
- CreateCoercedStore(AI, Ptr, /*DestIsVolatile=*/false, *this);
+ CreateCoercedStore(AI, Ptr, /*DestIsVolatile=*/false, PtrAlign, *this);
}
@@ -2411,15 +2422,17 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
}
} else {
llvm::Value *V = ReturnValue;
+ CharUnits Align = getContext().getTypeAlignInChars(RetTy);
// If the value is offset in memory, apply the offset now.
if (unsigned Offs = RetAI.getDirectOffset()) {
V = Builder.CreateBitCast(V, Builder.getInt8PtrTy());
V = Builder.CreateConstGEP1_32(Builder.getInt8Ty(), V, Offs);
V = Builder.CreateBitCast(V,
llvm::PointerType::getUnqual(RetAI.getCoerceToType()));
+ Align = Align.alignmentAtOffset(CharUnits::fromQuantity(Offs));
}
- RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this);
+ RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), Align, *this);
}
// In ARC, end functions that return a retainable type with a call
@@ -3282,12 +3295,17 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// FIXME: Avoid the conversion through memory if possible.
llvm::Value *SrcPtr;
+ CharUnits SrcAlign;
if (RV.isScalar() || RV.isComplex()) {
SrcPtr = CreateMemTemp(I->Ty, "coerce");
+ SrcAlign = TypeAlign;
LValue SrcLV = MakeAddrLValue(SrcPtr, I->Ty, TypeAlign);
EmitInitStoreOfNonAggregate(*this, RV, SrcLV);
- } else
+ } else {
SrcPtr = RV.getAggregateAddr();
+ // This alignment is guaranteed by EmitCallArg.
+ SrcAlign = TypeAlign;
+ }
// If the value is offset in memory, apply the offset now.
if (unsigned Offs = ArgInfo.getDirectOffset()) {
@@ -3295,7 +3313,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
SrcPtr = Builder.CreateConstGEP1_32(Builder.getInt8Ty(), SrcPtr, Offs);
SrcPtr = Builder.CreateBitCast(SrcPtr,
llvm::PointerType::getUnqual(ArgInfo.getCoerceToType()));
-
+ SrcAlign = SrcAlign.alignmentAtOffset(CharUnits::fromQuantity(Offs));
}
// Fast-isel and the optimizer generally like scalar values better than
@@ -3334,7 +3352,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// In the simple case, just pass the coerced loaded value.
assert(NumIRArgs == 1);
IRCallArgs[FirstIRArg] =
- CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(), *this);
+ CreateCoercedLoad(SrcPtr, ArgInfo.getCoerceToType(),
+ SrcAlign, *this);
}
break;
@@ -3531,12 +3550,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
case TEK_Aggregate: {
llvm::Value *DestPtr = ReturnValue.getValue();
bool DestIsVolatile = ReturnValue.isVolatile();
+ CharUnits DestAlign = getContext().getTypeAlignInChars(RetTy);
if (!DestPtr) {
DestPtr = CreateMemTemp(RetTy, "agg.tmp");
DestIsVolatile = false;
}
- BuildAggStore(*this, CI, DestPtr, DestIsVolatile, false);
+ BuildAggStore(*this, CI, DestPtr, DestIsVolatile, DestAlign);
return RValue::getAggregate(DestPtr);
}
case TEK_Scalar: {
@@ -3553,6 +3573,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
llvm::Value *DestPtr = ReturnValue.getValue();
bool DestIsVolatile = ReturnValue.isVolatile();
+ CharUnits DestAlign = getContext().getTypeAlignInChars(RetTy);
if (!DestPtr) {
DestPtr = CreateMemTemp(RetTy, "coerce");
@@ -3561,14 +3582,17 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// If the value is offset in memory, apply the offset now.
llvm::Value *StorePtr = DestPtr;
+ CharUnits StoreAlign = DestAlign;
if (unsigned Offs = RetAI.getDirectOffset()) {
StorePtr = Builder.CreateBitCast(StorePtr, Builder.getInt8PtrTy());
StorePtr =
Builder.CreateConstGEP1_32(Builder.getInt8Ty(), StorePtr, Offs);
StorePtr = Builder.CreateBitCast(StorePtr,
llvm::PointerType::getUnqual(RetAI.getCoerceToType()));
+ StoreAlign =
+ StoreAlign.alignmentAtOffset(CharUnits::fromQuantity(Offs));
}
- CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this);
+ CreateCoercedStore(CI, StorePtr, DestIsVolatile, StoreAlign, *this);
return convertTempToRValue(DestPtr, RetTy, SourceLocation());
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp
index 62df982..c49f182 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGClass.cpp
@@ -554,6 +554,20 @@ static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) {
return false;
}
+static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF,
+ CXXCtorInitializer *MemberInit,
+ LValue &LHS) {
+ FieldDecl *Field = MemberInit->getAnyMember();
+ if (MemberInit->isIndirectMemberInitializer()) {
+ // If we are initializing an anonymous union field, drill down to the field.
+ IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
+ for (const auto *I : IndirectField->chain())
+ LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
+ } else {
+ LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
+ }
+}
+
static void EmitMemberInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
CXXCtorInitializer *MemberInit,
@@ -572,16 +586,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
- if (MemberInit->isIndirectMemberInitializer()) {
- // If we are initializing an anonymous union field, drill down to
- // the field.
- IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
- for (const auto *I : IndirectField->chain())
- LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
- FieldType = MemberInit->getIndirectMember()->getAnonField()->getType();
- } else {
- LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
- }
+ EmitLValueForAnyFieldInitialization(CGF, MemberInit, LHS);
// Special case: if we are in a copy or move constructor, and we are copying
// an array of PODs or classes with trivial copy constructors, ignore the
@@ -606,6 +611,11 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
// Copy the aggregate.
CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
LHS.isVolatileQualified());
+ // Ensure that we destroy the objects if an exception is thrown later in
+ // the constructor.
+ QualType::DestructionKind dtorKind = FieldType.isDestructedType();
+ if (CGF.needsEHCleanup(dtorKind))
+ CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType);
return;
}
}
@@ -906,32 +916,18 @@ namespace {
return;
}
- CharUnits Alignment;
-
uint64_t FirstByteOffset;
if (FirstField->isBitField()) {
const CGRecordLayout &RL =
CGF.getTypes().getCGRecordLayout(FirstField->getParent());
const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField);
- Alignment = CharUnits::fromQuantity(BFInfo.StorageAlignment);
// FirstFieldOffset is not appropriate for bitfields,
- // it won't tell us what the storage offset should be and thus might not
- // be properly aligned.
- //
- // Instead calculate the storage offset using the offset of the field in
- // the struct type.
- const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
- FirstByteOffset =
- DL.getStructLayout(RL.getLLVMType())
- ->getElementOffsetInBits(RL.getLLVMFieldNo(FirstField));
+ // we need to use the storage offset instead.
+ FirstByteOffset = CGF.getContext().toBits(BFInfo.StorageOffset);
} else {
- Alignment = CGF.getContext().getDeclAlign(FirstField);
FirstByteOffset = FirstFieldOffset;
}
- assert((CGF.getContext().toCharUnitsFromBits(FirstByteOffset) %
- Alignment) == 0 && "Bad field alignment.");
-
CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
llvm::Value *ThisPtr = CGF.LoadCXXThis();
@@ -941,6 +937,9 @@ namespace {
LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy);
LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField);
+ CharUnits Offset = CGF.getContext().toCharUnitsFromBits(FirstByteOffset);
+ CharUnits Alignment = DestLV.getAlignment().alignmentAtOffset(Offset);
+
emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddr() : Dest.getAddress(),
Src.isBitField() ? Src.getBitFieldAddr() : Src.getAddress(),
MemcpySize, Alignment);
@@ -1078,6 +1077,7 @@ namespace {
CopyingValueRepresentation CVR(CGF);
EmitMemberInitializer(CGF, ConstructorDecl->getParent(),
AggregatedInits[0], ConstructorDecl, Args);
+ AggregatedInits.clear();
}
reset();
return;
@@ -1094,10 +1094,14 @@ namespace {
LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
- QualType FieldType = AggregatedInits[i]->getMember()->getType();
+ CXXCtorInitializer *MemberInit = AggregatedInits[i];
+ QualType FieldType = MemberInit->getAnyMember()->getType();
QualType::DestructionKind dtorKind = FieldType.isDestructedType();
- if (CGF.needsEHCleanup(dtorKind))
- CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType);
+ if (!CGF.needsEHCleanup(dtorKind))
+ continue;
+ LValue FieldLHS = LHS;
+ EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS);
+ CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
}
}
@@ -1363,6 +1367,25 @@ static bool CanSkipVTablePointerInitialization(ASTContext &Context,
return true;
}
+// Generates function call for handling object poisoning, passing in
+// references to 'this' and its size as arguments.
+static void EmitDtorSanitizerCallback(CodeGenFunction &CGF,
+ const CXXDestructorDecl *Dtor) {
+ const ASTRecordLayout &Layout =
+ CGF.getContext().getASTRecordLayout(Dtor->getParent());
+
+ llvm::Value *Args[] = {
+ CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.VoidPtrTy),
+ llvm::ConstantInt::get(CGF.SizeTy, Layout.getSize().getQuantity())};
+ llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+
+ llvm::FunctionType *FnType =
+ llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
+ llvm::Value *Fn =
+ CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+ CGF.EmitNounwindRuntimeCall(Fn, Args);
+}
+
/// EmitDestructorBody - Emits the body of the current destructor.
void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
@@ -1450,6 +1473,10 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
// Exit the try if applicable.
if (isTryBody)
ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
+
+ // Insert memory-poisoning instrumentation.
+ if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor)
+ EmitDtorSanitizerCallback(*this, Dtor);
}
void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) {
@@ -2202,8 +2229,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
SourceLocation Loc) {
- // FIXME: Add blacklisting scheme.
- if (RD->isInStdNamespace())
+ if (CGM.IsCFIBlacklistedRecord(RD))
return;
SanitizerScope SanScope(this);
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp
index 8c4b4b3..93a2287 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -106,8 +106,6 @@ ApplyDebugLocation::~ApplyDebugLocation() {
CGF.Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
}
-/// ArtificialLocation - An RAII object that temporarily switches to
-/// an artificial debug location that has a valid scope, but no line
void CGDebugInfo::setLocation(SourceLocation Loc) {
// If the new location isn't valid return.
if (Loc.isInvalid())
@@ -140,7 +138,6 @@ void CGDebugInfo::setLocation(SourceLocation Loc) {
}
}
-/// getContextDescriptor - Get context info for the decl.
llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context) {
if (!Context)
return TheCU;
@@ -162,9 +159,6 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context) {
return TheCU;
}
-/// getFunctionName - Get function name for the given FunctionDecl. If the
-/// name is constructed on demand (e.g. C++ destructor) then the name
-/// is stored on the side.
StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {
assert(FD && "Invalid FunctionDecl!");
IdentifierInfo *FII = FD->getIdentifier();
@@ -220,13 +214,10 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {
return internString(OS.str());
}
-/// getSelectorName - Return selector name. This is used for debugging
-/// info.
StringRef CGDebugInfo::getSelectorName(Selector S) {
return internString(S.getAsString());
}
-/// getClassName - Get class name including template argument list.
StringRef CGDebugInfo::getClassName(const RecordDecl *RD) {
// quick optimization to avoid having to intern strings that are already
// stored reliably elsewhere
@@ -244,7 +235,6 @@ StringRef CGDebugInfo::getClassName(const RecordDecl *RD) {
return internString(Name);
}
-/// getOrCreateFile - Get the file debug info descriptor for the input location.
llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
if (!Loc.isValid())
// If Location is not valid then use main input file.
@@ -274,13 +264,10 @@ llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
return F;
}
-/// getOrCreateMainFile - Get the file info for main compile unit.
llvm::DIFile *CGDebugInfo::getOrCreateMainFile() {
return DBuilder.createFile(TheCU->getFilename(), TheCU->getDirectory());
}
-/// getLineNumber - Get line number for the location. If location is invalid
-/// then use current location.
unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {
if (Loc.isInvalid() && CurLoc.isInvalid())
return 0;
@@ -289,7 +276,6 @@ unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {
return PLoc.isValid() ? PLoc.getLine() : 0;
}
-/// getColumnNumber - Get column number for the location.
unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) {
// We may not want column information at all.
if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo)
@@ -314,7 +300,6 @@ StringRef CGDebugInfo::getCurrentDirname() {
return CWDName = internString(CWD);
}
-/// CreateCompileUnit - Create new compile unit.
void CGDebugInfo::CreateCompileUnit() {
// Should we be asking the SourceManager for the main file name, instead of
@@ -385,8 +370,6 @@ void CGDebugInfo::CreateCompileUnit() {
DebugKind != CodeGenOptions::LocTrackingOnly);
}
-/// CreateType - Get the Basic type from the cache or create a new
-/// one if necessary.
llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
llvm::dwarf::TypeKind Encoding;
StringRef BTName;
@@ -537,8 +520,6 @@ llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
return DBuilder.createBasicType("complex", Size, Align, Encoding);
}
-/// CreateCVRType - Get the qualified type from the cache or create
-/// a new one if necessary.
llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
llvm::DIFile *Unit) {
QualifierCollector Qc;
@@ -627,6 +608,7 @@ static SmallString<256> getUniqueTagTypeName(const TagType *Ty,
return FullName;
}
+/// \return the approproate DWARF tag for a composite type.
static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) {
llvm::dwarf::Tag Tag;
if (RD->isStruct() || RD->isInterface())
@@ -642,7 +624,6 @@ static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) {
return Tag;
}
-// Creates a forward declaration for a RecordDecl in the given context.
llvm::DICompositeType *
CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
llvm::DIScope *Ctx) {
@@ -705,9 +686,6 @@ llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
llvm::DIType *CGDebugInfo::CreateType(const BlockPointerType *Ty,
llvm::DIFile *Unit) {
- if (BlockLiteralGeneric)
- return BlockLiteralGeneric;
-
SmallVector<llvm::Metadata *, 8> EltTys;
QualType FType;
uint64_t FieldSize, FieldOffset;
@@ -723,10 +701,10 @@ llvm::DIType *CGDebugInfo::CreateType(const BlockPointerType *Ty,
EltTys.clear();
unsigned Flags = llvm::DINode::FlagAppleBlock;
- unsigned LineNo = getLineNumber(CurLoc);
+ unsigned LineNo = 0;
auto *EltTy =
- DBuilder.createStructType(Unit, "__block_descriptor", Unit, LineNo,
+ DBuilder.createStructType(Unit, "__block_descriptor", nullptr, LineNo,
FieldOffset, 0, Flags, nullptr, Elements);
// Bit size, align and offset of the type.
@@ -746,19 +724,22 @@ llvm::DIType *CGDebugInfo::CreateType(const BlockPointerType *Ty,
FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy);
FieldSize = CGM.getContext().getTypeSize(Ty);
FieldAlign = CGM.getContext().getTypeAlign(Ty);
- EltTys.push_back(DBuilder.createMemberType(Unit, "__descriptor", Unit, LineNo,
+ EltTys.push_back(DBuilder.createMemberType(Unit, "__descriptor", nullptr, LineNo,
FieldSize, FieldAlign, FieldOffset,
0, DescTy));
FieldOffset += FieldSize;
Elements = DBuilder.getOrCreateArray(EltTys);
+ // The __block_literal_generic structs are marked with a special
+ // DW_AT_APPLE_BLOCK attribute and are an implementation detail only
+ // the debugger needs to know about. To allow type uniquing, emit
+ // them without a name or a location.
EltTy =
- DBuilder.createStructType(Unit, "__block_literal_generic", Unit, LineNo,
+ DBuilder.createStructType(Unit, "", nullptr, LineNo,
FieldOffset, 0, Flags, nullptr, Elements);
- BlockLiteralGeneric = DBuilder.createPointerType(EltTy, Size);
- return BlockLiteralGeneric;
+ return DBuilder.createPointerType(EltTy, Size);
}
llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
@@ -871,7 +852,6 @@ llvm::DIType *CGDebugInfo::createFieldType(
AlignInBits, offsetInBits, flags, debugType);
}
-/// CollectRecordLambdaFields - Helper for CollectRecordFields.
void CGDebugInfo::CollectRecordLambdaFields(
const CXXRecordDecl *CXXDecl, SmallVectorImpl<llvm::Metadata *> &elements,
llvm::DIType *RecordTy) {
@@ -916,7 +896,6 @@ void CGDebugInfo::CollectRecordLambdaFields(
}
}
-/// Helper for CollectRecordFields.
llvm::DIDerivedType *
CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy,
const RecordDecl *RD) {
@@ -946,7 +925,6 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy,
return GV;
}
-/// CollectRecordNormalField - Helper for CollectRecordFields.
void CGDebugInfo::CollectRecordNormalField(
const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit,
SmallVectorImpl<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
@@ -971,8 +949,6 @@ void CGDebugInfo::CollectRecordNormalField(
elements.push_back(fieldType);
}
-/// CollectRecordFields - A helper function to collect debug info for
-/// record fields. This is used while creating debug info entry for a Record.
void CGDebugInfo::CollectRecordFields(
const RecordDecl *record, llvm::DIFile *tunit,
SmallVectorImpl<llvm::Metadata *> &elements,
@@ -1011,9 +987,6 @@ void CGDebugInfo::CollectRecordFields(
}
}
-/// getOrCreateMethodType - CXXMethodDecl's type is a FunctionType. This
-/// function type is not updated to include implicit "this" pointer. Use this
-/// routine to get a method type which includes "this" pointer.
llvm::DISubroutineType *
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DIFile *Unit) {
@@ -1088,8 +1061,6 @@ static bool isFunctionLocalClass(const CXXRecordDecl *RD) {
return false;
}
-/// CreateCXXMemberFunction - A helper function to create a subprogram for
-/// a single member function GlobalDecl.
llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
bool IsCtorOrDtor =
@@ -1165,9 +1136,6 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
return SP;
}
-/// CollectCXXMemberFunctions - A helper function to collect debug info for
-/// C++ member functions. This is used while creating debug info entry for
-/// a Record.
void CGDebugInfo::CollectCXXMemberFunctions(
const CXXRecordDecl *RD, llvm::DIFile *Unit,
SmallVectorImpl<llvm::Metadata *> &EltTys, llvm::DIType *RecordTy) {
@@ -1206,9 +1174,6 @@ void CGDebugInfo::CollectCXXMemberFunctions(
}
}
-/// CollectCXXBases - A helper function to collect debug info for
-/// C++ base classes. This is used while creating debug info entry for
-/// a Record.
void CGDebugInfo::CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile *Unit,
SmallVectorImpl<llvm::Metadata *> &EltTys,
llvm::DIType *RecordTy) {
@@ -1246,7 +1211,6 @@ void CGDebugInfo::CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile *Unit,
}
}
-/// CollectTemplateParams - A helper function to collect template parameters.
llvm::DINodeArray
CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
ArrayRef<TemplateArgument> TAList,
@@ -1351,8 +1315,6 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
return DBuilder.getOrCreateArray(TemplateParams);
}
-/// CollectFunctionTemplateParams - A helper function to collect debug
-/// info for function template parameters.
llvm::DINodeArray
CGDebugInfo::CollectFunctionTemplateParams(const FunctionDecl *FD,
llvm::DIFile *Unit) {
@@ -1367,8 +1329,6 @@ CGDebugInfo::CollectFunctionTemplateParams(const FunctionDecl *FD,
return llvm::DINodeArray();
}
-/// CollectCXXTemplateParams - A helper function to collect debug info for
-/// template parameters.
llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const ClassTemplateSpecializationDecl *TSpecial, llvm::DIFile *Unit) {
// Always get the full list of parameters, not just the ones from
@@ -1379,7 +1339,6 @@ llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
return CollectTemplateParams(TPList, TAList.asArray(), Unit);
}
-/// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
if (VTablePtrType)
return VTablePtrType;
@@ -1397,14 +1356,11 @@ llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
return VTablePtrType;
}
-/// getVTableName - Get vtable name for the given Class.
StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {
// Copy the gdb compatible name on the side and use its reference.
return internString("_vptr$", RD->getNameAsString());
}
-/// CollectVTableInfo - If the C++ class has vtable info then insert appropriate
-/// debug info entry in EltTys vector.
void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,
SmallVectorImpl<llvm::Metadata *> &EltTys) {
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
@@ -1424,7 +1380,6 @@ void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,
EltTys.push_back(VPTR);
}
-/// getOrCreateRecordType - Emit record type's standalone debug info.
llvm::DIType *CGDebugInfo::getOrCreateRecordType(QualType RTy,
SourceLocation Loc) {
assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
@@ -1432,8 +1387,6 @@ llvm::DIType *CGDebugInfo::getOrCreateRecordType(QualType RTy,
return T;
}
-/// getOrCreateInterfaceType - Emit an objective c interface type standalone
-/// debug info.
llvm::DIType *CGDebugInfo::getOrCreateInterfaceType(QualType D,
SourceLocation Loc) {
assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
@@ -1531,7 +1484,6 @@ static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind,
return false;
}
-/// CreateType - get structure or union type.
llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {
RecordDecl *RD = Ty->getDecl();
llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0)));
@@ -1605,7 +1557,6 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
return FwdDecl;
}
-/// CreateType - get objective-c object type.
llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectType *Ty,
llvm::DIFile *Unit) {
// Ignore protocols.
@@ -1636,7 +1587,6 @@ static bool hasDefaultSetterName(const ObjCPropertyDecl *PD,
Setter->getDeclName().getObjCSelector().getNameForSlot(0);
}
-/// CreateType - get objective-c interface type.
llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
llvm::DIFile *Unit) {
ObjCInterfaceDecl *ID = Ty->getDecl();
@@ -1956,7 +1906,6 @@ llvm::DIType *CGDebugInfo::CreateType(const AtomicType *Ty, llvm::DIFile *U) {
return getOrCreateType(Ty->getValueType(), U);
}
-/// CreateEnumType - get enumeration type.
llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
const EnumDecl *ED = Ty->getDecl();
uint64_t Size = 0;
@@ -2076,8 +2025,6 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
} while (true);
}
-/// getType - Get the type from the cache or return null type if it doesn't
-/// exist.
llvm::DIType *CGDebugInfo::getTypeOrNull(QualType Ty) {
// Unwrap the type as needed for debug information.
@@ -2104,8 +2051,6 @@ void CGDebugInfo::completeTemplateDefinition(
RetainedTypes.push_back(CGM.getContext().getRecordType(&SD).getAsOpaquePtr());
}
-/// getOrCreateType - Get the type from the cache or create a new
-/// one if necessary.
llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) {
if (Ty.isNull())
return nullptr;
@@ -2126,8 +2071,6 @@ llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) {
return Res;
}
-/// Currently the checksum of an interface includes the number of
-/// ivars and property accessors.
unsigned CGDebugInfo::Checksum(const ObjCInterfaceDecl *ID) {
// The assumption is that the number of ivars can only increase
// monotonically, so it is safe to just use their current number as
@@ -2152,7 +2095,6 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCInterfaceDecl(QualType Ty) {
}
}
-/// CreateTypeNode - Create a new debug type node.
llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
// Handle qualifiers, which recursively handles what they refer to.
if (Ty.hasLocalQualifiers())
@@ -2233,8 +2175,6 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
llvm_unreachable("type should have been unwrapped!");
}
-/// getOrCreateLimitedType - Get the type from the cache or create a new
-/// limited type if necessary.
llvm::DIType *CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty,
llvm::DIFile *Unit) {
QualType QTy(Ty, 0);
@@ -2328,7 +2268,6 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
DBuilder.replaceVTableHolder(RealDecl, ContainingType);
}
-/// CreateMemberType - Create new member and increase Offset by FType's size.
llvm::DIType *CGDebugInfo::CreateMemberType(llvm::DIFile *Unit, QualType FType,
StringRef Name, uint64_t *Offset) {
llvm::DIType *FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
@@ -2493,8 +2432,6 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
return nullptr;
}
-/// getFunctionDeclaration - Return debug info descriptor to describe method
-/// declaration for the given method definition.
llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) {
if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly)
return nullptr;
@@ -2591,7 +2528,6 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D,
return cast<llvm::DISubroutineType>(getOrCreateType(FnType, F));
}
-/// EmitFunctionStart - Constructs the debug code for entering a function.
void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
SourceLocation ScopeLoc, QualType FnType,
llvm::Function *Fn, CGBuilderTy &Builder) {
@@ -2667,9 +2603,6 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
RegionMap[D].reset(SP);
}
-/// EmitLocation - Emit metadata to indicate a change in line/column
-/// information in the source file. If the location is invalid, the
-/// previous location will be reused.
void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
// Update our current location
setLocation(Loc);
@@ -2682,8 +2615,6 @@ void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope));
}
-/// CreateLexicalBlock - Creates a new lexical block node and pushes it on
-/// the stack.
void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
llvm::MDNode *Back = nullptr;
if (!LexicalBlockStack.empty())
@@ -2693,8 +2624,6 @@ void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
getColumnNumber(CurLoc)));
}
-/// EmitLexicalBlockStart - Constructs the debug code for entering a declarative
-/// region - beginning of a DW_TAG_lexical_block.
void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder,
SourceLocation Loc) {
// Set our current location.
@@ -2711,8 +2640,6 @@ void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder,
CreateLexicalBlock(Loc);
}
-/// EmitLexicalBlockEnd - Constructs the debug code for exiting a declarative
-/// region - end of a DW_TAG_lexical_block.
void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder,
SourceLocation Loc) {
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
@@ -2726,7 +2653,6 @@ void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder,
LexicalBlockStack.pop_back();
}
-/// EmitFunctionEnd - Constructs the debug code for exiting a function.
void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
unsigned RCount = FnBeginRegionCount.back();
@@ -2741,8 +2667,6 @@ void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder) {
FnBeginRegionCount.pop_back();
}
-// EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.
-// See BuildByRefType.
llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
uint64_t *XOffset) {
@@ -2816,7 +2740,6 @@ llvm::DIType *CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
nullptr, Elements);
}
-/// EmitDeclare - Emit local variable declaration debug info.
void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::dwarf::Tag Tag,
llvm::Value *Storage, unsigned ArgNo,
CGBuilderTy &Builder) {
@@ -2944,12 +2867,6 @@ void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, 0, Builder);
}
-/// Look up the completed type for a self pointer in the TypeCache and
-/// create a copy of it with the ObjectPointer and Artificial flags
-/// set. If the type is not cached, a new one is created. This should
-/// never happen though, since creating a type for the implicit self
-/// argument implies that we already parsed the interface definition
-/// and the ivar declarations in the implementation.
llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy,
llvm::DIType *Ty) {
llvm::DIType *CachedTy = getTypeOrNull(QualTy);
@@ -3027,8 +2944,6 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
Builder.GetInsertBlock());
}
-/// EmitDeclareOfArgVariable - Emit call to llvm.dbg.declare for an argument
-/// variable declaration.
void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
unsigned ArgNo,
CGBuilderTy &Builder) {
@@ -3192,8 +3107,6 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
Builder.GetInsertBlock());
}
-/// If D is an out-of-class definition of a static data member of a class, find
-/// its corresponding in-class declaration.
llvm::DIDerivedType *
CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) {
if (!D->isStaticDataMember())
@@ -3213,9 +3126,6 @@ CGDebugInfo::getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D) {
return CreateRecordStaticField(D, Ctxt, cast<RecordDecl>(DC));
}
-/// Recursively collect all of the member fields of a global anonymous decl and
-/// create static variables for them. The first time this is called it needs
-/// to be on a union and then from there we can have additional unnamed fields.
llvm::DIGlobalVariable *CGDebugInfo::CollectAnonRecordDecls(
const RecordDecl *RD, llvm::DIFile *Unit, unsigned LineNo,
StringRef LinkageName, llvm::GlobalVariable *Var, llvm::DIScope *DContext) {
@@ -3241,7 +3151,6 @@ llvm::DIGlobalVariable *CGDebugInfo::CollectAnonRecordDecls(
return GV;
}
-/// EmitGlobalVariable - Emit information about a global variable.
void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
const VarDecl *D) {
assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
@@ -3274,7 +3183,6 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
DeclCache[D->getCanonicalDecl()].reset(static_cast<llvm::Metadata *>(GV));
}
-/// EmitGlobalVariable - Emit global variable's debug info.
void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD,
llvm::Constant *Init) {
assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
@@ -3380,8 +3288,6 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
return R;
}
-/// getOrCreateNamesSpace - Return namespace descriptor for the given
-/// namespace decl.
llvm::DINamespace *
CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {
NSDecl = NSDecl->getCanonicalDecl();
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.h b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.h
index 10d3b0d..4c77a8d 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDebugInfo.h
@@ -26,26 +26,26 @@
#include "llvm/Support/Allocator.h"
namespace llvm {
- class MDNode;
+class MDNode;
}
namespace clang {
- class CXXMethodDecl;
- class VarDecl;
- class ObjCInterfaceDecl;
- class ObjCIvarDecl;
- class ClassTemplateSpecializationDecl;
- class GlobalDecl;
- class UsingDecl;
+class CXXMethodDecl;
+class VarDecl;
+class ObjCInterfaceDecl;
+class ObjCIvarDecl;
+class ClassTemplateSpecializationDecl;
+class GlobalDecl;
+class UsingDecl;
namespace CodeGen {
- class CodeGenModule;
- class CodeGenFunction;
- class CGBlockInfo;
+class CodeGenModule;
+class CodeGenFunction;
+class CGBlockInfo;
-/// \brief This class gathers all debug information during compilation
-/// and is responsible for emitting to llvm globals or pass directly to
-/// the backend.
+/// This class gathers all debug information during compilation and is
+/// responsible for emitting to llvm globals or pass directly to the
+/// backend.
class CGDebugInfo {
friend class ApplyDebugLocation;
friend class SaveAndRestoreLocation;
@@ -65,9 +65,8 @@ class CGDebugInfo {
llvm::DIType *OCLImage2dArrayDITy = nullptr;
llvm::DIType *OCLImage3dDITy = nullptr;
llvm::DIType *OCLEventDITy = nullptr;
- llvm::DIType *BlockLiteralGeneric = nullptr;
- /// \brief Cache of previously constructed Types.
+ /// Cache of previously constructed Types.
llvm::DenseMap<const void *, llvm::TrackingMDRef> TypeCache;
struct ObjCInterfaceCacheEntry {
@@ -79,41 +78,40 @@ class CGDebugInfo {
: Type(Type), Decl(Decl), Unit(Unit) {}
};
- /// \brief Cache of previously constructed interfaces
- /// which may change.
+ /// Cache of previously constructed interfaces which may change.
llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
- /// \brief Cache of references to AST files such as PCHs or modules.
+ /// Cache of references to AST files such as PCHs or modules.
llvm::DenseMap<uint64_t, llvm::DIModule *> ModuleRefCache;
- /// \brief list of interfaces we want to keep even if orphaned.
+ /// List of interfaces we want to keep even if orphaned.
std::vector<void *> RetainedTypes;
- /// \brief Cache of forward declared types to RAUW at the end of
+ /// Cache of forward declared types to RAUW at the end of
/// compilation.
std::vector<std::pair<const TagType *, llvm::TrackingMDRef>> ReplaceMap;
- /// \brief Cache of replaceable forward declarartions (functions and
+ /// Cache of replaceable forward declarartions (functions and
/// variables) to RAUW at the end of compilation.
std::vector<std::pair<const DeclaratorDecl *, llvm::TrackingMDRef>>
FwdDeclReplaceMap;
- // LexicalBlockStack - Keep track of our current nested lexical block.
+ /// Keep track of our current nested lexical block.
std::vector<llvm::TypedTrackingMDRef<llvm::DIScope>> LexicalBlockStack;
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> RegionMap;
- // FnBeginRegionCount - Keep track of LexicalBlockStack counter at the
- // beginning of a function. This is used to pop unbalanced regions at
- // the end of a function.
+ /// Keep track of LexicalBlockStack counter at the beginning of a
+ /// function. This is used to pop unbalanced regions at the end of a
+ /// function.
std::vector<unsigned> FnBeginRegionCount;
- /// \brief This is a storage for names that are
- /// constructed on demand. For example, C++ destructors, C++ operators etc..
+ /// This is a storage for names that are constructed on demand. For
+ /// example, C++ destructors, C++ operators etc..
llvm::BumpPtrAllocator DebugInfoNames;
StringRef CWDName;
llvm::DenseMap<const char *, llvm::TrackingMDRef> DIFileCache;
llvm::DenseMap<const FunctionDecl *, llvm::TrackingMDRef> SPCache;
- /// \brief Cache declarations relevant to DW_TAG_imported_declarations (C++
+ /// Cache declarations relevant to DW_TAG_imported_declarations (C++
/// using declarations) that aren't covered by other more specific caches.
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NameSpaceCache;
@@ -122,6 +120,9 @@ class CGDebugInfo {
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> StaticDataMemberCache;
/// Helper functions for getOrCreateType.
+ /// @{
+ /// Currently the checksum of an interface includes the number of
+ /// ivars and property accessors.
unsigned Checksum(const ObjCInterfaceDecl *InterfaceDecl);
llvm::DIType *CreateType(const BuiltinType *Ty);
llvm::DIType *CreateType(const ComplexType *Ty);
@@ -133,14 +134,17 @@ class CGDebugInfo {
llvm::DIType *CreateType(const PointerType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const BlockPointerType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const FunctionType *Ty, llvm::DIFile *F);
+ /// Get structure or union type.
llvm::DIType *CreateType(const RecordType *Tyg);
llvm::DIType *CreateTypeDefinition(const RecordType *Ty);
llvm::DICompositeType *CreateLimitedType(const RecordType *Ty);
void CollectContainingType(const CXXRecordDecl *RD,
llvm::DICompositeType *CT);
+ /// Get Objective-C interface type.
llvm::DIType *CreateType(const ObjCInterfaceType *Ty, llvm::DIFile *F);
llvm::DIType *CreateTypeDefinition(const ObjCInterfaceType *Ty,
llvm::DIFile *F);
+ /// Get Objective-C object type.
llvm::DIType *CreateType(const ObjCObjectType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const VectorType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const ArrayType *Ty, llvm::DIFile *F);
@@ -148,10 +152,25 @@ class CGDebugInfo {
llvm::DIType *CreateType(const RValueReferenceType *Ty, llvm::DIFile *Unit);
llvm::DIType *CreateType(const MemberPointerType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const AtomicType *Ty, llvm::DIFile *F);
+ /// Get enumeration type.
llvm::DIType *CreateEnumType(const EnumType *Ty);
llvm::DIType *CreateTypeDefinition(const EnumType *Ty);
+ /// Look up the completed type for a self pointer in the TypeCache and
+ /// create a copy of it with the ObjectPointer and Artificial flags
+ /// set. If the type is not cached, a new one is created. This should
+ /// never happen though, since creating a type for the implicit self
+ /// argument implies that we already parsed the interface definition
+ /// and the ivar declarations in the implementation.
llvm::DIType *CreateSelfType(const QualType &QualTy, llvm::DIType *Ty);
+ /// @}
+
+ /// Get the type from the cache or return null type if it doesn't
+ /// exist.
llvm::DIType *getTypeOrNull(const QualType);
+ /// Return the debug type for a C++ method.
+ /// \arg CXXMethodDecl is of FunctionType. This function type is
+ /// not updated to include implicit \c this pointer. Use this routine
+ /// to get a method type which includes \c this pointer.
llvm::DISubroutineType *getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DIFile *F);
llvm::DISubroutineType *
@@ -159,7 +178,9 @@ class CGDebugInfo {
llvm::DIFile *Unit);
llvm::DISubroutineType *
getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
+ /// \return debug info descriptor for vtable.
llvm::DIType *getOrCreateVTablePtrType(llvm::DIFile *F);
+ /// \return namespace descriptor for the given namespace decl.
llvm::DINamespace *getOrCreateNameSpace(const NamespaceDecl *N);
llvm::DIType *getOrCreateTypeDeclaration(QualType PointeeTy, llvm::DIFile *F);
llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
@@ -168,23 +189,37 @@ class CGDebugInfo {
llvm::Value *getCachedInterfaceTypeOrNull(const QualType Ty);
llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);
+ /// A helper function to create a subprogram for a single member
+ /// function GlobalDecl.
llvm::DISubprogram *CreateCXXMemberFunction(const CXXMethodDecl *Method,
llvm::DIFile *F,
llvm::DIType *RecordTy);
+ /// A helper function to collect debug info for C++ member
+ /// functions. This is used while creating debug info entry for a
+ /// Record.
void CollectCXXMemberFunctions(const CXXRecordDecl *Decl, llvm::DIFile *F,
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DIType *T);
+ /// A helper function to collect debug info for C++ base
+ /// classes. This is used while creating debug info entry for a
+ /// Record.
void CollectCXXBases(const CXXRecordDecl *Decl, llvm::DIFile *F,
SmallVectorImpl<llvm::Metadata *> &EltTys,
llvm::DIType *RecordTy);
+ /// A helper function to collect template parameters.
llvm::DINodeArray CollectTemplateParams(const TemplateParameterList *TPList,
ArrayRef<TemplateArgument> TAList,
llvm::DIFile *Unit);
+ /// A helper function to collect debug info for function template
+ /// parameters.
llvm::DINodeArray CollectFunctionTemplateParams(const FunctionDecl *FD,
llvm::DIFile *Unit);
+
+ /// A helper function to collect debug info for template
+ /// parameters.
llvm::DINodeArray
CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,
llvm::DIFile *F);
@@ -195,7 +230,8 @@ class CGDebugInfo {
llvm::DIFile *tunit, llvm::DIScope *scope,
const RecordDecl *RD = nullptr);
- // Helpers for collecting fields of a record.
+ /// Helpers for collecting fields of a record.
+ /// @{
void CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DIType *RecordTy);
@@ -210,11 +246,13 @@ class CGDebugInfo {
SmallVectorImpl<llvm::Metadata *> &E,
llvm::DICompositeType *RecordTy);
+ /// If the C++ class has vtable info then insert appropriate debug
+ /// info entry in EltTys vector.
void CollectVTableInfo(const CXXRecordDecl *Decl, llvm::DIFile *F,
SmallVectorImpl<llvm::Metadata *> &EltTys);
+ /// @}
- // CreateLexicalBlock - Create a new lexical block node and push it on
- // the stack.
+ /// Create a new lexical block node and push it on the stack.
void CreateLexicalBlock(SourceLocation Loc);
public:
@@ -223,86 +261,84 @@ public:
void finalize();
- /// \brief Update the current source location. If \arg loc is
- /// invalid it is ignored.
+ /// Update the current source location. If \arg loc is invalid it is
+ /// ignored.
void setLocation(SourceLocation Loc);
- /// \brief Emit metadata to indicate a change in line/column
- /// information in the source file.
+ /// Emit metadata to indicate a change in line/column information in
+ /// the source file. If the location is invalid, the previous
+ /// location will be reused.
void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
- /// \brief Emit a call to llvm.dbg.function.start to indicate
+ /// Emit a call to llvm.dbg.function.start to indicate
/// start of a new function.
/// \param Loc The location of the function header.
/// \param ScopeLoc The location of the function body.
- void EmitFunctionStart(GlobalDecl GD,
- SourceLocation Loc, SourceLocation ScopeLoc,
- QualType FnType, llvm::Function *Fn,
- CGBuilderTy &Builder);
+ void EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
+ SourceLocation ScopeLoc, QualType FnType,
+ llvm::Function *Fn, CGBuilderTy &Builder);
- /// \brief Constructs the debug code for exiting a function.
+ /// Constructs the debug code for exiting a function.
void EmitFunctionEnd(CGBuilderTy &Builder);
- /// \brief Emit metadata to indicate the beginning of a
- /// new lexical block and push the block onto the stack.
+ /// Emit metadata to indicate the beginning of a new lexical block
+ /// and push the block onto the stack.
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc);
- /// \brief Emit metadata to indicate the end of a new lexical
- /// block and pop the current block.
+ /// Emit metadata to indicate the end of a new lexical block and pop
+ /// the current block.
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc);
- /// \brief Emit call to llvm.dbg.declare for an automatic
- /// variable declaration.
+ /// Emit call to \c llvm.dbg.declare for an automatic variable
+ /// declaration.
void EmitDeclareOfAutoVariable(const VarDecl *Decl, llvm::Value *AI,
CGBuilderTy &Builder);
- /// \brief Emit call to llvm.dbg.declare for an
- /// imported variable declaration in a block.
+ /// Emit call to \c llvm.dbg.declare for an imported variable
+ /// declaration in a block.
void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable,
llvm::Value *storage,
CGBuilderTy &Builder,
const CGBlockInfo &blockInfo,
llvm::Instruction *InsertPoint = 0);
- /// \brief Emit call to llvm.dbg.declare for an argument
- /// variable declaration.
+ /// Emit call to \c llvm.dbg.declare for an argument variable
+ /// declaration.
void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
unsigned ArgNo, CGBuilderTy &Builder);
- /// \brief Emit call to
- /// llvm.dbg.declare for the block-literal argument to a block
- /// invocation function.
+ /// Emit call to \c llvm.dbg.declare for the block-literal argument
+ /// to a block invocation function.
void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
llvm::Value *Arg, unsigned ArgNo,
llvm::Value *LocalAddr,
CGBuilderTy &Builder);
- /// \brief Emit information about a global variable.
+ /// Emit information about a global variable.
void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
- /// \brief Emit global variable's debug info.
+ /// Emit global variable's debug info.
void EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init);
- /// \brief Emit C++ using directive.
+ /// Emit C++ using directive.
void EmitUsingDirective(const UsingDirectiveDecl &UD);
- /// \brief Emit the type explicitly casted to.
+ /// Emit the type explicitly casted to.
void EmitExplicitCastType(QualType Ty);
- /// \brief Emit C++ using declaration.
+ /// Emit C++ using declaration.
void EmitUsingDecl(const UsingDecl &UD);
- /// \brief Emit an @import declaration.
+ /// Emit an @import declaration.
void EmitImportDecl(const ImportDecl &ID);
- /// \brief Emit C++ namespace alias.
+ /// Emit C++ namespace alias.
llvm::DIImportedEntity *EmitNamespaceAlias(const NamespaceAliasDecl &NA);
- /// \brief Emit record type's standalone debug info.
+ /// Emit record type's standalone debug info.
llvm::DIType *getOrCreateRecordType(QualType Ty, SourceLocation L);
- /// \brief Emit an objective c interface type standalone
- /// debug info.
+ /// Emit an Objective-C interface type standalone debug info.
llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);
void completeType(const EnumDecl *ED);
@@ -313,120 +349,124 @@ public:
void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
private:
- /// \brief Emit call to llvm.dbg.declare for a variable declaration.
+ /// Emit call to llvm.dbg.declare for a variable declaration.
/// Tag accepts custom types DW_TAG_arg_variable and DW_TAG_auto_variable,
/// otherwise would be of type llvm::dwarf::Tag.
void EmitDeclare(const VarDecl *decl, llvm::dwarf::Tag Tag, llvm::Value *AI,
unsigned ArgNo, CGBuilderTy &Builder);
- // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.
- // See BuildByRefType.
+ /// Build up structure info for the byref. See \a BuildByRefType.
llvm::DIType *EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
uint64_t *OffSet);
- /// \brief Get context info for the decl.
+ /// Get context info for the decl.
llvm::DIScope *getContextDescriptor(const Decl *Decl);
llvm::DIScope *getCurrentContextDescriptor(const Decl *Decl);
- /// \brief Create a forward decl for a RecordType in a given context.
+ /// Create a forward decl for a RecordType in a given context.
llvm::DICompositeType *getOrCreateRecordFwdDecl(const RecordType *,
llvm::DIScope *);
- /// \brief Return current directory name.
+ /// Return current directory name.
StringRef getCurrentDirname();
- /// \brief Create new compile unit.
+ /// Create new compile unit.
void CreateCompileUnit();
- /// \brief Get the file debug info descriptor for the input
- /// location.
+ /// Get the file debug info descriptor for the input location.
llvm::DIFile *getOrCreateFile(SourceLocation Loc);
- /// \brief Get the file info for main compile unit.
+ /// Get the file info for main compile unit.
llvm::DIFile *getOrCreateMainFile();
- /// \brief Get the type from the cache or create a new type if
- /// necessary.
+ /// Get the type from the cache or create a new type if necessary.
llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg);
- /// \brief Get a reference to a clang module.
+ /// Get a reference to a clang module.
llvm::DIModule *
getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod);
- /// \brief Get the type from the cache or create a new
- /// partial type if necessary.
+ /// Get the type from the cache or create a new partial type if
+ /// necessary.
llvm::DIType *getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile *F);
- /// \brief Create type metadata for a source language type.
+ /// Create type metadata for a source language type.
llvm::DIType *CreateTypeNode(QualType Ty, llvm::DIFile *Fg);
- /// \brief return the underlying ObjCInterfaceDecl
- /// if Ty is an ObjCInterface or a pointer to one.
- ObjCInterfaceDecl* getObjCInterfaceDecl(QualType Ty);
+ /// Return the underlying ObjCInterfaceDecl if \arg Ty is an
+ /// ObjCInterface or a pointer to one.
+ ObjCInterfaceDecl *getObjCInterfaceDecl(QualType Ty);
- /// \brief Create new member and increase Offset by FType's size.
+ /// Create new member and increase Offset by FType's size.
llvm::DIType *CreateMemberType(llvm::DIFile *Unit, QualType FType,
StringRef Name, uint64_t *Offset);
- /// \brief Retrieve the DIDescriptor, if any, for the canonical form of this
+ /// Retrieve the DIDescriptor, if any, for the canonical form of this
/// declaration.
llvm::DINode *getDeclarationOrDefinition(const Decl *D);
- /// \brief Return debug info descriptor to describe method
+ /// \return debug info descriptor to describe method
/// declaration for the given method definition.
llvm::DISubprogram *getFunctionDeclaration(const Decl *D);
- /// Return debug info descriptor to describe in-class static data member
- /// declaration for the given out-of-class definition.
+ /// \return debug info descriptor to describe in-class static data
+ /// member declaration for the given out-of-class definition. If D
+ /// is an out-of-class definition of a static data member of a
+ /// class, find its corresponding in-class declaration.
llvm::DIDerivedType *
getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);
- /// \brief Create a subprogram describing the forward
- /// decalration represented in the given FunctionDecl.
+ /// Create a subprogram describing the forward declaration
+ /// represented in the given FunctionDecl.
llvm::DISubprogram *getFunctionForwardDeclaration(const FunctionDecl *FD);
- /// \brief Create a global variable describing the forward decalration
+ /// Create a global variable describing the forward decalration
/// represented in the given VarDecl.
llvm::DIGlobalVariable *
getGlobalVariableForwardDeclaration(const VarDecl *VD);
- /// Return a global variable that represents one of the collection of
- /// global variables created for an anonmyous union.
+ /// \brief Return a global variable that represents one of the
+ /// collection of global variables created for an anonmyous union.
+ ///
+ /// Recursively collect all of the member fields of a global
+ /// anonymous decl and create static variables for them. The first
+ /// time this is called it needs to be on a union and then from
+ /// there we can have additional unnamed fields.
llvm::DIGlobalVariable *
CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile *Unit,
unsigned LineNo, StringRef LinkageName,
llvm::GlobalVariable *Var, llvm::DIScope *DContext);
- /// \brief Get function name for the given FunctionDecl. If the
- /// name is constructed on demand (e.g. C++ destructor) then the name
- /// is stored on the side.
+ /// Get function name for the given FunctionDecl. If the name is
+ /// constructed on demand (e.g., C++ destructor) then the name is
+ /// stored on the side.
StringRef getFunctionName(const FunctionDecl *FD);
- /// \brief Returns the unmangled name of an Objective-C method.
+ /// Returns the unmangled name of an Objective-C method.
/// This is the display name for the debugging info.
StringRef getObjCMethodName(const ObjCMethodDecl *FD);
- /// \brief Return selector name. This is used for debugging
+ /// Return selector name. This is used for debugging
/// info.
StringRef getSelectorName(Selector S);
- /// \brief Get class name including template argument list.
+ /// Get class name including template argument list.
StringRef getClassName(const RecordDecl *RD);
- /// \brief Get vtable name for the given Class.
+ /// Get the vtable name for the given class.
StringRef getVTableName(const CXXRecordDecl *Decl);
- /// \brief Get line number for the location. If location is invalid
+ /// Get line number for the location. If location is invalid
/// then use current location.
unsigned getLineNumber(SourceLocation Loc);
- /// \brief Get column number for the location. If location is
+ /// Get column number for the location. If location is
/// invalid then use current location.
/// \param Force Assume DebugColumnInfo option is true.
- unsigned getColumnNumber(SourceLocation Loc, bool Force=false);
+ unsigned getColumnNumber(SourceLocation Loc, bool Force = false);
- /// \brief Collect various properties of a FunctionDecl.
+ /// Collect various properties of a FunctionDecl.
/// \param GD A GlobalDecl whose getDecl() must return a FunctionDecl.
void collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
StringRef &Name, StringRef &LinkageName,
@@ -434,12 +474,12 @@ private:
llvm::DINodeArray &TParamsArray,
unsigned &Flags);
- /// \brief Collect various properties of a VarDecl.
+ /// Collect various properties of a VarDecl.
void collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit,
unsigned &LineNo, QualType &T, StringRef &Name,
StringRef &LinkageName, llvm::DIScope *&VDContext);
- /// \brief Allocate a copy of \p A using the DebugInfoNames allocator
+ /// Allocate a copy of \p A using the DebugInfoNames allocator
/// and return a reference to it. If multiple arguments are given the strings
/// are concatenated.
StringRef internString(StringRef A, StringRef B = StringRef()) {
@@ -450,7 +490,7 @@ private:
}
};
-/// \brief A scoped helper to set the current debug location to the specified
+/// A scoped helper to set the current debug location to the specified
/// location or preferred location of the specified Expr.
class ApplyDebugLocation {
private:
@@ -460,55 +500,56 @@ private:
llvm::DebugLoc OriginalLocation;
CodeGenFunction &CGF;
-public:
- /// \brief Set the location to the (valid) TemporaryLocation.
+public:
+ /// Set the location to the (valid) TemporaryLocation.
ApplyDebugLocation(CodeGenFunction &CGF, SourceLocation TemporaryLocation);
ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E);
ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc);
~ApplyDebugLocation();
- /// \brief Apply TemporaryLocation if it is valid. Otherwise switch to an
- /// artificial debug location that has a valid scope, but no line information.
+ /// \brief Apply TemporaryLocation if it is valid. Otherwise switch
+ /// to an artificial debug location that has a valid scope, but no
+ /// line information.
///
- /// Artificial locations are useful when emitting compiler-generated helper
- /// functions that have no source location associated with them. The DWARF
- /// specification allows the compiler to use the special line number 0 to
- /// indicate code that can not be attributed to any source location. Note that
- /// passing an empty SourceLocation to CGDebugInfo::setLocation() will result
- /// in the last valid location being reused.
+ /// Artificial locations are useful when emitting compiler-generated
+ /// helper functions that have no source location associated with
+ /// them. The DWARF specification allows the compiler to use the
+ /// special line number 0 to indicate code that can not be
+ /// attributed to any source location. Note that passing an empty
+ /// SourceLocation to CGDebugInfo::setLocation() will result in the
+ /// last valid location being reused.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF) {
return ApplyDebugLocation(CGF, false, SourceLocation());
}
- /// \brief Apply TemporaryLocation if it is valid. Otherwise switch to an
- /// artificial debug location that has a valid scope, but no line information.
- static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF,
- SourceLocation TemporaryLocation) {
+ /// \brief Apply TemporaryLocation if it is valid. Otherwise switch
+ /// to an artificial debug location that has a valid scope, but no
+ /// line information.
+ static ApplyDebugLocation
+ CreateDefaultArtificial(CodeGenFunction &CGF,
+ SourceLocation TemporaryLocation) {
return ApplyDebugLocation(CGF, false, TemporaryLocation);
}
- /// \brief Set the IRBuilder to not attach debug locations. Note that passing
- /// an empty SourceLocation to CGDebugInfo::setLocation() will result in the
- /// last valid location being reused. Note that all instructions that do not
- /// have a location at the beginning of a function are counted towards to
- /// funciton prologue.
+ /// Set the IRBuilder to not attach debug locations. Note that
+ /// passing an empty SourceLocation to \a CGDebugInfo::setLocation()
+ /// will result in the last valid location being reused. Note that
+ /// all instructions that do not have a location at the beginning of
+ /// a function are counted towards to funciton prologue.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF) {
return ApplyDebugLocation(CGF, true, SourceLocation());
}
/// \brief Apply TemporaryLocation if it is valid. Otherwise set the IRBuilder
/// to not attach debug locations.
- static ApplyDebugLocation CreateDefaultEmpty(CodeGenFunction &CGF,
- SourceLocation TemporaryLocation) {
+ static ApplyDebugLocation
+ CreateDefaultEmpty(CodeGenFunction &CGF, SourceLocation TemporaryLocation) {
return ApplyDebugLocation(CGF, true, TemporaryLocation);
}
-
};
-
} // namespace CodeGen
} // namespace clang
-
#endif
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
index 839c2e4..96aa8c68 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp
@@ -79,6 +79,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::Captured:
case Decl::ClassScopeFunctionSpecialization:
case Decl::UsingShadow:
+ case Decl::ObjCTypeParam:
llvm_unreachable("Declaration should not be in declstmts!");
case Decl::Function: // void X();
case Decl::Record: // struct/union/class X;
@@ -987,7 +988,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
llvm::Value *Stack = CreateTempAlloca(Int8PtrTy, "saved_stack");
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
- llvm::Value *V = Builder.CreateCall(F, {});
+ llvm::Value *V = Builder.CreateCall(F);
Builder.CreateStore(V, Stack);
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGException.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGException.cpp
index 4c85017..7b8368e 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGException.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGException.cpp
@@ -20,6 +20,7 @@
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/TargetBuiltins.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -1279,14 +1280,6 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
}
void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
- // FIXME: Implement SEH on other architectures.
- const llvm::Triple &T = CGM.getTarget().getTriple();
- if (T.getArch() != llvm::Triple::x86_64 ||
- !T.isKnownWindowsMSVCEnvironment()) {
- ErrorUnsupported(&S, "__try statement");
- return;
- }
-
EnterSEHTryStmt(S);
{
JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
@@ -1311,24 +1304,27 @@ struct PerformSEHFinally : EHScopeStack::Cleanup {
void Emit(CodeGenFunction &CGF, Flags F) override {
ASTContext &Context = CGF.getContext();
- QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
- FunctionProtoType::ExtProtoInfo EPI;
- const auto *FTP = cast<FunctionType>(
- Context.getFunctionType(Context.VoidTy, ArgTys, EPI));
+ CodeGenModule &CGM = CGF.CGM;
CallArgList Args;
+
+ // Compute the two argument values.
+ QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
+ llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
+ llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
llvm::Value *IsForEH =
llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
Args.add(RValue::get(IsForEH), ArgTys[0]);
-
- CodeGenModule &CGM = CGF.CGM;
- llvm::Value *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0);
- llvm::Value *FrameAddr = CGM.getIntrinsic(llvm::Intrinsic::frameaddress);
- llvm::Value *FP = CGF.Builder.CreateCall(FrameAddr, Zero);
Args.add(RValue::get(FP), ArgTys[1]);
+ // Arrange a two-arg function info and type.
+ FunctionProtoType::ExtProtoInfo EPI;
+ const auto *FPT = cast<FunctionProtoType>(
+ Context.getFunctionType(Context.VoidTy, ArgTys, EPI));
const CGFunctionInfo &FnInfo =
- CGM.getTypes().arrangeFreeFunctionCall(Args, FTP, /*chainCall=*/false);
+ CGM.getTypes().arrangeFreeFunctionCall(Args, FPT,
+ /*chainCall=*/false);
+
CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
}
};
@@ -1340,9 +1336,15 @@ struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
CodeGenFunction &ParentCGF;
const VarDecl *ParentThis;
SmallVector<const VarDecl *, 4> Captures;
+ llvm::Value *SEHCodeSlot = nullptr;
CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
: ParentCGF(ParentCGF), ParentThis(ParentThis) {}
+ // Return true if we need to do any capturing work.
+ bool foundCaptures() {
+ return !Captures.empty() || SEHCodeSlot;
+ }
+
void Visit(const Stmt *S) {
// See if this is a capture, then recurse.
ConstStmtVisitor<CaptureFinder>::Visit(S);
@@ -1366,27 +1368,106 @@ struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
void VisitCXXThisExpr(const CXXThisExpr *E) {
Captures.push_back(ParentThis);
}
+
+ void VisitCallExpr(const CallExpr *E) {
+ // We only need to add parent frame allocations for these builtins in x86.
+ if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
+ return;
+
+ unsigned ID = E->getBuiltinCallee();
+ switch (ID) {
+ case Builtin::BI__exception_code:
+ case Builtin::BI_exception_code:
+ // This is the simple case where we are the outermost finally. All we
+ // have to do here is make sure we escape this and recover it in the
+ // outlined handler.
+ if (!SEHCodeSlot)
+ SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
+ break;
+ }
+ }
};
}
+llvm::Value *CodeGenFunction::recoverAddrOfEscapedLocal(
+ CodeGenFunction &ParentCGF, llvm::Value *ParentVar, llvm::Value *ParentFP) {
+ llvm::CallInst *RecoverCall = nullptr;
+ CGBuilderTy Builder(AllocaInsertPt);
+ if (auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar)) {
+ // Mark the variable escaped if nobody else referenced it and compute the
+ // localescape index.
+ auto InsertPair = ParentCGF.EscapedLocals.insert(
+ std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
+ int FrameEscapeIdx = InsertPair.first->second;
+ // call i8* @llvm.localrecover(i8* bitcast(@parentFn), i8* %fp, i32 N)
+ llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+ &CGM.getModule(), llvm::Intrinsic::localrecover);
+ llvm::Constant *ParentI8Fn =
+ llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+ RecoverCall = Builder.CreateCall(
+ FrameRecoverFn, {ParentI8Fn, ParentFP,
+ llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
+
+ } else {
+ // If the parent didn't have an alloca, we're doing some nested outlining.
+ // Just clone the existing localrecover call, but tweak the FP argument to
+ // use our FP value. All other arguments are constants.
+ auto *ParentRecover =
+ cast<llvm::IntrinsicInst>(ParentVar->stripPointerCasts());
+ assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
+ "expected alloca or localrecover in parent LocalDeclMap");
+ RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
+ RecoverCall->setArgOperand(1, ParentFP);
+ RecoverCall->insertBefore(AllocaInsertPt);
+ }
+
+ // Bitcast the variable, rename it, and insert it in the local decl map.
+ llvm::Value *ChildVar =
+ Builder.CreateBitCast(RecoverCall, ParentVar->getType());
+ ChildVar->setName(ParentVar->getName());
+ return ChildVar;
+}
+
void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
const Stmt *OutlinedStmt,
- llvm::Value *ParentFP) {
+ bool IsFilter) {
// Find all captures in the Stmt.
CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
Finder.Visit(OutlinedStmt);
- // Typically there are no captures and we can exit early.
- if (Finder.Captures.empty())
+ // We can exit early on x86_64 when there are no captures. We just have to
+ // save the exception code in filters so that __exception_code() works.
+ if (!Finder.foundCaptures() &&
+ CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
+ if (IsFilter)
+ EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
return;
+ }
- // Prepare the first two arguments to llvm.framerecover.
- llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
- &CGM.getModule(), llvm::Intrinsic::framerecover);
- llvm::Constant *ParentI8Fn =
- llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+ llvm::Value *EntryEBP = nullptr;
+ llvm::Value *ParentFP;
+ if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
+ // 32-bit SEH filters need to be careful about FP recovery. The end of the
+ // EH registration is passed in as the EBP physical register. We can
+ // recover that with llvm.frameaddress(1), and adjust that to recover the
+ // parent's true frame pointer.
+ CGBuilderTy Builder(AllocaInsertPt);
+ EntryEBP = Builder.CreateCall(
+ CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
+ llvm::Function *RecoverFPIntrin =
+ CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp);
+ llvm::Constant *ParentI8Fn =
+ llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+ ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryEBP});
+ } else {
+ // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
+ // second parameter.
+ auto AI = CurFn->arg_begin();
+ ++AI;
+ ParentFP = AI;
+ }
- // Create llvm.framerecover calls for all captures.
+ // Create llvm.localrecover calls for all captures.
for (const VarDecl *VD : Finder.Captures) {
if (isa<ImplicitParamDecl>(VD)) {
CGM.ErrorUnsupported(VD, "'this' captured by SEH");
@@ -1407,49 +1488,63 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
continue;
llvm::Value *ParentVar = I->second;
- llvm::CallInst *RecoverCall = nullptr;
- CGBuilderTy Builder(AllocaInsertPt);
- if (auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar)) {
- // Mark the variable escaped if nobody else referenced it and compute the
- // frameescape index.
- auto InsertPair =
- ParentCGF.EscapedLocals.insert(std::make_pair(ParentAlloca, -1));
- if (InsertPair.second)
- InsertPair.first->second = ParentCGF.EscapedLocals.size() - 1;
- int FrameEscapeIdx = InsertPair.first->second;
- // call i8* @llvm.framerecover(i8* bitcast(@parentFn), i8* %fp, i32 N)
- RecoverCall = Builder.CreateCall(
- FrameRecoverFn, {ParentI8Fn, ParentFP,
- llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
-
- } else {
- // If the parent didn't have an alloca, we're doing some nested outlining.
- // Just clone the existing framerecover call, but tweak the FP argument to
- // use our FP value. All other arguments are constants.
- auto *ParentRecover =
- cast<llvm::IntrinsicInst>(ParentVar->stripPointerCasts());
- assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::framerecover &&
- "expected alloca or framerecover in parent LocalDeclMap");
- RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
- RecoverCall->setArgOperand(1, ParentFP);
- RecoverCall->insertBefore(AllocaInsertPt);
- }
+ LocalDeclMap[VD] =
+ recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP);
+ }
- // Bitcast the variable, rename it, and insert it in the local decl map.
- llvm::Value *ChildVar =
- Builder.CreateBitCast(RecoverCall, ParentVar->getType());
- ChildVar->setName(ParentVar->getName());
- LocalDeclMap[VD] = ChildVar;
+ if (Finder.SEHCodeSlot) {
+ SEHCodeSlotStack.push_back(
+ recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
}
+
+ if (IsFilter)
+ EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryEBP);
}
/// Arrange a function prototype that can be called by Windows exception
/// handling personalities. On Win64, the prototype looks like:
/// RetTy func(void *EHPtrs, void *ParentFP);
void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
- StringRef Name, QualType RetTy,
- FunctionArgList &Args,
+ bool IsFilter,
const Stmt *OutlinedStmt) {
+ SourceLocation StartLoc = OutlinedStmt->getLocStart();
+
+ // Get the mangled function name.
+ SmallString<128> Name;
+ {
+ llvm::raw_svector_ostream OS(Name);
+ const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
+ const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
+ assert(Parent && "FIXME: handle unnamed decls (lambdas, blocks) with SEH");
+ MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
+ if (IsFilter)
+ Mangler.mangleSEHFilterExpression(Parent, OS);
+ else
+ Mangler.mangleSEHFinallyBlock(Parent, OS);
+ }
+
+ FunctionArgList Args;
+ if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
+ // All SEH finally functions take two parameters. Win64 filters take two
+ // parameters. Win32 filters take no parameters.
+ if (IsFilter) {
+ Args.push_back(ImplicitParamDecl::Create(
+ getContext(), nullptr, StartLoc,
+ &getContext().Idents.get("exception_pointers"),
+ getContext().VoidPtrTy));
+ } else {
+ Args.push_back(ImplicitParamDecl::Create(
+ getContext(), nullptr, StartLoc,
+ &getContext().Idents.get("abnormal_termination"),
+ getContext().UnsignedCharTy));
+ }
+ Args.push_back(ImplicitParamDecl::Create(
+ getContext(), nullptr, StartLoc,
+ &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
+ }
+
+ QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
+
llvm::Function *ParentFn = ParentCGF.CurFn;
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
RetTy, Args, FunctionType::ExtInfo(), /*isVariadic=*/false);
@@ -1474,10 +1569,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
CGM.SetLLVMFunctionAttributes(nullptr, FnInfo, CurFn);
-
- auto AI = Fn->arg_begin();
- ++AI;
- EmitCapturedLocals(ParentCGF, OutlinedStmt, &*AI);
+ EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
}
/// Create a stub filter function that will ultimately hold the code of the
@@ -1487,37 +1579,7 @@ llvm::Function *
CodeGenFunction::GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
const SEHExceptStmt &Except) {
const Expr *FilterExpr = Except.getFilterExpr();
- SourceLocation StartLoc = FilterExpr->getLocStart();
-
- SEHPointersDecl = ImplicitParamDecl::Create(
- getContext(), nullptr, StartLoc,
- &getContext().Idents.get("exception_pointers"), getContext().VoidPtrTy);
- FunctionArgList Args;
- Args.push_back(SEHPointersDecl);
- Args.push_back(ImplicitParamDecl::Create(
- getContext(), nullptr, StartLoc,
- &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
-
- // Get the mangled function name.
- SmallString<128> Name;
- {
- llvm::raw_svector_ostream OS(Name);
- const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
- const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
- assert(Parent && "FIXME: handle unnamed decls (lambdas, blocks) with SEH");
- CGM.getCXXABI().getMangleContext().mangleSEHFilterExpression(Parent, OS);
- }
-
- startOutlinedSEHHelper(ParentCGF, Name, getContext().LongTy, Args,
- FilterExpr);
-
- // Mark finally block calls as nounwind and noinline to make LLVM's job a
- // little easier.
- // FIXME: Remove these restrictions in the future.
- CurFn->addFnAttr(llvm::Attribute::NoUnwind);
- CurFn->addFnAttr(llvm::Attribute::NoInline);
-
- EmitSEHExceptionCodeSave();
+ startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
// Emit the original filter expression, convert to i32, and return.
llvm::Value *R = EmitScalarExpr(FilterExpr);
@@ -1534,29 +1596,13 @@ llvm::Function *
CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
const SEHFinallyStmt &Finally) {
const Stmt *FinallyBlock = Finally.getBlock();
- SourceLocation StartLoc = FinallyBlock->getLocStart();
+ startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
- FunctionArgList Args;
- Args.push_back(ImplicitParamDecl::Create(
- getContext(), nullptr, StartLoc,
- &getContext().Idents.get("abnormal_termination"),
- getContext().UnsignedCharTy));
- Args.push_back(ImplicitParamDecl::Create(
- getContext(), nullptr, StartLoc,
- &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
-
- // Get the mangled function name.
- SmallString<128> Name;
- {
- llvm::raw_svector_ostream OS(Name);
- const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
- const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
- assert(Parent && "FIXME: handle unnamed decls (lambdas, blocks) with SEH");
- CGM.getCXXABI().getMangleContext().mangleSEHFinallyBlock(Parent, OS);
- }
-
- startOutlinedSEHHelper(ParentCGF, Name, getContext().VoidTy, Args,
- FinallyBlock);
+ // Mark finally block calls as nounwind and noinline to make LLVM's job a
+ // little easier.
+ // FIXME: Remove these restrictions in the future.
+ CurFn->addFnAttr(llvm::Attribute::NoUnwind);
+ CurFn->addFnAttr(llvm::Attribute::NoInline);
// Emit the original filter expression, convert to i32, and return.
EmitStmt(FinallyBlock);
@@ -1566,44 +1612,58 @@ CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
return CurFn;
}
-void CodeGenFunction::EmitSEHExceptionCodeSave() {
+void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
+ llvm::Value *ParentFP,
+ llvm::Value *EntryEBP) {
+ // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
+ // __exception_info intrinsic.
+ if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
+ // On Win64, the info is passed as the first parameter to the filter.
+ auto AI = CurFn->arg_begin();
+ SEHInfo = AI;
+ SEHCodeSlotStack.push_back(
+ CreateMemTemp(getContext().IntTy, "__exception_code"));
+ } else {
+ // On Win32, the EBP on entry to the filter points to the end of an
+ // exception registration object. It contains 6 32-bit fields, and the info
+ // pointer is stored in the second field. So, GEP 20 bytes backwards and
+ // load the pointer.
+ SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryEBP, -20);
+ SEHInfo = Builder.CreateBitCast(SEHInfo, Int8PtrTy->getPointerTo());
+ SEHInfo = Builder.CreateLoad(Int8PtrTy, SEHInfo);
+ SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(
+ ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
+ }
+
// Save the exception code in the exception slot to unify exception access in
// the filter function and the landing pad.
// struct EXCEPTION_POINTERS {
// EXCEPTION_RECORD *ExceptionRecord;
// CONTEXT *ContextRecord;
// };
- // void *exn.slot =
- // (void *)(uintptr_t)exception_pointers->ExceptionRecord->ExceptionCode;
- llvm::Value *Ptrs = Builder.CreateLoad(GetAddrOfLocalVar(SEHPointersDecl));
+ // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy, nullptr);
- Ptrs = Builder.CreateBitCast(Ptrs, PtrsTy->getPointerTo());
+ llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo());
llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
Rec = Builder.CreateLoad(Rec);
llvm::Value *Code = Builder.CreateLoad(Rec);
- Code = Builder.CreateZExt(Code, CGM.IntPtrTy);
- // FIXME: Change landing pads to produce {i32, i32} and make the exception
- // slot an i32.
- Code = Builder.CreateIntToPtr(Code, CGM.VoidPtrTy);
- Builder.CreateStore(Code, getExceptionSlot());
+ assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
+ Builder.CreateStore(Code, SEHCodeSlotStack.back());
}
llvm::Value *CodeGenFunction::EmitSEHExceptionInfo() {
// Sema should diagnose calling this builtin outside of a filter context, but
// don't crash if we screw up.
- if (!SEHPointersDecl)
+ if (!SEHInfo)
return llvm::UndefValue::get(Int8PtrTy);
- return Builder.CreateLoad(GetAddrOfLocalVar(SEHPointersDecl));
+ assert(SEHInfo->getType() == Int8PtrTy);
+ return SEHInfo;
}
llvm::Value *CodeGenFunction::EmitSEHExceptionCode() {
- // If we're in a landing pad or filter function, the exception slot contains
- // the code.
- assert(ExceptionSlot);
- llvm::Value *Code =
- Builder.CreatePtrToInt(getExceptionFromSlot(), CGM.IntPtrTy);
- return Builder.CreateTrunc(Code, CGM.Int32Ty);
+ assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
+ return Builder.CreateLoad(Int32Ty, SEHCodeSlotStack.back());
}
llvm::Value *CodeGenFunction::EmitSEHAbnormalTermination() {
@@ -1616,9 +1676,11 @@ llvm::Value *CodeGenFunction::EmitSEHAbnormalTermination() {
void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
- // Push a cleanup for __finally blocks.
+ // Outline the finally block.
llvm::Function *FinallyFunc =
HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
+
+ // Push a cleanup for __finally blocks.
EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
return;
}
@@ -1627,12 +1689,16 @@ void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
const SEHExceptStmt *Except = S.getExceptHandler();
assert(Except);
EHCatchScope *CatchScope = EHStack.pushCatch(1);
+ SEHCodeSlotStack.push_back(
+ CreateMemTemp(getContext().IntTy, "__exception_code"));
- // If the filter is known to evaluate to 1, then we can use the clause "catch
- // i8* null".
+ // If the filter is known to evaluate to 1, then we can use the clause
+ // "catch i8* null". We can't do this on x86 because the filter has to save
+ // the exception code.
llvm::Constant *C =
CGM.EmitConstantExpr(Except->getFilterExpr(), getContext().IntTy, this);
- if (C && C->isOneValue()) {
+ if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
+ C->isOneValue()) {
CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
return;
}
@@ -1664,6 +1730,7 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
if (!CatchScope.hasEHBranches()) {
CatchScope.clearHandlerBlocks();
EHStack.popCatch();
+ SEHCodeSlotStack.pop_back();
return;
}
@@ -1683,9 +1750,20 @@ void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
EmitBlockAfterUses(ExceptBB);
+ // On Win64, the exception pointer is the exception code. Copy it to the slot.
+ if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
+ llvm::Value *Code =
+ Builder.CreatePtrToInt(getExceptionFromSlot(), IntPtrTy);
+ Code = Builder.CreateTrunc(Code, Int32Ty);
+ Builder.CreateStore(Code, SEHCodeSlotStack.back());
+ }
+
// Emit the __except body.
EmitStmt(Except->getBlock());
+ // End the lifetime of the exception code.
+ SEHCodeSlotStack.pop_back();
+
if (HaveInsertPoint())
Builder.CreateBr(ContBB);
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
index 175763c..9c3dfe5 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExpr.cpp
@@ -1356,14 +1356,15 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {
const CGBitFieldInfo &Info = LV.getBitFieldInfo();
+ CharUnits Align = LV.getAlignment().alignmentAtOffset(Info.StorageOffset);
// Get the output type.
llvm::Type *ResLTy = ConvertType(LV.getType());
llvm::Value *Ptr = LV.getBitFieldAddr();
- llvm::Value *Val = Builder.CreateLoad(Ptr, LV.isVolatileQualified(),
- "bf.load");
- cast<llvm::LoadInst>(Val)->setAlignment(Info.StorageAlignment);
+ llvm::Value *Val = Builder.CreateAlignedLoad(Ptr, Align.getQuantity(),
+ LV.isVolatileQualified(),
+ "bf.load");
if (Info.IsSigned) {
assert(static_cast<unsigned>(Info.Offset + Info.Size) <= Info.StorageSize);
@@ -1559,6 +1560,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
llvm::Value **Result) {
const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
+ CharUnits Align = Dst.getAlignment().alignmentAtOffset(Info.StorageOffset);
llvm::Type *ResLTy = ConvertTypeForMem(Dst.getType());
llvm::Value *Ptr = Dst.getBitFieldAddr();
@@ -1575,9 +1577,9 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// and mask together with source before storing.
if (Info.StorageSize != Info.Size) {
assert(Info.StorageSize > Info.Size && "Invalid bitfield size.");
- llvm::Value *Val = Builder.CreateLoad(Ptr, Dst.isVolatileQualified(),
- "bf.load");
- cast<llvm::LoadInst>(Val)->setAlignment(Info.StorageAlignment);
+ llvm::Value *Val = Builder.CreateAlignedLoad(Ptr, Align.getQuantity(),
+ Dst.isVolatileQualified(),
+ "bf.load");
// Mask the source value as needed.
if (!hasBooleanRepresentation(Dst.getType()))
@@ -1603,9 +1605,8 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
}
// Write the new value back out.
- llvm::StoreInst *Store = Builder.CreateStore(SrcVal, Ptr,
- Dst.isVolatileQualified());
- Store->setAlignment(Info.StorageAlignment);
+ Builder.CreateAlignedStore(SrcVal, Ptr, Align.getQuantity(),
+ Dst.isVolatileQualified());
// Return the new value of the bit-field, if requested.
if (Result) {
@@ -2415,8 +2416,7 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked) {
}
llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
- llvm::CallInst *TrapCall =
- Builder.CreateCall(CGM.getIntrinsic(IntrID), {});
+ llvm::CallInst *TrapCall = Builder.CreateCall(CGM.getIntrinsic(IntrID));
if (!CGM.getCodeGenOpts().TrapFuncName.empty())
TrapCall->addAttribute(llvm::AttributeSet::FunctionIndex,
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp
index 747326e..eb76ad1 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp
@@ -31,10 +31,9 @@ using namespace CodeGen;
typedef llvm::PointerIntPair<llvm::Value*,1,bool> TryEmitResult;
static TryEmitResult
tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e);
-static RValue AdjustRelatedResultType(CodeGenFunction &CGF,
- QualType ET,
- const ObjCMethodDecl *Method,
- RValue Result);
+static RValue AdjustObjCObjectType(CodeGenFunction &CGF,
+ QualType ET,
+ RValue Result);
/// Given the address of a variable of pointer type, find the correct
/// null to store into it.
@@ -248,23 +247,22 @@ llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
return CGM.getObjCRuntime().GenerateProtocolRef(*this, E->getProtocol());
}
-/// \brief Adjust the type of the result of an Objective-C message send
-/// expression when the method has a related result type.
-static RValue AdjustRelatedResultType(CodeGenFunction &CGF,
- QualType ExpT,
- const ObjCMethodDecl *Method,
- RValue Result) {
- if (!Method)
+/// \brief Adjust the type of an Objective-C object that doesn't match up due
+/// to type erasure at various points, e.g., related result types or the use
+/// of parameterized classes.
+static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ExpT,
+ RValue Result) {
+ if (!ExpT->isObjCRetainableType())
return Result;
- if (!Method->hasRelatedResultType() ||
- CGF.getContext().hasSameType(ExpT, Method->getReturnType()) ||
- !Result.isScalar())
+ // If the converted types are the same, we're done.
+ llvm::Type *ExpLLVMTy = CGF.ConvertType(ExpT);
+ if (ExpLLVMTy == Result.getScalarVal()->getType())
return Result;
-
- // We have applied a related result type. Cast the rvalue appropriately.
+
+ // We have applied a substitution. Cast the rvalue appropriately.
return RValue::get(CGF.Builder.CreateBitCast(Result.getScalarVal(),
- CGF.ConvertType(ExpT)));
+ ExpLLVMTy));
}
/// Decide whether to extend the lifetime of the receiver of a
@@ -449,7 +447,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
Builder.CreateStore(newSelf, selfAddr);
}
- return AdjustRelatedResultType(*this, E->getType(), method, result);
+ return AdjustObjCObjectType(*this, E->getType(), result);
}
namespace {
@@ -2011,7 +2009,7 @@ CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
// Call the marker asm if we made one, which we do only at -O0.
if (marker)
- Builder.CreateCall(marker, {});
+ Builder.CreateCall(marker);
return emitARCValueOperation(*this, value,
CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp
index 5290a87..2ac6bb2 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -134,7 +134,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
CGBitFieldInfo *Info = new (CGF.CGM.getContext()) CGBitFieldInfo(
CGBitFieldInfo::MakeInfo(CGF.CGM.getTypes(), Ivar, BitOffset, BitFieldSize,
CGF.CGM.getContext().toBits(StorageSize),
- Alignment.getQuantity()));
+ CharUnits::fromQuantity(0)));
V = CGF.Builder.CreateBitCast(V,
llvm::Type::getIntNPtrTy(CGF.getLLVMContext(),
@@ -160,7 +160,7 @@ namespace {
void Emit(CodeGenFunction &CGF, Flags flags) override {
if (!MightThrow) {
- CGF.Builder.CreateCall(Fn, {})->setDoesNotThrow();
+ CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
return;
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 534d148..8148839 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -537,7 +537,7 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
break;
}
case OMPRTL__kmpc_barrier: {
- // Build void __kmpc_cancel_barrier(ident_t *loc, kmp_int32 global_tid);
+ // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
llvm::FunctionType *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
@@ -829,6 +829,15 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
break;
}
+ case OMPRTL__kmpc_cancel: {
+ // Build kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
+ // kmp_int32 cncl_kind)
+ llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
+ llvm::FunctionType *FnTy =
+ llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
+ RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancel");
+ break;
+ }
}
return RTLFn;
}
@@ -923,6 +932,8 @@ llvm::Constant *CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize,
llvm::Constant *
CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
+ assert(!CGM.getLangOpts().OpenMPUseTLS ||
+ !CGM.getContext().getTargetInfo().isTLSSupported());
// Lookup the entry, lazily creating it if necessary.
return getOrCreateInternalVariable(CGM.Int8PtrPtrTy,
Twine(CGM.getMangledName(VD)) + ".cache.");
@@ -932,6 +943,10 @@ llvm::Value *CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
const VarDecl *VD,
llvm::Value *VDAddr,
SourceLocation Loc) {
+ if (CGM.getLangOpts().OpenMPUseTLS &&
+ CGM.getContext().getTargetInfo().isTLSSupported())
+ return VDAddr;
+
auto VarTy = VDAddr->getType()->getPointerElementType();
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
CGF.Builder.CreatePointerCast(VDAddr, CGM.Int8PtrTy),
@@ -961,6 +976,10 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit(
llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc,
bool PerformInit, CodeGenFunction *CGF) {
+ if (CGM.getLangOpts().OpenMPUseTLS &&
+ CGM.getContext().getTargetInfo().isTLSSupported())
+ return nullptr;
+
VD = VD->getDefinition(CGM.getContext());
if (VD && ThreadPrivateWithDefinition.count(VD) == 0) {
ThreadPrivateWithDefinition.insert(VD);
@@ -2723,18 +2742,18 @@ void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
}
-void CGOpenMPRuntime::emitCancellationPointCall(
- CodeGenFunction &CGF, SourceLocation Loc,
- OpenMPDirectiveKind CancelRegion) {
- // Build call kmp_int32 OMPRTL__kmpc_cancellationpoint(ident_t *loc, kmp_int32
- // global_tid, kmp_int32 cncl_kind);
- enum {
- CancelNoreq = 0,
- CancelParallel = 1,
- CancelLoop = 2,
- CancelSections = 3,
- CancelTaskgroup = 4
- } CancelKind = CancelNoreq;
+namespace {
+enum RTCancelKind {
+ CancelNoreq = 0,
+ CancelParallel = 1,
+ CancelLoop = 2,
+ CancelSections = 3,
+ CancelTaskgroup = 4
+};
+}
+
+static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
+ RTCancelKind CancelKind = CancelNoreq;
if (CancelRegion == OMPD_parallel)
CancelKind = CancelParallel;
else if (CancelRegion == OMPD_for)
@@ -2745,14 +2764,22 @@ void CGOpenMPRuntime::emitCancellationPointCall(
assert(CancelRegion == OMPD_taskgroup);
CancelKind = CancelTaskgroup;
}
+ return CancelKind;
+}
+
+void CGOpenMPRuntime::emitCancellationPointCall(
+ CodeGenFunction &CGF, SourceLocation Loc,
+ OpenMPDirectiveKind CancelRegion) {
+ // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
+ // global_tid, kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
auto CancelDest =
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
if (CancelDest.isValid()) {
- llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc),
- getThreadID(CGF, Loc),
- CGF.Builder.getInt32(CancelKind)};
+ llvm::Value *Args[] = {
+ emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
+ CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
// Ignore return result until untied tasks are supported.
auto *Result = CGF.EmitRuntimeCall(
createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
@@ -2774,3 +2801,36 @@ void CGOpenMPRuntime::emitCancellationPointCall(
}
}
+void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
+ OpenMPDirectiveKind CancelRegion) {
+ // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
+ // kmp_int32 cncl_kind);
+ if (auto *OMPRegionInfo =
+ dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
+ auto CancelDest =
+ CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
+ if (CancelDest.isValid()) {
+ llvm::Value *Args[] = {
+ emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
+ CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
+ // Ignore return result until untied tasks are supported.
+ auto *Result =
+ CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
+ // if (__kmpc_cancel()) {
+ // __kmpc_cancel_barrier();
+ // exit from construct;
+ // }
+ auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
+ auto *ContBB = CGF.createBasicBlock(".cancel.continue");
+ auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
+ CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
+ CGF.EmitBlock(ExitBB);
+ // __kmpc_cancel_barrier();
+ emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false);
+ // exit from construct;
+ CGF.EmitBranchThroughCleanup(CancelDest);
+ CGF.EmitBlock(ContBB, /*IsFinished=*/true);
+ }
+ }
+}
+
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
index 76bb3ae..44bc8a1 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -151,6 +151,9 @@ private:
// Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
// global_tid, kmp_int32 cncl_kind);
OMPRTL__kmpc_cancellationpoint,
+ // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
+ // kmp_int32 cncl_kind);
+ OMPRTL__kmpc_cancel,
};
/// \brief Values for bit flags used in the ident_t to describe the fields.
@@ -698,6 +701,12 @@ public:
virtual void emitCancellationPointCall(CodeGenFunction &CGF,
SourceLocation Loc,
OpenMPDirectiveKind CancelRegion);
+
+ /// \brief Emit code for 'cancel' construct.
+ /// \param CancelRegion Region kind for which the cancel must be emitted.
+ ///
+ virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
+ OpenMPDirectiveKind CancelRegion);
};
} // namespace CodeGen
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayout.h b/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayout.h
index c15f9fd..d4ad33e 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayout.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayout.h
@@ -78,16 +78,16 @@ struct CGBitFieldInfo {
/// bitfield.
unsigned StorageSize;
- /// The alignment which should be used when accessing the bitfield.
- unsigned StorageAlignment;
+ /// The offset of the bitfield storage from the start of the struct.
+ CharUnits StorageOffset;
CGBitFieldInfo()
- : Offset(), Size(), IsSigned(), StorageSize(), StorageAlignment() {}
+ : Offset(), Size(), IsSigned(), StorageSize(), StorageOffset() {}
CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned,
- unsigned StorageSize, unsigned StorageAlignment)
+ unsigned StorageSize, CharUnits StorageOffset)
: Offset(Offset), Size(Size), IsSigned(IsSigned),
- StorageSize(StorageSize), StorageAlignment(StorageAlignment) {}
+ StorageSize(StorageSize), StorageOffset(StorageOffset) {}
void print(raw_ostream &OS) const;
void dump() const;
@@ -99,7 +99,7 @@ struct CGBitFieldInfo {
const FieldDecl *FD,
uint64_t Offset, uint64_t Size,
uint64_t StorageSize,
- uint64_t StorageAlignment);
+ CharUnits StorageOffset);
};
/// CGRecordLayout - This class handles struct and union layout info while
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index c89d5cc..f91eceb 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -228,11 +228,7 @@ void CGRecordLowering::setBitFieldInfo(
Info.Offset = (unsigned)(getFieldBitOffset(FD) - Context.toBits(StartOffset));
Info.Size = FD->getBitWidthValue(Context);
Info.StorageSize = (unsigned)DataLayout.getTypeAllocSizeInBits(StorageType);
- // Here we calculate the actual storage alignment of the bits. E.g if we've
- // got an alignment >= 2 and the bitfield starts at offset 6 we've got an
- // alignment of 2.
- Info.StorageAlignment =
- Layout.getAlignment().alignmentAtOffset(StartOffset).getQuantity();
+ Info.StorageOffset = StartOffset;
if (Info.Size > Info.StorageSize)
Info.Size = Info.StorageSize;
// Reverse the bit offsets for big endian machines. Because we represent
@@ -651,7 +647,7 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
const FieldDecl *FD,
uint64_t Offset, uint64_t Size,
uint64_t StorageSize,
- uint64_t StorageAlignment) {
+ CharUnits StorageOffset) {
// This function is vestigial from CGRecordLayoutBuilder days but is still
// used in GCObjCRuntime.cpp. That usage has a "fixme" attached to it that
// when addressed will allow for the removal of this function.
@@ -683,7 +679,7 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
Offset = StorageSize - (Offset + Size);
}
- return CGBitFieldInfo(Offset, Size, IsSigned, StorageSize, StorageAlignment);
+ return CGBitFieldInfo(Offset, Size, IsSigned, StorageSize, StorageOffset);
}
CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
@@ -856,7 +852,7 @@ void CGBitFieldInfo::print(raw_ostream &OS) const {
<< " Size:" << Size
<< " IsSigned:" << IsSigned
<< " StorageSize:" << StorageSize
- << " StorageAlignment:" << StorageAlignment << ">";
+ << " StorageOffset:" << StorageOffset.getQuantity() << ">";
}
void CGBitFieldInfo::dump() const {
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
index a12f295..7a0b8a3 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmt.cpp
@@ -1852,6 +1852,14 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
std::vector<llvm::Value*> InOutArgs;
std::vector<llvm::Type*> InOutArgTypes;
+ // An inline asm can be marked readonly if it meets the following conditions:
+ // - it doesn't have any sideeffects
+ // - it doesn't clobber memory
+ // - it doesn't return a value by-reference
+ // It can be marked readnone if it doesn't have any input memory constraints
+ // in addition to meeting the conditions listed above.
+ bool ReadOnly = true, ReadNone = true;
+
for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
@@ -1915,6 +1923,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
Args.push_back(Dest.getAddress());
Constraints += "=*";
Constraints += OutputConstraint;
+ ReadOnly = ReadNone = false;
}
if (Info.isReadWrite()) {
@@ -1959,6 +1968,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
+ if (Info.allowsMemory())
+ ReadNone = false;
+
if (!Constraints.empty())
Constraints += ',';
@@ -2023,7 +2035,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
StringRef Clobber = S.getClobber(i);
- if (Clobber != "memory" && Clobber != "cc")
+ if (Clobber == "memory")
+ ReadOnly = ReadNone = false;
+ else if (Clobber != "cc")
Clobber = getTarget().getNormalizedGCCRegisterName(Clobber);
if (!Constraints.empty())
@@ -2063,6 +2077,16 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
Result->addAttribute(llvm::AttributeSet::FunctionIndex,
llvm::Attribute::NoUnwind);
+ // Attach readnone and readonly attributes.
+ if (!HasSideEffect) {
+ if (ReadNone)
+ Result->addAttribute(llvm::AttributeSet::FunctionIndex,
+ llvm::Attribute::ReadNone);
+ else if (ReadOnly)
+ Result->addAttribute(llvm::AttributeSet::FunctionIndex,
+ llvm::Attribute::ReadOnly);
+ }
+
// Slap the source location of the inline asm into a !srcloc metadata on the
// call.
if (const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) {
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
index b021c12..a1f093a 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -2108,7 +2108,8 @@ void CodeGenFunction::EmitOMPCancellationPointDirective(
}
void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
- llvm_unreachable("CodeGen for 'omp cancel' is not supported yet.");
+ CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(),
+ S.getCancelRegion());
}
CodeGenFunction::JumpDest
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
index 969629f..e36051c 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
@@ -364,7 +364,7 @@ void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD,
FinishFunction();
}
-void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
+void CodeGenFunction::generateThunk(llvm::Function *Fn,
const CGFunctionInfo &FnInfo,
GlobalDecl GD, const ThunkInfo &Thunk) {
StartThunk(Fn, GD, FnInfo);
@@ -376,13 +376,6 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
// Make the call and return the result.
EmitCallAndReturnForThunk(Callee, &Thunk);
-
- // Set the right linkage.
- CGM.setFunctionLinkage(GD, Fn);
-
- // Set the right visibility.
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
- setThunkVisibility(CGM, MD, Thunk, Fn);
}
void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
@@ -455,11 +448,17 @@ void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);
} else {
// Normal thunk body generation.
- CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
+ CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, Thunk);
}
+ CGM.setFunctionLinkage(GD, ThunkFn);
CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
!Thunk.Return.isEmpty());
+
+ // Set the right visibility.
+ const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+ setThunkVisibility(CGM, MD, Thunk, ThunkFn);
+
if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
}
@@ -841,6 +840,11 @@ void CodeGenModule::EmitDeferredVTables() {
DeferredVTables.clear();
}
+bool CodeGenModule::IsCFIBlacklistedRecord(const CXXRecordDecl *RD) {
+ // FIXME: Make this user configurable.
+ return RD->isInStdNamespace();
+}
+
void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
const VTableLayout &VTLayout) {
if (!LangOpts.Sanitize.has(SanitizerKind::CFIVCall) &&
@@ -855,8 +859,7 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
std::vector<llvm::MDTuple *> BitsetEntries;
// Create a bit set entry for each address point.
for (auto &&AP : VTLayout.getAddressPoints()) {
- // FIXME: Add blacklisting scheme.
- if (AP.first.getBase()->isInStdNamespace())
+ if (IsCFIBlacklistedRecord(AP.first.getBase()))
continue;
BitsetEntries.push_back(CreateVTableBitSetEntry(
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
index 1fca466..ec3c75c 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -45,12 +45,12 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
- AbnormalTerminationSlot(nullptr), SEHPointersDecl(nullptr),
- DebugInfo(CGM.getModuleDebugInfo()), DisableDebugInfo(false),
- DidCallStackSave(false), IndirectBranch(nullptr), PGO(cgm),
- SwitchInsn(nullptr), SwitchWeights(nullptr), CaseRangeBlock(nullptr),
- UnreachableBlock(nullptr), NumReturnExprs(0), NumSimpleReturnExprs(0),
- CXXABIThisDecl(nullptr), CXXABIThisValue(nullptr), CXXThisValue(nullptr),
+ DebugInfo(CGM.getModuleDebugInfo()),
+ DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
+ PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
+ CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
+ NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
+ CXXABIThisValue(nullptr), CXXThisValue(nullptr),
CXXDefaultInitExprThis(nullptr), CXXStructorImplicitParamDecl(nullptr),
CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
@@ -284,7 +284,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
Builder.ClearInsertionPoint();
}
- // If some of our locals escaped, insert a call to llvm.frameescape in the
+ // If some of our locals escaped, insert a call to llvm.localescape in the
// entry block.
if (!EscapedLocals.empty()) {
// Invert the map from local to index into a simple vector. There should be
@@ -294,7 +294,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
for (auto &Pair : EscapedLocals)
EscapeArgs[Pair.second] = Pair.first;
llvm::Function *FrameEscapeFn = llvm::Intrinsic::getDeclaration(
- &CGM.getModule(), llvm::Intrinsic::frameescape);
+ &CGM.getModule(), llvm::Intrinsic::localescape);
CGBuilderTy(AllocaInsertPt).CreateCall(FrameEscapeFn, EscapeArgs);
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
index a74c474..f2bc402 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h
@@ -324,11 +324,13 @@ public:
/// write the current selector value into this alloca.
llvm::AllocaInst *EHSelectorSlot;
- llvm::AllocaInst *AbnormalTerminationSlot;
+ /// A stack of exception code slots. Entering an __except block pushes a slot
+ /// on the stack and leaving pops one. The __exception_code() intrinsic loads
+ /// a value from the top of the stack.
+ SmallVector<llvm::Value *, 1> SEHCodeSlotStack;
- /// The implicit parameter to SEH filter functions of type
- /// 'EXCEPTION_POINTERS*'.
- ImplicitParamDecl *SEHPointersDecl;
+ /// Value returned by __exception_info intrinsic.
+ llvm::Value *SEHInfo = nullptr;
/// Emits a landing pad for the current EH stack.
llvm::BasicBlock *EmitLandingPad();
@@ -886,7 +888,7 @@ private:
DeclMapTy LocalDeclMap;
/// Track escaped local variables with auto storage. Used during SEH
- /// outlining to produce a call to llvm.frameescape.
+ /// outlining to produce a call to llvm.localescape.
llvm::DenseMap<llvm::AllocaInst *, int> EscapedLocals;
/// LabelMap - This keeps track of the LLVM basic block for each C label.
@@ -1292,8 +1294,8 @@ public:
void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr,
llvm::Value *Callee);
- /// GenerateThunk - Generate a thunk for the given method.
- void GenerateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
+ /// Generate a thunk for the given method.
+ void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
GlobalDecl GD, const ThunkInfo &Thunk);
llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn,
@@ -2048,8 +2050,7 @@ public:
void EnterSEHTryStmt(const SEHTryStmt &S);
void ExitSEHTryStmt(const SEHTryStmt &S);
- void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, StringRef Name,
- QualType RetTy, FunctionArgList &Args,
+ void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter,
const Stmt *OutlinedStmt);
llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
@@ -2058,16 +2059,27 @@ public:
llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
const SEHFinallyStmt &Finally);
- void EmitSEHExceptionCodeSave();
+ void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
+ llvm::Value *ParentFP,
+ llvm::Value *EntryEBP);
llvm::Value *EmitSEHExceptionCode();
llvm::Value *EmitSEHExceptionInfo();
llvm::Value *EmitSEHAbnormalTermination();
/// Scan the outlined statement for captures from the parent function. For
/// each capture, mark the capture as escaped and emit a call to
- /// llvm.framerecover. Insert the framerecover result into the LocalDeclMap.
+ /// llvm.localrecover. Insert the localrecover result into the LocalDeclMap.
void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt,
- llvm::Value *ParentFP);
+ bool IsFilter);
+
+ /// Recovers the address of a local in a parent function. ParentVar is the
+ /// address of the variable used in the immediate parent function. It can
+ /// either be an alloca or a call to llvm.localrecover if there are nested
+ /// outlined functions. ParentFP is the frame pointer of the outermost parent
+ /// frame.
+ llvm::Value *recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
+ llvm::Value *ParentVar,
+ llvm::Value *ParentFP);
void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
ArrayRef<const Attr *> Attrs = None);
@@ -2931,6 +2943,26 @@ private:
SourceLocation Loc);
public:
+#ifndef NDEBUG
+ // Determine whether the given argument is an Objective-C method
+ // that may have type parameters in its signature.
+ static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method) {
+ const DeclContext *dc = method->getDeclContext();
+ if (const ObjCInterfaceDecl *classDecl= dyn_cast<ObjCInterfaceDecl>(dc)) {
+ return classDecl->getTypeParamListAsWritten();
+ }
+
+ if (const ObjCCategoryDecl *catDecl = dyn_cast<ObjCCategoryDecl>(dc)) {
+ return catDecl->getTypeParamList();
+ }
+
+ return false;
+ }
+
+ template<typename T>
+ static bool isObjCMethodWithTypeParams(const T *) { return false; }
+#endif
+
/// EmitCallArgs - Emit call arguments for a function.
template <typename T>
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo,
@@ -2944,18 +2976,25 @@ public:
assert((ParamsToSkip == 0 || CallArgTypeInfo) &&
"Can't skip parameters if type info is not provided");
if (CallArgTypeInfo) {
+#ifndef NDEBUG
+ bool isGenericMethod = isObjCMethodWithTypeParams(CallArgTypeInfo);
+#endif
+
// First, use the argument types that the type info knows about
for (auto I = CallArgTypeInfo->param_type_begin() + ParamsToSkip,
E = CallArgTypeInfo->param_type_end();
I != E; ++I, ++Arg) {
assert(Arg != ArgEnd && "Running over edge of argument list!");
- assert(
- ((*I)->isVariablyModifiedType() ||
- getContext()
- .getCanonicalType((*I).getNonReferenceType())
- .getTypePtr() ==
- getContext().getCanonicalType(Arg->getType()).getTypePtr()) &&
- "type mismatch in call argument!");
+ assert((isGenericMethod ||
+ ((*I)->isVariablyModifiedType() ||
+ (*I).getNonReferenceType()->isObjCRetainableType() ||
+ getContext()
+ .getCanonicalType((*I).getNonReferenceType())
+ .getTypePtr() ==
+ getContext()
+ .getCanonicalType(Arg->getType())
+ .getTypePtr())) &&
+ "type mismatch in call argument!");
ArgTypes.push_back(*I);
}
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
index b905bd2..a179ad4 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1262,6 +1262,11 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
// Implicit template instantiations may change linkage if they are later
// explicitly instantiated, so they should not be emitted eagerly.
return false;
+ // If OpenMP is enabled and threadprivates must be generated like TLS, delay
+ // codegen for global variables, because they may be marked as threadprivate.
+ if (LangOpts.OpenMP && LangOpts.OpenMPUseTLS &&
+ getContext().getTargetInfo().isTLSSupported() && isa<VarDecl>(Global))
+ return false;
return true;
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h
index 9a295fe..dd167a2 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.h
@@ -1126,6 +1126,10 @@ public:
/// \param D Threadprivate declaration.
void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
+ /// Returns whether the given record is blacklisted from control flow
+ /// integrity checks.
+ bool IsCFIBlacklistedRecord(const CXXRecordDecl *RD);
+
/// Emit bit set entries for the given vtable using the given layout if
/// vptr CFI is enabled.
void EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp b/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp
index fa86e52..70af69b 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2095,7 +2095,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
CGBuilderTy Builder(Entry);
if (InitIsInitFunc) {
if (Init)
- Builder.CreateCall(Init, {});
+ Builder.CreateCall(Init);
} else {
// Don't know whether we have an init function. Call it if it exists.
llvm::Value *Have = Builder.CreateIsNotNull(Init);
@@ -2104,7 +2104,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
Builder.CreateCondBr(Have, InitBB, ExitBB);
Builder.SetInsertPoint(InitBB);
- Builder.CreateCall(Init, {});
+ Builder.CreateCall(Init);
Builder.CreateBr(ExitBB);
Builder.SetInsertPoint(ExitBB);
@@ -2133,7 +2133,7 @@ LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty);
llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
- Val = CGF.Builder.CreateCall(Wrapper, {});
+ Val = CGF.Builder.CreateCall(Wrapper);
LValue LV;
if (VD->getType()->isReferenceType())
@@ -3620,7 +3620,7 @@ static llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) {
catchCall->setCallingConv(CGM.getRuntimeCC());
// Call std::terminate().
- llvm::CallInst *termCall = builder.CreateCall(CGM.getTerminateFn(), {});
+ llvm::CallInst *termCall = builder.CreateCall(CGM.getTerminateFn());
termCall->setDoesNotThrow();
termCall->setDoesNotReturn();
termCall->setCallingConv(CGM.getRuntimeCC());
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d149df6..3433990 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1466,20 +1466,27 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
llvm::NamedMDNode *BitsetsMD =
CGM.getModule().getOrInsertNamedMetadata("llvm.bitsets");
- CharUnits PointerWidth = getContext().toCharUnitsFromBits(
- getContext().getTargetInfo().getPointerWidth(0));
- // FIXME: Add blacklisting scheme.
+ // The location of the first virtual function pointer in the virtual table,
+ // aka the "address point" on Itanium. This is at offset 0 if RTTI is
+ // disabled, or sizeof(void*) if RTTI is enabled.
+ CharUnits AddressPoint =
+ getContext().getLangOpts().RTTIData
+ ? getContext().toCharUnitsFromBits(
+ getContext().getTargetInfo().getPointerWidth(0))
+ : CharUnits::Zero();
if (Info->PathToBaseWithVPtr.empty()) {
- BitsetsMD->addOperand(
- CGM.CreateVTableBitSetEntry(VTable, PointerWidth, RD));
+ if (!CGM.IsCFIBlacklistedRecord(RD))
+ BitsetsMD->addOperand(
+ CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD));
return;
}
// Add a bitset entry for the least derived base belonging to this vftable.
- BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry(
- VTable, PointerWidth, Info->PathToBaseWithVPtr.back()));
+ if (!CGM.IsCFIBlacklistedRecord(Info->PathToBaseWithVPtr.back()))
+ BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry(
+ VTable, AddressPoint, Info->PathToBaseWithVPtr.back()));
// Add a bitset entry for each derived class that is laid out at the same
// offset as the least derived base.
@@ -1497,14 +1504,15 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
Offset = VBI->second.VBaseOffset;
if (!Offset.isZero())
return;
- BitsetsMD->addOperand(
- CGM.CreateVTableBitSetEntry(VTable, PointerWidth, DerivedRD));
+ if (!CGM.IsCFIBlacklistedRecord(DerivedRD))
+ BitsetsMD->addOperand(
+ CGM.CreateVTableBitSetEntry(VTable, AddressPoint, DerivedRD));
}
// Finally do the same for the most derived class.
- if (Info->FullOffsetInMDC.isZero())
+ if (Info->FullOffsetInMDC.isZero() && !CGM.IsCFIBlacklistedRecord(RD))
BitsetsMD->addOperand(
- CGM.CreateVTableBitSetEntry(VTable, PointerWidth, RD));
+ CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD));
}
void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
@@ -1707,7 +1715,7 @@ static const CXXRecordDecl *getClassAtVTableLocation(ASTContext &Ctx,
for (auto &&B : RD->bases()) {
const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
CharUnits BaseOffset = Layout.getBaseClassOffset(Base);
- if (BaseOffset <= Offset && BaseOffset > MaxBaseOffset) {
+ if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
MaxBase = Base;
MaxBaseOffset = BaseOffset;
}
@@ -1715,7 +1723,7 @@ static const CXXRecordDecl *getClassAtVTableLocation(ASTContext &Ctx,
for (auto &&B : RD->vbases()) {
const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
CharUnits BaseOffset = Layout.getVBaseClassOffset(Base);
- if (BaseOffset <= Offset && BaseOffset > MaxBaseOffset) {
+ if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
MaxBase = Base;
MaxBaseOffset = BaseOffset;
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/contrib/llvm/tools/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
new file mode 100644
index 0000000..8f04e06
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -0,0 +1,193 @@
+//===--- ObjectFilePCHContainerOperations.cpp -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
+#include "CGDebugInfo.h"
+#include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/CodeGen/BackendUtil.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Serialization/ASTWriter.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/TargetRegistry.h"
+#include <memory>
+using namespace clang;
+
+#define DEBUG_TYPE "pchcontainer"
+
+namespace {
+class PCHContainerGenerator : public ASTConsumer {
+ DiagnosticsEngine &Diags;
+ const std::string MainFileName;
+ ASTContext *Ctx;
+ const HeaderSearchOptions &HeaderSearchOpts;
+ const PreprocessorOptions &PreprocessorOpts;
+ CodeGenOptions CodeGenOpts;
+ const TargetOptions TargetOpts;
+ const LangOptions LangOpts;
+ std::unique_ptr<llvm::LLVMContext> VMContext;
+ std::unique_ptr<llvm::Module> M;
+ std::unique_ptr<CodeGen::CodeGenModule> Builder;
+ raw_pwrite_stream *OS;
+ std::shared_ptr<PCHBuffer> Buffer;
+
+public:
+ PCHContainerGenerator(DiagnosticsEngine &diags,
+ const HeaderSearchOptions &HSO,
+ const PreprocessorOptions &PPO, const TargetOptions &TO,
+ const LangOptions &LO, const std::string &MainFileName,
+ const std::string &OutputFileName,
+ raw_pwrite_stream *OS,
+ std::shared_ptr<PCHBuffer> Buffer)
+ : Diags(diags), HeaderSearchOpts(HSO), PreprocessorOpts(PPO),
+ TargetOpts(TO), LangOpts(LO), OS(OS), Buffer(Buffer) {
+ // The debug info output isn't affected by CodeModel and
+ // ThreadModel, but the backend expects them to be nonempty.
+ CodeGenOpts.CodeModel = "default";
+ CodeGenOpts.ThreadModel = "single";
+ CodeGenOpts.setDebugInfo(CodeGenOptions::FullDebugInfo);
+ CodeGenOpts.SplitDwarfFile = OutputFileName;
+ }
+
+ virtual ~PCHContainerGenerator() {}
+
+ void Initialize(ASTContext &Context) override {
+ Ctx = &Context;
+ VMContext.reset(new llvm::LLVMContext());
+ M.reset(new llvm::Module(MainFileName, *VMContext));
+ M->setDataLayout(Ctx->getTargetInfo().getTargetDescription());
+ Builder.reset(new CodeGen::CodeGenModule(*Ctx, HeaderSearchOpts,
+ PreprocessorOpts, CodeGenOpts, *M,
+ M->getDataLayout(), Diags));
+ }
+
+ /// Emit a container holding the serialized AST.
+ void HandleTranslationUnit(ASTContext &Ctx) override {
+ assert(M && VMContext && Builder);
+ // Delete these on function exit.
+ std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
+ std::unique_ptr<llvm::Module> M = std::move(this->M);
+ std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder);
+
+ if (Diags.hasErrorOccurred())
+ return;
+
+ M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple());
+ M->setDataLayout(Ctx.getTargetInfo().getTargetDescription());
+
+ // Finalize the Builder.
+ if (Builder)
+ Builder->Release();
+
+ // Ensure the target exists.
+ std::string Error;
+ auto Triple = Ctx.getTargetInfo().getTriple();
+ if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error))
+ llvm::report_fatal_error(Error);
+
+ // Emit the serialized Clang AST into its own section.
+ assert(Buffer->IsComplete && "serialization did not complete");
+ auto &SerializedAST = Buffer->Data;
+ auto Size = SerializedAST.size();
+ auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
+ auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
+ auto *Data = llvm::ConstantDataArray::getString(
+ *VMContext, StringRef(SerializedAST.data(), Size),
+ /*AddNull=*/false);
+ auto *ASTSym = new llvm::GlobalVariable(
+ *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
+ "__clang_ast");
+ // The on-disk hashtable needs to be aligned.
+ ASTSym->setAlignment(8);
+
+ // Mach-O also needs a segment name.
+ if (Triple.isOSBinFormatMachO())
+ ASTSym->setSection("__CLANG,__clangast");
+ // COFF has an eight character length limit.
+ else if (Triple.isOSBinFormatCOFF())
+ ASTSym->setSection("clangast");
+ else
+ ASTSym->setSection("__clangast");
+
+ DEBUG({
+ // Print the IR for the PCH container to the debug output.
+ llvm::SmallString<0> Buffer;
+ llvm::raw_svector_ostream OS(Buffer);
+ clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
+ Ctx.getTargetInfo().getTargetDescription(),
+ M.get(), BackendAction::Backend_EmitLL, &OS);
+ OS.flush();
+ llvm::dbgs() << Buffer;
+ });
+
+ // Use the LLVM backend to emit the pch container.
+ clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
+ Ctx.getTargetInfo().getTargetDescription(),
+ M.get(), BackendAction::Backend_EmitObj, OS);
+
+ // Make sure the pch container hits disk.
+ OS->flush();
+
+ // Free the memory for the temporary buffer.
+ llvm::SmallVector<char, 0> Empty;
+ SerializedAST = std::move(Empty);
+ }
+};
+
+} // namespace
+
+std::unique_ptr<ASTConsumer>
+ObjectFilePCHContainerOperations::CreatePCHContainerGenerator(
+ DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO,
+ const PreprocessorOptions &PPO, const TargetOptions &TO,
+ const LangOptions &LO, const std::string &MainFileName,
+ const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
+ std::shared_ptr<PCHBuffer> Buffer) const {
+ return llvm::make_unique<PCHContainerGenerator>(
+ Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer);
+}
+
+void ObjectFilePCHContainerOperations::ExtractPCH(
+ llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const {
+ if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) {
+ auto *Obj = OF.get().get();
+ bool IsCOFF = isa<llvm::object::COFFObjectFile>(Obj);
+ // Find the clang AST section in the container.
+ for (auto &Section : OF->get()->sections()) {
+ StringRef Name;
+ Section.getName(Name);
+ if ((!IsCOFF && Name == "__clangast") ||
+ ( IsCOFF && Name == "clangast")) {
+ StringRef Buf;
+ Section.getContents(Buf);
+ StreamFile.init((const unsigned char *)Buf.begin(),
+ (const unsigned char *)Buf.end());
+ return;
+ }
+ }
+ }
+
+ // As a fallback, treat the buffer as a raw AST.
+ StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
+ (const unsigned char *)Buffer.getBufferEnd());
+ return;
+}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
index e5ba200..6226d21 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp
@@ -2073,8 +2073,10 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
classify(I.getType(), Offset, FieldLo, FieldHi, isNamedArg);
Lo = merge(Lo, FieldLo);
Hi = merge(Hi, FieldHi);
- if (Lo == Memory || Hi == Memory)
- break;
+ if (Lo == Memory || Hi == Memory) {
+ postMerge(Size, Lo, Hi);
+ return;
+ }
}
}
@@ -2094,11 +2096,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,
//
if (Size > 128 && getContext().getTypeSize(i->getType()) != 256) {
Lo = Memory;
+ postMerge(Size, Lo, Hi);
return;
}
// Note, skip this test for bit-fields, see below.
if (!BitField && Offset % getContext().getTypeAlign(i->getType())) {
Lo = Memory;
+ postMerge(Size, Lo, Hi);
return;
}
@@ -7095,6 +7099,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
return *(TheTargetCodeGenInfo = new PNaClTargetCodeGenInfo(Types));
case llvm::Triple::mips:
case llvm::Triple::mipsel:
+ if (Triple.getOS() == llvm::Triple::NaCl)
+ return *(TheTargetCodeGenInfo = new PNaClTargetCodeGenInfo(Types));
return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, true));
case llvm::Triple::mips64:
OpenPOWER on IntegriCloud