[lldb] [clang] [clang-tools-extra] [c++20] P1907R1: Support for generalized non-type template arguments of scalar type. (PR #78041)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 26 07:47:11 PST 2024
================
@@ -8129,29 +8067,133 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
else
Kind = CharacterLiteralKind::Ascii;
- E = new (Context) CharacterLiteral(Arg.getAsIntegral().getZExtValue(),
- Kind, T, Loc);
+ E = new (S.Context) CharacterLiteral(Int.getZExtValue(), Kind, T, Loc);
} else if (T->isBooleanType()) {
- E = CXXBoolLiteralExpr::Create(Context, Arg.getAsIntegral().getBoolValue(),
- T, Loc);
- } else if (T->isNullPtrType()) {
- E = new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
+ E = CXXBoolLiteralExpr::Create(S.Context, Int.getBoolValue(), T, Loc);
} else {
- E = IntegerLiteral::Create(Context, Arg.getAsIntegral(), T, Loc);
+ E = IntegerLiteral::Create(S.Context, Int, T, Loc);
}
if (OrigT->isEnumeralType()) {
// FIXME: This is a hack. We need a better way to handle substituted
// non-type template parameters.
- E = CStyleCastExpr::Create(Context, OrigT, VK_PRValue, CK_IntegralCast, E,
- nullptr, CurFPFeatureOverrides(),
- Context.getTrivialTypeSourceInfo(OrigT, Loc),
+ E = CStyleCastExpr::Create(S.Context, OrigT, VK_PRValue, CK_IntegralCast, E,
+ nullptr, S.CurFPFeatureOverrides(),
+ S.Context.getTrivialTypeSourceInfo(OrigT, Loc),
Loc, Loc);
}
return E;
}
+static Expr *BuildExpressionFromNonTypeTemplateArgumentValue(
+ Sema &S, QualType T, const APValue &Val, SourceLocation Loc) {
+ auto MakeInitList = [&](ArrayRef<Expr *> Elts) -> Expr * {
+ auto *ILE = new (S.Context) InitListExpr(S.Context, Loc, Elts, Loc);
+ ILE->setType(T);
+ return ILE;
+ };
+
+ switch (Val.getKind()) {
+ case APValue::AddrLabelDiff:
+ // This cannot occur in a template argument at all.
+ case APValue::Array:
+ case APValue::Struct:
+ case APValue::Union:
+ // These can only occur within a template parameter object, which is
+ // represented as a TemplateArgument::Declaration.
+ llvm_unreachable("unexpected template argument value");
+
+ case APValue::Int:
+ return BuildExpressionFromIntegralTemplateArgumentValue(S, T, Val.getInt(),
+ Loc);
+
+ case APValue::Float:
+ return FloatingLiteral::Create(S.Context, Val.getFloat(), /*IsExact=*/true,
+ T, Loc);
+
+ case APValue::FixedPoint:
+ return FixedPointLiteral::CreateFromRawInt(
+ S.Context, Val.getFixedPoint().getValue(), T, Loc,
+ Val.getFixedPoint().getScale());
+
+ case APValue::ComplexInt: {
+ QualType ElemT = T->castAs<ComplexType>()->getElementType();
+ return MakeInitList({BuildExpressionFromIntegralTemplateArgumentValue(
+ S, ElemT, Val.getComplexIntReal(), Loc),
+ BuildExpressionFromIntegralTemplateArgumentValue(
+ S, ElemT, Val.getComplexIntImag(), Loc)});
+ }
+
+ case APValue::ComplexFloat: {
+ QualType ElemT = T->castAs<ComplexType>()->getElementType();
+ return MakeInitList(
+ {FloatingLiteral::Create(S.Context, Val.getComplexFloatReal(), true,
+ ElemT, Loc),
+ FloatingLiteral::Create(S.Context, Val.getComplexFloatImag(), true,
+ ElemT, Loc)});
+ }
+
+ case APValue::Vector: {
+ QualType ElemT = T->castAs<VectorType>()->getElementType();
+ llvm::SmallVector<Expr *, 8> Elts;
+ for (unsigned I = 0, N = Val.getVectorLength(); I != N; ++I)
+ Elts.push_back(BuildExpressionFromNonTypeTemplateArgumentValue(
+ S, ElemT, Val.getVectorElt(I), Loc));
+ return MakeInitList(Elts);
+ }
+
+ case APValue::None:
+ case APValue::Indeterminate:
+ llvm_unreachable("Unexpected APValue kind.");
+ case APValue::LValue:
+ case APValue::MemberPointer:
+ // There isn't necessarily a valid equivalent source-level syntax for
+ // these; in particular, a naive lowering might violate access control.
+ // So for now we lower to a ConstantExpr holding the value, wrapped around
+ // an OpaqueValueExpr.
+ // FIXME: We should have a better representation for this.
+ ExprValueKind VK = VK_PRValue;
+ if (T->isReferenceType()) {
+ T = T->getPointeeType();
+ VK = VK_LValue;
+ }
+ auto *OVE = new (S.Context) OpaqueValueExpr(Loc, T, VK);
----------------
cor3ntin wrote:
Here we create an OpaqueValueExpr without a source expression and the static analyser assume `cast<OpaqueValueExpr>(E)->getSourceExpr()` is not null in `ignoreTransparentExprs`
@steakhal
https://github.com/llvm/llvm-project/pull/78041
More information about the cfe-commits
mailing list