Skip to content

Commit 6d40a90

Browse files
committed
Revert "Temporarily revert partially applied concepts to simplify the diff"
This reverts commit d658277.
1 parent d658277 commit 6d40a90

28 files changed

+551
-25
lines changed

clang/include/clang/AST/ASTConcept.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,54 @@ class TypeConstraint {
281281

282282
};
283283

284+
class PartiallyAppliedConcept : public ConceptReference,
285+
public llvm::FoldingSetNode {
286+
287+
SourceLocation ConceptKWLoc;
288+
PartiallyAppliedConcept(NestedNameSpecifierLoc NNS,
289+
DeclarationNameInfo ConceptNameInfo,
290+
SourceLocation ConceptKWLoc, NamedDecl *FoundDecl,
291+
TemplateDecl *NamedConcept,
292+
const ASTTemplateArgumentListInfo *ArgsAsWritten)
293+
: ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(),
294+
ConceptNameInfo, FoundDecl, NamedConcept,
295+
ArgsAsWritten),
296+
ConceptKWLoc(ConceptKWLoc) {}
297+
298+
public:
299+
static PartiallyAppliedConcept *
300+
Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
301+
DeclarationNameInfo ConceptNameInfo, SourceLocation ConceptKWLoc,
302+
NamedDecl *FoundDecl, TemplateDecl *NamedConcept,
303+
const TemplateArgumentListInfo &TemplateArgs);
304+
305+
TemplateArgumentDependence getDependence() const;
306+
307+
bool isDependent() const {
308+
return getDependence() & TemplateArgumentDependence::Dependent;
309+
}
310+
311+
bool isInstantiationDependent() const {
312+
return getDependence() & TemplateArgumentDependence::Instantiation;
313+
}
314+
315+
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const {
316+
Profile(ID, C, getNamedConcept(), getTemplateArgsAsWritten());
317+
}
318+
319+
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
320+
const TemplateDecl *NamedConcept,
321+
const ASTTemplateArgumentListInfo *ArgsAsWritten);
322+
323+
SourceLocation getConceptKWLoc() const { return ConceptKWLoc; }
324+
325+
SourceRange getSourceRange() const {
326+
return {ConceptKWLoc, ArgsAsWritten->getRAngleLoc()};
327+
}
328+
329+
friend const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
330+
PartiallyAppliedConcept &C);
331+
};
284332

285333
} // clang
286334

clang/include/clang/AST/ASTContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class ObjCTypeParamDecl;
9797
class OMPTraitInfo;
9898
class ParentMapContext;
9999
struct ParsedTargetAttr;
100+
class PartiallyAppliedConcept;
100101
class Preprocessor;
101102
class ProfileList;
102103
class StoredDeclsMap;

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,14 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
904904
case TemplateArgument::Pack:
905905
return getDerived().TraverseTemplateArguments(Arg.pack_elements());
906906

907+
case TemplateArgument::Concept: {
908+
PartiallyAppliedConcept *C = Arg.getAsPartiallyAppliedConcept();
909+
TRY_TO(getDerived().TraverseDecl(C->getNamedConcept()));
910+
for (const TemplateArgumentLoc &Arg :
911+
C->getTemplateArgsAsWritten()->arguments())
912+
TRY_TO(TraverseTemplateArgument(Arg.getArgument()));
913+
return true;
914+
}
907915
case TemplateArgument::Universal:
908916
case TemplateArgument::UniversalExpansion: {
909917
UniversalTemplateParameterName *UTPN =
@@ -957,6 +965,14 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
957965
case TemplateArgument::Pack:
958966
return getDerived().TraverseTemplateArguments(Arg.pack_elements());
959967

968+
case TemplateArgument::Concept: {
969+
PartiallyAppliedConcept *C = Arg.getAsPartiallyAppliedConcept();
970+
TRY_TO(getDerived().TraverseDecl(C->getNamedConcept()));
971+
for (const TemplateArgumentLoc &Arg :
972+
C->getTemplateArgsAsWritten()->arguments())
973+
TRY_TO(TraverseTemplateArgument(Arg.getArgument()));
974+
return true;
975+
}
960976
}
961977

962978
return true;

