summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExprConstant.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp72
1 files changed, 42 insertions, 30 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 46ed90a20264f..c6b2930faece1 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -318,12 +318,17 @@ bool ConstantAggregateBuilder::split(size_t Index, CharUnits Hint) {
CharUnits Offset = Offsets[Index];
if (auto *CA = dyn_cast<llvm::ConstantAggregate>(C)) {
+ // Expand the sequence into its contained elements.
+ // FIXME: This assumes vector elements are byte-sized.
replace(Elems, Index, Index + 1,
llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
[&](unsigned Op) { return CA->getOperand(Op); }));
- if (auto *Seq = dyn_cast<llvm::SequentialType>(CA->getType())) {
+ if (isa<llvm::ArrayType>(CA->getType()) ||
+ isa<llvm::VectorType>(CA->getType())) {
// Array or vector.
- CharUnits ElemSize = getSize(Seq->getElementType());
+ llvm::Type *ElemTy =
+ llvm::GetElementPtrInst::getTypeAtIndex(CA->getType(), (uint64_t)0);
+ CharUnits ElemSize = getSize(ElemTy);
replace(
Offsets, Index, Index + 1,
llvm::map_range(llvm::seq(0u, CA->getNumOperands()),
@@ -344,6 +349,8 @@ bool ConstantAggregateBuilder::split(size_t Index, CharUnits Hint) {
}
if (auto *CDS = dyn_cast<llvm::ConstantDataSequential>(C)) {
+ // Expand the sequence into its contained elements.
+ // FIXME: This assumes vector elements are byte-sized.
// FIXME: If possible, split into two ConstantDataSequentials at Hint.
CharUnits ElemSize = getSize(CDS->getElementType());
replace(Elems, Index, Index + 1,
@@ -359,6 +366,7 @@ bool ConstantAggregateBuilder::split(size_t Index, CharUnits Hint) {
}
if (isa<llvm::ConstantAggregateZero>(C)) {
+ // Split into two zeros at the hinted offset.
CharUnits ElemSize = getSize(C);
assert(Hint > Offset && Hint < Offset + ElemSize && "nothing to split");
replace(Elems, Index, Index + 1,
@@ -368,6 +376,7 @@ bool ConstantAggregateBuilder::split(size_t Index, CharUnits Hint) {
}
if (isa<llvm::UndefValue>(C)) {
+ // Drop undef; it doesn't contribute to the final layout.
replace(Elems, Index, Index + 1, {});
replace(Offsets, Index, Index + 1, {});
return true;
@@ -589,19 +598,21 @@ bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars,
bool ConstStructBuilder::AppendBitField(
const FieldDecl *Field, uint64_t FieldOffset, llvm::ConstantInt *CI,
bool AllowOverwrite) {
- uint64_t FieldSize = Field->getBitWidthValue(CGM.getContext());
+ const CGRecordLayout &RL =
+ CGM.getTypes().getCGRecordLayout(Field->getParent());
+ const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
llvm::APInt FieldValue = CI->getValue();
// Promote the size of FieldValue if necessary
// FIXME: This should never occur, but currently it can because initializer
// constants are cast to bool, and because clang is not enforcing bitfield
// width limits.
- if (FieldSize > FieldValue.getBitWidth())
- FieldValue = FieldValue.zext(FieldSize);
+ if (Info.Size > FieldValue.getBitWidth())
+ FieldValue = FieldValue.zext(Info.Size);
// Truncate the size of FieldValue to the bit field size.
- if (FieldSize < FieldValue.getBitWidth())
- FieldValue = FieldValue.trunc(FieldSize);
+ if (Info.Size < FieldValue.getBitWidth())
+ FieldValue = FieldValue.trunc(Info.Size);
return Builder.addBits(FieldValue,
CGM.getContext().toBits(StartOffset) + FieldOffset,
@@ -766,7 +777,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
// Add a vtable pointer, if we need one and it hasn't already been added.
- if (CD->isDynamicClass() && !IsPrimaryBase) {
+ if (Layout.hasOwnVFPtr()) {
llvm::Constant *VTableAddressPoint =
CGM.getCXXABI().getVTableAddressPointForConstExpr(
BaseSubobject(CD, Offset), VTableClass);
@@ -1000,6 +1011,8 @@ public:
}
llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) {
+ if (llvm::Constant *Result = Emitter.tryEmitConstantExpr(CE))
+ return Result;
return Visit(CE->getSubExpr(), T);
}
@@ -1167,9 +1180,7 @@ public:
}
llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E, QualType T) {
- if (!E->cleanupsHaveSideEffects())
- return Visit(E->getSubExpr(), T);
- return nullptr;
+ return Visit(E->getSubExpr(), T);
}
llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E,
@@ -1269,19 +1280,7 @@ public:
if (!E->getConstructor()->isTrivial())
return nullptr;
- // FIXME: We should not have to call getBaseElementType here.
- const auto *RT =
- CGM.getContext().getBaseElementType(Ty)->castAs<RecordType>();
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-
- // If the class doesn't have a trivial destructor, we can't emit it as a
- // constant expr.
- if (!RD->hasTrivialDestructor())
- return nullptr;
-
- // Only copy and default constructors can be trivial.
-
-
+ // Only default and copy/move constructors can be trivial.
if (E->getNumArgs()) {
assert(E->getNumArgs() == 1 && "trivial ctor with > 1 argument");
assert(E->getConstructor()->isCopyOrMoveConstructor() &&
@@ -1361,6 +1360,20 @@ ConstantEmitter::tryEmitAbstract(const APValue &value, QualType destType) {
return validateAndPopAbstract(C, state);
}
+llvm::Constant *ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *CE) {
+ if (!CE->hasAPValueResult())
+ return nullptr;
+ const Expr *Inner = CE->getSubExpr()->IgnoreImplicit();
+ QualType RetType;
+ if (auto *Call = dyn_cast<CallExpr>(Inner))
+ RetType = Call->getCallReturnType(CGF->getContext());
+ else if (auto *Ctor = dyn_cast<CXXConstructExpr>(Inner))
+ RetType = Ctor->getType();
+ llvm::Constant *Res =
+ emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), RetType);
+ return Res;
+}
+
llvm::Constant *
ConstantEmitter::emitAbstract(const Expr *E, QualType destType) {
auto state = pushAbstract();
@@ -1769,7 +1782,6 @@ private:
ConstantLValue VisitCallExpr(const CallExpr *E);
ConstantLValue VisitBlockExpr(const BlockExpr *E);
ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *E);
- ConstantLValue VisitCXXUuidofExpr(const CXXUuidofExpr *E);
ConstantLValue VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
@@ -1884,6 +1896,9 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
}
}
+ if (auto *GD = dyn_cast<MSGuidDecl>(D))
+ return CGM.GetAddrOfMSGuidDecl(GD);
+
return nullptr;
}
@@ -1904,6 +1919,8 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
ConstantLValue
ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *E) {
+ if (llvm::Constant *Result = Emitter.tryEmitConstantExpr(E))
+ return Result;
return Visit(E->getSubExpr());
}
@@ -1994,11 +2011,6 @@ ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
}
ConstantLValue
-ConstantLValueEmitter::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
- return CGM.GetAddrOfUuidDescriptor(E);
-}
-
-ConstantLValue
ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
assert(E->getStorageDuration() == SD_Static);