Skip to content

[clang] Introduce SemaConcept #92672

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 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
407 changes: 26 additions & 381 deletions clang/include/clang/Sema/Sema.h

Large diffs are not rendered by default.

391 changes: 388 additions & 3 deletions clang/include/clang/Sema/SemaConcept.h

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "clang/Sema/SemaConcept.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenMP.h"
Expand Down Expand Up @@ -4082,8 +4083,9 @@ void Parser::ParseDeclarationSpecifiers(
if (!NextToken().isOneOf(tok::kw_auto, tok::kw_decltype))
goto DoneWithDeclSpec;

if (TemplateId && !isInvalid && Actions.CheckTypeConstraint(TemplateId))
TemplateId = nullptr;
if (TemplateId && !isInvalid &&
Actions.Concept().CheckTypeConstraint(TemplateId))
TemplateId = nullptr;

ConsumeAnnotationToken();
SourceLocation AutoLoc = Tok.getLocation();
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4290,16 +4290,16 @@ void Parser::ParseTrailingRequiresClause(Declarator &D) {
Scope::FunctionDeclarationScope |
Scope::FunctionPrototypeScope);

Actions.ActOnStartTrailingRequiresClause(getCurScope(), D);
Actions.Concept().ActOnStartTrailingRequiresClause(getCurScope(), D);

std::optional<Sema::CXXThisScopeRAII> ThisScope;
InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope);

TrailingRequiresClause =
ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);

TrailingRequiresClause =
Actions.ActOnFinishTrailingRequiresClause(TrailingRequiresClause);
TrailingRequiresClause = Actions.Concept().ActOnFinishTrailingRequiresClause(
TrailingRequiresClause);

