-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Clang] Normalize constraints before checking for satisfaction #141776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
a8c391c
bfcad78
7d66cd8
ccb3eb0
7ff50be
badb3f2
3e37bd4
e412201
fc0e116
e8d251b
da2022a
eb3922e
90b7a28
d2e310e
5f239d4
c5a8c31
9361310
3aec41a
aa79712
905de97
7237aaa
e11c377
0eec94b
8dc536c
b01c7f5
56aaa21
5454d00
f2bf57c
99b62f0
a160c64
95911f1
536b281
7ecf194
3604567
2843ad3
a1eb5b5
ebe396b
38c43e1
81413f0
ab3f023
aa7fcb9
cde4bb7
fdb9bfb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,9 +61,15 @@ struct NormalizedConstraint { | |
unsigned Kind : 5; | ||
unsigned Placeholder : 1; | ||
unsigned PackSubstitutionIndex : 26; | ||
// Indexes and Args are part of the common initial sequences | ||
// of constraints that do have a mapping. | ||
// Indexes, IndexesForSubsumption, and Args are part of the common initial | ||
// sequences of constraints that do have a mapping. | ||
|
||
// Indexes of the parameters used in a constraint expression. | ||
OccurenceList Indexes; | ||
// Indexes of the parameters named directly in a constraint expression. | ||
// FIXME: we should try to reduce the size of this struct? | ||
OccurenceList IndexesForSubsumption; | ||
|
||
TemplateArgumentLoc *Args; | ||
TemplateParameterList *ParamList; | ||
ExprOrConcept ConstraintExpr; | ||
|
@@ -77,6 +83,7 @@ struct NormalizedConstraint { | |
unsigned FoldOperator : 1; | ||
unsigned Placeholder : 26; | ||
OccurenceList Indexes; | ||
OccurenceList IndexesForSubsumption; | ||
TemplateArgumentLoc *Args; | ||
TemplateParameterList *ParamList; | ||
const Expr *Pattern; | ||
|
@@ -119,6 +126,7 @@ struct NormalizedConstraint { | |
/*Placeholder=*/0, | ||
PackIndex.toInternalRepresentation(), | ||
/*Indexes=*/{}, | ||
/*IndexesForSubsumption=*/{}, | ||
/*Args=*/nullptr, | ||
/*ParamList=*/nullptr, | ||
ConstraintExpr, | ||
|
@@ -131,6 +139,7 @@ struct NormalizedConstraint { | |
llvm::to_underlying(OpKind), | ||
/*Placeholder=*/0, | ||
/*Indexes=*/{}, | ||
/*IndexesForSubsumption=*/{}, | ||
/*Args=*/nullptr, | ||
/*ParamList=*/nullptr, | ||
Pattern, | ||
|
@@ -145,6 +154,7 @@ struct NormalizedConstraint { | |
: ConceptId{{llvm::to_underlying(ConstraintKind::ConceptId), | ||
/*Placeholder=*/0, PackIndex.toInternalRepresentation(), | ||
/*Indexes=*/{}, | ||
/*IndexesForSubsumption=*/{}, | ||
/*Args=*/nullptr, /*ParamList=*/nullptr, ConceptId, | ||
ConstraintDecl}, | ||
SubConstraint, | ||
|
@@ -166,6 +176,11 @@ struct NormalizedConstraint { | |
return Atomic.Indexes; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not there yet, but exposing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's copied entirely in in |
||
} | ||
|
||
const OccurenceList &mappingOccurenceListForSubsumption() const { | ||
assert(hasParameterMapping() && "This constraint has no parameter mapping"); | ||
return Atomic.IndexesForSubsumption; | ||
} | ||
|
||
llvm::MutableArrayRef<TemplateArgumentLoc> getParameterMapping() const { | ||
return {Atomic.Args, Atomic.Indexes.count()}; | ||
} | ||
|
@@ -175,11 +190,16 @@ struct NormalizedConstraint { | |
} | ||
|
||
void updateParameterMapping(OccurenceList Indexes, | ||
OccurenceList IndexesForSubsumption, | ||
llvm::MutableArrayRef<TemplateArgumentLoc> Args, | ||
TemplateParameterList *ParamList) { | ||
assert(getKind() != ConstraintKind::Compound); | ||
assert(Indexes.count() == Args.size()); | ||
Atomic.Indexes = Indexes; | ||
assert(IndexesForSubsumption.size() == Indexes.size()); | ||
assert((Indexes & IndexesForSubsumption) == Indexes); | ||
|
||
Atomic.IndexesForSubsumption = std::move(IndexesForSubsumption); | ||
Atomic.Indexes = std::move(Indexes); | ||
Atomic.Args = Args.data(); | ||
Atomic.ParamList = ParamList; | ||
} | ||
|
@@ -198,10 +218,17 @@ struct NormalizedConstraint { | |
llvm::ArrayRef<TemplateArgumentLoc> OtherParameterMapping = | ||
Other.getParameterMapping(); | ||
|
||
const OccurenceList &Indexes = mappingOccurenceListForSubsumption(); | ||
const OccurenceList &OtherIndexes = | ||
Other.mappingOccurenceListForSubsumption(); | ||
|
||
if (ParameterMapping.size() != OtherParameterMapping.size()) | ||
return false; | ||
|
||
for (unsigned I = 0, S = ParameterMapping.size(); I < S; ++I) { | ||
if (Indexes[I] != OtherIndexes[I]) | ||
return false; | ||
if (!Indexes[I]) | ||
continue; | ||
llvm::FoldingSetNodeID IDA, IDB; | ||
C.getCanonicalTemplateArgument(ParameterMapping[I].getArgument()) | ||
.Profile(IDA, C); | ||
|
@@ -296,6 +323,7 @@ class NormalizedConstraintWithParamMapping : public NormalizedConstraint { | |
using NormalizedConstraint::hasMatchingParameterMapping; | ||
using NormalizedConstraint::hasParameterMapping; | ||
using NormalizedConstraint::mappingOccurenceList; | ||
using NormalizedConstraint::mappingOccurenceListForSubsumption; | ||
using NormalizedConstraint::updateParameterMapping; | ||
|
||
const NamedDecl *getConstraintDecl() const { return Atomic.ConstraintDecl; } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1919,25 +1919,28 @@ void SubstituteParameterMappings::buildParameterMapping( | |
cast<TemplateDecl>(N.getConstraintDecl())->getTemplateParameters(); | ||
|
||
llvm::SmallBitVector OccurringIndices(TemplateParams->size()); | ||
llvm::SmallBitVector OccurringIndicesForSubsumption(TemplateParams->size()); | ||
|
||
if (N.getKind() == NormalizedConstraint::ConstraintKind::Atomic) { | ||
SemaRef.MarkUsedTemplateParameters( | ||
static_cast<AtomicConstraint &>(N).getConstraintExpr(), | ||
/*OnlyDeduced=*/false, | ||
/*Depth=*/0, OccurringIndices); | ||
|
||
SemaRef.MarkUsedTemplateParametersForSubsumptionParameterMapping( | ||
static_cast<AtomicConstraint &>(N).getConstraintExpr(), | ||
/*Depth=*/0, OccurringIndicesForSubsumption); | ||
|
||
Comment on lines
+1929
to
+1933
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think this is applicable to FoldExprs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did some testing and i can't get it to failed without it, so I removed it! |
||
} else if (N.getKind() == | ||
NormalizedConstraint::ConstraintKind::FoldExpanded) { | ||
SemaRef.MarkUsedTemplateParameters( | ||
static_cast<FoldExpandedConstraint &>(N).getPattern(), | ||
/*OnlyDeduced=*/false, | ||
/*Depth=*/0, OccurringIndices); | ||
} else if (N.getKind() == NormalizedConstraint::ConstraintKind::ConceptId) { | ||
auto *Args = static_cast<ConceptIdConstraint &>(N) | ||
.getConceptId() | ||
->getTemplateArgsAsWritten(); | ||
if (Args) | ||
SemaRef.MarkUsedTemplateParameters(Args->arguments(), | ||
/*Depth=*/0, OccurringIndices); | ||
|
||
SemaRef.MarkUsedTemplateParametersForSubsumptionParameterMapping( | ||
static_cast<FoldExpandedConstraint &>(N).getPattern(), | ||
/*Depth=*/0, OccurringIndicesForSubsumption); | ||
} | ||
TemplateArgumentLoc *TempArgs = | ||
new (SemaRef.Context) TemplateArgumentLoc[OccurringIndices.count()]; | ||
|
@@ -1962,7 +1965,7 @@ void SubstituteParameterMappings::buildParameterMapping( | |
/*RAngleLoc=*/SourceLocation(), | ||
/*RequiresClause=*/nullptr); | ||
N.updateParameterMapping( | ||
OccurringIndices, | ||
std::move(OccurringIndices), std::move(OccurringIndicesForSubsumption), | ||
MutableArrayRef<TemplateArgumentLoc>{TempArgs, OccurringIndices.count()}, | ||
UsedList); | ||
} | ||
|
@@ -2023,7 +2026,8 @@ bool SubstituteParameterMappings::substitute( | |
|
||
MutableArrayRef<TemplateArgumentLoc> Mapping(TempArgs, | ||
CTAI.SugaredConverted.size()); | ||
N.updateParameterMapping(N.mappingOccurenceList(), Mapping, | ||
N.updateParameterMapping(N.mappingOccurenceList(), | ||
N.mappingOccurenceListForSubsumption(), Mapping, | ||
N.getUsedTemplateParamList()); | ||
return false; | ||
} | ||
|
@@ -2481,10 +2485,13 @@ auto SubsumptionChecker::find(const AtomicConstraint *Ori) -> Literal { | |
ID.AddBoolean(Ori->hasParameterMapping()); | ||
if (Ori->hasParameterMapping()) { | ||
const auto &Mapping = Ori->getParameterMapping(); | ||
for (const TemplateArgumentLoc &TAL : Mapping) { | ||
SemaRef.getASTContext() | ||
.getCanonicalTemplateArgument(TAL.getArgument()) | ||
.Profile(ID, SemaRef.getASTContext()); | ||
const NormalizedConstraint::OccurenceList &Indexes = | ||
Ori->mappingOccurenceListForSubsumption(); | ||
for (auto [Idx, TAL] : llvm::enumerate(Mapping)) { | ||
if (Indexes[Idx]) | ||
SemaRef.getASTContext() | ||
.getCanonicalTemplateArgument(TAL.getArgument()) | ||
.Profile(ID, SemaRef.getASTContext()); | ||
} | ||
} | ||
auto It = Elems.find(ID); | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -6702,10 +6702,11 @@ namespace { | |||
struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor { | ||||
llvm::SmallBitVector &Used; | ||||
unsigned Depth; | ||||
bool VisitDeclRefTypes = true; | ||||
|
||||
MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &Used, | ||||
unsigned Depth) | ||||
: Used(Used), Depth(Depth) { } | ||||
MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &Used, unsigned Depth, | ||||
bool VisitDeclRefTypes = true) | ||||
: Used(Used), Depth(Depth), VisitDeclRefTypes(VisitDeclRefTypes) {} | ||||
|
||||
bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override { | ||||
if (T->getDepth() == Depth) | ||||
|
@@ -6726,7 +6727,8 @@ struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor { | |||
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) | ||||
if (NTTP->getDepth() == Depth) | ||||
Used[NTTP->getIndex()] = true; | ||||
DynamicRecursiveASTVisitor::TraverseType(E->getType()); | ||||
if (VisitDeclRefTypes) | ||||
DynamicRecursiveASTVisitor::TraverseType(E->getType()); | ||||
return true; | ||||
} | ||||
|
||||
|
@@ -7176,6 +7178,13 @@ Sema::MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, | |||
::MarkUsedTemplateParameters(Context, E, OnlyDeduced, Depth, Used); | ||||
} | ||||
|
||||
void Sema::MarkUsedTemplateParametersForSubsumptionParameterMapping( | ||||
const Expr *E, unsigned Depth, llvm::SmallBitVector &Used) { | ||||
MarkUsedTemplateParameterVisitor(Used, Depth, /*VisitDeclRefTypes=*/false) | ||||
.TraverseStmt(const_cast<Expr *>(E)); | ||||
return; | ||||
|
return; |
Uh oh!
There was an error while loading. Please reload this page.