clang  12.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,
38  ArrayRef<TemplateArgument> ConvertedArgs,
39  const ConstraintSatisfaction *Satisfaction)
40  : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary),
41  ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl,
42  NamedConcept, ArgsAsWritten),
43  NumTemplateArgs(ConvertedArgs.size()),
44  Satisfaction(Satisfaction
45  ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
46  : nullptr) {
47  setTemplateArguments(ConvertedArgs);
48  setDependence(computeDependence(this, /*ValueDependent=*/!Satisfaction));
49 
50  // Currently guaranteed by the fact concepts can only be at namespace-scope.
51  assert(!NestedNameSpec ||
55  assert((!isValueDependent() || isInstantiationDependent()) &&
56  "should not be value-dependent");
57 }
58 
60  unsigned NumTemplateArgs)
61  : Expr(ConceptSpecializationExprClass, Empty), ConceptReference(),
62  NumTemplateArgs(NumTemplateArgs) { }
63 
65  ArrayRef<TemplateArgument> Converted) {
66  assert(Converted.size() == NumTemplateArgs);
67  std::uninitialized_copy(Converted.begin(), Converted.end(),
68  getTrailingObjects<TemplateArgument>());
69 }
70 
75  DeclarationNameInfo ConceptNameInfo,
79  ArrayRef<TemplateArgument> ConvertedArgs,
81  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
82  ConvertedArgs.size()));
83  return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc,
84  ConceptNameInfo, FoundDecl,
85  NamedConcept, ArgsAsWritten,
86  ConvertedArgs, Satisfaction);
87 }
88 
91  ArrayRef<TemplateArgument> ConvertedArgs,
92  const ConstraintSatisfaction *Satisfaction, bool Dependent,
93  bool ContainsUnexpandedParameterPack)
94  : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary),
96  DeclarationNameInfo(), NamedConcept, NamedConcept,
97  nullptr),
98  NumTemplateArgs(ConvertedArgs.size()),
99  Satisfaction(Satisfaction
100  ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
101  : nullptr) {
102  setTemplateArguments(ConvertedArgs);
104  if (!Satisfaction)
106  if (Dependent)
107  D |= ExprDependence::Instantiation;
108  if (ContainsUnexpandedParameterPack)
109  D |= ExprDependence::UnexpandedPack;
110  setDependence(D);
111 }
112 
116  ArrayRef<TemplateArgument> ConvertedArgs,
118  bool Dependent,
119  bool ContainsUnexpandedParameterPack) {
120  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
121  ConvertedArgs.size()));
122  return new (Buffer) ConceptSpecializationExpr(
123  C, NamedConcept, ConvertedArgs, Satisfaction, Dependent,
124  ContainsUnexpandedParameterPack);
125 }
126 
129  unsigned NumTemplateArgs) {
130  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
131  NumTemplateArgs));
132  return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs);
133 }
134 
135 const TypeConstraint *
137  assert(isTypeConstraint());
138  auto TPL =
139  TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
140  return cast<TemplateTypeParmDecl>(TPL->getParam(0))
141  ->getTypeConstraint();
142 }
143 
144 RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
145  RequiresExprBodyDecl *Body,
146  ArrayRef<ParmVarDecl *> LocalParameters,
148  SourceLocation RBraceLoc)
149  : Expr(RequiresExprClass, C.BoolTy, VK_RValue, OK_Ordinary),
150  NumLocalParameters(LocalParameters.size()),
151  NumRequirements(Requirements.size()), Body(Body), RBraceLoc(RBraceLoc) {
152  RequiresExprBits.IsSatisfied = false;
153  RequiresExprBits.RequiresKWLoc = RequiresKWLoc;
154  bool Dependent = false;
155  bool ContainsUnexpandedParameterPack = false;
156  for (ParmVarDecl *P : LocalParameters) {
157  Dependent |= P->getType()->isInstantiationDependentType();
158  ContainsUnexpandedParameterPack |=
159  P->getType()->containsUnexpandedParameterPack();
160  }
161  RequiresExprBits.IsSatisfied = true;
162  for (concepts::Requirement *R : Requirements) {
163  Dependent |= R->isDependent();
164  ContainsUnexpandedParameterPack |= R->containsUnexpandedParameterPack();
165  if (!Dependent) {
166  RequiresExprBits.IsSatisfied = R->isSatisfied();
167  if (!RequiresExprBits.IsSatisfied)
168  break;
169  }
170  }
171  std::copy(LocalParameters.begin(), LocalParameters.end(),
172  getTrailingObjects<ParmVarDecl *>());
173  std::copy(Requirements.begin(), Requirements.end(),
174  getTrailingObjects<concepts::Requirement *>());
175  RequiresExprBits.IsSatisfied |= Dependent;
176  // FIXME: move the computing dependency logic to ComputeDependence.h
177  if (ContainsUnexpandedParameterPack)
178  setDependence(getDependence() | ExprDependence::UnexpandedPack);
179  // FIXME: this is incorrect for cases where we have a non-dependent
180  // requirement, but its parameters are instantiation-dependent. RequiresExpr
181  // should be instantiation-dependent if it has instantiation-dependent
182  // parameters.
183  if (Dependent)
184  setDependence(getDependence() | ExprDependence::ValueInstantiation);
185 }
186 
187 RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,
188  unsigned NumLocalParameters,
189  unsigned NumRequirements)
190  : Expr(RequiresExprClass, Empty), NumLocalParameters(NumLocalParameters),
191  NumRequirements(NumRequirements) { }
192 
193 RequiresExpr *
195  RequiresExprBodyDecl *Body,
196  ArrayRef<ParmVarDecl *> LocalParameters,
198  SourceLocation RBraceLoc) {
199  void *Mem =
200  C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
201  LocalParameters.size(), Requirements.size()),
202  alignof(RequiresExpr));
203  return new (Mem) RequiresExpr(C, RequiresKWLoc, Body, LocalParameters,
204  Requirements, RBraceLoc);
205 }
206 
207 RequiresExpr *
209  unsigned NumLocalParameters, unsigned NumRequirements) {
210  void *Mem =
211  C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
212  NumLocalParameters, NumRequirements),
213  alignof(RequiresExpr));
214  return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);
215 }
ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, ArrayRef< TemplateArgument > ConvertedArgs, const ConstraintSatisfaction *Satisfaction)
Defines the clang::ASTContext interface.
ExprDependence computeDependence(FullExpr *E)
C Language Family Type Representation.
Defines the C++ template declaration subclasses.
StringRef P
static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, ArrayRef< ParmVarDecl *> LocalParameters, ArrayRef< concepts::Requirement *> Requirements, SourceLocation RBraceLoc)
ASTConstraintSatisfaction * Satisfaction
Information about the satisfaction of the named concept with the given arguments. ...
Definition: ExprConcepts.h:56
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:605
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:69
Represents a parameter to a function.
Definition: Decl.h:1595
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:471
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:174
A C++ nested-name-specifier augmented with source location information.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:127
unsigned NumTemplateArgs
The number of template arguments in the tail-allocated list of converted template arguments...
Definition: ExprConcepts.h:51
An ordinary object is located at an address in memory.
Definition: Specifiers.h:143
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
Expr()=delete
void setDependence(ExprDependence Deps)
Each concrete expr subclass is expected to compute its dependence and call this in the constructor...
Definition: Expr.h:135
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:29
This represents one expression.
Definition: Expr.h:110
Represents the body of a requires-expression.
Definition: DeclCXX.h:1938
NestedNameSpecifierLoc NestedNameSpec
Definition: ASTConcept.h:103
NamedDecl * FoundDecl
The declaration found by name lookup when the expression was created.
Definition: ASTConcept.h:116
SourceLocation TemplateKWLoc
The location of the template keyword, if specified when naming the concept.
Definition: ASTConcept.h:107
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on...
Definition: Expr.h:215
Encodes a location in the source.
Common data class for constructs that reference concepts with template arguments. ...
Definition: ASTConcept.h:100
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:169
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:145
static ConceptSpecializationExpr * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten, ArrayRef< TemplateArgument > ConvertedArgs, const ConstraintSatisfaction *Satisfaction)
A placeholder type used to construct an empty shell of a type, that will be filled in later (e...
Definition: Stmt.h:1096
ExprDependence getDependence() const
Definition: Expr.h:156
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:626
Dataflow Directional Tag Classes.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
RequiresExprBitfields RequiresExprBits
Definition: Stmt.h:1062
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:77
ConceptDecl * NamedConcept
The concept named.
Definition: ASTConcept.h:119
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
Set new template arguments for this concept specialization.
Defines the clang::SourceLocation class and associated facilities.
Defines Expressions and AST nodes for C++2a concepts.
Represents the specialization of a concept - evaluates to a prvalue of type bool. ...
Definition: ExprConcepts.h:40
const ASTTemplateArgumentListInfo * ArgsAsWritten
The template argument list source info used to specialize the concept.
Definition: ASTConcept.h:123
This represents a decl that may have a name.
Definition: Decl.h:223
CanQualType BoolTy
Definition: ASTContext.h:943
This file provides AST data structures related to concepts.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.