]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - clang/lib/AST/ExprConcepts.cpp
Vendor import of llvm-project branch release/10.x
[FreeBSD/FreeBSD.git] / clang / lib / AST / ExprConcepts.cpp
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/ASTContext.h"
15 #include "clang/AST/ASTConcept.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/NestedNameSpecifier.h"
21 #include "clang/AST/TemplateBase.h"
22 #include "clang/AST/Type.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "llvm/Support/TrailingObjects.h"
25 #include <algorithm>
26 #include <utility>
27 #include <string>
28
29 using namespace clang;
30
31 ConceptSpecializationExpr::ConceptSpecializationExpr(const ASTContext &C,
32     NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
33     DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
34     ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten,
35     ArrayRef<TemplateArgument> ConvertedArgs,
36     const ConstraintSatisfaction *Satisfaction)
37     : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
38            /*TypeDependent=*/false,
39            // All the flags below are set in setTemplateArguments.
40            /*ValueDependent=*/!Satisfaction, /*InstantiationDependent=*/false,
41            /*ContainsUnexpandedParameterPacks=*/false),
42       ConceptReference(NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl,
43                        NamedConcept, ArgsAsWritten),
44       NumTemplateArgs(ConvertedArgs.size()),
45       Satisfaction(Satisfaction ?
46                    ASTConstraintSatisfaction::Create(C, *Satisfaction) :
47                    nullptr) {
48   setTemplateArguments(ConvertedArgs);
49   bool IsInstantiationDependent = false;
50   bool ContainsUnexpandedParameterPack = false;
51   for (const TemplateArgumentLoc& ArgLoc : ArgsAsWritten->arguments()) {
52     if (ArgLoc.getArgument().isInstantiationDependent())
53       IsInstantiationDependent = true;
54     if (ArgLoc.getArgument().containsUnexpandedParameterPack())
55       ContainsUnexpandedParameterPack = true;
56     if (ContainsUnexpandedParameterPack && IsInstantiationDependent)
57       break;
58   }
59
60   // Currently guaranteed by the fact concepts can only be at namespace-scope.
61   assert(!NestedNameSpec ||
62          (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() &&
63           !NestedNameSpec.getNestedNameSpecifier()
64               ->containsUnexpandedParameterPack()));
65   setInstantiationDependent(IsInstantiationDependent);
66   setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack);
67   assert((!isValueDependent() || isInstantiationDependent()) &&
68          "should not be value-dependent");
69 }
70
71 ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty,
72     unsigned NumTemplateArgs)
73     : Expr(ConceptSpecializationExprClass, Empty), ConceptReference(),
74       NumTemplateArgs(NumTemplateArgs) { }
75
76 void ConceptSpecializationExpr::setTemplateArguments(
77     ArrayRef<TemplateArgument> Converted) {
78   assert(Converted.size() == NumTemplateArgs);
79   std::uninitialized_copy(Converted.begin(), Converted.end(),
80                           getTrailingObjects<TemplateArgument>());
81 }
82
83 ConceptSpecializationExpr *
84 ConceptSpecializationExpr::Create(const ASTContext &C,
85                                   NestedNameSpecifierLoc NNS,
86                                   SourceLocation TemplateKWLoc,
87                                   DeclarationNameInfo ConceptNameInfo,
88                                   NamedDecl *FoundDecl,
89                                   ConceptDecl *NamedConcept,
90                                const ASTTemplateArgumentListInfo *ArgsAsWritten,
91                                   ArrayRef<TemplateArgument> ConvertedArgs,
92                                   const ConstraintSatisfaction *Satisfaction) {
93   void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
94                                 ConvertedArgs.size()));
95   return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc,
96                                                 ConceptNameInfo, FoundDecl,
97                                                 NamedConcept, ArgsAsWritten,
98                                                 ConvertedArgs, Satisfaction);
99 }
100
101 ConceptSpecializationExpr::ConceptSpecializationExpr(
102     const ASTContext &C, ConceptDecl *NamedConcept,
103     ArrayRef<TemplateArgument> ConvertedArgs,
104     const ConstraintSatisfaction *Satisfaction, bool Dependent,
105     bool ContainsUnexpandedParameterPack)
106     : Expr(ConceptSpecializationExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
107            /*TypeDependent=*/false,
108            /*ValueDependent=*/!Satisfaction, Dependent,
109            ContainsUnexpandedParameterPack),
110       ConceptReference(NestedNameSpecifierLoc(), SourceLocation(),
111                        DeclarationNameInfo(), NamedConcept,
112                        NamedConcept, nullptr),
113       NumTemplateArgs(ConvertedArgs.size()),
114       Satisfaction(Satisfaction ?
115                    ASTConstraintSatisfaction::Create(C, *Satisfaction) :
116                    nullptr) {
117   setTemplateArguments(ConvertedArgs);
118 }
119
120 ConceptSpecializationExpr *
121 ConceptSpecializationExpr::Create(const ASTContext &C,
122                                   ConceptDecl *NamedConcept,
123                                   ArrayRef<TemplateArgument> ConvertedArgs,
124                                   const ConstraintSatisfaction *Satisfaction,
125                                   bool Dependent,
126                                   bool ContainsUnexpandedParameterPack) {
127   void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
128                                 ConvertedArgs.size()));
129   return new (Buffer) ConceptSpecializationExpr(
130       C, NamedConcept, ConvertedArgs, Satisfaction, Dependent,
131       ContainsUnexpandedParameterPack);
132 }
133
134 ConceptSpecializationExpr *
135 ConceptSpecializationExpr::Create(ASTContext &C, EmptyShell Empty,
136                                   unsigned NumTemplateArgs) {
137   void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
138                                 NumTemplateArgs));
139   return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs);
140 }
141
142 const TypeConstraint *
143 concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
144   assert(isTypeConstraint());
145   auto TPL =
146       TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
147   return cast<TemplateTypeParmDecl>(TPL->getParam(0))
148       ->getTypeConstraint();
149 }
150
151 RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
152                            RequiresExprBodyDecl *Body,
153                            ArrayRef<ParmVarDecl *> LocalParameters,
154                            ArrayRef<concepts::Requirement *> Requirements,
155                            SourceLocation RBraceLoc)
156   : Expr(RequiresExprClass, C.BoolTy, VK_RValue, OK_Ordinary,
157          /*TD=*/false, /*VD=*/false, /*ID=*/false,
158          /*ContainsUnexpandedParameterPack=*/false),
159     NumLocalParameters(LocalParameters.size()),
160     NumRequirements(Requirements.size()), Body(Body), RBraceLoc(RBraceLoc) {
161   RequiresExprBits.IsSatisfied = false;
162   RequiresExprBits.RequiresKWLoc = RequiresKWLoc;
163   bool Dependent = false;
164   bool ContainsUnexpandedParameterPack = false;
165   for (ParmVarDecl *P : LocalParameters) {
166     Dependent |= P->getType()->isInstantiationDependentType();
167     ContainsUnexpandedParameterPack |=
168         P->getType()->containsUnexpandedParameterPack();
169   }
170   RequiresExprBits.IsSatisfied = true;
171   for (concepts::Requirement *R : Requirements) {
172     Dependent |= R->isDependent();
173     ContainsUnexpandedParameterPack |= R->containsUnexpandedParameterPack();
174     if (!Dependent) {
175       RequiresExprBits.IsSatisfied = R->isSatisfied();
176       if (!RequiresExprBits.IsSatisfied)
177         break;
178     }
179   }
180   std::copy(LocalParameters.begin(), LocalParameters.end(),
181             getTrailingObjects<ParmVarDecl *>());
182   std::copy(Requirements.begin(), Requirements.end(),
183             getTrailingObjects<concepts::Requirement *>());
184   RequiresExprBits.IsSatisfied |= Dependent;
185   setValueDependent(Dependent);
186   setInstantiationDependent(Dependent);
187   setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack);
188 }
189
190 RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,
191                            unsigned NumLocalParameters,
192                            unsigned NumRequirements)
193   : Expr(RequiresExprClass, Empty), NumLocalParameters(NumLocalParameters),
194     NumRequirements(NumRequirements) { }
195
196 RequiresExpr *
197 RequiresExpr::Create(ASTContext &C, SourceLocation RequiresKWLoc,
198                      RequiresExprBodyDecl *Body,
199                      ArrayRef<ParmVarDecl *> LocalParameters,
200                      ArrayRef<concepts::Requirement *> Requirements,
201                      SourceLocation RBraceLoc) {
202   void *Mem =
203       C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
204                      LocalParameters.size(), Requirements.size()),
205                  alignof(RequiresExpr));
206   return new (Mem) RequiresExpr(C, RequiresKWLoc, Body, LocalParameters,
207                                 Requirements, RBraceLoc);
208 }
209
210 RequiresExpr *
211 RequiresExpr::Create(ASTContext &C, EmptyShell Empty,
212                      unsigned NumLocalParameters, unsigned NumRequirements) {
213   void *Mem =
214       C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
215                      NumLocalParameters, NumRequirements),
216                  alignof(RequiresExpr));
217   return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);
218 }