clang/include/clang/AST/TemplateArgumentVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Base {
4242
DISPATCH(TemplateExpansion);
4343
DISPATCH(Expression);
4444
DISPATCH(Pack);
45+
DISPATCH(Concept);
4546
DISPATCH(Universal);
4647
DISPATCH(UniversalExpansion);
4748
}
@@ -67,6 +68,7 @@ class Base {
6768
VISIT_METHOD(TemplateExpansion);
6869
VISIT_METHOD(Expression);
6970
VISIT_METHOD(Pack);
71+
VISIT_METHOD(Concept);
7072
VISIT_METHOD(Universal);
7173
VISIT_METHOD(UniversalExpansion);
7274

clang/include/clang/AST/TemplateBase.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Expr;
5858
struct PrintingPolicy;
5959
class TypeSourceInfo;
6060
class ValueDecl;
61+
class PartiallyAppliedConcept;
6162

6263
/// Represents a template argument.
6364
class TemplateArgument {
@@ -108,6 +109,9 @@ class TemplateArgument {
108109
/// in the Args struct.
109110
Pack,
110111

112+
// A concept with argument
113+
Concept,
114+
111115
/// The template argument refers to a universal template parameter
112116
Universal,
113117

@@ -179,6 +183,12 @@ class TemplateArgument {
179183
uintptr_t V;
180184
};
181185

186+
struct ConceptData {
187+
unsigned Kind : 31;
188+
unsigned IsDefaulted : 1;
189+
PartiallyAppliedConcept *C;
190+
};
191+
182192
struct UniversalTpl {
183193
unsigned Kind : 31;
184194
unsigned IsDefaulted : 1;
@@ -193,6 +203,7 @@ class TemplateArgument {
193203
struct A Args;
194204
struct TA TemplateArg;
195205
struct TV TypeOrValue;
206+
struct ConceptData PartialConcept;
196207
struct UniversalTpl UniversalArg;
197208
};
198209

@@ -300,6 +311,13 @@ class TemplateArgument {
300311
this->Args.NumArgs = Args.size();
301312
}
302313

314+
explicit TemplateArgument(PartiallyAppliedConcept *C,
315+
bool IsDefaulted = false) {
316+
PartialConcept.Kind = Concept;
317+
PartialConcept.IsDefaulted = IsDefaulted;
318+
PartialConcept.C = C;
319+
}
320+
303321
explicit TemplateArgument(UniversalTemplateParameterName *U,
304322
bool IsDefaulted = false) {
305323
UniversalArg.Kind = Universal;
@@ -393,6 +411,11 @@ class TemplateArgument {
393411
return TemplateName::getFromVoidPointer(TemplateArg.Name);
394412
}
395413

414+
PartiallyAppliedConcept *getAsPartiallyAppliedConcept() const {
415+
assert((getKind() == Concept) && "Unexpected kind");
416+
return PartialConcept.C;
417+
}
418+
396419
UniversalTemplateParameterName *getAsUniversalTemplateParameterName() const {
397420
assert((getKind() == Universal) && "Unexpected kind");
398421
return UniversalArg.D;
@@ -624,7 +647,8 @@ class TemplateArgumentLoc {
624647
: Argument(Argument),
625648
LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
626649
assert(Argument.getKind() == TemplateArgument::Template ||
627-
Argument.getKind() == TemplateArgument::TemplateExpansion);
650+
Argument.getKind() == TemplateArgument::TemplateExpansion ||
651+
Argument.getKind() == TemplateArgument::Concept);
628652
}
629653

630654
TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
@@ -638,7 +662,8 @@ class TemplateArgumentLoc {
638662
/// - Fetches the primary location of the argument.
639663
SourceLocation getLocation() const {
640664
if (Argument.getKind() == TemplateArgument::Template ||
641-
Argument.getKind() == TemplateArgument::TemplateExpansion)
665+
Argument.getKind() == TemplateArgument::TemplateExpansion ||
666+
Argument.getKind() == TemplateArgument::Concept)
642667
return getTemplateNameLoc();
643668

644669
return getSourceRange().getBegin();
@@ -684,14 +709,16 @@ class TemplateArgumentLoc {
684709

685710
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
686711
if (Argument.getKind() != TemplateArgument::Template &&
687-
Argument.getKind() != TemplateArgument::TemplateExpansion)
712+
Argument.getKind() != TemplateArgument::TemplateExpansion &&
713+
Argument.getKind() != TemplateArgument::Concept)
688714
return NestedNameSpecifierLoc();
689715
return LocInfo.getTemplateQualifierLoc();
690716
}
691717

692718
SourceLocation getTemplateNameLoc() const {
693719
if (Argument.getKind() != TemplateArgument::Template &&
694-
Argument.getKind() != TemplateArgument::TemplateExpansion)
720+
Argument.getKind() != TemplateArgument::TemplateExpansion &&
721+
Argument.getKind() != TemplateArgument::Concept)
695722
return SourceLocation();
696723
return LocInfo.getTemplateNameLoc();
697724
}

clang/include/clang/AST/TypeProperties.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ let Class = AutoType in {
508508
}
509509
def : Property<"typeConstraintConcept", Optional<TemplateDeclRef>> {
510510
let Read = [{ makeOptionalFromPointer(
511-
node->getTypeConstraintConcept()) }];
511+
const_cast<const TemplateDecl*>(node->getTypeConstraintConcept())) }];
512512
}
513513
def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
514514
let Read = [{ node->getTypeConstraintArguments() }];

clang/include/clang/Parse/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3865,6 +3865,7 @@ class Parser : public CodeCompletionHandler {
38653865
bool IsClassName = false);
38663866
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
38673867
TemplateTy Template, SourceLocation OpenLoc);
3868+
ParsedTemplateArgument ParsePartiallyAppliedConceptTemplateArgument();
38683869
ParsedTemplateArgument ParseTemplateTemplateArgument();
38693870
ParsedTemplateArgument ParseUniversalTemplateParamNameArgument();
38703871
ParsedTemplateArgument ParseTemplateArgument();

