[c++20] P1327R1: Support for typeid applied to objects of polymorphic
class type in constant evaluation.
This reinstates r360977, reverted in r360987, now that its rerequisite
patch is reinstated and fixed.
llvm-svn: 361067
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index af33209..856efc8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1349,6 +1349,7 @@
AK_Decrement,
AK_MemberCall,
AK_DynamicCast,
+ AK_TypeId,
};
static bool isModification(AccessKinds AK) {
@@ -1356,6 +1357,7 @@
case AK_Read:
case AK_MemberCall:
case AK_DynamicCast:
+ case AK_TypeId:
return false;
case AK_Assign:
case AK_Increment:
@@ -6034,19 +6036,33 @@
}
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
+ TypeInfoLValue TypeInfo;
+
if (!E->isPotentiallyEvaluated()) {
- TypeInfoLValue TypeInfo;
if (E->isTypeOperand())
TypeInfo = TypeInfoLValue(E->getTypeOperand(Info.Ctx).getTypePtr());
else
TypeInfo = TypeInfoLValue(E->getExprOperand()->getType().getTypePtr());
- return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
+ } else {
+ if (!Info.Ctx.getLangOpts().CPlusPlus2a) {
+ Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
+ << E->getExprOperand()->getType()
+ << E->getExprOperand()->getSourceRange();
+ }
+
+ if (!Visit(E->getExprOperand()))
+ return false;
+
+ Optional<DynamicType> DynType =
+ ComputeDynamicType(Info, E, Result, AK_TypeId);
+ if (!DynType)
+ return false;
+
+ TypeInfo =
+ TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
}
- Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
- << E->getExprOperand()->getType()
- << E->getExprOperand()->getSourceRange();
- return false;
+ return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
}
bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {