Skip to content

Corentin/concepts pre poland #37

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

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7d217e5
non type template template parameters (wip)
cor3ntin Mar 18, 2023
da8c879
[Clang] Improve diagnostics when using a concept as template argument
cor3ntin Mar 23, 2023
6c6dc6a
Concept template parameter subsumption
cor3ntin Mar 27, 2023
e4696c5
[Clang] Support concept template parameters as type constraints
cor3ntin Apr 10, 2023
6080337
Use a templatedecl instead of a namedecl
cor3ntin Apr 10, 2023
c147f9d
fix tests
cor3ntin Apr 10, 2023
ff342ef
Work around the fact that UnresolvedLookupExpr can have args
cor3ntin Apr 10, 2023
49b7088
Support default arguments for template template parameters
cor3ntin Apr 11, 2023
cf25ce2
Partially applied concepts (wip)
cor3ntin Apr 14, 2023
f925457
Fix dependence of TTP parameter
cor3ntin Apr 18, 2023
73e756f
Fix concept param arity matching + add test file
cor3ntin Apr 18, 2023
256d3f7
Fix subsumption for concept template parameters
cor3ntin Apr 23, 2023
895fb72
subsumption for partial concepts
cor3ntin Apr 25, 2023
af717cb
Fix build
cor3ntin May 13, 2023
411e8e5
Fix build
cor3ntin May 13, 2023
3cb9722
Fix crash when using an unexisting concvept as partial concept
cor3ntin May 14, 2023
54a7261
Fix build after rebase
cor3ntin Sep 17, 2023
063daf7
[WIP] Universal template parameters
cor3ntin Sep 19, 2023
c0f5fb1
Fix rebase
cor3ntin Oct 22, 2023
bd1e6e1
Fix mangling crash
cor3ntin Oct 23, 2023
74146aa
First pass at argument deduction for non type template parameter
cor3ntin Oct 24, 2023
c8ae96b
Use a symbolic reference model for id-expression NTTP arguments
cor3ntin Dec 13, 2023
1893c4b
Subsumption for fold expressions not involving concept template param…
cor3ntin Nov 26, 2023
b645cc5
Dependent concept-id during partial ordering should result in a subst…
cor3ntin Feb 20, 2024
99cd439
Fix rebase
cor3ntin Apr 11, 2024
58cedbb
Merge remote-tracking branch 'llvm_be_very_careful/main' into corenti…
cor3ntin Sep 30, 2024
b93e741
fix merge
cor3ntin Sep 30, 2024
d658277
Temporarily revert partially applied concepts to simplify the diff
cor3ntin Oct 4, 2024
ffb33f1
Temporarily revert universal template params
cor3ntin Oct 4, 2024
b77adc0
Fix missing brace after merge
cor3ntin Oct 4, 2024
f9f1174
Add concept dependent constraints
cor3ntin Oct 4, 2024
2b1be03
fix subsumption for members
cor3ntin Oct 5, 2024
52a8112
fix serialization
cor3ntin Oct 5, 2024
9053226
Use the instantiation pattern to compute subsumbtion whennot dependin…
cor3ntin Oct 6, 2024
793a862
subsumption for concept template arguments
cor3ntin Oct 6, 2024
2d34163
subsumption for concept template arguments packs
cor3ntin Oct 7, 2024
b142f9b
Subsumption of parent context templates
cor3ntin Oct 14, 2024
07a0917
Fix tests
cor3ntin Oct 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions clang/include/clang/AST/ASTConcept.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
namespace clang {

class ConceptDecl;
class TemplateDecl;
class Expr;
class NamedDecl;
struct PrintingPolicy;
Expand Down Expand Up @@ -122,6 +123,7 @@ struct ASTConstraintSatisfaction final :
/// template <std::derives_from<Expr> T> void dump();
/// ~~~~~~~~~~~~~~~~~~~~~~~ (in TemplateTypeParmDecl)
class ConceptReference {
protected:
// \brief The optional nested name specifier used when naming the concept.
NestedNameSpecifierLoc NestedNameSpec;

Expand All @@ -139,15 +141,15 @@ class ConceptReference {
NamedDecl *FoundDecl;

/// \brief The concept named.
ConceptDecl *NamedConcept;
TemplateDecl *NamedConcept;

/// \brief The template argument list source info used to specialize the
/// concept.
const ASTTemplateArgumentListInfo *ArgsAsWritten;

ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
ConceptDecl *NamedConcept,
TemplateDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten)
: NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
Expand All @@ -157,7 +159,7 @@ class ConceptReference {
static ConceptReference *
Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
NamedDecl *FoundDecl, TemplateDecl *NamedConcept,
const ASTTemplateArgumentListInfo *ArgsAsWritten);

const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
Expand Down Expand Up @@ -196,9 +198,7 @@ class ConceptReference {
return FoundDecl;
}

ConceptDecl *getNamedConcept() const {
return NamedConcept;
}
TemplateDecl *getNamedConcept() const { return NamedConcept; }

const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
Expand Down Expand Up @@ -247,7 +247,7 @@ class TypeConstraint {

// FIXME: Instead of using these concept related functions the callers should
// directly work with the corresponding ConceptReference.
ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
TemplateDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }

SourceLocation getConceptNameLoc() const {
return ConceptRef->getConceptNameLoc();
Expand Down Expand Up @@ -278,8 +278,10 @@ class TypeConstraint {
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {
ConceptRef->print(OS, Policy);
}

};


} // clang

#endif // LLVM_CLANG_AST_ASTCONCEPT_H
11 changes: 6 additions & 5 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1660,7 +1660,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType
getAutoTypeInternal(QualType DeducedType, AutoTypeKeyword Keyword,
bool IsDependent, bool IsPack = false,
ConceptDecl *TypeConstraintConcept = nullptr,
TemplateDecl *TypeConstraintConcept = nullptr,
ArrayRef<TemplateArgument> TypeConstraintArgs = {},
bool IsCanon = false) const;

Expand Down Expand Up @@ -1825,10 +1825,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
UnaryTransformType::UTTKind UKind) const;

/// C++11 deduced auto type.
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
bool IsDependent, bool IsPack = false,
ConceptDecl *TypeConstraintConcept = nullptr,
ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;
QualType
getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent,
bool IsPack = false,
TemplateDecl *TypeConstraintConcept = nullptr,
ArrayRef<TemplateArgument> TypeConstraintArgs = {}) const;

