Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/ExprConcepts.cpp
Line
Count
Source
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
672
                   nullptr) {
48
672
  setTemplateArguments(ConvertedArgs);
49
672
  bool IsInstantiationDependent = false;
50
672
  bool ContainsUnexpandedParameterPack = false;
51
963
  for (const TemplateArgumentLoc& ArgLoc : ArgsAsWritten->arguments()) {
52
963
    if (ArgLoc.getArgument().isInstantiationDependent())
53
265
      IsInstantiationDependent = true;
54
963
    if (ArgLoc.getArgument().containsUnexpandedParameterPack())
55
23
      ContainsUnexpandedParameterPack = true;
56
963
    if (ContainsUnexpandedParameterPack && 
IsInstantiationDependent23
)
57
23
      break;
58
963
  }
59
672
60
672
  // Currently guaranteed by the fact concepts can only be at namespace-scope.
61
672
  assert(!NestedNameSpec ||
62
672
         (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() &&
63
672
          !NestedNameSpec.getNestedNameSpecifier()
64
672
              ->containsUnexpandedParameterPack()));
65
672
  setInstantiationDependent(IsInstantiationDependent);
66
672
  setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack);
67
672
  assert((!isValueDependent() || isInstantiationDependent()) &&
68
672
         "should not be value-dependent");
69
672
}
70
71
ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty,
72
    unsigned NumTemplateArgs)
73
    : Expr(ConceptSpecializationExprClass, Empty), ConceptReference(),
74
5
      NumTemplateArgs(NumTemplateArgs) { }
75
76
void ConceptSpecializationExpr::setTemplateArguments(
77
678
    ArrayRef<TemplateArgument> Converted) {
78
678
  assert(Converted.size() == NumTemplateArgs);
79
678
  std::uninitialized_copy(Converted.begin(), Converted.end(),
80
678
                          getTrailingObjects<TemplateArgument>());
81
678
}
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
672
                                  const ConstraintSatisfaction *Satisfaction) {
93
672
  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
94
672
                                ConvertedArgs.size()));
95
672
  return new (Buffer) ConceptSpecializationExpr(C, NNS, TemplateKWLoc,
96
672
                                                ConceptNameInfo, FoundDecl,
97
672
                                                NamedConcept, ArgsAsWritten,
98
672
                                                ConvertedArgs, Satisfaction);
99
672
}
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
1
                   nullptr) {
117
1
  setTemplateArguments(ConvertedArgs);
118
1
}
119
120
ConceptSpecializationExpr *
121
ConceptSpecializationExpr::Create(const ASTContext &C,
122
                                  ConceptDecl *NamedConcept,
123
                                  ArrayRef<TemplateArgument> ConvertedArgs,
124
                                  const ConstraintSatisfaction *Satisfaction,
125
                                  bool Dependent,
126
1
                                  bool ContainsUnexpandedParameterPack) {
127
1
  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
128
1
                                ConvertedArgs.size()));
129
1
  return new (Buffer) ConceptSpecializationExpr(
130
1
      C, NamedConcept, ConvertedArgs, Satisfaction, Dependent,
131
1
      ContainsUnexpandedParameterPack);
132
1
}
133
134
ConceptSpecializationExpr *
135
ConceptSpecializationExpr::Create(ASTContext &C, EmptyShell Empty,
136
5
                                  unsigned NumTemplateArgs) {
137
5
  void *Buffer = C.Allocate(totalSizeToAlloc<TemplateArgument>(
138
5
                                NumTemplateArgs));
139
5
  return new (Buffer) ConceptSpecializationExpr(Empty, NumTemplateArgs);
140
5
}
141
142
const TypeConstraint *
143
22
concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
144
22
  assert(isTypeConstraint());
145
22
  auto TPL =
146
22
      TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
147
22
  return cast<TemplateTypeParmDecl>(TPL->getParam(0))
148
22
      ->getTypeConstraint();
149
22
}
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
318
    NumRequirements(Requirements.size()), Body(Body), RBraceLoc(RBraceLoc) {
161
318
  RequiresExprBits.IsSatisfied = false;
162
318
  RequiresExprBits.RequiresKWLoc = RequiresKWLoc;
163
318
  bool Dependent = false;
164
318
  bool ContainsUnexpandedParameterPack = false;
165
318
  for (ParmVarDecl *P : LocalParameters) {
166
159
    Dependent |= P->getType()->isInstantiationDependentType();
167
159
    ContainsUnexpandedParameterPack |=
168
159
        P->getType()->containsUnexpandedParameterPack();
169
159
  }
170
318
  RequiresExprBits.IsSatisfied = true;
171
369
  for (concepts::Requirement *R : Requirements) {
172
369
    Dependent |= R->isDependent();
173
369
    ContainsUnexpandedParameterPack |= R->containsUnexpandedParameterPack();
174
369
    if (!Dependent) {
175
248
      RequiresExprBits.IsSatisfied = R->isSatisfied();
176
248
      if (!RequiresExprBits.IsSatisfied)
177
91
        break;
178
248
    }
179
369
  }
180
318
  std::copy(LocalParameters.begin(), LocalParameters.end(),
181
318
            getTrailingObjects<ParmVarDecl *>());
182
318
  std::copy(Requirements.begin(), Requirements.end(),
183
318
            getTrailingObjects<concepts::Requirement *>());
184
318
  RequiresExprBits.IsSatisfied |= Dependent;
185
318
  setValueDependent(Dependent);
186
318
  setInstantiationDependent(Dependent);
187
318
  setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack);
188
318
}
189
190
RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty,
191
                           unsigned NumLocalParameters,
192
                           unsigned NumRequirements)
193
  : Expr(RequiresExprClass, Empty), NumLocalParameters(NumLocalParameters),
194
1
    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
318
                     SourceLocation RBraceLoc) {
202
318
  void *Mem =
203
318
      C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
204
318
                     LocalParameters.size(), Requirements.size()),
205
318
                 alignof(RequiresExpr));
206
318
  return new (Mem) RequiresExpr(C, RequiresKWLoc, Body, LocalParameters,
207
318
                                Requirements, RBraceLoc);
208
318
}
209
210
RequiresExpr *
211
RequiresExpr::Create(ASTContext &C, EmptyShell Empty,
212
1
                     unsigned NumLocalParameters, unsigned NumRequirements) {
213
1
  void *Mem =
214
1
      C.Allocate(totalSizeToAlloc<ParmVarDecl *, concepts::Requirement *>(
215
1
                     NumLocalParameters, NumRequirements),
216
1
                 alignof(RequiresExpr));
217
1
  return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);
218
1
}