clang  16.0.0git
ExprConcepts.cpp
Go to the documentation of this file.
1 //===- ExprCXX.cpp - (C++) Expression AST Node Implementation -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the subclesses of Expr class declared in ExprCXX.h
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/ExprConcepts.h"
14 #include "clang/AST/ASTConcept.h"
15 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/Expr.h"
23 #include "clang/AST/TemplateBase.h"
24 #include "clang/AST/Type.h"
26 #include "llvm/Support/TrailingObjects.h"
27 #include <algorithm>
28 #include <string>
29 #include <utility>
30 
31 using namespace clang;
32 
34  const ASTContext &C, NestedNameSpecifierLoc NNS,
35  SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
36  NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
37  const ASTTemplateArgumentListInfo *ArgsAsWritten,
39  const ConstraintSatisfaction *Satisfaction)
40  : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),
41  ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl,
42  NamedConcept, ArgsAsWritten),
43  SpecDecl(SpecDecl),
44  Satisfaction(Satisfaction
45  ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
46  : nullptr) {
47  setDependence(computeDependence(this, /*ValueDependent=*/!Satisfaction));
48 
49  // Currently guaranteed by the fact concepts can only be at namespace-scope.
50  assert(!NestedNameSpec ||
54  assert((!isValueDependent() || isInstantiationDependent()) &&
55  "should not be value-dependent");
56 }
57 
59  : Expr(ConceptSpecializationExprClass, Empty) {}
60 
62  const ASTContext &C, NestedNameSpecifierLoc NNS,
63  SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
64  NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
65  const ASTTemplateArgumentListInfo *ArgsAsWritten,
67  const ConstraintSatisfaction *Satisfaction) {
68  return new (C) ConceptSpecializationExpr(
69  C, NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept,
71 }
72 
74  const ASTContext &C, ConceptDecl *NamedConcept,
76  const ConstraintSatisfaction *Satisfaction, bool Dependent,
77  bool ContainsUnexpandedParameterPack)
78  : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),
80  DeclarationNameInfo(), NamedConcept, NamedConcept,
81  nullptr),
82  SpecDecl(SpecDecl),
83  Satisfaction(Satisfaction
84  ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
85  : nullptr) {
87  if (!Satisfaction)
89  if (Dependent)
90  D |= ExprDependence::Instantiation;
91  if (ContainsUnexpandedParameterPack)
92  D |= ExprDependence::UnexpandedPack;
93  setDependence(D);
94 }
95 
97  const ASTContext &C, ConceptDecl *NamedConcept,
99  const ConstraintSatisfaction *Satisfaction, bool Dependent,
100  bool ContainsUnexpandedParameterPack) {
101  return new (C)
103  Dependent, ContainsUnexpandedParameterPack);
104 }
105 
106 const TypeConstraint *
108  assert(isTypeConstraint());
109  auto TPL =
110  TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
111  return cast<TemplateTypeParmDecl>(TPL->getParam(0))
112  ->getTypeConstraint();
113 }
114 
115 RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
116  RequiresExprBodyDecl *Body,
117  ArrayRef<ParmVarDecl *> LocalParameters,
119  SourceLocation RBraceLoc)
120  : Expr(RequiresExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),
121  NumLocalParameters(LocalParameters.size()),
122  NumRequirements(Requirements.size()), Body(Body), RBraceLoc(RBraceLoc) {
123  RequiresExprBits.IsSatisfied = false;
124  RequiresExprBits.RequiresKWLoc = RequiresKWLoc;
125  bool Dependent = false;
126  bool ContainsUnexpandedParameterPack = false;
127  for (ParmVarDecl *P : LocalParameters) {
128  Dependent |= P->getType()->isInstantiationDependentType();
129  ContainsUnexpandedParameterPack |=
130  P->getType()->containsUnexpandedParameterPack();
131  }
132  RequiresExprBits.IsSatisfied = true;
133  for (concepts::Requirement *R : Requirements) {
134  Dependent |= R->isDependent();
135  ContainsUnexpandedParameterPack |= R->containsUnexpandedParameterPack();
136  if (!Dependent) {
137  RequiresExprBits.IsSatisfied = R->isSatisfied();
138  if (!RequiresExprBits.IsSatisfied)
139  break;
140  }
141  }
142  std::copy(LocalParameters.begin(), LocalParameters.end(),
143  getTrailingObjects<ParmVarDecl *>());
144  std::copy(Requirements.begin(), Requirements.end(),
145  getTrailingObjects<concepts::Requirement *>());
146  RequiresExprBits.IsSatisfied |= Dependent;
147  // FIXME: move the computing dependency logic to ComputeDependence.h
148  if (ContainsUnexpandedParameterPack)
149  setDependence(getDependence() | ExprDependence::UnexpandedPack);
150  // FIXME: this is incorrect for cases where we have a non-dependent
151  // requirement, but its parameters are instantiation-dependent. RequiresExpr
152  // should be instantiation-dependent if it has instantiation-dependent
153  // parameters.
154  if (Dependent)
155  setDependence(getDependence() | ExprDependence::ValueInstantiation);
156 }
157 
158 RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,
159  unsigned NumLocalParameters,
160  unsigned NumRequirements)
161  : Expr(RequiresExprClass, Empty), NumLocalParameters(NumLocalParameters),
162  NumRequirements(NumRequirements) { }
163 
164 RequiresExpr *
166  RequiresExprBodyDecl *Body,
167  ArrayRef<ParmVarDecl *> LocalParameters,
169  SourceLocation RBraceLoc) {
170  void *Mem =
171  C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
172  LocalParameters.size(), Requirements.size()),
173  alignof(RequiresExpr));
174  return new (Mem) RequiresExpr(C, RequiresKWLoc, Body, LocalParameters,
175  Requirements, RBraceLoc);
176 }
177 
178 RequiresExpr *
180  unsigned NumLocalParameters, unsigned NumRequirements) {
181  void *Mem =
182  C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
183  NumLocalParameters, NumRequirements),
184  alignof(RequiresExpr));
185  return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);
186 }
clang::ASTConstraintSatisfaction
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:77
clang::concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint
const TypeConstraint * getTypeConstraint() const
Definition: ExprConcepts.cpp:107
clang::OK_Ordinary
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:139
DependenceFlags.h
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:247
clang::NestedNameSpecifier::isInstantiationDependent
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
Definition: NestedNameSpecifier.cpp:238
clang::RequiresExpr
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:471
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1712
clang::concepts::ExprRequirement::ReturnTypeRequirement::isTypeConstraint
bool isTypeConstraint() const
Definition: ExprConcepts.h:309
clang::ExprDependenceScope::ExprDependence
ExprDependence
Definition: DependenceFlags.h:17
clang::ConceptSpecializationExpr::Satisfaction
ASTConstraintSatisfaction * Satisfaction
Information about the satisfaction of the named concept with the given arguments.
Definition: ExprConcepts.h:55
clang::RequiresExpr::Create
static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, ArrayRef< ParmVarDecl * > LocalParameters, ArrayRef< concepts::Requirement * > Requirements, SourceLocation RBraceLoc)
Definition: ExprConcepts.cpp:165
clang::Stmt::EmptyShell
A placeholder type used to construct an empty shell of a type, that will be filled in later (e....
Definition: Stmt.h:1109
Decl.h
ExprConcepts.h
TemplateBase.h
clang::NestedNameSpecifier::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
Definition: NestedNameSpecifier.cpp:242
DeclTemplate.h
clang::RequiresExprBodyDecl
Represents the body of a requires-expression.
Definition: DeclCXX.h:1961
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::ConceptDecl
Declaration of a C++20 concept.
Definition: DeclTemplate.h:3262
clang::ConceptSpecializationExpr
Represents the specialization of a concept - evaluates to a prvalue of type bool.
Definition: ExprConcepts.h:40
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:209
NestedNameSpecifier.h
clang::ConceptReference::NamedConcept
ConceptDecl * NamedConcept
The concept named.
Definition: ASTConcept.h:120
clang::concepts::Requirement
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:145
Type.h
clang::Expr::isInstantiationDependent
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition: Expr.h:214
Expr.h
ASTContext.h
ComputeDependence.h
clang::TemplateParameterList
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:70
clang::NestedNameSpecifierLoc
A C++ nested-name-specifier augmented with source location information.
Definition: NestedNameSpecifier.h:243
ASTConcept.h
This file provides AST data structures related to concepts.
clang::computeDependence
ExprDependence computeDependence(FullExpr *E)
Definition: ComputeDependence.cpp:24
clang::ConceptReference::ArgsAsWritten
const ASTTemplateArgumentListInfo * ArgsAsWritten
The template argument list source info used to specialize the concept.
Definition: ASTConcept.h:124
SourceLocation.h
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::ConceptReference::NestedNameSpec
NestedNameSpecifierLoc NestedNameSpec
Definition: ASTConcept.h:104
clang::VK_PRValue
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:123
clang::ConceptSpecializationExpr::Create
static ConceptSpecializationExpr * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction)
Definition: ExprConcepts.cpp:61
clang::ConceptReference
Common data class for constructs that reference concepts with template arguments.
Definition: ASTConcept.h:101
clang::ImplicitConceptSpecializationDecl
Definition: DeclTemplate.h:3309
clang::ConceptSpecializationExpr::ConceptSpecializationExpr
ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, ImplicitConceptSpecializationDecl *SpecDecl, const ConstraintSatisfaction *Satisfaction)
Definition: ExprConcepts.cpp:33
llvm::ArrayRef
Definition: LLVM.h:34
Value
Value
Definition: UninitializedValues.cpp:103
clang::Expr::isValueDependent
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:168
clang::Expr::setDependence
void setDependence(ExprDependence Deps)
Each concrete expr subclass is expected to compute its dependence and call this in the constructor.
Definition: Expr.h:134
DeclarationName.h
clang
Definition: CalledOnceCheck.h:17
clang::NestedNameSpecifierLoc::getNestedNameSpecifier
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Definition: NestedNameSpecifier.h:274
clang::ConstraintSatisfaction
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:28
clang::ASTTemplateArgumentListInfo
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:612
clang::ConceptReference::FoundDecl
NamedDecl * FoundDecl
The declaration found by name lookup when the expression was created.
Definition: ASTConcept.h:117
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::DeclarationNameInfo
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Definition: DeclarationName.h:767
clang::ConceptSpecializationExpr::SpecDecl
ImplicitConceptSpecializationDecl * SpecDecl
The Implicit Concept Specialization Decl, which holds the template arguments for this specialization.
Definition: ExprConcepts.h:50
clang::TypeConstraint
Definition: ASTConcept.h:169
clang::ConceptReference::TemplateKWLoc
SourceLocation TemplateKWLoc
The location of the template keyword, if specified when naming the concept.
Definition: ASTConcept.h:108