/// C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
Expand Down
46 changes: 36 additions & 10 deletions clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TemplateKinds.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
Expand Down Expand Up @@ -1600,15 +1601,22 @@ class TemplateTemplateParmDecl final
/// The number of parameters in an expanded parameter pack.
unsigned NumExpandedParams = 0;

TemplateNameKind ParameterKind = TemplateNameKind::TNK_Type_template;

TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, bool ParameterPack, IdentifierInfo *Id,
bool Typename, TemplateParameterList *Params)
TemplateNameKind ParameterKind,
bool Typename,
TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
TemplateParmPosition(D, P), Typename(Typename),
ParameterPack(ParameterPack), ExpandedParameterPack(false) {}
ParameterPack(ParameterPack),
ExpandedParameterPack(false), ParameterKind(ParameterKind) {}

TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, bool Typename,
unsigned P, IdentifierInfo *Id,
TemplateNameKind ParameterKind,
bool Typename,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions);

Expand All @@ -1619,14 +1627,17 @@ class TemplateTemplateParmDecl final
friend class ASTDeclWriter;
friend TrailingObjects;

static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D,
unsigned P, bool ParameterPack,
IdentifierInfo *Id, bool Typename,
TemplateParameterList *Params);
static TemplateTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, bool Typename,
unsigned P, bool ParameterPack, IdentifierInfo *Id,
TemplateNameKind ParameterKind, bool Typename,
TemplateParameterList *Params);

static TemplateTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id,
TemplateNameKind ParameterKind,
bool Typename,
TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions);

Expand Down Expand Up @@ -1741,6 +1752,16 @@ class TemplateTemplateParmDecl final
return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
}

TemplateNameKind kind() const {
return ParameterKind;
}

bool isTypeConceptTemplateParam() const {
return kind() == TemplateNameKind::TNK_Concept_template &&
getTemplateParameters()->size() > 0 &&
isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
}

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
Expand Down Expand Up @@ -3304,7 +3325,12 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
return TD && (isa<ClassTemplateDecl>(TD) ||
isa<ClassTemplatePartialSpecializationDecl>(TD) ||
isa<TypeAliasTemplateDecl>(TD) ||
isa<TemplateTemplateParmDecl>(TD))
[&]() {
if (TemplateTemplateParmDecl *TTP =
dyn_cast<TemplateTemplateParmDecl>(TD))
return TTP->kind() == TNK_Type_template;
return false;
}())
? TD
: nullptr;
}
Expand Down
47 changes: 45 additions & 2 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
Expand Down Expand Up @@ -3132,7 +3133,49 @@ class OverloadExpr : public Expr {
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }

/// Determines whether this expression had explicit template arguments.
bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
bool hasExplicitTemplateArgs() const {
if (!hasTemplateKWAndArgsInfo())
return false;
// FIXME corentin: deduced function types can have "hidden" args and no <
// investigate that further, but ultimately maybe we want to model concepts
// reference with another kind of expression.
return (isConceptReference() || isVarDeclReference())
? getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs
: getLAngleLoc().isValid();
}

bool isConceptReference() const {
return getNumDecls() == 1 && [&]() {
if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
getTrailingResults()->getDecl()))
return TTP->kind() == TNK_Concept_template;
if (isa<ConceptDecl>(getTrailingResults()->getDecl()))
return true;
return false;
}();
}