if (!D.isDeclarationOfFunction()) {
Diag(RequiresKWLoc,
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "clang/Sema/SemaConcept.h"
#include "clang/Sema/SemaObjC.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/SemaOpenMP.h"
Expand Down Expand Up @@ -268,7 +269,8 @@ ExprResult Parser::ParseConstraintExpression() {
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
ExprResult LHS(ParseCastExpression(AnyCastExpr));
ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) {
if (Res.isUsable() &&
!Actions.Concept().CheckConstraintExpression(Res.get())) {
Actions.CorrectDelayedTyposInExpr(Res);
return ExprError();
}
Expand Down Expand Up @@ -329,9 +331,8 @@ Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) {
NotPrimaryExpression = false;
}
bool PossibleNonPrimary;
bool IsConstraintExpr =
Actions.CheckConstraintExpression(E.get(), Tok, &PossibleNonPrimary,
IsTrailingRequiresClause);
bool IsConstraintExpr = Actions.Concept().CheckConstraintExpression(
E.get(), Tok, &PossibleNonPrimary, IsTrailingRequiresClause);
if (!IsConstraintExpr || PossibleNonPrimary) {
// Atomic constraint might be an unparenthesized non-primary expression
// (such as a binary operator), in which case we might get here (e.g. in
Expand Down
30 changes: 16 additions & 14 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "clang/Sema/SemaConcept.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <numeric>
Expand Down Expand Up @@ -1417,8 +1418,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
++CurTemplateDepthTracker;
ExprResult RequiresClause;
if (TryConsumeToken(tok::kw_requires)) {
RequiresClause =
Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(
RequiresClause = Actions.Concept().ActOnRequiresClause(
ParseConstraintLogicalOrExpression(
/*IsTrailingRequiresClause=*/false));
if (RequiresClause.isInvalid())
SkipUntil({tok::l_brace, tok::l_paren}, StopAtSemi | StopBeforeMatch);
Expand Down Expand Up @@ -3628,7 +3629,7 @@ ExprResult Parser::ParseRequiresExpression() {
// Dependent diagnostics are attached to this Decl and non-depenedent
// diagnostics are surfaced after this parse.
ParsingDeclRAIIObject ParsingBodyDecl(*this, ParsingDeclRAIIObject::NoParent);
RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr(
RequiresExprBodyDecl *Body = Actions.Concept().ActOnStartRequiresExpr(
RequiresKWLoc, LocalParameterDecls, getCurScope());

if (Tok.is(tok::r_brace)) {
Expand Down Expand Up @@ -3669,7 +3670,8 @@ ExprResult Parser::ParseRequiresExpression() {
SourceLocation NoexceptLoc;
TryConsumeToken(tok::kw_noexcept, NoexceptLoc);
if (Tok.is(tok::semi)) {
Req = Actions.ActOnCompoundRequirement(Expression.get(), NoexceptLoc);
Req = Actions.Concept().ActOnCompoundRequirement(Expression.get(),
NoexceptLoc);
if (Req)
Requirements.push_back(Req);
break;
Expand All @@ -3696,7 +3698,7 @@ ExprResult Parser::ParseRequiresExpression() {
ConsumeAnnotationToken();
}

Req = Actions.ActOnCompoundRequirement(
Req = Actions.Concept().ActOnCompoundRequirement(
Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok),
TemplateParameterDepth);
ConsumeAnnotationToken();
Expand Down Expand Up @@ -3764,8 +3766,8 @@ ExprResult Parser::ParseRequiresExpression() {
SkipUntilFlags::StopBeforeMatch);
break;
}
if (auto *Req =
Actions.ActOnNestedRequirement(ConstraintExpr.get()))
if (auto *Req = Actions.Concept().ActOnNestedRequirement(
ConstraintExpr.get()))
Requirements.push_back(Req);
else {
SkipUntil(tok::semi, tok::r_brace,
Expand Down Expand Up @@ -3810,9 +3812,8 @@ ExprResult Parser::ParseRequiresExpression() {
break;
}

if (auto *Req = Actions.ActOnTypeRequirement(TypenameKWLoc, SS,
NameLoc, II,
TemplateId)) {
if (auto *Req = Actions.Concept().ActOnTypeRequirement(
TypenameKWLoc, SS, NameLoc, II, TemplateId)) {
Requirements.push_back(Req);
}
break;
Expand All @@ -3833,7 +3834,8 @@ ExprResult Parser::ParseRequiresExpression() {
if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)
Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)
<< FixItHint::CreateInsertion(StartLoc, "requires");
if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get()))
if (auto *Req =
Actions.Concept().ActOnSimpleRequirement(Expression.get()))
Requirements.push_back(Req);
else {
SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
Expand Down Expand Up @@ -3861,14 +3863,14 @@ ExprResult Parser::ParseRequiresExpression() {
// other diagnostics quoting an empty requires expression they never
// wrote.
Braces.consumeClose();
Actions.ActOnFinishRequiresExpr();
Actions.Concept().ActOnFinishRequiresExpr();
return ExprError();
}
}
Braces.consumeClose();
Actions.ActOnFinishRequiresExpr();
Actions.Concept().ActOnFinishRequiresExpr();
ParsingBodyDecl.complete(Body);
return Actions.ActOnRequiresExpr(
return Actions.Concept().ActOnRequiresExpr(
RequiresKWLoc, Body, Parens.getOpenLocation(), LocalParameterDecls,
Parens.getCloseLocation(), Requirements, Braces.getCloseLocation());
}
Expand Down
23 changes: 13 additions & 10 deletions clang/lib/Parse/ParseTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaConcept.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/Support/TimeProfiler.h"
using namespace clang;
Expand Down Expand Up @@ -145,8 +146,9 @@ Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(

if (TryConsumeToken(tok::kw_requires)) {
OptionalRequiresClauseConstraintER =
Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(
/*IsTrailingRequiresClause=*/false));
Actions.Concept().ActOnRequiresClause(
ParseConstraintLogicalOrExpression(
/*IsTrailingRequiresClause=*/false));
if (!OptionalRequiresClauseConstraintER.isUsable()) {
// Skip until the semi-colon or a '}'.
SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
Expand Down Expand Up @@ -339,9 +341,9 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
DeclEnd = Tok.getLocation();
ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
Expr *ConstraintExpr = ConstraintExprResult.get();
return Actions.ActOnConceptDefinition(getCurScope(),
*TemplateInfo.TemplateParams, Id, IdLoc,
ConstraintExpr, Attrs);
return Actions.Concept().ActOnConceptDefinition(
getCurScope(), *TemplateInfo.TemplateParams, Id, IdLoc, ConstraintExpr,
Attrs);
}

/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
Expand Down Expand Up @@ -763,9 +765,9 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
TypeConstraint != nullptr);

if (TypeConstraint) {
Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
cast<TemplateTypeParmDecl>(NewDecl),
EllipsisLoc);
Actions.Concept().ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,
cast<TemplateTypeParmDecl>(NewDecl),
EllipsisLoc);
}

return NewDecl;
Expand Down Expand Up @@ -800,8 +802,9 @@ NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
}
if (TryConsumeToken(tok::kw_requires)) {
OptionalRequiresClauseConstraintER =
Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(
/*IsTrailingRequiresClause=*/false));
Actions.Concept().ActOnRequiresClause(
ParseConstraintLogicalOrExpression(
/*IsTrailingRequiresClause=*/false));
if (!OptionalRequiresClauseConstraintER.isUsable()) {
SkipUntil(tok::comma, tok::greater, tok::greatergreater,
StopAtSemi | StopBeforeMatch);
Expand Down
12 changes: 3 additions & 9 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaCUDA.h"
#include "clang/Sema/SemaCodeCompletion.h"
#include "clang/Sema/SemaConcept.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaInternal.h"
Expand Down Expand Up @@ -205,6 +206,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
CurScope(nullptr), Ident_super(nullptr),
CodeCompletionPtr(
std::make_unique<SemaCodeCompletion>(*this, CodeCompleter)),
ConceptPtr(std::make_unique<SemaConcept>(*this)),
CUDAPtr(std::make_unique<SemaCUDA>(*this)),
HLSLPtr(std::make_unique<SemaHLSL>(*this)),
ObjCPtr(std::make_unique<SemaObjC>(*this)),
Expand All @@ -228,7 +230,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TyposCorrected(0), IsBuildingRecoveryCallExpr(false), NumSFINAEErrors(0),
AccessCheckingSFINAE(false), CurrentInstantiationScope(nullptr),
InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0),
ArgumentPackSubstitutionIndex(-1), SatisfactionCache(Context) {
ArgumentPackSubstitutionIndex(-1) {
assert(pp.TUKind == TUKind);
TUScope = nullptr;

Expand Down Expand Up @@ -491,14 +493,6 @@ Sema::~Sema() {
= dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
ExternalSema->ForgetSema();

// Delete cached satisfactions.
std::vector<ConstraintSatisfaction *> Satisfactions;
Satisfactions.reserve(SatisfactionCache.size());
for (auto &Node : SatisfactionCache)
Satisfactions.push_back(&Node);
for (auto *Node : Satisfactions)
delete Node;

threadSafety::threadSafetyCleanup(ThreadSafetyDeclCache);

// Destroys data sharing attributes stack for OpenMP
Expand Down
6 changes: 0 additions & 6 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8092,12 +8092,6 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);
}

void Sema::CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc) {
if (ConceptDecl *Decl = AutoT->getTypeConstraintConcept()) {
DiagnoseUseOfDecl(Decl, Loc);
}
}

/// CheckConstructorCall - Check a constructor call for correctness and safety
/// properties not enforced by the C type system.
void Sema::CheckConstructorCall(FunctionDecl *FDecl, QualType ThisType,
Expand Down
Loading
Loading