clang/include/clang/Sema/ParsedTemplate.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <new>
2727

2828
namespace clang {
29+
class PartiallyAppliedConcept;
2930

3031
/// Represents the parsed form of a C++ template argument.
3132
class ParsedTemplateArgument {
@@ -38,6 +39,8 @@ class ParsedTemplateArgument {
3839
NonType,
3940
/// A template template argument, stored as a template name.
4041
Template,
42+
/// A partially applied concept
43+
PartiallyAppliedConcept,
4144
/// The name of a Universal Template Parameter
4245
Universal
4346
};
@@ -68,6 +71,11 @@ class ParsedTemplateArgument {
6871
: Kind(ParsedTemplateArgument::Template), Arg(Template.getAsOpaquePtr()),
6972
SS(SS), Loc(TemplateLoc) {}
7073

74+
ParsedTemplateArgument(class PartiallyAppliedConcept *Concept,
75+
SourceLocation TemplateLoc)
76+
: Kind(ParsedTemplateArgument::PartiallyAppliedConcept), Arg(Concept),
77+
Loc(TemplateLoc) {}
78+
7179
ParsedTemplateArgument(UniversalTemplateParamNameTy ParamName,
7280
SourceLocation Loc)
7381
: Kind(ParsedTemplateArgument::Universal),
@@ -97,6 +105,11 @@ class ParsedTemplateArgument {
97105
return ParsedTemplateTy::getFromOpaquePtr(Arg);
98106
}
99107

108+
class PartiallyAppliedConcept *getAsConcept() const {
109+
assert(Kind == PartiallyAppliedConcept && "Not a concept argument");
110+
return reinterpret_cast<class PartiallyAppliedConcept *>(Arg);
111+
}
112+
100113
UniversalTemplateParamNameTy getAsUniversalTemplateParamName() const {
101114
assert(Kind == Universal &&
102115
"Not a reference to a universal template parameter");
@@ -109,7 +122,7 @@ class ParsedTemplateArgument {
109122
/// Retrieve the nested-name-specifier that precedes the template
110123
/// name in a template template argument.
111124
const CXXScopeSpec &getScopeSpec() const {
112-
assert((Kind == Template) &&
125+
assert((Kind == Template || Kind == PartiallyAppliedConcept) &&
113126
"Only template template arguments can have a scope specifier");
114127
return SS;
115128
}

clang/include/clang/Sema/Sema.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,7 @@ class Sema final : public SemaBase {
974974

975975
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
976976
typedef OpaquePtr<TemplateName> TemplateTy;
977+
typedef OpaquePtr<PartiallyAppliedConcept> ConceptTy;
977978
typedef OpaquePtr<UniversalTemplateParameterName *>
978979
UniversalTemplateParamNameTy;
979980
typedef OpaquePtr<QualType> TypeTy;
@@ -11536,6 +11537,15 @@ class Sema final : public SemaBase {
1153611537
bool EnteringContext, TemplateTy &Template,
1153711538
bool AllowInjectedClassName = false);
1153811539

11540+
PartiallyAppliedConcept *BuildPartiallyAppliedConcept(
11541+
NestedNameSpecifierLoc NNS, SourceLocation ConceptKWLoc,
11542+
DeclarationNameInfo ConceptName, TemplateDecl *TD,
11543+
const TemplateArgumentListInfo &TemplateArgs);
11544+
PartiallyAppliedConcept *
11545+
ActOnPartiallyAppliedConcept(Scope *S, CXXScopeSpec &SS,
11546+
SourceLocation ConceptKWLoc,
11547+
TemplateIdAnnotation *TemplateId);
11548+
1153911549
bool
1154011550
ActOnUniversalTemplateParameterName(Scope *S, const UnqualifiedId &Name,
1154111551
bool EnteringContext,
@@ -11826,6 +11836,10 @@ class Sema final : public SemaBase {
1182611836
TemplateArgument &SugaredConverted,
1182711837
TemplateArgument &CanonicalConverted,
1182811838
CheckTemplateArgumentKind CTAK);
11839+
bool
11840+
CheckPartiallyAppliedConceptTemplateArgument(TemplateTemplateParmDecl *Param,
11841+
TemplateParameterList *Params,
11842+
TemplateArgumentLoc &Arg);
1182911843

1183011844
/// Check a template argument against its corresponding
1183111845
/// template template parameter.

clang/lib/AST/ASTConcept.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,55 @@ void ConceptReference::print(llvm::raw_ostream &OS,
113113
OS << ">";
114114
}
115115
}
116+
117+
118+
PartiallyAppliedConcept *PartiallyAppliedConcept::Create(
119+
const ASTContext &C, NestedNameSpecifierLoc NNS,
120+
DeclarationNameInfo ConceptNameInfo, SourceLocation ConceptKWLoc,
121+
NamedDecl *FoundDecl, TemplateDecl *NamedConcept,
122+
const TemplateArgumentListInfo &TemplateArgs) {
123+
124+
return new (C) PartiallyAppliedConcept(
125+
NNS, ConceptNameInfo, ConceptKWLoc, FoundDecl, NamedConcept,
126+
ASTTemplateArgumentListInfo::Create(C, TemplateArgs));
127+
}
128+
129+
TemplateArgumentDependence PartiallyAppliedConcept::getDependence() const {
130+
auto TA = TemplateArgumentDependence::None;
131+
if (isa<TemplateTemplateParmDecl>(getNamedConcept())) {
132+
TA |= TemplateArgumentDependence::DependentInstantiation;
133+
}
134+
const auto InterestingDeps = TemplateArgumentDependence::Instantiation |
135+
TemplateArgumentDependence::UnexpandedPack;
136+
for (const TemplateArgumentLoc &ArgLoc :
137+
getTemplateArgsAsWritten()->arguments()) {
138+
TA |= ArgLoc.getArgument().getDependence() & InterestingDeps;
139+
if (TA == InterestingDeps)
140+
break;
141+
}
142+
return TA;
143+
}
144+
145+
void PartiallyAppliedConcept::Profile(
146+
llvm::FoldingSetNodeID &ID, const ASTContext &C,
147+
const TemplateDecl *NamedConcept,
148+
const ASTTemplateArgumentListInfo *ArgsAsWritten) {
149+
ID.AddPointer(NamedConcept);
150+
ID.AddInteger(ArgsAsWritten->getNumTemplateArgs());
151+
for (auto &Arg : ArgsAsWritten->arguments())
152+
Arg.getArgument().Profile(ID, C);
153+
}
154+
155+
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
156+
PartiallyAppliedConcept &C) {
157+
std::string NameStr;
158+
llvm::raw_string_ostream OS(NameStr);
159+
LangOptions LO;
160+
LO.CPlusPlus = true;
161+
LO.Bool = true;
162+
OS << '\'';
163+
C.print(OS, PrintingPolicy(LO));
164+
OS << '\'';
165+
OS.flush();
166+
return DB << NameStr;
167+
}

clang/lib/AST/ASTContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7308,6 +7308,10 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
73087308
case TemplateArgument::Expression:
73097309
return Arg;
73107310

7311+
// FIXME corentin: do concept needs to be canonicalized?
7312+
case TemplateArgument::Concept:
7313+
return Arg;
7314+
73117315
case TemplateArgument::Declaration: {
73127316
auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
73137317
return TemplateArgument(D, getCanonicalType(Arg.getParamTypeForDecl()),

0 commit comments

Comments
 (0)