bool isVarDeclReference() const {
return getNumDecls() == 1 && [&]() {
if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
getTrailingResults()->getDecl()))
return TTP->kind() == TNK_Var_template;
if (isa<VarTemplateDecl>(getTrailingResults()->getDecl()))
return true;
return false;
}();
}

TemplateDecl *getTemplateDecl() const {
assert(getNumDecls() == 1);
return dyn_cast_or_null<TemplateDecl>(getTrailingResults()->getDecl());
}

TemplateTemplateParmDecl *getTemplateTemplateDecl() const {
assert(getNumDecls() == 1);
return dyn_cast_or_null<TemplateTemplateParmDecl>(
getTrailingResults()->getDecl());
}

TemplateArgumentLoc const *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
Expand Down Expand Up @@ -4535,7 +4578,7 @@ class SubstNonTypeTemplateParmExpr : public Expr {
return PackIndex - 1;
}

NonTypeTemplateParmDecl *getParameter() const;
NamedDecl *getParameter() const;

bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); }

Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/AST/ExprConcepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class ConceptSpecializationExpr final : public Expr {

ConceptReference *getConceptReference() const { return ConceptRef; }

ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
ConceptDecl *getNamedConcept() const { return cast<ConceptDecl>(ConceptRef->getNamedConcept()); }

// FIXME: Several of the following functions can be removed. Instead the
// caller can directly work with the ConceptReference.
Expand Down Expand Up @@ -152,6 +152,7 @@ class ConceptSpecializationExpr final : public Expr {
return ConceptRef->getLocation();
}


// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(

case TemplateArgument::Pack:
return getDerived().TraverseTemplateArguments(Arg.pack_elements());

}

return true;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/TemplateArgumentVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class Base {
VISIT_METHOD(TemplateExpansion);
VISIT_METHOD(Expression);
VISIT_METHOD(Pack);
VISIT_METHOD(Universal);
VISIT_METHOD(UniversalExpansion);

RetTy VisitTemplateArgument(REF(TemplateArgument), ParamTys...) {
return RetTy();
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/AST/TemplateBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
#define LLVM_CLANG_AST_TEMPLATEBASE_H

#include "clang/AST/ASTFwd.h"
#include "clang/AST/DependenceFlags.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
Expand Down Expand Up @@ -104,7 +105,7 @@ class TemplateArgument {

/// The template argument is actually a parameter pack. Arguments are stored
/// in the Args struct.
Pack
Pack,
};

private:
Expand Down Expand Up @@ -169,6 +170,7 @@ class TemplateArgument {
unsigned IsDefaulted : 1;
uintptr_t V;
};

union {
struct DA DeclArg;
struct I Integer;
Expand Down Expand Up @@ -315,6 +317,8 @@ class TemplateArgument {
/// Determine whether this template argument is a pack expansion.
bool isPackExpansion() const;

bool isConceptOrConceptTemplateParameter() const;

/// Retrieve the type for a type template argument.
QualType getAsType() const {
assert(getKind() == Type && "Unexpected kind");
Expand Down Expand Up @@ -480,6 +484,7 @@ struct TemplateArgumentLocInfo {
SourceLocation EllipsisLoc;
};


llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
Pointer;

Expand Down Expand Up @@ -625,6 +630,7 @@ class TemplateArgumentLoc {
return SourceLocation();
return LocInfo.getTemplateEllipsisLoc();
}

};

/// A convenient class for passing around template argument
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ class TextNodeDumper
void VisitTemplateTemplateArgument(const TemplateArgument &TA);
void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
void VisitExpressionTemplateArgument(const TemplateArgument &TA);
void VisitConceptTemplateArgument(const TemplateArgument &TA);

void VisitPackTemplateArgument(const TemplateArgument &TA);

void VisitIfStmt(const IfStmt *Node);
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -6445,10 +6445,10 @@ class DeducedType : public Type {
class AutoType : public DeducedType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these

ConceptDecl *TypeConstraintConcept;
TemplateDecl *TypeConstraintConcept;

AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD,
TypeDependence ExtraDependence, QualType Canon, TemplateDecl *CD,
ArrayRef<TemplateArgument> TypeConstraintArgs);

public:
Expand All @@ -6457,7 +6457,7 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode {
AutoTypeBits.NumArgs};
}

ConceptDecl *getTypeConstraintConcept() const {
TemplateDecl *getTypeConstraintConcept() const {
return TypeConstraintConcept;
}

Expand All @@ -6480,7 +6480,7 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode {
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType Deduced, AutoTypeKeyword Keyword,
bool IsDependent, ConceptDecl *CD,
bool IsDependent, TemplateDecl *CD,
ArrayRef<TemplateArgument> Arguments);

static bool classof(const Type *T) {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/TypeLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2259,7 +2259,7 @@ class AutoTypeLoc
return nullptr;
}

ConceptDecl *getNamedConcept() const {
TemplateDecl *getNamedConcept() const {
if (const auto *CR = getConceptReference())
return CR->getNamedConcept();
return nullptr;
Expand Down
Loading