Changeset View
Standalone View
clang/lib/Sema/SemaExprCXX.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 5,885 Lines • ▼ Show 20 Lines | static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, | ||||
// as follows: | // as follows: | ||||
// -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be | // -- If E2 is an lvalue: E1 can be converted to match E2 if E1 can be | ||||
// implicitly converted to type "lvalue reference to T2", subject to the | // implicitly converted to type "lvalue reference to T2", subject to the | ||||
// constraint that in the conversion the reference must bind directly to | // constraint that in the conversion the reference must bind directly to | ||||
// an lvalue. | // an lvalue. | ||||
// -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be | // -- If E2 is an xvalue: E1 can be converted to match E2 if E1 can be | ||||
// implicitly converted to the type "rvalue reference to R2", subject to | // implicitly converted to the type "rvalue reference to R2", subject to | ||||
// the constraint that the reference must bind directly. | // the constraint that the reference must bind directly. | ||||
if (To->isLValue() || To->isXValue()) { | if (To->isGLValue()) { | ||||
QualType T = To->isLValue() ? Self.Context.getLValueReferenceType(ToType) | QualType T = Self.Context.getReferenceQualifiedType(To); | ||||
aaronpuchert: The quote doesn't reference parenthesized expressions, isn't this just coincidentally the same… | |||||
It's fundamentally the same thing. The getDecltypeForParenthesizedExpr name is what I tried to keep, I don't have better ideas there. mizvekov: It's fundamentally the same thing. The `getDecltypeForParenthesizedExpr` name is what I tried… | |||||
Not Done ReplyInline ActionsWhat this is doing is pointwise equal to getDecltypeForParenthesizedExpr, but there is no parenthesized expression, and no decltype. There is a quote from the standard that defines this separately (by now this seems to be expr.cond#4), and there are some differences especially in the prvalue case. So I'm not sure this helps. aaronpuchert: What this is doing is pointwise equal to `getDecltypeForParenthesizedExpr`, but there is no… | |||||
Here for XValue and and LValue, the rules are exactly the same as https://eel.is/c++draft/dcl.type.decltype#1. I am sure there is some way we can agree that we should not repeat the code just because the standard did not bother to give a name to this part of the rules... And again I think it is no coincidence that it makes sense to perform the same changes in all these cases. mizvekov: Here for XValue and and LValue, the rules are exactly the same as https://eel.is/c++draft/dcl. | |||||
Maybe we can find a more general name for this functionality that doesn't mention decltype. Perhaps something like getReferenceQualifiedType? rsmith: Maybe we can find a more general name for this functionality that doesn't mention `decltype`. | |||||
Yes that is a good name, thanks! mizvekov: Yes that is a good name, thanks! | |||||
: Self.Context.getRValueReferenceType(ToType); | |||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); | InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); | ||||
InitializationSequence InitSeq(Self, Entity, Kind, From); | InitializationSequence InitSeq(Self, Entity, Kind, From); | ||||
if (InitSeq.isDirectReferenceBinding()) { | if (InitSeq.isDirectReferenceBinding()) { | ||||
ToType = T; | ToType = T; | ||||
HaveConversion = true; | HaveConversion = true; | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,832 Lines • ▼ Show 20 Lines | else if (ReturnTypeRequirement.isSubstitutionFailure()) | ||||
Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure; | Status = concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure; | ||||
else if (ReturnTypeRequirement.isTypeConstraint()) { | else if (ReturnTypeRequirement.isTypeConstraint()) { | ||||
// C++2a [expr.prim.req]p1.3.3 | // C++2a [expr.prim.req]p1.3.3 | ||||
// The immediately-declared constraint ([temp]) of decltype((E)) shall | // The immediately-declared constraint ([temp]) of decltype((E)) shall | ||||
// be satisfied. | // be satisfied. | ||||
TemplateParameterList *TPL = | TemplateParameterList *TPL = | ||||
ReturnTypeRequirement.getTypeConstraintTemplateParameterList(); | ReturnTypeRequirement.getTypeConstraintTemplateParameterList(); | ||||
QualType MatchedType = | QualType MatchedType = | ||||
getDecltypeForParenthesizedExpr(E).getCanonicalType(); | Context.getReferenceQualifiedType(E).getCanonicalType(); | ||||
llvm::SmallVector<TemplateArgument, 1> Args; | llvm::SmallVector<TemplateArgument, 1> Args; | ||||
Args.push_back(TemplateArgument(MatchedType)); | Args.push_back(TemplateArgument(MatchedType)); | ||||
TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); | TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); | ||||
MultiLevelTemplateArgumentList MLTAL(TAL); | MultiLevelTemplateArgumentList MLTAL(TAL); | ||||
for (unsigned I = 0; I < TPL->getDepth(); ++I) | for (unsigned I = 0; I < TPL->getDepth(); ++I) | ||||
MLTAL.addOuterRetainedLevel(); | MLTAL.addOuterRetainedLevel(); | ||||
Expr *IDC = | Expr *IDC = | ||||
cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint() | cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint() | ||||
▲ Show 20 Lines • Show All 106 Lines • Show Last 20 Lines |
The quote doesn't reference parenthesized expressions, isn't this just coincidentally the same thing?