1 //===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
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 // This file implements a semantic tree transformation that takes a given
9 // AST and rebuilds it, possibly transforming some nodes in the process.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14 #define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
16 #include "CoroutineStmtBuilder.h"
17 #include "TypeLocBuilder.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/Expr.h"
22 #include "clang/AST/ExprCXX.h"
23 #include "clang/AST/ExprConcepts.h"
24 #include "clang/AST/ExprObjC.h"
25 #include "clang/AST/ExprOpenMP.h"
26 #include "clang/AST/OpenMPClause.h"
27 #include "clang/AST/Stmt.h"
28 #include "clang/AST/StmtCXX.h"
29 #include "clang/AST/StmtObjC.h"
30 #include "clang/AST/StmtOpenACC.h"
31 #include "clang/AST/StmtOpenMP.h"
32 #include "clang/AST/StmtSYCL.h"
33 #include "clang/Basic/DiagnosticParse.h"
34 #include "clang/Basic/OpenMPKinds.h"
35 #include "clang/Sema/Designator.h"
36 #include "clang/Sema/EnterExpressionEvaluationContext.h"
37 #include "clang/Sema/Lookup.h"
38 #include "clang/Sema/Ownership.h"
39 #include "clang/Sema/ParsedTemplate.h"
40 #include "clang/Sema/ScopeInfo.h"
41 #include "clang/Sema/SemaDiagnostic.h"
42 #include "clang/Sema/SemaInternal.h"
43 #include "clang/Sema/SemaObjC.h"
44 #include "clang/Sema/SemaOpenACC.h"
45 #include "clang/Sema/SemaOpenMP.h"
46 #include "clang/Sema/SemaPseudoObject.h"
47 #include "clang/Sema/SemaSYCL.h"
48 #include "llvm/ADT/ArrayRef.h"
49 #include "llvm/Support/ErrorHandling.h"
50 #include <algorithm>
51 #include <optional>
52
53 using namespace llvm::omp;
54
55 namespace clang {
56 using namespace sema;
57
58 /// A semantic tree transformation that allows one to transform one
59 /// abstract syntax tree into another.
60 ///
61 /// A new tree transformation is defined by creating a new subclass \c X of
62 /// \c TreeTransform<X> and then overriding certain operations to provide
63 /// behavior specific to that transformation. For example, template
64 /// instantiation is implemented as a tree transformation where the
65 /// transformation of TemplateTypeParmType nodes involves substituting the
66 /// template arguments for their corresponding template parameters; a similar
67 /// transformation is performed for non-type template parameters and
68 /// template template parameters.
69 ///
70 /// This tree-transformation template uses static polymorphism to allow
71 /// subclasses to customize any of its operations. Thus, a subclass can
72 /// override any of the transformation or rebuild operators by providing an
73 /// operation with the same signature as the default implementation. The
74 /// overriding function should not be virtual.
75 ///
76 /// Semantic tree transformations are split into two stages, either of which
77 /// can be replaced by a subclass. The "transform" step transforms an AST node
78 /// or the parts of an AST node using the various transformation functions,
79 /// then passes the pieces on to the "rebuild" step, which constructs a new AST
80 /// node of the appropriate kind from the pieces. The default transformation
81 /// routines recursively transform the operands to composite AST nodes (e.g.,
82 /// the pointee type of a PointerType node) and, if any of those operand nodes
83 /// were changed by the transformation, invokes the rebuild operation to create
84 /// a new AST node.
85 ///
86 /// Subclasses can customize the transformation at various levels. The
87 /// most coarse-grained transformations involve replacing TransformType(),
88 /// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
89 /// TransformTemplateName(), or TransformTemplateArgument() with entirely
90 /// new implementations.
91 ///
92 /// For more fine-grained transformations, subclasses can replace any of the
93 /// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
94 /// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
95 /// replacing TransformTemplateTypeParmType() allows template instantiation
96 /// to substitute template arguments for their corresponding template
97 /// parameters. Additionally, subclasses can override the \c RebuildXXX
98 /// functions to control how AST nodes are rebuilt when their operands change.
99 /// By default, \c TreeTransform will invoke semantic analysis to rebuild
100 /// AST nodes. However, certain other tree transformations (e.g, cloning) may
101 /// be able to use more efficient rebuild steps.
102 ///
103 /// There are a handful of other functions that can be overridden, allowing one
104 /// to avoid traversing nodes that don't need any transformation
105 /// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
106 /// operands have not changed (\c AlwaysRebuild()), and customize the
107 /// default locations and entity names used for type-checking
108 /// (\c getBaseLocation(), \c getBaseEntity()).
109 template<typename Derived>
110 class TreeTransform {
111 /// Private RAII object that helps us forget and then re-remember
112 /// the template argument corresponding to a partially-substituted parameter
113 /// pack.
114 class ForgetPartiallySubstitutedPackRAII {
115 Derived &Self;
116 TemplateArgument Old;
117 // Set the pack expansion index to -1 to avoid pack substitution and
118 // indicate that parameter packs should be instantiated as themselves.
119 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
120
121 public:
ForgetPartiallySubstitutedPackRAII(Derived & Self)122 ForgetPartiallySubstitutedPackRAII(Derived &Self)
123 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
124 Old = Self.ForgetPartiallySubstitutedPack();
125 }
126
~ForgetPartiallySubstitutedPackRAII()127 ~ForgetPartiallySubstitutedPackRAII() {
128 Self.RememberPartiallySubstitutedPack(Old);
129 }
130 };
131
132 protected:
133 Sema &SemaRef;
134
135 /// The set of local declarations that have been transformed, for
136 /// cases where we are forced to build new declarations within the transformer
137 /// rather than in the subclass (e.g., lambda closure types).
138 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
139
140 public:
141 /// Initializes a new tree transformer.
TreeTransform(Sema & SemaRef)142 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
143
144 /// Retrieves a reference to the derived class.
getDerived()145 Derived &getDerived() { return static_cast<Derived&>(*this); }
146
147 /// Retrieves a reference to the derived class.
getDerived()148 const Derived &getDerived() const {
149 return static_cast<const Derived&>(*this);
150 }
151
Owned(Expr * E)152 static inline ExprResult Owned(Expr *E) { return E; }
Owned(Stmt * S)153 static inline StmtResult Owned(Stmt *S) { return S; }
154
155 /// Retrieves a reference to the semantic analysis object used for
156 /// this tree transform.
getSema()157 Sema &getSema() const { return SemaRef; }
158
159 /// Whether the transformation should always rebuild AST nodes, even
160 /// if none of the children have changed.
161 ///
162 /// Subclasses may override this function to specify when the transformation
163 /// should rebuild all AST nodes.
164 ///
165 /// We must always rebuild all AST nodes when performing variadic template
166 /// pack expansion, in order to avoid violating the AST invariant that each
167 /// statement node appears at most once in its containing declaration.
AlwaysRebuild()168 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
169
170 /// Whether the transformation is forming an expression or statement that
171 /// replaces the original. In this case, we'll reuse mangling numbers from
172 /// existing lambdas.
ReplacingOriginal()173 bool ReplacingOriginal() { return false; }
174
175 /// Wether CXXConstructExpr can be skipped when they are implicit.
176 /// They will be reconstructed when used if needed.
177 /// This is useful when the user that cause rebuilding of the
178 /// CXXConstructExpr is outside of the expression at which the TreeTransform
179 /// started.
AllowSkippingCXXConstructExpr()180 bool AllowSkippingCXXConstructExpr() { return true; }
181
182 /// Returns the location of the entity being transformed, if that
183 /// information was not available elsewhere in the AST.
184 ///
185 /// By default, returns no source-location information. Subclasses can
186 /// provide an alternative implementation that provides better location
187 /// information.
getBaseLocation()188 SourceLocation getBaseLocation() { return SourceLocation(); }
189
190 /// Returns the name of the entity being transformed, if that
191 /// information was not available elsewhere in the AST.
192 ///
193 /// By default, returns an empty name. Subclasses can provide an alternative
194 /// implementation with a more precise name.
getBaseEntity()195 DeclarationName getBaseEntity() { return DeclarationName(); }
196
197 /// Sets the "base" location and entity when that
198 /// information is known based on another transformation.
199 ///
200 /// By default, the source location and entity are ignored. Subclasses can
201 /// override this function to provide a customized implementation.
setBase(SourceLocation Loc,DeclarationName Entity)202 void setBase(SourceLocation Loc, DeclarationName Entity) { }
203
204 /// RAII object that temporarily sets the base location and entity
205 /// used for reporting diagnostics in types.
206 class TemporaryBase {
207 TreeTransform &Self;
208 SourceLocation OldLocation;
209 DeclarationName OldEntity;
210
211 public:
TemporaryBase(TreeTransform & Self,SourceLocation Location,DeclarationName Entity)212 TemporaryBase(TreeTransform &Self, SourceLocation Location,
213 DeclarationName Entity) : Self(Self) {
214 OldLocation = Self.getDerived().getBaseLocation();
215 OldEntity = Self.getDerived().getBaseEntity();
216
217 if (Location.isValid())
218 Self.getDerived().setBase(Location, Entity);
219 }
220
~TemporaryBase()221 ~TemporaryBase() {
222 Self.getDerived().setBase(OldLocation, OldEntity);
223 }
224 };
225
226 /// Determine whether the given type \p T has already been
227 /// transformed.
228 ///
229 /// Subclasses can provide an alternative implementation of this routine
230 /// to short-circuit evaluation when it is known that a given type will
231 /// not change. For example, template instantiation need not traverse
232 /// non-dependent types.
AlreadyTransformed(QualType T)233 bool AlreadyTransformed(QualType T) {
234 return T.isNull();
235 }
236
237 /// Transform a template parameter depth level.
238 ///
239 /// During a transformation that transforms template parameters, this maps
240 /// an old template parameter depth to a new depth.
TransformTemplateDepth(unsigned Depth)241 unsigned TransformTemplateDepth(unsigned Depth) {
242 return Depth;
243 }
244
245 /// Determine whether the given call argument should be dropped, e.g.,
246 /// because it is a default argument.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine to
249 /// determine which kinds of call arguments get dropped. By default,
250 /// CXXDefaultArgument nodes are dropped (prior to transformation).
DropCallArgument(Expr * E)251 bool DropCallArgument(Expr *E) {
252 return E->isDefaultArgument();
253 }
254
255 /// Determine whether we should expand a pack expansion with the
256 /// given set of parameter packs into separate arguments by repeatedly
257 /// transforming the pattern.
258 ///
259 /// By default, the transformer never tries to expand pack expansions.
260 /// Subclasses can override this routine to provide different behavior.
261 ///
262 /// \param EllipsisLoc The location of the ellipsis that identifies the
263 /// pack expansion.
264 ///
265 /// \param PatternRange The source range that covers the entire pattern of
266 /// the pack expansion.
267 ///
268 /// \param Unexpanded The set of unexpanded parameter packs within the
269 /// pattern.
270 ///
271 /// \param ShouldExpand Will be set to \c true if the transformer should
272 /// expand the corresponding pack expansions into separate arguments. When
273 /// set, \c NumExpansions must also be set.
274 ///
275 /// \param RetainExpansion Whether the caller should add an unexpanded
276 /// pack expansion after all of the expanded arguments. This is used
277 /// when extending explicitly-specified template argument packs per
278 /// C++0x [temp.arg.explicit]p9.
279 ///
280 /// \param NumExpansions The number of separate arguments that will be in
281 /// the expanded form of the corresponding pack expansion. This is both an
282 /// input and an output parameter, which can be set by the caller if the
283 /// number of expansions is known a priori (e.g., due to a prior substitution)
284 /// and will be set by the callee when the number of expansions is known.
285 /// The callee must set this value when \c ShouldExpand is \c true; it may
286 /// set this value in other cases.
287 ///
288 /// \returns true if an error occurred (e.g., because the parameter packs
289 /// are to be instantiated with arguments of different lengths), false
290 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
291 /// must be set.
TryExpandParameterPacks(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,bool & ShouldExpand,bool & RetainExpansion,UnsignedOrNone & NumExpansions)292 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
293 SourceRange PatternRange,
294 ArrayRef<UnexpandedParameterPack> Unexpanded,
295 bool &ShouldExpand, bool &RetainExpansion,
296 UnsignedOrNone &NumExpansions) {
297 ShouldExpand = false;
298 return false;
299 }
300
301 /// "Forget" about the partially-substituted pack template argument,
302 /// when performing an instantiation that must preserve the parameter pack
303 /// use.
304 ///
305 /// This routine is meant to be overridden by the template instantiator.
ForgetPartiallySubstitutedPack()306 TemplateArgument ForgetPartiallySubstitutedPack() {
307 return TemplateArgument();
308 }
309
310 /// "Remember" the partially-substituted pack template argument
311 /// after performing an instantiation that must preserve the parameter pack
312 /// use.
313 ///
314 /// This routine is meant to be overridden by the template instantiator.
RememberPartiallySubstitutedPack(TemplateArgument Arg)315 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
316
317 /// Note to the derived class when a function parameter pack is
318 /// being expanded.
ExpandingFunctionParameterPack(ParmVarDecl * Pack)319 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
320
321 /// Transforms the given type into another type.
322 ///
323 /// By default, this routine transforms a type by creating a
324 /// TypeSourceInfo for it and delegating to the appropriate
325 /// function. This is expensive, but we don't mind, because
326 /// this method is deprecated anyway; all users should be
327 /// switched to storing TypeSourceInfos.
328 ///
329 /// \returns the transformed type.
330 QualType TransformType(QualType T);
331
332 /// Transforms the given type-with-location into a new
333 /// type-with-location.
334 ///
335 /// By default, this routine transforms a type by delegating to the
336 /// appropriate TransformXXXType to build a new type. Subclasses
337 /// may override this function (to take over all type
338 /// transformations) or some set of the TransformXXXType functions
339 /// to alter the transformation.
340 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
341
342 /// Transform the given type-with-location into a new
343 /// type, collecting location information in the given builder
344 /// as necessary.
345 ///
346 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
347
348 /// Transform a type that is permitted to produce a
349 /// DeducedTemplateSpecializationType.
350 ///
351 /// This is used in the (relatively rare) contexts where it is acceptable
352 /// for transformation to produce a class template type with deduced
353 /// template arguments.
354 /// @{
355 QualType TransformTypeWithDeducedTST(QualType T);
356 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
357 /// @}
358
359 /// The reason why the value of a statement is not discarded, if any.
360 enum class StmtDiscardKind {
361 Discarded,
362 NotDiscarded,
363 StmtExprResult,
364 };
365
366 /// Transform the given statement.
367 ///
368 /// By default, this routine transforms a statement by delegating to the
369 /// appropriate TransformXXXStmt function to transform a specific kind of
370 /// statement or the TransformExpr() function to transform an expression.
371 /// Subclasses may override this function to transform statements using some
372 /// other mechanism.
373 ///
374 /// \returns the transformed statement.
375 StmtResult TransformStmt(Stmt *S,
376 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
377
378 /// Transform the given statement.
379 ///
380 /// By default, this routine transforms a statement by delegating to the
381 /// appropriate TransformOMPXXXClause function to transform a specific kind
382 /// of clause. Subclasses may override this function to transform statements
383 /// using some other mechanism.
384 ///
385 /// \returns the transformed OpenMP clause.
386 OMPClause *TransformOMPClause(OMPClause *S);
387
388 /// Transform the given attribute.
389 ///
390 /// By default, this routine transforms a statement by delegating to the
391 /// appropriate TransformXXXAttr function to transform a specific kind
392 /// of attribute. Subclasses may override this function to transform
393 /// attributed statements/types using some other mechanism.
394 ///
395 /// \returns the transformed attribute
396 const Attr *TransformAttr(const Attr *S);
397
398 // Transform the given statement attribute.
399 //
400 // Delegates to the appropriate TransformXXXAttr function to transform a
401 // specific kind of statement attribute. Unlike the non-statement taking
402 // version of this, this implements all attributes, not just pragmas.
403 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
404 const Attr *A);
405
406 // Transform the specified attribute.
407 //
408 // Subclasses should override the transformation of attributes with a pragma
409 // spelling to transform expressions stored within the attribute.
410 //
411 // \returns the transformed attribute.
412 #define ATTR(X) \
413 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
414 #include "clang/Basic/AttrList.inc"
415
416 // Transform the specified attribute.
417 //
418 // Subclasses should override the transformation of attributes to do
419 // transformation and checking of statement attributes. By default, this
420 // delegates to the non-statement taking version.
421 //
422 // \returns the transformed attribute.
423 #define ATTR(X) \
424 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
425 const X##Attr *A) { \
426 return getDerived().Transform##X##Attr(A); \
427 }
428 #include "clang/Basic/AttrList.inc"
429
430 /// Transform the given expression.
431 ///
432 /// By default, this routine transforms an expression by delegating to the
433 /// appropriate TransformXXXExpr function to build a new expression.
434 /// Subclasses may override this function to transform expressions using some
435 /// other mechanism.
436 ///
437 /// \returns the transformed expression.
438 ExprResult TransformExpr(Expr *E);
439
440 /// Transform the given initializer.
441 ///
442 /// By default, this routine transforms an initializer by stripping off the
443 /// semantic nodes added by initialization, then passing the result to
444 /// TransformExpr or TransformExprs.
445 ///
446 /// \returns the transformed initializer.
447 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
448
449 /// Transform the given list of expressions.
450 ///
451 /// This routine transforms a list of expressions by invoking
452 /// \c TransformExpr() for each subexpression. However, it also provides
453 /// support for variadic templates by expanding any pack expansions (if the
454 /// derived class permits such expansion) along the way. When pack expansions
455 /// are present, the number of outputs may not equal the number of inputs.
456 ///
457 /// \param Inputs The set of expressions to be transformed.
458 ///
459 /// \param NumInputs The number of expressions in \c Inputs.
460 ///
461 /// \param IsCall If \c true, then this transform is being performed on
462 /// function-call arguments, and any arguments that should be dropped, will
463 /// be.
464 ///
465 /// \param Outputs The transformed input expressions will be added to this
466 /// vector.
467 ///
468 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
469 /// due to transformation.
470 ///
471 /// \returns true if an error occurred, false otherwise.
472 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
473 SmallVectorImpl<Expr *> &Outputs,
474 bool *ArgChanged = nullptr);
475
476 /// Transform the given declaration, which is referenced from a type
477 /// or expression.
478 ///
479 /// By default, acts as the identity function on declarations, unless the
480 /// transformer has had to transform the declaration itself. Subclasses
481 /// may override this function to provide alternate behavior.
TransformDecl(SourceLocation Loc,Decl * D)482 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
483 llvm::DenseMap<Decl *, Decl *>::iterator Known
484 = TransformedLocalDecls.find(D);
485 if (Known != TransformedLocalDecls.end())
486 return Known->second;
487
488 return D;
489 }
490
491 /// Transform the specified condition.
492 ///
493 /// By default, this transforms the variable and expression and rebuilds
494 /// the condition.
495 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
496 Expr *Expr,
497 Sema::ConditionKind Kind);
498
499 /// Transform the attributes associated with the given declaration and
500 /// place them on the new declaration.
501 ///
502 /// By default, this operation does nothing. Subclasses may override this
503 /// behavior to transform attributes.
transformAttrs(Decl * Old,Decl * New)504 void transformAttrs(Decl *Old, Decl *New) { }
505
506 /// Note that a local declaration has been transformed by this
507 /// transformer.
508 ///
509 /// Local declarations are typically transformed via a call to
510 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
511 /// the transformer itself has to transform the declarations. This routine
512 /// can be overridden by a subclass that keeps track of such mappings.
transformedLocalDecl(Decl * Old,ArrayRef<Decl * > New)513 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
514 assert(New.size() == 1 &&
515 "must override transformedLocalDecl if performing pack expansion");
516 TransformedLocalDecls[Old] = New.front();
517 }
518
519 /// Transform the definition of the given declaration.
520 ///
521 /// By default, invokes TransformDecl() to transform the declaration.
522 /// Subclasses may override this function to provide alternate behavior.
TransformDefinition(SourceLocation Loc,Decl * D)523 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
524 return getDerived().TransformDecl(Loc, D);
525 }
526
527 /// Transform the given declaration, which was the first part of a
528 /// nested-name-specifier in a member access expression.
529 ///
530 /// This specific declaration transformation only applies to the first
531 /// identifier in a nested-name-specifier of a member access expression, e.g.,
532 /// the \c T in \c x->T::member
533 ///
534 /// By default, invokes TransformDecl() to transform the declaration.
535 /// Subclasses may override this function to provide alternate behavior.
TransformFirstQualifierInScope(NamedDecl * D,SourceLocation Loc)536 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
537 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
538 }
539
540 /// Transform the set of declarations in an OverloadExpr.
541 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
542 LookupResult &R);
543
544 /// Transform the given nested-name-specifier with source-location
545 /// information.
546 ///
547 /// By default, transforms all of the types and declarations within the
548 /// nested-name-specifier. Subclasses may override this function to provide
549 /// alternate behavior.
550 NestedNameSpecifierLoc
551 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
552 QualType ObjectType = QualType(),
553 NamedDecl *FirstQualifierInScope = nullptr);
554
555 /// Transform the given declaration name.
556 ///
557 /// By default, transforms the types of conversion function, constructor,
558 /// and destructor names and then (if needed) rebuilds the declaration name.
559 /// Identifiers and selectors are returned unmodified. Subclasses may
560 /// override this function to provide alternate behavior.
561 DeclarationNameInfo
562 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
563
564 bool TransformRequiresExprRequirements(
565 ArrayRef<concepts::Requirement *> Reqs,
566 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
567 concepts::TypeRequirement *
568 TransformTypeRequirement(concepts::TypeRequirement *Req);
569 concepts::ExprRequirement *
570 TransformExprRequirement(concepts::ExprRequirement *Req);
571 concepts::NestedRequirement *
572 TransformNestedRequirement(concepts::NestedRequirement *Req);
573
574 /// Transform the given template name.
575 ///
576 /// \param SS The nested-name-specifier that qualifies the template
577 /// name. This nested-name-specifier must already have been transformed.
578 ///
579 /// \param Name The template name to transform.
580 ///
581 /// \param NameLoc The source location of the template name.
582 ///
583 /// \param ObjectType If we're translating a template name within a member
584 /// access expression, this is the type of the object whose member template
585 /// is being referenced.
586 ///
587 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
588 /// also refers to a name within the current (lexical) scope, this is the
589 /// declaration it refers to.
590 ///
591 /// By default, transforms the template name by transforming the declarations
592 /// and nested-name-specifiers that occur within the template name.
593 /// Subclasses may override this function to provide alternate behavior.
594 TemplateName
595 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
596 SourceLocation NameLoc,
597 QualType ObjectType = QualType(),
598 NamedDecl *FirstQualifierInScope = nullptr,
599 bool AllowInjectedClassName = false);
600
601 /// Transform the given template argument.
602 ///
603 /// By default, this operation transforms the type, expression, or
604 /// declaration stored within the template argument and constructs a
605 /// new template argument from the transformed result. Subclasses may
606 /// override this function to provide alternate behavior.
607 ///
608 /// Returns true if there was an error.
609 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
610 TemplateArgumentLoc &Output,
611 bool Uneval = false);
612
613 /// Transform the given set of template arguments.
614 ///
615 /// By default, this operation transforms all of the template arguments
616 /// in the input set using \c TransformTemplateArgument(), and appends
617 /// the transformed arguments to the output list.
618 ///
619 /// Note that this overload of \c TransformTemplateArguments() is merely
620 /// a convenience function. Subclasses that wish to override this behavior
621 /// should override the iterator-based member template version.
622 ///
623 /// \param Inputs The set of template arguments to be transformed.
624 ///
625 /// \param NumInputs The number of template arguments in \p Inputs.
626 ///
627 /// \param Outputs The set of transformed template arguments output by this
628 /// routine.
629 ///
630 /// Returns true if an error occurred.
631 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
632 unsigned NumInputs,
633 TemplateArgumentListInfo &Outputs,
634 bool Uneval = false) {
635 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
636 Uneval);
637 }
638
639 /// Transform the given set of template arguments.
640 ///
641 /// By default, this operation transforms all of the template arguments
642 /// in the input set using \c TransformTemplateArgument(), and appends
643 /// the transformed arguments to the output list.
644 ///
645 /// \param First An iterator to the first template argument.
646 ///
647 /// \param Last An iterator one step past the last template argument.
648 ///
649 /// \param Outputs The set of transformed template arguments output by this
650 /// routine.
651 ///
652 /// Returns true if an error occurred.
653 template<typename InputIterator>
654 bool TransformTemplateArguments(InputIterator First,
655 InputIterator Last,
656 TemplateArgumentListInfo &Outputs,
657 bool Uneval = false);
658
659 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
660 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
661 TemplateArgumentLoc &ArgLoc);
662
663 /// Fakes up a TypeSourceInfo for a type.
InventTypeSourceInfo(QualType T)664 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
665 return SemaRef.Context.getTrivialTypeSourceInfo(T,
666 getDerived().getBaseLocation());
667 }
668
669 #define ABSTRACT_TYPELOC(CLASS, PARENT)
670 #define TYPELOC(CLASS, PARENT) \
671 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
672 #include "clang/AST/TypeLocNodes.def"
673
674 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
675 TemplateTypeParmTypeLoc TL,
676 bool SuppressObjCLifetime);
677 QualType
678 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
679 SubstTemplateTypeParmPackTypeLoc TL,
680 bool SuppressObjCLifetime);
681
682 template<typename Fn>
683 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
684 FunctionProtoTypeLoc TL,
685 CXXRecordDecl *ThisContext,
686 Qualifiers ThisTypeQuals,
687 Fn TransformExceptionSpec);
688
689 bool TransformExceptionSpec(SourceLocation Loc,
690 FunctionProtoType::ExceptionSpecInfo &ESI,
691 SmallVectorImpl<QualType> &Exceptions,
692 bool &Changed);
693
694 StmtResult TransformSEHHandler(Stmt *Handler);
695
696 QualType
697 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
698 TemplateSpecializationTypeLoc TL,
699 TemplateName Template);
700
701 QualType
702 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
703 DependentTemplateSpecializationTypeLoc TL,
704 TemplateName Template,
705 CXXScopeSpec &SS);
706
707 QualType TransformDependentTemplateSpecializationType(
708 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
709 CXXScopeSpec &SS);
710
711 /// Transforms the parameters of a function type into the
712 /// given vectors.
713 ///
714 /// The result vectors should be kept in sync; null entries in the
715 /// variables vector are acceptable.
716 ///
717 /// LastParamTransformed, if non-null, will be set to the index of the last
718 /// parameter on which transformation was started. In the event of an error,
719 /// this will contain the parameter which failed to instantiate.
720 ///
721 /// Return true on error.
722 bool TransformFunctionTypeParams(
723 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
724 const QualType *ParamTypes,
725 const FunctionProtoType::ExtParameterInfo *ParamInfos,
726 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
727 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
728
TransformFunctionTypeParams(SourceLocation Loc,ArrayRef<ParmVarDecl * > Params,const QualType * ParamTypes,const FunctionProtoType::ExtParameterInfo * ParamInfos,SmallVectorImpl<QualType> & PTypes,SmallVectorImpl<ParmVarDecl * > * PVars,Sema::ExtParameterInfoBuilder & PInfos)729 bool TransformFunctionTypeParams(
730 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
731 const QualType *ParamTypes,
732 const FunctionProtoType::ExtParameterInfo *ParamInfos,
733 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
734 Sema::ExtParameterInfoBuilder &PInfos) {
735 return getDerived().TransformFunctionTypeParams(
736 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
737 }
738
739 /// Transforms the parameters of a requires expresison into the given vectors.
740 ///
741 /// The result vectors should be kept in sync; null entries in the
742 /// variables vector are acceptable.
743 ///
744 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
745 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
746 /// which are cases where transformation shouldn't continue.
TransformRequiresTypeParams(SourceLocation KWLoc,SourceLocation RBraceLoc,const RequiresExpr * RE,RequiresExprBodyDecl * Body,ArrayRef<ParmVarDecl * > Params,SmallVectorImpl<QualType> & PTypes,SmallVectorImpl<ParmVarDecl * > & TransParams,Sema::ExtParameterInfoBuilder & PInfos)747 ExprResult TransformRequiresTypeParams(
748 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
749 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
750 SmallVectorImpl<QualType> &PTypes,
751 SmallVectorImpl<ParmVarDecl *> &TransParams,
752 Sema::ExtParameterInfoBuilder &PInfos) {
753 if (getDerived().TransformFunctionTypeParams(
754 KWLoc, Params, /*ParamTypes=*/nullptr,
755 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
756 return ExprError();
757
758 return ExprResult{};
759 }
760
761 /// Transforms a single function-type parameter. Return null
762 /// on error.
763 ///
764 /// \param indexAdjustment - A number to add to the parameter's
765 /// scope index; can be negative
766 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
767 int indexAdjustment,
768 UnsignedOrNone NumExpansions,
769 bool ExpectParameterPack);
770
771 /// Transform the body of a lambda-expression.
772 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
773 /// Alternative implementation of TransformLambdaBody that skips transforming
774 /// the body.
775 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
776
777 CXXRecordDecl::LambdaDependencyKind
ComputeLambdaDependency(LambdaScopeInfo * LSI)778 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
779 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
780 LSI->Lambda->getLambdaDependencyKind());
781 }
782
783 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
784
785 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
786 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
787
TransformTemplateParameterList(TemplateParameterList * TPL)788 TemplateParameterList *TransformTemplateParameterList(
789 TemplateParameterList *TPL) {
790 return TPL;
791 }
792
793 ExprResult TransformAddressOfOperand(Expr *E);
794
795 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
796 bool IsAddressOfOperand,
797 TypeSourceInfo **RecoveryTSI);
798
799 ExprResult TransformParenDependentScopeDeclRefExpr(
800 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
801 TypeSourceInfo **RecoveryTSI);
802
803 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
804 bool IsAddressOfOperand);
805
806 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
807
808 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
809
810 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
811 // amount of stack usage with clang.
812 #define STMT(Node, Parent) \
813 LLVM_ATTRIBUTE_NOINLINE \
814 StmtResult Transform##Node(Node *S);
815 #define VALUESTMT(Node, Parent) \
816 LLVM_ATTRIBUTE_NOINLINE \
817 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
818 #define EXPR(Node, Parent) \
819 LLVM_ATTRIBUTE_NOINLINE \
820 ExprResult Transform##Node(Node *E);
821 #define ABSTRACT_STMT(Stmt)
822 #include "clang/AST/StmtNodes.inc"
823
824 #define GEN_CLANG_CLAUSE_CLASS
825 #define CLAUSE_CLASS(Enum, Str, Class) \
826 LLVM_ATTRIBUTE_NOINLINE \
827 OMPClause *Transform##Class(Class *S);
828 #include "llvm/Frontend/OpenMP/OMP.inc"
829
830 /// Build a new qualified type given its unqualified type and type location.
831 ///
832 /// By default, this routine adds type qualifiers only to types that can
833 /// have qualifiers, and silently suppresses those qualifiers that are not
834 /// permitted. Subclasses may override this routine to provide different
835 /// behavior.
836 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
837
838 /// Build a new pointer type given its pointee type.
839 ///
840 /// By default, performs semantic analysis when building the pointer type.
841 /// Subclasses may override this routine to provide different behavior.
842 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
843
844 /// Build a new block pointer type given its pointee type.
845 ///
846 /// By default, performs semantic analysis when building the block pointer
847 /// type. Subclasses may override this routine to provide different behavior.
848 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
849
850 /// Build a new reference type given the type it references.
851 ///
852 /// By default, performs semantic analysis when building the
853 /// reference type. Subclasses may override this routine to provide
854 /// different behavior.
855 ///
856 /// \param LValue whether the type was written with an lvalue sigil
857 /// or an rvalue sigil.
858 QualType RebuildReferenceType(QualType ReferentType,
859 bool LValue,
860 SourceLocation Sigil);
861
862 /// Build a new member pointer type given the pointee type and the
863 /// qualifier it refers into.
864 ///
865 /// By default, performs semantic analysis when building the member pointer
866 /// type. Subclasses may override this routine to provide different behavior.
867 QualType RebuildMemberPointerType(QualType PointeeType,
868 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
869 SourceLocation Sigil);
870
871 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
872 SourceLocation ProtocolLAngleLoc,
873 ArrayRef<ObjCProtocolDecl *> Protocols,
874 ArrayRef<SourceLocation> ProtocolLocs,
875 SourceLocation ProtocolRAngleLoc);
876
877 /// Build an Objective-C object type.
878 ///
879 /// By default, performs semantic analysis when building the object type.
880 /// Subclasses may override this routine to provide different behavior.
881 QualType RebuildObjCObjectType(QualType BaseType,
882 SourceLocation Loc,
883 SourceLocation TypeArgsLAngleLoc,
884 ArrayRef<TypeSourceInfo *> TypeArgs,
885 SourceLocation TypeArgsRAngleLoc,
886 SourceLocation ProtocolLAngleLoc,
887 ArrayRef<ObjCProtocolDecl *> Protocols,
888 ArrayRef<SourceLocation> ProtocolLocs,
889 SourceLocation ProtocolRAngleLoc);
890
891 /// Build a new Objective-C object pointer type given the pointee type.
892 ///
893 /// By default, directly builds the pointer type, with no additional semantic
894 /// analysis.
895 QualType RebuildObjCObjectPointerType(QualType PointeeType,
896 SourceLocation Star);
897
898 /// Build a new array type given the element type, size
899 /// modifier, size of the array (if known), size expression, and index type
900 /// qualifiers.
901 ///
902 /// By default, performs semantic analysis when building the array type.
903 /// Subclasses may override this routine to provide different behavior.
904 /// Also by default, all of the other Rebuild*Array
905 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
906 const llvm::APInt *Size, Expr *SizeExpr,
907 unsigned IndexTypeQuals, SourceRange BracketsRange);
908
909 /// Build a new constant array type given the element type, size
910 /// modifier, (known) size of the array, and index type qualifiers.
911 ///
912 /// By default, performs semantic analysis when building the array type.
913 /// Subclasses may override this routine to provide different behavior.
914 QualType RebuildConstantArrayType(QualType ElementType,
915 ArraySizeModifier SizeMod,
916 const llvm::APInt &Size, Expr *SizeExpr,
917 unsigned IndexTypeQuals,
918 SourceRange BracketsRange);
919
920 /// Build a new incomplete array type given the element type, size
921 /// modifier, and index type qualifiers.
922 ///
923 /// By default, performs semantic analysis when building the array type.
924 /// Subclasses may override this routine to provide different behavior.
925 QualType RebuildIncompleteArrayType(QualType ElementType,
926 ArraySizeModifier SizeMod,
927 unsigned IndexTypeQuals,
928 SourceRange BracketsRange);
929
930 /// Build a new variable-length array type given the element type,
931 /// size modifier, size expression, and index type qualifiers.
932 ///
933 /// By default, performs semantic analysis when building the array type.
934 /// Subclasses may override this routine to provide different behavior.
935 QualType RebuildVariableArrayType(QualType ElementType,
936 ArraySizeModifier SizeMod, Expr *SizeExpr,
937 unsigned IndexTypeQuals,
938 SourceRange BracketsRange);
939
940 /// Build a new dependent-sized array type given the element type,
941 /// size modifier, size expression, and index type qualifiers.
942 ///
943 /// By default, performs semantic analysis when building the array type.
944 /// Subclasses may override this routine to provide different behavior.
945 QualType RebuildDependentSizedArrayType(QualType ElementType,
946 ArraySizeModifier SizeMod,
947 Expr *SizeExpr,
948 unsigned IndexTypeQuals,
949 SourceRange BracketsRange);
950
951 /// Build a new vector type given the element type and
952 /// number of elements.
953 ///
954 /// By default, performs semantic analysis when building the vector type.
955 /// Subclasses may override this routine to provide different behavior.
956 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
957 VectorKind VecKind);
958
959 /// Build a new potentially dependently-sized extended vector type
960 /// given the element type and number of elements.
961 ///
962 /// By default, performs semantic analysis when building the vector type.
963 /// Subclasses may override this routine to provide different behavior.
964 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
965 SourceLocation AttributeLoc, VectorKind);
966
967 /// Build a new extended vector type given the element type and
968 /// number of elements.
969 ///
970 /// By default, performs semantic analysis when building the vector type.
971 /// Subclasses may override this routine to provide different behavior.
972 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
973 SourceLocation AttributeLoc);
974
975 /// Build a new potentially dependently-sized extended vector type
976 /// given the element type and number of elements.
977 ///
978 /// By default, performs semantic analysis when building the vector type.
979 /// Subclasses may override this routine to provide different behavior.
980 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
981 Expr *SizeExpr,
982 SourceLocation AttributeLoc);
983
984 /// Build a new matrix type given the element type and dimensions.
985 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
986 unsigned NumColumns);
987
988 /// Build a new matrix type given the type and dependently-defined
989 /// dimensions.
990 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
991 Expr *ColumnExpr,
992 SourceLocation AttributeLoc);
993
994 /// Build a new DependentAddressSpaceType or return the pointee
995 /// type variable with the correct address space (retrieved from
996 /// AddrSpaceExpr) applied to it. The former will be returned in cases
997 /// where the address space remains dependent.
998 ///
999 /// By default, performs semantic analysis when building the type with address
1000 /// space applied. Subclasses may override this routine to provide different
1001 /// behavior.
1002 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1003 Expr *AddrSpaceExpr,
1004 SourceLocation AttributeLoc);
1005
1006 /// Build a new function type.
1007 ///
1008 /// By default, performs semantic analysis when building the function type.
1009 /// Subclasses may override this routine to provide different behavior.
1010 QualType RebuildFunctionProtoType(QualType T,
1011 MutableArrayRef<QualType> ParamTypes,
1012 const FunctionProtoType::ExtProtoInfo &EPI);
1013
1014 /// Build a new unprototyped function type.
1015 QualType RebuildFunctionNoProtoType(QualType ResultType);
1016
1017 /// Rebuild an unresolved typename type, given the decl that
1018 /// the UnresolvedUsingTypenameDecl was transformed to.
1019 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1020
1021 /// Build a new type found via an alias.
RebuildUsingType(UsingShadowDecl * Found,QualType Underlying)1022 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1023 return SemaRef.Context.getUsingType(Found, Underlying);
1024 }
1025
1026 /// Build a new typedef type.
RebuildTypedefType(TypedefNameDecl * Typedef)1027 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1028 return SemaRef.Context.getTypeDeclType(Typedef);
1029 }
1030
1031 /// Build a new MacroDefined type.
RebuildMacroQualifiedType(QualType T,const IdentifierInfo * MacroII)1032 QualType RebuildMacroQualifiedType(QualType T,
1033 const IdentifierInfo *MacroII) {
1034 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1035 }
1036
1037 /// Build a new class/struct/union type.
RebuildRecordType(RecordDecl * Record)1038 QualType RebuildRecordType(RecordDecl *Record) {
1039 return SemaRef.Context.getTypeDeclType(Record);
1040 }
1041
1042 /// Build a new Enum type.
RebuildEnumType(EnumDecl * Enum)1043 QualType RebuildEnumType(EnumDecl *Enum) {
1044 return SemaRef.Context.getTypeDeclType(Enum);
1045 }
1046
1047 /// Build a new typeof(expr) type.
1048 ///
1049 /// By default, performs semantic analysis when building the typeof type.
1050 /// Subclasses may override this routine to provide different behavior.
1051 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1052 TypeOfKind Kind);
1053
1054 /// Build a new typeof(type) type.
1055 ///
1056 /// By default, builds a new TypeOfType with the given underlying type.
1057 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1058
1059 /// Build a new unary transform type.
1060 QualType RebuildUnaryTransformType(QualType BaseType,
1061 UnaryTransformType::UTTKind UKind,
1062 SourceLocation Loc);
1063
1064 /// Build a new C++11 decltype type.
1065 ///
1066 /// By default, performs semantic analysis when building the decltype type.
1067 /// Subclasses may override this routine to provide different behavior.
1068 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1069
1070 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1071 SourceLocation Loc,
1072 SourceLocation EllipsisLoc,
1073 bool FullySubstituted,
1074 ArrayRef<QualType> Expansions = {});
1075
1076 /// Build a new C++11 auto type.
1077 ///
1078 /// By default, builds a new AutoType with the given deduced type.
RebuildAutoType(QualType Deduced,AutoTypeKeyword Keyword,ConceptDecl * TypeConstraintConcept,ArrayRef<TemplateArgument> TypeConstraintArgs)1079 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1080 ConceptDecl *TypeConstraintConcept,
1081 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1082 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1083 // which has been deduced to a dependent type into an undeduced 'auto', so
1084 // that we'll retry deduction after the transformation.
1085 return SemaRef.Context.getAutoType(Deduced, Keyword,
1086 /*IsDependent*/ false, /*IsPack=*/false,
1087 TypeConstraintConcept,
1088 TypeConstraintArgs);
1089 }
1090
1091 /// By default, builds a new DeducedTemplateSpecializationType with the given
1092 /// deduced type.
RebuildDeducedTemplateSpecializationType(TemplateName Template,QualType Deduced)1093 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1094 QualType Deduced) {
1095 return SemaRef.Context.getDeducedTemplateSpecializationType(
1096 Template, Deduced, /*IsDependent*/ false);
1097 }
1098
1099 /// Build a new template specialization type.
1100 ///
1101 /// By default, performs semantic analysis when building the template
1102 /// specialization type. Subclasses may override this routine to provide
1103 /// different behavior.
1104 QualType RebuildTemplateSpecializationType(TemplateName Template,
1105 SourceLocation TemplateLoc,
1106 TemplateArgumentListInfo &Args);
1107
1108 /// Build a new parenthesized type.
1109 ///
1110 /// By default, builds a new ParenType type from the inner type.
1111 /// Subclasses may override this routine to provide different behavior.
RebuildParenType(QualType InnerType)1112 QualType RebuildParenType(QualType InnerType) {
1113 return SemaRef.BuildParenType(InnerType);
1114 }
1115
1116 /// Build a new qualified name type.
1117 ///
1118 /// By default, builds a new ElaboratedType type from the keyword,
1119 /// the nested-name-specifier and the named type.
1120 /// Subclasses may override this routine to provide different behavior.
RebuildElaboratedType(SourceLocation KeywordLoc,ElaboratedTypeKeyword Keyword,NestedNameSpecifierLoc QualifierLoc,QualType Named)1121 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1122 ElaboratedTypeKeyword Keyword,
1123 NestedNameSpecifierLoc QualifierLoc,
1124 QualType Named) {
1125 return SemaRef.Context.getElaboratedType(Keyword,
1126 QualifierLoc.getNestedNameSpecifier(),
1127 Named);
1128 }
1129
1130 /// Build a new typename type that refers to a template-id.
1131 ///
1132 /// By default, builds a new DependentNameType type from the
1133 /// nested-name-specifier and the given type. Subclasses may override
1134 /// this routine to provide different behavior.
RebuildDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,NestedNameSpecifier * NNS,SourceLocation TemplateKWLoc,TemplateName Name,SourceLocation NameLoc,TemplateArgumentListInfo & Args,bool AllowInjectedClassName)1135 QualType RebuildDependentTemplateSpecializationType(
1136 ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
1137 SourceLocation TemplateKWLoc, TemplateName Name, SourceLocation NameLoc,
1138 TemplateArgumentListInfo &Args, bool AllowInjectedClassName) {
1139 // If it's still dependent, make a dependent specialization.
1140 if (const DependentTemplateStorage *S = Name.getAsDependentTemplateName())
1141 return SemaRef.Context.getDependentTemplateSpecializationType(
1142 Keyword, *S, Args.arguments());
1143
1144 // Otherwise, make an elaborated type wrapping a non-dependent
1145 // specialization.
1146 QualType T =
1147 getDerived().RebuildTemplateSpecializationType(Name, NameLoc, Args);
1148 if (T.isNull())
1149 return QualType();
1150 return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
1151 }
1152
1153 /// Build a new typename type that refers to an identifier.
1154 ///
1155 /// By default, performs semantic analysis when building the typename type
1156 /// (or elaborated type). Subclasses may override this routine to provide
1157 /// different behavior.
RebuildDependentNameType(ElaboratedTypeKeyword Keyword,SourceLocation KeywordLoc,NestedNameSpecifierLoc QualifierLoc,const IdentifierInfo * Id,SourceLocation IdLoc,bool DeducedTSTContext)1158 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1159 SourceLocation KeywordLoc,
1160 NestedNameSpecifierLoc QualifierLoc,
1161 const IdentifierInfo *Id,
1162 SourceLocation IdLoc,
1163 bool DeducedTSTContext) {
1164 CXXScopeSpec SS;
1165 SS.Adopt(QualifierLoc);
1166
1167 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1168 // If the name is still dependent, just build a new dependent name type.
1169 if (!SemaRef.computeDeclContext(SS))
1170 return SemaRef.Context.getDependentNameType(Keyword,
1171 QualifierLoc.getNestedNameSpecifier(),
1172 Id);
1173 }
1174
1175 if (Keyword == ElaboratedTypeKeyword::None ||
1176 Keyword == ElaboratedTypeKeyword::Typename) {
1177 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1178 *Id, IdLoc, DeducedTSTContext);
1179 }
1180
1181 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1182
1183 // We had a dependent elaborated-type-specifier that has been transformed
1184 // into a non-dependent elaborated-type-specifier. Find the tag we're
1185 // referring to.
1186 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1187 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1188 if (!DC)
1189 return QualType();
1190
1191 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1192 return QualType();
1193
1194 TagDecl *Tag = nullptr;
1195 SemaRef.LookupQualifiedName(Result, DC);
1196 switch (Result.getResultKind()) {
1197 case LookupResultKind::NotFound:
1198 case LookupResultKind::NotFoundInCurrentInstantiation:
1199 break;
1200
1201 case LookupResultKind::Found:
1202 Tag = Result.getAsSingle<TagDecl>();
1203 break;
1204
1205 case LookupResultKind::FoundOverloaded:
1206 case LookupResultKind::FoundUnresolvedValue:
1207 llvm_unreachable("Tag lookup cannot find non-tags");
1208
1209 case LookupResultKind::Ambiguous:
1210 // Let the LookupResult structure handle ambiguities.
1211 return QualType();
1212 }
1213
1214 if (!Tag) {
1215 // Check where the name exists but isn't a tag type and use that to emit
1216 // better diagnostics.
1217 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1218 SemaRef.LookupQualifiedName(Result, DC);
1219 switch (Result.getResultKind()) {
1220 case LookupResultKind::Found:
1221 case LookupResultKind::FoundOverloaded:
1222 case LookupResultKind::FoundUnresolvedValue: {
1223 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1224 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1225 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1226 << SomeDecl << NTK << Kind;
1227 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1228 break;
1229 }
1230 default:
1231 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1232 << Kind << Id << DC << QualifierLoc.getSourceRange();
1233 break;
1234 }
1235 return QualType();
1236 }
1237
1238 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1239 IdLoc, Id)) {
1240 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1241 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1242 return QualType();
1243 }
1244
1245 // Build the elaborated-type-specifier type.
1246 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1247 return SemaRef.Context.getElaboratedType(Keyword,
1248 QualifierLoc.getNestedNameSpecifier(),
1249 T);
1250 }
1251
1252 /// Build a new pack expansion type.
1253 ///
1254 /// By default, builds a new PackExpansionType type from the given pattern.
1255 /// Subclasses may override this routine to provide different behavior.
RebuildPackExpansionType(QualType Pattern,SourceRange PatternRange,SourceLocation EllipsisLoc,UnsignedOrNone NumExpansions)1256 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1257 SourceLocation EllipsisLoc,
1258 UnsignedOrNone NumExpansions) {
1259 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1260 NumExpansions);
1261 }
1262
1263 /// Build a new atomic type given its value type.
1264 ///
1265 /// By default, performs semantic analysis when building the atomic type.
1266 /// Subclasses may override this routine to provide different behavior.
1267 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1268
1269 /// Build a new pipe type given its value type.
1270 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1271 bool isReadPipe);
1272
1273 /// Build a bit-precise int given its value type.
1274 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1275 SourceLocation Loc);
1276
1277 /// Build a dependent bit-precise int given its value type.
1278 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1279 SourceLocation Loc);
1280
1281 /// Build a new template name given a nested name specifier, a flag
1282 /// indicating whether the "template" keyword was provided, and the template
1283 /// that the template name refers to.
1284 ///
1285 /// By default, builds the new template name directly. Subclasses may override
1286 /// this routine to provide different behavior.
1287 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1288 bool TemplateKW,
1289 TemplateDecl *Template);
1290
1291 /// Build a new template name given a nested name specifier and the
1292 /// name that is referred to as a template.
1293 ///
1294 /// By default, performs semantic analysis to determine whether the name can
1295 /// be resolved to a specific template, then builds the appropriate kind of
1296 /// template name. Subclasses may override this routine to provide different
1297 /// behavior.
1298 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1299 SourceLocation TemplateKWLoc,
1300 const IdentifierInfo &Name,
1301 SourceLocation NameLoc, QualType ObjectType,
1302 NamedDecl *FirstQualifierInScope,
1303 bool AllowInjectedClassName);
1304
1305 /// Build a new template name given a nested name specifier and the
1306 /// overloaded operator name that is referred to as a template.
1307 ///
1308 /// By default, performs semantic analysis to determine whether the name can
1309 /// be resolved to a specific template, then builds the appropriate kind of
1310 /// template name. Subclasses may override this routine to provide different
1311 /// behavior.
1312 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1313 SourceLocation TemplateKWLoc,
1314 OverloadedOperatorKind Operator,
1315 SourceLocation NameLoc, QualType ObjectType,
1316 bool AllowInjectedClassName);
1317
1318 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1319 SourceLocation TemplateKWLoc,
1320 IdentifierOrOverloadedOperator IO,
1321 SourceLocation NameLoc, QualType ObjectType,
1322 NamedDecl *FirstQualifierInScope,
1323 bool AllowInjectedClassName);
1324
1325 /// Build a new template name given a template template parameter pack
1326 /// and the
1327 ///
1328 /// By default, performs semantic analysis to determine whether the name can
1329 /// be resolved to a specific template, then builds the appropriate kind of
1330 /// template name. Subclasses may override this routine to provide different
1331 /// behavior.
RebuildTemplateName(const TemplateArgument & ArgPack,Decl * AssociatedDecl,unsigned Index,bool Final)1332 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1333 Decl *AssociatedDecl, unsigned Index,
1334 bool Final) {
1335 return getSema().Context.getSubstTemplateTemplateParmPack(
1336 ArgPack, AssociatedDecl, Index, Final);
1337 }
1338
1339 /// Build a new compound statement.
1340 ///
1341 /// By default, performs semantic analysis to build the new statement.
1342 /// Subclasses may override this routine to provide different behavior.
RebuildCompoundStmt(SourceLocation LBraceLoc,MultiStmtArg Statements,SourceLocation RBraceLoc,bool IsStmtExpr)1343 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1344 MultiStmtArg Statements,
1345 SourceLocation RBraceLoc,
1346 bool IsStmtExpr) {
1347 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1348 IsStmtExpr);
1349 }
1350
1351 /// Build a new case statement.
1352 ///
1353 /// By default, performs semantic analysis to build the new statement.
1354 /// Subclasses may override this routine to provide different behavior.
RebuildCaseStmt(SourceLocation CaseLoc,Expr * LHS,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation ColonLoc)1355 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1356 Expr *LHS,
1357 SourceLocation EllipsisLoc,
1358 Expr *RHS,
1359 SourceLocation ColonLoc) {
1360 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1361 ColonLoc);
1362 }
1363
1364 /// Attach the body to a new case statement.
1365 ///
1366 /// By default, performs semantic analysis to build the new statement.
1367 /// Subclasses may override this routine to provide different behavior.
RebuildCaseStmtBody(Stmt * S,Stmt * Body)1368 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1369 getSema().ActOnCaseStmtBody(S, Body);
1370 return S;
1371 }
1372
1373 /// Build a new default statement.
1374 ///
1375 /// By default, performs semantic analysis to build the new statement.
1376 /// Subclasses may override this routine to provide different behavior.
RebuildDefaultStmt(SourceLocation DefaultLoc,SourceLocation ColonLoc,Stmt * SubStmt)1377 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1378 SourceLocation ColonLoc,
1379 Stmt *SubStmt) {
1380 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1381 /*CurScope=*/nullptr);
1382 }
1383
1384 /// Build a new label statement.
1385 ///
1386 /// By default, performs semantic analysis to build the new statement.
1387 /// Subclasses may override this routine to provide different behavior.
RebuildLabelStmt(SourceLocation IdentLoc,LabelDecl * L,SourceLocation ColonLoc,Stmt * SubStmt)1388 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1389 SourceLocation ColonLoc, Stmt *SubStmt) {
1390 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1391 }
1392
1393 /// Build a new attributed statement.
1394 ///
1395 /// By default, performs semantic analysis to build the new statement.
1396 /// Subclasses may override this routine to provide different behavior.
RebuildAttributedStmt(SourceLocation AttrLoc,ArrayRef<const Attr * > Attrs,Stmt * SubStmt)1397 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1398 ArrayRef<const Attr *> Attrs,
1399 Stmt *SubStmt) {
1400 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1401 return StmtError();
1402 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1403 }
1404
1405 /// Build a new "if" statement.
1406 ///
1407 /// By default, performs semantic analysis to build the new statement.
1408 /// Subclasses may override this routine to provide different behavior.
RebuildIfStmt(SourceLocation IfLoc,IfStatementKind Kind,SourceLocation LParenLoc,Sema::ConditionResult Cond,SourceLocation RParenLoc,Stmt * Init,Stmt * Then,SourceLocation ElseLoc,Stmt * Else)1409 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1410 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1411 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1412 SourceLocation ElseLoc, Stmt *Else) {
1413 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1414 Then, ElseLoc, Else);
1415 }
1416
1417 /// Start building a new switch statement.
1418 ///
1419 /// By default, performs semantic analysis to build the new statement.
1420 /// Subclasses may override this routine to provide different behavior.
RebuildSwitchStmtStart(SourceLocation SwitchLoc,SourceLocation LParenLoc,Stmt * Init,Sema::ConditionResult Cond,SourceLocation RParenLoc)1421 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1422 SourceLocation LParenLoc, Stmt *Init,
1423 Sema::ConditionResult Cond,
1424 SourceLocation RParenLoc) {
1425 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1426 RParenLoc);
1427 }
1428
1429 /// Attach the body to the switch statement.
1430 ///
1431 /// By default, performs semantic analysis to build the new statement.
1432 /// Subclasses may override this routine to provide different behavior.
RebuildSwitchStmtBody(SourceLocation SwitchLoc,Stmt * Switch,Stmt * Body)1433 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1434 Stmt *Switch, Stmt *Body) {
1435 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1436 }
1437
1438 /// Build a new while statement.
1439 ///
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
RebuildWhileStmt(SourceLocation WhileLoc,SourceLocation LParenLoc,Sema::ConditionResult Cond,SourceLocation RParenLoc,Stmt * Body)1442 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1443 Sema::ConditionResult Cond,
1444 SourceLocation RParenLoc, Stmt *Body) {
1445 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1446 }
1447
1448 /// Build a new do-while statement.
1449 ///
1450 /// By default, performs semantic analysis to build the new statement.
1451 /// Subclasses may override this routine to provide different behavior.
RebuildDoStmt(SourceLocation DoLoc,Stmt * Body,SourceLocation WhileLoc,SourceLocation LParenLoc,Expr * Cond,SourceLocation RParenLoc)1452 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1453 SourceLocation WhileLoc, SourceLocation LParenLoc,
1454 Expr *Cond, SourceLocation RParenLoc) {
1455 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1456 Cond, RParenLoc);
1457 }
1458
1459 /// Build a new for statement.
1460 ///
1461 /// By default, performs semantic analysis to build the new statement.
1462 /// Subclasses may override this routine to provide different behavior.
RebuildForStmt(SourceLocation ForLoc,SourceLocation LParenLoc,Stmt * Init,Sema::ConditionResult Cond,Sema::FullExprArg Inc,SourceLocation RParenLoc,Stmt * Body)1463 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1464 Stmt *Init, Sema::ConditionResult Cond,
1465 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1466 Stmt *Body) {
1467 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1468 Inc, RParenLoc, Body);
1469 }
1470
1471 /// Build a new goto statement.
1472 ///
1473 /// By default, performs semantic analysis to build the new statement.
1474 /// Subclasses may override this routine to provide different behavior.
RebuildGotoStmt(SourceLocation GotoLoc,SourceLocation LabelLoc,LabelDecl * Label)1475 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1476 LabelDecl *Label) {
1477 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1478 }
1479
1480 /// Build a new indirect goto statement.
1481 ///
1482 /// By default, performs semantic analysis to build the new statement.
1483 /// Subclasses may override this routine to provide different behavior.
RebuildIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc,Expr * Target)1484 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1485 SourceLocation StarLoc,
1486 Expr *Target) {
1487 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1488 }
1489
1490 /// Build a new return statement.
1491 ///
1492 /// By default, performs semantic analysis to build the new statement.
1493 /// Subclasses may override this routine to provide different behavior.
RebuildReturnStmt(SourceLocation ReturnLoc,Expr * Result)1494 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1495 return getSema().BuildReturnStmt(ReturnLoc, Result);
1496 }
1497
1498 /// Build a new declaration statement.
1499 ///
1500 /// By default, performs semantic analysis to build the new statement.
1501 /// Subclasses may override this routine to provide different behavior.
RebuildDeclStmt(MutableArrayRef<Decl * > Decls,SourceLocation StartLoc,SourceLocation EndLoc)1502 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1503 SourceLocation StartLoc, SourceLocation EndLoc) {
1504 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1505 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1506 }
1507
1508 /// Build a new inline asm statement.
1509 ///
1510 /// By default, performs semantic analysis to build the new statement.
1511 /// Subclasses may override this routine to provide different behavior.
RebuildGCCAsmStmt(SourceLocation AsmLoc,bool IsSimple,bool IsVolatile,unsigned NumOutputs,unsigned NumInputs,IdentifierInfo ** Names,MultiExprArg Constraints,MultiExprArg Exprs,Expr * AsmString,MultiExprArg Clobbers,unsigned NumLabels,SourceLocation RParenLoc)1512 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1513 bool IsVolatile, unsigned NumOutputs,
1514 unsigned NumInputs, IdentifierInfo **Names,
1515 MultiExprArg Constraints, MultiExprArg Exprs,
1516 Expr *AsmString, MultiExprArg Clobbers,
1517 unsigned NumLabels,
1518 SourceLocation RParenLoc) {
1519 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1520 NumInputs, Names, Constraints, Exprs,
1521 AsmString, Clobbers, NumLabels, RParenLoc);
1522 }
1523
1524 /// Build a new MS style inline asm statement.
1525 ///
1526 /// By default, performs semantic analysis to build the new statement.
1527 /// Subclasses may override this routine to provide different behavior.
RebuildMSAsmStmt(SourceLocation AsmLoc,SourceLocation LBraceLoc,ArrayRef<Token> AsmToks,StringRef AsmString,unsigned NumOutputs,unsigned NumInputs,ArrayRef<StringRef> Constraints,ArrayRef<StringRef> Clobbers,ArrayRef<Expr * > Exprs,SourceLocation EndLoc)1528 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1529 ArrayRef<Token> AsmToks,
1530 StringRef AsmString,
1531 unsigned NumOutputs, unsigned NumInputs,
1532 ArrayRef<StringRef> Constraints,
1533 ArrayRef<StringRef> Clobbers,
1534 ArrayRef<Expr*> Exprs,
1535 SourceLocation EndLoc) {
1536 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1537 NumOutputs, NumInputs,
1538 Constraints, Clobbers, Exprs, EndLoc);
1539 }
1540
1541 /// Build a new co_return statement.
1542 ///
1543 /// By default, performs semantic analysis to build the new statement.
1544 /// Subclasses may override this routine to provide different behavior.
RebuildCoreturnStmt(SourceLocation CoreturnLoc,Expr * Result,bool IsImplicit)1545 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1546 bool IsImplicit) {
1547 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1548 }
1549
1550 /// Build a new co_await expression.
1551 ///
1552 /// By default, performs semantic analysis to build the new expression.
1553 /// Subclasses may override this routine to provide different behavior.
RebuildCoawaitExpr(SourceLocation CoawaitLoc,Expr * Operand,UnresolvedLookupExpr * OpCoawaitLookup,bool IsImplicit)1554 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1555 UnresolvedLookupExpr *OpCoawaitLookup,
1556 bool IsImplicit) {
1557 // This function rebuilds a coawait-expr given its operator.
1558 // For an explicit coawait-expr, the rebuild involves the full set
1559 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1560 // including calling await_transform().
1561 // For an implicit coawait-expr, we need to rebuild the "operator
1562 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1563 // This mirrors how the implicit CoawaitExpr is originally created
1564 // in Sema::ActOnCoroutineBodyStart().
1565 if (IsImplicit) {
1566 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1567 CoawaitLoc, Operand, OpCoawaitLookup);
1568 if (Suspend.isInvalid())
1569 return ExprError();
1570 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1571 Suspend.get(), true);
1572 }
1573
1574 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1575 OpCoawaitLookup);
1576 }
1577
1578 /// Build a new co_await expression.
1579 ///
1580 /// By default, performs semantic analysis to build the new expression.
1581 /// Subclasses may override this routine to provide different behavior.
RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,Expr * Result,UnresolvedLookupExpr * Lookup)1582 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1583 Expr *Result,
1584 UnresolvedLookupExpr *Lookup) {
1585 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1586 }
1587
1588 /// Build a new co_yield expression.
1589 ///
1590 /// By default, performs semantic analysis to build the new expression.
1591 /// Subclasses may override this routine to provide different behavior.
RebuildCoyieldExpr(SourceLocation CoyieldLoc,Expr * Result)1592 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1593 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1594 }
1595
RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args)1596 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1597 return getSema().BuildCoroutineBodyStmt(Args);
1598 }
1599
1600 /// Build a new Objective-C \@try statement.
1601 ///
1602 /// By default, performs semantic analysis to build the new statement.
1603 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAtTryStmt(SourceLocation AtLoc,Stmt * TryBody,MultiStmtArg CatchStmts,Stmt * Finally)1604 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1605 Stmt *TryBody,
1606 MultiStmtArg CatchStmts,
1607 Stmt *Finally) {
1608 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1609 Finally);
1610 }
1611
1612 /// Rebuild an Objective-C exception declaration.
1613 ///
1614 /// By default, performs semantic analysis to build the new declaration.
1615 /// Subclasses may override this routine to provide different behavior.
RebuildObjCExceptionDecl(VarDecl * ExceptionDecl,TypeSourceInfo * TInfo,QualType T)1616 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1617 TypeSourceInfo *TInfo, QualType T) {
1618 return getSema().ObjC().BuildObjCExceptionDecl(
1619 TInfo, T, ExceptionDecl->getInnerLocStart(),
1620 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1621 }
1622
1623 /// Build a new Objective-C \@catch statement.
1624 ///
1625 /// By default, performs semantic analysis to build the new statement.
1626 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAtCatchStmt(SourceLocation AtLoc,SourceLocation RParenLoc,VarDecl * Var,Stmt * Body)1627 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1628 SourceLocation RParenLoc,
1629 VarDecl *Var,
1630 Stmt *Body) {
1631 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1632 }
1633
1634 /// Build a new Objective-C \@finally statement.
1635 ///
1636 /// By default, performs semantic analysis to build the new statement.
1637 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAtFinallyStmt(SourceLocation AtLoc,Stmt * Body)1638 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1639 Stmt *Body) {
1640 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1641 }
1642
1643 /// Build a new Objective-C \@throw statement.
1644 ///
1645 /// By default, performs semantic analysis to build the new statement.
1646 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAtThrowStmt(SourceLocation AtLoc,Expr * Operand)1647 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1648 Expr *Operand) {
1649 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1650 }
1651
1652 /// Build a new OpenMP Canonical loop.
1653 ///
1654 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1655 /// OMPCanonicalLoop.
RebuildOMPCanonicalLoop(Stmt * LoopStmt)1656 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1657 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1658 }
1659
1660 /// Build a new OpenMP executable directive.
1661 ///
1662 /// By default, performs semantic analysis to build the new statement.
1663 /// Subclasses may override this routine to provide different behavior.
RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,DeclarationNameInfo DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)1664 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1665 DeclarationNameInfo DirName,
1666 OpenMPDirectiveKind CancelRegion,
1667 ArrayRef<OMPClause *> Clauses,
1668 Stmt *AStmt, SourceLocation StartLoc,
1669 SourceLocation EndLoc) {
1670
1671 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1672 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1673 }
1674
1675 /// Build a new OpenMP informational directive.
RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,DeclarationNameInfo DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)1676 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1677 DeclarationNameInfo DirName,
1678 ArrayRef<OMPClause *> Clauses,
1679 Stmt *AStmt,
1680 SourceLocation StartLoc,
1681 SourceLocation EndLoc) {
1682
1683 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1684 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1685 }
1686
1687 /// Build a new OpenMP 'if' clause.
1688 ///
1689 /// By default, performs semantic analysis to build the new OpenMP clause.
1690 /// Subclasses may override this routine to provide different behavior.
RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)1691 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1692 Expr *Condition, SourceLocation StartLoc,
1693 SourceLocation LParenLoc,
1694 SourceLocation NameModifierLoc,
1695 SourceLocation ColonLoc,
1696 SourceLocation EndLoc) {
1697 return getSema().OpenMP().ActOnOpenMPIfClause(
1698 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1699 EndLoc);
1700 }
1701
1702 /// Build a new OpenMP 'final' clause.
1703 ///
1704 /// By default, performs semantic analysis to build the new OpenMP clause.
1705 /// Subclasses may override this routine to provide different behavior.
RebuildOMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1706 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1707 SourceLocation LParenLoc,
1708 SourceLocation EndLoc) {
1709 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1710 LParenLoc, EndLoc);
1711 }
1712
1713 /// Build a new OpenMP 'num_threads' clause.
1714 ///
1715 /// By default, performs semantic analysis to build the new OpenMP clause.
1716 /// Subclasses may override this routine to provide different behavior.
RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)1717 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,
1718 Expr *NumThreads,
1719 SourceLocation StartLoc,
1720 SourceLocation LParenLoc,
1721 SourceLocation ModifierLoc,
1722 SourceLocation EndLoc) {
1723 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1724 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);
1725 }
1726
1727 /// Build a new OpenMP 'safelen' clause.
1728 ///
1729 /// By default, performs semantic analysis to build the new OpenMP clause.
1730 /// Subclasses may override this routine to provide different behavior.
RebuildOMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1731 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1732 SourceLocation LParenLoc,
1733 SourceLocation EndLoc) {
1734 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1735 EndLoc);
1736 }
1737
1738 /// Build a new OpenMP 'simdlen' clause.
1739 ///
1740 /// By default, performs semantic analysis to build the new OpenMP clause.
1741 /// Subclasses may override this routine to provide different behavior.
RebuildOMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1742 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1743 SourceLocation LParenLoc,
1744 SourceLocation EndLoc) {
1745 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1746 EndLoc);
1747 }
1748
RebuildOMPSizesClause(ArrayRef<Expr * > Sizes,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1749 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1750 SourceLocation StartLoc,
1751 SourceLocation LParenLoc,
1752 SourceLocation EndLoc) {
1753 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1754 EndLoc);
1755 }
1756
1757 /// Build a new OpenMP 'permutation' clause.
RebuildOMPPermutationClause(ArrayRef<Expr * > PermExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1758 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1759 SourceLocation StartLoc,
1760 SourceLocation LParenLoc,
1761 SourceLocation EndLoc) {
1762 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1763 LParenLoc, EndLoc);
1764 }
1765
1766 /// Build a new OpenMP 'full' clause.
RebuildOMPFullClause(SourceLocation StartLoc,SourceLocation EndLoc)1767 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1770 }
1771
1772 /// Build a new OpenMP 'partial' clause.
RebuildOMPPartialClause(Expr * Factor,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1773 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1774 SourceLocation LParenLoc,
1775 SourceLocation EndLoc) {
1776 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1777 LParenLoc, EndLoc);
1778 }
1779
1780 /// Build a new OpenMP 'allocator' clause.
1781 ///
1782 /// By default, performs semantic analysis to build the new OpenMP clause.
1783 /// Subclasses may override this routine to provide different behavior.
RebuildOMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1784 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1785 SourceLocation LParenLoc,
1786 SourceLocation EndLoc) {
1787 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1788 EndLoc);
1789 }
1790
1791 /// Build a new OpenMP 'collapse' clause.
1792 ///
1793 /// By default, performs semantic analysis to build the new OpenMP clause.
1794 /// Subclasses may override this routine to provide different behavior.
RebuildOMPCollapseClause(Expr * Num,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1795 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1796 SourceLocation LParenLoc,
1797 SourceLocation EndLoc) {
1798 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1799 LParenLoc, EndLoc);
1800 }
1801
1802 /// Build a new OpenMP 'default' clause.
1803 ///
1804 /// By default, performs semantic analysis to build the new OpenMP clause.
1805 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1806 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1807 SourceLocation StartLoc,
1808 SourceLocation LParenLoc,
1809 SourceLocation EndLoc) {
1810 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1811 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1812 }
1813
1814 /// Build a new OpenMP 'proc_bind' clause.
1815 ///
1816 /// By default, performs semantic analysis to build the new OpenMP clause.
1817 /// Subclasses may override this routine to provide different behavior.
RebuildOMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1818 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1819 SourceLocation KindKwLoc,
1820 SourceLocation StartLoc,
1821 SourceLocation LParenLoc,
1822 SourceLocation EndLoc) {
1823 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1824 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1825 }
1826
1827 /// Build a new OpenMP 'schedule' clause.
1828 ///
1829 /// By default, performs semantic analysis to build the new OpenMP clause.
1830 /// Subclasses may override this routine to provide different behavior.
RebuildOMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)1831 OMPClause *RebuildOMPScheduleClause(
1832 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1833 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1834 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1835 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1836 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1837 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1838 CommaLoc, EndLoc);
1839 }
1840
1841 /// Build a new OpenMP 'ordered' clause.
1842 ///
1843 /// By default, performs semantic analysis to build the new OpenMP clause.
1844 /// Subclasses may override this routine to provide different behavior.
RebuildOMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * Num)1845 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1846 SourceLocation EndLoc,
1847 SourceLocation LParenLoc, Expr *Num) {
1848 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1849 LParenLoc, Num);
1850 }
1851
1852 /// Build a new OpenMP 'private' clause.
1853 ///
1854 /// By default, performs semantic analysis to build the new OpenMP clause.
1855 /// Subclasses may override this routine to provide different behavior.
RebuildOMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1856 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1857 SourceLocation StartLoc,
1858 SourceLocation LParenLoc,
1859 SourceLocation EndLoc) {
1860 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1861 LParenLoc, EndLoc);
1862 }
1863
1864 /// Build a new OpenMP 'firstprivate' clause.
1865 ///
1866 /// By default, performs semantic analysis to build the new OpenMP clause.
1867 /// Subclasses may override this routine to provide different behavior.
RebuildOMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1868 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1869 SourceLocation StartLoc,
1870 SourceLocation LParenLoc,
1871 SourceLocation EndLoc) {
1872 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1873 LParenLoc, EndLoc);
1874 }
1875
1876 /// Build a new OpenMP 'lastprivate' clause.
1877 ///
1878 /// By default, performs semantic analysis to build the new OpenMP clause.
1879 /// Subclasses may override this routine to provide different behavior.
RebuildOMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1880 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1881 OpenMPLastprivateModifier LPKind,
1882 SourceLocation LPKindLoc,
1883 SourceLocation ColonLoc,
1884 SourceLocation StartLoc,
1885 SourceLocation LParenLoc,
1886 SourceLocation EndLoc) {
1887 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1888 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1889 }
1890
1891 /// Build a new OpenMP 'shared' clause.
1892 ///
1893 /// By default, performs semantic analysis to build the new OpenMP clause.
1894 /// Subclasses may override this routine to provide different behavior.
RebuildOMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1895 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1896 SourceLocation StartLoc,
1897 SourceLocation LParenLoc,
1898 SourceLocation EndLoc) {
1899 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1900 LParenLoc, EndLoc);
1901 }
1902
1903 /// Build a new OpenMP 'reduction' clause.
1904 ///
1905 /// By default, performs semantic analysis to build the new statement.
1906 /// Subclasses may override this routine to provide different behavior.
RebuildOMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,OpenMPOriginalSharingModifier OriginalSharingModifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)1907 OMPClause *RebuildOMPReductionClause(
1908 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1909 OpenMPOriginalSharingModifier OriginalSharingModifier,
1910 SourceLocation StartLoc, SourceLocation LParenLoc,
1911 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1912 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1913 const DeclarationNameInfo &ReductionId,
1914 ArrayRef<Expr *> UnresolvedReductions) {
1915 return getSema().OpenMP().ActOnOpenMPReductionClause(
1916 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1917 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1918 UnresolvedReductions);
1919 }
1920
1921 /// Build a new OpenMP 'task_reduction' clause.
1922 ///
1923 /// By default, performs semantic analysis to build the new statement.
1924 /// Subclasses may override this routine to provide different behavior.
RebuildOMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)1925 OMPClause *RebuildOMPTaskReductionClause(
1926 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1927 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1928 CXXScopeSpec &ReductionIdScopeSpec,
1929 const DeclarationNameInfo &ReductionId,
1930 ArrayRef<Expr *> UnresolvedReductions) {
1931 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1932 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1933 ReductionId, UnresolvedReductions);
1934 }
1935
1936 /// Build a new OpenMP 'in_reduction' clause.
1937 ///
1938 /// By default, performs semantic analysis to build the new statement.
1939 /// Subclasses may override this routine to provide different behavior.
1940 OMPClause *
RebuildOMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)1941 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1942 SourceLocation LParenLoc, SourceLocation ColonLoc,
1943 SourceLocation EndLoc,
1944 CXXScopeSpec &ReductionIdScopeSpec,
1945 const DeclarationNameInfo &ReductionId,
1946 ArrayRef<Expr *> UnresolvedReductions) {
1947 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1948 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1949 ReductionId, UnresolvedReductions);
1950 }
1951
1952 /// Build a new OpenMP 'linear' clause.
1953 ///
1954 /// By default, performs semantic analysis to build the new OpenMP clause.
1955 /// Subclasses may override this routine to provide different behavior.
RebuildOMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind Modifier,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation StepModifierLoc,SourceLocation EndLoc)1956 OMPClause *RebuildOMPLinearClause(
1957 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1958 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1959 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1960 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1961 return getSema().OpenMP().ActOnOpenMPLinearClause(
1962 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1963 StepModifierLoc, EndLoc);
1964 }
1965
1966 /// Build a new OpenMP 'aligned' clause.
1967 ///
1968 /// By default, performs semantic analysis to build the new OpenMP clause.
1969 /// Subclasses may override this routine to provide different behavior.
RebuildOMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)1970 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1971 SourceLocation StartLoc,
1972 SourceLocation LParenLoc,
1973 SourceLocation ColonLoc,
1974 SourceLocation EndLoc) {
1975 return getSema().OpenMP().ActOnOpenMPAlignedClause(
1976 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1977 }
1978
1979 /// Build a new OpenMP 'copyin' clause.
1980 ///
1981 /// By default, performs semantic analysis to build the new OpenMP clause.
1982 /// Subclasses may override this routine to provide different behavior.
RebuildOMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1983 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1984 SourceLocation StartLoc,
1985 SourceLocation LParenLoc,
1986 SourceLocation EndLoc) {
1987 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1988 LParenLoc, EndLoc);
1989 }
1990
1991 /// Build a new OpenMP 'copyprivate' clause.
1992 ///
1993 /// By default, performs semantic analysis to build the new OpenMP clause.
1994 /// Subclasses may override this routine to provide different behavior.
RebuildOMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)1995 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1996 SourceLocation StartLoc,
1997 SourceLocation LParenLoc,
1998 SourceLocation EndLoc) {
1999 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2000 LParenLoc, EndLoc);
2001 }
2002
2003 /// Build a new OpenMP 'flush' pseudo clause.
2004 ///
2005 /// By default, performs semantic analysis to build the new OpenMP clause.
2006 /// Subclasses may override this routine to provide different behavior.
RebuildOMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2007 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2008 SourceLocation StartLoc,
2009 SourceLocation LParenLoc,
2010 SourceLocation EndLoc) {
2011 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2012 LParenLoc, EndLoc);
2013 }
2014
2015 /// Build a new OpenMP 'depobj' pseudo clause.
2016 ///
2017 /// By default, performs semantic analysis to build the new OpenMP clause.
2018 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2019 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2020 SourceLocation LParenLoc,
2021 SourceLocation EndLoc) {
2022 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2023 LParenLoc, EndLoc);
2024 }
2025
2026 /// Build a new OpenMP 'depend' pseudo clause.
2027 ///
2028 /// By default, performs semantic analysis to build the new OpenMP clause.
2029 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDependClause(OMPDependClause::DependDataTy Data,Expr * DepModifier,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2030 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2031 Expr *DepModifier, ArrayRef<Expr *> VarList,
2032 SourceLocation StartLoc,
2033 SourceLocation LParenLoc,
2034 SourceLocation EndLoc) {
2035 return getSema().OpenMP().ActOnOpenMPDependClause(
2036 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2037 }
2038
2039 /// Build a new OpenMP 'device' clause.
2040 ///
2041 /// By default, performs semantic analysis to build the new statement.
2042 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)2043 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2044 Expr *Device, SourceLocation StartLoc,
2045 SourceLocation LParenLoc,
2046 SourceLocation ModifierLoc,
2047 SourceLocation EndLoc) {
2048 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2049 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2050 }
2051
2052 /// Build a new OpenMP 'map' clause.
2053 ///
2054 /// By default, performs semantic analysis to build the new OpenMP clause.
2055 /// Subclasses may override this routine to provide different behavior.
RebuildOMPMapClause(Expr * IteratorModifier,ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,CXXScopeSpec MapperIdScopeSpec,DeclarationNameInfo MapperId,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)2056 OMPClause *RebuildOMPMapClause(
2057 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2058 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2059 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2060 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2061 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2062 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2063 return getSema().OpenMP().ActOnOpenMPMapClause(
2064 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2065 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2066 ColonLoc, VarList, Locs,
2067 /*NoDiagnose=*/false, UnresolvedMappers);
2068 }
2069
2070 /// Build a new OpenMP 'allocate' clause.
2071 ///
2072 /// By default, performs semantic analysis to build the new OpenMP clause.
2073 /// Subclasses may override this routine to provide different behavior.
2074 OMPClause *
RebuildOMPAllocateClause(Expr * Allocate,Expr * Alignment,OpenMPAllocateClauseModifier FirstModifier,SourceLocation FirstModifierLoc,OpenMPAllocateClauseModifier SecondModifier,SourceLocation SecondModifierLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)2075 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2076 OpenMPAllocateClauseModifier FirstModifier,
2077 SourceLocation FirstModifierLoc,
2078 OpenMPAllocateClauseModifier SecondModifier,
2079 SourceLocation SecondModifierLoc,
2080 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2081 SourceLocation LParenLoc, SourceLocation ColonLoc,
2082 SourceLocation EndLoc) {
2083 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2084 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2085 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2086 }
2087
2088 /// Build a new OpenMP 'num_teams' clause.
2089 ///
2090 /// By default, performs semantic analysis to build the new statement.
2091 /// Subclasses may override this routine to provide different behavior.
RebuildOMPNumTeamsClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2092 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2093 SourceLocation StartLoc,
2094 SourceLocation LParenLoc,
2095 SourceLocation EndLoc) {
2096 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2097 LParenLoc, EndLoc);
2098 }
2099
2100 /// Build a new OpenMP 'thread_limit' clause.
2101 ///
2102 /// By default, performs semantic analysis to build the new statement.
2103 /// Subclasses may override this routine to provide different behavior.
RebuildOMPThreadLimitClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2104 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2105 SourceLocation StartLoc,
2106 SourceLocation LParenLoc,
2107 SourceLocation EndLoc) {
2108 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2109 LParenLoc, EndLoc);
2110 }
2111
2112 /// Build a new OpenMP 'priority' clause.
2113 ///
2114 /// By default, performs semantic analysis to build the new statement.
2115 /// Subclasses may override this routine to provide different behavior.
RebuildOMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2116 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2117 SourceLocation LParenLoc,
2118 SourceLocation EndLoc) {
2119 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2120 LParenLoc, EndLoc);
2121 }
2122
2123 /// Build a new OpenMP 'grainsize' clause.
2124 ///
2125 /// By default, performs semantic analysis to build the new statement.
2126 /// Subclasses may override this routine to provide different behavior.
RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)2127 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2128 Expr *Device, SourceLocation StartLoc,
2129 SourceLocation LParenLoc,
2130 SourceLocation ModifierLoc,
2131 SourceLocation EndLoc) {
2132 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2133 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2134 }
2135
2136 /// Build a new OpenMP 'num_tasks' clause.
2137 ///
2138 /// By default, performs semantic analysis to build the new statement.
2139 /// Subclasses may override this routine to provide different behavior.
RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)2140 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2141 Expr *NumTasks, SourceLocation StartLoc,
2142 SourceLocation LParenLoc,
2143 SourceLocation ModifierLoc,
2144 SourceLocation EndLoc) {
2145 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2146 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2147 }
2148
2149 /// Build a new OpenMP 'hint' clause.
2150 ///
2151 /// By default, performs semantic analysis to build the new statement.
2152 /// Subclasses may override this routine to provide different behavior.
RebuildOMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2153 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2154 SourceLocation LParenLoc,
2155 SourceLocation EndLoc) {
2156 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2157 EndLoc);
2158 }
2159
2160 /// Build a new OpenMP 'detach' clause.
2161 ///
2162 /// By default, performs semantic analysis to build the new statement.
2163 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2164 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2165 SourceLocation LParenLoc,
2166 SourceLocation EndLoc) {
2167 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2168 EndLoc);
2169 }
2170
2171 /// Build a new OpenMP 'dist_schedule' clause.
2172 ///
2173 /// By default, performs semantic analysis to build the new OpenMP clause.
2174 /// Subclasses may override this routine to provide different behavior.
2175 OMPClause *
RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)2176 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2177 Expr *ChunkSize, SourceLocation StartLoc,
2178 SourceLocation LParenLoc, SourceLocation KindLoc,
2179 SourceLocation CommaLoc, SourceLocation EndLoc) {
2180 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2181 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2182 }
2183
2184 /// Build a new OpenMP 'to' clause.
2185 ///
2186 /// By default, performs semantic analysis to build the new statement.
2187 /// Subclasses may override this routine to provide different behavior.
2188 OMPClause *
RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)2189 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2190 ArrayRef<SourceLocation> MotionModifiersLoc,
2191 CXXScopeSpec &MapperIdScopeSpec,
2192 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2193 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2194 ArrayRef<Expr *> UnresolvedMappers) {
2195 return getSema().OpenMP().ActOnOpenMPToClause(
2196 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2197 ColonLoc, VarList, Locs, UnresolvedMappers);
2198 }
2199
2200 /// Build a new OpenMP 'from' clause.
2201 ///
2202 /// By default, performs semantic analysis to build the new statement.
2203 /// Subclasses may override this routine to provide different behavior.
2204 OMPClause *
RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)2205 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2206 ArrayRef<SourceLocation> MotionModifiersLoc,
2207 CXXScopeSpec &MapperIdScopeSpec,
2208 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2209 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2210 ArrayRef<Expr *> UnresolvedMappers) {
2211 return getSema().OpenMP().ActOnOpenMPFromClause(
2212 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2213 ColonLoc, VarList, Locs, UnresolvedMappers);
2214 }
2215
2216 /// Build a new OpenMP 'use_device_ptr' clause.
2217 ///
2218 /// By default, performs semantic analysis to build the new OpenMP clause.
2219 /// Subclasses may override this routine to provide different behavior.
RebuildOMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)2220 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2221 const OMPVarListLocTy &Locs) {
2222 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2223 }
2224
2225 /// Build a new OpenMP 'use_device_addr' clause.
2226 ///
2227 /// By default, performs semantic analysis to build the new OpenMP clause.
2228 /// Subclasses may override this routine to provide different behavior.
RebuildOMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)2229 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2230 const OMPVarListLocTy &Locs) {
2231 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2232 }
2233
2234 /// Build a new OpenMP 'is_device_ptr' clause.
2235 ///
2236 /// By default, performs semantic analysis to build the new OpenMP clause.
2237 /// Subclasses may override this routine to provide different behavior.
RebuildOMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)2238 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2239 const OMPVarListLocTy &Locs) {
2240 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2241 }
2242
2243 /// Build a new OpenMP 'has_device_addr' clause.
2244 ///
2245 /// By default, performs semantic analysis to build the new OpenMP clause.
2246 /// Subclasses may override this routine to provide different behavior.
RebuildOMPHasDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)2247 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2248 const OMPVarListLocTy &Locs) {
2249 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2250 }
2251
2252 /// Build a new OpenMP 'defaultmap' clause.
2253 ///
2254 /// By default, performs semantic analysis to build the new OpenMP clause.
2255 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)2256 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2257 OpenMPDefaultmapClauseKind Kind,
2258 SourceLocation StartLoc,
2259 SourceLocation LParenLoc,
2260 SourceLocation MLoc,
2261 SourceLocation KindLoc,
2262 SourceLocation EndLoc) {
2263 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2264 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2265 }
2266
2267 /// Build a new OpenMP 'nontemporal' clause.
2268 ///
2269 /// By default, performs semantic analysis to build the new OpenMP clause.
2270 /// Subclasses may override this routine to provide different behavior.
RebuildOMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2271 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2272 SourceLocation StartLoc,
2273 SourceLocation LParenLoc,
2274 SourceLocation EndLoc) {
2275 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2276 LParenLoc, EndLoc);
2277 }
2278
2279 /// Build a new OpenMP 'inclusive' clause.
2280 ///
2281 /// By default, performs semantic analysis to build the new OpenMP clause.
2282 /// Subclasses may override this routine to provide different behavior.
RebuildOMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2283 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2284 SourceLocation StartLoc,
2285 SourceLocation LParenLoc,
2286 SourceLocation EndLoc) {
2287 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2288 LParenLoc, EndLoc);
2289 }
2290
2291 /// Build a new OpenMP 'exclusive' clause.
2292 ///
2293 /// By default, performs semantic analysis to build the new OpenMP clause.
2294 /// Subclasses may override this routine to provide different behavior.
RebuildOMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2295 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2296 SourceLocation StartLoc,
2297 SourceLocation LParenLoc,
2298 SourceLocation EndLoc) {
2299 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2300 LParenLoc, EndLoc);
2301 }
2302
2303 /// Build a new OpenMP 'uses_allocators' clause.
2304 ///
2305 /// By default, performs semantic analysis to build the new OpenMP clause.
2306 /// Subclasses may override this routine to provide different behavior.
RebuildOMPUsesAllocatorsClause(ArrayRef<SemaOpenMP::UsesAllocatorsData> Data,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2307 OMPClause *RebuildOMPUsesAllocatorsClause(
2308 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2309 SourceLocation LParenLoc, SourceLocation EndLoc) {
2310 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2311 StartLoc, LParenLoc, EndLoc, Data);
2312 }
2313
2314 /// Build a new OpenMP 'affinity' clause.
2315 ///
2316 /// By default, performs semantic analysis to build the new OpenMP clause.
2317 /// Subclasses may override this routine to provide different behavior.
RebuildOMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)2318 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2319 SourceLocation LParenLoc,
2320 SourceLocation ColonLoc,
2321 SourceLocation EndLoc, Expr *Modifier,
2322 ArrayRef<Expr *> Locators) {
2323 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2324 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2325 }
2326
2327 /// Build a new OpenMP 'order' clause.
2328 ///
2329 /// By default, performs semantic analysis to build the new OpenMP clause.
2330 /// Subclasses may override this routine to provide different behavior.
RebuildOMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,OpenMPOrderClauseModifier Modifier,SourceLocation ModifierKwLoc)2331 OMPClause *RebuildOMPOrderClause(
2332 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2333 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2334 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2335 return getSema().OpenMP().ActOnOpenMPOrderClause(
2336 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2337 }
2338
2339 /// Build a new OpenMP 'init' clause.
2340 ///
2341 /// By default, performs semantic analysis to build the new OpenMP clause.
2342 /// Subclasses may override this routine to provide different behavior.
RebuildOMPInitClause(Expr * InteropVar,OMPInteropInfo & InteropInfo,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)2343 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2344 SourceLocation StartLoc,
2345 SourceLocation LParenLoc,
2346 SourceLocation VarLoc,
2347 SourceLocation EndLoc) {
2348 return getSema().OpenMP().ActOnOpenMPInitClause(
2349 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2350 }
2351
2352 /// Build a new OpenMP 'use' clause.
2353 ///
2354 /// By default, performs semantic analysis to build the new OpenMP clause.
2355 /// Subclasses may override this routine to provide different behavior.
RebuildOMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)2356 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2357 SourceLocation LParenLoc,
2358 SourceLocation VarLoc, SourceLocation EndLoc) {
2359 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2360 LParenLoc, VarLoc, EndLoc);
2361 }
2362
2363 /// Build a new OpenMP 'destroy' clause.
2364 ///
2365 /// By default, performs semantic analysis to build the new OpenMP clause.
2366 /// Subclasses may override this routine to provide different behavior.
RebuildOMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)2367 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2368 SourceLocation LParenLoc,
2369 SourceLocation VarLoc,
2370 SourceLocation EndLoc) {
2371 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2372 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2373 }
2374
2375 /// Build a new OpenMP 'novariants' clause.
2376 ///
2377 /// By default, performs semantic analysis to build the new OpenMP clause.
2378 /// Subclasses may override this routine to provide different behavior.
RebuildOMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2379 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2380 SourceLocation StartLoc,
2381 SourceLocation LParenLoc,
2382 SourceLocation EndLoc) {
2383 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2384 LParenLoc, EndLoc);
2385 }
2386
2387 /// Build a new OpenMP 'nocontext' clause.
2388 ///
2389 /// By default, performs semantic analysis to build the new OpenMP clause.
2390 /// Subclasses may override this routine to provide different behavior.
RebuildOMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2391 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2392 SourceLocation LParenLoc,
2393 SourceLocation EndLoc) {
2394 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2395 LParenLoc, EndLoc);
2396 }
2397
2398 /// Build a new OpenMP 'filter' clause.
2399 ///
2400 /// By default, performs semantic analysis to build the new OpenMP clause.
2401 /// Subclasses may override this routine to provide different behavior.
RebuildOMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2402 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2403 SourceLocation LParenLoc,
2404 SourceLocation EndLoc) {
2405 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2406 LParenLoc, EndLoc);
2407 }
2408
2409 /// Build a new OpenMP 'bind' clause.
2410 ///
2411 /// By default, performs semantic analysis to build the new OpenMP clause.
2412 /// Subclasses may override this routine to provide different behavior.
RebuildOMPBindClause(OpenMPBindClauseKind Kind,SourceLocation KindLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2413 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2414 SourceLocation KindLoc,
2415 SourceLocation StartLoc,
2416 SourceLocation LParenLoc,
2417 SourceLocation EndLoc) {
2418 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2419 LParenLoc, EndLoc);
2420 }
2421
2422 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2423 ///
2424 /// By default, performs semantic analysis to build the new OpenMP clause.
2425 /// Subclasses may override this routine to provide different behavior.
RebuildOMPXDynCGroupMemClause(Expr * Size,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2426 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2427 SourceLocation LParenLoc,
2428 SourceLocation EndLoc) {
2429 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2430 LParenLoc, EndLoc);
2431 }
2432
2433 /// Build a new OpenMP 'ompx_attribute' clause.
2434 ///
2435 /// By default, performs semantic analysis to build the new OpenMP clause.
2436 /// Subclasses may override this routine to provide different behavior.
RebuildOMPXAttributeClause(ArrayRef<const Attr * > Attrs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2437 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2438 SourceLocation StartLoc,
2439 SourceLocation LParenLoc,
2440 SourceLocation EndLoc) {
2441 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2442 LParenLoc, EndLoc);
2443 }
2444
2445 /// Build a new OpenMP 'ompx_bare' clause.
2446 ///
2447 /// By default, performs semantic analysis to build the new OpenMP clause.
2448 /// Subclasses may override this routine to provide different behavior.
RebuildOMPXBareClause(SourceLocation StartLoc,SourceLocation EndLoc)2449 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2450 SourceLocation EndLoc) {
2451 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2452 }
2453
2454 /// Build a new OpenMP 'align' clause.
2455 ///
2456 /// By default, performs semantic analysis to build the new OpenMP clause.
2457 /// Subclasses may override this routine to provide different behavior.
RebuildOMPAlignClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2458 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2459 SourceLocation LParenLoc,
2460 SourceLocation EndLoc) {
2461 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2462 EndLoc);
2463 }
2464
2465 /// Build a new OpenMP 'at' clause.
2466 ///
2467 /// By default, performs semantic analysis to build the new OpenMP clause.
2468 /// Subclasses may override this routine to provide different behavior.
RebuildOMPAtClause(OpenMPAtClauseKind Kind,SourceLocation KwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2469 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2470 SourceLocation StartLoc,
2471 SourceLocation LParenLoc,
2472 SourceLocation EndLoc) {
2473 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2474 LParenLoc, EndLoc);
2475 }
2476
2477 /// Build a new OpenMP 'severity' clause.
2478 ///
2479 /// By default, performs semantic analysis to build the new OpenMP clause.
2480 /// Subclasses may override this routine to provide different behavior.
RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,SourceLocation KwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2481 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2482 SourceLocation KwLoc,
2483 SourceLocation StartLoc,
2484 SourceLocation LParenLoc,
2485 SourceLocation EndLoc) {
2486 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2487 LParenLoc, EndLoc);
2488 }
2489
2490 /// Build a new OpenMP 'message' clause.
2491 ///
2492 /// By default, performs semantic analysis to build the new OpenMP clause.
2493 /// Subclasses may override this routine to provide different behavior.
RebuildOMPMessageClause(Expr * MS,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2494 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2495 SourceLocation LParenLoc,
2496 SourceLocation EndLoc) {
2497 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2498 EndLoc);
2499 }
2500
2501 /// Build a new OpenMP 'doacross' clause.
2502 ///
2503 /// By default, performs semantic analysis to build the new OpenMP clause.
2504 /// Subclasses may override this routine to provide different behavior.
2505 OMPClause *
RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2506 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2507 SourceLocation DepLoc, SourceLocation ColonLoc,
2508 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2509 SourceLocation LParenLoc, SourceLocation EndLoc) {
2510 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2511 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2512 }
2513
2514 /// Build a new OpenMP 'holds' clause.
RebuildOMPHoldsClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)2515 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2516 SourceLocation LParenLoc,
2517 SourceLocation EndLoc) {
2518 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2519 EndLoc);
2520 }
2521
2522 /// Rebuild the operand to an Objective-C \@synchronized statement.
2523 ///
2524 /// By default, performs semantic analysis to build the new statement.
2525 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,Expr * object)2526 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2527 Expr *object) {
2528 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2529 }
2530
2531 /// Build a new Objective-C \@synchronized statement.
2532 ///
2533 /// By default, performs semantic analysis to build the new statement.
2534 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,Expr * Object,Stmt * Body)2535 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2536 Expr *Object, Stmt *Body) {
2537 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2538 }
2539
2540 /// Build a new Objective-C \@autoreleasepool statement.
2541 ///
2542 /// By default, performs semantic analysis to build the new statement.
2543 /// Subclasses may override this routine to provide different behavior.
RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,Stmt * Body)2544 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2545 Stmt *Body) {
2546 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2547 }
2548
2549 /// Build a new Objective-C fast enumeration statement.
2550 ///
2551 /// By default, performs semantic analysis to build the new statement.
2552 /// Subclasses may override this routine to provide different behavior.
RebuildObjCForCollectionStmt(SourceLocation ForLoc,Stmt * Element,Expr * Collection,SourceLocation RParenLoc,Stmt * Body)2553 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2554 Stmt *Element,
2555 Expr *Collection,
2556 SourceLocation RParenLoc,
2557 Stmt *Body) {
2558 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2559 ForLoc, Element, Collection, RParenLoc);
2560 if (ForEachStmt.isInvalid())
2561 return StmtError();
2562
2563 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2564 Body);
2565 }
2566
2567 /// Build a new C++ exception declaration.
2568 ///
2569 /// By default, performs semantic analysis to build the new decaration.
2570 /// Subclasses may override this routine to provide different behavior.
RebuildExceptionDecl(VarDecl * ExceptionDecl,TypeSourceInfo * Declarator,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id)2571 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2572 TypeSourceInfo *Declarator,
2573 SourceLocation StartLoc,
2574 SourceLocation IdLoc,
2575 IdentifierInfo *Id) {
2576 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2577 StartLoc, IdLoc, Id);
2578 if (Var)
2579 getSema().CurContext->addDecl(Var);
2580 return Var;
2581 }
2582
2583 /// Build a new C++ catch statement.
2584 ///
2585 /// By default, performs semantic analysis to build the new statement.
2586 /// Subclasses may override this routine to provide different behavior.
RebuildCXXCatchStmt(SourceLocation CatchLoc,VarDecl * ExceptionDecl,Stmt * Handler)2587 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2588 VarDecl *ExceptionDecl,
2589 Stmt *Handler) {
2590 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2591 Handler));
2592 }
2593
2594 /// Build a new C++ try statement.
2595 ///
2596 /// By default, performs semantic analysis to build the new statement.
2597 /// Subclasses may override this routine to provide different behavior.
RebuildCXXTryStmt(SourceLocation TryLoc,Stmt * TryBlock,ArrayRef<Stmt * > Handlers)2598 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2599 ArrayRef<Stmt *> Handlers) {
2600 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2601 }
2602
2603 /// Build a new C++0x range-based for statement.
2604 ///
2605 /// By default, performs semantic analysis to build the new statement.
2606 /// Subclasses may override this routine to provide different behavior.
RebuildCXXForRangeStmt(SourceLocation ForLoc,SourceLocation CoawaitLoc,Stmt * Init,SourceLocation ColonLoc,Stmt * Range,Stmt * Begin,Stmt * End,Expr * Cond,Expr * Inc,Stmt * LoopVar,SourceLocation RParenLoc,ArrayRef<MaterializeTemporaryExpr * > LifetimeExtendTemps)2607 StmtResult RebuildCXXForRangeStmt(
2608 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2609 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2610 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2611 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2612 // If we've just learned that the range is actually an Objective-C
2613 // collection, treat this as an Objective-C fast enumeration loop.
2614 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2615 if (RangeStmt->isSingleDecl()) {
2616 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2617 if (RangeVar->isInvalidDecl())
2618 return StmtError();
2619
2620 Expr *RangeExpr = RangeVar->getInit();
2621 if (!RangeExpr->isTypeDependent() &&
2622 RangeExpr->getType()->isObjCObjectPointerType()) {
2623 // FIXME: Support init-statements in Objective-C++20 ranged for
2624 // statement.
2625 if (Init) {
2626 return SemaRef.Diag(Init->getBeginLoc(),
2627 diag::err_objc_for_range_init_stmt)
2628 << Init->getSourceRange();
2629 }
2630 return getSema().ObjC().ActOnObjCForCollectionStmt(
2631 ForLoc, LoopVar, RangeExpr, RParenLoc);
2632 }
2633 }
2634 }
2635 }
2636
2637 return getSema().BuildCXXForRangeStmt(
2638 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2639 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2640 }
2641
2642 /// Build a new C++0x range-based for statement.
2643 ///
2644 /// By default, performs semantic analysis to build the new statement.
2645 /// Subclasses may override this routine to provide different behavior.
RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,bool IsIfExists,NestedNameSpecifierLoc QualifierLoc,DeclarationNameInfo NameInfo,Stmt * Nested)2646 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2647 bool IsIfExists,
2648 NestedNameSpecifierLoc QualifierLoc,
2649 DeclarationNameInfo NameInfo,
2650 Stmt *Nested) {
2651 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2652 QualifierLoc, NameInfo, Nested);
2653 }
2654
2655 /// Attach body to a C++0x range-based for statement.
2656 ///
2657 /// By default, performs semantic analysis to finish the new statement.
2658 /// Subclasses may override this routine to provide different behavior.
FinishCXXForRangeStmt(Stmt * ForRange,Stmt * Body)2659 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2660 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2661 }
2662
RebuildSEHTryStmt(bool IsCXXTry,SourceLocation TryLoc,Stmt * TryBlock,Stmt * Handler)2663 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2664 Stmt *TryBlock, Stmt *Handler) {
2665 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2666 }
2667
RebuildSEHExceptStmt(SourceLocation Loc,Expr * FilterExpr,Stmt * Block)2668 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2669 Stmt *Block) {
2670 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2671 }
2672
RebuildSEHFinallyStmt(SourceLocation Loc,Stmt * Block)2673 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2674 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2675 }
2676
RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,SourceLocation LParen,SourceLocation RParen,TypeSourceInfo * TSI)2677 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2678 SourceLocation LParen,
2679 SourceLocation RParen,
2680 TypeSourceInfo *TSI) {
2681 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2682 TSI);
2683 }
2684
2685 /// Build a new predefined expression.
2686 ///
2687 /// By default, performs semantic analysis to build the new expression.
2688 /// Subclasses may override this routine to provide different behavior.
RebuildPredefinedExpr(SourceLocation Loc,PredefinedIdentKind IK)2689 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2690 return getSema().BuildPredefinedExpr(Loc, IK);
2691 }
2692
2693 /// Build a new expression that references a declaration.
2694 ///
2695 /// By default, performs semantic analysis to build the new expression.
2696 /// Subclasses may override this routine to provide different behavior.
RebuildDeclarationNameExpr(const CXXScopeSpec & SS,LookupResult & R,bool RequiresADL)2697 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2698 LookupResult &R,
2699 bool RequiresADL) {
2700 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2701 }
2702
2703
2704 /// Build a new expression that references a declaration.
2705 ///
2706 /// By default, performs semantic analysis to build the new expression.
2707 /// Subclasses may override this routine to provide different behavior.
RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,ValueDecl * VD,const DeclarationNameInfo & NameInfo,NamedDecl * Found,TemplateArgumentListInfo * TemplateArgs)2708 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2709 ValueDecl *VD,
2710 const DeclarationNameInfo &NameInfo,
2711 NamedDecl *Found,
2712 TemplateArgumentListInfo *TemplateArgs) {
2713 CXXScopeSpec SS;
2714 SS.Adopt(QualifierLoc);
2715 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2716 TemplateArgs);
2717 }
2718
2719 /// Build a new expression in parentheses.
2720 ///
2721 /// By default, performs semantic analysis to build the new expression.
2722 /// Subclasses may override this routine to provide different behavior.
RebuildParenExpr(Expr * SubExpr,SourceLocation LParen,SourceLocation RParen)2723 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2724 SourceLocation RParen) {
2725 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2726 }
2727
2728 /// Build a new pseudo-destructor expression.
2729 ///
2730 /// By default, performs semantic analysis to build the new expression.
2731 /// Subclasses may override this routine to provide different behavior.
2732 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2733 SourceLocation OperatorLoc,
2734 bool isArrow,
2735 CXXScopeSpec &SS,
2736 TypeSourceInfo *ScopeType,
2737 SourceLocation CCLoc,
2738 SourceLocation TildeLoc,
2739 PseudoDestructorTypeStorage Destroyed);
2740
2741 /// Build a new unary operator expression.
2742 ///
2743 /// By default, performs semantic analysis to build the new expression.
2744 /// Subclasses may override this routine to provide different behavior.
RebuildUnaryOperator(SourceLocation OpLoc,UnaryOperatorKind Opc,Expr * SubExpr)2745 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2746 UnaryOperatorKind Opc,
2747 Expr *SubExpr) {
2748 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2749 }
2750
2751 /// Build a new builtin offsetof expression.
2752 ///
2753 /// By default, performs semantic analysis to build the new expression.
2754 /// Subclasses may override this routine to provide different behavior.
RebuildOffsetOfExpr(SourceLocation OperatorLoc,TypeSourceInfo * Type,ArrayRef<Sema::OffsetOfComponent> Components,SourceLocation RParenLoc)2755 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2756 TypeSourceInfo *Type,
2757 ArrayRef<Sema::OffsetOfComponent> Components,
2758 SourceLocation RParenLoc) {
2759 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2760 RParenLoc);
2761 }
2762
2763 /// Build a new sizeof, alignof or vec_step expression with a
2764 /// type argument.
2765 ///
2766 /// By default, performs semantic analysis to build the new expression.
2767 /// Subclasses may override this routine to provide different behavior.
RebuildUnaryExprOrTypeTrait(TypeSourceInfo * TInfo,SourceLocation OpLoc,UnaryExprOrTypeTrait ExprKind,SourceRange R)2768 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2769 SourceLocation OpLoc,
2770 UnaryExprOrTypeTrait ExprKind,
2771 SourceRange R) {
2772 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2773 }
2774
2775 /// Build a new sizeof, alignof or vec step expression with an
2776 /// expression argument.
2777 ///
2778 /// By default, performs semantic analysis to build the new expression.
2779 /// Subclasses may override this routine to provide different behavior.
RebuildUnaryExprOrTypeTrait(Expr * SubExpr,SourceLocation OpLoc,UnaryExprOrTypeTrait ExprKind,SourceRange R)2780 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2781 UnaryExprOrTypeTrait ExprKind,
2782 SourceRange R) {
2783 ExprResult Result
2784 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2785 if (Result.isInvalid())
2786 return ExprError();
2787
2788 return Result;
2789 }
2790
2791 /// Build a new array subscript expression.
2792 ///
2793 /// By default, performs semantic analysis to build the new expression.
2794 /// Subclasses may override this routine to provide different behavior.
RebuildArraySubscriptExpr(Expr * LHS,SourceLocation LBracketLoc,Expr * RHS,SourceLocation RBracketLoc)2795 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2796 SourceLocation LBracketLoc,
2797 Expr *RHS,
2798 SourceLocation RBracketLoc) {
2799 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2800 LBracketLoc, RHS,
2801 RBracketLoc);
2802 }
2803
2804 /// Build a new matrix subscript expression.
2805 ///
2806 /// By default, performs semantic analysis to build the new expression.
2807 /// Subclasses may override this routine to provide different behavior.
RebuildMatrixSubscriptExpr(Expr * Base,Expr * RowIdx,Expr * ColumnIdx,SourceLocation RBracketLoc)2808 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2809 Expr *ColumnIdx,
2810 SourceLocation RBracketLoc) {
2811 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2812 RBracketLoc);
2813 }
2814
2815 /// Build a new array section expression.
2816 ///
2817 /// By default, performs semantic analysis to build the new expression.
2818 /// Subclasses may override this routine to provide different behavior.
RebuildArraySectionExpr(bool IsOMPArraySection,Expr * Base,SourceLocation LBracketLoc,Expr * LowerBound,SourceLocation ColonLocFirst,SourceLocation ColonLocSecond,Expr * Length,Expr * Stride,SourceLocation RBracketLoc)2819 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2820 SourceLocation LBracketLoc,
2821 Expr *LowerBound,
2822 SourceLocation ColonLocFirst,
2823 SourceLocation ColonLocSecond,
2824 Expr *Length, Expr *Stride,
2825 SourceLocation RBracketLoc) {
2826 if (IsOMPArraySection)
2827 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2828 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2829 Stride, RBracketLoc);
2830
2831 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2832 "Stride/second colon not allowed for OpenACC");
2833
2834 return getSema().OpenACC().ActOnArraySectionExpr(
2835 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2836 }
2837
2838 /// Build a new array shaping expression.
2839 ///
2840 /// By default, performs semantic analysis to build the new expression.
2841 /// Subclasses may override this routine to provide different behavior.
RebuildOMPArrayShapingExpr(Expr * Base,SourceLocation LParenLoc,SourceLocation RParenLoc,ArrayRef<Expr * > Dims,ArrayRef<SourceRange> BracketsRanges)2842 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2843 SourceLocation RParenLoc,
2844 ArrayRef<Expr *> Dims,
2845 ArrayRef<SourceRange> BracketsRanges) {
2846 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2847 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2848 }
2849
2850 /// Build a new iterator expression.
2851 ///
2852 /// By default, performs semantic analysis to build the new expression.
2853 /// Subclasses may override this routine to provide different behavior.
2854 ExprResult
RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc,SourceLocation LLoc,SourceLocation RLoc,ArrayRef<SemaOpenMP::OMPIteratorData> Data)2855 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2856 SourceLocation RLoc,
2857 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2858 return getSema().OpenMP().ActOnOMPIteratorExpr(
2859 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2860 }
2861
2862 /// Build a new call expression.
2863 ///
2864 /// By default, performs semantic analysis to build the new expression.
2865 /// Subclasses may override this routine to provide different behavior.
2866 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2867 MultiExprArg Args,
2868 SourceLocation RParenLoc,
2869 Expr *ExecConfig = nullptr) {
2870 return getSema().ActOnCallExpr(
2871 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2872 }
2873
RebuildCxxSubscriptExpr(Expr * Callee,SourceLocation LParenLoc,MultiExprArg Args,SourceLocation RParenLoc)2874 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2875 MultiExprArg Args,
2876 SourceLocation RParenLoc) {
2877 return getSema().ActOnArraySubscriptExpr(
2878 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2879 }
2880
2881 /// Build a new member access expression.
2882 ///
2883 /// By default, performs semantic analysis to build the new expression.
2884 /// Subclasses may override this routine to provide different behavior.
RebuildMemberExpr(Expr * Base,SourceLocation OpLoc,bool isArrow,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & MemberNameInfo,ValueDecl * Member,NamedDecl * FoundDecl,const TemplateArgumentListInfo * ExplicitTemplateArgs,NamedDecl * FirstQualifierInScope)2885 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2886 bool isArrow,
2887 NestedNameSpecifierLoc QualifierLoc,
2888 SourceLocation TemplateKWLoc,
2889 const DeclarationNameInfo &MemberNameInfo,
2890 ValueDecl *Member,
2891 NamedDecl *FoundDecl,
2892 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2893 NamedDecl *FirstQualifierInScope) {
2894 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2895 isArrow);
2896 if (!Member->getDeclName()) {
2897 // We have a reference to an unnamed field. This is always the
2898 // base of an anonymous struct/union member access, i.e. the
2899 // field is always of record type.
2900 assert(Member->getType()->isRecordType() &&
2901 "unnamed member not of record type?");
2902
2903 BaseResult =
2904 getSema().PerformObjectMemberConversion(BaseResult.get(),
2905 QualifierLoc.getNestedNameSpecifier(),
2906 FoundDecl, Member);
2907 if (BaseResult.isInvalid())
2908 return ExprError();
2909 Base = BaseResult.get();
2910
2911 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2912 // from the AST, so we need to re-insert them if needed (since
2913 // `BuildFieldRefereneExpr()` doesn't do this).
2914 if (!isArrow && Base->isPRValue()) {
2915 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2916 if (BaseResult.isInvalid())
2917 return ExprError();
2918 Base = BaseResult.get();
2919 }
2920
2921 CXXScopeSpec EmptySS;
2922 return getSema().BuildFieldReferenceExpr(
2923 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2924 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
2925 MemberNameInfo);
2926 }
2927
2928 CXXScopeSpec SS;
2929 SS.Adopt(QualifierLoc);
2930
2931 Base = BaseResult.get();
2932 if (Base->containsErrors())
2933 return ExprError();
2934
2935 QualType BaseType = Base->getType();
2936
2937 if (isArrow && !BaseType->isPointerType())
2938 return ExprError();
2939
2940 // FIXME: this involves duplicating earlier analysis in a lot of
2941 // cases; we should avoid this when possible.
2942 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2943 R.addDecl(FoundDecl);
2944 R.resolveKind();
2945
2946 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2947 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2948 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2949 ->getType()
2950 ->getPointeeType()
2951 ->getAsCXXRecordDecl()) {
2952 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2953 // In unevaluated contexts, an expression supposed to be a member access
2954 // might reference a member in an unrelated class.
2955 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2956 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2957 VK_LValue, Member->getLocation());
2958 }
2959 }
2960
2961 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2962 SS, TemplateKWLoc,
2963 FirstQualifierInScope,
2964 R, ExplicitTemplateArgs,
2965 /*S*/nullptr);
2966 }
2967
2968 /// Build a new binary operator expression.
2969 ///
2970 /// By default, performs semantic analysis to build the new expression.
2971 /// Subclasses may override this routine to provide different behavior.
2972 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
2973 Expr *LHS, Expr *RHS,
2974 bool ForFoldExpression = false) {
2975 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
2976 ForFoldExpression);
2977 }
2978
2979 /// Build a new rewritten operator expression.
2980 ///
2981 /// By default, performs semantic analysis to build the new expression.
2982 /// Subclasses may override this routine to provide different behavior.
RebuildCXXRewrittenBinaryOperator(SourceLocation OpLoc,BinaryOperatorKind Opcode,const UnresolvedSetImpl & UnqualLookups,Expr * LHS,Expr * RHS)2983 ExprResult RebuildCXXRewrittenBinaryOperator(
2984 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2985 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2986 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2987 RHS, /*RequiresADL*/false);
2988 }
2989
2990 /// Build a new conditional operator expression.
2991 ///
2992 /// By default, performs semantic analysis to build the new expression.
2993 /// Subclasses may override this routine to provide different behavior.
RebuildConditionalOperator(Expr * Cond,SourceLocation QuestionLoc,Expr * LHS,SourceLocation ColonLoc,Expr * RHS)2994 ExprResult RebuildConditionalOperator(Expr *Cond,
2995 SourceLocation QuestionLoc,
2996 Expr *LHS,
2997 SourceLocation ColonLoc,
2998 Expr *RHS) {
2999 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3000 LHS, RHS);
3001 }
3002
3003 /// Build a new C-style cast expression.
3004 ///
3005 /// By default, performs semantic analysis to build the new expression.
3006 /// Subclasses may override this routine to provide different behavior.
RebuildCStyleCastExpr(SourceLocation LParenLoc,TypeSourceInfo * TInfo,SourceLocation RParenLoc,Expr * SubExpr)3007 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3008 TypeSourceInfo *TInfo,
3009 SourceLocation RParenLoc,
3010 Expr *SubExpr) {
3011 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3012 SubExpr);
3013 }
3014
3015 /// Build a new compound literal expression.
3016 ///
3017 /// By default, performs semantic analysis to build the new expression.
3018 /// Subclasses may override this routine to provide different behavior.
RebuildCompoundLiteralExpr(SourceLocation LParenLoc,TypeSourceInfo * TInfo,SourceLocation RParenLoc,Expr * Init)3019 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3020 TypeSourceInfo *TInfo,
3021 SourceLocation RParenLoc,
3022 Expr *Init) {
3023 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3024 Init);
3025 }
3026
3027 /// Build a new extended vector element access expression.
3028 ///
3029 /// By default, performs semantic analysis to build the new expression.
3030 /// Subclasses may override this routine to provide different behavior.
RebuildExtVectorElementExpr(Expr * Base,SourceLocation OpLoc,bool IsArrow,SourceLocation AccessorLoc,IdentifierInfo & Accessor)3031 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
3032 bool IsArrow,
3033 SourceLocation AccessorLoc,
3034 IdentifierInfo &Accessor) {
3035
3036 CXXScopeSpec SS;
3037 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3038 return getSema().BuildMemberReferenceExpr(
3039 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3040 /*FirstQualifierInScope*/ nullptr, NameInfo,
3041 /* TemplateArgs */ nullptr,
3042 /*S*/ nullptr);
3043 }
3044
3045 /// Build a new initializer list expression.
3046 ///
3047 /// By default, performs semantic analysis to build the new expression.
3048 /// Subclasses may override this routine to provide different behavior.
RebuildInitList(SourceLocation LBraceLoc,MultiExprArg Inits,SourceLocation RBraceLoc)3049 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3050 MultiExprArg Inits,
3051 SourceLocation RBraceLoc) {
3052 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
3053 }
3054
3055 /// Build a new designated initializer expression.
3056 ///
3057 /// By default, performs semantic analysis to build the new expression.
3058 /// Subclasses may override this routine to provide different behavior.
RebuildDesignatedInitExpr(Designation & Desig,MultiExprArg ArrayExprs,SourceLocation EqualOrColonLoc,bool GNUSyntax,Expr * Init)3059 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3060 MultiExprArg ArrayExprs,
3061 SourceLocation EqualOrColonLoc,
3062 bool GNUSyntax,
3063 Expr *Init) {
3064 ExprResult Result
3065 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3066 Init);
3067 if (Result.isInvalid())
3068 return ExprError();
3069
3070 return Result;
3071 }
3072
3073 /// Build a new value-initialized expression.
3074 ///
3075 /// By default, builds the implicit value initialization without performing
3076 /// any semantic analysis. Subclasses may override this routine to provide
3077 /// different behavior.
RebuildImplicitValueInitExpr(QualType T)3078 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3079 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3080 }
3081
3082 /// Build a new \c va_arg expression.
3083 ///
3084 /// By default, performs semantic analysis to build the new expression.
3085 /// Subclasses may override this routine to provide different behavior.
RebuildVAArgExpr(SourceLocation BuiltinLoc,Expr * SubExpr,TypeSourceInfo * TInfo,SourceLocation RParenLoc)3086 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3087 Expr *SubExpr, TypeSourceInfo *TInfo,
3088 SourceLocation RParenLoc) {
3089 return getSema().BuildVAArgExpr(BuiltinLoc,
3090 SubExpr, TInfo,
3091 RParenLoc);
3092 }
3093
3094 /// Build a new expression list in parentheses.
3095 ///
3096 /// By default, performs semantic analysis to build the new expression.
3097 /// Subclasses may override this routine to provide different behavior.
RebuildParenListExpr(SourceLocation LParenLoc,MultiExprArg SubExprs,SourceLocation RParenLoc)3098 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3099 MultiExprArg SubExprs,
3100 SourceLocation RParenLoc) {
3101 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3102 }
3103
RebuildCXXParenListInitExpr(ArrayRef<Expr * > Args,QualType T,unsigned NumUserSpecifiedExprs,SourceLocation InitLoc,SourceLocation LParenLoc,SourceLocation RParenLoc)3104 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3105 unsigned NumUserSpecifiedExprs,
3106 SourceLocation InitLoc,
3107 SourceLocation LParenLoc,
3108 SourceLocation RParenLoc) {
3109 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3110 InitLoc, LParenLoc, RParenLoc);
3111 }
3112
3113 /// Build a new address-of-label expression.
3114 ///
3115 /// By default, performs semantic analysis, using the name of the label
3116 /// rather than attempting to map the label statement itself.
3117 /// Subclasses may override this routine to provide different behavior.
RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,SourceLocation LabelLoc,LabelDecl * Label)3118 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3119 SourceLocation LabelLoc, LabelDecl *Label) {
3120 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3121 }
3122
3123 /// Build a new GNU statement expression.
3124 ///
3125 /// By default, performs semantic analysis to build the new expression.
3126 /// Subclasses may override this routine to provide different behavior.
RebuildStmtExpr(SourceLocation LParenLoc,Stmt * SubStmt,SourceLocation RParenLoc,unsigned TemplateDepth)3127 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3128 SourceLocation RParenLoc, unsigned TemplateDepth) {
3129 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3130 TemplateDepth);
3131 }
3132
3133 /// Build a new __builtin_choose_expr expression.
3134 ///
3135 /// By default, performs semantic analysis to build the new expression.
3136 /// Subclasses may override this routine to provide different behavior.
RebuildChooseExpr(SourceLocation BuiltinLoc,Expr * Cond,Expr * LHS,Expr * RHS,SourceLocation RParenLoc)3137 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3138 Expr *Cond, Expr *LHS, Expr *RHS,
3139 SourceLocation RParenLoc) {
3140 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3141 Cond, LHS, RHS,
3142 RParenLoc);
3143 }
3144
3145 /// Build a new generic selection expression with an expression predicate.
3146 ///
3147 /// By default, performs semantic analysis to build the new expression.
3148 /// Subclasses may override this routine to provide different behavior.
RebuildGenericSelectionExpr(SourceLocation KeyLoc,SourceLocation DefaultLoc,SourceLocation RParenLoc,Expr * ControllingExpr,ArrayRef<TypeSourceInfo * > Types,ArrayRef<Expr * > Exprs)3149 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3150 SourceLocation DefaultLoc,
3151 SourceLocation RParenLoc,
3152 Expr *ControllingExpr,
3153 ArrayRef<TypeSourceInfo *> Types,
3154 ArrayRef<Expr *> Exprs) {
3155 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3156 /*PredicateIsExpr=*/true,
3157 ControllingExpr, Types, Exprs);
3158 }
3159
3160 /// Build a new generic selection expression with a type predicate.
3161 ///
3162 /// By default, performs semantic analysis to build the new expression.
3163 /// Subclasses may override this routine to provide different behavior.
RebuildGenericSelectionExpr(SourceLocation KeyLoc,SourceLocation DefaultLoc,SourceLocation RParenLoc,TypeSourceInfo * ControllingType,ArrayRef<TypeSourceInfo * > Types,ArrayRef<Expr * > Exprs)3164 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3165 SourceLocation DefaultLoc,
3166 SourceLocation RParenLoc,
3167 TypeSourceInfo *ControllingType,
3168 ArrayRef<TypeSourceInfo *> Types,
3169 ArrayRef<Expr *> Exprs) {
3170 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3171 /*PredicateIsExpr=*/false,
3172 ControllingType, Types, Exprs);
3173 }
3174
3175 /// Build a new overloaded operator call expression.
3176 ///
3177 /// By default, performs semantic analysis to build the new expression.
3178 /// The semantic analysis provides the behavior of template instantiation,
3179 /// copying with transformations that turn what looks like an overloaded
3180 /// operator call into a use of a builtin operator, performing
3181 /// argument-dependent lookup, etc. Subclasses may override this routine to
3182 /// provide different behavior.
3183 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3184 SourceLocation OpLoc,
3185 SourceLocation CalleeLoc,
3186 bool RequiresADL,
3187 const UnresolvedSetImpl &Functions,
3188 Expr *First, Expr *Second);
3189
3190 /// Build a new C++ "named" cast expression, such as static_cast or
3191 /// reinterpret_cast.
3192 ///
3193 /// By default, this routine dispatches to one of the more-specific routines
3194 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3195 /// Subclasses may override this routine to provide different behavior.
RebuildCXXNamedCastExpr(SourceLocation OpLoc,Stmt::StmtClass Class,SourceLocation LAngleLoc,TypeSourceInfo * TInfo,SourceLocation RAngleLoc,SourceLocation LParenLoc,Expr * SubExpr,SourceLocation RParenLoc)3196 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3197 Stmt::StmtClass Class,
3198 SourceLocation LAngleLoc,
3199 TypeSourceInfo *TInfo,
3200 SourceLocation RAngleLoc,
3201 SourceLocation LParenLoc,
3202 Expr *SubExpr,
3203 SourceLocation RParenLoc) {
3204 switch (Class) {
3205 case Stmt::CXXStaticCastExprClass:
3206 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3207 RAngleLoc, LParenLoc,
3208 SubExpr, RParenLoc);
3209
3210 case Stmt::CXXDynamicCastExprClass:
3211 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3212 RAngleLoc, LParenLoc,
3213 SubExpr, RParenLoc);
3214
3215 case Stmt::CXXReinterpretCastExprClass:
3216 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3217 RAngleLoc, LParenLoc,
3218 SubExpr,
3219 RParenLoc);
3220
3221 case Stmt::CXXConstCastExprClass:
3222 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3223 RAngleLoc, LParenLoc,
3224 SubExpr, RParenLoc);
3225
3226 case Stmt::CXXAddrspaceCastExprClass:
3227 return getDerived().RebuildCXXAddrspaceCastExpr(
3228 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3229
3230 default:
3231 llvm_unreachable("Invalid C++ named cast");
3232 }
3233 }
3234
3235 /// Build a new C++ static_cast expression.
3236 ///
3237 /// By default, performs semantic analysis to build the new expression.
3238 /// Subclasses may override this routine to provide different behavior.
RebuildCXXStaticCastExpr(SourceLocation OpLoc,SourceLocation LAngleLoc,TypeSourceInfo * TInfo,SourceLocation RAngleLoc,SourceLocation LParenLoc,Expr * SubExpr,SourceLocation RParenLoc)3239 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3240 SourceLocation LAngleLoc,
3241 TypeSourceInfo *TInfo,
3242 SourceLocation RAngleLoc,
3243 SourceLocation LParenLoc,
3244 Expr *SubExpr,
3245 SourceLocation RParenLoc) {
3246 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3247 TInfo, SubExpr,
3248 SourceRange(LAngleLoc, RAngleLoc),
3249 SourceRange(LParenLoc, RParenLoc));
3250 }
3251
3252 /// Build a new C++ dynamic_cast expression.
3253 ///
3254 /// By default, performs semantic analysis to build the new expression.
3255 /// Subclasses may override this routine to provide different behavior.
RebuildCXXDynamicCastExpr(SourceLocation OpLoc,SourceLocation LAngleLoc,TypeSourceInfo * TInfo,SourceLocation RAngleLoc,SourceLocation LParenLoc,Expr * SubExpr,SourceLocation RParenLoc)3256 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3257 SourceLocation LAngleLoc,
3258 TypeSourceInfo *TInfo,
3259 SourceLocation RAngleLoc,
3260 SourceLocation LParenLoc,
3261 Expr *SubExpr,
3262 SourceLocation RParenLoc) {
3263 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3264 TInfo, SubExpr,
3265 SourceRange(LAngleLoc, RAngleLoc),
3266 SourceRange(LParenLoc, RParenLoc));
3267 }
3268
3269 /// Build a new C++ reinterpret_cast expression.
3270 ///
3271 /// By default, performs semantic analysis to build the new expression.
3272 /// Subclasses may override this routine to provide different behavior.
RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,SourceLocation LAngleLoc,TypeSourceInfo * TInfo,SourceLocation RAngleLoc,SourceLocation LParenLoc,Expr * SubExpr,SourceLocation RParenLoc)3273 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3274 SourceLocation LAngleLoc,
3275 TypeSourceInfo *TInfo,
3276 SourceLocation RAngleLoc,
3277 SourceLocation LParenLoc,
3278 Expr *SubExpr,
3279 SourceLocation RParenLoc) {
3280 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3281 TInfo, SubExpr,
3282 SourceRange(LAngleLoc, RAngleLoc),
3283 SourceRange(LParenLoc, RParenLoc));
3284 }
3285
3286 /// Build a new C++ const_cast expression.
3287 ///
3288 /// By default, performs semantic analysis to build the new expression.
3289 /// Subclasses may override this routine to provide different behavior.
RebuildCXXConstCastExpr(SourceLocation OpLoc,SourceLocation LAngleLoc,TypeSourceInfo * TInfo,SourceLocation RAngleLoc,SourceLocation LParenLoc,Expr * SubExpr,SourceLocation RParenLoc)3290 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3291 SourceLocation LAngleLoc,
3292 TypeSourceInfo *TInfo,
3293 SourceLocation RAngleLoc,
3294 SourceLocation LParenLoc,
3295 Expr *SubExpr,
3296 SourceLocation RParenLoc) {
3297 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3298 TInfo, SubExpr,
3299 SourceRange(LAngleLoc, RAngleLoc),
3300 SourceRange(LParenLoc, RParenLoc));
3301 }
3302
3303 ExprResult
RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc,SourceLocation LAngleLoc,TypeSourceInfo * TInfo,SourceLocation RAngleLoc,SourceLocation LParenLoc,Expr * SubExpr,SourceLocation RParenLoc)3304 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3305 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3306 SourceLocation LParenLoc, Expr *SubExpr,
3307 SourceLocation RParenLoc) {
3308 return getSema().BuildCXXNamedCast(
3309 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3310 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3311 }
3312
3313 /// Build a new C++ functional-style cast expression.
3314 ///
3315 /// By default, performs semantic analysis to build the new expression.
3316 /// Subclasses may override this routine to provide different behavior.
RebuildCXXFunctionalCastExpr(TypeSourceInfo * TInfo,SourceLocation LParenLoc,Expr * Sub,SourceLocation RParenLoc,bool ListInitialization)3317 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3318 SourceLocation LParenLoc,
3319 Expr *Sub,
3320 SourceLocation RParenLoc,
3321 bool ListInitialization) {
3322 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3323 // CXXParenListInitExpr. Pass its expanded arguments so that the
3324 // CXXParenListInitExpr can be rebuilt.
3325 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3326 return getSema().BuildCXXTypeConstructExpr(
3327 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3328 RParenLoc, ListInitialization);
3329
3330 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Sub))
3331 return getSema().BuildCXXTypeConstructExpr(
3332 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3333
3334 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3335 MultiExprArg(&Sub, 1), RParenLoc,
3336 ListInitialization);
3337 }
3338
3339 /// Build a new C++ __builtin_bit_cast expression.
3340 ///
3341 /// By default, performs semantic analysis to build the new expression.
3342 /// Subclasses may override this routine to provide different behavior.
RebuildBuiltinBitCastExpr(SourceLocation KWLoc,TypeSourceInfo * TSI,Expr * Sub,SourceLocation RParenLoc)3343 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3344 TypeSourceInfo *TSI, Expr *Sub,
3345 SourceLocation RParenLoc) {
3346 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3347 }
3348
3349 /// Build a new C++ typeid(type) expression.
3350 ///
3351 /// By default, performs semantic analysis to build the new expression.
3352 /// Subclasses may override this routine to provide different behavior.
RebuildCXXTypeidExpr(QualType TypeInfoType,SourceLocation TypeidLoc,TypeSourceInfo * Operand,SourceLocation RParenLoc)3353 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3354 SourceLocation TypeidLoc,
3355 TypeSourceInfo *Operand,
3356 SourceLocation RParenLoc) {
3357 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3358 RParenLoc);
3359 }
3360
3361
3362 /// Build a new C++ typeid(expr) expression.
3363 ///
3364 /// By default, performs semantic analysis to build the new expression.
3365 /// Subclasses may override this routine to provide different behavior.
RebuildCXXTypeidExpr(QualType TypeInfoType,SourceLocation TypeidLoc,Expr * Operand,SourceLocation RParenLoc)3366 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3367 SourceLocation TypeidLoc,
3368 Expr *Operand,
3369 SourceLocation RParenLoc) {
3370 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3371 RParenLoc);
3372 }
3373
3374 /// Build a new C++ __uuidof(type) expression.
3375 ///
3376 /// By default, performs semantic analysis to build the new expression.
3377 /// Subclasses may override this routine to provide different behavior.
RebuildCXXUuidofExpr(QualType Type,SourceLocation TypeidLoc,TypeSourceInfo * Operand,SourceLocation RParenLoc)3378 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3379 TypeSourceInfo *Operand,
3380 SourceLocation RParenLoc) {
3381 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3382 }
3383
3384 /// Build a new C++ __uuidof(expr) expression.
3385 ///
3386 /// By default, performs semantic analysis to build the new expression.
3387 /// Subclasses may override this routine to provide different behavior.
RebuildCXXUuidofExpr(QualType Type,SourceLocation TypeidLoc,Expr * Operand,SourceLocation RParenLoc)3388 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3389 Expr *Operand, SourceLocation RParenLoc) {
3390 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3391 }
3392
3393 /// Build a new C++ "this" expression.
3394 ///
3395 /// By default, performs semantic analysis to build a new "this" expression.
3396 /// Subclasses may override this routine to provide different behavior.
RebuildCXXThisExpr(SourceLocation ThisLoc,QualType ThisType,bool isImplicit)3397 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3398 QualType ThisType,
3399 bool isImplicit) {
3400 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3401 return ExprError();
3402 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3403 }
3404
3405 /// Build a new C++ throw expression.
3406 ///
3407 /// By default, performs semantic analysis to build the new expression.
3408 /// Subclasses may override this routine to provide different behavior.
RebuildCXXThrowExpr(SourceLocation ThrowLoc,Expr * Sub,bool IsThrownVariableInScope)3409 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3410 bool IsThrownVariableInScope) {
3411 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3412 }
3413
3414 /// Build a new C++ default-argument expression.
3415 ///
3416 /// By default, builds a new default-argument expression, which does not
3417 /// require any semantic analysis. Subclasses may override this routine to
3418 /// provide different behavior.
RebuildCXXDefaultArgExpr(SourceLocation Loc,ParmVarDecl * Param,Expr * RewrittenExpr)3419 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3420 Expr *RewrittenExpr) {
3421 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3422 RewrittenExpr, getSema().CurContext);
3423 }
3424
3425 /// Build a new C++11 default-initialization expression.
3426 ///
3427 /// By default, builds a new default field initialization expression, which
3428 /// does not require any semantic analysis. Subclasses may override this
3429 /// routine to provide different behavior.
RebuildCXXDefaultInitExpr(SourceLocation Loc,FieldDecl * Field)3430 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3431 FieldDecl *Field) {
3432 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3433 }
3434
3435 /// Build a new C++ zero-initialization expression.
3436 ///
3437 /// By default, performs semantic analysis to build the new expression.
3438 /// Subclasses may override this routine to provide different behavior.
RebuildCXXScalarValueInitExpr(TypeSourceInfo * TSInfo,SourceLocation LParenLoc,SourceLocation RParenLoc)3439 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3440 SourceLocation LParenLoc,
3441 SourceLocation RParenLoc) {
3442 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3443 /*ListInitialization=*/false);
3444 }
3445
3446 /// Build a new C++ "new" expression.
3447 ///
3448 /// By default, performs semantic analysis to build the new expression.
3449 /// Subclasses may override this routine to provide different behavior.
RebuildCXXNewExpr(SourceLocation StartLoc,bool UseGlobal,SourceLocation PlacementLParen,MultiExprArg PlacementArgs,SourceLocation PlacementRParen,SourceRange TypeIdParens,QualType AllocatedType,TypeSourceInfo * AllocatedTypeInfo,std::optional<Expr * > ArraySize,SourceRange DirectInitRange,Expr * Initializer)3450 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3451 SourceLocation PlacementLParen,
3452 MultiExprArg PlacementArgs,
3453 SourceLocation PlacementRParen,
3454 SourceRange TypeIdParens, QualType AllocatedType,
3455 TypeSourceInfo *AllocatedTypeInfo,
3456 std::optional<Expr *> ArraySize,
3457 SourceRange DirectInitRange, Expr *Initializer) {
3458 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3459 PlacementLParen,
3460 PlacementArgs,
3461 PlacementRParen,
3462 TypeIdParens,
3463 AllocatedType,
3464 AllocatedTypeInfo,
3465 ArraySize,
3466 DirectInitRange,
3467 Initializer);
3468 }
3469
3470 /// Build a new C++ "delete" expression.
3471 ///
3472 /// By default, performs semantic analysis to build the new expression.
3473 /// Subclasses may override this routine to provide different behavior.
RebuildCXXDeleteExpr(SourceLocation StartLoc,bool IsGlobalDelete,bool IsArrayForm,Expr * Operand)3474 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3475 bool IsGlobalDelete,
3476 bool IsArrayForm,
3477 Expr *Operand) {
3478 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3479 Operand);
3480 }
3481
3482 /// Build a new type trait expression.
3483 ///
3484 /// By default, performs semantic analysis to build the new expression.
3485 /// Subclasses may override this routine to provide different behavior.
RebuildTypeTrait(TypeTrait Trait,SourceLocation StartLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc)3486 ExprResult RebuildTypeTrait(TypeTrait Trait,
3487 SourceLocation StartLoc,
3488 ArrayRef<TypeSourceInfo *> Args,
3489 SourceLocation RParenLoc) {
3490 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3491 }
3492
3493 /// Build a new array type trait expression.
3494 ///
3495 /// By default, performs semantic analysis to build the new expression.
3496 /// Subclasses may override this routine to provide different behavior.
RebuildArrayTypeTrait(ArrayTypeTrait Trait,SourceLocation StartLoc,TypeSourceInfo * TSInfo,Expr * DimExpr,SourceLocation RParenLoc)3497 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3498 SourceLocation StartLoc,
3499 TypeSourceInfo *TSInfo,
3500 Expr *DimExpr,
3501 SourceLocation RParenLoc) {
3502 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3503 }
3504
3505 /// Build a new expression trait expression.
3506 ///
3507 /// By default, performs semantic analysis to build the new expression.
3508 /// Subclasses may override this routine to provide different behavior.
RebuildExpressionTrait(ExpressionTrait Trait,SourceLocation StartLoc,Expr * Queried,SourceLocation RParenLoc)3509 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3510 SourceLocation StartLoc,
3511 Expr *Queried,
3512 SourceLocation RParenLoc) {
3513 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3514 }
3515
3516 /// Build a new (previously unresolved) declaration reference
3517 /// expression.
3518 ///
3519 /// By default, performs semantic analysis to build the new expression.
3520 /// Subclasses may override this routine to provide different behavior.
RebuildDependentScopeDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,const DeclarationNameInfo & NameInfo,const TemplateArgumentListInfo * TemplateArgs,bool IsAddressOfOperand,TypeSourceInfo ** RecoveryTSI)3521 ExprResult RebuildDependentScopeDeclRefExpr(
3522 NestedNameSpecifierLoc QualifierLoc,
3523 SourceLocation TemplateKWLoc,
3524 const DeclarationNameInfo &NameInfo,
3525 const TemplateArgumentListInfo *TemplateArgs,
3526 bool IsAddressOfOperand,
3527 TypeSourceInfo **RecoveryTSI) {
3528 CXXScopeSpec SS;
3529 SS.Adopt(QualifierLoc);
3530
3531 if (TemplateArgs || TemplateKWLoc.isValid())
3532 return getSema().BuildQualifiedTemplateIdExpr(
3533 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3534
3535 return getSema().BuildQualifiedDeclarationNameExpr(
3536 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3537 }
3538
3539 /// Build a new template-id expression.
3540 ///
3541 /// By default, performs semantic analysis to build the new expression.
3542 /// Subclasses may override this routine to provide different behavior.
RebuildTemplateIdExpr(const CXXScopeSpec & SS,SourceLocation TemplateKWLoc,LookupResult & R,bool RequiresADL,const TemplateArgumentListInfo * TemplateArgs)3543 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3544 SourceLocation TemplateKWLoc,
3545 LookupResult &R,
3546 bool RequiresADL,
3547 const TemplateArgumentListInfo *TemplateArgs) {
3548 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3549 TemplateArgs);
3550 }
3551
3552 /// Build a new object-construction expression.
3553 ///
3554 /// By default, performs semantic analysis to build the new expression.
3555 /// Subclasses may override this routine to provide different behavior.
RebuildCXXConstructExpr(QualType T,SourceLocation Loc,CXXConstructorDecl * Constructor,bool IsElidable,MultiExprArg Args,bool HadMultipleCandidates,bool ListInitialization,bool StdInitListInitialization,bool RequiresZeroInit,CXXConstructionKind ConstructKind,SourceRange ParenRange)3556 ExprResult RebuildCXXConstructExpr(
3557 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3558 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3559 bool ListInitialization, bool StdInitListInitialization,
3560 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3561 SourceRange ParenRange) {
3562 // Reconstruct the constructor we originally found, which might be
3563 // different if this is a call to an inherited constructor.
3564 CXXConstructorDecl *FoundCtor = Constructor;
3565 if (Constructor->isInheritingConstructor())
3566 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3567
3568 SmallVector<Expr *, 8> ConvertedArgs;
3569 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3570 ConvertedArgs))
3571 return ExprError();
3572
3573 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3574 IsElidable,
3575 ConvertedArgs,
3576 HadMultipleCandidates,
3577 ListInitialization,
3578 StdInitListInitialization,
3579 RequiresZeroInit, ConstructKind,
3580 ParenRange);
3581 }
3582
3583 /// Build a new implicit construction via inherited constructor
3584 /// expression.
RebuildCXXInheritedCtorInitExpr(QualType T,SourceLocation Loc,CXXConstructorDecl * Constructor,bool ConstructsVBase,bool InheritedFromVBase)3585 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3586 CXXConstructorDecl *Constructor,
3587 bool ConstructsVBase,
3588 bool InheritedFromVBase) {
3589 return new (getSema().Context) CXXInheritedCtorInitExpr(
3590 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3591 }
3592
3593 /// Build a new object-construction expression.
3594 ///
3595 /// By default, performs semantic analysis to build the new expression.
3596 /// Subclasses may override this routine to provide different behavior.
RebuildCXXTemporaryObjectExpr(TypeSourceInfo * TSInfo,SourceLocation LParenOrBraceLoc,MultiExprArg Args,SourceLocation RParenOrBraceLoc,bool ListInitialization)3597 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3598 SourceLocation LParenOrBraceLoc,
3599 MultiExprArg Args,
3600 SourceLocation RParenOrBraceLoc,
3601 bool ListInitialization) {
3602 return getSema().BuildCXXTypeConstructExpr(
3603 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3604 }
3605
3606 /// Build a new object-construction expression.
3607 ///
3608 /// By default, performs semantic analysis to build the new expression.
3609 /// Subclasses may override this routine to provide different behavior.
RebuildCXXUnresolvedConstructExpr(TypeSourceInfo * TSInfo,SourceLocation LParenLoc,MultiExprArg Args,SourceLocation RParenLoc,bool ListInitialization)3610 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3611 SourceLocation LParenLoc,
3612 MultiExprArg Args,
3613 SourceLocation RParenLoc,
3614 bool ListInitialization) {
3615 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3616 RParenLoc, ListInitialization);
3617 }
3618
3619 /// Build a new member reference expression.
3620 ///
3621 /// By default, performs semantic analysis to build the new expression.
3622 /// Subclasses may override this routine to provide different behavior.
RebuildCXXDependentScopeMemberExpr(Expr * BaseE,QualType BaseType,bool IsArrow,SourceLocation OperatorLoc,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,NamedDecl * FirstQualifierInScope,const DeclarationNameInfo & MemberNameInfo,const TemplateArgumentListInfo * TemplateArgs)3623 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3624 QualType BaseType,
3625 bool IsArrow,
3626 SourceLocation OperatorLoc,
3627 NestedNameSpecifierLoc QualifierLoc,
3628 SourceLocation TemplateKWLoc,
3629 NamedDecl *FirstQualifierInScope,
3630 const DeclarationNameInfo &MemberNameInfo,
3631 const TemplateArgumentListInfo *TemplateArgs) {
3632 CXXScopeSpec SS;
3633 SS.Adopt(QualifierLoc);
3634
3635 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3636 OperatorLoc, IsArrow,
3637 SS, TemplateKWLoc,
3638 FirstQualifierInScope,
3639 MemberNameInfo,
3640 TemplateArgs, /*S*/nullptr);
3641 }
3642
3643 /// Build a new member reference expression.
3644 ///
3645 /// By default, performs semantic analysis to build the new expression.
3646 /// Subclasses may override this routine to provide different behavior.
RebuildUnresolvedMemberExpr(Expr * BaseE,QualType BaseType,SourceLocation OperatorLoc,bool IsArrow,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateKWLoc,NamedDecl * FirstQualifierInScope,LookupResult & R,const TemplateArgumentListInfo * TemplateArgs)3647 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3648 SourceLocation OperatorLoc,
3649 bool IsArrow,
3650 NestedNameSpecifierLoc QualifierLoc,
3651 SourceLocation TemplateKWLoc,
3652 NamedDecl *FirstQualifierInScope,
3653 LookupResult &R,
3654 const TemplateArgumentListInfo *TemplateArgs) {
3655 CXXScopeSpec SS;
3656 SS.Adopt(QualifierLoc);
3657
3658 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3659 OperatorLoc, IsArrow,
3660 SS, TemplateKWLoc,
3661 FirstQualifierInScope,
3662 R, TemplateArgs, /*S*/nullptr);
3663 }
3664
3665 /// Build a new noexcept expression.
3666 ///
3667 /// By default, performs semantic analysis to build the new expression.
3668 /// Subclasses may override this routine to provide different behavior.
RebuildCXXNoexceptExpr(SourceRange Range,Expr * Arg)3669 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3670 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3671 }
3672
3673 UnsignedOrNone
3674 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3675
3676 /// Build a new expression to compute the length of a parameter pack.
RebuildSizeOfPackExpr(SourceLocation OperatorLoc,NamedDecl * Pack,SourceLocation PackLoc,SourceLocation RParenLoc,UnsignedOrNone Length,ArrayRef<TemplateArgument> PartialArgs)3677 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3678 SourceLocation PackLoc,
3679 SourceLocation RParenLoc,
3680 UnsignedOrNone Length,
3681 ArrayRef<TemplateArgument> PartialArgs) {
3682 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3683 RParenLoc, Length, PartialArgs);
3684 }
3685
3686 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3687 SourceLocation RSquareLoc,
3688 Expr *PackIdExpression, Expr *IndexExpr,
3689 ArrayRef<Expr *> ExpandedExprs,
3690 bool FullySubstituted = false) {
3691 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3692 IndexExpr, RSquareLoc, ExpandedExprs,
3693 FullySubstituted);
3694 }
3695
3696 /// Build a new expression representing a call to a source location
3697 /// builtin.
3698 ///
3699 /// By default, performs semantic analysis to build the new expression.
3700 /// Subclasses may override this routine to provide different behavior.
RebuildSourceLocExpr(SourceLocIdentKind Kind,QualType ResultTy,SourceLocation BuiltinLoc,SourceLocation RPLoc,DeclContext * ParentContext)3701 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3702 SourceLocation BuiltinLoc,
3703 SourceLocation RPLoc,
3704 DeclContext *ParentContext) {
3705 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3706 ParentContext);
3707 }
3708
3709 /// Build a new Objective-C boxed expression.
3710 ///
3711 /// By default, performs semantic analysis to build the new expression.
3712 /// Subclasses may override this routine to provide different behavior.
RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,SourceLocation TemplateKWLoc,DeclarationNameInfo ConceptNameInfo,NamedDecl * FoundDecl,ConceptDecl * NamedConcept,TemplateArgumentListInfo * TALI)3713 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3714 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3715 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3716 TemplateArgumentListInfo *TALI) {
3717 CXXScopeSpec SS;
3718 SS.Adopt(NNS);
3719 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3720 ConceptNameInfo,
3721 FoundDecl,
3722 NamedConcept, TALI);
3723 if (Result.isInvalid())
3724 return ExprError();
3725 return Result;
3726 }
3727
3728 /// \brief Build a new requires expression.
3729 ///
3730 /// By default, performs semantic analysis to build the new expression.
3731 /// Subclasses may override this routine to provide different behavior.
RebuildRequiresExpr(SourceLocation RequiresKWLoc,RequiresExprBodyDecl * Body,SourceLocation LParenLoc,ArrayRef<ParmVarDecl * > LocalParameters,SourceLocation RParenLoc,ArrayRef<concepts::Requirement * > Requirements,SourceLocation ClosingBraceLoc)3732 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3733 RequiresExprBodyDecl *Body,
3734 SourceLocation LParenLoc,
3735 ArrayRef<ParmVarDecl *> LocalParameters,
3736 SourceLocation RParenLoc,
3737 ArrayRef<concepts::Requirement *> Requirements,
3738 SourceLocation ClosingBraceLoc) {
3739 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3740 LocalParameters, RParenLoc, Requirements,
3741 ClosingBraceLoc);
3742 }
3743
3744 concepts::TypeRequirement *
RebuildTypeRequirement(concepts::Requirement::SubstitutionDiagnostic * SubstDiag)3745 RebuildTypeRequirement(
3746 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3747 return SemaRef.BuildTypeRequirement(SubstDiag);
3748 }
3749
RebuildTypeRequirement(TypeSourceInfo * T)3750 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3751 return SemaRef.BuildTypeRequirement(T);
3752 }
3753
3754 concepts::ExprRequirement *
RebuildExprRequirement(concepts::Requirement::SubstitutionDiagnostic * SubstDiag,bool IsSimple,SourceLocation NoexceptLoc,concepts::ExprRequirement::ReturnTypeRequirement Ret)3755 RebuildExprRequirement(
3756 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3757 SourceLocation NoexceptLoc,
3758 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3759 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3760 std::move(Ret));
3761 }
3762
3763 concepts::ExprRequirement *
RebuildExprRequirement(Expr * E,bool IsSimple,SourceLocation NoexceptLoc,concepts::ExprRequirement::ReturnTypeRequirement Ret)3764 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3765 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3766 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3767 std::move(Ret));
3768 }
3769
3770 concepts::NestedRequirement *
RebuildNestedRequirement(StringRef InvalidConstraintEntity,const ASTConstraintSatisfaction & Satisfaction)3771 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3772 const ASTConstraintSatisfaction &Satisfaction) {
3773 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3774 Satisfaction);
3775 }
3776
RebuildNestedRequirement(Expr * Constraint)3777 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3778 return SemaRef.BuildNestedRequirement(Constraint);
3779 }
3780
3781 /// \brief Build a new Objective-C boxed expression.
3782 ///
3783 /// By default, performs semantic analysis to build the new expression.
3784 /// Subclasses may override this routine to provide different behavior.
RebuildObjCBoxedExpr(SourceRange SR,Expr * ValueExpr)3785 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3786 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3787 }
3788
3789 /// Build a new Objective-C array literal.
3790 ///
3791 /// By default, performs semantic analysis to build the new expression.
3792 /// Subclasses may override this routine to provide different behavior.
RebuildObjCArrayLiteral(SourceRange Range,Expr ** Elements,unsigned NumElements)3793 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3794 Expr **Elements, unsigned NumElements) {
3795 return getSema().ObjC().BuildObjCArrayLiteral(
3796 Range, MultiExprArg(Elements, NumElements));
3797 }
3798
RebuildObjCSubscriptRefExpr(SourceLocation RB,Expr * Base,Expr * Key,ObjCMethodDecl * getterMethod,ObjCMethodDecl * setterMethod)3799 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3800 Expr *Base, Expr *Key,
3801 ObjCMethodDecl *getterMethod,
3802 ObjCMethodDecl *setterMethod) {
3803 return getSema().ObjC().BuildObjCSubscriptExpression(
3804 RB, Base, Key, getterMethod, setterMethod);
3805 }
3806
3807 /// Build a new Objective-C dictionary literal.
3808 ///
3809 /// By default, performs semantic analysis to build the new expression.
3810 /// Subclasses may override this routine to provide different behavior.
RebuildObjCDictionaryLiteral(SourceRange Range,MutableArrayRef<ObjCDictionaryElement> Elements)3811 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3812 MutableArrayRef<ObjCDictionaryElement> Elements) {
3813 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3814 }
3815
3816 /// Build a new Objective-C \@encode expression.
3817 ///
3818 /// By default, performs semantic analysis to build the new expression.
3819 /// Subclasses may override this routine to provide different behavior.
RebuildObjCEncodeExpr(SourceLocation AtLoc,TypeSourceInfo * EncodeTypeInfo,SourceLocation RParenLoc)3820 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3821 TypeSourceInfo *EncodeTypeInfo,
3822 SourceLocation RParenLoc) {
3823 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
3824 RParenLoc);
3825 }
3826
3827 /// Build a new Objective-C class message.
RebuildObjCMessageExpr(TypeSourceInfo * ReceiverTypeInfo,Selector Sel,ArrayRef<SourceLocation> SelectorLocs,ObjCMethodDecl * Method,SourceLocation LBracLoc,MultiExprArg Args,SourceLocation RBracLoc)3828 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3829 Selector Sel,
3830 ArrayRef<SourceLocation> SelectorLocs,
3831 ObjCMethodDecl *Method,
3832 SourceLocation LBracLoc,
3833 MultiExprArg Args,
3834 SourceLocation RBracLoc) {
3835 return SemaRef.ObjC().BuildClassMessage(
3836 ReceiverTypeInfo, ReceiverTypeInfo->getType(),
3837 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3838 RBracLoc, Args);
3839 }
3840
3841 /// Build a new Objective-C instance message.
RebuildObjCMessageExpr(Expr * Receiver,Selector Sel,ArrayRef<SourceLocation> SelectorLocs,ObjCMethodDecl * Method,SourceLocation LBracLoc,MultiExprArg Args,SourceLocation RBracLoc)3842 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3843 Selector Sel,
3844 ArrayRef<SourceLocation> SelectorLocs,
3845 ObjCMethodDecl *Method,
3846 SourceLocation LBracLoc,
3847 MultiExprArg Args,
3848 SourceLocation RBracLoc) {
3849 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),
3850 /*SuperLoc=*/SourceLocation(),
3851 Sel, Method, LBracLoc,
3852 SelectorLocs, RBracLoc, Args);
3853 }
3854
3855 /// Build a new Objective-C instance/class message to 'super'.
RebuildObjCMessageExpr(SourceLocation SuperLoc,Selector Sel,ArrayRef<SourceLocation> SelectorLocs,QualType SuperType,ObjCMethodDecl * Method,SourceLocation LBracLoc,MultiExprArg Args,SourceLocation RBracLoc)3856 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3857 Selector Sel,
3858 ArrayRef<SourceLocation> SelectorLocs,
3859 QualType SuperType,
3860 ObjCMethodDecl *Method,
3861 SourceLocation LBracLoc,
3862 MultiExprArg Args,
3863 SourceLocation RBracLoc) {
3864 return Method->isInstanceMethod()
3865 ? SemaRef.ObjC().BuildInstanceMessage(
3866 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,
3867 SelectorLocs, RBracLoc, Args)
3868 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,
3869 Sel, Method, LBracLoc,
3870 SelectorLocs, RBracLoc, Args);
3871 }
3872
3873 /// Build a new Objective-C ivar reference expression.
3874 ///
3875 /// By default, performs semantic analysis to build the new expression.
3876 /// Subclasses may override this routine to provide different behavior.
RebuildObjCIvarRefExpr(Expr * BaseArg,ObjCIvarDecl * Ivar,SourceLocation IvarLoc,bool IsArrow,bool IsFreeIvar)3877 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3878 SourceLocation IvarLoc,
3879 bool IsArrow, bool IsFreeIvar) {
3880 CXXScopeSpec SS;
3881 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3882 ExprResult Result = getSema().BuildMemberReferenceExpr(
3883 BaseArg, BaseArg->getType(),
3884 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3885 /*FirstQualifierInScope=*/nullptr, NameInfo,
3886 /*TemplateArgs=*/nullptr,
3887 /*S=*/nullptr);
3888 if (IsFreeIvar && Result.isUsable())
3889 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3890 return Result;
3891 }
3892
3893 /// Build a new Objective-C property reference expression.
3894 ///
3895 /// By default, performs semantic analysis to build the new expression.
3896 /// Subclasses may override this routine to provide different behavior.
RebuildObjCPropertyRefExpr(Expr * BaseArg,ObjCPropertyDecl * Property,SourceLocation PropertyLoc)3897 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3898 ObjCPropertyDecl *Property,
3899 SourceLocation PropertyLoc) {
3900 CXXScopeSpec SS;
3901 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3902 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3903 /*FIXME:*/PropertyLoc,
3904 /*IsArrow=*/false,
3905 SS, SourceLocation(),
3906 /*FirstQualifierInScope=*/nullptr,
3907 NameInfo,
3908 /*TemplateArgs=*/nullptr,
3909 /*S=*/nullptr);
3910 }
3911
3912 /// Build a new Objective-C property reference expression.
3913 ///
3914 /// By default, performs semantic analysis to build the new expression.
3915 /// Subclasses may override this routine to provide different behavior.
RebuildObjCPropertyRefExpr(Expr * Base,QualType T,ObjCMethodDecl * Getter,ObjCMethodDecl * Setter,SourceLocation PropertyLoc)3916 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3917 ObjCMethodDecl *Getter,
3918 ObjCMethodDecl *Setter,
3919 SourceLocation PropertyLoc) {
3920 // Since these expressions can only be value-dependent, we do not
3921 // need to perform semantic analysis again.
3922 return Owned(
3923 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3924 VK_LValue, OK_ObjCProperty,
3925 PropertyLoc, Base));
3926 }
3927
3928 /// Build a new Objective-C "isa" expression.
3929 ///
3930 /// By default, performs semantic analysis to build the new expression.
3931 /// Subclasses may override this routine to provide different behavior.
RebuildObjCIsaExpr(Expr * BaseArg,SourceLocation IsaLoc,SourceLocation OpLoc,bool IsArrow)3932 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3933 SourceLocation OpLoc, bool IsArrow) {
3934 CXXScopeSpec SS;
3935 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3936 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3937 OpLoc, IsArrow,
3938 SS, SourceLocation(),
3939 /*FirstQualifierInScope=*/nullptr,
3940 NameInfo,
3941 /*TemplateArgs=*/nullptr,
3942 /*S=*/nullptr);
3943 }
3944
3945 /// Build a new shuffle vector expression.
3946 ///
3947 /// By default, performs semantic analysis to build the new expression.
3948 /// Subclasses may override this routine to provide different behavior.
RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,MultiExprArg SubExprs,SourceLocation RParenLoc)3949 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3950 MultiExprArg SubExprs,
3951 SourceLocation RParenLoc) {
3952 // Find the declaration for __builtin_shufflevector
3953 const IdentifierInfo &Name
3954 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3955 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3956 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3957 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3958
3959 // Build a reference to the __builtin_shufflevector builtin
3960 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3961 Expr *Callee = new (SemaRef.Context)
3962 DeclRefExpr(SemaRef.Context, Builtin, false,
3963 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3964 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3965 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3966 CK_BuiltinFnToFnPtr).get();
3967
3968 // Build the CallExpr
3969 ExprResult TheCall = CallExpr::Create(
3970 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3971 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3972 FPOptionsOverride());
3973
3974 // Type-check the __builtin_shufflevector expression.
3975 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3976 }
3977
3978 /// Build a new convert vector expression.
RebuildConvertVectorExpr(SourceLocation BuiltinLoc,Expr * SrcExpr,TypeSourceInfo * DstTInfo,SourceLocation RParenLoc)3979 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3980 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3981 SourceLocation RParenLoc) {
3982 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);
3983 }
3984
3985 /// Build a new template argument pack expansion.
3986 ///
3987 /// By default, performs semantic analysis to build a new pack expansion
3988 /// for a template argument. Subclasses may override this routine to provide
3989 /// different behavior.
RebuildPackExpansion(TemplateArgumentLoc Pattern,SourceLocation EllipsisLoc,UnsignedOrNone NumExpansions)3990 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
3991 SourceLocation EllipsisLoc,
3992 UnsignedOrNone NumExpansions) {
3993 switch (Pattern.getArgument().getKind()) {
3994 case TemplateArgument::Expression: {
3995 ExprResult Result
3996 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3997 EllipsisLoc, NumExpansions);
3998 if (Result.isInvalid())
3999 return TemplateArgumentLoc();
4000
4001 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4002 /*IsCanonical=*/false),
4003 Result.get());
4004 }
4005
4006 case TemplateArgument::Template:
4007 return TemplateArgumentLoc(
4008 SemaRef.Context,
4009 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4010 NumExpansions),
4011 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
4012 EllipsisLoc);
4013
4014 case TemplateArgument::Null:
4015 case TemplateArgument::Integral:
4016 case TemplateArgument::Declaration:
4017 case TemplateArgument::StructuralValue:
4018 case TemplateArgument::Pack:
4019 case TemplateArgument::TemplateExpansion:
4020 case TemplateArgument::NullPtr:
4021 llvm_unreachable("Pack expansion pattern has no parameter packs");
4022
4023 case TemplateArgument::Type:
4024 if (TypeSourceInfo *Expansion
4025 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4026 EllipsisLoc,
4027 NumExpansions))
4028 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4029 Expansion);
4030 break;
4031 }
4032
4033 return TemplateArgumentLoc();
4034 }
4035
4036 /// Build a new expression pack expansion.
4037 ///
4038 /// By default, performs semantic analysis to build a new pack expansion
4039 /// for an expression. Subclasses may override this routine to provide
4040 /// different behavior.
RebuildPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc,UnsignedOrNone NumExpansions)4041 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4042 UnsignedOrNone NumExpansions) {
4043 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4044 }
4045
4046 /// Build a new C++1z fold-expression.
4047 ///
4048 /// By default, performs semantic analysis in order to build a new fold
4049 /// expression.
RebuildCXXFoldExpr(UnresolvedLookupExpr * ULE,SourceLocation LParenLoc,Expr * LHS,BinaryOperatorKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc,UnsignedOrNone NumExpansions)4050 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4051 SourceLocation LParenLoc, Expr *LHS,
4052 BinaryOperatorKind Operator,
4053 SourceLocation EllipsisLoc, Expr *RHS,
4054 SourceLocation RParenLoc,
4055 UnsignedOrNone NumExpansions) {
4056 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4057 EllipsisLoc, RHS, RParenLoc,
4058 NumExpansions);
4059 }
4060
RebuildLambdaExpr(SourceLocation StartLoc,SourceLocation EndLoc,LambdaScopeInfo * LSI)4061 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4062 LambdaScopeInfo *LSI) {
4063 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4064 if (Expr *Init = PVD->getInit())
4065 LSI->ContainsUnexpandedParameterPack |=
4066 Init->containsUnexpandedParameterPack();
4067 else if (PVD->hasUninstantiatedDefaultArg())
4068 LSI->ContainsUnexpandedParameterPack |=
4069 PVD->getUninstantiatedDefaultArg()
4070 ->containsUnexpandedParameterPack();
4071 }
4072 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4073 }
4074
4075 /// Build an empty C++1z fold-expression with the given operator.
4076 ///
4077 /// By default, produces the fallback value for the fold-expression, or
4078 /// produce an error if there is no fallback value.
RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,BinaryOperatorKind Operator)4079 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4080 BinaryOperatorKind Operator) {
4081 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4082 }
4083
4084 /// Build a new atomic operation expression.
4085 ///
4086 /// By default, performs semantic analysis to build the new expression.
4087 /// Subclasses may override this routine to provide different behavior.
RebuildAtomicExpr(SourceLocation BuiltinLoc,MultiExprArg SubExprs,AtomicExpr::AtomicOp Op,SourceLocation RParenLoc)4088 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4089 AtomicExpr::AtomicOp Op,
4090 SourceLocation RParenLoc) {
4091 // Use this for all of the locations, since we don't know the difference
4092 // between the call and the expr at this point.
4093 SourceRange Range{BuiltinLoc, RParenLoc};
4094 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4095 Sema::AtomicArgumentOrder::AST);
4096 }
4097
RebuildRecoveryExpr(SourceLocation BeginLoc,SourceLocation EndLoc,ArrayRef<Expr * > SubExprs,QualType Type)4098 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4099 ArrayRef<Expr *> SubExprs, QualType Type) {
4100 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4101 }
4102
RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult StrBlock)4103 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4104 SourceLocation BeginLoc,
4105 SourceLocation DirLoc,
4106 SourceLocation EndLoc,
4107 ArrayRef<OpenACCClause *> Clauses,
4108 StmtResult StrBlock) {
4109 return getSema().OpenACC().ActOnEndStmtDirective(
4110 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4111 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4112 }
4113
RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult Loop)4114 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4115 SourceLocation DirLoc,
4116 SourceLocation EndLoc,
4117 ArrayRef<OpenACCClause *> Clauses,
4118 StmtResult Loop) {
4119 return getSema().OpenACC().ActOnEndStmtDirective(
4120 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4121 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4122 Clauses, Loop);
4123 }
4124
RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult Loop)4125 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4126 SourceLocation BeginLoc,
4127 SourceLocation DirLoc,
4128 SourceLocation EndLoc,
4129 ArrayRef<OpenACCClause *> Clauses,
4130 StmtResult Loop) {
4131 return getSema().OpenACC().ActOnEndStmtDirective(
4132 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4133 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4134 }
4135
RebuildOpenACCDataConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult StrBlock)4136 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4137 SourceLocation DirLoc,
4138 SourceLocation EndLoc,
4139 ArrayRef<OpenACCClause *> Clauses,
4140 StmtResult StrBlock) {
4141 return getSema().OpenACC().ActOnEndStmtDirective(
4142 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4143 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4144 Clauses, StrBlock);
4145 }
4146
4147 StmtResult
RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4148 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4149 SourceLocation DirLoc, SourceLocation EndLoc,
4150 ArrayRef<OpenACCClause *> Clauses) {
4151 return getSema().OpenACC().ActOnEndStmtDirective(
4152 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4153 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4154 Clauses, {});
4155 }
4156
4157 StmtResult
RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4158 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4159 SourceLocation DirLoc, SourceLocation EndLoc,
4160 ArrayRef<OpenACCClause *> Clauses) {
4161 return getSema().OpenACC().ActOnEndStmtDirective(
4162 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4163 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4164 Clauses, {});
4165 }
4166
RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult StrBlock)4167 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4168 SourceLocation DirLoc,
4169 SourceLocation EndLoc,
4170 ArrayRef<OpenACCClause *> Clauses,
4171 StmtResult StrBlock) {
4172 return getSema().OpenACC().ActOnEndStmtDirective(
4173 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4174 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4175 Clauses, StrBlock);
4176 }
4177
RebuildOpenACCInitConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4178 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4179 SourceLocation DirLoc,
4180 SourceLocation EndLoc,
4181 ArrayRef<OpenACCClause *> Clauses) {
4182 return getSema().OpenACC().ActOnEndStmtDirective(
4183 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4184 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4185 Clauses, {});
4186 }
4187
4188 StmtResult
RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4189 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4190 SourceLocation DirLoc, SourceLocation EndLoc,
4191 ArrayRef<OpenACCClause *> Clauses) {
4192 return getSema().OpenACC().ActOnEndStmtDirective(
4193 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4194 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4195 Clauses, {});
4196 }
4197
RebuildOpenACCSetConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4198 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4199 SourceLocation DirLoc,
4200 SourceLocation EndLoc,
4201 ArrayRef<OpenACCClause *> Clauses) {
4202 return getSema().OpenACC().ActOnEndStmtDirective(
4203 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4204 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4205 Clauses, {});
4206 }
4207
RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4208 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4209 SourceLocation DirLoc,
4210 SourceLocation EndLoc,
4211 ArrayRef<OpenACCClause *> Clauses) {
4212 return getSema().OpenACC().ActOnEndStmtDirective(
4213 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4214 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4215 Clauses, {});
4216 }
4217
RebuildOpenACCWaitConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation LParenLoc,Expr * DevNumExpr,SourceLocation QueuesLoc,ArrayRef<Expr * > QueueIdExprs,SourceLocation RParenLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses)4218 StmtResult RebuildOpenACCWaitConstruct(
4219 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4220 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4221 SourceLocation RParenLoc, SourceLocation EndLoc,
4222 ArrayRef<OpenACCClause *> Clauses) {
4223 llvm::SmallVector<Expr *> Exprs;
4224 Exprs.push_back(DevNumExpr);
4225 llvm::append_range(Exprs, QueueIdExprs);
4226 return getSema().OpenACC().ActOnEndStmtDirective(
4227 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4228 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4229 }
4230
RebuildOpenACCCacheConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation LParenLoc,SourceLocation ReadOnlyLoc,ArrayRef<Expr * > VarList,SourceLocation RParenLoc,SourceLocation EndLoc)4231 StmtResult RebuildOpenACCCacheConstruct(
4232 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4233 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4234 SourceLocation RParenLoc, SourceLocation EndLoc) {
4235 return getSema().OpenACC().ActOnEndStmtDirective(
4236 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4237 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4238 }
4239
RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,SourceLocation DirLoc,OpenACCAtomicKind AtKind,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult AssociatedStmt)4240 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4241 SourceLocation DirLoc,
4242 OpenACCAtomicKind AtKind,
4243 SourceLocation EndLoc,
4244 ArrayRef<OpenACCClause *> Clauses,
4245 StmtResult AssociatedStmt) {
4246 return getSema().OpenACC().ActOnEndStmtDirective(
4247 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4248 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4249 AssociatedStmt);
4250 }
4251
RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)4252 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4253 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4254 }
4255
4256 private:
4257 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4258 QualType ObjectType,
4259 NamedDecl *FirstQualifierInScope,
4260 CXXScopeSpec &SS);
4261
4262 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4263 QualType ObjectType,
4264 NamedDecl *FirstQualifierInScope,
4265 CXXScopeSpec &SS);
4266
4267 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4268 NamedDecl *FirstQualifierInScope,
4269 CXXScopeSpec &SS);
4270
4271 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4272 DependentNameTypeLoc TL,
4273 bool DeducibleTSTContext);
4274
4275 llvm::SmallVector<OpenACCClause *>
4276 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4277 ArrayRef<const OpenACCClause *> OldClauses);
4278
4279 OpenACCClause *
4280 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4281 OpenACCDirectiveKind DirKind,
4282 const OpenACCClause *OldClause);
4283 };
4284
4285 template <typename Derived>
TransformStmt(Stmt * S,StmtDiscardKind SDK)4286 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4287 if (!S)
4288 return S;
4289
4290 switch (S->getStmtClass()) {
4291 case Stmt::NoStmtClass: break;
4292
4293 // Transform individual statement nodes
4294 // Pass SDK into statements that can produce a value
4295 #define STMT(Node, Parent) \
4296 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4297 #define VALUESTMT(Node, Parent) \
4298 case Stmt::Node##Class: \
4299 return getDerived().Transform##Node(cast<Node>(S), SDK);
4300 #define ABSTRACT_STMT(Node)
4301 #define EXPR(Node, Parent)
4302 #include "clang/AST/StmtNodes.inc"
4303
4304 // Transform expressions by calling TransformExpr.
4305 #define STMT(Node, Parent)
4306 #define ABSTRACT_STMT(Stmt)
4307 #define EXPR(Node, Parent) case Stmt::Node##Class:
4308 #include "clang/AST/StmtNodes.inc"
4309 {
4310 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4311
4312 if (SDK == StmtDiscardKind::StmtExprResult)
4313 E = getSema().ActOnStmtExprResult(E);
4314 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4315 }
4316 }
4317
4318 return S;
4319 }
4320
4321 template<typename Derived>
TransformOMPClause(OMPClause * S)4322 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4323 if (!S)
4324 return S;
4325
4326 switch (S->getClauseKind()) {
4327 default: break;
4328 // Transform individual clause nodes
4329 #define GEN_CLANG_CLAUSE_CLASS
4330 #define CLAUSE_CLASS(Enum, Str, Class) \
4331 case Enum: \
4332 return getDerived().Transform##Class(cast<Class>(S));
4333 #include "llvm/Frontend/OpenMP/OMP.inc"
4334 }
4335
4336 return S;
4337 }
4338
4339
4340 template<typename Derived>
TransformExpr(Expr * E)4341 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4342 if (!E)
4343 return E;
4344
4345 switch (E->getStmtClass()) {
4346 case Stmt::NoStmtClass: break;
4347 #define STMT(Node, Parent) case Stmt::Node##Class: break;
4348 #define ABSTRACT_STMT(Stmt)
4349 #define EXPR(Node, Parent) \
4350 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4351 #include "clang/AST/StmtNodes.inc"
4352 }
4353
4354 return E;
4355 }
4356
4357 template<typename Derived>
TransformInitializer(Expr * Init,bool NotCopyInit)4358 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4359 bool NotCopyInit) {
4360 // Initializers are instantiated like expressions, except that various outer
4361 // layers are stripped.
4362 if (!Init)
4363 return Init;
4364
4365 if (auto *FE = dyn_cast<FullExpr>(Init))
4366 Init = FE->getSubExpr();
4367
4368 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4369 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4370 Init = OVE->getSourceExpr();
4371 }
4372
4373 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4374 Init = MTE->getSubExpr();
4375
4376 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4377 Init = Binder->getSubExpr();
4378
4379 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4380 Init = ICE->getSubExprAsWritten();
4381
4382 if (CXXStdInitializerListExpr *ILE =
4383 dyn_cast<CXXStdInitializerListExpr>(Init))
4384 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4385
4386 // If this is copy-initialization, we only need to reconstruct
4387 // InitListExprs. Other forms of copy-initialization will be a no-op if
4388 // the initializer is already the right type.
4389 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4390 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4391 return getDerived().TransformExpr(Init);
4392
4393 // Revert value-initialization back to empty parens.
4394 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4395 SourceRange Parens = VIE->getSourceRange();
4396 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4397 Parens.getEnd());
4398 }
4399
4400 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4401 if (isa<ImplicitValueInitExpr>(Init))
4402 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4403 SourceLocation());
4404
4405 // Revert initialization by constructor back to a parenthesized or braced list
4406 // of expressions. Any other form of initializer can just be reused directly.
4407 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4408 return getDerived().TransformExpr(Init);
4409
4410 // If the initialization implicitly converted an initializer list to a
4411 // std::initializer_list object, unwrap the std::initializer_list too.
4412 if (Construct && Construct->isStdInitListInitialization())
4413 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4414
4415 // Enter a list-init context if this was list initialization.
4416 EnterExpressionEvaluationContext Context(
4417 getSema(), EnterExpressionEvaluationContext::InitList,
4418 Construct->isListInitialization());
4419
4420 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4421 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4422 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4423 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4424 SmallVector<Expr*, 8> NewArgs;
4425 bool ArgChanged = false;
4426 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4427 /*IsCall*/true, NewArgs, &ArgChanged))
4428 return ExprError();
4429
4430 // If this was list initialization, revert to syntactic list form.
4431 if (Construct->isListInitialization())
4432 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4433 Construct->getEndLoc());
4434
4435 // Build a ParenListExpr to represent anything else.
4436 SourceRange Parens = Construct->getParenOrBraceRange();
4437 if (Parens.isInvalid()) {
4438 // This was a variable declaration's initialization for which no initializer
4439 // was specified.
4440 assert(NewArgs.empty() &&
4441 "no parens or braces but have direct init with arguments?");
4442 return ExprEmpty();
4443 }
4444 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4445 Parens.getEnd());
4446 }
4447
4448 template<typename Derived>
TransformExprs(Expr * const * Inputs,unsigned NumInputs,bool IsCall,SmallVectorImpl<Expr * > & Outputs,bool * ArgChanged)4449 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4450 unsigned NumInputs,
4451 bool IsCall,
4452 SmallVectorImpl<Expr *> &Outputs,
4453 bool *ArgChanged) {
4454 for (unsigned I = 0; I != NumInputs; ++I) {
4455 // If requested, drop call arguments that need to be dropped.
4456 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4457 if (ArgChanged)
4458 *ArgChanged = true;
4459
4460 break;
4461 }
4462
4463 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4464 Expr *Pattern = Expansion->getPattern();
4465
4466 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4467 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4468 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4469
4470 // Determine whether the set of unexpanded parameter packs can and should
4471 // be expanded.
4472 bool Expand = true;
4473 bool RetainExpansion = false;
4474 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4475 UnsignedOrNone NumExpansions = OrigNumExpansions;
4476 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4477 Pattern->getSourceRange(),
4478 Unexpanded,
4479 Expand, RetainExpansion,
4480 NumExpansions))
4481 return true;
4482
4483 if (!Expand) {
4484 // The transform has determined that we should perform a simple
4485 // transformation on the pack expansion, producing another pack
4486 // expansion.
4487 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4488 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4489 if (OutPattern.isInvalid())
4490 return true;
4491
4492 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4493 Expansion->getEllipsisLoc(),
4494 NumExpansions);
4495 if (Out.isInvalid())
4496 return true;
4497
4498 if (ArgChanged)
4499 *ArgChanged = true;
4500 Outputs.push_back(Out.get());
4501 continue;
4502 }
4503
4504 // Record right away that the argument was changed. This needs
4505 // to happen even if the array expands to nothing.
4506 if (ArgChanged) *ArgChanged = true;
4507
4508 // The transform has determined that we should perform an elementwise
4509 // expansion of the pattern. Do so.
4510 for (unsigned I = 0; I != *NumExpansions; ++I) {
4511 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4512 ExprResult Out = getDerived().TransformExpr(Pattern);
4513 if (Out.isInvalid())
4514 return true;
4515
4516 if (Out.get()->containsUnexpandedParameterPack()) {
4517 Out = getDerived().RebuildPackExpansion(
4518 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4519 if (Out.isInvalid())
4520 return true;
4521 }
4522
4523 Outputs.push_back(Out.get());
4524 }
4525
4526 // If we're supposed to retain a pack expansion, do so by temporarily
4527 // forgetting the partially-substituted parameter pack.
4528 if (RetainExpansion) {
4529 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4530
4531 ExprResult Out = getDerived().TransformExpr(Pattern);
4532 if (Out.isInvalid())
4533 return true;
4534
4535 Out = getDerived().RebuildPackExpansion(
4536 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4537 if (Out.isInvalid())
4538 return true;
4539
4540 Outputs.push_back(Out.get());
4541 }
4542
4543 continue;
4544 }
4545
4546 ExprResult Result =
4547 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4548 : getDerived().TransformExpr(Inputs[I]);
4549 if (Result.isInvalid())
4550 return true;
4551
4552 if (Result.get() != Inputs[I] && ArgChanged)
4553 *ArgChanged = true;
4554
4555 Outputs.push_back(Result.get());
4556 }
4557
4558 return false;
4559 }
4560
4561 template <typename Derived>
TransformCondition(SourceLocation Loc,VarDecl * Var,Expr * Expr,Sema::ConditionKind Kind)4562 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4563 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4564
4565 EnterExpressionEvaluationContext Eval(
4566 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4567 /*LambdaContextDecl=*/nullptr,
4568 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4569 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4570
4571 if (Var) {
4572 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4573 getDerived().TransformDefinition(Var->getLocation(), Var));
4574
4575 if (!ConditionVar)
4576 return Sema::ConditionError();
4577
4578 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4579 }
4580
4581 if (Expr) {
4582 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4583
4584 if (CondExpr.isInvalid())
4585 return Sema::ConditionError();
4586
4587 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4588 /*MissingOK=*/true);
4589 }
4590
4591 return Sema::ConditionResult();
4592 }
4593
4594 template <typename Derived>
TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,QualType ObjectType,NamedDecl * FirstQualifierInScope)4595 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4596 NestedNameSpecifierLoc NNS, QualType ObjectType,
4597 NamedDecl *FirstQualifierInScope) {
4598 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4599
4600 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4601 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4602 Qualifier = Qualifier.getPrefix())
4603 Qualifiers.push_back(Qualifier);
4604 };
4605 insertNNS(NNS);
4606
4607 CXXScopeSpec SS;
4608 while (!Qualifiers.empty()) {
4609 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4610 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4611
4612 switch (QNNS->getKind()) {
4613 case NestedNameSpecifier::Identifier: {
4614 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4615 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4616 ObjectType);
4617 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4618 SS, FirstQualifierInScope, false))
4619 return NestedNameSpecifierLoc();
4620 break;
4621 }
4622
4623 case NestedNameSpecifier::Namespace: {
4624 NamespaceDecl *NS =
4625 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4626 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4627 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4628 break;
4629 }
4630
4631 case NestedNameSpecifier::NamespaceAlias: {
4632 NamespaceAliasDecl *Alias =
4633 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4634 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4635 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4636 Q.getLocalEndLoc());
4637 break;
4638 }
4639
4640 case NestedNameSpecifier::Global:
4641 // There is no meaningful transformation that one could perform on the
4642 // global scope.
4643 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4644 break;
4645
4646 case NestedNameSpecifier::Super: {
4647 CXXRecordDecl *RD =
4648 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4649 SourceLocation(), QNNS->getAsRecordDecl()));
4650 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4651 break;
4652 }
4653
4654 case NestedNameSpecifier::TypeSpec: {
4655 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4656 FirstQualifierInScope, SS);
4657
4658 if (!TL)
4659 return NestedNameSpecifierLoc();
4660
4661 QualType T = TL.getType();
4662 if (T->isDependentType() || T->isRecordType() ||
4663 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4664 if (T->isEnumeralType())
4665 SemaRef.Diag(TL.getBeginLoc(),
4666 diag::warn_cxx98_compat_enum_nested_name_spec);
4667
4668 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4669 SS.Adopt(ETL.getQualifierLoc());
4670 TL = ETL.getNamedTypeLoc();
4671 }
4672
4673 SS.Extend(SemaRef.Context, TL, Q.getLocalEndLoc());
4674 break;
4675 }
4676 // If the nested-name-specifier is an invalid type def, don't emit an
4677 // error because a previous error should have already been emitted.
4678 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4679 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4680 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4681 << T << SS.getRange();
4682 }
4683 return NestedNameSpecifierLoc();
4684 }
4685 }
4686
4687 // The qualifier-in-scope and object type only apply to the leftmost entity.
4688 FirstQualifierInScope = nullptr;
4689 ObjectType = QualType();
4690 }
4691
4692 // Don't rebuild the nested-name-specifier if we don't have to.
4693 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4694 !getDerived().AlwaysRebuild())
4695 return NNS;
4696
4697 // If we can re-use the source-location data from the original
4698 // nested-name-specifier, do so.
4699 if (SS.location_size() == NNS.getDataLength() &&
4700 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4701 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4702
4703 // Allocate new nested-name-specifier location information.
4704 return SS.getWithLocInContext(SemaRef.Context);
4705 }
4706
4707 template<typename Derived>
4708 DeclarationNameInfo
4709 TreeTransform<Derived>
TransformDeclarationNameInfo(const DeclarationNameInfo & NameInfo)4710 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4711 DeclarationName Name = NameInfo.getName();
4712 if (!Name)
4713 return DeclarationNameInfo();
4714
4715 switch (Name.getNameKind()) {
4716 case DeclarationName::Identifier:
4717 case DeclarationName::ObjCZeroArgSelector:
4718 case DeclarationName::ObjCOneArgSelector:
4719 case DeclarationName::ObjCMultiArgSelector:
4720 case DeclarationName::CXXOperatorName:
4721 case DeclarationName::CXXLiteralOperatorName:
4722 case DeclarationName::CXXUsingDirective:
4723 return NameInfo;
4724
4725 case DeclarationName::CXXDeductionGuideName: {
4726 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4727 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4728 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4729 if (!NewTemplate)
4730 return DeclarationNameInfo();
4731
4732 DeclarationNameInfo NewNameInfo(NameInfo);
4733 NewNameInfo.setName(
4734 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4735 return NewNameInfo;
4736 }
4737
4738 case DeclarationName::CXXConstructorName:
4739 case DeclarationName::CXXDestructorName:
4740 case DeclarationName::CXXConversionFunctionName: {
4741 TypeSourceInfo *NewTInfo;
4742 CanQualType NewCanTy;
4743 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4744 NewTInfo = getDerived().TransformType(OldTInfo);
4745 if (!NewTInfo)
4746 return DeclarationNameInfo();
4747 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4748 }
4749 else {
4750 NewTInfo = nullptr;
4751 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4752 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4753 if (NewT.isNull())
4754 return DeclarationNameInfo();
4755 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4756 }
4757
4758 DeclarationName NewName
4759 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4760 NewCanTy);
4761 DeclarationNameInfo NewNameInfo(NameInfo);
4762 NewNameInfo.setName(NewName);
4763 NewNameInfo.setNamedTypeInfo(NewTInfo);
4764 return NewNameInfo;
4765 }
4766 }
4767
4768 llvm_unreachable("Unknown name kind.");
4769 }
4770
4771 template <typename Derived>
RebuildTemplateName(CXXScopeSpec & SS,SourceLocation TemplateKWLoc,IdentifierOrOverloadedOperator IO,SourceLocation NameLoc,QualType ObjectType,NamedDecl * FirstQualifierInScope,bool AllowInjectedClassName)4772 TemplateName TreeTransform<Derived>::RebuildTemplateName(
4773 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4774 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4775 QualType ObjectType, NamedDecl *FirstQualifierInScope,
4776 bool AllowInjectedClassName) {
4777 if (const IdentifierInfo *II = IO.getIdentifier()) {
4778 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4779 ObjectType, FirstQualifierInScope,
4780 AllowInjectedClassName);
4781 }
4782 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4783 NameLoc, ObjectType,
4784 AllowInjectedClassName);
4785 }
4786
4787 template<typename Derived>
4788 TemplateName
TransformTemplateName(CXXScopeSpec & SS,TemplateName Name,SourceLocation NameLoc,QualType ObjectType,NamedDecl * FirstQualifierInScope,bool AllowInjectedClassName)4789 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4790 TemplateName Name,
4791 SourceLocation NameLoc,
4792 QualType ObjectType,
4793 NamedDecl *FirstQualifierInScope,
4794 bool AllowInjectedClassName) {
4795 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4796 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4797 assert(Template && "qualified template name must refer to a template");
4798
4799 TemplateDecl *TransTemplate
4800 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4801 Template));
4802 if (!TransTemplate)
4803 return TemplateName();
4804
4805 if (!getDerived().AlwaysRebuild() &&
4806 SS.getScopeRep() == QTN->getQualifier() &&
4807 TransTemplate == Template)
4808 return Name;
4809
4810 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4811 TransTemplate);
4812 }
4813
4814 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4815 if (SS.getScopeRep()) {
4816 // These apply to the scope specifier, not the template.
4817 ObjectType = QualType();
4818 FirstQualifierInScope = nullptr;
4819 }
4820
4821 if (!getDerived().AlwaysRebuild() &&
4822 SS.getScopeRep() == DTN->getQualifier() &&
4823 ObjectType.isNull())
4824 return Name;
4825
4826 // FIXME: Preserve the location of the "template" keyword.
4827 SourceLocation TemplateKWLoc = NameLoc;
4828 return getDerived().RebuildTemplateName(
4829 SS, TemplateKWLoc, DTN->getName(), NameLoc, ObjectType,
4830 FirstQualifierInScope, AllowInjectedClassName);
4831 }
4832
4833 // FIXME: Try to preserve more of the TemplateName.
4834 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4835 TemplateDecl *TransTemplate
4836 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4837 Template));
4838 if (!TransTemplate)
4839 return TemplateName();
4840
4841 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4842 TransTemplate);
4843 }
4844
4845 if (SubstTemplateTemplateParmPackStorage *SubstPack
4846 = Name.getAsSubstTemplateTemplateParmPack()) {
4847 return getDerived().RebuildTemplateName(
4848 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4849 SubstPack->getIndex(), SubstPack->getFinal());
4850 }
4851
4852 // These should be getting filtered out before they reach the AST.
4853 llvm_unreachable("overloaded function decl survived to here");
4854 }
4855
4856 template<typename Derived>
InventTemplateArgumentLoc(const TemplateArgument & Arg,TemplateArgumentLoc & Output)4857 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4858 const TemplateArgument &Arg,
4859 TemplateArgumentLoc &Output) {
4860 Output = getSema().getTrivialTemplateArgumentLoc(
4861 Arg, QualType(), getDerived().getBaseLocation());
4862 }
4863
4864 template <typename Derived>
TransformTemplateArgument(const TemplateArgumentLoc & Input,TemplateArgumentLoc & Output,bool Uneval)4865 bool TreeTransform<Derived>::TransformTemplateArgument(
4866 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4867 bool Uneval) {
4868 const TemplateArgument &Arg = Input.getArgument();
4869 switch (Arg.getKind()) {
4870 case TemplateArgument::Null:
4871 case TemplateArgument::Pack:
4872 llvm_unreachable("Unexpected TemplateArgument");
4873
4874 case TemplateArgument::Integral:
4875 case TemplateArgument::NullPtr:
4876 case TemplateArgument::Declaration:
4877 case TemplateArgument::StructuralValue: {
4878 // Transform a resolved template argument straight to a resolved template
4879 // argument. We get here when substituting into an already-substituted
4880 // template type argument during concept satisfaction checking.
4881 QualType T = Arg.getNonTypeTemplateArgumentType();
4882 QualType NewT = getDerived().TransformType(T);
4883 if (NewT.isNull())
4884 return true;
4885
4886 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4887 ? Arg.getAsDecl()
4888 : nullptr;
4889 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4890 getDerived().getBaseLocation(), D))
4891 : nullptr;
4892 if (D && !NewD)
4893 return true;
4894
4895 if (NewT == T && D == NewD)
4896 Output = Input;
4897 else if (Arg.getKind() == TemplateArgument::Integral)
4898 Output = TemplateArgumentLoc(
4899 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4900 TemplateArgumentLocInfo());
4901 else if (Arg.getKind() == TemplateArgument::NullPtr)
4902 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4903 TemplateArgumentLocInfo());
4904 else if (Arg.getKind() == TemplateArgument::Declaration)
4905 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4906 TemplateArgumentLocInfo());
4907 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4908 Output = TemplateArgumentLoc(
4909 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4910 TemplateArgumentLocInfo());
4911 else
4912 llvm_unreachable("unexpected template argument kind");
4913
4914 return false;
4915 }
4916
4917 case TemplateArgument::Type: {
4918 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4919 if (!DI)
4920 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4921
4922 DI = getDerived().TransformType(DI);
4923 if (!DI)
4924 return true;
4925
4926 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4927 return false;
4928 }
4929
4930 case TemplateArgument::Template: {
4931 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4932 if (QualifierLoc) {
4933 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4934 if (!QualifierLoc)
4935 return true;
4936 }
4937
4938 CXXScopeSpec SS;
4939 SS.Adopt(QualifierLoc);
4940 TemplateName Template = getDerived().TransformTemplateName(
4941 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4942 if (Template.isNull())
4943 return true;
4944
4945 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4946 QualifierLoc, Input.getTemplateNameLoc());
4947 return false;
4948 }
4949
4950 case TemplateArgument::TemplateExpansion:
4951 llvm_unreachable("Caller should expand pack expansions");
4952
4953 case TemplateArgument::Expression: {
4954 // Template argument expressions are constant expressions.
4955 EnterExpressionEvaluationContext Unevaluated(
4956 getSema(),
4957 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4958 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4959 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4960 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4961
4962 Expr *InputExpr = Input.getSourceExpression();
4963 if (!InputExpr)
4964 InputExpr = Input.getArgument().getAsExpr();
4965
4966 ExprResult E = getDerived().TransformExpr(InputExpr);
4967 E = SemaRef.ActOnConstantExpression(E);
4968 if (E.isInvalid())
4969 return true;
4970 Output = TemplateArgumentLoc(
4971 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
4972 return false;
4973 }
4974 }
4975
4976 // Work around bogus GCC warning
4977 return true;
4978 }
4979
4980 /// Iterator adaptor that invents template argument location information
4981 /// for each of the template arguments in its underlying iterator.
4982 template<typename Derived, typename InputIterator>
4983 class TemplateArgumentLocInventIterator {
4984 TreeTransform<Derived> &Self;
4985 InputIterator Iter;
4986
4987 public:
4988 typedef TemplateArgumentLoc value_type;
4989 typedef TemplateArgumentLoc reference;
4990 typedef typename std::iterator_traits<InputIterator>::difference_type
4991 difference_type;
4992 typedef std::input_iterator_tag iterator_category;
4993
4994 class pointer {
4995 TemplateArgumentLoc Arg;
4996
4997 public:
pointer(TemplateArgumentLoc Arg)4998 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4999
5000 const TemplateArgumentLoc *operator->() const { return &Arg; }
5001 };
5002
TemplateArgumentLocInventIterator(TreeTransform<Derived> & Self,InputIterator Iter)5003 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5004 InputIterator Iter)
5005 : Self(Self), Iter(Iter) { }
5006
5007 TemplateArgumentLocInventIterator &operator++() {
5008 ++Iter;
5009 return *this;
5010 }
5011
5012 TemplateArgumentLocInventIterator operator++(int) {
5013 TemplateArgumentLocInventIterator Old(*this);
5014 ++(*this);
5015 return Old;
5016 }
5017
5018 reference operator*() const {
5019 TemplateArgumentLoc Result;
5020 Self.InventTemplateArgumentLoc(*Iter, Result);
5021 return Result;
5022 }
5023
5024 pointer operator->() const { return pointer(**this); }
5025
5026 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5027 const TemplateArgumentLocInventIterator &Y) {
5028 return X.Iter == Y.Iter;
5029 }
5030
5031 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5032 const TemplateArgumentLocInventIterator &Y) {
5033 return X.Iter != Y.Iter;
5034 }
5035 };
5036
5037 template<typename Derived>
5038 template<typename InputIterator>
TransformTemplateArguments(InputIterator First,InputIterator Last,TemplateArgumentListInfo & Outputs,bool Uneval)5039 bool TreeTransform<Derived>::TransformTemplateArguments(
5040 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5041 bool Uneval) {
5042 for (; First != Last; ++First) {
5043 TemplateArgumentLoc Out;
5044 TemplateArgumentLoc In = *First;
5045
5046 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5047 // Unpack argument packs, which we translate them into separate
5048 // arguments.
5049 // FIXME: We could do much better if we could guarantee that the
5050 // TemplateArgumentLocInfo for the pack expansion would be usable for
5051 // all of the template arguments in the argument pack.
5052 typedef TemplateArgumentLocInventIterator<Derived,
5053 TemplateArgument::pack_iterator>
5054 PackLocIterator;
5055 if (TransformTemplateArguments(PackLocIterator(*this,
5056 In.getArgument().pack_begin()),
5057 PackLocIterator(*this,
5058 In.getArgument().pack_end()),
5059 Outputs, Uneval))
5060 return true;
5061
5062 continue;
5063 }
5064
5065 if (In.getArgument().isPackExpansion()) {
5066 // We have a pack expansion, for which we will be substituting into
5067 // the pattern.
5068 SourceLocation Ellipsis;
5069 UnsignedOrNone OrigNumExpansions = std::nullopt;
5070 TemplateArgumentLoc Pattern
5071 = getSema().getTemplateArgumentPackExpansionPattern(
5072 In, Ellipsis, OrigNumExpansions);
5073
5074 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5075 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5076 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5077
5078 // Determine whether the set of unexpanded parameter packs can and should
5079 // be expanded.
5080 bool Expand = true;
5081 bool RetainExpansion = false;
5082 UnsignedOrNone NumExpansions = OrigNumExpansions;
5083 if (getDerived().TryExpandParameterPacks(Ellipsis,
5084 Pattern.getSourceRange(),
5085 Unexpanded,
5086 Expand,
5087 RetainExpansion,
5088 NumExpansions))
5089 return true;
5090
5091 if (!Expand) {
5092 // The transform has determined that we should perform a simple
5093 // transformation on the pack expansion, producing another pack
5094 // expansion.
5095 TemplateArgumentLoc OutPattern;
5096 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5097 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5098 return true;
5099
5100 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
5101 NumExpansions);
5102 if (Out.getArgument().isNull())
5103 return true;
5104
5105 Outputs.addArgument(Out);
5106 continue;
5107 }
5108
5109 // The transform has determined that we should perform an elementwise
5110 // expansion of the pattern. Do so.
5111 for (unsigned I = 0; I != *NumExpansions; ++I) {
5112 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5113
5114 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5115 return true;
5116
5117 if (Out.getArgument().containsUnexpandedParameterPack()) {
5118 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5119 OrigNumExpansions);
5120 if (Out.getArgument().isNull())
5121 return true;
5122 }
5123
5124 Outputs.addArgument(Out);
5125 }
5126
5127 // If we're supposed to retain a pack expansion, do so by temporarily
5128 // forgetting the partially-substituted parameter pack.
5129 if (RetainExpansion) {
5130 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5131
5132 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5133 return true;
5134
5135 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5136 OrigNumExpansions);
5137 if (Out.getArgument().isNull())
5138 return true;
5139
5140 Outputs.addArgument(Out);
5141 }
5142
5143 continue;
5144 }
5145
5146 // The simple case:
5147 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5148 return true;
5149
5150 Outputs.addArgument(Out);
5151 }
5152
5153 return false;
5154
5155 }
5156
5157 //===----------------------------------------------------------------------===//
5158 // Type transformation
5159 //===----------------------------------------------------------------------===//
5160
5161 template<typename Derived>
TransformType(QualType T)5162 QualType TreeTransform<Derived>::TransformType(QualType T) {
5163 if (getDerived().AlreadyTransformed(T))
5164 return T;
5165
5166 // Temporary workaround. All of these transformations should
5167 // eventually turn into transformations on TypeLocs.
5168 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5169 getDerived().getBaseLocation());
5170
5171 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5172
5173 if (!NewDI)
5174 return QualType();
5175
5176 return NewDI->getType();
5177 }
5178
5179 template<typename Derived>
TransformType(TypeSourceInfo * DI)5180 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
5181 // Refine the base location to the type's location.
5182 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5183 getDerived().getBaseEntity());
5184 if (getDerived().AlreadyTransformed(DI->getType()))
5185 return DI;
5186
5187 TypeLocBuilder TLB;
5188
5189 TypeLoc TL = DI->getTypeLoc();
5190 TLB.reserve(TL.getFullDataSize());
5191
5192 QualType Result = getDerived().TransformType(TLB, TL);
5193 if (Result.isNull())
5194 return nullptr;
5195
5196 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5197 }
5198
5199 template<typename Derived>
5200 QualType
TransformType(TypeLocBuilder & TLB,TypeLoc T)5201 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5202 switch (T.getTypeLocClass()) {
5203 #define ABSTRACT_TYPELOC(CLASS, PARENT)
5204 #define TYPELOC(CLASS, PARENT) \
5205 case TypeLoc::CLASS: \
5206 return getDerived().Transform##CLASS##Type(TLB, \
5207 T.castAs<CLASS##TypeLoc>());
5208 #include "clang/AST/TypeLocNodes.def"
5209 }
5210
5211 llvm_unreachable("unhandled type loc!");
5212 }
5213
5214 template<typename Derived>
TransformTypeWithDeducedTST(QualType T)5215 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5216 if (!isa<DependentNameType>(T))
5217 return TransformType(T);
5218
5219 if (getDerived().AlreadyTransformed(T))
5220 return T;
5221 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5222 getDerived().getBaseLocation());
5223 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5224 return NewDI ? NewDI->getType() : QualType();
5225 }
5226
5227 template<typename Derived>
5228 TypeSourceInfo *
TransformTypeWithDeducedTST(TypeSourceInfo * DI)5229 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5230 if (!isa<DependentNameType>(DI->getType()))
5231 return TransformType(DI);
5232
5233 // Refine the base location to the type's location.
5234 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5235 getDerived().getBaseEntity());
5236 if (getDerived().AlreadyTransformed(DI->getType()))
5237 return DI;
5238
5239 TypeLocBuilder TLB;
5240
5241 TypeLoc TL = DI->getTypeLoc();
5242 TLB.reserve(TL.getFullDataSize());
5243
5244 auto QTL = TL.getAs<QualifiedTypeLoc>();
5245 if (QTL)
5246 TL = QTL.getUnqualifiedLoc();
5247
5248 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5249
5250 QualType Result = getDerived().TransformDependentNameType(
5251 TLB, DNTL, /*DeducedTSTContext*/true);
5252 if (Result.isNull())
5253 return nullptr;
5254
5255 if (QTL) {
5256 Result = getDerived().RebuildQualifiedType(Result, QTL);
5257 if (Result.isNull())
5258 return nullptr;
5259 TLB.TypeWasModifiedSafely(Result);
5260 }
5261
5262 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5263 }
5264
5265 template<typename Derived>
5266 QualType
TransformQualifiedType(TypeLocBuilder & TLB,QualifiedTypeLoc T)5267 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5268 QualifiedTypeLoc T) {
5269 QualType Result;
5270 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5271 auto SuppressObjCLifetime =
5272 T.getType().getLocalQualifiers().hasObjCLifetime();
5273 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5274 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5275 SuppressObjCLifetime);
5276 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5277 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5278 TLB, STTP, SuppressObjCLifetime);
5279 } else {
5280 Result = getDerived().TransformType(TLB, UnqualTL);
5281 }
5282
5283 if (Result.isNull())
5284 return QualType();
5285
5286 Result = getDerived().RebuildQualifiedType(Result, T);
5287
5288 if (Result.isNull())
5289 return QualType();
5290
5291 // RebuildQualifiedType might have updated the type, but not in a way
5292 // that invalidates the TypeLoc. (There's no location information for
5293 // qualifiers.)
5294 TLB.TypeWasModifiedSafely(Result);
5295
5296 return Result;
5297 }
5298
5299 template <typename Derived>
RebuildQualifiedType(QualType T,QualifiedTypeLoc TL)5300 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5301 QualifiedTypeLoc TL) {
5302
5303 SourceLocation Loc = TL.getBeginLoc();
5304 Qualifiers Quals = TL.getType().getLocalQualifiers();
5305
5306 if ((T.getAddressSpace() != LangAS::Default &&
5307 Quals.getAddressSpace() != LangAS::Default) &&
5308 T.getAddressSpace() != Quals.getAddressSpace()) {
5309 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5310 << TL.getType() << T;
5311 return QualType();
5312 }
5313
5314 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5315 if (LocalPointerAuth.isPresent()) {
5316 if (T.getPointerAuth().isPresent()) {
5317 SemaRef.Diag(Loc, diag::err_ptrauth_qualifier_redundant) << TL.getType();
5318 return QualType();
5319 }
5320 if (!T->isDependentType()) {
5321 if (!T->isSignableType(SemaRef.getASTContext())) {
5322 SemaRef.Diag(Loc, diag::err_ptrauth_qualifier_invalid_target) << T;
5323 return QualType();
5324 }
5325 }
5326 }
5327 // C++ [dcl.fct]p7:
5328 // [When] adding cv-qualifications on top of the function type [...] the
5329 // cv-qualifiers are ignored.
5330 if (T->isFunctionType()) {
5331 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5332 Quals.getAddressSpace());
5333 return T;
5334 }
5335
5336 // C++ [dcl.ref]p1:
5337 // when the cv-qualifiers are introduced through the use of a typedef-name
5338 // or decltype-specifier [...] the cv-qualifiers are ignored.
5339 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5340 // applied to a reference type.
5341 if (T->isReferenceType()) {
5342 // The only qualifier that applies to a reference type is restrict.
5343 if (!Quals.hasRestrict())
5344 return T;
5345 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
5346 }
5347
5348 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5349 // resulting type.
5350 if (Quals.hasObjCLifetime()) {
5351 if (!T->isObjCLifetimeType() && !T->isDependentType())
5352 Quals.removeObjCLifetime();
5353 else if (T.getObjCLifetime()) {
5354 // Objective-C ARC:
5355 // A lifetime qualifier applied to a substituted template parameter
5356 // overrides the lifetime qualifier from the template argument.
5357 const AutoType *AutoTy;
5358 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5359 // 'auto' types behave the same way as template parameters.
5360 QualType Deduced = AutoTy->getDeducedType();
5361 Qualifiers Qs = Deduced.getQualifiers();
5362 Qs.removeObjCLifetime();
5363 Deduced =
5364 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5365 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5366 AutoTy->isDependentType(),
5367 /*isPack=*/false,
5368 AutoTy->getTypeConstraintConcept(),
5369 AutoTy->getTypeConstraintArguments());
5370 } else {
5371 // Otherwise, complain about the addition of a qualifier to an
5372 // already-qualified type.
5373 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5374 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5375 Quals.removeObjCLifetime();
5376 }
5377 }
5378 }
5379
5380 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5381 }
5382
5383 template<typename Derived>
5384 TypeLoc
TransformTypeInObjectScope(TypeLoc TL,QualType ObjectType,NamedDecl * UnqualLookup,CXXScopeSpec & SS)5385 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5386 QualType ObjectType,
5387 NamedDecl *UnqualLookup,
5388 CXXScopeSpec &SS) {
5389 if (getDerived().AlreadyTransformed(TL.getType()))
5390 return TL;
5391
5392 TypeSourceInfo *TSI =
5393 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5394 if (TSI)
5395 return TSI->getTypeLoc();
5396 return TypeLoc();
5397 }
5398
5399 template<typename Derived>
5400 TypeSourceInfo *
TransformTypeInObjectScope(TypeSourceInfo * TSInfo,QualType ObjectType,NamedDecl * UnqualLookup,CXXScopeSpec & SS)5401 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5402 QualType ObjectType,
5403 NamedDecl *UnqualLookup,
5404 CXXScopeSpec &SS) {
5405 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5406 return TSInfo;
5407
5408 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5409 UnqualLookup, SS);
5410 }
5411
5412 template <typename Derived>
TransformTSIInObjectScope(TypeLoc TL,QualType ObjectType,NamedDecl * UnqualLookup,CXXScopeSpec & SS)5413 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5414 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5415 CXXScopeSpec &SS) {
5416 QualType T = TL.getType();
5417 assert(!getDerived().AlreadyTransformed(T));
5418
5419 TypeLocBuilder TLB;
5420 QualType Result;
5421
5422 if (isa<TemplateSpecializationType>(T)) {
5423 TemplateSpecializationTypeLoc SpecTL =
5424 TL.castAs<TemplateSpecializationTypeLoc>();
5425
5426 TemplateName Template = getDerived().TransformTemplateName(
5427 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5428 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5429 if (Template.isNull())
5430 return nullptr;
5431
5432 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5433 Template);
5434 } else if (isa<DependentTemplateSpecializationType>(T)) {
5435 DependentTemplateSpecializationTypeLoc SpecTL =
5436 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5437
5438 const IdentifierInfo *II = SpecTL.getTypePtr()
5439 ->getDependentTemplateName()
5440 .getName()
5441 .getIdentifier();
5442 TemplateName Template = getDerived().RebuildTemplateName(
5443 SS, SpecTL.getTemplateKeywordLoc(), *II, SpecTL.getTemplateNameLoc(),
5444 ObjectType, UnqualLookup,
5445 /*AllowInjectedClassName*/ true);
5446 if (Template.isNull())
5447 return nullptr;
5448
5449 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5450 SpecTL,
5451 Template,
5452 SS);
5453 } else {
5454 // Nothing special needs to be done for these.
5455 Result = getDerived().TransformType(TLB, TL);
5456 }
5457
5458 if (Result.isNull())
5459 return nullptr;
5460
5461 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5462 }
5463
5464 template <class TyLoc> static inline
TransformTypeSpecType(TypeLocBuilder & TLB,TyLoc T)5465 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5466 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5467 NewT.setNameLoc(T.getNameLoc());
5468 return T.getType();
5469 }
5470
5471 template<typename Derived>
TransformBuiltinType(TypeLocBuilder & TLB,BuiltinTypeLoc T)5472 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5473 BuiltinTypeLoc T) {
5474 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5475 NewT.setBuiltinLoc(T.getBuiltinLoc());
5476 if (T.needsExtraLocalData())
5477 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5478 return T.getType();
5479 }
5480
5481 template<typename Derived>
TransformComplexType(TypeLocBuilder & TLB,ComplexTypeLoc T)5482 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5483 ComplexTypeLoc T) {
5484 // FIXME: recurse?
5485 return TransformTypeSpecType(TLB, T);
5486 }
5487
5488 template <typename Derived>
TransformAdjustedType(TypeLocBuilder & TLB,AdjustedTypeLoc TL)5489 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5490 AdjustedTypeLoc TL) {
5491 // Adjustments applied during transformation are handled elsewhere.
5492 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5493 }
5494
5495 template<typename Derived>
TransformDecayedType(TypeLocBuilder & TLB,DecayedTypeLoc TL)5496 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5497 DecayedTypeLoc TL) {
5498 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5499 if (OriginalType.isNull())
5500 return QualType();
5501
5502 QualType Result = TL.getType();
5503 if (getDerived().AlwaysRebuild() ||
5504 OriginalType != TL.getOriginalLoc().getType())
5505 Result = SemaRef.Context.getDecayedType(OriginalType);
5506 TLB.push<DecayedTypeLoc>(Result);
5507 // Nothing to set for DecayedTypeLoc.
5508 return Result;
5509 }
5510
5511 template <typename Derived>
5512 QualType
TransformArrayParameterType(TypeLocBuilder & TLB,ArrayParameterTypeLoc TL)5513 TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5514 ArrayParameterTypeLoc TL) {
5515 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5516 if (OriginalType.isNull())
5517 return QualType();
5518
5519 QualType Result = TL.getType();
5520 if (getDerived().AlwaysRebuild() ||
5521 OriginalType != TL.getElementLoc().getType())
5522 Result = SemaRef.Context.getArrayParameterType(OriginalType);
5523 TLB.push<ArrayParameterTypeLoc>(Result);
5524 // Nothing to set for ArrayParameterTypeLoc.
5525 return Result;
5526 }
5527
5528 template<typename Derived>
TransformPointerType(TypeLocBuilder & TLB,PointerTypeLoc TL)5529 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5530 PointerTypeLoc TL) {
5531 QualType PointeeType
5532 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5533 if (PointeeType.isNull())
5534 return QualType();
5535
5536 QualType Result = TL.getType();
5537 if (PointeeType->getAs<ObjCObjectType>()) {
5538 // A dependent pointer type 'T *' has is being transformed such
5539 // that an Objective-C class type is being replaced for 'T'. The
5540 // resulting pointer type is an ObjCObjectPointerType, not a
5541 // PointerType.
5542 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5543
5544 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5545 NewT.setStarLoc(TL.getStarLoc());
5546 return Result;
5547 }
5548
5549 if (getDerived().AlwaysRebuild() ||
5550 PointeeType != TL.getPointeeLoc().getType()) {
5551 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5552 if (Result.isNull())
5553 return QualType();
5554 }
5555
5556 // Objective-C ARC can add lifetime qualifiers to the type that we're
5557 // pointing to.
5558 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5559
5560 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5561 NewT.setSigilLoc(TL.getSigilLoc());
5562 return Result;
5563 }
5564
5565 template<typename Derived>
5566 QualType
TransformBlockPointerType(TypeLocBuilder & TLB,BlockPointerTypeLoc TL)5567 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5568 BlockPointerTypeLoc TL) {
5569 QualType PointeeType
5570 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5571 if (PointeeType.isNull())
5572 return QualType();
5573
5574 QualType Result = TL.getType();
5575 if (getDerived().AlwaysRebuild() ||
5576 PointeeType != TL.getPointeeLoc().getType()) {
5577 Result = getDerived().RebuildBlockPointerType(PointeeType,
5578 TL.getSigilLoc());
5579 if (Result.isNull())
5580 return QualType();
5581 }
5582
5583 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5584 NewT.setSigilLoc(TL.getSigilLoc());
5585 return Result;
5586 }
5587
5588 /// Transforms a reference type. Note that somewhat paradoxically we
5589 /// don't care whether the type itself is an l-value type or an r-value
5590 /// type; we only care if the type was *written* as an l-value type
5591 /// or an r-value type.
5592 template<typename Derived>
5593 QualType
TransformReferenceType(TypeLocBuilder & TLB,ReferenceTypeLoc TL)5594 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5595 ReferenceTypeLoc TL) {
5596 const ReferenceType *T = TL.getTypePtr();
5597
5598 // Note that this works with the pointee-as-written.
5599 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5600 if (PointeeType.isNull())
5601 return QualType();
5602
5603 QualType Result = TL.getType();
5604 if (getDerived().AlwaysRebuild() ||
5605 PointeeType != T->getPointeeTypeAsWritten()) {
5606 Result = getDerived().RebuildReferenceType(PointeeType,
5607 T->isSpelledAsLValue(),
5608 TL.getSigilLoc());
5609 if (Result.isNull())
5610 return QualType();
5611 }
5612
5613 // Objective-C ARC can add lifetime qualifiers to the type that we're
5614 // referring to.
5615 TLB.TypeWasModifiedSafely(
5616 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5617
5618 // r-value references can be rebuilt as l-value references.
5619 ReferenceTypeLoc NewTL;
5620 if (isa<LValueReferenceType>(Result))
5621 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5622 else
5623 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5624 NewTL.setSigilLoc(TL.getSigilLoc());
5625
5626 return Result;
5627 }
5628
5629 template<typename Derived>
5630 QualType
TransformLValueReferenceType(TypeLocBuilder & TLB,LValueReferenceTypeLoc TL)5631 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5632 LValueReferenceTypeLoc TL) {
5633 return TransformReferenceType(TLB, TL);
5634 }
5635
5636 template<typename Derived>
5637 QualType
TransformRValueReferenceType(TypeLocBuilder & TLB,RValueReferenceTypeLoc TL)5638 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5639 RValueReferenceTypeLoc TL) {
5640 return TransformReferenceType(TLB, TL);
5641 }
5642
5643 template<typename Derived>
5644 QualType
TransformMemberPointerType(TypeLocBuilder & TLB,MemberPointerTypeLoc TL)5645 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5646 MemberPointerTypeLoc TL) {
5647 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5648 if (PointeeType.isNull())
5649 return QualType();
5650
5651 const MemberPointerType *T = TL.getTypePtr();
5652
5653 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5654 NestedNameSpecifierLoc NewQualifierLoc =
5655 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5656 if (!NewQualifierLoc)
5657 return QualType();
5658
5659 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5660 if (OldCls) {
5661 NewCls = cast_or_null<CXXRecordDecl>(
5662 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5663 if (!NewCls)
5664 return QualType();
5665 }
5666
5667 QualType Result = TL.getType();
5668 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5669 NewQualifierLoc.getNestedNameSpecifier() !=
5670 OldQualifierLoc.getNestedNameSpecifier() ||
5671 NewCls != OldCls) {
5672 CXXScopeSpec SS;
5673 SS.Adopt(NewQualifierLoc);
5674 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5675 TL.getStarLoc());
5676 if (Result.isNull())
5677 return QualType();
5678 }
5679
5680 // If we had to adjust the pointee type when building a member pointer, make
5681 // sure to push TypeLoc info for it.
5682 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5683 if (MPT && PointeeType != MPT->getPointeeType()) {
5684 assert(isa<AdjustedType>(MPT->getPointeeType()));
5685 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5686 }
5687
5688 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5689 NewTL.setSigilLoc(TL.getSigilLoc());
5690 NewTL.setQualifierLoc(NewQualifierLoc);
5691
5692 return Result;
5693 }
5694
5695 template<typename Derived>
5696 QualType
TransformConstantArrayType(TypeLocBuilder & TLB,ConstantArrayTypeLoc TL)5697 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5698 ConstantArrayTypeLoc TL) {
5699 const ConstantArrayType *T = TL.getTypePtr();
5700 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5701 if (ElementType.isNull())
5702 return QualType();
5703
5704 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5705 Expr *OldSize = TL.getSizeExpr();
5706 if (!OldSize)
5707 OldSize = const_cast<Expr*>(T->getSizeExpr());
5708 Expr *NewSize = nullptr;
5709 if (OldSize) {
5710 EnterExpressionEvaluationContext Unevaluated(
5711 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5712 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5713 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5714 }
5715
5716 QualType Result = TL.getType();
5717 if (getDerived().AlwaysRebuild() ||
5718 ElementType != T->getElementType() ||
5719 (T->getSizeExpr() && NewSize != OldSize)) {
5720 Result = getDerived().RebuildConstantArrayType(ElementType,
5721 T->getSizeModifier(),
5722 T->getSize(), NewSize,
5723 T->getIndexTypeCVRQualifiers(),
5724 TL.getBracketsRange());
5725 if (Result.isNull())
5726 return QualType();
5727 }
5728
5729 // We might have either a ConstantArrayType or a VariableArrayType now:
5730 // a ConstantArrayType is allowed to have an element type which is a
5731 // VariableArrayType if the type is dependent. Fortunately, all array
5732 // types have the same location layout.
5733 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5734 NewTL.setLBracketLoc(TL.getLBracketLoc());
5735 NewTL.setRBracketLoc(TL.getRBracketLoc());
5736 NewTL.setSizeExpr(NewSize);
5737
5738 return Result;
5739 }
5740
5741 template<typename Derived>
TransformIncompleteArrayType(TypeLocBuilder & TLB,IncompleteArrayTypeLoc TL)5742 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5743 TypeLocBuilder &TLB,
5744 IncompleteArrayTypeLoc TL) {
5745 const IncompleteArrayType *T = TL.getTypePtr();
5746 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5747 if (ElementType.isNull())
5748 return QualType();
5749
5750 QualType Result = TL.getType();
5751 if (getDerived().AlwaysRebuild() ||
5752 ElementType != T->getElementType()) {
5753 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5754 T->getSizeModifier(),
5755 T->getIndexTypeCVRQualifiers(),
5756 TL.getBracketsRange());
5757 if (Result.isNull())
5758 return QualType();
5759 }
5760
5761 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5762 NewTL.setLBracketLoc(TL.getLBracketLoc());
5763 NewTL.setRBracketLoc(TL.getRBracketLoc());
5764 NewTL.setSizeExpr(nullptr);
5765
5766 return Result;
5767 }
5768
5769 template<typename Derived>
5770 QualType
TransformVariableArrayType(TypeLocBuilder & TLB,VariableArrayTypeLoc TL)5771 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5772 VariableArrayTypeLoc TL) {
5773 const VariableArrayType *T = TL.getTypePtr();
5774 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5775 if (ElementType.isNull())
5776 return QualType();
5777
5778 ExprResult SizeResult;
5779 {
5780 EnterExpressionEvaluationContext Context(
5781 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5782 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5783 }
5784 if (SizeResult.isInvalid())
5785 return QualType();
5786 SizeResult =
5787 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5788 if (SizeResult.isInvalid())
5789 return QualType();
5790
5791 Expr *Size = SizeResult.get();
5792
5793 QualType Result = TL.getType();
5794 if (getDerived().AlwaysRebuild() ||
5795 ElementType != T->getElementType() ||
5796 Size != T->getSizeExpr()) {
5797 Result = getDerived().RebuildVariableArrayType(ElementType,
5798 T->getSizeModifier(),
5799 Size,
5800 T->getIndexTypeCVRQualifiers(),
5801 TL.getBracketsRange());
5802 if (Result.isNull())
5803 return QualType();
5804 }
5805
5806 // We might have constant size array now, but fortunately it has the same
5807 // location layout.
5808 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5809 NewTL.setLBracketLoc(TL.getLBracketLoc());
5810 NewTL.setRBracketLoc(TL.getRBracketLoc());
5811 NewTL.setSizeExpr(Size);
5812
5813 return Result;
5814 }
5815
5816 template<typename Derived>
5817 QualType
TransformDependentSizedArrayType(TypeLocBuilder & TLB,DependentSizedArrayTypeLoc TL)5818 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5819 DependentSizedArrayTypeLoc TL) {
5820 const DependentSizedArrayType *T = TL.getTypePtr();
5821 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5822 if (ElementType.isNull())
5823 return QualType();
5824
5825 // Array bounds are constant expressions.
5826 EnterExpressionEvaluationContext Unevaluated(
5827 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5828
5829 // If we have a VLA then it won't be a constant.
5830 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5831
5832 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5833 Expr *origSize = TL.getSizeExpr();
5834 if (!origSize) origSize = T->getSizeExpr();
5835
5836 ExprResult sizeResult
5837 = getDerived().TransformExpr(origSize);
5838 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5839 if (sizeResult.isInvalid())
5840 return QualType();
5841
5842 Expr *size = sizeResult.get();
5843
5844 QualType Result = TL.getType();
5845 if (getDerived().AlwaysRebuild() ||
5846 ElementType != T->getElementType() ||
5847 size != origSize) {
5848 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5849 T->getSizeModifier(),
5850 size,
5851 T->getIndexTypeCVRQualifiers(),
5852 TL.getBracketsRange());
5853 if (Result.isNull())
5854 return QualType();
5855 }
5856
5857 // We might have any sort of array type now, but fortunately they
5858 // all have the same location layout.
5859 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5860 NewTL.setLBracketLoc(TL.getLBracketLoc());
5861 NewTL.setRBracketLoc(TL.getRBracketLoc());
5862 NewTL.setSizeExpr(size);
5863
5864 return Result;
5865 }
5866
5867 template <typename Derived>
TransformDependentVectorType(TypeLocBuilder & TLB,DependentVectorTypeLoc TL)5868 QualType TreeTransform<Derived>::TransformDependentVectorType(
5869 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5870 const DependentVectorType *T = TL.getTypePtr();
5871 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5872 if (ElementType.isNull())
5873 return QualType();
5874
5875 EnterExpressionEvaluationContext Unevaluated(
5876 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5877
5878 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5879 Size = SemaRef.ActOnConstantExpression(Size);
5880 if (Size.isInvalid())
5881 return QualType();
5882
5883 QualType Result = TL.getType();
5884 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5885 Size.get() != T->getSizeExpr()) {
5886 Result = getDerived().RebuildDependentVectorType(
5887 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5888 if (Result.isNull())
5889 return QualType();
5890 }
5891
5892 // Result might be dependent or not.
5893 if (isa<DependentVectorType>(Result)) {
5894 DependentVectorTypeLoc NewTL =
5895 TLB.push<DependentVectorTypeLoc>(Result);
5896 NewTL.setNameLoc(TL.getNameLoc());
5897 } else {
5898 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5899 NewTL.setNameLoc(TL.getNameLoc());
5900 }
5901
5902 return Result;
5903 }
5904
5905 template<typename Derived>
TransformDependentSizedExtVectorType(TypeLocBuilder & TLB,DependentSizedExtVectorTypeLoc TL)5906 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5907 TypeLocBuilder &TLB,
5908 DependentSizedExtVectorTypeLoc TL) {
5909 const DependentSizedExtVectorType *T = TL.getTypePtr();
5910
5911 // FIXME: ext vector locs should be nested
5912 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5913 if (ElementType.isNull())
5914 return QualType();
5915
5916 // Vector sizes are constant expressions.
5917 EnterExpressionEvaluationContext Unevaluated(
5918 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5919
5920 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5921 Size = SemaRef.ActOnConstantExpression(Size);
5922 if (Size.isInvalid())
5923 return QualType();
5924
5925 QualType Result = TL.getType();
5926 if (getDerived().AlwaysRebuild() ||
5927 ElementType != T->getElementType() ||
5928 Size.get() != T->getSizeExpr()) {
5929 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5930 Size.get(),
5931 T->getAttributeLoc());
5932 if (Result.isNull())
5933 return QualType();
5934 }
5935
5936 // Result might be dependent or not.
5937 if (isa<DependentSizedExtVectorType>(Result)) {
5938 DependentSizedExtVectorTypeLoc NewTL
5939 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5940 NewTL.setNameLoc(TL.getNameLoc());
5941 } else {
5942 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5943 NewTL.setNameLoc(TL.getNameLoc());
5944 }
5945
5946 return Result;
5947 }
5948
5949 template <typename Derived>
5950 QualType
TransformConstantMatrixType(TypeLocBuilder & TLB,ConstantMatrixTypeLoc TL)5951 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5952 ConstantMatrixTypeLoc TL) {
5953 const ConstantMatrixType *T = TL.getTypePtr();
5954 QualType ElementType = getDerived().TransformType(T->getElementType());
5955 if (ElementType.isNull())
5956 return QualType();
5957
5958 QualType Result = TL.getType();
5959 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5960 Result = getDerived().RebuildConstantMatrixType(
5961 ElementType, T->getNumRows(), T->getNumColumns());
5962 if (Result.isNull())
5963 return QualType();
5964 }
5965
5966 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5967 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5968 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5969 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5970 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5971
5972 return Result;
5973 }
5974
5975 template <typename Derived>
TransformDependentSizedMatrixType(TypeLocBuilder & TLB,DependentSizedMatrixTypeLoc TL)5976 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5977 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5978 const DependentSizedMatrixType *T = TL.getTypePtr();
5979
5980 QualType ElementType = getDerived().TransformType(T->getElementType());
5981 if (ElementType.isNull()) {
5982 return QualType();
5983 }
5984
5985 // Matrix dimensions are constant expressions.
5986 EnterExpressionEvaluationContext Unevaluated(
5987 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5988
5989 Expr *origRows = TL.getAttrRowOperand();
5990 if (!origRows)
5991 origRows = T->getRowExpr();
5992 Expr *origColumns = TL.getAttrColumnOperand();
5993 if (!origColumns)
5994 origColumns = T->getColumnExpr();
5995
5996 ExprResult rowResult = getDerived().TransformExpr(origRows);
5997 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5998 if (rowResult.isInvalid())
5999 return QualType();
6000
6001 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6002 columnResult = SemaRef.ActOnConstantExpression(columnResult);
6003 if (columnResult.isInvalid())
6004 return QualType();
6005
6006 Expr *rows = rowResult.get();
6007 Expr *columns = columnResult.get();
6008
6009 QualType Result = TL.getType();
6010 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6011 rows != origRows || columns != origColumns) {
6012 Result = getDerived().RebuildDependentSizedMatrixType(
6013 ElementType, rows, columns, T->getAttributeLoc());
6014
6015 if (Result.isNull())
6016 return QualType();
6017 }
6018
6019 // We might have any sort of matrix type now, but fortunately they
6020 // all have the same location layout.
6021 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
6022 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6023 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6024 NewTL.setAttrRowOperand(rows);
6025 NewTL.setAttrColumnOperand(columns);
6026 return Result;
6027 }
6028
6029 template <typename Derived>
TransformDependentAddressSpaceType(TypeLocBuilder & TLB,DependentAddressSpaceTypeLoc TL)6030 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6031 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6032 const DependentAddressSpaceType *T = TL.getTypePtr();
6033
6034 QualType pointeeType =
6035 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6036
6037 if (pointeeType.isNull())
6038 return QualType();
6039
6040 // Address spaces are constant expressions.
6041 EnterExpressionEvaluationContext Unevaluated(
6042 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6043
6044 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6045 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
6046 if (AddrSpace.isInvalid())
6047 return QualType();
6048
6049 QualType Result = TL.getType();
6050 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6051 AddrSpace.get() != T->getAddrSpaceExpr()) {
6052 Result = getDerived().RebuildDependentAddressSpaceType(
6053 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6054 if (Result.isNull())
6055 return QualType();
6056 }
6057
6058 // Result might be dependent or not.
6059 if (isa<DependentAddressSpaceType>(Result)) {
6060 DependentAddressSpaceTypeLoc NewTL =
6061 TLB.push<DependentAddressSpaceTypeLoc>(Result);
6062
6063 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6064 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6065 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6066
6067 } else {
6068 TLB.TypeWasModifiedSafely(Result);
6069 }
6070
6071 return Result;
6072 }
6073
6074 template <typename Derived>
TransformVectorType(TypeLocBuilder & TLB,VectorTypeLoc TL)6075 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6076 VectorTypeLoc TL) {
6077 const VectorType *T = TL.getTypePtr();
6078 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6079 if (ElementType.isNull())
6080 return QualType();
6081
6082 QualType Result = TL.getType();
6083 if (getDerived().AlwaysRebuild() ||
6084 ElementType != T->getElementType()) {
6085 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6086 T->getVectorKind());
6087 if (Result.isNull())
6088 return QualType();
6089 }
6090
6091 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
6092 NewTL.setNameLoc(TL.getNameLoc());
6093
6094 return Result;
6095 }
6096
6097 template<typename Derived>
TransformExtVectorType(TypeLocBuilder & TLB,ExtVectorTypeLoc TL)6098 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6099 ExtVectorTypeLoc TL) {
6100 const VectorType *T = TL.getTypePtr();
6101 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6102 if (ElementType.isNull())
6103 return QualType();
6104
6105 QualType Result = TL.getType();
6106 if (getDerived().AlwaysRebuild() ||
6107 ElementType != T->getElementType()) {
6108 Result = getDerived().RebuildExtVectorType(ElementType,
6109 T->getNumElements(),
6110 /*FIXME*/ SourceLocation());
6111 if (Result.isNull())
6112 return QualType();
6113 }
6114
6115 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
6116 NewTL.setNameLoc(TL.getNameLoc());
6117
6118 return Result;
6119 }
6120
6121 template <typename Derived>
TransformFunctionTypeParam(ParmVarDecl * OldParm,int indexAdjustment,UnsignedOrNone NumExpansions,bool ExpectParameterPack)6122 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6123 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6124 bool ExpectParameterPack) {
6125 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
6126 TypeSourceInfo *NewDI = nullptr;
6127
6128 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
6129 // If we're substituting into a pack expansion type and we know the
6130 // length we want to expand to, just substitute for the pattern.
6131 TypeLoc OldTL = OldDI->getTypeLoc();
6132 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6133
6134 TypeLocBuilder TLB;
6135 TypeLoc NewTL = OldDI->getTypeLoc();
6136 TLB.reserve(NewTL.getFullDataSize());
6137
6138 QualType Result = getDerived().TransformType(TLB,
6139 OldExpansionTL.getPatternLoc());
6140 if (Result.isNull())
6141 return nullptr;
6142
6143 Result = RebuildPackExpansionType(Result,
6144 OldExpansionTL.getPatternLoc().getSourceRange(),
6145 OldExpansionTL.getEllipsisLoc(),
6146 NumExpansions);
6147 if (Result.isNull())
6148 return nullptr;
6149
6150 PackExpansionTypeLoc NewExpansionTL
6151 = TLB.push<PackExpansionTypeLoc>(Result);
6152 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6153 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
6154 } else
6155 NewDI = getDerived().TransformType(OldDI);
6156 if (!NewDI)
6157 return nullptr;
6158
6159 if (NewDI == OldDI && indexAdjustment == 0)
6160 return OldParm;
6161
6162 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
6163 OldParm->getDeclContext(),
6164 OldParm->getInnerLocStart(),
6165 OldParm->getLocation(),
6166 OldParm->getIdentifier(),
6167 NewDI->getType(),
6168 NewDI,
6169 OldParm->getStorageClass(),
6170 /* DefArg */ nullptr);
6171 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
6172 OldParm->getFunctionScopeIndex() + indexAdjustment);
6173 transformedLocalDecl(OldParm, {newParm});
6174 return newParm;
6175 }
6176
6177 template <typename Derived>
TransformFunctionTypeParams(SourceLocation Loc,ArrayRef<ParmVarDecl * > Params,const QualType * ParamTypes,const FunctionProtoType::ExtParameterInfo * ParamInfos,SmallVectorImpl<QualType> & OutParamTypes,SmallVectorImpl<ParmVarDecl * > * PVars,Sema::ExtParameterInfoBuilder & PInfos,unsigned * LastParamTransformed)6178 bool TreeTransform<Derived>::TransformFunctionTypeParams(
6179 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6180 const QualType *ParamTypes,
6181 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6182 SmallVectorImpl<QualType> &OutParamTypes,
6183 SmallVectorImpl<ParmVarDecl *> *PVars,
6184 Sema::ExtParameterInfoBuilder &PInfos,
6185 unsigned *LastParamTransformed) {
6186 int indexAdjustment = 0;
6187
6188 unsigned NumParams = Params.size();
6189 for (unsigned i = 0; i != NumParams; ++i) {
6190 if (LastParamTransformed)
6191 *LastParamTransformed = i;
6192 if (ParmVarDecl *OldParm = Params[i]) {
6193 assert(OldParm->getFunctionScopeIndex() == i);
6194
6195 UnsignedOrNone NumExpansions = std::nullopt;
6196 ParmVarDecl *NewParm = nullptr;
6197 if (OldParm->isParameterPack()) {
6198 // We have a function parameter pack that may need to be expanded.
6199 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6200
6201 // Find the parameter packs that could be expanded.
6202 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6203 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6204 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6205 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
6206
6207 // Determine whether we should expand the parameter packs.
6208 bool ShouldExpand = false;
6209 bool RetainExpansion = false;
6210 UnsignedOrNone OrigNumExpansions = std::nullopt;
6211 if (Unexpanded.size() > 0) {
6212 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6213 NumExpansions = OrigNumExpansions;
6214 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6215 Pattern.getSourceRange(),
6216 Unexpanded,
6217 ShouldExpand,
6218 RetainExpansion,
6219 NumExpansions)) {
6220 return true;
6221 }
6222 } else {
6223 #ifndef NDEBUG
6224 const AutoType *AT =
6225 Pattern.getType().getTypePtr()->getContainedAutoType();
6226 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6227 "Could not find parameter packs or undeduced auto type!");
6228 #endif
6229 }
6230
6231 if (ShouldExpand) {
6232 // Expand the function parameter pack into multiple, separate
6233 // parameters.
6234 getDerived().ExpandingFunctionParameterPack(OldParm);
6235 for (unsigned I = 0; I != *NumExpansions; ++I) {
6236 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6237 ParmVarDecl *NewParm
6238 = getDerived().TransformFunctionTypeParam(OldParm,
6239 indexAdjustment++,
6240 OrigNumExpansions,
6241 /*ExpectParameterPack=*/false);
6242 if (!NewParm)
6243 return true;
6244
6245 if (ParamInfos)
6246 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6247 OutParamTypes.push_back(NewParm->getType());
6248 if (PVars)
6249 PVars->push_back(NewParm);
6250 }
6251
6252 // If we're supposed to retain a pack expansion, do so by temporarily
6253 // forgetting the partially-substituted parameter pack.
6254 if (RetainExpansion) {
6255 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6256 ParmVarDecl *NewParm
6257 = getDerived().TransformFunctionTypeParam(OldParm,
6258 indexAdjustment++,
6259 OrigNumExpansions,
6260 /*ExpectParameterPack=*/false);
6261 if (!NewParm)
6262 return true;
6263
6264 if (ParamInfos)
6265 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6266 OutParamTypes.push_back(NewParm->getType());
6267 if (PVars)
6268 PVars->push_back(NewParm);
6269 }
6270
6271 // The next parameter should have the same adjustment as the
6272 // last thing we pushed, but we post-incremented indexAdjustment
6273 // on every push. Also, if we push nothing, the adjustment should
6274 // go down by one.
6275 indexAdjustment--;
6276
6277 // We're done with the pack expansion.
6278 continue;
6279 }
6280
6281 // We'll substitute the parameter now without expanding the pack
6282 // expansion.
6283 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6284 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6285 indexAdjustment,
6286 NumExpansions,
6287 /*ExpectParameterPack=*/true);
6288 assert(NewParm->isParameterPack() &&
6289 "Parameter pack no longer a parameter pack after "
6290 "transformation.");
6291 } else {
6292 NewParm = getDerived().TransformFunctionTypeParam(
6293 OldParm, indexAdjustment, std::nullopt,
6294 /*ExpectParameterPack=*/false);
6295 }
6296
6297 if (!NewParm)
6298 return true;
6299
6300 if (ParamInfos)
6301 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6302 OutParamTypes.push_back(NewParm->getType());
6303 if (PVars)
6304 PVars->push_back(NewParm);
6305 continue;
6306 }
6307
6308 // Deal with the possibility that we don't have a parameter
6309 // declaration for this parameter.
6310 assert(ParamTypes);
6311 QualType OldType = ParamTypes[i];
6312 bool IsPackExpansion = false;
6313 UnsignedOrNone NumExpansions = std::nullopt;
6314 QualType NewType;
6315 if (const PackExpansionType *Expansion
6316 = dyn_cast<PackExpansionType>(OldType)) {
6317 // We have a function parameter pack that may need to be expanded.
6318 QualType Pattern = Expansion->getPattern();
6319 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6320 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6321
6322 // Determine whether we should expand the parameter packs.
6323 bool ShouldExpand = false;
6324 bool RetainExpansion = false;
6325 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6326 Unexpanded,
6327 ShouldExpand,
6328 RetainExpansion,
6329 NumExpansions)) {
6330 return true;
6331 }
6332
6333 if (ShouldExpand) {
6334 // Expand the function parameter pack into multiple, separate
6335 // parameters.
6336 for (unsigned I = 0; I != *NumExpansions; ++I) {
6337 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6338 QualType NewType = getDerived().TransformType(Pattern);
6339 if (NewType.isNull())
6340 return true;
6341
6342 if (NewType->containsUnexpandedParameterPack()) {
6343 NewType = getSema().getASTContext().getPackExpansionType(
6344 NewType, std::nullopt);
6345
6346 if (NewType.isNull())
6347 return true;
6348 }
6349
6350 if (ParamInfos)
6351 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6352 OutParamTypes.push_back(NewType);
6353 if (PVars)
6354 PVars->push_back(nullptr);
6355 }
6356
6357 // We're done with the pack expansion.
6358 continue;
6359 }
6360
6361 // If we're supposed to retain a pack expansion, do so by temporarily
6362 // forgetting the partially-substituted parameter pack.
6363 if (RetainExpansion) {
6364 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6365 QualType NewType = getDerived().TransformType(Pattern);
6366 if (NewType.isNull())
6367 return true;
6368
6369 if (ParamInfos)
6370 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6371 OutParamTypes.push_back(NewType);
6372 if (PVars)
6373 PVars->push_back(nullptr);
6374 }
6375
6376 // We'll substitute the parameter now without expanding the pack
6377 // expansion.
6378 OldType = Expansion->getPattern();
6379 IsPackExpansion = true;
6380 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6381 NewType = getDerived().TransformType(OldType);
6382 } else {
6383 NewType = getDerived().TransformType(OldType);
6384 }
6385
6386 if (NewType.isNull())
6387 return true;
6388
6389 if (IsPackExpansion)
6390 NewType = getSema().Context.getPackExpansionType(NewType,
6391 NumExpansions);
6392
6393 if (ParamInfos)
6394 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6395 OutParamTypes.push_back(NewType);
6396 if (PVars)
6397 PVars->push_back(nullptr);
6398 }
6399
6400 #ifndef NDEBUG
6401 if (PVars) {
6402 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6403 if (ParmVarDecl *parm = (*PVars)[i])
6404 assert(parm->getFunctionScopeIndex() == i);
6405 }
6406 #endif
6407
6408 return false;
6409 }
6410
6411 template<typename Derived>
6412 QualType
TransformFunctionProtoType(TypeLocBuilder & TLB,FunctionProtoTypeLoc TL)6413 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6414 FunctionProtoTypeLoc TL) {
6415 SmallVector<QualType, 4> ExceptionStorage;
6416 return getDerived().TransformFunctionProtoType(
6417 TLB, TL, nullptr, Qualifiers(),
6418 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6419 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6420 ExceptionStorage, Changed);
6421 });
6422 }
6423
6424 template<typename Derived> template<typename Fn>
TransformFunctionProtoType(TypeLocBuilder & TLB,FunctionProtoTypeLoc TL,CXXRecordDecl * ThisContext,Qualifiers ThisTypeQuals,Fn TransformExceptionSpec)6425 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6426 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6427 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6428
6429 // Transform the parameters and return type.
6430 //
6431 // We are required to instantiate the params and return type in source order.
6432 // When the function has a trailing return type, we instantiate the
6433 // parameters before the return type, since the return type can then refer
6434 // to the parameters themselves (via decltype, sizeof, etc.).
6435 //
6436 SmallVector<QualType, 4> ParamTypes;
6437 SmallVector<ParmVarDecl*, 4> ParamDecls;
6438 Sema::ExtParameterInfoBuilder ExtParamInfos;
6439 const FunctionProtoType *T = TL.getTypePtr();
6440
6441 QualType ResultType;
6442
6443 if (T->hasTrailingReturn()) {
6444 if (getDerived().TransformFunctionTypeParams(
6445 TL.getBeginLoc(), TL.getParams(),
6446 TL.getTypePtr()->param_type_begin(),
6447 T->getExtParameterInfosOrNull(),
6448 ParamTypes, &ParamDecls, ExtParamInfos))
6449 return QualType();
6450
6451 {
6452 // C++11 [expr.prim.general]p3:
6453 // If a declaration declares a member function or member function
6454 // template of a class X, the expression this is a prvalue of type
6455 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6456 // and the end of the function-definition, member-declarator, or
6457 // declarator.
6458 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6459 Sema::CXXThisScopeRAII ThisScope(
6460 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6461
6462 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6463 if (ResultType.isNull())
6464 return QualType();
6465 }
6466 }
6467 else {
6468 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6469 if (ResultType.isNull())
6470 return QualType();
6471
6472 if (getDerived().TransformFunctionTypeParams(
6473 TL.getBeginLoc(), TL.getParams(),
6474 TL.getTypePtr()->param_type_begin(),
6475 T->getExtParameterInfosOrNull(),
6476 ParamTypes, &ParamDecls, ExtParamInfos))
6477 return QualType();
6478 }
6479
6480 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6481
6482 bool EPIChanged = false;
6483 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6484 return QualType();
6485
6486 // Handle extended parameter information.
6487 if (auto NewExtParamInfos =
6488 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6489 if (!EPI.ExtParameterInfos ||
6490 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6491 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6492 EPIChanged = true;
6493 }
6494 EPI.ExtParameterInfos = NewExtParamInfos;
6495 } else if (EPI.ExtParameterInfos) {
6496 EPIChanged = true;
6497 EPI.ExtParameterInfos = nullptr;
6498 }
6499
6500 // Transform any function effects with unevaluated conditions.
6501 // Hold this set in a local for the rest of this function, since EPI
6502 // may need to hold a FunctionEffectsRef pointing into it.
6503 std::optional<FunctionEffectSet> NewFX;
6504 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6505 NewFX.emplace();
6506 EnterExpressionEvaluationContext Unevaluated(
6507 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6508
6509 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6510 FunctionEffectWithCondition NewEC = PrevEC;
6511 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6512 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6513 if (NewExpr.isInvalid())
6514 return QualType();
6515 std::optional<FunctionEffectMode> Mode =
6516 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());
6517 if (!Mode)
6518 return QualType();
6519
6520 // The condition expression has been transformed, and re-evaluated.
6521 // It may or may not have become constant.
6522 switch (*Mode) {
6523 case FunctionEffectMode::True:
6524 NewEC.Cond = {};
6525 break;
6526 case FunctionEffectMode::False:
6527 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6528 NewEC.Cond = {};
6529 break;
6530 case FunctionEffectMode::Dependent:
6531 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6532 break;
6533 case FunctionEffectMode::None:
6534 llvm_unreachable(
6535 "FunctionEffectMode::None shouldn't be possible here");
6536 }
6537 }
6538 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,
6539 TL.getBeginLoc())) {
6540 FunctionEffectSet::Conflicts Errs;
6541 NewFX->insert(NewEC, Errs);
6542 assert(Errs.empty());
6543 }
6544 }
6545 EPI.FunctionEffects = *NewFX;
6546 EPIChanged = true;
6547 }
6548
6549 QualType Result = TL.getType();
6550 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6551 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6552 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6553 if (Result.isNull())
6554 return QualType();
6555 }
6556
6557 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6558 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6559 NewTL.setLParenLoc(TL.getLParenLoc());
6560 NewTL.setRParenLoc(TL.getRParenLoc());
6561 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6562 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6563 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6564 NewTL.setParam(i, ParamDecls[i]);
6565
6566 return Result;
6567 }
6568
6569 template<typename Derived>
TransformExceptionSpec(SourceLocation Loc,FunctionProtoType::ExceptionSpecInfo & ESI,SmallVectorImpl<QualType> & Exceptions,bool & Changed)6570 bool TreeTransform<Derived>::TransformExceptionSpec(
6571 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6572 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6573 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6574
6575 // Instantiate a dynamic noexcept expression, if any.
6576 if (isComputedNoexcept(ESI.Type)) {
6577 // Update this scrope because ContextDecl in Sema will be used in
6578 // TransformExpr.
6579 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6580 Sema::CXXThisScopeRAII ThisScope(
6581 SemaRef, Method ? Method->getParent() : nullptr,
6582 Method ? Method->getMethodQualifiers() : Qualifiers{},
6583 Method != nullptr);
6584 EnterExpressionEvaluationContext Unevaluated(
6585 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6586 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6587 if (NoexceptExpr.isInvalid())
6588 return true;
6589
6590 ExceptionSpecificationType EST = ESI.Type;
6591 NoexceptExpr =
6592 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6593 if (NoexceptExpr.isInvalid())
6594 return true;
6595
6596 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6597 Changed = true;
6598 ESI.NoexceptExpr = NoexceptExpr.get();
6599 ESI.Type = EST;
6600 }
6601
6602 if (ESI.Type != EST_Dynamic)
6603 return false;
6604
6605 // Instantiate a dynamic exception specification's type.
6606 for (QualType T : ESI.Exceptions) {
6607 if (const PackExpansionType *PackExpansion =
6608 T->getAs<PackExpansionType>()) {
6609 Changed = true;
6610
6611 // We have a pack expansion. Instantiate it.
6612 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6613 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6614 Unexpanded);
6615 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6616
6617 // Determine whether the set of unexpanded parameter packs can and
6618 // should
6619 // be expanded.
6620 bool Expand = false;
6621 bool RetainExpansion = false;
6622 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6623 // FIXME: Track the location of the ellipsis (and track source location
6624 // information for the types in the exception specification in general).
6625 if (getDerived().TryExpandParameterPacks(
6626 Loc, SourceRange(), Unexpanded, Expand,
6627 RetainExpansion, NumExpansions))
6628 return true;
6629
6630 if (!Expand) {
6631 // We can't expand this pack expansion into separate arguments yet;
6632 // just substitute into the pattern and create a new pack expansion
6633 // type.
6634 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6635 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6636 if (U.isNull())
6637 return true;
6638
6639 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6640 Exceptions.push_back(U);
6641 continue;
6642 }
6643
6644 // Substitute into the pack expansion pattern for each slice of the
6645 // pack.
6646 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6647 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6648
6649 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6650 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6651 return true;
6652
6653 Exceptions.push_back(U);
6654 }
6655 } else {
6656 QualType U = getDerived().TransformType(T);
6657 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6658 return true;
6659 if (T != U)
6660 Changed = true;
6661
6662 Exceptions.push_back(U);
6663 }
6664 }
6665
6666 ESI.Exceptions = Exceptions;
6667 if (ESI.Exceptions.empty())
6668 ESI.Type = EST_DynamicNone;
6669 return false;
6670 }
6671
6672 template<typename Derived>
TransformFunctionNoProtoType(TypeLocBuilder & TLB,FunctionNoProtoTypeLoc TL)6673 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6674 TypeLocBuilder &TLB,
6675 FunctionNoProtoTypeLoc TL) {
6676 const FunctionNoProtoType *T = TL.getTypePtr();
6677 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6678 if (ResultType.isNull())
6679 return QualType();
6680
6681 QualType Result = TL.getType();
6682 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6683 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6684
6685 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6686 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6687 NewTL.setLParenLoc(TL.getLParenLoc());
6688 NewTL.setRParenLoc(TL.getRParenLoc());
6689 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6690
6691 return Result;
6692 }
6693
6694 template <typename Derived>
TransformUnresolvedUsingType(TypeLocBuilder & TLB,UnresolvedUsingTypeLoc TL)6695 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6696 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6697 const UnresolvedUsingType *T = TL.getTypePtr();
6698 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6699 if (!D)
6700 return QualType();
6701
6702 QualType Result = TL.getType();
6703 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6704 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6705 if (Result.isNull())
6706 return QualType();
6707 }
6708
6709 // We might get an arbitrary type spec type back. We should at
6710 // least always get a type spec type, though.
6711 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6712 NewTL.setNameLoc(TL.getNameLoc());
6713
6714 return Result;
6715 }
6716
6717 template <typename Derived>
TransformUsingType(TypeLocBuilder & TLB,UsingTypeLoc TL)6718 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6719 UsingTypeLoc TL) {
6720 const UsingType *T = TL.getTypePtr();
6721
6722 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6723 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6724 if (!Found)
6725 return QualType();
6726
6727 QualType Underlying = getDerived().TransformType(T->desugar());
6728 if (Underlying.isNull())
6729 return QualType();
6730
6731 QualType Result = TL.getType();
6732 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6733 Underlying != T->getUnderlyingType()) {
6734 Result = getDerived().RebuildUsingType(Found, Underlying);
6735 if (Result.isNull())
6736 return QualType();
6737 }
6738
6739 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6740 return Result;
6741 }
6742
6743 template<typename Derived>
TransformTypedefType(TypeLocBuilder & TLB,TypedefTypeLoc TL)6744 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6745 TypedefTypeLoc TL) {
6746 const TypedefType *T = TL.getTypePtr();
6747 TypedefNameDecl *Typedef
6748 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6749 T->getDecl()));
6750 if (!Typedef)
6751 return QualType();
6752
6753 QualType Result = TL.getType();
6754 if (getDerived().AlwaysRebuild() ||
6755 Typedef != T->getDecl()) {
6756 Result = getDerived().RebuildTypedefType(Typedef);
6757 if (Result.isNull())
6758 return QualType();
6759 }
6760
6761 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6762 NewTL.setNameLoc(TL.getNameLoc());
6763
6764 return Result;
6765 }
6766
6767 template<typename Derived>
TransformTypeOfExprType(TypeLocBuilder & TLB,TypeOfExprTypeLoc TL)6768 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6769 TypeOfExprTypeLoc TL) {
6770 // typeof expressions are not potentially evaluated contexts
6771 EnterExpressionEvaluationContext Unevaluated(
6772 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6773 Sema::ReuseLambdaContextDecl);
6774
6775 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6776 if (E.isInvalid())
6777 return QualType();
6778
6779 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6780 if (E.isInvalid())
6781 return QualType();
6782
6783 QualType Result = TL.getType();
6784 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6785 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6786 Result =
6787 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6788 if (Result.isNull())
6789 return QualType();
6790 }
6791
6792 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6793 NewTL.setTypeofLoc(TL.getTypeofLoc());
6794 NewTL.setLParenLoc(TL.getLParenLoc());
6795 NewTL.setRParenLoc(TL.getRParenLoc());
6796
6797 return Result;
6798 }
6799
6800 template<typename Derived>
TransformTypeOfType(TypeLocBuilder & TLB,TypeOfTypeLoc TL)6801 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6802 TypeOfTypeLoc TL) {
6803 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6804 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6805 if (!New_Under_TI)
6806 return QualType();
6807
6808 QualType Result = TL.getType();
6809 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6810 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6811 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6812 if (Result.isNull())
6813 return QualType();
6814 }
6815
6816 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6817 NewTL.setTypeofLoc(TL.getTypeofLoc());
6818 NewTL.setLParenLoc(TL.getLParenLoc());
6819 NewTL.setRParenLoc(TL.getRParenLoc());
6820 NewTL.setUnmodifiedTInfo(New_Under_TI);
6821
6822 return Result;
6823 }
6824
6825 template<typename Derived>
TransformDecltypeType(TypeLocBuilder & TLB,DecltypeTypeLoc TL)6826 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6827 DecltypeTypeLoc TL) {
6828 const DecltypeType *T = TL.getTypePtr();
6829
6830 // decltype expressions are not potentially evaluated contexts
6831 EnterExpressionEvaluationContext Unevaluated(
6832 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6833 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6834
6835 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6836 if (E.isInvalid())
6837 return QualType();
6838
6839 E = getSema().ActOnDecltypeExpression(E.get());
6840 if (E.isInvalid())
6841 return QualType();
6842
6843 QualType Result = TL.getType();
6844 if (getDerived().AlwaysRebuild() ||
6845 E.get() != T->getUnderlyingExpr()) {
6846 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6847 if (Result.isNull())
6848 return QualType();
6849 }
6850 else E.get();
6851
6852 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6853 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6854 NewTL.setRParenLoc(TL.getRParenLoc());
6855 return Result;
6856 }
6857
6858 template <typename Derived>
6859 QualType
TransformPackIndexingType(TypeLocBuilder & TLB,PackIndexingTypeLoc TL)6860 TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6861 PackIndexingTypeLoc TL) {
6862 // Transform the index
6863 ExprResult IndexExpr;
6864 {
6865 EnterExpressionEvaluationContext ConstantContext(
6866 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6867
6868 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6869 if (IndexExpr.isInvalid())
6870 return QualType();
6871 }
6872 QualType Pattern = TL.getPattern();
6873
6874 const PackIndexingType *PIT = TL.getTypePtr();
6875 SmallVector<QualType, 5> SubtitutedTypes;
6876 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6877
6878 bool NotYetExpanded = Types.empty();
6879 bool FullySubstituted = true;
6880
6881 if (Types.empty() && !PIT->expandsToEmptyPack())
6882 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6883
6884 for (QualType T : Types) {
6885 if (!T->containsUnexpandedParameterPack()) {
6886 QualType Transformed = getDerived().TransformType(T);
6887 if (Transformed.isNull())
6888 return QualType();
6889 SubtitutedTypes.push_back(Transformed);
6890 continue;
6891 }
6892
6893 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6894 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6895 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6896 // Determine whether the set of unexpanded parameter packs can and should
6897 // be expanded.
6898 bool ShouldExpand = true;
6899 bool RetainExpansion = false;
6900 UnsignedOrNone NumExpansions = std::nullopt;
6901 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6902 Unexpanded, ShouldExpand,
6903 RetainExpansion, NumExpansions))
6904 return QualType();
6905 if (!ShouldExpand) {
6906 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6907 // FIXME: should we keep TypeLoc for individual expansions in
6908 // PackIndexingTypeLoc?
6909 TypeSourceInfo *TI =
6910 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6911 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6912 if (Pack.isNull())
6913 return QualType();
6914 if (NotYetExpanded) {
6915 FullySubstituted = false;
6916 QualType Out = getDerived().RebuildPackIndexingType(
6917 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6918 FullySubstituted);
6919 if (Out.isNull())
6920 return QualType();
6921
6922 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6923 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6924 return Out;
6925 }
6926 SubtitutedTypes.push_back(Pack);
6927 continue;
6928 }
6929 for (unsigned I = 0; I != *NumExpansions; ++I) {
6930 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6931 QualType Out = getDerived().TransformType(T);
6932 if (Out.isNull())
6933 return QualType();
6934 SubtitutedTypes.push_back(Out);
6935 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6936 }
6937 // If we're supposed to retain a pack expansion, do so by temporarily
6938 // forgetting the partially-substituted parameter pack.
6939 if (RetainExpansion) {
6940 FullySubstituted = false;
6941 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6942 QualType Out = getDerived().TransformType(T);
6943 if (Out.isNull())
6944 return QualType();
6945 SubtitutedTypes.push_back(Out);
6946 }
6947 }
6948
6949 // A pack indexing type can appear in a larger pack expansion,
6950 // e.g. `Pack...[pack_of_indexes]...`
6951 // so we need to temporarily disable substitution of pack elements
6952 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6953 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6954
6955 QualType Out = getDerived().RebuildPackIndexingType(
6956 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6957 FullySubstituted, SubtitutedTypes);
6958 if (Out.isNull())
6959 return Out;
6960
6961 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6962 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6963 return Out;
6964 }
6965
6966 template<typename Derived>
TransformUnaryTransformType(TypeLocBuilder & TLB,UnaryTransformTypeLoc TL)6967 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6968 TypeLocBuilder &TLB,
6969 UnaryTransformTypeLoc TL) {
6970 QualType Result = TL.getType();
6971 if (Result->isDependentType()) {
6972 const UnaryTransformType *T = TL.getTypePtr();
6973
6974 TypeSourceInfo *NewBaseTSI =
6975 getDerived().TransformType(TL.getUnderlyingTInfo());
6976 if (!NewBaseTSI)
6977 return QualType();
6978 QualType NewBase = NewBaseTSI->getType();
6979
6980 Result = getDerived().RebuildUnaryTransformType(NewBase,
6981 T->getUTTKind(),
6982 TL.getKWLoc());
6983 if (Result.isNull())
6984 return QualType();
6985 }
6986
6987 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6988 NewTL.setKWLoc(TL.getKWLoc());
6989 NewTL.setParensRange(TL.getParensRange());
6990 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6991 return Result;
6992 }
6993
6994 template<typename Derived>
TransformDeducedTemplateSpecializationType(TypeLocBuilder & TLB,DeducedTemplateSpecializationTypeLoc TL)6995 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6996 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6997 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6998
6999 CXXScopeSpec SS;
7000 TemplateName TemplateName = getDerived().TransformTemplateName(
7001 SS, T->getTemplateName(), TL.getTemplateNameLoc());
7002 if (TemplateName.isNull())
7003 return QualType();
7004
7005 QualType OldDeduced = T->getDeducedType();
7006 QualType NewDeduced;
7007 if (!OldDeduced.isNull()) {
7008 NewDeduced = getDerived().TransformType(OldDeduced);
7009 if (NewDeduced.isNull())
7010 return QualType();
7011 }
7012
7013 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7014 TemplateName, NewDeduced);
7015 if (Result.isNull())
7016 return QualType();
7017
7018 DeducedTemplateSpecializationTypeLoc NewTL =
7019 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
7020 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7021
7022 return Result;
7023 }
7024
7025 template<typename Derived>
TransformRecordType(TypeLocBuilder & TLB,RecordTypeLoc TL)7026 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7027 RecordTypeLoc TL) {
7028 const RecordType *T = TL.getTypePtr();
7029 RecordDecl *Record
7030 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7031 T->getDecl()));
7032 if (!Record)
7033 return QualType();
7034
7035 QualType Result = TL.getType();
7036 if (getDerived().AlwaysRebuild() ||
7037 Record != T->getDecl()) {
7038 Result = getDerived().RebuildRecordType(Record);
7039 if (Result.isNull())
7040 return QualType();
7041 }
7042
7043 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
7044 NewTL.setNameLoc(TL.getNameLoc());
7045
7046 return Result;
7047 }
7048
7049 template<typename Derived>
TransformEnumType(TypeLocBuilder & TLB,EnumTypeLoc TL)7050 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7051 EnumTypeLoc TL) {
7052 const EnumType *T = TL.getTypePtr();
7053 EnumDecl *Enum
7054 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7055 T->getDecl()));
7056 if (!Enum)
7057 return QualType();
7058
7059 QualType Result = TL.getType();
7060 if (getDerived().AlwaysRebuild() ||
7061 Enum != T->getDecl()) {
7062 Result = getDerived().RebuildEnumType(Enum);
7063 if (Result.isNull())
7064 return QualType();
7065 }
7066
7067 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
7068 NewTL.setNameLoc(TL.getNameLoc());
7069
7070 return Result;
7071 }
7072
7073 template<typename Derived>
TransformInjectedClassNameType(TypeLocBuilder & TLB,InjectedClassNameTypeLoc TL)7074 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7075 TypeLocBuilder &TLB,
7076 InjectedClassNameTypeLoc TL) {
7077 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
7078 TL.getTypePtr()->getDecl());
7079 if (!D) return QualType();
7080
7081 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
7082 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
7083 return T;
7084 }
7085
7086 template<typename Derived>
TransformTemplateTypeParmType(TypeLocBuilder & TLB,TemplateTypeParmTypeLoc TL)7087 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7088 TypeLocBuilder &TLB,
7089 TemplateTypeParmTypeLoc TL) {
7090 return getDerived().TransformTemplateTypeParmType(
7091 TLB, TL,
7092 /*SuppressObjCLifetime=*/false);
7093 }
7094
7095 template <typename Derived>
TransformTemplateTypeParmType(TypeLocBuilder & TLB,TemplateTypeParmTypeLoc TL,bool)7096 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7097 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7098 return TransformTypeSpecType(TLB, TL);
7099 }
7100
7101 template<typename Derived>
TransformSubstTemplateTypeParmType(TypeLocBuilder & TLB,SubstTemplateTypeParmTypeLoc TL)7102 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7103 TypeLocBuilder &TLB,
7104 SubstTemplateTypeParmTypeLoc TL) {
7105 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7106
7107 Decl *NewReplaced =
7108 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7109
7110 // Substitute into the replacement type, which itself might involve something
7111 // that needs to be transformed. This only tends to occur with default
7112 // template arguments of template template parameters.
7113 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7114 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7115 if (Replacement.isNull())
7116 return QualType();
7117
7118 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7119 Replacement, NewReplaced, T->getIndex(), T->getPackIndex(),
7120 T->getFinal());
7121
7122 // Propagate type-source information.
7123 SubstTemplateTypeParmTypeLoc NewTL
7124 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
7125 NewTL.setNameLoc(TL.getNameLoc());
7126 return Result;
7127
7128 }
7129
7130 template<typename Derived>
TransformSubstTemplateTypeParmPackType(TypeLocBuilder & TLB,SubstTemplateTypeParmPackTypeLoc TL)7131 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7132 TypeLocBuilder &TLB,
7133 SubstTemplateTypeParmPackTypeLoc TL) {
7134 return getDerived().TransformSubstTemplateTypeParmPackType(
7135 TLB, TL, /*SuppressObjCLifetime=*/false);
7136 }
7137
7138 template <typename Derived>
TransformSubstTemplateTypeParmPackType(TypeLocBuilder & TLB,SubstTemplateTypeParmPackTypeLoc TL,bool)7139 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7140 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7141 return TransformTypeSpecType(TLB, TL);
7142 }
7143
7144 template<typename Derived>
TransformTemplateSpecializationType(TypeLocBuilder & TLB,TemplateSpecializationTypeLoc TL)7145 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7146 TypeLocBuilder &TLB,
7147 TemplateSpecializationTypeLoc TL) {
7148 const TemplateSpecializationType *T = TL.getTypePtr();
7149
7150 // The nested-name-specifier never matters in a TemplateSpecializationType,
7151 // because we can't have a dependent nested-name-specifier anyway.
7152 CXXScopeSpec SS;
7153 TemplateName Template
7154 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
7155 TL.getTemplateNameLoc());
7156 if (Template.isNull())
7157 return QualType();
7158
7159 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
7160 }
7161
7162 template<typename Derived>
TransformAtomicType(TypeLocBuilder & TLB,AtomicTypeLoc TL)7163 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7164 AtomicTypeLoc TL) {
7165 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7166 if (ValueType.isNull())
7167 return QualType();
7168
7169 QualType Result = TL.getType();
7170 if (getDerived().AlwaysRebuild() ||
7171 ValueType != TL.getValueLoc().getType()) {
7172 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7173 if (Result.isNull())
7174 return QualType();
7175 }
7176
7177 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
7178 NewTL.setKWLoc(TL.getKWLoc());
7179 NewTL.setLParenLoc(TL.getLParenLoc());
7180 NewTL.setRParenLoc(TL.getRParenLoc());
7181
7182 return Result;
7183 }
7184
7185 template <typename Derived>
TransformPipeType(TypeLocBuilder & TLB,PipeTypeLoc TL)7186 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7187 PipeTypeLoc TL) {
7188 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7189 if (ValueType.isNull())
7190 return QualType();
7191
7192 QualType Result = TL.getType();
7193 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7194 const PipeType *PT = Result->castAs<PipeType>();
7195 bool isReadPipe = PT->isReadOnly();
7196 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7197 if (Result.isNull())
7198 return QualType();
7199 }
7200
7201 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
7202 NewTL.setKWLoc(TL.getKWLoc());
7203
7204 return Result;
7205 }
7206
7207 template <typename Derived>
TransformBitIntType(TypeLocBuilder & TLB,BitIntTypeLoc TL)7208 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7209 BitIntTypeLoc TL) {
7210 const BitIntType *EIT = TL.getTypePtr();
7211 QualType Result = TL.getType();
7212
7213 if (getDerived().AlwaysRebuild()) {
7214 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7215 EIT->getNumBits(), TL.getNameLoc());
7216 if (Result.isNull())
7217 return QualType();
7218 }
7219
7220 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7221 NewTL.setNameLoc(TL.getNameLoc());
7222 return Result;
7223 }
7224
7225 template <typename Derived>
TransformDependentBitIntType(TypeLocBuilder & TLB,DependentBitIntTypeLoc TL)7226 QualType TreeTransform<Derived>::TransformDependentBitIntType(
7227 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7228 const DependentBitIntType *EIT = TL.getTypePtr();
7229
7230 EnterExpressionEvaluationContext Unevaluated(
7231 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7232 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7233 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
7234
7235 if (BitsExpr.isInvalid())
7236 return QualType();
7237
7238 QualType Result = TL.getType();
7239
7240 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7241 Result = getDerived().RebuildDependentBitIntType(
7242 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7243
7244 if (Result.isNull())
7245 return QualType();
7246 }
7247
7248 if (isa<DependentBitIntType>(Result)) {
7249 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
7250 NewTL.setNameLoc(TL.getNameLoc());
7251 } else {
7252 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7253 NewTL.setNameLoc(TL.getNameLoc());
7254 }
7255 return Result;
7256 }
7257
7258 /// Simple iterator that traverses the template arguments in a
7259 /// container that provides a \c getArgLoc() member function.
7260 ///
7261 /// This iterator is intended to be used with the iterator form of
7262 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7263 template<typename ArgLocContainer>
7264 class TemplateArgumentLocContainerIterator {
7265 ArgLocContainer *Container;
7266 unsigned Index;
7267
7268 public:
7269 typedef TemplateArgumentLoc value_type;
7270 typedef TemplateArgumentLoc reference;
7271 typedef int difference_type;
7272 typedef std::input_iterator_tag iterator_category;
7273
7274 class pointer {
7275 TemplateArgumentLoc Arg;
7276
7277 public:
pointer(TemplateArgumentLoc Arg)7278 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7279
7280 const TemplateArgumentLoc *operator->() const {
7281 return &Arg;
7282 }
7283 };
7284
7285
TemplateArgumentLocContainerIterator()7286 TemplateArgumentLocContainerIterator() {}
7287
TemplateArgumentLocContainerIterator(ArgLocContainer & Container,unsigned Index)7288 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7289 unsigned Index)
7290 : Container(&Container), Index(Index) { }
7291
7292 TemplateArgumentLocContainerIterator &operator++() {
7293 ++Index;
7294 return *this;
7295 }
7296
7297 TemplateArgumentLocContainerIterator operator++(int) {
7298 TemplateArgumentLocContainerIterator Old(*this);
7299 ++(*this);
7300 return Old;
7301 }
7302
7303 TemplateArgumentLoc operator*() const {
7304 return Container->getArgLoc(Index);
7305 }
7306
7307 pointer operator->() const {
7308 return pointer(Container->getArgLoc(Index));
7309 }
7310
7311 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7312 const TemplateArgumentLocContainerIterator &Y) {
7313 return X.Container == Y.Container && X.Index == Y.Index;
7314 }
7315
7316 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7317 const TemplateArgumentLocContainerIterator &Y) {
7318 return !(X == Y);
7319 }
7320 };
7321
7322 template<typename Derived>
TransformAutoType(TypeLocBuilder & TLB,AutoTypeLoc TL)7323 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7324 AutoTypeLoc TL) {
7325 const AutoType *T = TL.getTypePtr();
7326 QualType OldDeduced = T->getDeducedType();
7327 QualType NewDeduced;
7328 if (!OldDeduced.isNull()) {
7329 NewDeduced = getDerived().TransformType(OldDeduced);
7330 if (NewDeduced.isNull())
7331 return QualType();
7332 }
7333
7334 ConceptDecl *NewCD = nullptr;
7335 TemplateArgumentListInfo NewTemplateArgs;
7336 NestedNameSpecifierLoc NewNestedNameSpec;
7337 if (T->isConstrained()) {
7338 assert(TL.getConceptReference());
7339 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7340 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7341
7342 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7343 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7344 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7345 if (getDerived().TransformTemplateArguments(
7346 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7347 NewTemplateArgs))
7348 return QualType();
7349
7350 if (TL.getNestedNameSpecifierLoc()) {
7351 NewNestedNameSpec
7352 = getDerived().TransformNestedNameSpecifierLoc(
7353 TL.getNestedNameSpecifierLoc());
7354 if (!NewNestedNameSpec)
7355 return QualType();
7356 }
7357 }
7358
7359 QualType Result = TL.getType();
7360 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7361 T->isDependentType() || T->isConstrained()) {
7362 // FIXME: Maybe don't rebuild if all template arguments are the same.
7363 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7364 NewArgList.reserve(NewTemplateArgs.size());
7365 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7366 NewArgList.push_back(ArgLoc.getArgument());
7367 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7368 NewArgList);
7369 if (Result.isNull())
7370 return QualType();
7371 }
7372
7373 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7374 NewTL.setNameLoc(TL.getNameLoc());
7375 NewTL.setRParenLoc(TL.getRParenLoc());
7376 NewTL.setConceptReference(nullptr);
7377
7378 if (T->isConstrained()) {
7379 DeclarationNameInfo DNI = DeclarationNameInfo(
7380 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7381 TL.getConceptNameLoc(),
7382 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7383 auto *CR = ConceptReference::Create(
7384 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
7385 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
7386 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
7387 NewTL.setConceptReference(CR);
7388 }
7389
7390 return Result;
7391 }
7392
7393 template <typename Derived>
TransformTemplateSpecializationType(TypeLocBuilder & TLB,TemplateSpecializationTypeLoc TL,TemplateName Template)7394 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7395 TypeLocBuilder &TLB,
7396 TemplateSpecializationTypeLoc TL,
7397 TemplateName Template) {
7398 TemplateArgumentListInfo NewTemplateArgs;
7399 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7400 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7401 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7402 ArgIterator;
7403 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7404 ArgIterator(TL, TL.getNumArgs()),
7405 NewTemplateArgs))
7406 return QualType();
7407
7408 // This needs to be rebuilt if either the arguments changed, or if the
7409 // original template changed. If the template changed, and even if the
7410 // arguments didn't change, these arguments might not correspond to their
7411 // respective parameters, therefore needing conversions.
7412 QualType Result =
7413 getDerived().RebuildTemplateSpecializationType(Template,
7414 TL.getTemplateNameLoc(),
7415 NewTemplateArgs);
7416
7417 if (!Result.isNull()) {
7418 // Specializations of template template parameters are represented as
7419 // TemplateSpecializationTypes, and substitution of type alias templates
7420 // within a dependent context can transform them into
7421 // DependentTemplateSpecializationTypes.
7422 if (isa<DependentTemplateSpecializationType>(Result)) {
7423 DependentTemplateSpecializationTypeLoc NewTL
7424 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7425 NewTL.setElaboratedKeywordLoc(SourceLocation());
7426 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7427 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7428 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7429 NewTL.setLAngleLoc(TL.getLAngleLoc());
7430 NewTL.setRAngleLoc(TL.getRAngleLoc());
7431 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7432 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7433 return Result;
7434 }
7435
7436 TemplateSpecializationTypeLoc NewTL
7437 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7438 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7439 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7440 NewTL.setLAngleLoc(TL.getLAngleLoc());
7441 NewTL.setRAngleLoc(TL.getRAngleLoc());
7442 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7443 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7444 }
7445
7446 return Result;
7447 }
7448
7449 template <typename Derived>
TransformDependentTemplateSpecializationType(TypeLocBuilder & TLB,DependentTemplateSpecializationTypeLoc TL,TemplateName Template,CXXScopeSpec & SS)7450 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7451 TypeLocBuilder &TLB,
7452 DependentTemplateSpecializationTypeLoc TL,
7453 TemplateName Template,
7454 CXXScopeSpec &SS) {
7455 TemplateArgumentListInfo NewTemplateArgs;
7456 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7457 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7458 typedef TemplateArgumentLocContainerIterator<
7459 DependentTemplateSpecializationTypeLoc> ArgIterator;
7460 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7461 ArgIterator(TL, TL.getNumArgs()),
7462 NewTemplateArgs))
7463 return QualType();
7464
7465 // FIXME: maybe don't rebuild if all the template arguments are the same.
7466
7467 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7468 assert(DTN->getQualifier() == SS.getScopeRep());
7469 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7470 TL.getTypePtr()->getKeyword(), *DTN, NewTemplateArgs.arguments());
7471
7472 DependentTemplateSpecializationTypeLoc NewTL
7473 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7474 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7475 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
7476 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7477 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7478 NewTL.setLAngleLoc(TL.getLAngleLoc());
7479 NewTL.setRAngleLoc(TL.getRAngleLoc());
7480 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7481 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7482 return Result;
7483 }
7484
7485 QualType Result
7486 = getDerived().RebuildTemplateSpecializationType(Template,
7487 TL.getTemplateNameLoc(),
7488 NewTemplateArgs);
7489
7490 if (!Result.isNull()) {
7491 /// FIXME: Wrap this in an elaborated-type-specifier?
7492 TemplateSpecializationTypeLoc NewTL
7493 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7494 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7495 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7496 NewTL.setLAngleLoc(TL.getLAngleLoc());
7497 NewTL.setRAngleLoc(TL.getRAngleLoc());
7498 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7499 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7500 }
7501
7502 return Result;
7503 }
7504
7505 template<typename Derived>
7506 QualType
TransformElaboratedType(TypeLocBuilder & TLB,ElaboratedTypeLoc TL)7507 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7508 ElaboratedTypeLoc TL) {
7509 const ElaboratedType *T = TL.getTypePtr();
7510
7511 NestedNameSpecifierLoc QualifierLoc;
7512 // NOTE: the qualifier in an ElaboratedType is optional.
7513 if (TL.getQualifierLoc()) {
7514 QualifierLoc
7515 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7516 if (!QualifierLoc)
7517 return QualType();
7518 }
7519
7520 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7521 if (NamedT.isNull())
7522 return QualType();
7523
7524 // C++0x [dcl.type.elab]p2:
7525 // If the identifier resolves to a typedef-name or the simple-template-id
7526 // resolves to an alias template specialization, the
7527 // elaborated-type-specifier is ill-formed.
7528 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7529 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7530 if (const TemplateSpecializationType *TST =
7531 NamedT->getAs<TemplateSpecializationType>()) {
7532 TemplateName Template = TST->getTemplateName();
7533 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7534 Template.getAsTemplateDecl())) {
7535 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7536 diag::err_tag_reference_non_tag)
7537 << TAT << NonTagKind::TypeAliasTemplate
7538 << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword());
7539 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7540 }
7541 }
7542 }
7543
7544 QualType Result = TL.getType();
7545 if (getDerived().AlwaysRebuild() ||
7546 QualifierLoc != TL.getQualifierLoc() ||
7547 NamedT != T->getNamedType()) {
7548 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7549 T->getKeyword(),
7550 QualifierLoc, NamedT);
7551 if (Result.isNull())
7552 return QualType();
7553 }
7554
7555 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7556 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7557 NewTL.setQualifierLoc(QualifierLoc);
7558 return Result;
7559 }
7560
7561 template <typename Derived>
TransformAttributedType(TypeLocBuilder & TLB,AttributedTypeLoc TL)7562 QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7563 AttributedTypeLoc TL) {
7564 const AttributedType *oldType = TL.getTypePtr();
7565 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7566 if (modifiedType.isNull())
7567 return QualType();
7568
7569 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7570 const Attr *oldAttr = TL.getAttr();
7571 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7572 if (oldAttr && !newAttr)
7573 return QualType();
7574
7575 QualType result = TL.getType();
7576
7577 // FIXME: dependent operand expressions?
7578 if (getDerived().AlwaysRebuild() ||
7579 modifiedType != oldType->getModifiedType()) {
7580 // If the equivalent type is equal to the modified type, we don't want to
7581 // transform it as well because:
7582 //
7583 // 1. The transformation would yield the same result and is therefore
7584 // superfluous, and
7585 //
7586 // 2. Transforming the same type twice can cause problems, e.g. if it
7587 // is a FunctionProtoType, we may end up instantiating the function
7588 // parameters twice, which causes an assertion since the parameters
7589 // are already bound to their counterparts in the template for this
7590 // instantiation.
7591 //
7592 QualType equivalentType = modifiedType;
7593 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7594 TypeLocBuilder AuxiliaryTLB;
7595 AuxiliaryTLB.reserve(TL.getFullDataSize());
7596 equivalentType =
7597 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7598 if (equivalentType.isNull())
7599 return QualType();
7600 }
7601
7602 // Check whether we can add nullability; it is only represented as
7603 // type sugar, and therefore cannot be diagnosed in any other way.
7604 if (auto nullability = oldType->getImmediateNullability()) {
7605 if (!modifiedType->canHaveNullability()) {
7606 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7607 : TL.getModifiedLoc().getBeginLoc()),
7608 diag::err_nullability_nonpointer)
7609 << DiagNullabilityKind(*nullability, false) << modifiedType;
7610 return QualType();
7611 }
7612 }
7613
7614 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7615 modifiedType,
7616 equivalentType,
7617 TL.getAttr());
7618 }
7619
7620 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7621 newTL.setAttr(newAttr);
7622 return result;
7623 }
7624
7625 template <typename Derived>
TransformCountAttributedType(TypeLocBuilder & TLB,CountAttributedTypeLoc TL)7626 QualType TreeTransform<Derived>::TransformCountAttributedType(
7627 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7628 const CountAttributedType *OldTy = TL.getTypePtr();
7629 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7630 if (InnerTy.isNull())
7631 return QualType();
7632
7633 Expr *OldCount = TL.getCountExpr();
7634 Expr *NewCount = nullptr;
7635 if (OldCount) {
7636 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7637 if (CountResult.isInvalid())
7638 return QualType();
7639 NewCount = CountResult.get();
7640 }
7641
7642 QualType Result = TL.getType();
7643 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7644 OldCount != NewCount) {
7645 // Currently, CountAttributedType can only wrap incomplete array types.
7646 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7647 InnerTy, NewCount, OldTy->isCountInBytes(), OldTy->isOrNull());
7648 }
7649
7650 TLB.push<CountAttributedTypeLoc>(Result);
7651 return Result;
7652 }
7653
7654 template <typename Derived>
TransformBTFTagAttributedType(TypeLocBuilder & TLB,BTFTagAttributedTypeLoc TL)7655 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7656 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7657 // The BTFTagAttributedType is available for C only.
7658 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7659 }
7660
7661 template <typename Derived>
TransformHLSLAttributedResourceType(TypeLocBuilder & TLB,HLSLAttributedResourceTypeLoc TL)7662 QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7663 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7664
7665 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7666
7667 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7668 if (WrappedTy.isNull())
7669 return QualType();
7670
7671 QualType ContainedTy = QualType();
7672 QualType OldContainedTy = oldType->getContainedType();
7673 if (!OldContainedTy.isNull()) {
7674 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7675 if (!oldContainedTSI)
7676 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7677 OldContainedTy, SourceLocation());
7678 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7679 if (!ContainedTSI)
7680 return QualType();
7681 ContainedTy = ContainedTSI->getType();
7682 }
7683
7684 QualType Result = TL.getType();
7685 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7686 ContainedTy != oldType->getContainedType()) {
7687 Result = SemaRef.Context.getHLSLAttributedResourceType(
7688 WrappedTy, ContainedTy, oldType->getAttrs());
7689 }
7690
7691 TLB.push<HLSLAttributedResourceTypeLoc>(Result);
7692 return Result;
7693 }
7694
7695 template <typename Derived>
TransformHLSLInlineSpirvType(TypeLocBuilder & TLB,HLSLInlineSpirvTypeLoc TL)7696 QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7697 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7698 // No transformations needed.
7699 return TL.getType();
7700 }
7701
7702 template<typename Derived>
7703 QualType
TransformParenType(TypeLocBuilder & TLB,ParenTypeLoc TL)7704 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7705 ParenTypeLoc TL) {
7706 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7707 if (Inner.isNull())
7708 return QualType();
7709
7710 QualType Result = TL.getType();
7711 if (getDerived().AlwaysRebuild() ||
7712 Inner != TL.getInnerLoc().getType()) {
7713 Result = getDerived().RebuildParenType(Inner);
7714 if (Result.isNull())
7715 return QualType();
7716 }
7717
7718 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7719 NewTL.setLParenLoc(TL.getLParenLoc());
7720 NewTL.setRParenLoc(TL.getRParenLoc());
7721 return Result;
7722 }
7723
7724 template <typename Derived>
7725 QualType
TransformMacroQualifiedType(TypeLocBuilder & TLB,MacroQualifiedTypeLoc TL)7726 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7727 MacroQualifiedTypeLoc TL) {
7728 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7729 if (Inner.isNull())
7730 return QualType();
7731
7732 QualType Result = TL.getType();
7733 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7734 Result =
7735 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7736 if (Result.isNull())
7737 return QualType();
7738 }
7739
7740 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7741 NewTL.setExpansionLoc(TL.getExpansionLoc());
7742 return Result;
7743 }
7744
7745 template<typename Derived>
TransformDependentNameType(TypeLocBuilder & TLB,DependentNameTypeLoc TL)7746 QualType TreeTransform<Derived>::TransformDependentNameType(
7747 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7748 return TransformDependentNameType(TLB, TL, false);
7749 }
7750
7751 template<typename Derived>
TransformDependentNameType(TypeLocBuilder & TLB,DependentNameTypeLoc TL,bool DeducedTSTContext)7752 QualType TreeTransform<Derived>::TransformDependentNameType(
7753 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7754 const DependentNameType *T = TL.getTypePtr();
7755
7756 NestedNameSpecifierLoc QualifierLoc
7757 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7758 if (!QualifierLoc)
7759 return QualType();
7760
7761 QualType Result
7762 = getDerived().RebuildDependentNameType(T->getKeyword(),
7763 TL.getElaboratedKeywordLoc(),
7764 QualifierLoc,
7765 T->getIdentifier(),
7766 TL.getNameLoc(),
7767 DeducedTSTContext);
7768 if (Result.isNull())
7769 return QualType();
7770
7771 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7772 QualType NamedT = ElabT->getNamedType();
7773 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7774
7775 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7776 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7777 NewTL.setQualifierLoc(QualifierLoc);
7778 } else {
7779 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7780 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7781 NewTL.setQualifierLoc(QualifierLoc);
7782 NewTL.setNameLoc(TL.getNameLoc());
7783 }
7784 return Result;
7785 }
7786
7787 template<typename Derived>
7788 QualType TreeTransform<Derived>::
TransformDependentTemplateSpecializationType(TypeLocBuilder & TLB,DependentTemplateSpecializationTypeLoc TL)7789 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7790 DependentTemplateSpecializationTypeLoc TL) {
7791 NestedNameSpecifierLoc QualifierLoc;
7792 if (TL.getQualifierLoc()) {
7793 QualifierLoc
7794 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7795 if (!QualifierLoc)
7796 return QualType();
7797 }
7798
7799 CXXScopeSpec SS;
7800 SS.Adopt(QualifierLoc);
7801 return getDerived().TransformDependentTemplateSpecializationType(TLB, TL, SS);
7802 }
7803
7804 template <typename Derived>
TransformDependentTemplateSpecializationType(TypeLocBuilder & TLB,DependentTemplateSpecializationTypeLoc TL,CXXScopeSpec & SS)7805 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7806 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
7807 CXXScopeSpec &SS) {
7808 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7809
7810 TemplateArgumentListInfo NewTemplateArgs;
7811 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7812 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7813
7814 auto ArgsRange = llvm::make_range<TemplateArgumentLocContainerIterator<
7815 DependentTemplateSpecializationTypeLoc>>({TL, 0}, {TL, TL.getNumArgs()});
7816
7817 if (getDerived().TransformTemplateArguments(ArgsRange.begin(),
7818 ArgsRange.end(), NewTemplateArgs))
7819 return QualType();
7820 bool TemplateArgumentsChanged = !llvm::equal(
7821 ArgsRange, NewTemplateArgs.arguments(),
7822 [](const TemplateArgumentLoc &A, const TemplateArgumentLoc &B) {
7823 return A.getArgument().structurallyEquals(B.getArgument());
7824 });
7825
7826 const DependentTemplateStorage &DTN = T->getDependentTemplateName();
7827
7828 QualType Result = TL.getType();
7829 if (getDerived().AlwaysRebuild() || SS.getScopeRep() != DTN.getQualifier() ||
7830 TemplateArgumentsChanged) {
7831 TemplateName Name = getDerived().RebuildTemplateName(
7832 SS, TL.getTemplateKeywordLoc(), DTN.getName(), TL.getTemplateNameLoc(),
7833 /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7834 /*AllowInjectedClassName=*/false);
7835 if (Name.isNull())
7836 return QualType();
7837 Result = getDerived().RebuildDependentTemplateSpecializationType(
7838 T->getKeyword(), SS.getScopeRep(), TL.getTemplateKeywordLoc(), Name,
7839 TL.getTemplateNameLoc(), NewTemplateArgs,
7840 /*AllowInjectedClassName=*/false);
7841 if (Result.isNull())
7842 return QualType();
7843 }
7844
7845 NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(SemaRef.Context);
7846 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7847 QualType NamedT = ElabT->getNamedType();
7848
7849 // Copy information relevant to the template specialization.
7850 TemplateSpecializationTypeLoc NamedTL
7851 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7852 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7853 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7854 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7855 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7856 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7857 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7858
7859 // Copy information relevant to the elaborated type.
7860 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7861 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7862 NewTL.setQualifierLoc(QualifierLoc);
7863 } else {
7864 assert(isa<DependentTemplateSpecializationType>(Result));
7865 DependentTemplateSpecializationTypeLoc SpecTL
7866 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7867 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7868 SpecTL.setQualifierLoc(QualifierLoc);
7869 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7870 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7871 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7872 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7873 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7874 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7875 }
7876 return Result;
7877 }
7878
7879 template<typename Derived>
TransformPackExpansionType(TypeLocBuilder & TLB,PackExpansionTypeLoc TL)7880 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7881 PackExpansionTypeLoc TL) {
7882 QualType Pattern
7883 = getDerived().TransformType(TLB, TL.getPatternLoc());
7884 if (Pattern.isNull())
7885 return QualType();
7886
7887 QualType Result = TL.getType();
7888 if (getDerived().AlwaysRebuild() ||
7889 Pattern != TL.getPatternLoc().getType()) {
7890 Result = getDerived().RebuildPackExpansionType(Pattern,
7891 TL.getPatternLoc().getSourceRange(),
7892 TL.getEllipsisLoc(),
7893 TL.getTypePtr()->getNumExpansions());
7894 if (Result.isNull())
7895 return QualType();
7896 }
7897
7898 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7899 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7900 return Result;
7901 }
7902
7903 template<typename Derived>
7904 QualType
TransformObjCInterfaceType(TypeLocBuilder & TLB,ObjCInterfaceTypeLoc TL)7905 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7906 ObjCInterfaceTypeLoc TL) {
7907 // ObjCInterfaceType is never dependent.
7908 TLB.pushFullCopy(TL);
7909 return TL.getType();
7910 }
7911
7912 template<typename Derived>
7913 QualType
TransformObjCTypeParamType(TypeLocBuilder & TLB,ObjCTypeParamTypeLoc TL)7914 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7915 ObjCTypeParamTypeLoc TL) {
7916 const ObjCTypeParamType *T = TL.getTypePtr();
7917 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7918 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7919 if (!OTP)
7920 return QualType();
7921
7922 QualType Result = TL.getType();
7923 if (getDerived().AlwaysRebuild() ||
7924 OTP != T->getDecl()) {
7925 Result = getDerived().RebuildObjCTypeParamType(
7926 OTP, TL.getProtocolLAngleLoc(),
7927 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7928 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7929 if (Result.isNull())
7930 return QualType();
7931 }
7932
7933 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7934 if (TL.getNumProtocols()) {
7935 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7936 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7937 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7938 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7939 }
7940 return Result;
7941 }
7942
7943 template<typename Derived>
7944 QualType
TransformObjCObjectType(TypeLocBuilder & TLB,ObjCObjectTypeLoc TL)7945 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7946 ObjCObjectTypeLoc TL) {
7947 // Transform base type.
7948 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7949 if (BaseType.isNull())
7950 return QualType();
7951
7952 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7953
7954 // Transform type arguments.
7955 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7956 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7957 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7958 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7959 QualType TypeArg = TypeArgInfo->getType();
7960 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7961 AnyChanged = true;
7962
7963 // We have a pack expansion. Instantiate it.
7964 const auto *PackExpansion = PackExpansionLoc.getType()
7965 ->castAs<PackExpansionType>();
7966 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7967 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7968 Unexpanded);
7969 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7970
7971 // Determine whether the set of unexpanded parameter packs can
7972 // and should be expanded.
7973 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7974 bool Expand = false;
7975 bool RetainExpansion = false;
7976 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
7977 if (getDerived().TryExpandParameterPacks(
7978 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7979 Unexpanded, Expand, RetainExpansion, NumExpansions))
7980 return QualType();
7981
7982 if (!Expand) {
7983 // We can't expand this pack expansion into separate arguments yet;
7984 // just substitute into the pattern and create a new pack expansion
7985 // type.
7986 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7987
7988 TypeLocBuilder TypeArgBuilder;
7989 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7990 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7991 PatternLoc);
7992 if (NewPatternType.isNull())
7993 return QualType();
7994
7995 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7996 NewPatternType, NumExpansions);
7997 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7998 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7999 NewTypeArgInfos.push_back(
8000 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
8001 continue;
8002 }
8003
8004 // Substitute into the pack expansion pattern for each slice of the
8005 // pack.
8006 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8007 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8008
8009 TypeLocBuilder TypeArgBuilder;
8010 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
8011
8012 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8013 PatternLoc);
8014 if (NewTypeArg.isNull())
8015 return QualType();
8016
8017 NewTypeArgInfos.push_back(
8018 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
8019 }
8020
8021 continue;
8022 }
8023
8024 TypeLocBuilder TypeArgBuilder;
8025 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
8026 QualType NewTypeArg =
8027 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8028 if (NewTypeArg.isNull())
8029 return QualType();
8030
8031 // If nothing changed, just keep the old TypeSourceInfo.
8032 if (NewTypeArg == TypeArg) {
8033 NewTypeArgInfos.push_back(TypeArgInfo);
8034 continue;
8035 }
8036
8037 NewTypeArgInfos.push_back(
8038 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
8039 AnyChanged = true;
8040 }
8041
8042 QualType Result = TL.getType();
8043 if (getDerived().AlwaysRebuild() || AnyChanged) {
8044 // Rebuild the type.
8045 Result = getDerived().RebuildObjCObjectType(
8046 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8047 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8048 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8049 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8050
8051 if (Result.isNull())
8052 return QualType();
8053 }
8054
8055 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
8056 NewT.setHasBaseTypeAsWritten(true);
8057 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8058 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8059 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
8060 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8061 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8062 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8063 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
8064 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8065 return Result;
8066 }
8067
8068 template<typename Derived>
8069 QualType
TransformObjCObjectPointerType(TypeLocBuilder & TLB,ObjCObjectPointerTypeLoc TL)8070 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8071 ObjCObjectPointerTypeLoc TL) {
8072 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8073 if (PointeeType.isNull())
8074 return QualType();
8075
8076 QualType Result = TL.getType();
8077 if (getDerived().AlwaysRebuild() ||
8078 PointeeType != TL.getPointeeLoc().getType()) {
8079 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8080 TL.getStarLoc());
8081 if (Result.isNull())
8082 return QualType();
8083 }
8084
8085 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
8086 NewT.setStarLoc(TL.getStarLoc());
8087 return Result;
8088 }
8089
8090 //===----------------------------------------------------------------------===//
8091 // Statement transformation
8092 //===----------------------------------------------------------------------===//
8093 template<typename Derived>
8094 StmtResult
TransformNullStmt(NullStmt * S)8095 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8096 return S;
8097 }
8098
8099 template<typename Derived>
8100 StmtResult
TransformCompoundStmt(CompoundStmt * S)8101 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8102 return getDerived().TransformCompoundStmt(S, false);
8103 }
8104
8105 template<typename Derived>
8106 StmtResult
TransformCompoundStmt(CompoundStmt * S,bool IsStmtExpr)8107 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8108 bool IsStmtExpr) {
8109 Sema::CompoundScopeRAII CompoundScope(getSema());
8110 Sema::FPFeaturesStateRAII FPSave(getSema());
8111 if (S->hasStoredFPFeatures())
8112 getSema().resetFPOptions(
8113 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8114
8115 const Stmt *ExprResult = S->getStmtExprResult();
8116 bool SubStmtInvalid = false;
8117 bool SubStmtChanged = false;
8118 SmallVector<Stmt*, 8> Statements;
8119 for (auto *B : S->body()) {
8120 StmtResult Result = getDerived().TransformStmt(
8121 B, IsStmtExpr && B == ExprResult ? StmtDiscardKind::StmtExprResult
8122 : StmtDiscardKind::Discarded);
8123
8124 if (Result.isInvalid()) {
8125 // Immediately fail if this was a DeclStmt, since it's very
8126 // likely that this will cause problems for future statements.
8127 if (isa<DeclStmt>(B))
8128 return StmtError();
8129
8130 // Otherwise, just keep processing substatements and fail later.
8131 SubStmtInvalid = true;
8132 continue;
8133 }
8134
8135 SubStmtChanged = SubStmtChanged || Result.get() != B;
8136 Statements.push_back(Result.getAs<Stmt>());
8137 }
8138
8139 if (SubStmtInvalid)
8140 return StmtError();
8141
8142 if (!getDerived().AlwaysRebuild() &&
8143 !SubStmtChanged)
8144 return S;
8145
8146 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8147 Statements,
8148 S->getRBracLoc(),
8149 IsStmtExpr);
8150 }
8151
8152 template<typename Derived>
8153 StmtResult
TransformCaseStmt(CaseStmt * S)8154 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8155 ExprResult LHS, RHS;
8156 {
8157 EnterExpressionEvaluationContext Unevaluated(
8158 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8159
8160 // Transform the left-hand case value.
8161 LHS = getDerived().TransformExpr(S->getLHS());
8162 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
8163 if (LHS.isInvalid())
8164 return StmtError();
8165
8166 // Transform the right-hand case value (for the GNU case-range extension).
8167 RHS = getDerived().TransformExpr(S->getRHS());
8168 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
8169 if (RHS.isInvalid())
8170 return StmtError();
8171 }
8172
8173 // Build the case statement.
8174 // Case statements are always rebuilt so that they will attached to their
8175 // transformed switch statement.
8176 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8177 LHS.get(),
8178 S->getEllipsisLoc(),
8179 RHS.get(),
8180 S->getColonLoc());
8181 if (Case.isInvalid())
8182 return StmtError();
8183
8184 // Transform the statement following the case
8185 StmtResult SubStmt =
8186 getDerived().TransformStmt(S->getSubStmt());
8187 if (SubStmt.isInvalid())
8188 return StmtError();
8189
8190 // Attach the body to the case statement
8191 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8192 }
8193
8194 template <typename Derived>
TransformDefaultStmt(DefaultStmt * S)8195 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8196 // Transform the statement following the default case
8197 StmtResult SubStmt =
8198 getDerived().TransformStmt(S->getSubStmt());
8199 if (SubStmt.isInvalid())
8200 return StmtError();
8201
8202 // Default statements are always rebuilt
8203 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8204 SubStmt.get());
8205 }
8206
8207 template<typename Derived>
8208 StmtResult
TransformLabelStmt(LabelStmt * S,StmtDiscardKind SDK)8209 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8210 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8211 if (SubStmt.isInvalid())
8212 return StmtError();
8213
8214 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8215 S->getDecl());
8216 if (!LD)
8217 return StmtError();
8218
8219 // If we're transforming "in-place" (we're not creating new local
8220 // declarations), assume we're replacing the old label statement
8221 // and clear out the reference to it.
8222 if (LD == S->getDecl())
8223 S->getDecl()->setStmt(nullptr);
8224
8225 // FIXME: Pass the real colon location in.
8226 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8227 cast<LabelDecl>(LD), SourceLocation(),
8228 SubStmt.get());
8229 }
8230
8231 template <typename Derived>
TransformAttr(const Attr * R)8232 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8233 if (!R)
8234 return R;
8235
8236 switch (R->getKind()) {
8237 // Transform attributes by calling TransformXXXAttr.
8238 #define ATTR(X) \
8239 case attr::X: \
8240 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8241 #include "clang/Basic/AttrList.inc"
8242 }
8243 return R;
8244 }
8245
8246 template <typename Derived>
TransformStmtAttr(const Stmt * OrigS,const Stmt * InstS,const Attr * R)8247 const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8248 const Stmt *InstS,
8249 const Attr *R) {
8250 if (!R)
8251 return R;
8252
8253 switch (R->getKind()) {
8254 // Transform attributes by calling TransformStmtXXXAttr.
8255 #define ATTR(X) \
8256 case attr::X: \
8257 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8258 #include "clang/Basic/AttrList.inc"
8259 }
8260 return TransformAttr(R);
8261 }
8262
8263 template <typename Derived>
8264 StmtResult
TransformAttributedStmt(AttributedStmt * S,StmtDiscardKind SDK)8265 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8266 StmtDiscardKind SDK) {
8267 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8268 if (SubStmt.isInvalid())
8269 return StmtError();
8270
8271 bool AttrsChanged = false;
8272 SmallVector<const Attr *, 1> Attrs;
8273
8274 // Visit attributes and keep track if any are transformed.
8275 for (const auto *I : S->getAttrs()) {
8276 const Attr *R =
8277 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8278 AttrsChanged |= (I != R);
8279 if (R)
8280 Attrs.push_back(R);
8281 }
8282
8283 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8284 return S;
8285
8286 // If transforming the attributes failed for all of the attributes in the
8287 // statement, don't make an AttributedStmt without attributes.
8288 if (Attrs.empty())
8289 return SubStmt;
8290
8291 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8292 SubStmt.get());
8293 }
8294
8295 template<typename Derived>
8296 StmtResult
TransformIfStmt(IfStmt * S)8297 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8298 // Transform the initialization statement
8299 StmtResult Init = getDerived().TransformStmt(S->getInit());
8300 if (Init.isInvalid())
8301 return StmtError();
8302
8303 Sema::ConditionResult Cond;
8304 if (!S->isConsteval()) {
8305 // Transform the condition
8306 Cond = getDerived().TransformCondition(
8307 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8308 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8309 : Sema::ConditionKind::Boolean);
8310 if (Cond.isInvalid())
8311 return StmtError();
8312 }
8313
8314 // If this is a constexpr if, determine which arm we should instantiate.
8315 std::optional<bool> ConstexprConditionValue;
8316 if (S->isConstexpr())
8317 ConstexprConditionValue = Cond.getKnownValue();
8318
8319 // Transform the "then" branch.
8320 StmtResult Then;
8321 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8322 EnterExpressionEvaluationContext Ctx(
8323 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8324 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8325 S->isNonNegatedConsteval());
8326
8327 Then = getDerived().TransformStmt(S->getThen());
8328 if (Then.isInvalid())
8329 return StmtError();
8330 } else {
8331 // Discarded branch is replaced with empty CompoundStmt so we can keep
8332 // proper source location for start and end of original branch, so
8333 // subsequent transformations like CoverageMapping work properly
8334 Then = new (getSema().Context)
8335 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8336 }
8337
8338 // Transform the "else" branch.
8339 StmtResult Else;
8340 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8341 EnterExpressionEvaluationContext Ctx(
8342 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8343 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8344 S->isNegatedConsteval());
8345
8346 Else = getDerived().TransformStmt(S->getElse());
8347 if (Else.isInvalid())
8348 return StmtError();
8349 } else if (S->getElse() && ConstexprConditionValue &&
8350 *ConstexprConditionValue) {
8351 // Same thing here as with <then> branch, we are discarding it, we can't
8352 // replace it with NULL nor NullStmt as we need to keep for source location
8353 // range, for CoverageMapping
8354 Else = new (getSema().Context)
8355 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8356 }
8357
8358 if (!getDerived().AlwaysRebuild() &&
8359 Init.get() == S->getInit() &&
8360 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8361 Then.get() == S->getThen() &&
8362 Else.get() == S->getElse())
8363 return S;
8364
8365 return getDerived().RebuildIfStmt(
8366 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8367 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8368 }
8369
8370 template<typename Derived>
8371 StmtResult
TransformSwitchStmt(SwitchStmt * S)8372 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8373 // Transform the initialization statement
8374 StmtResult Init = getDerived().TransformStmt(S->getInit());
8375 if (Init.isInvalid())
8376 return StmtError();
8377
8378 // Transform the condition.
8379 Sema::ConditionResult Cond = getDerived().TransformCondition(
8380 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8381 Sema::ConditionKind::Switch);
8382 if (Cond.isInvalid())
8383 return StmtError();
8384
8385 // Rebuild the switch statement.
8386 StmtResult Switch =
8387 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8388 Init.get(), Cond, S->getRParenLoc());
8389 if (Switch.isInvalid())
8390 return StmtError();
8391
8392 // Transform the body of the switch statement.
8393 StmtResult Body = getDerived().TransformStmt(S->getBody());
8394 if (Body.isInvalid())
8395 return StmtError();
8396
8397 // Complete the switch statement.
8398 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8399 Body.get());
8400 }
8401
8402 template<typename Derived>
8403 StmtResult
TransformWhileStmt(WhileStmt * S)8404 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8405 // Transform the condition
8406 Sema::ConditionResult Cond = getDerived().TransformCondition(
8407 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8408 Sema::ConditionKind::Boolean);
8409 if (Cond.isInvalid())
8410 return StmtError();
8411
8412 // OpenACC Restricts a while-loop inside of certain construct/clause
8413 // combinations, so diagnose that here in OpenACC mode.
8414 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8415 SemaRef.OpenACC().ActOnWhileStmt(S->getBeginLoc());
8416
8417 // Transform the body
8418 StmtResult Body = getDerived().TransformStmt(S->getBody());
8419 if (Body.isInvalid())
8420 return StmtError();
8421
8422 if (!getDerived().AlwaysRebuild() &&
8423 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8424 Body.get() == S->getBody())
8425 return Owned(S);
8426
8427 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8428 Cond, S->getRParenLoc(), Body.get());
8429 }
8430
8431 template<typename Derived>
8432 StmtResult
TransformDoStmt(DoStmt * S)8433 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8434 // OpenACC Restricts a do-loop inside of certain construct/clause
8435 // combinations, so diagnose that here in OpenACC mode.
8436 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8437 SemaRef.OpenACC().ActOnDoStmt(S->getBeginLoc());
8438
8439 // Transform the body
8440 StmtResult Body = getDerived().TransformStmt(S->getBody());
8441 if (Body.isInvalid())
8442 return StmtError();
8443
8444 // Transform the condition
8445 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8446 if (Cond.isInvalid())
8447 return StmtError();
8448
8449 if (!getDerived().AlwaysRebuild() &&
8450 Cond.get() == S->getCond() &&
8451 Body.get() == S->getBody())
8452 return S;
8453
8454 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8455 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8456 S->getRParenLoc());
8457 }
8458
8459 template<typename Derived>
8460 StmtResult
TransformForStmt(ForStmt * S)8461 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8462 if (getSema().getLangOpts().OpenMP)
8463 getSema().OpenMP().startOpenMPLoop();
8464
8465 // Transform the initialization statement
8466 StmtResult Init = getDerived().TransformStmt(S->getInit());
8467 if (Init.isInvalid())
8468 return StmtError();
8469
8470 // In OpenMP loop region loop control variable must be captured and be
8471 // private. Perform analysis of first part (if any).
8472 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8473 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8474 Init.get());
8475
8476 // Transform the condition
8477 Sema::ConditionResult Cond = getDerived().TransformCondition(
8478 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8479 Sema::ConditionKind::Boolean);
8480 if (Cond.isInvalid())
8481 return StmtError();
8482
8483 // Transform the increment
8484 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8485 if (Inc.isInvalid())
8486 return StmtError();
8487
8488 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8489 if (S->getInc() && !FullInc.get())
8490 return StmtError();
8491
8492 // OpenACC Restricts a for-loop inside of certain construct/clause
8493 // combinations, so diagnose that here in OpenACC mode.
8494 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8495 SemaRef.OpenACC().ActOnForStmtBegin(
8496 S->getBeginLoc(), S->getInit(), Init.get(), S->getCond(),
8497 Cond.get().second, S->getInc(), Inc.get());
8498
8499 // Transform the body
8500 StmtResult Body = getDerived().TransformStmt(S->getBody());
8501 if (Body.isInvalid())
8502 return StmtError();
8503
8504 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
8505
8506 if (!getDerived().AlwaysRebuild() &&
8507 Init.get() == S->getInit() &&
8508 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8509 Inc.get() == S->getInc() &&
8510 Body.get() == S->getBody())
8511 return S;
8512
8513 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8514 Init.get(), Cond, FullInc,
8515 S->getRParenLoc(), Body.get());
8516 }
8517
8518 template<typename Derived>
8519 StmtResult
TransformGotoStmt(GotoStmt * S)8520 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8521 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8522 S->getLabel());
8523 if (!LD)
8524 return StmtError();
8525
8526 // Goto statements must always be rebuilt, to resolve the label.
8527 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8528 cast<LabelDecl>(LD));
8529 }
8530
8531 template<typename Derived>
8532 StmtResult
TransformIndirectGotoStmt(IndirectGotoStmt * S)8533 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8534 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8535 if (Target.isInvalid())
8536 return StmtError();
8537 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
8538
8539 if (!getDerived().AlwaysRebuild() &&
8540 Target.get() == S->getTarget())
8541 return S;
8542
8543 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8544 Target.get());
8545 }
8546
8547 template<typename Derived>
8548 StmtResult
TransformContinueStmt(ContinueStmt * S)8549 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8550 return S;
8551 }
8552
8553 template<typename Derived>
8554 StmtResult
TransformBreakStmt(BreakStmt * S)8555 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8556 return S;
8557 }
8558
8559 template<typename Derived>
8560 StmtResult
TransformReturnStmt(ReturnStmt * S)8561 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8562 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8563 /*NotCopyInit*/false);
8564 if (Result.isInvalid())
8565 return StmtError();
8566
8567 // FIXME: We always rebuild the return statement because there is no way
8568 // to tell whether the return type of the function has changed.
8569 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8570 }
8571
8572 template<typename Derived>
8573 StmtResult
TransformDeclStmt(DeclStmt * S)8574 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8575 bool DeclChanged = false;
8576 SmallVector<Decl *, 4> Decls;
8577 LambdaScopeInfo *LSI = getSema().getCurLambda();
8578 for (auto *D : S->decls()) {
8579 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8580 if (!Transformed)
8581 return StmtError();
8582
8583 if (Transformed != D)
8584 DeclChanged = true;
8585
8586 if (LSI) {
8587 if (auto *TD = dyn_cast<TypeDecl>(Transformed))
8588 LSI->ContainsUnexpandedParameterPack |=
8589 getSema()
8590 .getASTContext()
8591 .getTypeDeclType(TD)
8592 .getSingleStepDesugaredType(getSema().getASTContext())
8593 ->containsUnexpandedParameterPack();
8594
8595 if (auto *VD = dyn_cast<VarDecl>(Transformed))
8596 LSI->ContainsUnexpandedParameterPack |=
8597 VD->getType()->containsUnexpandedParameterPack();
8598 }
8599
8600 Decls.push_back(Transformed);
8601 }
8602
8603 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8604 return S;
8605
8606 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8607 }
8608
8609 template<typename Derived>
8610 StmtResult
TransformGCCAsmStmt(GCCAsmStmt * S)8611 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8612
8613 SmallVector<Expr*, 8> Constraints;
8614 SmallVector<Expr*, 8> Exprs;
8615 SmallVector<IdentifierInfo *, 4> Names;
8616
8617 SmallVector<Expr*, 8> Clobbers;
8618
8619 bool ExprsChanged = false;
8620
8621 auto RebuildString = [&](Expr *E) {
8622 ExprResult Result = getDerived().TransformExpr(E);
8623 if (!Result.isUsable())
8624 return Result;
8625 if (Result.get() != E) {
8626 ExprsChanged = true;
8627 Result = SemaRef.ActOnGCCAsmStmtString(Result.get(), /*ForLabel=*/false);
8628 }
8629 return Result;
8630 };
8631
8632 // Go through the outputs.
8633 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8634 Names.push_back(S->getOutputIdentifier(I));
8635
8636 ExprResult Result = RebuildString(S->getOutputConstraintExpr(I));
8637 if (Result.isInvalid())
8638 return StmtError();
8639
8640 Constraints.push_back(Result.get());
8641
8642 // Transform the output expr.
8643 Expr *OutputExpr = S->getOutputExpr(I);
8644 Result = getDerived().TransformExpr(OutputExpr);
8645 if (Result.isInvalid())
8646 return StmtError();
8647
8648 ExprsChanged |= Result.get() != OutputExpr;
8649
8650 Exprs.push_back(Result.get());
8651 }
8652
8653 // Go through the inputs.
8654 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8655 Names.push_back(S->getInputIdentifier(I));
8656
8657 ExprResult Result = RebuildString(S->getInputConstraintExpr(I));
8658 if (Result.isInvalid())
8659 return StmtError();
8660
8661 Constraints.push_back(Result.get());
8662
8663 // Transform the input expr.
8664 Expr *InputExpr = S->getInputExpr(I);
8665 Result = getDerived().TransformExpr(InputExpr);
8666 if (Result.isInvalid())
8667 return StmtError();
8668
8669 ExprsChanged |= Result.get() != InputExpr;
8670
8671 Exprs.push_back(Result.get());
8672 }
8673
8674 // Go through the Labels.
8675 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8676 Names.push_back(S->getLabelIdentifier(I));
8677
8678 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8679 if (Result.isInvalid())
8680 return StmtError();
8681 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8682 Exprs.push_back(Result.get());
8683 }
8684
8685 // Go through the clobbers.
8686 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8687 ExprResult Result = RebuildString(S->getClobberExpr(I));
8688 if (Result.isInvalid())
8689 return StmtError();
8690 Clobbers.push_back(Result.get());
8691 }
8692
8693 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8694 if (AsmString.isInvalid())
8695 return StmtError();
8696
8697 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8698 return S;
8699
8700 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8701 S->isVolatile(), S->getNumOutputs(),
8702 S->getNumInputs(), Names.data(),
8703 Constraints, Exprs, AsmString.get(),
8704 Clobbers, S->getNumLabels(),
8705 S->getRParenLoc());
8706 }
8707
8708 template<typename Derived>
8709 StmtResult
TransformMSAsmStmt(MSAsmStmt * S)8710 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8711 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8712
8713 bool HadError = false, HadChange = false;
8714
8715 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8716 SmallVector<Expr*, 8> TransformedExprs;
8717 TransformedExprs.reserve(SrcExprs.size());
8718 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8719 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8720 if (!Result.isUsable()) {
8721 HadError = true;
8722 } else {
8723 HadChange |= (Result.get() != SrcExprs[i]);
8724 TransformedExprs.push_back(Result.get());
8725 }
8726 }
8727
8728 if (HadError) return StmtError();
8729 if (!HadChange && !getDerived().AlwaysRebuild())
8730 return Owned(S);
8731
8732 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8733 AsmToks, S->getAsmString(),
8734 S->getNumOutputs(), S->getNumInputs(),
8735 S->getAllConstraints(), S->getClobbers(),
8736 TransformedExprs, S->getEndLoc());
8737 }
8738
8739 // C++ Coroutines
8740 template<typename Derived>
8741 StmtResult
TransformCoroutineBodyStmt(CoroutineBodyStmt * S)8742 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8743 auto *ScopeInfo = SemaRef.getCurFunction();
8744 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8745 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8746 ScopeInfo->NeedsCoroutineSuspends &&
8747 ScopeInfo->CoroutineSuspends.first == nullptr &&
8748 ScopeInfo->CoroutineSuspends.second == nullptr &&
8749 "expected clean scope info");
8750
8751 // Set that we have (possibly-invalid) suspend points before we do anything
8752 // that may fail.
8753 ScopeInfo->setNeedsCoroutineSuspends(false);
8754
8755 // We re-build the coroutine promise object (and the coroutine parameters its
8756 // type and constructor depend on) based on the types used in our current
8757 // function. We must do so, and set it on the current FunctionScopeInfo,
8758 // before attempting to transform the other parts of the coroutine body
8759 // statement, such as the implicit suspend statements (because those
8760 // statements reference the FunctionScopeInfo::CoroutinePromise).
8761 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8762 return StmtError();
8763 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8764 if (!Promise)
8765 return StmtError();
8766 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8767 ScopeInfo->CoroutinePromise = Promise;
8768
8769 // Transform the implicit coroutine statements constructed using dependent
8770 // types during the previous parse: initial and final suspensions, the return
8771 // object, and others. We also transform the coroutine function's body.
8772 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8773 if (InitSuspend.isInvalid())
8774 return StmtError();
8775 StmtResult FinalSuspend =
8776 getDerived().TransformStmt(S->getFinalSuspendStmt());
8777 if (FinalSuspend.isInvalid() ||
8778 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8779 return StmtError();
8780 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8781 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8782
8783 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8784 if (BodyRes.isInvalid())
8785 return StmtError();
8786
8787 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8788 if (Builder.isInvalid())
8789 return StmtError();
8790
8791 Expr *ReturnObject = S->getReturnValueInit();
8792 assert(ReturnObject && "the return object is expected to be valid");
8793 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8794 /*NoCopyInit*/ false);
8795 if (Res.isInvalid())
8796 return StmtError();
8797 Builder.ReturnValue = Res.get();
8798
8799 // If during the previous parse the coroutine still had a dependent promise
8800 // statement, we may need to build some implicit coroutine statements
8801 // (such as exception and fallthrough handlers) for the first time.
8802 if (S->hasDependentPromiseType()) {
8803 // We can only build these statements, however, if the current promise type
8804 // is not dependent.
8805 if (!Promise->getType()->isDependentType()) {
8806 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8807 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8808 "these nodes should not have been built yet");
8809 if (!Builder.buildDependentStatements())
8810 return StmtError();
8811 }
8812 } else {
8813 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8814 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8815 if (Res.isInvalid())
8816 return StmtError();
8817 Builder.OnFallthrough = Res.get();
8818 }
8819
8820 if (auto *OnException = S->getExceptionHandler()) {
8821 StmtResult Res = getDerived().TransformStmt(OnException);
8822 if (Res.isInvalid())
8823 return StmtError();
8824 Builder.OnException = Res.get();
8825 }
8826
8827 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8828 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8829 if (Res.isInvalid())
8830 return StmtError();
8831 Builder.ReturnStmtOnAllocFailure = Res.get();
8832 }
8833
8834 // Transform any additional statements we may have already built
8835 assert(S->getAllocate() && S->getDeallocate() &&
8836 "allocation and deallocation calls must already be built");
8837 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8838 if (AllocRes.isInvalid())
8839 return StmtError();
8840 Builder.Allocate = AllocRes.get();
8841
8842 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8843 if (DeallocRes.isInvalid())
8844 return StmtError();
8845 Builder.Deallocate = DeallocRes.get();
8846
8847 if (auto *ResultDecl = S->getResultDecl()) {
8848 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8849 if (Res.isInvalid())
8850 return StmtError();
8851 Builder.ResultDecl = Res.get();
8852 }
8853
8854 if (auto *ReturnStmt = S->getReturnStmt()) {
8855 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8856 if (Res.isInvalid())
8857 return StmtError();
8858 Builder.ReturnStmt = Res.get();
8859 }
8860 }
8861
8862 return getDerived().RebuildCoroutineBodyStmt(Builder);
8863 }
8864
8865 template<typename Derived>
8866 StmtResult
TransformCoreturnStmt(CoreturnStmt * S)8867 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8868 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8869 /*NotCopyInit*/false);
8870 if (Result.isInvalid())
8871 return StmtError();
8872
8873 // Always rebuild; we don't know if this needs to be injected into a new
8874 // context or if the promise type has changed.
8875 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8876 S->isImplicit());
8877 }
8878
8879 template <typename Derived>
TransformCoawaitExpr(CoawaitExpr * E)8880 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8881 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8882 /*NotCopyInit*/ false);
8883 if (Operand.isInvalid())
8884 return ExprError();
8885
8886 // Rebuild the common-expr from the operand rather than transforming it
8887 // separately.
8888
8889 // FIXME: getCurScope() should not be used during template instantiation.
8890 // We should pick up the set of unqualified lookup results for operator
8891 // co_await during the initial parse.
8892 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8893 getSema().getCurScope(), E->getKeywordLoc());
8894
8895 // Always rebuild; we don't know if this needs to be injected into a new
8896 // context or if the promise type has changed.
8897 return getDerived().RebuildCoawaitExpr(
8898 E->getKeywordLoc(), Operand.get(),
8899 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8900 }
8901
8902 template <typename Derived>
8903 ExprResult
TransformDependentCoawaitExpr(DependentCoawaitExpr * E)8904 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8905 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8906 /*NotCopyInit*/ false);
8907 if (OperandResult.isInvalid())
8908 return ExprError();
8909
8910 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8911 E->getOperatorCoawaitLookup());
8912
8913 if (LookupResult.isInvalid())
8914 return ExprError();
8915
8916 // Always rebuild; we don't know if this needs to be injected into a new
8917 // context or if the promise type has changed.
8918 return getDerived().RebuildDependentCoawaitExpr(
8919 E->getKeywordLoc(), OperandResult.get(),
8920 cast<UnresolvedLookupExpr>(LookupResult.get()));
8921 }
8922
8923 template<typename Derived>
8924 ExprResult
TransformCoyieldExpr(CoyieldExpr * E)8925 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8926 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8927 /*NotCopyInit*/false);
8928 if (Result.isInvalid())
8929 return ExprError();
8930
8931 // Always rebuild; we don't know if this needs to be injected into a new
8932 // context or if the promise type has changed.
8933 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8934 }
8935
8936 // Objective-C Statements.
8937
8938 template<typename Derived>
8939 StmtResult
TransformObjCAtTryStmt(ObjCAtTryStmt * S)8940 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8941 // Transform the body of the @try.
8942 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8943 if (TryBody.isInvalid())
8944 return StmtError();
8945
8946 // Transform the @catch statements (if present).
8947 bool AnyCatchChanged = false;
8948 SmallVector<Stmt*, 8> CatchStmts;
8949 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8950 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8951 if (Catch.isInvalid())
8952 return StmtError();
8953 if (Catch.get() != S->getCatchStmt(I))
8954 AnyCatchChanged = true;
8955 CatchStmts.push_back(Catch.get());
8956 }
8957
8958 // Transform the @finally statement (if present).
8959 StmtResult Finally;
8960 if (S->getFinallyStmt()) {
8961 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8962 if (Finally.isInvalid())
8963 return StmtError();
8964 }
8965
8966 // If nothing changed, just retain this statement.
8967 if (!getDerived().AlwaysRebuild() &&
8968 TryBody.get() == S->getTryBody() &&
8969 !AnyCatchChanged &&
8970 Finally.get() == S->getFinallyStmt())
8971 return S;
8972
8973 // Build a new statement.
8974 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8975 CatchStmts, Finally.get());
8976 }
8977
8978 template<typename Derived>
8979 StmtResult
TransformObjCAtCatchStmt(ObjCAtCatchStmt * S)8980 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8981 // Transform the @catch parameter, if there is one.
8982 VarDecl *Var = nullptr;
8983 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8984 TypeSourceInfo *TSInfo = nullptr;
8985 if (FromVar->getTypeSourceInfo()) {
8986 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8987 if (!TSInfo)
8988 return StmtError();
8989 }
8990
8991 QualType T;
8992 if (TSInfo)
8993 T = TSInfo->getType();
8994 else {
8995 T = getDerived().TransformType(FromVar->getType());
8996 if (T.isNull())
8997 return StmtError();
8998 }
8999
9000 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9001 if (!Var)
9002 return StmtError();
9003 }
9004
9005 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9006 if (Body.isInvalid())
9007 return StmtError();
9008
9009 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9010 S->getRParenLoc(),
9011 Var, Body.get());
9012 }
9013
9014 template<typename Derived>
9015 StmtResult
TransformObjCAtFinallyStmt(ObjCAtFinallyStmt * S)9016 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9017 // Transform the body.
9018 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9019 if (Body.isInvalid())
9020 return StmtError();
9021
9022 // If nothing changed, just retain this statement.
9023 if (!getDerived().AlwaysRebuild() &&
9024 Body.get() == S->getFinallyBody())
9025 return S;
9026
9027 // Build a new statement.
9028 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9029 Body.get());
9030 }
9031
9032 template<typename Derived>
9033 StmtResult
TransformObjCAtThrowStmt(ObjCAtThrowStmt * S)9034 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9035 ExprResult Operand;
9036 if (S->getThrowExpr()) {
9037 Operand = getDerived().TransformExpr(S->getThrowExpr());
9038 if (Operand.isInvalid())
9039 return StmtError();
9040 }
9041
9042 if (!getDerived().AlwaysRebuild() &&
9043 Operand.get() == S->getThrowExpr())
9044 return S;
9045
9046 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9047 }
9048
9049 template<typename Derived>
9050 StmtResult
TransformObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt * S)9051 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9052 ObjCAtSynchronizedStmt *S) {
9053 // Transform the object we are locking.
9054 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9055 if (Object.isInvalid())
9056 return StmtError();
9057 Object =
9058 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9059 Object.get());
9060 if (Object.isInvalid())
9061 return StmtError();
9062
9063 // Transform the body.
9064 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9065 if (Body.isInvalid())
9066 return StmtError();
9067
9068 // If nothing change, just retain the current statement.
9069 if (!getDerived().AlwaysRebuild() &&
9070 Object.get() == S->getSynchExpr() &&
9071 Body.get() == S->getSynchBody())
9072 return S;
9073
9074 // Build a new statement.
9075 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9076 Object.get(), Body.get());
9077 }
9078
9079 template<typename Derived>
9080 StmtResult
TransformObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt * S)9081 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9082 ObjCAutoreleasePoolStmt *S) {
9083 // Transform the body.
9084 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9085 if (Body.isInvalid())
9086 return StmtError();
9087
9088 // If nothing changed, just retain this statement.
9089 if (!getDerived().AlwaysRebuild() &&
9090 Body.get() == S->getSubStmt())
9091 return S;
9092
9093 // Build a new statement.
9094 return getDerived().RebuildObjCAutoreleasePoolStmt(
9095 S->getAtLoc(), Body.get());
9096 }
9097
9098 template<typename Derived>
9099 StmtResult
TransformObjCForCollectionStmt(ObjCForCollectionStmt * S)9100 TreeTransform<Derived>::TransformObjCForCollectionStmt(
9101 ObjCForCollectionStmt *S) {
9102 // Transform the element statement.
9103 StmtResult Element = getDerived().TransformStmt(
9104 S->getElement(), StmtDiscardKind::NotDiscarded);
9105 if (Element.isInvalid())
9106 return StmtError();
9107
9108 // Transform the collection expression.
9109 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9110 if (Collection.isInvalid())
9111 return StmtError();
9112
9113 // Transform the body.
9114 StmtResult Body = getDerived().TransformStmt(S->getBody());
9115 if (Body.isInvalid())
9116 return StmtError();
9117
9118 // If nothing changed, just retain this statement.
9119 if (!getDerived().AlwaysRebuild() &&
9120 Element.get() == S->getElement() &&
9121 Collection.get() == S->getCollection() &&
9122 Body.get() == S->getBody())
9123 return S;
9124
9125 // Build a new statement.
9126 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9127 Element.get(),
9128 Collection.get(),
9129 S->getRParenLoc(),
9130 Body.get());
9131 }
9132
9133 template <typename Derived>
TransformCXXCatchStmt(CXXCatchStmt * S)9134 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9135 // Transform the exception declaration, if any.
9136 VarDecl *Var = nullptr;
9137 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9138 TypeSourceInfo *T =
9139 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9140 if (!T)
9141 return StmtError();
9142
9143 Var = getDerived().RebuildExceptionDecl(
9144 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9145 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9146 if (!Var || Var->isInvalidDecl())
9147 return StmtError();
9148 }
9149
9150 // Transform the actual exception handler.
9151 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9152 if (Handler.isInvalid())
9153 return StmtError();
9154
9155 if (!getDerived().AlwaysRebuild() && !Var &&
9156 Handler.get() == S->getHandlerBlock())
9157 return S;
9158
9159 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9160 }
9161
9162 template <typename Derived>
TransformCXXTryStmt(CXXTryStmt * S)9163 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9164 // Transform the try block itself.
9165 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9166 if (TryBlock.isInvalid())
9167 return StmtError();
9168
9169 // Transform the handlers.
9170 bool HandlerChanged = false;
9171 SmallVector<Stmt *, 8> Handlers;
9172 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9173 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
9174 if (Handler.isInvalid())
9175 return StmtError();
9176
9177 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
9178 Handlers.push_back(Handler.getAs<Stmt>());
9179 }
9180
9181 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9182
9183 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9184 !HandlerChanged)
9185 return S;
9186
9187 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9188 Handlers);
9189 }
9190
9191 template<typename Derived>
9192 StmtResult
TransformCXXForRangeStmt(CXXForRangeStmt * S)9193 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9194 EnterExpressionEvaluationContext ForRangeInitContext(
9195 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9196 /*LambdaContextDecl=*/nullptr,
9197 Sema::ExpressionEvaluationContextRecord::EK_Other,
9198 getSema().getLangOpts().CPlusPlus23);
9199
9200 // P2718R0 - Lifetime extension in range-based for loops.
9201 if (getSema().getLangOpts().CPlusPlus23) {
9202 auto &LastRecord = getSema().currentEvaluationContext();
9203 LastRecord.InLifetimeExtendingContext = true;
9204 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9205 }
9206 StmtResult Init =
9207 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9208 if (Init.isInvalid())
9209 return StmtError();
9210
9211 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9212 if (Range.isInvalid())
9213 return StmtError();
9214
9215 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9216 assert(getSema().getLangOpts().CPlusPlus23 ||
9217 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9218 auto ForRangeLifetimeExtendTemps =
9219 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9220
9221 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9222 if (Begin.isInvalid())
9223 return StmtError();
9224 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9225 if (End.isInvalid())
9226 return StmtError();
9227
9228 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9229 if (Cond.isInvalid())
9230 return StmtError();
9231 if (Cond.get())
9232 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
9233 if (Cond.isInvalid())
9234 return StmtError();
9235 if (Cond.get())
9236 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
9237
9238 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9239 if (Inc.isInvalid())
9240 return StmtError();
9241 if (Inc.get())
9242 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
9243
9244 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9245 if (LoopVar.isInvalid())
9246 return StmtError();
9247
9248 StmtResult NewStmt = S;
9249 if (getDerived().AlwaysRebuild() ||
9250 Init.get() != S->getInit() ||
9251 Range.get() != S->getRangeStmt() ||
9252 Begin.get() != S->getBeginStmt() ||
9253 End.get() != S->getEndStmt() ||
9254 Cond.get() != S->getCond() ||
9255 Inc.get() != S->getInc() ||
9256 LoopVar.get() != S->getLoopVarStmt()) {
9257 NewStmt = getDerived().RebuildCXXForRangeStmt(
9258 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9259 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9260 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9261 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9262 // Might not have attached any initializer to the loop variable.
9263 getSema().ActOnInitializerError(
9264 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
9265 return StmtError();
9266 }
9267 }
9268
9269 // OpenACC Restricts a while-loop inside of certain construct/clause
9270 // combinations, so diagnose that here in OpenACC mode.
9271 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9272 SemaRef.OpenACC().ActOnRangeForStmtBegin(S->getBeginLoc(), S, NewStmt.get());
9273
9274 StmtResult Body = getDerived().TransformStmt(S->getBody());
9275 if (Body.isInvalid())
9276 return StmtError();
9277
9278 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
9279
9280 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9281 // it now so we have a new statement to attach the body to.
9282 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9283 NewStmt = getDerived().RebuildCXXForRangeStmt(
9284 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9285 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9286 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9287 if (NewStmt.isInvalid())
9288 return StmtError();
9289 }
9290
9291 if (NewStmt.get() == S)
9292 return S;
9293
9294 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
9295 }
9296
9297 template<typename Derived>
9298 StmtResult
TransformMSDependentExistsStmt(MSDependentExistsStmt * S)9299 TreeTransform<Derived>::TransformMSDependentExistsStmt(
9300 MSDependentExistsStmt *S) {
9301 // Transform the nested-name-specifier, if any.
9302 NestedNameSpecifierLoc QualifierLoc;
9303 if (S->getQualifierLoc()) {
9304 QualifierLoc
9305 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9306 if (!QualifierLoc)
9307 return StmtError();
9308 }
9309
9310 // Transform the declaration name.
9311 DeclarationNameInfo NameInfo = S->getNameInfo();
9312 if (NameInfo.getName()) {
9313 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9314 if (!NameInfo.getName())
9315 return StmtError();
9316 }
9317
9318 // Check whether anything changed.
9319 if (!getDerived().AlwaysRebuild() &&
9320 QualifierLoc == S->getQualifierLoc() &&
9321 NameInfo.getName() == S->getNameInfo().getName())
9322 return S;
9323
9324 // Determine whether this name exists, if we can.
9325 CXXScopeSpec SS;
9326 SS.Adopt(QualifierLoc);
9327 bool Dependent = false;
9328 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9329 case IfExistsResult::Exists:
9330 if (S->isIfExists())
9331 break;
9332
9333 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9334
9335 case IfExistsResult::DoesNotExist:
9336 if (S->isIfNotExists())
9337 break;
9338
9339 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9340
9341 case IfExistsResult::Dependent:
9342 Dependent = true;
9343 break;
9344
9345 case IfExistsResult::Error:
9346 return StmtError();
9347 }
9348
9349 // We need to continue with the instantiation, so do so now.
9350 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9351 if (SubStmt.isInvalid())
9352 return StmtError();
9353
9354 // If we have resolved the name, just transform to the substatement.
9355 if (!Dependent)
9356 return SubStmt;
9357
9358 // The name is still dependent, so build a dependent expression again.
9359 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9360 S->isIfExists(),
9361 QualifierLoc,
9362 NameInfo,
9363 SubStmt.get());
9364 }
9365
9366 template<typename Derived>
9367 ExprResult
TransformMSPropertyRefExpr(MSPropertyRefExpr * E)9368 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9369 NestedNameSpecifierLoc QualifierLoc;
9370 if (E->getQualifierLoc()) {
9371 QualifierLoc
9372 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9373 if (!QualifierLoc)
9374 return ExprError();
9375 }
9376
9377 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9378 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9379 if (!PD)
9380 return ExprError();
9381
9382 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9383 if (Base.isInvalid())
9384 return ExprError();
9385
9386 return new (SemaRef.getASTContext())
9387 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9388 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9389 QualifierLoc, E->getMemberLoc());
9390 }
9391
9392 template <typename Derived>
TransformMSPropertySubscriptExpr(MSPropertySubscriptExpr * E)9393 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9394 MSPropertySubscriptExpr *E) {
9395 auto BaseRes = getDerived().TransformExpr(E->getBase());
9396 if (BaseRes.isInvalid())
9397 return ExprError();
9398 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9399 if (IdxRes.isInvalid())
9400 return ExprError();
9401
9402 if (!getDerived().AlwaysRebuild() &&
9403 BaseRes.get() == E->getBase() &&
9404 IdxRes.get() == E->getIdx())
9405 return E;
9406
9407 return getDerived().RebuildArraySubscriptExpr(
9408 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9409 }
9410
9411 template <typename Derived>
TransformSEHTryStmt(SEHTryStmt * S)9412 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9413 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9414 if (TryBlock.isInvalid())
9415 return StmtError();
9416
9417 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9418 if (Handler.isInvalid())
9419 return StmtError();
9420
9421 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9422 Handler.get() == S->getHandler())
9423 return S;
9424
9425 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9426 TryBlock.get(), Handler.get());
9427 }
9428
9429 template <typename Derived>
TransformSEHFinallyStmt(SEHFinallyStmt * S)9430 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9431 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9432 if (Block.isInvalid())
9433 return StmtError();
9434
9435 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9436 }
9437
9438 template <typename Derived>
TransformSEHExceptStmt(SEHExceptStmt * S)9439 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9440 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9441 if (FilterExpr.isInvalid())
9442 return StmtError();
9443
9444 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9445 if (Block.isInvalid())
9446 return StmtError();
9447
9448 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9449 Block.get());
9450 }
9451
9452 template <typename Derived>
TransformSEHHandler(Stmt * Handler)9453 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9454 if (isa<SEHFinallyStmt>(Handler))
9455 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9456 else
9457 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9458 }
9459
9460 template<typename Derived>
9461 StmtResult
TransformSEHLeaveStmt(SEHLeaveStmt * S)9462 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9463 return S;
9464 }
9465
9466 //===----------------------------------------------------------------------===//
9467 // OpenMP directive transformation
9468 //===----------------------------------------------------------------------===//
9469
9470 template <typename Derived>
9471 StmtResult
TransformOMPCanonicalLoop(OMPCanonicalLoop * L)9472 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9473 // OMPCanonicalLoops are eliminated during transformation, since they will be
9474 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9475 // after transformation.
9476 return getDerived().TransformStmt(L->getLoopStmt());
9477 }
9478
9479 template <typename Derived>
TransformOMPExecutableDirective(OMPExecutableDirective * D)9480 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9481 OMPExecutableDirective *D) {
9482
9483 // Transform the clauses
9484 llvm::SmallVector<OMPClause *, 16> TClauses;
9485 ArrayRef<OMPClause *> Clauses = D->clauses();
9486 TClauses.reserve(Clauses.size());
9487 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9488 I != E; ++I) {
9489 if (*I) {
9490 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9491 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9492 getDerived().getSema().OpenMP().EndOpenMPClause();
9493 if (Clause)
9494 TClauses.push_back(Clause);
9495 } else {
9496 TClauses.push_back(nullptr);
9497 }
9498 }
9499 StmtResult AssociatedStmt;
9500 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9501 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9502 D->getDirectiveKind(),
9503 /*CurScope=*/nullptr);
9504 StmtResult Body;
9505 {
9506 Sema::CompoundScopeRAII CompoundScope(getSema());
9507 Stmt *CS;
9508 if (D->getDirectiveKind() == OMPD_atomic ||
9509 D->getDirectiveKind() == OMPD_critical ||
9510 D->getDirectiveKind() == OMPD_section ||
9511 D->getDirectiveKind() == OMPD_master)
9512 CS = D->getAssociatedStmt();
9513 else
9514 CS = D->getRawStmt();
9515 Body = getDerived().TransformStmt(CS);
9516 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
9517 getSema().getLangOpts().OpenMPIRBuilder)
9518 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9519 }
9520 AssociatedStmt =
9521 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9522 if (AssociatedStmt.isInvalid()) {
9523 return StmtError();
9524 }
9525 }
9526 if (TClauses.size() != Clauses.size()) {
9527 return StmtError();
9528 }
9529
9530 // Transform directive name for 'omp critical' directive.
9531 DeclarationNameInfo DirName;
9532 if (D->getDirectiveKind() == OMPD_critical) {
9533 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9534 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9535 }
9536 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9537 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9538 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9539 } else if (D->getDirectiveKind() == OMPD_cancel) {
9540 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9541 }
9542
9543 return getDerived().RebuildOMPExecutableDirective(
9544 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9545 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9546 }
9547
9548 /// This is mostly the same as above, but allows 'informational' class
9549 /// directives when rebuilding the stmt. It still takes an
9550 /// OMPExecutableDirective-type argument because we're reusing that as the
9551 /// superclass for the 'assume' directive at present, instead of defining a
9552 /// mostly-identical OMPInformationalDirective parent class.
9553 template <typename Derived>
TransformOMPInformationalDirective(OMPExecutableDirective * D)9554 StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9555 OMPExecutableDirective *D) {
9556
9557 // Transform the clauses
9558 llvm::SmallVector<OMPClause *, 16> TClauses;
9559 ArrayRef<OMPClause *> Clauses = D->clauses();
9560 TClauses.reserve(Clauses.size());
9561 for (OMPClause *C : Clauses) {
9562 if (C) {
9563 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9564 OMPClause *Clause = getDerived().TransformOMPClause(C);
9565 getDerived().getSema().OpenMP().EndOpenMPClause();
9566 if (Clause)
9567 TClauses.push_back(Clause);
9568 } else {
9569 TClauses.push_back(nullptr);
9570 }
9571 }
9572 StmtResult AssociatedStmt;
9573 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9574 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9575 D->getDirectiveKind(),
9576 /*CurScope=*/nullptr);
9577 StmtResult Body;
9578 {
9579 Sema::CompoundScopeRAII CompoundScope(getSema());
9580 assert(D->getDirectiveKind() == OMPD_assume &&
9581 "Unexpected informational directive");
9582 Stmt *CS = D->getAssociatedStmt();
9583 Body = getDerived().TransformStmt(CS);
9584 }
9585 AssociatedStmt =
9586 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9587 if (AssociatedStmt.isInvalid())
9588 return StmtError();
9589 }
9590 if (TClauses.size() != Clauses.size())
9591 return StmtError();
9592
9593 DeclarationNameInfo DirName;
9594
9595 return getDerived().RebuildOMPInformationalDirective(
9596 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9597 D->getBeginLoc(), D->getEndLoc());
9598 }
9599
9600 template <typename Derived>
9601 StmtResult
TransformOMPMetaDirective(OMPMetaDirective * D)9602 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9603 // TODO: Fix This
9604 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9605 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9606 << getOpenMPDirectiveName(D->getDirectiveKind(), OMPVersion);
9607 return StmtError();
9608 }
9609
9610 template <typename Derived>
9611 StmtResult
TransformOMPParallelDirective(OMPParallelDirective * D)9612 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9613 DeclarationNameInfo DirName;
9614 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9615 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9616 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9617 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9618 return Res;
9619 }
9620
9621 template <typename Derived>
9622 StmtResult
TransformOMPSimdDirective(OMPSimdDirective * D)9623 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9624 DeclarationNameInfo DirName;
9625 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9626 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9627 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9628 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9629 return Res;
9630 }
9631
9632 template <typename Derived>
9633 StmtResult
TransformOMPTileDirective(OMPTileDirective * D)9634 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9635 DeclarationNameInfo DirName;
9636 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9637 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9638 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9639 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9640 return Res;
9641 }
9642
9643 template <typename Derived>
9644 StmtResult
TransformOMPStripeDirective(OMPStripeDirective * D)9645 TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9646 DeclarationNameInfo DirName;
9647 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9648 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9649 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9650 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9651 return Res;
9652 }
9653
9654 template <typename Derived>
9655 StmtResult
TransformOMPUnrollDirective(OMPUnrollDirective * D)9656 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9657 DeclarationNameInfo DirName;
9658 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9659 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9660 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9661 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9662 return Res;
9663 }
9664
9665 template <typename Derived>
9666 StmtResult
TransformOMPReverseDirective(OMPReverseDirective * D)9667 TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9668 DeclarationNameInfo DirName;
9669 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9670 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9671 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9672 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9673 return Res;
9674 }
9675
9676 template <typename Derived>
TransformOMPInterchangeDirective(OMPInterchangeDirective * D)9677 StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9678 OMPInterchangeDirective *D) {
9679 DeclarationNameInfo DirName;
9680 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9681 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9682 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9683 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9684 return Res;
9685 }
9686
9687 template <typename Derived>
9688 StmtResult
TransformOMPForDirective(OMPForDirective * D)9689 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9690 DeclarationNameInfo DirName;
9691 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9692 OMPD_for, DirName, nullptr, D->getBeginLoc());
9693 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9694 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9695 return Res;
9696 }
9697
9698 template <typename Derived>
9699 StmtResult
TransformOMPForSimdDirective(OMPForSimdDirective * D)9700 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9701 DeclarationNameInfo DirName;
9702 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9703 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9704 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9705 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9706 return Res;
9707 }
9708
9709 template <typename Derived>
9710 StmtResult
TransformOMPSectionsDirective(OMPSectionsDirective * D)9711 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9712 DeclarationNameInfo DirName;
9713 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9714 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9715 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9716 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9717 return Res;
9718 }
9719
9720 template <typename Derived>
9721 StmtResult
TransformOMPSectionDirective(OMPSectionDirective * D)9722 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9723 DeclarationNameInfo DirName;
9724 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9725 OMPD_section, DirName, nullptr, D->getBeginLoc());
9726 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9727 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9728 return Res;
9729 }
9730
9731 template <typename Derived>
9732 StmtResult
TransformOMPScopeDirective(OMPScopeDirective * D)9733 TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9734 DeclarationNameInfo DirName;
9735 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9736 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9737 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9738 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9739 return Res;
9740 }
9741
9742 template <typename Derived>
9743 StmtResult
TransformOMPSingleDirective(OMPSingleDirective * D)9744 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9745 DeclarationNameInfo DirName;
9746 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9747 OMPD_single, DirName, nullptr, D->getBeginLoc());
9748 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9749 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9750 return Res;
9751 }
9752
9753 template <typename Derived>
9754 StmtResult
TransformOMPMasterDirective(OMPMasterDirective * D)9755 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9756 DeclarationNameInfo DirName;
9757 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9758 OMPD_master, DirName, nullptr, D->getBeginLoc());
9759 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9760 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9761 return Res;
9762 }
9763
9764 template <typename Derived>
9765 StmtResult
TransformOMPCriticalDirective(OMPCriticalDirective * D)9766 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9767 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9768 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9769 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9770 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9771 return Res;
9772 }
9773
9774 template <typename Derived>
TransformOMPParallelForDirective(OMPParallelForDirective * D)9775 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9776 OMPParallelForDirective *D) {
9777 DeclarationNameInfo DirName;
9778 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9779 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9780 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9781 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9782 return Res;
9783 }
9784
9785 template <typename Derived>
TransformOMPParallelForSimdDirective(OMPParallelForSimdDirective * D)9786 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9787 OMPParallelForSimdDirective *D) {
9788 DeclarationNameInfo DirName;
9789 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9790 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9791 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9792 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9793 return Res;
9794 }
9795
9796 template <typename Derived>
TransformOMPParallelMasterDirective(OMPParallelMasterDirective * D)9797 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9798 OMPParallelMasterDirective *D) {
9799 DeclarationNameInfo DirName;
9800 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9801 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9802 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9803 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9804 return Res;
9805 }
9806
9807 template <typename Derived>
TransformOMPParallelMaskedDirective(OMPParallelMaskedDirective * D)9808 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9809 OMPParallelMaskedDirective *D) {
9810 DeclarationNameInfo DirName;
9811 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9812 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9813 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9814 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9815 return Res;
9816 }
9817
9818 template <typename Derived>
TransformOMPParallelSectionsDirective(OMPParallelSectionsDirective * D)9819 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9820 OMPParallelSectionsDirective *D) {
9821 DeclarationNameInfo DirName;
9822 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9823 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9824 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9825 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9826 return Res;
9827 }
9828
9829 template <typename Derived>
9830 StmtResult
TransformOMPTaskDirective(OMPTaskDirective * D)9831 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9832 DeclarationNameInfo DirName;
9833 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9834 OMPD_task, DirName, nullptr, D->getBeginLoc());
9835 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9836 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9837 return Res;
9838 }
9839
9840 template <typename Derived>
TransformOMPTaskyieldDirective(OMPTaskyieldDirective * D)9841 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9842 OMPTaskyieldDirective *D) {
9843 DeclarationNameInfo DirName;
9844 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9845 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9846 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9847 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9848 return Res;
9849 }
9850
9851 template <typename Derived>
9852 StmtResult
TransformOMPBarrierDirective(OMPBarrierDirective * D)9853 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9854 DeclarationNameInfo DirName;
9855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9856 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9857 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9858 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9859 return Res;
9860 }
9861
9862 template <typename Derived>
9863 StmtResult
TransformOMPTaskwaitDirective(OMPTaskwaitDirective * D)9864 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9865 DeclarationNameInfo DirName;
9866 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9867 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9868 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9869 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9870 return Res;
9871 }
9872
9873 template <typename Derived>
9874 StmtResult
TransformOMPAssumeDirective(OMPAssumeDirective * D)9875 TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9876 DeclarationNameInfo DirName;
9877 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9878 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9879 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9880 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9881 return Res;
9882 }
9883
9884 template <typename Derived>
9885 StmtResult
TransformOMPErrorDirective(OMPErrorDirective * D)9886 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9887 DeclarationNameInfo DirName;
9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9889 OMPD_error, DirName, nullptr, D->getBeginLoc());
9890 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9891 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9892 return Res;
9893 }
9894
9895 template <typename Derived>
TransformOMPTaskgroupDirective(OMPTaskgroupDirective * D)9896 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9897 OMPTaskgroupDirective *D) {
9898 DeclarationNameInfo DirName;
9899 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9900 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9901 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9902 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9903 return Res;
9904 }
9905
9906 template <typename Derived>
9907 StmtResult
TransformOMPFlushDirective(OMPFlushDirective * D)9908 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9909 DeclarationNameInfo DirName;
9910 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9911 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9912 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9913 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9914 return Res;
9915 }
9916
9917 template <typename Derived>
9918 StmtResult
TransformOMPDepobjDirective(OMPDepobjDirective * D)9919 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9920 DeclarationNameInfo DirName;
9921 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9922 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9923 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9924 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9925 return Res;
9926 }
9927
9928 template <typename Derived>
9929 StmtResult
TransformOMPScanDirective(OMPScanDirective * D)9930 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9931 DeclarationNameInfo DirName;
9932 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9933 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9934 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9935 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9936 return Res;
9937 }
9938
9939 template <typename Derived>
9940 StmtResult
TransformOMPOrderedDirective(OMPOrderedDirective * D)9941 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9942 DeclarationNameInfo DirName;
9943 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9944 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9945 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9946 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9947 return Res;
9948 }
9949
9950 template <typename Derived>
9951 StmtResult
TransformOMPAtomicDirective(OMPAtomicDirective * D)9952 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9953 DeclarationNameInfo DirName;
9954 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9955 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9956 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9957 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9958 return Res;
9959 }
9960
9961 template <typename Derived>
9962 StmtResult
TransformOMPTargetDirective(OMPTargetDirective * D)9963 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9964 DeclarationNameInfo DirName;
9965 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9966 OMPD_target, DirName, nullptr, D->getBeginLoc());
9967 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9968 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9969 return Res;
9970 }
9971
9972 template <typename Derived>
TransformOMPTargetDataDirective(OMPTargetDataDirective * D)9973 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9974 OMPTargetDataDirective *D) {
9975 DeclarationNameInfo DirName;
9976 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9977 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9978 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9979 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9980 return Res;
9981 }
9982
9983 template <typename Derived>
TransformOMPTargetEnterDataDirective(OMPTargetEnterDataDirective * D)9984 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9985 OMPTargetEnterDataDirective *D) {
9986 DeclarationNameInfo DirName;
9987 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9988 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9989 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9990 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9991 return Res;
9992 }
9993
9994 template <typename Derived>
TransformOMPTargetExitDataDirective(OMPTargetExitDataDirective * D)9995 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9996 OMPTargetExitDataDirective *D) {
9997 DeclarationNameInfo DirName;
9998 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9999 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10000 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10001 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10002 return Res;
10003 }
10004
10005 template <typename Derived>
TransformOMPTargetParallelDirective(OMPTargetParallelDirective * D)10006 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10007 OMPTargetParallelDirective *D) {
10008 DeclarationNameInfo DirName;
10009 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10010 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10011 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10012 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10013 return Res;
10014 }
10015
10016 template <typename Derived>
TransformOMPTargetParallelForDirective(OMPTargetParallelForDirective * D)10017 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10018 OMPTargetParallelForDirective *D) {
10019 DeclarationNameInfo DirName;
10020 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10021 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10022 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10023 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10024 return Res;
10025 }
10026
10027 template <typename Derived>
TransformOMPTargetUpdateDirective(OMPTargetUpdateDirective * D)10028 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10029 OMPTargetUpdateDirective *D) {
10030 DeclarationNameInfo DirName;
10031 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10032 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10033 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10034 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10035 return Res;
10036 }
10037
10038 template <typename Derived>
10039 StmtResult
TransformOMPTeamsDirective(OMPTeamsDirective * D)10040 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10041 DeclarationNameInfo DirName;
10042 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10043 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10044 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10045 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10046 return Res;
10047 }
10048
10049 template <typename Derived>
TransformOMPCancellationPointDirective(OMPCancellationPointDirective * D)10050 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10051 OMPCancellationPointDirective *D) {
10052 DeclarationNameInfo DirName;
10053 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10054 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10055 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10056 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10057 return Res;
10058 }
10059
10060 template <typename Derived>
10061 StmtResult
TransformOMPCancelDirective(OMPCancelDirective * D)10062 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10063 DeclarationNameInfo DirName;
10064 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10065 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10066 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10067 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10068 return Res;
10069 }
10070
10071 template <typename Derived>
10072 StmtResult
TransformOMPTaskLoopDirective(OMPTaskLoopDirective * D)10073 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10074 DeclarationNameInfo DirName;
10075 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10076 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10077 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10078 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10079 return Res;
10080 }
10081
10082 template <typename Derived>
TransformOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective * D)10083 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10084 OMPTaskLoopSimdDirective *D) {
10085 DeclarationNameInfo DirName;
10086 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10087 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10088 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10089 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10090 return Res;
10091 }
10092
10093 template <typename Derived>
TransformOMPMasterTaskLoopDirective(OMPMasterTaskLoopDirective * D)10094 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10095 OMPMasterTaskLoopDirective *D) {
10096 DeclarationNameInfo DirName;
10097 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10098 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10099 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10100 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10101 return Res;
10102 }
10103
10104 template <typename Derived>
TransformOMPMaskedTaskLoopDirective(OMPMaskedTaskLoopDirective * D)10105 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10106 OMPMaskedTaskLoopDirective *D) {
10107 DeclarationNameInfo DirName;
10108 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10109 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10110 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10111 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10112 return Res;
10113 }
10114
10115 template <typename Derived>
TransformOMPMasterTaskLoopSimdDirective(OMPMasterTaskLoopSimdDirective * D)10116 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10117 OMPMasterTaskLoopSimdDirective *D) {
10118 DeclarationNameInfo DirName;
10119 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10120 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10121 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10122 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10123 return Res;
10124 }
10125
10126 template <typename Derived>
TransformOMPMaskedTaskLoopSimdDirective(OMPMaskedTaskLoopSimdDirective * D)10127 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10128 OMPMaskedTaskLoopSimdDirective *D) {
10129 DeclarationNameInfo DirName;
10130 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10131 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10132 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10133 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10134 return Res;
10135 }
10136
10137 template <typename Derived>
TransformOMPParallelMasterTaskLoopDirective(OMPParallelMasterTaskLoopDirective * D)10138 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10139 OMPParallelMasterTaskLoopDirective *D) {
10140 DeclarationNameInfo DirName;
10141 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10142 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10143 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10144 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10145 return Res;
10146 }
10147
10148 template <typename Derived>
TransformOMPParallelMaskedTaskLoopDirective(OMPParallelMaskedTaskLoopDirective * D)10149 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10150 OMPParallelMaskedTaskLoopDirective *D) {
10151 DeclarationNameInfo DirName;
10152 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10153 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10154 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10155 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10156 return Res;
10157 }
10158
10159 template <typename Derived>
10160 StmtResult
TransformOMPParallelMasterTaskLoopSimdDirective(OMPParallelMasterTaskLoopSimdDirective * D)10161 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10162 OMPParallelMasterTaskLoopSimdDirective *D) {
10163 DeclarationNameInfo DirName;
10164 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10165 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10166 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10167 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10168 return Res;
10169 }
10170
10171 template <typename Derived>
10172 StmtResult
TransformOMPParallelMaskedTaskLoopSimdDirective(OMPParallelMaskedTaskLoopSimdDirective * D)10173 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10174 OMPParallelMaskedTaskLoopSimdDirective *D) {
10175 DeclarationNameInfo DirName;
10176 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10177 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10178 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10179 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10180 return Res;
10181 }
10182
10183 template <typename Derived>
TransformOMPDistributeDirective(OMPDistributeDirective * D)10184 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10185 OMPDistributeDirective *D) {
10186 DeclarationNameInfo DirName;
10187 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10188 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10189 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10190 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10191 return Res;
10192 }
10193
10194 template <typename Derived>
TransformOMPDistributeParallelForDirective(OMPDistributeParallelForDirective * D)10195 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10196 OMPDistributeParallelForDirective *D) {
10197 DeclarationNameInfo DirName;
10198 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10199 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10200 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10201 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10202 return Res;
10203 }
10204
10205 template <typename Derived>
10206 StmtResult
TransformOMPDistributeParallelForSimdDirective(OMPDistributeParallelForSimdDirective * D)10207 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10208 OMPDistributeParallelForSimdDirective *D) {
10209 DeclarationNameInfo DirName;
10210 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10211 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10212 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10213 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10214 return Res;
10215 }
10216
10217 template <typename Derived>
TransformOMPDistributeSimdDirective(OMPDistributeSimdDirective * D)10218 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10219 OMPDistributeSimdDirective *D) {
10220 DeclarationNameInfo DirName;
10221 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10222 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10223 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10224 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10225 return Res;
10226 }
10227
10228 template <typename Derived>
TransformOMPTargetParallelForSimdDirective(OMPTargetParallelForSimdDirective * D)10229 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10230 OMPTargetParallelForSimdDirective *D) {
10231 DeclarationNameInfo DirName;
10232 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10233 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10234 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10235 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10236 return Res;
10237 }
10238
10239 template <typename Derived>
TransformOMPTargetSimdDirective(OMPTargetSimdDirective * D)10240 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10241 OMPTargetSimdDirective *D) {
10242 DeclarationNameInfo DirName;
10243 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10244 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10245 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10246 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10247 return Res;
10248 }
10249
10250 template <typename Derived>
TransformOMPTeamsDistributeDirective(OMPTeamsDistributeDirective * D)10251 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10252 OMPTeamsDistributeDirective *D) {
10253 DeclarationNameInfo DirName;
10254 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10255 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10256 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10257 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10258 return Res;
10259 }
10260
10261 template <typename Derived>
TransformOMPTeamsDistributeSimdDirective(OMPTeamsDistributeSimdDirective * D)10262 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10263 OMPTeamsDistributeSimdDirective *D) {
10264 DeclarationNameInfo DirName;
10265 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10266 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10267 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10268 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10269 return Res;
10270 }
10271
10272 template <typename Derived>
TransformOMPTeamsDistributeParallelForSimdDirective(OMPTeamsDistributeParallelForSimdDirective * D)10273 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10274 OMPTeamsDistributeParallelForSimdDirective *D) {
10275 DeclarationNameInfo DirName;
10276 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10277 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10278 D->getBeginLoc());
10279 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10280 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10281 return Res;
10282 }
10283
10284 template <typename Derived>
TransformOMPTeamsDistributeParallelForDirective(OMPTeamsDistributeParallelForDirective * D)10285 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10286 OMPTeamsDistributeParallelForDirective *D) {
10287 DeclarationNameInfo DirName;
10288 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10289 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10290 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10291 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10292 return Res;
10293 }
10294
10295 template <typename Derived>
TransformOMPTargetTeamsDirective(OMPTargetTeamsDirective * D)10296 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10297 OMPTargetTeamsDirective *D) {
10298 DeclarationNameInfo DirName;
10299 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10300 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10301 auto Res = getDerived().TransformOMPExecutableDirective(D);
10302 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10303 return Res;
10304 }
10305
10306 template <typename Derived>
TransformOMPTargetTeamsDistributeDirective(OMPTargetTeamsDistributeDirective * D)10307 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10308 OMPTargetTeamsDistributeDirective *D) {
10309 DeclarationNameInfo DirName;
10310 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10311 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10312 auto Res = getDerived().TransformOMPExecutableDirective(D);
10313 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10314 return Res;
10315 }
10316
10317 template <typename Derived>
10318 StmtResult
TransformOMPTargetTeamsDistributeParallelForDirective(OMPTargetTeamsDistributeParallelForDirective * D)10319 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10320 OMPTargetTeamsDistributeParallelForDirective *D) {
10321 DeclarationNameInfo DirName;
10322 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10323 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10324 D->getBeginLoc());
10325 auto Res = getDerived().TransformOMPExecutableDirective(D);
10326 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10327 return Res;
10328 }
10329
10330 template <typename Derived>
10331 StmtResult TreeTransform<Derived>::
TransformOMPTargetTeamsDistributeParallelForSimdDirective(OMPTargetTeamsDistributeParallelForSimdDirective * D)10332 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10333 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10334 DeclarationNameInfo DirName;
10335 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10336 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10337 D->getBeginLoc());
10338 auto Res = getDerived().TransformOMPExecutableDirective(D);
10339 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10340 return Res;
10341 }
10342
10343 template <typename Derived>
10344 StmtResult
TransformOMPTargetTeamsDistributeSimdDirective(OMPTargetTeamsDistributeSimdDirective * D)10345 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10346 OMPTargetTeamsDistributeSimdDirective *D) {
10347 DeclarationNameInfo DirName;
10348 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10349 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10350 auto Res = getDerived().TransformOMPExecutableDirective(D);
10351 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10352 return Res;
10353 }
10354
10355 template <typename Derived>
10356 StmtResult
TransformOMPInteropDirective(OMPInteropDirective * D)10357 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10358 DeclarationNameInfo DirName;
10359 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10360 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10361 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10362 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10363 return Res;
10364 }
10365
10366 template <typename Derived>
10367 StmtResult
TransformOMPDispatchDirective(OMPDispatchDirective * D)10368 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10369 DeclarationNameInfo DirName;
10370 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10371 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10372 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10373 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10374 return Res;
10375 }
10376
10377 template <typename Derived>
10378 StmtResult
TransformOMPMaskedDirective(OMPMaskedDirective * D)10379 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10380 DeclarationNameInfo DirName;
10381 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10382 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10383 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10384 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10385 return Res;
10386 }
10387
10388 template <typename Derived>
TransformOMPGenericLoopDirective(OMPGenericLoopDirective * D)10389 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10390 OMPGenericLoopDirective *D) {
10391 DeclarationNameInfo DirName;
10392 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10393 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10394 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10395 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10396 return Res;
10397 }
10398
10399 template <typename Derived>
TransformOMPTeamsGenericLoopDirective(OMPTeamsGenericLoopDirective * D)10400 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10401 OMPTeamsGenericLoopDirective *D) {
10402 DeclarationNameInfo DirName;
10403 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10404 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10405 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10406 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10407 return Res;
10408 }
10409
10410 template <typename Derived>
TransformOMPTargetTeamsGenericLoopDirective(OMPTargetTeamsGenericLoopDirective * D)10411 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10412 OMPTargetTeamsGenericLoopDirective *D) {
10413 DeclarationNameInfo DirName;
10414 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10415 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10416 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10417 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10418 return Res;
10419 }
10420
10421 template <typename Derived>
TransformOMPParallelGenericLoopDirective(OMPParallelGenericLoopDirective * D)10422 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10423 OMPParallelGenericLoopDirective *D) {
10424 DeclarationNameInfo DirName;
10425 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10426 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10427 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10428 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10429 return Res;
10430 }
10431
10432 template <typename Derived>
10433 StmtResult
TransformOMPTargetParallelGenericLoopDirective(OMPTargetParallelGenericLoopDirective * D)10434 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10435 OMPTargetParallelGenericLoopDirective *D) {
10436 DeclarationNameInfo DirName;
10437 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10438 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10439 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10440 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10441 return Res;
10442 }
10443
10444 //===----------------------------------------------------------------------===//
10445 // OpenMP clause transformation
10446 //===----------------------------------------------------------------------===//
10447 template <typename Derived>
TransformOMPIfClause(OMPIfClause * C)10448 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10449 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10450 if (Cond.isInvalid())
10451 return nullptr;
10452 return getDerived().RebuildOMPIfClause(
10453 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10454 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10455 }
10456
10457 template <typename Derived>
TransformOMPFinalClause(OMPFinalClause * C)10458 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10459 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10460 if (Cond.isInvalid())
10461 return nullptr;
10462 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10463 C->getLParenLoc(), C->getEndLoc());
10464 }
10465
10466 template <typename Derived>
10467 OMPClause *
TransformOMPNumThreadsClause(OMPNumThreadsClause * C)10468 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10469 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10470 if (NumThreads.isInvalid())
10471 return nullptr;
10472 return getDerived().RebuildOMPNumThreadsClause(
10473 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10474 C->getModifierLoc(), C->getEndLoc());
10475 }
10476
10477 template <typename Derived>
10478 OMPClause *
TransformOMPSafelenClause(OMPSafelenClause * C)10479 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10480 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10481 if (E.isInvalid())
10482 return nullptr;
10483 return getDerived().RebuildOMPSafelenClause(
10484 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10485 }
10486
10487 template <typename Derived>
10488 OMPClause *
TransformOMPAllocatorClause(OMPAllocatorClause * C)10489 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10490 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10491 if (E.isInvalid())
10492 return nullptr;
10493 return getDerived().RebuildOMPAllocatorClause(
10494 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10495 }
10496
10497 template <typename Derived>
10498 OMPClause *
TransformOMPSimdlenClause(OMPSimdlenClause * C)10499 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10500 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10501 if (E.isInvalid())
10502 return nullptr;
10503 return getDerived().RebuildOMPSimdlenClause(
10504 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10505 }
10506
10507 template <typename Derived>
TransformOMPSizesClause(OMPSizesClause * C)10508 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10509 SmallVector<Expr *, 4> TransformedSizes;
10510 TransformedSizes.reserve(C->getNumSizes());
10511 bool Changed = false;
10512 for (Expr *E : C->getSizesRefs()) {
10513 if (!E) {
10514 TransformedSizes.push_back(nullptr);
10515 continue;
10516 }
10517
10518 ExprResult T = getDerived().TransformExpr(E);
10519 if (T.isInvalid())
10520 return nullptr;
10521 if (E != T.get())
10522 Changed = true;
10523 TransformedSizes.push_back(T.get());
10524 }
10525
10526 if (!Changed && !getDerived().AlwaysRebuild())
10527 return C;
10528 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
10529 C->getLParenLoc(), C->getEndLoc());
10530 }
10531
10532 template <typename Derived>
10533 OMPClause *
TransformOMPPermutationClause(OMPPermutationClause * C)10534 TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10535 SmallVector<Expr *> TransformedArgs;
10536 TransformedArgs.reserve(C->getNumLoops());
10537 bool Changed = false;
10538 for (Expr *E : C->getArgsRefs()) {
10539 if (!E) {
10540 TransformedArgs.push_back(nullptr);
10541 continue;
10542 }
10543
10544 ExprResult T = getDerived().TransformExpr(E);
10545 if (T.isInvalid())
10546 return nullptr;
10547 if (E != T.get())
10548 Changed = true;
10549 TransformedArgs.push_back(T.get());
10550 }
10551
10552 if (!Changed && !getDerived().AlwaysRebuild())
10553 return C;
10554 return RebuildOMPPermutationClause(TransformedArgs, C->getBeginLoc(),
10555 C->getLParenLoc(), C->getEndLoc());
10556 }
10557
10558 template <typename Derived>
TransformOMPFullClause(OMPFullClause * C)10559 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10560 if (!getDerived().AlwaysRebuild())
10561 return C;
10562 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
10563 }
10564
10565 template <typename Derived>
10566 OMPClause *
TransformOMPPartialClause(OMPPartialClause * C)10567 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10568 ExprResult T = getDerived().TransformExpr(C->getFactor());
10569 if (T.isInvalid())
10570 return nullptr;
10571 Expr *Factor = T.get();
10572 bool Changed = Factor != C->getFactor();
10573
10574 if (!Changed && !getDerived().AlwaysRebuild())
10575 return C;
10576 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
10577 C->getEndLoc());
10578 }
10579
10580 template <typename Derived>
10581 OMPClause *
TransformOMPCollapseClause(OMPCollapseClause * C)10582 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10583 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10584 if (E.isInvalid())
10585 return nullptr;
10586 return getDerived().RebuildOMPCollapseClause(
10587 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10588 }
10589
10590 template <typename Derived>
10591 OMPClause *
TransformOMPDefaultClause(OMPDefaultClause * C)10592 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10593 return getDerived().RebuildOMPDefaultClause(
10594 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10595 C->getLParenLoc(), C->getEndLoc());
10596 }
10597
10598 template <typename Derived>
10599 OMPClause *
TransformOMPProcBindClause(OMPProcBindClause * C)10600 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10601 return getDerived().RebuildOMPProcBindClause(
10602 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10603 C->getLParenLoc(), C->getEndLoc());
10604 }
10605
10606 template <typename Derived>
10607 OMPClause *
TransformOMPScheduleClause(OMPScheduleClause * C)10608 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10609 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10610 if (E.isInvalid())
10611 return nullptr;
10612 return getDerived().RebuildOMPScheduleClause(
10613 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10614 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10615 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10616 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10617 }
10618
10619 template <typename Derived>
10620 OMPClause *
TransformOMPOrderedClause(OMPOrderedClause * C)10621 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10622 ExprResult E;
10623 if (auto *Num = C->getNumForLoops()) {
10624 E = getDerived().TransformExpr(Num);
10625 if (E.isInvalid())
10626 return nullptr;
10627 }
10628 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10629 C->getLParenLoc(), E.get());
10630 }
10631
10632 template <typename Derived>
10633 OMPClause *
TransformOMPDetachClause(OMPDetachClause * C)10634 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10635 ExprResult E;
10636 if (Expr *Evt = C->getEventHandler()) {
10637 E = getDerived().TransformExpr(Evt);
10638 if (E.isInvalid())
10639 return nullptr;
10640 }
10641 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10642 C->getLParenLoc(), C->getEndLoc());
10643 }
10644
10645 template <typename Derived>
10646 OMPClause *
TransformOMPNowaitClause(OMPNowaitClause * C)10647 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10648 // No need to rebuild this clause, no template-dependent parameters.
10649 return C;
10650 }
10651
10652 template <typename Derived>
10653 OMPClause *
TransformOMPUntiedClause(OMPUntiedClause * C)10654 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10655 // No need to rebuild this clause, no template-dependent parameters.
10656 return C;
10657 }
10658
10659 template <typename Derived>
10660 OMPClause *
TransformOMPMergeableClause(OMPMergeableClause * C)10661 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10662 // No need to rebuild this clause, no template-dependent parameters.
10663 return C;
10664 }
10665
10666 template <typename Derived>
TransformOMPReadClause(OMPReadClause * C)10667 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10668 // No need to rebuild this clause, no template-dependent parameters.
10669 return C;
10670 }
10671
10672 template <typename Derived>
TransformOMPWriteClause(OMPWriteClause * C)10673 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10674 // No need to rebuild this clause, no template-dependent parameters.
10675 return C;
10676 }
10677
10678 template <typename Derived>
10679 OMPClause *
TransformOMPUpdateClause(OMPUpdateClause * C)10680 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10681 // No need to rebuild this clause, no template-dependent parameters.
10682 return C;
10683 }
10684
10685 template <typename Derived>
10686 OMPClause *
TransformOMPCaptureClause(OMPCaptureClause * C)10687 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10688 // No need to rebuild this clause, no template-dependent parameters.
10689 return C;
10690 }
10691
10692 template <typename Derived>
10693 OMPClause *
TransformOMPCompareClause(OMPCompareClause * C)10694 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10695 // No need to rebuild this clause, no template-dependent parameters.
10696 return C;
10697 }
10698
10699 template <typename Derived>
TransformOMPFailClause(OMPFailClause * C)10700 OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10701 // No need to rebuild this clause, no template-dependent parameters.
10702 return C;
10703 }
10704
10705 template <typename Derived>
10706 OMPClause *
TransformOMPAbsentClause(OMPAbsentClause * C)10707 TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10708 return C;
10709 }
10710
10711 template <typename Derived>
TransformOMPHoldsClause(OMPHoldsClause * C)10712 OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10713 ExprResult E = getDerived().TransformExpr(C->getExpr());
10714 if (E.isInvalid())
10715 return nullptr;
10716 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10717 C->getLParenLoc(), C->getEndLoc());
10718 }
10719
10720 template <typename Derived>
10721 OMPClause *
TransformOMPContainsClause(OMPContainsClause * C)10722 TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10723 return C;
10724 }
10725
10726 template <typename Derived>
10727 OMPClause *
TransformOMPNoOpenMPClause(OMPNoOpenMPClause * C)10728 TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10729 return C;
10730 }
10731 template <typename Derived>
TransformOMPNoOpenMPRoutinesClause(OMPNoOpenMPRoutinesClause * C)10732 OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10733 OMPNoOpenMPRoutinesClause *C) {
10734 return C;
10735 }
10736 template <typename Derived>
TransformOMPNoOpenMPConstructsClause(OMPNoOpenMPConstructsClause * C)10737 OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10738 OMPNoOpenMPConstructsClause *C) {
10739 return C;
10740 }
10741 template <typename Derived>
TransformOMPNoParallelismClause(OMPNoParallelismClause * C)10742 OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10743 OMPNoParallelismClause *C) {
10744 return C;
10745 }
10746
10747 template <typename Derived>
10748 OMPClause *
TransformOMPSeqCstClause(OMPSeqCstClause * C)10749 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10750 // No need to rebuild this clause, no template-dependent parameters.
10751 return C;
10752 }
10753
10754 template <typename Derived>
10755 OMPClause *
TransformOMPAcqRelClause(OMPAcqRelClause * C)10756 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10757 // No need to rebuild this clause, no template-dependent parameters.
10758 return C;
10759 }
10760
10761 template <typename Derived>
10762 OMPClause *
TransformOMPAcquireClause(OMPAcquireClause * C)10763 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10764 // No need to rebuild this clause, no template-dependent parameters.
10765 return C;
10766 }
10767
10768 template <typename Derived>
10769 OMPClause *
TransformOMPReleaseClause(OMPReleaseClause * C)10770 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10771 // No need to rebuild this clause, no template-dependent parameters.
10772 return C;
10773 }
10774
10775 template <typename Derived>
10776 OMPClause *
TransformOMPRelaxedClause(OMPRelaxedClause * C)10777 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10778 // No need to rebuild this clause, no template-dependent parameters.
10779 return C;
10780 }
10781
10782 template <typename Derived>
TransformOMPWeakClause(OMPWeakClause * C)10783 OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10784 // No need to rebuild this clause, no template-dependent parameters.
10785 return C;
10786 }
10787
10788 template <typename Derived>
10789 OMPClause *
TransformOMPThreadsClause(OMPThreadsClause * C)10790 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10791 // No need to rebuild this clause, no template-dependent parameters.
10792 return C;
10793 }
10794
10795 template <typename Derived>
TransformOMPSIMDClause(OMPSIMDClause * C)10796 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10797 // No need to rebuild this clause, no template-dependent parameters.
10798 return C;
10799 }
10800
10801 template <typename Derived>
10802 OMPClause *
TransformOMPNogroupClause(OMPNogroupClause * C)10803 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10804 // No need to rebuild this clause, no template-dependent parameters.
10805 return C;
10806 }
10807
10808 template <typename Derived>
TransformOMPInitClause(OMPInitClause * C)10809 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10810 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10811 if (IVR.isInvalid())
10812 return nullptr;
10813
10814 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10815 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
10816 for (Expr *E : llvm::drop_begin(C->varlist())) {
10817 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10818 if (ER.isInvalid())
10819 return nullptr;
10820 InteropInfo.PreferTypes.push_back(ER.get());
10821 }
10822 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10823 C->getBeginLoc(), C->getLParenLoc(),
10824 C->getVarLoc(), C->getEndLoc());
10825 }
10826
10827 template <typename Derived>
TransformOMPUseClause(OMPUseClause * C)10828 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10829 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10830 if (ER.isInvalid())
10831 return nullptr;
10832 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10833 C->getLParenLoc(), C->getVarLoc(),
10834 C->getEndLoc());
10835 }
10836
10837 template <typename Derived>
10838 OMPClause *
TransformOMPDestroyClause(OMPDestroyClause * C)10839 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10840 ExprResult ER;
10841 if (Expr *IV = C->getInteropVar()) {
10842 ER = getDerived().TransformExpr(IV);
10843 if (ER.isInvalid())
10844 return nullptr;
10845 }
10846 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10847 C->getLParenLoc(), C->getVarLoc(),
10848 C->getEndLoc());
10849 }
10850
10851 template <typename Derived>
10852 OMPClause *
TransformOMPNovariantsClause(OMPNovariantsClause * C)10853 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10854 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10855 if (Cond.isInvalid())
10856 return nullptr;
10857 return getDerived().RebuildOMPNovariantsClause(
10858 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10859 }
10860
10861 template <typename Derived>
10862 OMPClause *
TransformOMPNocontextClause(OMPNocontextClause * C)10863 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10864 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10865 if (Cond.isInvalid())
10866 return nullptr;
10867 return getDerived().RebuildOMPNocontextClause(
10868 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10869 }
10870
10871 template <typename Derived>
10872 OMPClause *
TransformOMPFilterClause(OMPFilterClause * C)10873 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10874 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10875 if (ThreadID.isInvalid())
10876 return nullptr;
10877 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10878 C->getLParenLoc(), C->getEndLoc());
10879 }
10880
10881 template <typename Derived>
TransformOMPAlignClause(OMPAlignClause * C)10882 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10883 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10884 if (E.isInvalid())
10885 return nullptr;
10886 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10887 C->getLParenLoc(), C->getEndLoc());
10888 }
10889
10890 template <typename Derived>
TransformOMPUnifiedAddressClause(OMPUnifiedAddressClause * C)10891 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10892 OMPUnifiedAddressClause *C) {
10893 llvm_unreachable("unified_address clause cannot appear in dependent context");
10894 }
10895
10896 template <typename Derived>
TransformOMPUnifiedSharedMemoryClause(OMPUnifiedSharedMemoryClause * C)10897 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10898 OMPUnifiedSharedMemoryClause *C) {
10899 llvm_unreachable(
10900 "unified_shared_memory clause cannot appear in dependent context");
10901 }
10902
10903 template <typename Derived>
TransformOMPReverseOffloadClause(OMPReverseOffloadClause * C)10904 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10905 OMPReverseOffloadClause *C) {
10906 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10907 }
10908
10909 template <typename Derived>
TransformOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause * C)10910 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10911 OMPDynamicAllocatorsClause *C) {
10912 llvm_unreachable(
10913 "dynamic_allocators clause cannot appear in dependent context");
10914 }
10915
10916 template <typename Derived>
TransformOMPAtomicDefaultMemOrderClause(OMPAtomicDefaultMemOrderClause * C)10917 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10918 OMPAtomicDefaultMemOrderClause *C) {
10919 llvm_unreachable(
10920 "atomic_default_mem_order clause cannot appear in dependent context");
10921 }
10922
10923 template <typename Derived>
10924 OMPClause *
TransformOMPSelfMapsClause(OMPSelfMapsClause * C)10925 TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
10926 llvm_unreachable("self_maps clause cannot appear in dependent context");
10927 }
10928
10929 template <typename Derived>
TransformOMPAtClause(OMPAtClause * C)10930 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10931 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10932 C->getBeginLoc(), C->getLParenLoc(),
10933 C->getEndLoc());
10934 }
10935
10936 template <typename Derived>
10937 OMPClause *
TransformOMPSeverityClause(OMPSeverityClause * C)10938 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10939 return getDerived().RebuildOMPSeverityClause(
10940 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10941 C->getLParenLoc(), C->getEndLoc());
10942 }
10943
10944 template <typename Derived>
10945 OMPClause *
TransformOMPMessageClause(OMPMessageClause * C)10946 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10947 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10948 if (E.isInvalid())
10949 return nullptr;
10950 return getDerived().RebuildOMPMessageClause(
10951 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10952 C->getEndLoc());
10953 }
10954
10955 template <typename Derived>
10956 OMPClause *
TransformOMPPrivateClause(OMPPrivateClause * C)10957 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10958 llvm::SmallVector<Expr *, 16> Vars;
10959 Vars.reserve(C->varlist_size());
10960 for (auto *VE : C->varlist()) {
10961 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10962 if (EVar.isInvalid())
10963 return nullptr;
10964 Vars.push_back(EVar.get());
10965 }
10966 return getDerived().RebuildOMPPrivateClause(
10967 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10968 }
10969
10970 template <typename Derived>
TransformOMPFirstprivateClause(OMPFirstprivateClause * C)10971 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10972 OMPFirstprivateClause *C) {
10973 llvm::SmallVector<Expr *, 16> Vars;
10974 Vars.reserve(C->varlist_size());
10975 for (auto *VE : C->varlist()) {
10976 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10977 if (EVar.isInvalid())
10978 return nullptr;
10979 Vars.push_back(EVar.get());
10980 }
10981 return getDerived().RebuildOMPFirstprivateClause(
10982 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10983 }
10984
10985 template <typename Derived>
10986 OMPClause *
TransformOMPLastprivateClause(OMPLastprivateClause * C)10987 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10988 llvm::SmallVector<Expr *, 16> Vars;
10989 Vars.reserve(C->varlist_size());
10990 for (auto *VE : C->varlist()) {
10991 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10992 if (EVar.isInvalid())
10993 return nullptr;
10994 Vars.push_back(EVar.get());
10995 }
10996 return getDerived().RebuildOMPLastprivateClause(
10997 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10998 C->getLParenLoc(), C->getEndLoc());
10999 }
11000
11001 template <typename Derived>
11002 OMPClause *
TransformOMPSharedClause(OMPSharedClause * C)11003 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11004 llvm::SmallVector<Expr *, 16> Vars;
11005 Vars.reserve(C->varlist_size());
11006 for (auto *VE : C->varlist()) {
11007 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11008 if (EVar.isInvalid())
11009 return nullptr;
11010 Vars.push_back(EVar.get());
11011 }
11012 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11013 C->getLParenLoc(), C->getEndLoc());
11014 }
11015
11016 template <typename Derived>
11017 OMPClause *
TransformOMPReductionClause(OMPReductionClause * C)11018 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11019 llvm::SmallVector<Expr *, 16> Vars;
11020 Vars.reserve(C->varlist_size());
11021 for (auto *VE : C->varlist()) {
11022 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11023 if (EVar.isInvalid())
11024 return nullptr;
11025 Vars.push_back(EVar.get());
11026 }
11027 CXXScopeSpec ReductionIdScopeSpec;
11028 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
11029
11030 DeclarationNameInfo NameInfo = C->getNameInfo();
11031 if (NameInfo.getName()) {
11032 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11033 if (!NameInfo.getName())
11034 return nullptr;
11035 }
11036 // Build a list of all UDR decls with the same names ranged by the Scopes.
11037 // The Scope boundary is a duplication of the previous decl.
11038 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11039 for (auto *E : C->reduction_ops()) {
11040 // Transform all the decls.
11041 if (E) {
11042 auto *ULE = cast<UnresolvedLookupExpr>(E);
11043 UnresolvedSet<8> Decls;
11044 for (auto *D : ULE->decls()) {
11045 NamedDecl *InstD =
11046 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11047 Decls.addDecl(InstD, InstD->getAccess());
11048 }
11049 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11050 SemaRef.Context, /*NamingClass=*/nullptr,
11051 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11052 /*ADL=*/true, Decls.begin(), Decls.end(),
11053 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11054 } else
11055 UnresolvedReductions.push_back(nullptr);
11056 }
11057 return getDerived().RebuildOMPReductionClause(
11058 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11059 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11060 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11061 }
11062
11063 template <typename Derived>
TransformOMPTaskReductionClause(OMPTaskReductionClause * C)11064 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11065 OMPTaskReductionClause *C) {
11066 llvm::SmallVector<Expr *, 16> Vars;
11067 Vars.reserve(C->varlist_size());
11068 for (auto *VE : C->varlist()) {
11069 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11070 if (EVar.isInvalid())
11071 return nullptr;
11072 Vars.push_back(EVar.get());
11073 }
11074 CXXScopeSpec ReductionIdScopeSpec;
11075 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
11076
11077 DeclarationNameInfo NameInfo = C->getNameInfo();
11078 if (NameInfo.getName()) {
11079 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11080 if (!NameInfo.getName())
11081 return nullptr;
11082 }
11083 // Build a list of all UDR decls with the same names ranged by the Scopes.
11084 // The Scope boundary is a duplication of the previous decl.
11085 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11086 for (auto *E : C->reduction_ops()) {
11087 // Transform all the decls.
11088 if (E) {
11089 auto *ULE = cast<UnresolvedLookupExpr>(E);
11090 UnresolvedSet<8> Decls;
11091 for (auto *D : ULE->decls()) {
11092 NamedDecl *InstD =
11093 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11094 Decls.addDecl(InstD, InstD->getAccess());
11095 }
11096 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11097 SemaRef.Context, /*NamingClass=*/nullptr,
11098 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11099 /*ADL=*/true, Decls.begin(), Decls.end(),
11100 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11101 } else
11102 UnresolvedReductions.push_back(nullptr);
11103 }
11104 return getDerived().RebuildOMPTaskReductionClause(
11105 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11106 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11107 }
11108
11109 template <typename Derived>
11110 OMPClause *
TransformOMPInReductionClause(OMPInReductionClause * C)11111 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11112 llvm::SmallVector<Expr *, 16> Vars;
11113 Vars.reserve(C->varlist_size());
11114 for (auto *VE : C->varlist()) {
11115 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11116 if (EVar.isInvalid())
11117 return nullptr;
11118 Vars.push_back(EVar.get());
11119 }
11120 CXXScopeSpec ReductionIdScopeSpec;
11121 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
11122
11123 DeclarationNameInfo NameInfo = C->getNameInfo();
11124 if (NameInfo.getName()) {
11125 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11126 if (!NameInfo.getName())
11127 return nullptr;
11128 }
11129 // Build a list of all UDR decls with the same names ranged by the Scopes.
11130 // The Scope boundary is a duplication of the previous decl.
11131 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11132 for (auto *E : C->reduction_ops()) {
11133 // Transform all the decls.
11134 if (E) {
11135 auto *ULE = cast<UnresolvedLookupExpr>(E);
11136 UnresolvedSet<8> Decls;
11137 for (auto *D : ULE->decls()) {
11138 NamedDecl *InstD =
11139 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11140 Decls.addDecl(InstD, InstD->getAccess());
11141 }
11142 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11143 SemaRef.Context, /*NamingClass=*/nullptr,
11144 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11145 /*ADL=*/true, Decls.begin(), Decls.end(),
11146 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11147 } else
11148 UnresolvedReductions.push_back(nullptr);
11149 }
11150 return getDerived().RebuildOMPInReductionClause(
11151 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11152 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11153 }
11154
11155 template <typename Derived>
11156 OMPClause *
TransformOMPLinearClause(OMPLinearClause * C)11157 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11158 llvm::SmallVector<Expr *, 16> Vars;
11159 Vars.reserve(C->varlist_size());
11160 for (auto *VE : C->varlist()) {
11161 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11162 if (EVar.isInvalid())
11163 return nullptr;
11164 Vars.push_back(EVar.get());
11165 }
11166 ExprResult Step = getDerived().TransformExpr(C->getStep());
11167 if (Step.isInvalid())
11168 return nullptr;
11169 return getDerived().RebuildOMPLinearClause(
11170 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11171 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11172 C->getEndLoc());
11173 }
11174
11175 template <typename Derived>
11176 OMPClause *
TransformOMPAlignedClause(OMPAlignedClause * C)11177 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11178 llvm::SmallVector<Expr *, 16> Vars;
11179 Vars.reserve(C->varlist_size());
11180 for (auto *VE : C->varlist()) {
11181 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11182 if (EVar.isInvalid())
11183 return nullptr;
11184 Vars.push_back(EVar.get());
11185 }
11186 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11187 if (Alignment.isInvalid())
11188 return nullptr;
11189 return getDerived().RebuildOMPAlignedClause(
11190 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11191 C->getColonLoc(), C->getEndLoc());
11192 }
11193
11194 template <typename Derived>
11195 OMPClause *
TransformOMPCopyinClause(OMPCopyinClause * C)11196 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11197 llvm::SmallVector<Expr *, 16> Vars;
11198 Vars.reserve(C->varlist_size());
11199 for (auto *VE : C->varlist()) {
11200 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11201 if (EVar.isInvalid())
11202 return nullptr;
11203 Vars.push_back(EVar.get());
11204 }
11205 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11206 C->getLParenLoc(), C->getEndLoc());
11207 }
11208
11209 template <typename Derived>
11210 OMPClause *
TransformOMPCopyprivateClause(OMPCopyprivateClause * C)11211 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11212 llvm::SmallVector<Expr *, 16> Vars;
11213 Vars.reserve(C->varlist_size());
11214 for (auto *VE : C->varlist()) {
11215 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11216 if (EVar.isInvalid())
11217 return nullptr;
11218 Vars.push_back(EVar.get());
11219 }
11220 return getDerived().RebuildOMPCopyprivateClause(
11221 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11222 }
11223
11224 template <typename Derived>
TransformOMPFlushClause(OMPFlushClause * C)11225 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11226 llvm::SmallVector<Expr *, 16> Vars;
11227 Vars.reserve(C->varlist_size());
11228 for (auto *VE : C->varlist()) {
11229 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11230 if (EVar.isInvalid())
11231 return nullptr;
11232 Vars.push_back(EVar.get());
11233 }
11234 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11235 C->getLParenLoc(), C->getEndLoc());
11236 }
11237
11238 template <typename Derived>
11239 OMPClause *
TransformOMPDepobjClause(OMPDepobjClause * C)11240 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11241 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11242 if (E.isInvalid())
11243 return nullptr;
11244 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11245 C->getLParenLoc(), C->getEndLoc());
11246 }
11247
11248 template <typename Derived>
11249 OMPClause *
TransformOMPDependClause(OMPDependClause * C)11250 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11251 llvm::SmallVector<Expr *, 16> Vars;
11252 Expr *DepModifier = C->getModifier();
11253 if (DepModifier) {
11254 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11255 if (DepModRes.isInvalid())
11256 return nullptr;
11257 DepModifier = DepModRes.get();
11258 }
11259 Vars.reserve(C->varlist_size());
11260 for (auto *VE : C->varlist()) {
11261 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11262 if (EVar.isInvalid())
11263 return nullptr;
11264 Vars.push_back(EVar.get());
11265 }
11266 return getDerived().RebuildOMPDependClause(
11267 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11268 C->getOmpAllMemoryLoc()},
11269 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11270 }
11271
11272 template <typename Derived>
11273 OMPClause *
TransformOMPDeviceClause(OMPDeviceClause * C)11274 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11275 ExprResult E = getDerived().TransformExpr(C->getDevice());
11276 if (E.isInvalid())
11277 return nullptr;
11278 return getDerived().RebuildOMPDeviceClause(
11279 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11280 C->getModifierLoc(), C->getEndLoc());
11281 }
11282
11283 template <typename Derived, class T>
transformOMPMappableExprListClause(TreeTransform<Derived> & TT,OMPMappableExprListClause<T> * C,llvm::SmallVectorImpl<Expr * > & Vars,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperIdInfo,llvm::SmallVectorImpl<Expr * > & UnresolvedMappers)11284 bool transformOMPMappableExprListClause(
11285 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11286 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11287 DeclarationNameInfo &MapperIdInfo,
11288 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11289 // Transform expressions in the list.
11290 Vars.reserve(C->varlist_size());
11291 for (auto *VE : C->varlist()) {
11292 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11293 if (EVar.isInvalid())
11294 return true;
11295 Vars.push_back(EVar.get());
11296 }
11297 // Transform mapper scope specifier and identifier.
11298 NestedNameSpecifierLoc QualifierLoc;
11299 if (C->getMapperQualifierLoc()) {
11300 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11301 C->getMapperQualifierLoc());
11302 if (!QualifierLoc)
11303 return true;
11304 }
11305 MapperIdScopeSpec.Adopt(QualifierLoc);
11306 MapperIdInfo = C->getMapperIdInfo();
11307 if (MapperIdInfo.getName()) {
11308 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11309 if (!MapperIdInfo.getName())
11310 return true;
11311 }
11312 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11313 // the previous user-defined mapper lookup in dependent environment.
11314 for (auto *E : C->mapperlists()) {
11315 // Transform all the decls.
11316 if (E) {
11317 auto *ULE = cast<UnresolvedLookupExpr>(E);
11318 UnresolvedSet<8> Decls;
11319 for (auto *D : ULE->decls()) {
11320 NamedDecl *InstD =
11321 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11322 Decls.addDecl(InstD, InstD->getAccess());
11323 }
11324 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
11325 TT.getSema().Context, /*NamingClass=*/nullptr,
11326 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
11327 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11328 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11329 } else {
11330 UnresolvedMappers.push_back(nullptr);
11331 }
11332 }
11333 return false;
11334 }
11335
11336 template <typename Derived>
TransformOMPMapClause(OMPMapClause * C)11337 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11338 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11339 llvm::SmallVector<Expr *, 16> Vars;
11340 Expr *IteratorModifier = C->getIteratorModifier();
11341 if (IteratorModifier) {
11342 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11343 if (MapModRes.isInvalid())
11344 return nullptr;
11345 IteratorModifier = MapModRes.get();
11346 }
11347 CXXScopeSpec MapperIdScopeSpec;
11348 DeclarationNameInfo MapperIdInfo;
11349 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11350 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11351 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11352 return nullptr;
11353 return getDerived().RebuildOMPMapClause(
11354 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11355 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11356 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11357 }
11358
11359 template <typename Derived>
11360 OMPClause *
TransformOMPAllocateClause(OMPAllocateClause * C)11361 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11362 Expr *Allocator = C->getAllocator();
11363 if (Allocator) {
11364 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11365 if (AllocatorRes.isInvalid())
11366 return nullptr;
11367 Allocator = AllocatorRes.get();
11368 }
11369 Expr *Alignment = C->getAlignment();
11370 if (Alignment) {
11371 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11372 if (AlignmentRes.isInvalid())
11373 return nullptr;
11374 Alignment = AlignmentRes.get();
11375 }
11376 llvm::SmallVector<Expr *, 16> Vars;
11377 Vars.reserve(C->varlist_size());
11378 for (auto *VE : C->varlist()) {
11379 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11380 if (EVar.isInvalid())
11381 return nullptr;
11382 Vars.push_back(EVar.get());
11383 }
11384 return getDerived().RebuildOMPAllocateClause(
11385 Allocator, Alignment, C->getFirstAllocateModifier(),
11386 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11387 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11388 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11389 }
11390
11391 template <typename Derived>
11392 OMPClause *
TransformOMPNumTeamsClause(OMPNumTeamsClause * C)11393 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11394 llvm::SmallVector<Expr *, 3> Vars;
11395 Vars.reserve(C->varlist_size());
11396 for (auto *VE : C->varlist()) {
11397 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11398 if (EVar.isInvalid())
11399 return nullptr;
11400 Vars.push_back(EVar.get());
11401 }
11402 return getDerived().RebuildOMPNumTeamsClause(
11403 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11404 }
11405
11406 template <typename Derived>
11407 OMPClause *
TransformOMPThreadLimitClause(OMPThreadLimitClause * C)11408 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11409 llvm::SmallVector<Expr *, 3> Vars;
11410 Vars.reserve(C->varlist_size());
11411 for (auto *VE : C->varlist()) {
11412 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11413 if (EVar.isInvalid())
11414 return nullptr;
11415 Vars.push_back(EVar.get());
11416 }
11417 return getDerived().RebuildOMPThreadLimitClause(
11418 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11419 }
11420
11421 template <typename Derived>
11422 OMPClause *
TransformOMPPriorityClause(OMPPriorityClause * C)11423 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11424 ExprResult E = getDerived().TransformExpr(C->getPriority());
11425 if (E.isInvalid())
11426 return nullptr;
11427 return getDerived().RebuildOMPPriorityClause(
11428 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11429 }
11430
11431 template <typename Derived>
11432 OMPClause *
TransformOMPGrainsizeClause(OMPGrainsizeClause * C)11433 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11434 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11435 if (E.isInvalid())
11436 return nullptr;
11437 return getDerived().RebuildOMPGrainsizeClause(
11438 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11439 C->getModifierLoc(), C->getEndLoc());
11440 }
11441
11442 template <typename Derived>
11443 OMPClause *
TransformOMPNumTasksClause(OMPNumTasksClause * C)11444 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11445 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11446 if (E.isInvalid())
11447 return nullptr;
11448 return getDerived().RebuildOMPNumTasksClause(
11449 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11450 C->getModifierLoc(), C->getEndLoc());
11451 }
11452
11453 template <typename Derived>
TransformOMPHintClause(OMPHintClause * C)11454 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11455 ExprResult E = getDerived().TransformExpr(C->getHint());
11456 if (E.isInvalid())
11457 return nullptr;
11458 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11459 C->getLParenLoc(), C->getEndLoc());
11460 }
11461
11462 template <typename Derived>
TransformOMPDistScheduleClause(OMPDistScheduleClause * C)11463 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11464 OMPDistScheduleClause *C) {
11465 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11466 if (E.isInvalid())
11467 return nullptr;
11468 return getDerived().RebuildOMPDistScheduleClause(
11469 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11470 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11471 }
11472
11473 template <typename Derived>
11474 OMPClause *
TransformOMPDefaultmapClause(OMPDefaultmapClause * C)11475 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11476 // Rebuild Defaultmap Clause since we need to invoke the checking of
11477 // defaultmap(none:variable-category) after template initialization.
11478 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11479 C->getDefaultmapKind(),
11480 C->getBeginLoc(),
11481 C->getLParenLoc(),
11482 C->getDefaultmapModifierLoc(),
11483 C->getDefaultmapKindLoc(),
11484 C->getEndLoc());
11485 }
11486
11487 template <typename Derived>
TransformOMPToClause(OMPToClause * C)11488 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11489 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11490 llvm::SmallVector<Expr *, 16> Vars;
11491 CXXScopeSpec MapperIdScopeSpec;
11492 DeclarationNameInfo MapperIdInfo;
11493 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11494 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11495 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11496 return nullptr;
11497 return getDerived().RebuildOMPToClause(
11498 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11499 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11500 }
11501
11502 template <typename Derived>
TransformOMPFromClause(OMPFromClause * C)11503 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11504 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11505 llvm::SmallVector<Expr *, 16> Vars;
11506 CXXScopeSpec MapperIdScopeSpec;
11507 DeclarationNameInfo MapperIdInfo;
11508 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11509 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11510 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11511 return nullptr;
11512 return getDerived().RebuildOMPFromClause(
11513 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11514 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11515 }
11516
11517 template <typename Derived>
TransformOMPUseDevicePtrClause(OMPUseDevicePtrClause * C)11518 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11519 OMPUseDevicePtrClause *C) {
11520 llvm::SmallVector<Expr *, 16> Vars;
11521 Vars.reserve(C->varlist_size());
11522 for (auto *VE : C->varlist()) {
11523 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11524 if (EVar.isInvalid())
11525 return nullptr;
11526 Vars.push_back(EVar.get());
11527 }
11528 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11529 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11530 }
11531
11532 template <typename Derived>
TransformOMPUseDeviceAddrClause(OMPUseDeviceAddrClause * C)11533 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11534 OMPUseDeviceAddrClause *C) {
11535 llvm::SmallVector<Expr *, 16> Vars;
11536 Vars.reserve(C->varlist_size());
11537 for (auto *VE : C->varlist()) {
11538 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11539 if (EVar.isInvalid())
11540 return nullptr;
11541 Vars.push_back(EVar.get());
11542 }
11543 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11544 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11545 }
11546
11547 template <typename Derived>
11548 OMPClause *
TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause * C)11549 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11550 llvm::SmallVector<Expr *, 16> Vars;
11551 Vars.reserve(C->varlist_size());
11552 for (auto *VE : C->varlist()) {
11553 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11554 if (EVar.isInvalid())
11555 return nullptr;
11556 Vars.push_back(EVar.get());
11557 }
11558 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11559 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11560 }
11561
11562 template <typename Derived>
TransformOMPHasDeviceAddrClause(OMPHasDeviceAddrClause * C)11563 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11564 OMPHasDeviceAddrClause *C) {
11565 llvm::SmallVector<Expr *, 16> Vars;
11566 Vars.reserve(C->varlist_size());
11567 for (auto *VE : C->varlist()) {
11568 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11569 if (EVar.isInvalid())
11570 return nullptr;
11571 Vars.push_back(EVar.get());
11572 }
11573 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11574 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11575 }
11576
11577 template <typename Derived>
11578 OMPClause *
TransformOMPNontemporalClause(OMPNontemporalClause * C)11579 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11580 llvm::SmallVector<Expr *, 16> Vars;
11581 Vars.reserve(C->varlist_size());
11582 for (auto *VE : C->varlist()) {
11583 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11584 if (EVar.isInvalid())
11585 return nullptr;
11586 Vars.push_back(EVar.get());
11587 }
11588 return getDerived().RebuildOMPNontemporalClause(
11589 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11590 }
11591
11592 template <typename Derived>
11593 OMPClause *
TransformOMPInclusiveClause(OMPInclusiveClause * C)11594 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11595 llvm::SmallVector<Expr *, 16> Vars;
11596 Vars.reserve(C->varlist_size());
11597 for (auto *VE : C->varlist()) {
11598 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11599 if (EVar.isInvalid())
11600 return nullptr;
11601 Vars.push_back(EVar.get());
11602 }
11603 return getDerived().RebuildOMPInclusiveClause(
11604 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11605 }
11606
11607 template <typename Derived>
11608 OMPClause *
TransformOMPExclusiveClause(OMPExclusiveClause * C)11609 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11610 llvm::SmallVector<Expr *, 16> Vars;
11611 Vars.reserve(C->varlist_size());
11612 for (auto *VE : C->varlist()) {
11613 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11614 if (EVar.isInvalid())
11615 return nullptr;
11616 Vars.push_back(EVar.get());
11617 }
11618 return getDerived().RebuildOMPExclusiveClause(
11619 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11620 }
11621
11622 template <typename Derived>
TransformOMPUsesAllocatorsClause(OMPUsesAllocatorsClause * C)11623 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11624 OMPUsesAllocatorsClause *C) {
11625 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11626 Data.reserve(C->getNumberOfAllocators());
11627 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11628 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11629 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11630 if (Allocator.isInvalid())
11631 continue;
11632 ExprResult AllocatorTraits;
11633 if (Expr *AT = D.AllocatorTraits) {
11634 AllocatorTraits = getDerived().TransformExpr(AT);
11635 if (AllocatorTraits.isInvalid())
11636 continue;
11637 }
11638 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11639 NewD.Allocator = Allocator.get();
11640 NewD.AllocatorTraits = AllocatorTraits.get();
11641 NewD.LParenLoc = D.LParenLoc;
11642 NewD.RParenLoc = D.RParenLoc;
11643 }
11644 return getDerived().RebuildOMPUsesAllocatorsClause(
11645 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11646 }
11647
11648 template <typename Derived>
11649 OMPClause *
TransformOMPAffinityClause(OMPAffinityClause * C)11650 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11651 SmallVector<Expr *, 4> Locators;
11652 Locators.reserve(C->varlist_size());
11653 ExprResult ModifierRes;
11654 if (Expr *Modifier = C->getModifier()) {
11655 ModifierRes = getDerived().TransformExpr(Modifier);
11656 if (ModifierRes.isInvalid())
11657 return nullptr;
11658 }
11659 for (Expr *E : C->varlist()) {
11660 ExprResult Locator = getDerived().TransformExpr(E);
11661 if (Locator.isInvalid())
11662 continue;
11663 Locators.push_back(Locator.get());
11664 }
11665 return getDerived().RebuildOMPAffinityClause(
11666 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11667 ModifierRes.get(), Locators);
11668 }
11669
11670 template <typename Derived>
TransformOMPOrderClause(OMPOrderClause * C)11671 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11672 return getDerived().RebuildOMPOrderClause(
11673 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11674 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11675 }
11676
11677 template <typename Derived>
TransformOMPBindClause(OMPBindClause * C)11678 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11679 return getDerived().RebuildOMPBindClause(
11680 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11681 C->getLParenLoc(), C->getEndLoc());
11682 }
11683
11684 template <typename Derived>
TransformOMPXDynCGroupMemClause(OMPXDynCGroupMemClause * C)11685 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11686 OMPXDynCGroupMemClause *C) {
11687 ExprResult Size = getDerived().TransformExpr(C->getSize());
11688 if (Size.isInvalid())
11689 return nullptr;
11690 return getDerived().RebuildOMPXDynCGroupMemClause(
11691 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11692 }
11693
11694 template <typename Derived>
11695 OMPClause *
TransformOMPDoacrossClause(OMPDoacrossClause * C)11696 TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11697 llvm::SmallVector<Expr *, 16> Vars;
11698 Vars.reserve(C->varlist_size());
11699 for (auto *VE : C->varlist()) {
11700 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11701 if (EVar.isInvalid())
11702 return nullptr;
11703 Vars.push_back(EVar.get());
11704 }
11705 return getDerived().RebuildOMPDoacrossClause(
11706 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11707 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11708 }
11709
11710 template <typename Derived>
11711 OMPClause *
TransformOMPXAttributeClause(OMPXAttributeClause * C)11712 TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11713 SmallVector<const Attr *> NewAttrs;
11714 for (auto *A : C->getAttrs())
11715 NewAttrs.push_back(getDerived().TransformAttr(A));
11716 return getDerived().RebuildOMPXAttributeClause(
11717 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11718 }
11719
11720 template <typename Derived>
TransformOMPXBareClause(OMPXBareClause * C)11721 OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11722 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11723 }
11724
11725 //===----------------------------------------------------------------------===//
11726 // OpenACC transformation
11727 //===----------------------------------------------------------------------===//
11728 namespace {
11729 template <typename Derived>
11730 class OpenACCClauseTransform final
11731 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11732 TreeTransform<Derived> &Self;
11733 ArrayRef<const OpenACCClause *> ExistingClauses;
11734 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11735 OpenACCClause *NewClause = nullptr;
11736
VisitVarList(ArrayRef<Expr * > VarList)11737 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11738 llvm::SmallVector<Expr *> InstantiatedVarList;
11739 for (Expr *CurVar : VarList) {
11740 ExprResult Res = Self.TransformExpr(CurVar);
11741
11742 if (!Res.isUsable())
11743 continue;
11744
11745 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11746 ParsedClause.getClauseKind(),
11747 Res.get());
11748
11749 if (Res.isUsable())
11750 InstantiatedVarList.push_back(Res.get());
11751 }
11752
11753 return InstantiatedVarList;
11754 }
11755
11756 public:
OpenACCClauseTransform(TreeTransform<Derived> & Self,ArrayRef<const OpenACCClause * > ExistingClauses,SemaOpenACC::OpenACCParsedClause & PC)11757 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11758 ArrayRef<const OpenACCClause *> ExistingClauses,
11759 SemaOpenACC::OpenACCParsedClause &PC)
11760 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11761
CreatedClause()11762 OpenACCClause *CreatedClause() const { return NewClause; }
11763
11764 #define VISIT_CLAUSE(CLAUSE_NAME) \
11765 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11766 #include "clang/Basic/OpenACCClauses.def"
11767 };
11768
11769 template <typename Derived>
VisitDefaultClause(const OpenACCDefaultClause & C)11770 void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11771 const OpenACCDefaultClause &C) {
11772 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11773
11774 NewClause = OpenACCDefaultClause::Create(
11775 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),
11776 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11777 ParsedClause.getEndLoc());
11778 }
11779
11780 template <typename Derived>
VisitIfClause(const OpenACCIfClause & C)11781 void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11782 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11783 assert(Cond && "If constructed with invalid Condition");
11784 Sema::ConditionResult Res = Self.TransformCondition(
11785 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11786
11787 if (Res.isInvalid() || !Res.get().second)
11788 return;
11789
11790 ParsedClause.setConditionDetails(Res.get().second);
11791
11792 NewClause = OpenACCIfClause::Create(
11793 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11794 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11795 ParsedClause.getEndLoc());
11796 }
11797
11798 template <typename Derived>
VisitSelfClause(const OpenACCSelfClause & C)11799 void OpenACCClauseTransform<Derived>::VisitSelfClause(
11800 const OpenACCSelfClause &C) {
11801
11802 // If this is an 'update' 'self' clause, this is actually a var list instead.
11803 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11804 llvm::SmallVector<Expr *> InstantiatedVarList;
11805 for (Expr *CurVar : C.getVarList()) {
11806 ExprResult Res = Self.TransformExpr(CurVar);
11807
11808 if (!Res.isUsable())
11809 continue;
11810
11811 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11812 ParsedClause.getClauseKind(),
11813 Res.get());
11814
11815 if (Res.isUsable())
11816 InstantiatedVarList.push_back(Res.get());
11817 }
11818
11819 ParsedClause.setVarListDetails(InstantiatedVarList,
11820 OpenACCModifierKind::Invalid);
11821
11822 NewClause = OpenACCSelfClause::Create(
11823 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11824 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11825 ParsedClause.getEndLoc());
11826 } else {
11827
11828 if (C.hasConditionExpr()) {
11829 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11830 Sema::ConditionResult Res =
11831 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11832 Sema::ConditionKind::Boolean);
11833
11834 if (Res.isInvalid() || !Res.get().second)
11835 return;
11836
11837 ParsedClause.setConditionDetails(Res.get().second);
11838 }
11839
11840 NewClause = OpenACCSelfClause::Create(
11841 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11842 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11843 ParsedClause.getEndLoc());
11844 }
11845 }
11846
11847 template <typename Derived>
VisitNumGangsClause(const OpenACCNumGangsClause & C)11848 void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11849 const OpenACCNumGangsClause &C) {
11850 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11851
11852 for (Expr *CurIntExpr : C.getIntExprs()) {
11853 ExprResult Res = Self.TransformExpr(CurIntExpr);
11854
11855 if (!Res.isUsable())
11856 return;
11857
11858 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11859 C.getClauseKind(),
11860 C.getBeginLoc(), Res.get());
11861 if (!Res.isUsable())
11862 return;
11863
11864 InstantiatedIntExprs.push_back(Res.get());
11865 }
11866
11867 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11868 NewClause = OpenACCNumGangsClause::Create(
11869 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11870 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
11871 ParsedClause.getEndLoc());
11872 }
11873
11874 template <typename Derived>
VisitPrivateClause(const OpenACCPrivateClause & C)11875 void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11876 const OpenACCPrivateClause &C) {
11877 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11878 OpenACCModifierKind::Invalid);
11879
11880 NewClause = OpenACCPrivateClause::Create(
11881 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11882 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11883 ParsedClause.getEndLoc());
11884 }
11885
11886 template <typename Derived>
VisitHostClause(const OpenACCHostClause & C)11887 void OpenACCClauseTransform<Derived>::VisitHostClause(
11888 const OpenACCHostClause &C) {
11889 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11890 OpenACCModifierKind::Invalid);
11891
11892 NewClause = OpenACCHostClause::Create(
11893 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11894 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11895 ParsedClause.getEndLoc());
11896 }
11897
11898 template <typename Derived>
VisitDeviceClause(const OpenACCDeviceClause & C)11899 void OpenACCClauseTransform<Derived>::VisitDeviceClause(
11900 const OpenACCDeviceClause &C) {
11901 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11902 OpenACCModifierKind::Invalid);
11903
11904 NewClause = OpenACCDeviceClause::Create(
11905 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11906 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11907 ParsedClause.getEndLoc());
11908 }
11909
11910 template <typename Derived>
VisitFirstPrivateClause(const OpenACCFirstPrivateClause & C)11911 void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11912 const OpenACCFirstPrivateClause &C) {
11913 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11914 OpenACCModifierKind::Invalid);
11915
11916 NewClause = OpenACCFirstPrivateClause::Create(
11917 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11918 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11919 ParsedClause.getEndLoc());
11920 }
11921
11922 template <typename Derived>
VisitNoCreateClause(const OpenACCNoCreateClause & C)11923 void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11924 const OpenACCNoCreateClause &C) {
11925 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11926 OpenACCModifierKind::Invalid);
11927
11928 NewClause = OpenACCNoCreateClause::Create(
11929 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11930 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11931 ParsedClause.getEndLoc());
11932 }
11933
11934 template <typename Derived>
VisitPresentClause(const OpenACCPresentClause & C)11935 void OpenACCClauseTransform<Derived>::VisitPresentClause(
11936 const OpenACCPresentClause &C) {
11937 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11938 OpenACCModifierKind::Invalid);
11939
11940 NewClause = OpenACCPresentClause::Create(
11941 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11942 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11943 ParsedClause.getEndLoc());
11944 }
11945
11946 template <typename Derived>
VisitCopyClause(const OpenACCCopyClause & C)11947 void OpenACCClauseTransform<Derived>::VisitCopyClause(
11948 const OpenACCCopyClause &C) {
11949 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11950 C.getModifierList());
11951
11952 NewClause = OpenACCCopyClause::Create(
11953 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11954 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11955 ParsedClause.getModifierList(), ParsedClause.getVarList(),
11956 ParsedClause.getEndLoc());
11957 }
11958
11959 template <typename Derived>
VisitLinkClause(const OpenACCLinkClause & C)11960 void OpenACCClauseTransform<Derived>::VisitLinkClause(
11961 const OpenACCLinkClause &C) {
11962 llvm_unreachable("link clause not valid unless a decl transform");
11963 }
11964
11965 template <typename Derived>
VisitDeviceResidentClause(const OpenACCDeviceResidentClause & C)11966 void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
11967 const OpenACCDeviceResidentClause &C) {
11968 llvm_unreachable("device_resident clause not valid unless a decl transform");
11969 }
11970 template <typename Derived>
VisitNoHostClause(const OpenACCNoHostClause & C)11971 void OpenACCClauseTransform<Derived>::VisitNoHostClause(
11972 const OpenACCNoHostClause &C) {
11973 llvm_unreachable("nohost clause not valid unless a decl transform");
11974 }
11975 template <typename Derived>
VisitBindClause(const OpenACCBindClause & C)11976 void OpenACCClauseTransform<Derived>::VisitBindClause(
11977 const OpenACCBindClause &C) {
11978 llvm_unreachable("bind clause not valid unless a decl transform");
11979 }
11980
11981 template <typename Derived>
VisitCopyInClause(const OpenACCCopyInClause & C)11982 void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11983 const OpenACCCopyInClause &C) {
11984 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11985 C.getModifierList());
11986
11987 NewClause = OpenACCCopyInClause::Create(
11988 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11989 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11990 ParsedClause.getModifierList(), ParsedClause.getVarList(),
11991 ParsedClause.getEndLoc());
11992 }
11993
11994 template <typename Derived>
VisitCopyOutClause(const OpenACCCopyOutClause & C)11995 void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11996 const OpenACCCopyOutClause &C) {
11997 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11998 C.getModifierList());
11999
12000 NewClause = OpenACCCopyOutClause::Create(
12001 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
12002 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12003 ParsedClause.getModifierList(), ParsedClause.getVarList(),
12004 ParsedClause.getEndLoc());
12005 }
12006
12007 template <typename Derived>
VisitCreateClause(const OpenACCCreateClause & C)12008 void OpenACCClauseTransform<Derived>::VisitCreateClause(
12009 const OpenACCCreateClause &C) {
12010 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
12011 C.getModifierList());
12012
12013 NewClause = OpenACCCreateClause::Create(
12014 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
12015 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12016 ParsedClause.getModifierList(), ParsedClause.getVarList(),
12017 ParsedClause.getEndLoc());
12018 }
12019 template <typename Derived>
VisitAttachClause(const OpenACCAttachClause & C)12020 void OpenACCClauseTransform<Derived>::VisitAttachClause(
12021 const OpenACCAttachClause &C) {
12022 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
12023
12024 // Ensure each var is a pointer type.
12025 llvm::erase_if(VarList, [&](Expr *E) {
12026 return Self.getSema().OpenACC().CheckVarIsPointerType(
12027 OpenACCClauseKind::Attach, E);
12028 });
12029
12030 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
12031 NewClause = OpenACCAttachClause::Create(
12032 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12033 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12034 ParsedClause.getEndLoc());
12035 }
12036
12037 template <typename Derived>
VisitDetachClause(const OpenACCDetachClause & C)12038 void OpenACCClauseTransform<Derived>::VisitDetachClause(
12039 const OpenACCDetachClause &C) {
12040 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
12041
12042 // Ensure each var is a pointer type.
12043 llvm::erase_if(VarList, [&](Expr *E) {
12044 return Self.getSema().OpenACC().CheckVarIsPointerType(
12045 OpenACCClauseKind::Detach, E);
12046 });
12047
12048 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
12049 NewClause = OpenACCDetachClause::Create(
12050 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12051 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12052 ParsedClause.getEndLoc());
12053 }
12054
12055 template <typename Derived>
VisitDeleteClause(const OpenACCDeleteClause & C)12056 void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12057 const OpenACCDeleteClause &C) {
12058 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
12059 OpenACCModifierKind::Invalid);
12060 NewClause = OpenACCDeleteClause::Create(
12061 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12062 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12063 ParsedClause.getEndLoc());
12064 }
12065
12066 template <typename Derived>
VisitUseDeviceClause(const OpenACCUseDeviceClause & C)12067 void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12068 const OpenACCUseDeviceClause &C) {
12069 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
12070 OpenACCModifierKind::Invalid);
12071 NewClause = OpenACCUseDeviceClause::Create(
12072 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12073 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12074 ParsedClause.getEndLoc());
12075 }
12076
12077 template <typename Derived>
VisitDevicePtrClause(const OpenACCDevicePtrClause & C)12078 void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12079 const OpenACCDevicePtrClause &C) {
12080 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
12081
12082 // Ensure each var is a pointer type.
12083 llvm::erase_if(VarList, [&](Expr *E) {
12084 return Self.getSema().OpenACC().CheckVarIsPointerType(
12085 OpenACCClauseKind::DevicePtr, E);
12086 });
12087
12088 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
12089 NewClause = OpenACCDevicePtrClause::Create(
12090 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12091 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12092 ParsedClause.getEndLoc());
12093 }
12094
12095 template <typename Derived>
VisitNumWorkersClause(const OpenACCNumWorkersClause & C)12096 void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12097 const OpenACCNumWorkersClause &C) {
12098 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12099 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12100
12101 ExprResult Res = Self.TransformExpr(IntExpr);
12102 if (!Res.isUsable())
12103 return;
12104
12105 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12106 C.getClauseKind(),
12107 C.getBeginLoc(), Res.get());
12108 if (!Res.isUsable())
12109 return;
12110
12111 ParsedClause.setIntExprDetails(Res.get());
12112 NewClause = OpenACCNumWorkersClause::Create(
12113 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12114 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12115 ParsedClause.getEndLoc());
12116 }
12117
12118 template <typename Derived>
VisitDeviceNumClause(const OpenACCDeviceNumClause & C)12119 void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12120 const OpenACCDeviceNumClause &C) {
12121 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12122 assert(IntExpr && "device_num clause constructed with invalid int expr");
12123
12124 ExprResult Res = Self.TransformExpr(IntExpr);
12125 if (!Res.isUsable())
12126 return;
12127
12128 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12129 C.getClauseKind(),
12130 C.getBeginLoc(), Res.get());
12131 if (!Res.isUsable())
12132 return;
12133
12134 ParsedClause.setIntExprDetails(Res.get());
12135 NewClause = OpenACCDeviceNumClause::Create(
12136 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12137 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12138 ParsedClause.getEndLoc());
12139 }
12140
12141 template <typename Derived>
VisitDefaultAsyncClause(const OpenACCDefaultAsyncClause & C)12142 void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12143 const OpenACCDefaultAsyncClause &C) {
12144 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12145 assert(IntExpr && "default_async clause constructed with invalid int expr");
12146
12147 ExprResult Res = Self.TransformExpr(IntExpr);
12148 if (!Res.isUsable())
12149 return;
12150
12151 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12152 C.getClauseKind(),
12153 C.getBeginLoc(), Res.get());
12154 if (!Res.isUsable())
12155 return;
12156
12157 ParsedClause.setIntExprDetails(Res.get());
12158 NewClause = OpenACCDefaultAsyncClause::Create(
12159 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12160 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12161 ParsedClause.getEndLoc());
12162 }
12163
12164 template <typename Derived>
VisitVectorLengthClause(const OpenACCVectorLengthClause & C)12165 void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12166 const OpenACCVectorLengthClause &C) {
12167 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12168 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12169
12170 ExprResult Res = Self.TransformExpr(IntExpr);
12171 if (!Res.isUsable())
12172 return;
12173
12174 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12175 C.getClauseKind(),
12176 C.getBeginLoc(), Res.get());
12177 if (!Res.isUsable())
12178 return;
12179
12180 ParsedClause.setIntExprDetails(Res.get());
12181 NewClause = OpenACCVectorLengthClause::Create(
12182 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12183 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12184 ParsedClause.getEndLoc());
12185 }
12186
12187 template <typename Derived>
VisitAsyncClause(const OpenACCAsyncClause & C)12188 void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12189 const OpenACCAsyncClause &C) {
12190 if (C.hasIntExpr()) {
12191 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12192 if (!Res.isUsable())
12193 return;
12194
12195 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12196 C.getClauseKind(),
12197 C.getBeginLoc(), Res.get());
12198 if (!Res.isUsable())
12199 return;
12200 ParsedClause.setIntExprDetails(Res.get());
12201 }
12202
12203 NewClause = OpenACCAsyncClause::Create(
12204 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12205 ParsedClause.getLParenLoc(),
12206 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12207 : nullptr,
12208 ParsedClause.getEndLoc());
12209 }
12210
12211 template <typename Derived>
VisitWorkerClause(const OpenACCWorkerClause & C)12212 void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12213 const OpenACCWorkerClause &C) {
12214 if (C.hasIntExpr()) {
12215 // restrictions on this expression are all "does it exist in certain
12216 // situations" that are not possible to be dependent, so the only check we
12217 // have is that it transforms, and is an int expression.
12218 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12219 if (!Res.isUsable())
12220 return;
12221
12222 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12223 C.getClauseKind(),
12224 C.getBeginLoc(), Res.get());
12225 if (!Res.isUsable())
12226 return;
12227 ParsedClause.setIntExprDetails(Res.get());
12228 }
12229
12230 NewClause = OpenACCWorkerClause::Create(
12231 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12232 ParsedClause.getLParenLoc(),
12233 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12234 : nullptr,
12235 ParsedClause.getEndLoc());
12236 }
12237
12238 template <typename Derived>
VisitVectorClause(const OpenACCVectorClause & C)12239 void OpenACCClauseTransform<Derived>::VisitVectorClause(
12240 const OpenACCVectorClause &C) {
12241 if (C.hasIntExpr()) {
12242 // restrictions on this expression are all "does it exist in certain
12243 // situations" that are not possible to be dependent, so the only check we
12244 // have is that it transforms, and is an int expression.
12245 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12246 if (!Res.isUsable())
12247 return;
12248
12249 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12250 C.getClauseKind(),
12251 C.getBeginLoc(), Res.get());
12252 if (!Res.isUsable())
12253 return;
12254 ParsedClause.setIntExprDetails(Res.get());
12255 }
12256
12257 NewClause = OpenACCVectorClause::Create(
12258 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12259 ParsedClause.getLParenLoc(),
12260 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12261 : nullptr,
12262 ParsedClause.getEndLoc());
12263 }
12264
12265 template <typename Derived>
VisitWaitClause(const OpenACCWaitClause & C)12266 void OpenACCClauseTransform<Derived>::VisitWaitClause(
12267 const OpenACCWaitClause &C) {
12268 if (C.hasExprs()) {
12269 Expr *DevNumExpr = nullptr;
12270 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12271
12272 // Instantiate devnum expr if it exists.
12273 if (C.getDevNumExpr()) {
12274 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12275 if (!Res.isUsable())
12276 return;
12277 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12278 C.getClauseKind(),
12279 C.getBeginLoc(), Res.get());
12280 if (!Res.isUsable())
12281 return;
12282
12283 DevNumExpr = Res.get();
12284 }
12285
12286 // Instantiate queue ids.
12287 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12288 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12289 if (!Res.isUsable())
12290 return;
12291 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12292 C.getClauseKind(),
12293 C.getBeginLoc(), Res.get());
12294 if (!Res.isUsable())
12295 return;
12296
12297 InstantiatedQueueIdExprs.push_back(Res.get());
12298 }
12299
12300 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),
12301 std::move(InstantiatedQueueIdExprs));
12302 }
12303
12304 NewClause = OpenACCWaitClause::Create(
12305 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12306 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),
12307 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),
12308 ParsedClause.getEndLoc());
12309 }
12310
12311 template <typename Derived>
VisitDeviceTypeClause(const OpenACCDeviceTypeClause & C)12312 void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12313 const OpenACCDeviceTypeClause &C) {
12314 // Nothing to transform here, just create a new version of 'C'.
12315 NewClause = OpenACCDeviceTypeClause::Create(
12316 Self.getSema().getASTContext(), C.getClauseKind(),
12317 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12318 C.getArchitectures(), ParsedClause.getEndLoc());
12319 }
12320
12321 template <typename Derived>
VisitAutoClause(const OpenACCAutoClause & C)12322 void OpenACCClauseTransform<Derived>::VisitAutoClause(
12323 const OpenACCAutoClause &C) {
12324 // Nothing to do, so just create a new node.
12325 NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),
12326 ParsedClause.getBeginLoc(),
12327 ParsedClause.getEndLoc());
12328 }
12329
12330 template <typename Derived>
VisitIndependentClause(const OpenACCIndependentClause & C)12331 void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12332 const OpenACCIndependentClause &C) {
12333 NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),
12334 ParsedClause.getBeginLoc(),
12335 ParsedClause.getEndLoc());
12336 }
12337
12338 template <typename Derived>
VisitSeqClause(const OpenACCSeqClause & C)12339 void OpenACCClauseTransform<Derived>::VisitSeqClause(
12340 const OpenACCSeqClause &C) {
12341 NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),
12342 ParsedClause.getBeginLoc(),
12343 ParsedClause.getEndLoc());
12344 }
12345 template <typename Derived>
VisitFinalizeClause(const OpenACCFinalizeClause & C)12346 void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12347 const OpenACCFinalizeClause &C) {
12348 NewClause = OpenACCFinalizeClause::Create(Self.getSema().getASTContext(),
12349 ParsedClause.getBeginLoc(),
12350 ParsedClause.getEndLoc());
12351 }
12352
12353 template <typename Derived>
VisitIfPresentClause(const OpenACCIfPresentClause & C)12354 void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12355 const OpenACCIfPresentClause &C) {
12356 NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(),
12357 ParsedClause.getBeginLoc(),
12358 ParsedClause.getEndLoc());
12359 }
12360
12361 template <typename Derived>
VisitReductionClause(const OpenACCReductionClause & C)12362 void OpenACCClauseTransform<Derived>::VisitReductionClause(
12363 const OpenACCReductionClause &C) {
12364 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());
12365 SmallVector<Expr *> ValidVars;
12366
12367 for (Expr *Var : TransformedVars) {
12368 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12369 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12370 if (Res.isUsable())
12371 ValidVars.push_back(Res.get());
12372 }
12373
12374 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12375 ExistingClauses, ParsedClause.getDirectiveKind(),
12376 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12377 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
12378 }
12379
12380 template <typename Derived>
VisitCollapseClause(const OpenACCCollapseClause & C)12381 void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12382 const OpenACCCollapseClause &C) {
12383 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12384 assert(LoopCount && "collapse clause constructed with invalid loop count");
12385
12386 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12387
12388 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12389 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12390 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12391
12392 NewLoopCount =
12393 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12394
12395 ParsedClause.setCollapseDetails(C.hasForce(), NewLoopCount.get());
12396 NewClause = OpenACCCollapseClause::Create(
12397 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12398 ParsedClause.getLParenLoc(), ParsedClause.isForce(),
12399 ParsedClause.getLoopCount(), ParsedClause.getEndLoc());
12400 }
12401
12402 template <typename Derived>
VisitTileClause(const OpenACCTileClause & C)12403 void OpenACCClauseTransform<Derived>::VisitTileClause(
12404 const OpenACCTileClause &C) {
12405
12406 llvm::SmallVector<Expr *> TransformedExprs;
12407
12408 for (Expr *E : C.getSizeExprs()) {
12409 ExprResult NewSizeExpr = Self.TransformExpr(E);
12410
12411 if (!NewSizeExpr.isUsable())
12412 return;
12413
12414 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12415 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12416 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12417
12418 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12419
12420 if (!NewSizeExpr.isUsable())
12421 return;
12422 TransformedExprs.push_back(NewSizeExpr.get());
12423 }
12424
12425 ParsedClause.setIntExprDetails(TransformedExprs);
12426 NewClause = OpenACCTileClause::Create(
12427 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12428 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
12429 ParsedClause.getEndLoc());
12430 }
12431 template <typename Derived>
VisitGangClause(const OpenACCGangClause & C)12432 void OpenACCClauseTransform<Derived>::VisitGangClause(
12433 const OpenACCGangClause &C) {
12434 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12435 llvm::SmallVector<Expr *> TransformedIntExprs;
12436
12437 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12438 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12439 if (!ER.isUsable())
12440 continue;
12441
12442 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12443 ParsedClause.getDirectiveKind(),
12444 C.getExpr(I).first, ER.get());
12445 if (!ER.isUsable())
12446 continue;
12447 TransformedGangKinds.push_back(C.getExpr(I).first);
12448 TransformedIntExprs.push_back(ER.get());
12449 }
12450
12451 NewClause = Self.getSema().OpenACC().CheckGangClause(
12452 ParsedClause.getDirectiveKind(), ExistingClauses,
12453 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12454 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12455 }
12456 } // namespace
12457 template <typename Derived>
TransformOpenACCClause(ArrayRef<const OpenACCClause * > ExistingClauses,OpenACCDirectiveKind DirKind,const OpenACCClause * OldClause)12458 OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12459 ArrayRef<const OpenACCClause *> ExistingClauses,
12460 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12461
12462 SemaOpenACC::OpenACCParsedClause ParsedClause(
12463 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12464 ParsedClause.setEndLoc(OldClause->getEndLoc());
12465
12466 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
12467 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12468
12469 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12470 ParsedClause};
12471 Transform.Visit(OldClause);
12472
12473 return Transform.CreatedClause();
12474 }
12475
12476 template <typename Derived>
12477 llvm::SmallVector<OpenACCClause *>
TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,ArrayRef<const OpenACCClause * > OldClauses)12478 TreeTransform<Derived>::TransformOpenACCClauseList(
12479 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12480 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12481 for (const auto *Clause : OldClauses) {
12482 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12483 TransformedClauses, DirKind, Clause))
12484 TransformedClauses.push_back(TransformedClause);
12485 }
12486 return TransformedClauses;
12487 }
12488
12489 template <typename Derived>
TransformOpenACCComputeConstruct(OpenACCComputeConstruct * C)12490 StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12491 OpenACCComputeConstruct *C) {
12492 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12493
12494 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12495 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12496 C->clauses());
12497
12498 if (getSema().OpenACC().ActOnStartStmtDirective(
12499 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12500 return StmtError();
12501
12502 // Transform Structured Block.
12503 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12504 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12505 C->clauses(), TransformedClauses);
12506 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12507 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12508 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12509
12510 return getDerived().RebuildOpenACCComputeConstruct(
12511 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12512 C->getEndLoc(), TransformedClauses, StrBlock);
12513 }
12514
12515 template <typename Derived>
12516 StmtResult
TransformOpenACCLoopConstruct(OpenACCLoopConstruct * C)12517 TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12518
12519 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12520
12521 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12522 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12523 C->clauses());
12524
12525 if (getSema().OpenACC().ActOnStartStmtDirective(
12526 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12527 return StmtError();
12528
12529 // Transform Loop.
12530 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12531 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12532 C->clauses(), TransformedClauses);
12533 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12534 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12535 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12536
12537 return getDerived().RebuildOpenACCLoopConstruct(
12538 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12539 TransformedClauses, Loop);
12540 }
12541
12542 template <typename Derived>
TransformOpenACCCombinedConstruct(OpenACCCombinedConstruct * C)12543 StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12544 OpenACCCombinedConstruct *C) {
12545 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12546
12547 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12548 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12549 C->clauses());
12550
12551 if (getSema().OpenACC().ActOnStartStmtDirective(
12552 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12553 return StmtError();
12554
12555 // Transform Loop.
12556 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12557 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12558 C->clauses(), TransformedClauses);
12559 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12560 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12561 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12562
12563 return getDerived().RebuildOpenACCCombinedConstruct(
12564 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12565 C->getEndLoc(), TransformedClauses, Loop);
12566 }
12567
12568 template <typename Derived>
12569 StmtResult
TransformOpenACCDataConstruct(OpenACCDataConstruct * C)12570 TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12571 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12572
12573 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12574 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12575 C->clauses());
12576 if (getSema().OpenACC().ActOnStartStmtDirective(
12577 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12578 return StmtError();
12579
12580 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12581 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12582 C->clauses(), TransformedClauses);
12583 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12584 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12585 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12586
12587 return getDerived().RebuildOpenACCDataConstruct(
12588 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12589 TransformedClauses, StrBlock);
12590 }
12591
12592 template <typename Derived>
TransformOpenACCEnterDataConstruct(OpenACCEnterDataConstruct * C)12593 StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12594 OpenACCEnterDataConstruct *C) {
12595 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12596
12597 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12598 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12599 C->clauses());
12600 if (getSema().OpenACC().ActOnStartStmtDirective(
12601 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12602 return StmtError();
12603
12604 return getDerived().RebuildOpenACCEnterDataConstruct(
12605 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12606 TransformedClauses);
12607 }
12608
12609 template <typename Derived>
TransformOpenACCExitDataConstruct(OpenACCExitDataConstruct * C)12610 StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12611 OpenACCExitDataConstruct *C) {
12612 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12613
12614 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12615 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12616 C->clauses());
12617 if (getSema().OpenACC().ActOnStartStmtDirective(
12618 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12619 return StmtError();
12620
12621 return getDerived().RebuildOpenACCExitDataConstruct(
12622 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12623 TransformedClauses);
12624 }
12625
12626 template <typename Derived>
TransformOpenACCHostDataConstruct(OpenACCHostDataConstruct * C)12627 StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12628 OpenACCHostDataConstruct *C) {
12629 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12630
12631 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12632 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12633 C->clauses());
12634 if (getSema().OpenACC().ActOnStartStmtDirective(
12635 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12636 return StmtError();
12637
12638 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12639 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12640 C->clauses(), TransformedClauses);
12641 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12642 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12643 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12644
12645 return getDerived().RebuildOpenACCHostDataConstruct(
12646 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12647 TransformedClauses, StrBlock);
12648 }
12649
12650 template <typename Derived>
12651 StmtResult
TransformOpenACCInitConstruct(OpenACCInitConstruct * C)12652 TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12653 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12654
12655 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12656 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12657 C->clauses());
12658 if (getSema().OpenACC().ActOnStartStmtDirective(
12659 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12660 return StmtError();
12661
12662 return getDerived().RebuildOpenACCInitConstruct(
12663 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12664 TransformedClauses);
12665 }
12666
12667 template <typename Derived>
TransformOpenACCShutdownConstruct(OpenACCShutdownConstruct * C)12668 StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12669 OpenACCShutdownConstruct *C) {
12670 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12671
12672 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12673 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12674 C->clauses());
12675 if (getSema().OpenACC().ActOnStartStmtDirective(
12676 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12677 return StmtError();
12678
12679 return getDerived().RebuildOpenACCShutdownConstruct(
12680 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12681 TransformedClauses);
12682 }
12683 template <typename Derived>
12684 StmtResult
TransformOpenACCSetConstruct(OpenACCSetConstruct * C)12685 TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12686 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12687
12688 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12689 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12690 C->clauses());
12691 if (getSema().OpenACC().ActOnStartStmtDirective(
12692 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12693 return StmtError();
12694
12695 return getDerived().RebuildOpenACCSetConstruct(
12696 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12697 TransformedClauses);
12698 }
12699
12700 template <typename Derived>
TransformOpenACCUpdateConstruct(OpenACCUpdateConstruct * C)12701 StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12702 OpenACCUpdateConstruct *C) {
12703 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12704
12705 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12706 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12707 C->clauses());
12708 if (getSema().OpenACC().ActOnStartStmtDirective(
12709 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12710 return StmtError();
12711
12712 return getDerived().RebuildOpenACCUpdateConstruct(
12713 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12714 TransformedClauses);
12715 }
12716
12717 template <typename Derived>
12718 StmtResult
TransformOpenACCWaitConstruct(OpenACCWaitConstruct * C)12719 TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12720 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12721
12722 ExprResult DevNumExpr;
12723 if (C->hasDevNumExpr()) {
12724 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12725
12726 if (DevNumExpr.isUsable())
12727 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12728 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12729 C->getBeginLoc(), DevNumExpr.get());
12730 }
12731
12732 llvm::SmallVector<Expr *> QueueIdExprs;
12733
12734 for (Expr *QE : C->getQueueIdExprs()) {
12735 assert(QE && "Null queue id expr?");
12736 ExprResult NewEQ = getDerived().TransformExpr(QE);
12737
12738 if (!NewEQ.isUsable())
12739 break;
12740 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12741 OpenACCClauseKind::Invalid,
12742 C->getBeginLoc(), NewEQ.get());
12743 if (NewEQ.isUsable())
12744 QueueIdExprs.push_back(NewEQ.get());
12745 }
12746
12747 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12748 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12749 C->clauses());
12750
12751 if (getSema().OpenACC().ActOnStartStmtDirective(
12752 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12753 return StmtError();
12754
12755 return getDerived().RebuildOpenACCWaitConstruct(
12756 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12757 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12758 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12759 }
12760 template <typename Derived>
TransformOpenACCCacheConstruct(OpenACCCacheConstruct * C)12761 StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12762 OpenACCCacheConstruct *C) {
12763 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12764
12765 llvm::SmallVector<Expr *> TransformedVarList;
12766 for (Expr *Var : C->getVarList()) {
12767 assert(Var && "Null var listexpr?");
12768
12769 ExprResult NewVar = getDerived().TransformExpr(Var);
12770
12771 if (!NewVar.isUsable())
12772 break;
12773
12774 NewVar = getSema().OpenACC().ActOnVar(
12775 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
12776 if (!NewVar.isUsable())
12777 break;
12778
12779 TransformedVarList.push_back(NewVar.get());
12780 }
12781
12782 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12783 C->getBeginLoc(), {}))
12784 return StmtError();
12785
12786 return getDerived().RebuildOpenACCCacheConstruct(
12787 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12788 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
12789 C->getEndLoc());
12790 }
12791
12792 template <typename Derived>
TransformOpenACCAtomicConstruct(OpenACCAtomicConstruct * C)12793 StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
12794 OpenACCAtomicConstruct *C) {
12795 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12796
12797 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12798 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12799 C->clauses());
12800
12801 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12802 C->getBeginLoc(), {}))
12803 return StmtError();
12804
12805 // Transform Associated Stmt.
12806 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12807 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
12808
12809 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
12810 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
12811 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
12812 AssocStmt);
12813
12814 return getDerived().RebuildOpenACCAtomicConstruct(
12815 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
12816 C->getEndLoc(), TransformedClauses, AssocStmt);
12817 }
12818
12819 template <typename Derived>
TransformOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr * E)12820 ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12821 OpenACCAsteriskSizeExpr *E) {
12822 if (getDerived().AlwaysRebuild())
12823 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12824 // Nothing can ever change, so there is never anything to transform.
12825 return E;
12826 }
12827
12828 //===----------------------------------------------------------------------===//
12829 // Expression transformation
12830 //===----------------------------------------------------------------------===//
12831 template<typename Derived>
12832 ExprResult
TransformConstantExpr(ConstantExpr * E)12833 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12834 return TransformExpr(E->getSubExpr());
12835 }
12836
12837 template <typename Derived>
TransformSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr * E)12838 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12839 SYCLUniqueStableNameExpr *E) {
12840 if (!E->isTypeDependent())
12841 return E;
12842
12843 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12844
12845 if (!NewT)
12846 return ExprError();
12847
12848 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12849 return E;
12850
12851 return getDerived().RebuildSYCLUniqueStableNameExpr(
12852 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12853 }
12854
12855 template<typename Derived>
12856 ExprResult
TransformPredefinedExpr(PredefinedExpr * E)12857 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12858 if (!E->isTypeDependent())
12859 return E;
12860
12861 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12862 E->getIdentKind());
12863 }
12864
12865 template<typename Derived>
12866 ExprResult
TransformDeclRefExpr(DeclRefExpr * E)12867 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12868 NestedNameSpecifierLoc QualifierLoc;
12869 if (E->getQualifierLoc()) {
12870 QualifierLoc
12871 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12872 if (!QualifierLoc)
12873 return ExprError();
12874 }
12875
12876 ValueDecl *ND
12877 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12878 E->getDecl()));
12879 if (!ND || ND->isInvalidDecl())
12880 return ExprError();
12881
12882 NamedDecl *Found = ND;
12883 if (E->getFoundDecl() != E->getDecl()) {
12884 Found = cast_or_null<NamedDecl>(
12885 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12886 if (!Found)
12887 return ExprError();
12888 }
12889
12890 DeclarationNameInfo NameInfo = E->getNameInfo();
12891 if (NameInfo.getName()) {
12892 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12893 if (!NameInfo.getName())
12894 return ExprError();
12895 }
12896
12897 if (!getDerived().AlwaysRebuild() &&
12898 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12899 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12900 Found == E->getFoundDecl() &&
12901 NameInfo.getName() == E->getDecl()->getDeclName() &&
12902 !E->hasExplicitTemplateArgs()) {
12903
12904 // Mark it referenced in the new context regardless.
12905 // FIXME: this is a bit instantiation-specific.
12906 SemaRef.MarkDeclRefReferenced(E);
12907
12908 return E;
12909 }
12910
12911 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12912 if (E->hasExplicitTemplateArgs()) {
12913 TemplateArgs = &TransArgs;
12914 TransArgs.setLAngleLoc(E->getLAngleLoc());
12915 TransArgs.setRAngleLoc(E->getRAngleLoc());
12916 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12917 E->getNumTemplateArgs(),
12918 TransArgs))
12919 return ExprError();
12920 }
12921
12922 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12923 Found, TemplateArgs);
12924 }
12925
12926 template<typename Derived>
12927 ExprResult
TransformIntegerLiteral(IntegerLiteral * E)12928 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12929 return E;
12930 }
12931
12932 template <typename Derived>
TransformFixedPointLiteral(FixedPointLiteral * E)12933 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12934 FixedPointLiteral *E) {
12935 return E;
12936 }
12937
12938 template<typename Derived>
12939 ExprResult
TransformFloatingLiteral(FloatingLiteral * E)12940 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12941 return E;
12942 }
12943
12944 template<typename Derived>
12945 ExprResult
TransformImaginaryLiteral(ImaginaryLiteral * E)12946 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12947 return E;
12948 }
12949
12950 template<typename Derived>
12951 ExprResult
TransformStringLiteral(StringLiteral * E)12952 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12953 return E;
12954 }
12955
12956 template<typename Derived>
12957 ExprResult
TransformCharacterLiteral(CharacterLiteral * E)12958 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12959 return E;
12960 }
12961
12962 template<typename Derived>
12963 ExprResult
TransformUserDefinedLiteral(UserDefinedLiteral * E)12964 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12965 return getDerived().TransformCallExpr(E);
12966 }
12967
12968 template<typename Derived>
12969 ExprResult
TransformGenericSelectionExpr(GenericSelectionExpr * E)12970 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12971 ExprResult ControllingExpr;
12972 TypeSourceInfo *ControllingType = nullptr;
12973 if (E->isExprPredicate())
12974 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12975 else
12976 ControllingType = getDerived().TransformType(E->getControllingType());
12977
12978 if (ControllingExpr.isInvalid() && !ControllingType)
12979 return ExprError();
12980
12981 SmallVector<Expr *, 4> AssocExprs;
12982 SmallVector<TypeSourceInfo *, 4> AssocTypes;
12983 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12984 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12985 if (TSI) {
12986 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12987 if (!AssocType)
12988 return ExprError();
12989 AssocTypes.push_back(AssocType);
12990 } else {
12991 AssocTypes.push_back(nullptr);
12992 }
12993
12994 ExprResult AssocExpr =
12995 getDerived().TransformExpr(Assoc.getAssociationExpr());
12996 if (AssocExpr.isInvalid())
12997 return ExprError();
12998 AssocExprs.push_back(AssocExpr.get());
12999 }
13000
13001 if (!ControllingType)
13002 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13003 E->getDefaultLoc(),
13004 E->getRParenLoc(),
13005 ControllingExpr.get(),
13006 AssocTypes,
13007 AssocExprs);
13008 return getDerived().RebuildGenericSelectionExpr(
13009 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13010 ControllingType, AssocTypes, AssocExprs);
13011 }
13012
13013 template<typename Derived>
13014 ExprResult
TransformParenExpr(ParenExpr * E)13015 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13016 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13017 if (SubExpr.isInvalid())
13018 return ExprError();
13019
13020 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13021 return E;
13022
13023 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13024 E->getRParen());
13025 }
13026
13027 /// The operand of a unary address-of operator has special rules: it's
13028 /// allowed to refer to a non-static member of a class even if there's no 'this'
13029 /// object available.
13030 template<typename Derived>
13031 ExprResult
TransformAddressOfOperand(Expr * E)13032 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13033 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
13034 return getDerived().TransformDependentScopeDeclRefExpr(
13035 DRE, /*IsAddressOfOperand=*/true, nullptr);
13036 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
13037 return getDerived().TransformUnresolvedLookupExpr(
13038 ULE, /*IsAddressOfOperand=*/true);
13039 else
13040 return getDerived().TransformExpr(E);
13041 }
13042
13043 template<typename Derived>
13044 ExprResult
TransformUnaryOperator(UnaryOperator * E)13045 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13046 ExprResult SubExpr;
13047 if (E->getOpcode() == UO_AddrOf)
13048 SubExpr = TransformAddressOfOperand(E->getSubExpr());
13049 else
13050 SubExpr = TransformExpr(E->getSubExpr());
13051 if (SubExpr.isInvalid())
13052 return ExprError();
13053
13054 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13055 return E;
13056
13057 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13058 E->getOpcode(),
13059 SubExpr.get());
13060 }
13061
13062 template<typename Derived>
13063 ExprResult
TransformOffsetOfExpr(OffsetOfExpr * E)13064 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13065 // Transform the type.
13066 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13067 if (!Type)
13068 return ExprError();
13069
13070 // Transform all of the components into components similar to what the
13071 // parser uses.
13072 // FIXME: It would be slightly more efficient in the non-dependent case to
13073 // just map FieldDecls, rather than requiring the rebuilder to look for
13074 // the fields again. However, __builtin_offsetof is rare enough in
13075 // template code that we don't care.
13076 bool ExprChanged = false;
13077 typedef Sema::OffsetOfComponent Component;
13078 SmallVector<Component, 4> Components;
13079 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13080 const OffsetOfNode &ON = E->getComponent(I);
13081 Component Comp;
13082 Comp.isBrackets = true;
13083 Comp.LocStart = ON.getSourceRange().getBegin();
13084 Comp.LocEnd = ON.getSourceRange().getEnd();
13085 switch (ON.getKind()) {
13086 case OffsetOfNode::Array: {
13087 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
13088 ExprResult Index = getDerived().TransformExpr(FromIndex);
13089 if (Index.isInvalid())
13090 return ExprError();
13091
13092 ExprChanged = ExprChanged || Index.get() != FromIndex;
13093 Comp.isBrackets = true;
13094 Comp.U.E = Index.get();
13095 break;
13096 }
13097
13098 case OffsetOfNode::Field:
13099 case OffsetOfNode::Identifier:
13100 Comp.isBrackets = false;
13101 Comp.U.IdentInfo = ON.getFieldName();
13102 if (!Comp.U.IdentInfo)
13103 continue;
13104
13105 break;
13106
13107 case OffsetOfNode::Base:
13108 // Will be recomputed during the rebuild.
13109 continue;
13110 }
13111
13112 Components.push_back(Comp);
13113 }
13114
13115 // If nothing changed, retain the existing expression.
13116 if (!getDerived().AlwaysRebuild() &&
13117 Type == E->getTypeSourceInfo() &&
13118 !ExprChanged)
13119 return E;
13120
13121 // Build a new offsetof expression.
13122 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13123 Components, E->getRParenLoc());
13124 }
13125
13126 template<typename Derived>
13127 ExprResult
TransformOpaqueValueExpr(OpaqueValueExpr * E)13128 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13129 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13130 "opaque value expression requires transformation");
13131 return E;
13132 }
13133
13134 template <typename Derived>
TransformRecoveryExpr(RecoveryExpr * E)13135 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13136 llvm::SmallVector<Expr *, 8> Children;
13137 bool Changed = false;
13138 for (Expr *C : E->subExpressions()) {
13139 ExprResult NewC = getDerived().TransformExpr(C);
13140 if (NewC.isInvalid())
13141 return ExprError();
13142 Children.push_back(NewC.get());
13143
13144 Changed |= NewC.get() != C;
13145 }
13146 if (!getDerived().AlwaysRebuild() && !Changed)
13147 return E;
13148 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13149 Children, E->getType());
13150 }
13151
13152 template<typename Derived>
13153 ExprResult
TransformPseudoObjectExpr(PseudoObjectExpr * E)13154 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13155 // Rebuild the syntactic form. The original syntactic form has
13156 // opaque-value expressions in it, so strip those away and rebuild
13157 // the result. This is a really awful way of doing this, but the
13158 // better solution (rebuilding the semantic expressions and
13159 // rebinding OVEs as necessary) doesn't work; we'd need
13160 // TreeTransform to not strip away implicit conversions.
13161 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13162 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13163 if (result.isInvalid()) return ExprError();
13164
13165 // If that gives us a pseudo-object result back, the pseudo-object
13166 // expression must have been an lvalue-to-rvalue conversion which we
13167 // should reapply.
13168 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
13169 result = SemaRef.PseudoObject().checkRValue(result.get());
13170
13171 return result;
13172 }
13173
13174 template<typename Derived>
13175 ExprResult
TransformUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr * E)13176 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13177 UnaryExprOrTypeTraitExpr *E) {
13178 if (E->isArgumentType()) {
13179 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13180
13181 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13182 if (!NewT)
13183 return ExprError();
13184
13185 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13186 return E;
13187
13188 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13189 E->getKind(),
13190 E->getSourceRange());
13191 }
13192
13193 // C++0x [expr.sizeof]p1:
13194 // The operand is either an expression, which is an unevaluated operand
13195 // [...]
13196 EnterExpressionEvaluationContext Unevaluated(
13197 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13198 Sema::ReuseLambdaContextDecl);
13199
13200 // Try to recover if we have something like sizeof(T::X) where X is a type.
13201 // Notably, there must be *exactly* one set of parens if X is a type.
13202 TypeSourceInfo *RecoveryTSI = nullptr;
13203 ExprResult SubExpr;
13204 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
13205 if (auto *DRE =
13206 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
13207 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13208 PE, DRE, false, &RecoveryTSI);
13209 else
13210 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13211
13212 if (RecoveryTSI) {
13213 return getDerived().RebuildUnaryExprOrTypeTrait(
13214 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13215 } else if (SubExpr.isInvalid())
13216 return ExprError();
13217
13218 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13219 return E;
13220
13221 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13222 E->getOperatorLoc(),
13223 E->getKind(),
13224 E->getSourceRange());
13225 }
13226
13227 template<typename Derived>
13228 ExprResult
TransformArraySubscriptExpr(ArraySubscriptExpr * E)13229 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13230 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13231 if (LHS.isInvalid())
13232 return ExprError();
13233
13234 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13235 if (RHS.isInvalid())
13236 return ExprError();
13237
13238
13239 if (!getDerived().AlwaysRebuild() &&
13240 LHS.get() == E->getLHS() &&
13241 RHS.get() == E->getRHS())
13242 return E;
13243
13244 return getDerived().RebuildArraySubscriptExpr(
13245 LHS.get(),
13246 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13247 }
13248
13249 template <typename Derived>
13250 ExprResult
TransformMatrixSubscriptExpr(MatrixSubscriptExpr * E)13251 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13252 ExprResult Base = getDerived().TransformExpr(E->getBase());
13253 if (Base.isInvalid())
13254 return ExprError();
13255
13256 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13257 if (RowIdx.isInvalid())
13258 return ExprError();
13259
13260 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13261 if (ColumnIdx.isInvalid())
13262 return ExprError();
13263
13264 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13265 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13266 return E;
13267
13268 return getDerived().RebuildMatrixSubscriptExpr(
13269 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13270 }
13271
13272 template <typename Derived>
13273 ExprResult
TransformArraySectionExpr(ArraySectionExpr * E)13274 TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13275 ExprResult Base = getDerived().TransformExpr(E->getBase());
13276 if (Base.isInvalid())
13277 return ExprError();
13278
13279 ExprResult LowerBound;
13280 if (E->getLowerBound()) {
13281 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13282 if (LowerBound.isInvalid())
13283 return ExprError();
13284 }
13285
13286 ExprResult Length;
13287 if (E->getLength()) {
13288 Length = getDerived().TransformExpr(E->getLength());
13289 if (Length.isInvalid())
13290 return ExprError();
13291 }
13292
13293 ExprResult Stride;
13294 if (E->isOMPArraySection()) {
13295 if (Expr *Str = E->getStride()) {
13296 Stride = getDerived().TransformExpr(Str);
13297 if (Stride.isInvalid())
13298 return ExprError();
13299 }
13300 }
13301
13302 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13303 LowerBound.get() == E->getLowerBound() &&
13304 Length.get() == E->getLength() &&
13305 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13306 return E;
13307
13308 return getDerived().RebuildArraySectionExpr(
13309 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13310 LowerBound.get(), E->getColonLocFirst(),
13311 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13312 Length.get(), Stride.get(), E->getRBracketLoc());
13313 }
13314
13315 template <typename Derived>
13316 ExprResult
TransformOMPArrayShapingExpr(OMPArrayShapingExpr * E)13317 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13318 ExprResult Base = getDerived().TransformExpr(E->getBase());
13319 if (Base.isInvalid())
13320 return ExprError();
13321
13322 SmallVector<Expr *, 4> Dims;
13323 bool ErrorFound = false;
13324 for (Expr *Dim : E->getDimensions()) {
13325 ExprResult DimRes = getDerived().TransformExpr(Dim);
13326 if (DimRes.isInvalid()) {
13327 ErrorFound = true;
13328 continue;
13329 }
13330 Dims.push_back(DimRes.get());
13331 }
13332
13333 if (ErrorFound)
13334 return ExprError();
13335 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13336 E->getRParenLoc(), Dims,
13337 E->getBracketsRanges());
13338 }
13339
13340 template <typename Derived>
13341 ExprResult
TransformOMPIteratorExpr(OMPIteratorExpr * E)13342 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13343 unsigned NumIterators = E->numOfIterators();
13344 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13345
13346 bool ErrorFound = false;
13347 bool NeedToRebuild = getDerived().AlwaysRebuild();
13348 for (unsigned I = 0; I < NumIterators; ++I) {
13349 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
13350 Data[I].DeclIdent = D->getIdentifier();
13351 Data[I].DeclIdentLoc = D->getLocation();
13352 if (D->getLocation() == D->getBeginLoc()) {
13353 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13354 "Implicit type must be int.");
13355 } else {
13356 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13357 QualType DeclTy = getDerived().TransformType(D->getType());
13358 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
13359 }
13360 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13361 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13362 ExprResult End = getDerived().TransformExpr(Range.End);
13363 ExprResult Step = getDerived().TransformExpr(Range.Step);
13364 ErrorFound = ErrorFound ||
13365 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13366 !Data[I].Type.get().isNull())) ||
13367 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13368 if (ErrorFound)
13369 continue;
13370 Data[I].Range.Begin = Begin.get();
13371 Data[I].Range.End = End.get();
13372 Data[I].Range.Step = Step.get();
13373 Data[I].AssignLoc = E->getAssignLoc(I);
13374 Data[I].ColonLoc = E->getColonLoc(I);
13375 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13376 NeedToRebuild =
13377 NeedToRebuild ||
13378 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13379 D->getType().getTypePtrOrNull()) ||
13380 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13381 Range.Step != Data[I].Range.Step;
13382 }
13383 if (ErrorFound)
13384 return ExprError();
13385 if (!NeedToRebuild)
13386 return E;
13387
13388 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13389 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13390 if (!Res.isUsable())
13391 return Res;
13392 auto *IE = cast<OMPIteratorExpr>(Res.get());
13393 for (unsigned I = 0; I < NumIterators; ++I)
13394 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13395 IE->getIteratorDecl(I));
13396 return Res;
13397 }
13398
13399 template<typename Derived>
13400 ExprResult
TransformCallExpr(CallExpr * E)13401 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13402 // Transform the callee.
13403 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13404 if (Callee.isInvalid())
13405 return ExprError();
13406
13407 // Transform arguments.
13408 bool ArgChanged = false;
13409 SmallVector<Expr*, 8> Args;
13410 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13411 &ArgChanged))
13412 return ExprError();
13413
13414 if (!getDerived().AlwaysRebuild() &&
13415 Callee.get() == E->getCallee() &&
13416 !ArgChanged)
13417 return SemaRef.MaybeBindToTemporary(E);
13418
13419 // FIXME: Wrong source location information for the '('.
13420 SourceLocation FakeLParenLoc
13421 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13422
13423 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13424 if (E->hasStoredFPFeatures()) {
13425 FPOptionsOverride NewOverrides = E->getFPFeatures();
13426 getSema().CurFPFeatures =
13427 NewOverrides.applyOverrides(getSema().getLangOpts());
13428 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13429 }
13430
13431 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13432 Args,
13433 E->getRParenLoc());
13434 }
13435
13436 template<typename Derived>
13437 ExprResult
TransformMemberExpr(MemberExpr * E)13438 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13439 ExprResult Base = getDerived().TransformExpr(E->getBase());
13440 if (Base.isInvalid())
13441 return ExprError();
13442
13443 NestedNameSpecifierLoc QualifierLoc;
13444 if (E->hasQualifier()) {
13445 QualifierLoc
13446 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13447
13448 if (!QualifierLoc)
13449 return ExprError();
13450 }
13451 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13452
13453 ValueDecl *Member
13454 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13455 E->getMemberDecl()));
13456 if (!Member)
13457 return ExprError();
13458
13459 NamedDecl *FoundDecl = E->getFoundDecl();
13460 if (FoundDecl == E->getMemberDecl()) {
13461 FoundDecl = Member;
13462 } else {
13463 FoundDecl = cast_or_null<NamedDecl>(
13464 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13465 if (!FoundDecl)
13466 return ExprError();
13467 }
13468
13469 if (!getDerived().AlwaysRebuild() &&
13470 Base.get() == E->getBase() &&
13471 QualifierLoc == E->getQualifierLoc() &&
13472 Member == E->getMemberDecl() &&
13473 FoundDecl == E->getFoundDecl() &&
13474 !E->hasExplicitTemplateArgs()) {
13475
13476 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13477 // for Openmp where the field need to be privatizized in the case.
13478 if (!(isa<CXXThisExpr>(E->getBase()) &&
13479 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13480 cast<ValueDecl>(Member)))) {
13481 // Mark it referenced in the new context regardless.
13482 // FIXME: this is a bit instantiation-specific.
13483 SemaRef.MarkMemberReferenced(E);
13484 return E;
13485 }
13486 }
13487
13488 TemplateArgumentListInfo TransArgs;
13489 if (E->hasExplicitTemplateArgs()) {
13490 TransArgs.setLAngleLoc(E->getLAngleLoc());
13491 TransArgs.setRAngleLoc(E->getRAngleLoc());
13492 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13493 E->getNumTemplateArgs(),
13494 TransArgs))
13495 return ExprError();
13496 }
13497
13498 // FIXME: Bogus source location for the operator
13499 SourceLocation FakeOperatorLoc =
13500 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
13501
13502 // FIXME: to do this check properly, we will need to preserve the
13503 // first-qualifier-in-scope here, just in case we had a dependent
13504 // base (and therefore couldn't do the check) and a
13505 // nested-name-qualifier (and therefore could do the lookup).
13506 NamedDecl *FirstQualifierInScope = nullptr;
13507 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13508 if (MemberNameInfo.getName()) {
13509 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13510 if (!MemberNameInfo.getName())
13511 return ExprError();
13512 }
13513
13514 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13515 E->isArrow(),
13516 QualifierLoc,
13517 TemplateKWLoc,
13518 MemberNameInfo,
13519 Member,
13520 FoundDecl,
13521 (E->hasExplicitTemplateArgs()
13522 ? &TransArgs : nullptr),
13523 FirstQualifierInScope);
13524 }
13525
13526 template<typename Derived>
13527 ExprResult
TransformBinaryOperator(BinaryOperator * E)13528 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13529 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13530 if (LHS.isInvalid())
13531 return ExprError();
13532
13533 ExprResult RHS =
13534 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13535 if (RHS.isInvalid())
13536 return ExprError();
13537
13538 if (!getDerived().AlwaysRebuild() &&
13539 LHS.get() == E->getLHS() &&
13540 RHS.get() == E->getRHS())
13541 return E;
13542
13543 if (E->isCompoundAssignmentOp())
13544 // FPFeatures has already been established from trailing storage
13545 return getDerived().RebuildBinaryOperator(
13546 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13547 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13548 FPOptionsOverride NewOverrides(E->getFPFeatures());
13549 getSema().CurFPFeatures =
13550 NewOverrides.applyOverrides(getSema().getLangOpts());
13551 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13552 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13553 LHS.get(), RHS.get());
13554 }
13555
13556 template <typename Derived>
TransformCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator * E)13557 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13558 CXXRewrittenBinaryOperator *E) {
13559 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13560
13561 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13562 if (LHS.isInvalid())
13563 return ExprError();
13564
13565 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13566 if (RHS.isInvalid())
13567 return ExprError();
13568
13569 // Extract the already-resolved callee declarations so that we can restrict
13570 // ourselves to using them as the unqualified lookup results when rebuilding.
13571 UnresolvedSet<2> UnqualLookups;
13572 bool ChangedAnyLookups = false;
13573 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13574 const_cast<Expr *>(Decomp.InnerBinOp)};
13575 for (Expr *PossibleBinOp : PossibleBinOps) {
13576 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
13577 if (!Op)
13578 continue;
13579 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
13580 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
13581 continue;
13582
13583 // Transform the callee in case we built a call to a local extern
13584 // declaration.
13585 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13586 E->getOperatorLoc(), Callee->getFoundDecl()));
13587 if (!Found)
13588 return ExprError();
13589 if (Found != Callee->getFoundDecl())
13590 ChangedAnyLookups = true;
13591 UnqualLookups.addDecl(Found);
13592 }
13593
13594 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13595 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13596 // Mark all functions used in the rewrite as referenced. Note that when
13597 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13598 // function calls, and/or there might be a user-defined conversion sequence
13599 // applied to the operands of the <.
13600 // FIXME: this is a bit instantiation-specific.
13601 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13602 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
13603 return E;
13604 }
13605
13606 return getDerived().RebuildCXXRewrittenBinaryOperator(
13607 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13608 }
13609
13610 template<typename Derived>
13611 ExprResult
TransformCompoundAssignOperator(CompoundAssignOperator * E)13612 TreeTransform<Derived>::TransformCompoundAssignOperator(
13613 CompoundAssignOperator *E) {
13614 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13615 FPOptionsOverride NewOverrides(E->getFPFeatures());
13616 getSema().CurFPFeatures =
13617 NewOverrides.applyOverrides(getSema().getLangOpts());
13618 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13619 return getDerived().TransformBinaryOperator(E);
13620 }
13621
13622 template<typename Derived>
13623 ExprResult TreeTransform<Derived>::
TransformBinaryConditionalOperator(BinaryConditionalOperator * e)13624 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13625 // Just rebuild the common and RHS expressions and see whether we
13626 // get any changes.
13627
13628 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13629 if (commonExpr.isInvalid())
13630 return ExprError();
13631
13632 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13633 if (rhs.isInvalid())
13634 return ExprError();
13635
13636 if (!getDerived().AlwaysRebuild() &&
13637 commonExpr.get() == e->getCommon() &&
13638 rhs.get() == e->getFalseExpr())
13639 return e;
13640
13641 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13642 e->getQuestionLoc(),
13643 nullptr,
13644 e->getColonLoc(),
13645 rhs.get());
13646 }
13647
13648 template<typename Derived>
13649 ExprResult
TransformConditionalOperator(ConditionalOperator * E)13650 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13651 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13652 if (Cond.isInvalid())
13653 return ExprError();
13654
13655 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13656 if (LHS.isInvalid())
13657 return ExprError();
13658
13659 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13660 if (RHS.isInvalid())
13661 return ExprError();
13662
13663 if (!getDerived().AlwaysRebuild() &&
13664 Cond.get() == E->getCond() &&
13665 LHS.get() == E->getLHS() &&
13666 RHS.get() == E->getRHS())
13667 return E;
13668
13669 return getDerived().RebuildConditionalOperator(Cond.get(),
13670 E->getQuestionLoc(),
13671 LHS.get(),
13672 E->getColonLoc(),
13673 RHS.get());
13674 }
13675
13676 template<typename Derived>
13677 ExprResult
TransformImplicitCastExpr(ImplicitCastExpr * E)13678 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13679 // Implicit casts are eliminated during transformation, since they
13680 // will be recomputed by semantic analysis after transformation.
13681 return getDerived().TransformExpr(E->getSubExprAsWritten());
13682 }
13683
13684 template<typename Derived>
13685 ExprResult
TransformCStyleCastExpr(CStyleCastExpr * E)13686 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13687 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13688 if (!Type)
13689 return ExprError();
13690
13691 ExprResult SubExpr
13692 = getDerived().TransformExpr(E->getSubExprAsWritten());
13693 if (SubExpr.isInvalid())
13694 return ExprError();
13695
13696 if (!getDerived().AlwaysRebuild() &&
13697 Type == E->getTypeInfoAsWritten() &&
13698 SubExpr.get() == E->getSubExpr())
13699 return E;
13700
13701 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13702 Type,
13703 E->getRParenLoc(),
13704 SubExpr.get());
13705 }
13706
13707 template<typename Derived>
13708 ExprResult
TransformCompoundLiteralExpr(CompoundLiteralExpr * E)13709 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13710 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13711 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13712 if (!NewT)
13713 return ExprError();
13714
13715 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13716 if (Init.isInvalid())
13717 return ExprError();
13718
13719 if (!getDerived().AlwaysRebuild() &&
13720 OldT == NewT &&
13721 Init.get() == E->getInitializer())
13722 return SemaRef.MaybeBindToTemporary(E);
13723
13724 // Note: the expression type doesn't necessarily match the
13725 // type-as-written, but that's okay, because it should always be
13726 // derivable from the initializer.
13727
13728 return getDerived().RebuildCompoundLiteralExpr(
13729 E->getLParenLoc(), NewT,
13730 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13731 }
13732
13733 template<typename Derived>
13734 ExprResult
TransformExtVectorElementExpr(ExtVectorElementExpr * E)13735 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13736 ExprResult Base = getDerived().TransformExpr(E->getBase());
13737 if (Base.isInvalid())
13738 return ExprError();
13739
13740 if (!getDerived().AlwaysRebuild() &&
13741 Base.get() == E->getBase())
13742 return E;
13743
13744 // FIXME: Bad source location
13745 SourceLocation FakeOperatorLoc =
13746 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
13747 return getDerived().RebuildExtVectorElementExpr(
13748 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13749 E->getAccessor());
13750 }
13751
13752 template<typename Derived>
13753 ExprResult
TransformInitListExpr(InitListExpr * E)13754 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13755 if (InitListExpr *Syntactic = E->getSyntacticForm())
13756 E = Syntactic;
13757
13758 bool InitChanged = false;
13759
13760 EnterExpressionEvaluationContext Context(
13761 getSema(), EnterExpressionEvaluationContext::InitList);
13762
13763 SmallVector<Expr*, 4> Inits;
13764 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13765 Inits, &InitChanged))
13766 return ExprError();
13767
13768 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13769 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13770 // in some cases. We can't reuse it in general, because the syntactic and
13771 // semantic forms are linked, and we can't know that semantic form will
13772 // match even if the syntactic form does.
13773 }
13774
13775 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13776 E->getRBraceLoc());
13777 }
13778
13779 template<typename Derived>
13780 ExprResult
TransformDesignatedInitExpr(DesignatedInitExpr * E)13781 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13782 Designation Desig;
13783
13784 // transform the initializer value
13785 ExprResult Init = getDerived().TransformExpr(E->getInit());
13786 if (Init.isInvalid())
13787 return ExprError();
13788
13789 // transform the designators.
13790 SmallVector<Expr*, 4> ArrayExprs;
13791 bool ExprChanged = false;
13792 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13793 if (D.isFieldDesignator()) {
13794 if (D.getFieldDecl()) {
13795 FieldDecl *Field = cast_or_null<FieldDecl>(
13796 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13797 if (Field != D.getFieldDecl())
13798 // Rebuild the expression when the transformed FieldDecl is
13799 // different to the already assigned FieldDecl.
13800 ExprChanged = true;
13801 if (Field->isAnonymousStructOrUnion())
13802 continue;
13803 } else {
13804 // Ensure that the designator expression is rebuilt when there isn't
13805 // a resolved FieldDecl in the designator as we don't want to assign
13806 // a FieldDecl to a pattern designator that will be instantiated again.
13807 ExprChanged = true;
13808 }
13809 Desig.AddDesignator(Designator::CreateFieldDesignator(
13810 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
13811 continue;
13812 }
13813
13814 if (D.isArrayDesignator()) {
13815 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13816 if (Index.isInvalid())
13817 return ExprError();
13818
13819 Desig.AddDesignator(
13820 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
13821
13822 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
13823 ArrayExprs.push_back(Index.get());
13824 continue;
13825 }
13826
13827 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13828 ExprResult Start
13829 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13830 if (Start.isInvalid())
13831 return ExprError();
13832
13833 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13834 if (End.isInvalid())
13835 return ExprError();
13836
13837 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
13838 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
13839
13840 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13841 End.get() != E->getArrayRangeEnd(D);
13842
13843 ArrayExprs.push_back(Start.get());
13844 ArrayExprs.push_back(End.get());
13845 }
13846
13847 if (!getDerived().AlwaysRebuild() &&
13848 Init.get() == E->getInit() &&
13849 !ExprChanged)
13850 return E;
13851
13852 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13853 E->getEqualOrColonLoc(),
13854 E->usesGNUSyntax(), Init.get());
13855 }
13856
13857 // Seems that if TransformInitListExpr() only works on the syntactic form of an
13858 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13859 template<typename Derived>
13860 ExprResult
TransformDesignatedInitUpdateExpr(DesignatedInitUpdateExpr * E)13861 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13862 DesignatedInitUpdateExpr *E) {
13863 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13864 "initializer");
13865 return ExprError();
13866 }
13867
13868 template<typename Derived>
13869 ExprResult
TransformNoInitExpr(NoInitExpr * E)13870 TreeTransform<Derived>::TransformNoInitExpr(
13871 NoInitExpr *E) {
13872 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13873 return ExprError();
13874 }
13875
13876 template<typename Derived>
13877 ExprResult
TransformArrayInitLoopExpr(ArrayInitLoopExpr * E)13878 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13879 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13880 return ExprError();
13881 }
13882
13883 template<typename Derived>
13884 ExprResult
TransformArrayInitIndexExpr(ArrayInitIndexExpr * E)13885 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13886 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13887 return ExprError();
13888 }
13889
13890 template<typename Derived>
13891 ExprResult
TransformImplicitValueInitExpr(ImplicitValueInitExpr * E)13892 TreeTransform<Derived>::TransformImplicitValueInitExpr(
13893 ImplicitValueInitExpr *E) {
13894 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13895
13896 // FIXME: Will we ever have proper type location here? Will we actually
13897 // need to transform the type?
13898 QualType T = getDerived().TransformType(E->getType());
13899 if (T.isNull())
13900 return ExprError();
13901
13902 if (!getDerived().AlwaysRebuild() &&
13903 T == E->getType())
13904 return E;
13905
13906 return getDerived().RebuildImplicitValueInitExpr(T);
13907 }
13908
13909 template<typename Derived>
13910 ExprResult
TransformVAArgExpr(VAArgExpr * E)13911 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13912 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13913 if (!TInfo)
13914 return ExprError();
13915
13916 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13917 if (SubExpr.isInvalid())
13918 return ExprError();
13919
13920 if (!getDerived().AlwaysRebuild() &&
13921 TInfo == E->getWrittenTypeInfo() &&
13922 SubExpr.get() == E->getSubExpr())
13923 return E;
13924
13925 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13926 TInfo, E->getRParenLoc());
13927 }
13928
13929 template<typename Derived>
13930 ExprResult
TransformParenListExpr(ParenListExpr * E)13931 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13932 bool ArgumentChanged = false;
13933 SmallVector<Expr*, 4> Inits;
13934 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
13935 &ArgumentChanged))
13936 return ExprError();
13937
13938 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13939 Inits,
13940 E->getRParenLoc());
13941 }
13942
13943 /// Transform an address-of-label expression.
13944 ///
13945 /// By default, the transformation of an address-of-label expression always
13946 /// rebuilds the expression, so that the label identifier can be resolved to
13947 /// the corresponding label statement by semantic analysis.
13948 template<typename Derived>
13949 ExprResult
TransformAddrLabelExpr(AddrLabelExpr * E)13950 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13951 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13952 E->getLabel());
13953 if (!LD)
13954 return ExprError();
13955
13956 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13957 cast<LabelDecl>(LD));
13958 }
13959
13960 template<typename Derived>
13961 ExprResult
TransformStmtExpr(StmtExpr * E)13962 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13963 SemaRef.ActOnStartStmtExpr();
13964 StmtResult SubStmt
13965 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13966 if (SubStmt.isInvalid()) {
13967 SemaRef.ActOnStmtExprError();
13968 return ExprError();
13969 }
13970
13971 unsigned OldDepth = E->getTemplateDepth();
13972 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13973
13974 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13975 SubStmt.get() == E->getSubStmt()) {
13976 // Calling this an 'error' is unintuitive, but it does the right thing.
13977 SemaRef.ActOnStmtExprError();
13978 return SemaRef.MaybeBindToTemporary(E);
13979 }
13980
13981 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13982 E->getRParenLoc(), NewDepth);
13983 }
13984
13985 template<typename Derived>
13986 ExprResult
TransformChooseExpr(ChooseExpr * E)13987 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13988 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13989 if (Cond.isInvalid())
13990 return ExprError();
13991
13992 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13993 if (LHS.isInvalid())
13994 return ExprError();
13995
13996 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13997 if (RHS.isInvalid())
13998 return ExprError();
13999
14000 if (!getDerived().AlwaysRebuild() &&
14001 Cond.get() == E->getCond() &&
14002 LHS.get() == E->getLHS() &&
14003 RHS.get() == E->getRHS())
14004 return E;
14005
14006 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14007 Cond.get(), LHS.get(), RHS.get(),
14008 E->getRParenLoc());
14009 }
14010
14011 template<typename Derived>
14012 ExprResult
TransformGNUNullExpr(GNUNullExpr * E)14013 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14014 return E;
14015 }
14016
14017 template<typename Derived>
14018 ExprResult
TransformCXXOperatorCallExpr(CXXOperatorCallExpr * E)14019 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14020 switch (E->getOperator()) {
14021 case OO_New:
14022 case OO_Delete:
14023 case OO_Array_New:
14024 case OO_Array_Delete:
14025 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14026
14027 case OO_Subscript:
14028 case OO_Call: {
14029 // This is a call to an object's operator().
14030 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14031
14032 // Transform the object itself.
14033 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
14034 if (Object.isInvalid())
14035 return ExprError();
14036
14037 // FIXME: Poor location information
14038 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
14039 static_cast<Expr *>(Object.get())->getEndLoc());
14040
14041 // Transform the call arguments.
14042 SmallVector<Expr*, 8> Args;
14043 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14044 Args))
14045 return ExprError();
14046
14047 if (E->getOperator() == OO_Subscript)
14048 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14049 Args, E->getEndLoc());
14050
14051 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14052 E->getEndLoc());
14053 }
14054
14055 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14056 case OO_##Name: \
14057 break;
14058
14059 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14060 #include "clang/Basic/OperatorKinds.def"
14061
14062 case OO_Conditional:
14063 llvm_unreachable("conditional operator is not actually overloadable");
14064
14065 case OO_None:
14066 case NUM_OVERLOADED_OPERATORS:
14067 llvm_unreachable("not an overloaded operator?");
14068 }
14069
14070 ExprResult First;
14071 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14072 First = getDerived().TransformAddressOfOperand(E->getArg(0));
14073 else
14074 First = getDerived().TransformExpr(E->getArg(0));
14075 if (First.isInvalid())
14076 return ExprError();
14077
14078 ExprResult Second;
14079 if (E->getNumArgs() == 2) {
14080 Second =
14081 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
14082 if (Second.isInvalid())
14083 return ExprError();
14084 }
14085
14086 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14087 FPOptionsOverride NewOverrides(E->getFPFeatures());
14088 getSema().CurFPFeatures =
14089 NewOverrides.applyOverrides(getSema().getLangOpts());
14090 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14091
14092 Expr *Callee = E->getCallee();
14093 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
14094 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14095 Sema::LookupOrdinaryName);
14096 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14097 return ExprError();
14098
14099 return getDerived().RebuildCXXOperatorCallExpr(
14100 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14101 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14102 }
14103
14104 UnresolvedSet<1> Functions;
14105 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
14106 Callee = ICE->getSubExprAsWritten();
14107 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
14108 ValueDecl *VD = cast_or_null<ValueDecl>(
14109 getDerived().TransformDecl(DR->getLocation(), DR));
14110 if (!VD)
14111 return ExprError();
14112
14113 if (!isa<CXXMethodDecl>(VD))
14114 Functions.addDecl(VD);
14115
14116 return getDerived().RebuildCXXOperatorCallExpr(
14117 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14118 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14119 }
14120
14121 template<typename Derived>
14122 ExprResult
TransformCXXMemberCallExpr(CXXMemberCallExpr * E)14123 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14124 return getDerived().TransformCallExpr(E);
14125 }
14126
14127 template <typename Derived>
TransformSourceLocExpr(SourceLocExpr * E)14128 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14129 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&
14130 getSema().CurContext != E->getParentContext();
14131
14132 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14133 return E;
14134
14135 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14136 E->getBeginLoc(), E->getEndLoc(),
14137 getSema().CurContext);
14138 }
14139
14140 template <typename Derived>
TransformEmbedExpr(EmbedExpr * E)14141 ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14142 return E;
14143 }
14144
14145 template<typename Derived>
14146 ExprResult
TransformCUDAKernelCallExpr(CUDAKernelCallExpr * E)14147 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14148 // Transform the callee.
14149 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14150 if (Callee.isInvalid())
14151 return ExprError();
14152
14153 // Transform exec config.
14154 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14155 if (EC.isInvalid())
14156 return ExprError();
14157
14158 // Transform arguments.
14159 bool ArgChanged = false;
14160 SmallVector<Expr*, 8> Args;
14161 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14162 &ArgChanged))
14163 return ExprError();
14164
14165 if (!getDerived().AlwaysRebuild() &&
14166 Callee.get() == E->getCallee() &&
14167 !ArgChanged)
14168 return SemaRef.MaybeBindToTemporary(E);
14169
14170 // FIXME: Wrong source location information for the '('.
14171 SourceLocation FakeLParenLoc
14172 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14173 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14174 Args,
14175 E->getRParenLoc(), EC.get());
14176 }
14177
14178 template<typename Derived>
14179 ExprResult
TransformCXXNamedCastExpr(CXXNamedCastExpr * E)14180 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14181 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14182 if (!Type)
14183 return ExprError();
14184
14185 ExprResult SubExpr
14186 = getDerived().TransformExpr(E->getSubExprAsWritten());
14187 if (SubExpr.isInvalid())
14188 return ExprError();
14189
14190 if (!getDerived().AlwaysRebuild() &&
14191 Type == E->getTypeInfoAsWritten() &&
14192 SubExpr.get() == E->getSubExpr())
14193 return E;
14194 return getDerived().RebuildCXXNamedCastExpr(
14195 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14196 Type, E->getAngleBrackets().getEnd(),
14197 // FIXME. this should be '(' location
14198 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14199 }
14200
14201 template<typename Derived>
14202 ExprResult
TransformBuiltinBitCastExpr(BuiltinBitCastExpr * BCE)14203 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14204 TypeSourceInfo *TSI =
14205 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14206 if (!TSI)
14207 return ExprError();
14208
14209 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14210 if (Sub.isInvalid())
14211 return ExprError();
14212
14213 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14214 Sub.get(), BCE->getEndLoc());
14215 }
14216
14217 template<typename Derived>
14218 ExprResult
TransformCXXStaticCastExpr(CXXStaticCastExpr * E)14219 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14220 return getDerived().TransformCXXNamedCastExpr(E);
14221 }
14222
14223 template<typename Derived>
14224 ExprResult
TransformCXXDynamicCastExpr(CXXDynamicCastExpr * E)14225 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14226 return getDerived().TransformCXXNamedCastExpr(E);
14227 }
14228
14229 template<typename Derived>
14230 ExprResult
TransformCXXReinterpretCastExpr(CXXReinterpretCastExpr * E)14231 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14232 CXXReinterpretCastExpr *E) {
14233 return getDerived().TransformCXXNamedCastExpr(E);
14234 }
14235
14236 template<typename Derived>
14237 ExprResult
TransformCXXConstCastExpr(CXXConstCastExpr * E)14238 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14239 return getDerived().TransformCXXNamedCastExpr(E);
14240 }
14241
14242 template<typename Derived>
14243 ExprResult
TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr * E)14244 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14245 return getDerived().TransformCXXNamedCastExpr(E);
14246 }
14247
14248 template<typename Derived>
14249 ExprResult
TransformCXXFunctionalCastExpr(CXXFunctionalCastExpr * E)14250 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14251 CXXFunctionalCastExpr *E) {
14252 TypeSourceInfo *Type =
14253 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14254 if (!Type)
14255 return ExprError();
14256
14257 ExprResult SubExpr
14258 = getDerived().TransformExpr(E->getSubExprAsWritten());
14259 if (SubExpr.isInvalid())
14260 return ExprError();
14261
14262 if (!getDerived().AlwaysRebuild() &&
14263 Type == E->getTypeInfoAsWritten() &&
14264 SubExpr.get() == E->getSubExpr())
14265 return E;
14266
14267 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14268 E->getLParenLoc(),
14269 SubExpr.get(),
14270 E->getRParenLoc(),
14271 E->isListInitialization());
14272 }
14273
14274 template<typename Derived>
14275 ExprResult
TransformCXXTypeidExpr(CXXTypeidExpr * E)14276 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14277 if (E->isTypeOperand()) {
14278 TypeSourceInfo *TInfo
14279 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14280 if (!TInfo)
14281 return ExprError();
14282
14283 if (!getDerived().AlwaysRebuild() &&
14284 TInfo == E->getTypeOperandSourceInfo())
14285 return E;
14286
14287 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14288 TInfo, E->getEndLoc());
14289 }
14290
14291 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14292 // type. We must not unilaterally enter unevaluated context here, as then
14293 // semantic processing can re-transform an already transformed operand.
14294 Expr *Op = E->getExprOperand();
14295 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14296 if (E->isGLValue())
14297 if (auto *RecordT = Op->getType()->getAs<RecordType>())
14298 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
14299 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14300
14301 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14302 Sema::ReuseLambdaContextDecl);
14303
14304 ExprResult SubExpr = getDerived().TransformExpr(Op);
14305 if (SubExpr.isInvalid())
14306 return ExprError();
14307
14308 if (!getDerived().AlwaysRebuild() &&
14309 SubExpr.get() == E->getExprOperand())
14310 return E;
14311
14312 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14313 SubExpr.get(), E->getEndLoc());
14314 }
14315
14316 template<typename Derived>
14317 ExprResult
TransformCXXUuidofExpr(CXXUuidofExpr * E)14318 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14319 if (E->isTypeOperand()) {
14320 TypeSourceInfo *TInfo
14321 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14322 if (!TInfo)
14323 return ExprError();
14324
14325 if (!getDerived().AlwaysRebuild() &&
14326 TInfo == E->getTypeOperandSourceInfo())
14327 return E;
14328
14329 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14330 TInfo, E->getEndLoc());
14331 }
14332
14333 EnterExpressionEvaluationContext Unevaluated(
14334 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14335
14336 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14337 if (SubExpr.isInvalid())
14338 return ExprError();
14339
14340 if (!getDerived().AlwaysRebuild() &&
14341 SubExpr.get() == E->getExprOperand())
14342 return E;
14343
14344 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14345 SubExpr.get(), E->getEndLoc());
14346 }
14347
14348 template<typename Derived>
14349 ExprResult
TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr * E)14350 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14351 return E;
14352 }
14353
14354 template<typename Derived>
14355 ExprResult
TransformCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr * E)14356 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14357 CXXNullPtrLiteralExpr *E) {
14358 return E;
14359 }
14360
14361 template<typename Derived>
14362 ExprResult
TransformCXXThisExpr(CXXThisExpr * E)14363 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14364
14365 // In lambdas, the qualifiers of the type depends of where in
14366 // the call operator `this` appear, and we do not have a good way to
14367 // rebuild this information, so we transform the type.
14368 //
14369 // In other contexts, the type of `this` may be overrided
14370 // for type deduction, so we need to recompute it.
14371 //
14372 // Always recompute the type if we're in the body of a lambda, and
14373 // 'this' is dependent on a lambda's explicit object parameter.
14374 QualType T = [&]() {
14375 auto &S = getSema();
14376 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14377 return S.getCurrentThisType();
14378 if (S.getCurLambda())
14379 return getDerived().TransformType(E->getType());
14380 return S.getCurrentThisType();
14381 }();
14382
14383 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
14384 // Mark it referenced in the new context regardless.
14385 // FIXME: this is a bit instantiation-specific.
14386 getSema().MarkThisReferenced(E);
14387 return E;
14388 }
14389
14390 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14391 }
14392
14393 template<typename Derived>
14394 ExprResult
TransformCXXThrowExpr(CXXThrowExpr * E)14395 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14396 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14397 if (SubExpr.isInvalid())
14398 return ExprError();
14399
14400 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14401
14402 if (!getDerived().AlwaysRebuild() &&
14403 SubExpr.get() == E->getSubExpr())
14404 return E;
14405
14406 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14407 E->isThrownVariableInScope());
14408 }
14409
14410 template<typename Derived>
14411 ExprResult
TransformCXXDefaultArgExpr(CXXDefaultArgExpr * E)14412 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14413 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14414 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14415 if (!Param)
14416 return ExprError();
14417
14418 ExprResult InitRes;
14419 if (E->hasRewrittenInit()) {
14420 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14421 if (InitRes.isInvalid())
14422 return ExprError();
14423 }
14424
14425 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14426 E->getUsedContext() == SemaRef.CurContext &&
14427 InitRes.get() == E->getRewrittenExpr())
14428 return E;
14429
14430 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14431 InitRes.get());
14432 }
14433
14434 template<typename Derived>
14435 ExprResult
TransformCXXDefaultInitExpr(CXXDefaultInitExpr * E)14436 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14437 FieldDecl *Field = cast_or_null<FieldDecl>(
14438 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14439 if (!Field)
14440 return ExprError();
14441
14442 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14443 E->getUsedContext() == SemaRef.CurContext)
14444 return E;
14445
14446 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14447 }
14448
14449 template<typename Derived>
14450 ExprResult
TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr * E)14451 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14452 CXXScalarValueInitExpr *E) {
14453 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14454 if (!T)
14455 return ExprError();
14456
14457 if (!getDerived().AlwaysRebuild() &&
14458 T == E->getTypeSourceInfo())
14459 return E;
14460
14461 return getDerived().RebuildCXXScalarValueInitExpr(T,
14462 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14463 E->getRParenLoc());
14464 }
14465
14466 template<typename Derived>
14467 ExprResult
TransformCXXNewExpr(CXXNewExpr * E)14468 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14469 // Transform the type that we're allocating
14470 TypeSourceInfo *AllocTypeInfo =
14471 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14472 if (!AllocTypeInfo)
14473 return ExprError();
14474
14475 // Transform the size of the array we're allocating (if any).
14476 std::optional<Expr *> ArraySize;
14477 if (E->isArray()) {
14478 ExprResult NewArraySize;
14479 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14480 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14481 if (NewArraySize.isInvalid())
14482 return ExprError();
14483 }
14484 ArraySize = NewArraySize.get();
14485 }
14486
14487 // Transform the placement arguments (if any).
14488 bool ArgumentChanged = false;
14489 SmallVector<Expr*, 8> PlacementArgs;
14490 if (getDerived().TransformExprs(E->getPlacementArgs(),
14491 E->getNumPlacementArgs(), true,
14492 PlacementArgs, &ArgumentChanged))
14493 return ExprError();
14494
14495 // Transform the initializer (if any).
14496 Expr *OldInit = E->getInitializer();
14497 ExprResult NewInit;
14498 if (OldInit)
14499 NewInit = getDerived().TransformInitializer(OldInit, true);
14500 if (NewInit.isInvalid())
14501 return ExprError();
14502
14503 // Transform new operator and delete operator.
14504 FunctionDecl *OperatorNew = nullptr;
14505 if (E->getOperatorNew()) {
14506 OperatorNew = cast_or_null<FunctionDecl>(
14507 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14508 if (!OperatorNew)
14509 return ExprError();
14510 }
14511
14512 FunctionDecl *OperatorDelete = nullptr;
14513 if (E->getOperatorDelete()) {
14514 OperatorDelete = cast_or_null<FunctionDecl>(
14515 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14516 if (!OperatorDelete)
14517 return ExprError();
14518 }
14519
14520 if (!getDerived().AlwaysRebuild() &&
14521 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14522 ArraySize == E->getArraySize() &&
14523 NewInit.get() == OldInit &&
14524 OperatorNew == E->getOperatorNew() &&
14525 OperatorDelete == E->getOperatorDelete() &&
14526 !ArgumentChanged) {
14527 // Mark any declarations we need as referenced.
14528 // FIXME: instantiation-specific.
14529 if (OperatorNew)
14530 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
14531 if (OperatorDelete)
14532 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
14533
14534 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14535 QualType ElementType
14536 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
14537 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
14538 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
14539 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
14540 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
14541 }
14542 }
14543 }
14544
14545 return E;
14546 }
14547
14548 QualType AllocType = AllocTypeInfo->getType();
14549 if (!ArraySize) {
14550 // If no array size was specified, but the new expression was
14551 // instantiated with an array type (e.g., "new T" where T is
14552 // instantiated with "int[4]"), extract the outer bound from the
14553 // array type as our array size. We do this with constant and
14554 // dependently-sized array types.
14555 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
14556 if (!ArrayT) {
14557 // Do nothing
14558 } else if (const ConstantArrayType *ConsArrayT
14559 = dyn_cast<ConstantArrayType>(ArrayT)) {
14560 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
14561 SemaRef.Context.getSizeType(),
14562 /*FIXME:*/ E->getBeginLoc());
14563 AllocType = ConsArrayT->getElementType();
14564 } else if (const DependentSizedArrayType *DepArrayT
14565 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
14566 if (DepArrayT->getSizeExpr()) {
14567 ArraySize = DepArrayT->getSizeExpr();
14568 AllocType = DepArrayT->getElementType();
14569 }
14570 }
14571 }
14572
14573 return getDerived().RebuildCXXNewExpr(
14574 E->getBeginLoc(), E->isGlobalNew(),
14575 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14576 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14577 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14578 }
14579
14580 template<typename Derived>
14581 ExprResult
TransformCXXDeleteExpr(CXXDeleteExpr * E)14582 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14583 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14584 if (Operand.isInvalid())
14585 return ExprError();
14586
14587 // Transform the delete operator, if known.
14588 FunctionDecl *OperatorDelete = nullptr;
14589 if (E->getOperatorDelete()) {
14590 OperatorDelete = cast_or_null<FunctionDecl>(
14591 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14592 if (!OperatorDelete)
14593 return ExprError();
14594 }
14595
14596 if (!getDerived().AlwaysRebuild() &&
14597 Operand.get() == E->getArgument() &&
14598 OperatorDelete == E->getOperatorDelete()) {
14599 // Mark any declarations we need as referenced.
14600 // FIXME: instantiation-specific.
14601 if (OperatorDelete)
14602 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
14603
14604 if (!E->getArgument()->isTypeDependent()) {
14605 QualType Destroyed = SemaRef.Context.getBaseElementType(
14606 E->getDestroyedType());
14607 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
14608 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
14609 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
14610 SemaRef.LookupDestructor(Record));
14611 }
14612 }
14613
14614 return E;
14615 }
14616
14617 return getDerived().RebuildCXXDeleteExpr(
14618 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14619 }
14620
14621 template<typename Derived>
14622 ExprResult
TransformCXXPseudoDestructorExpr(CXXPseudoDestructorExpr * E)14623 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14624 CXXPseudoDestructorExpr *E) {
14625 ExprResult Base = getDerived().TransformExpr(E->getBase());
14626 if (Base.isInvalid())
14627 return ExprError();
14628
14629 ParsedType ObjectTypePtr;
14630 bool MayBePseudoDestructor = false;
14631 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
14632 E->getOperatorLoc(),
14633 E->isArrow()? tok::arrow : tok::period,
14634 ObjectTypePtr,
14635 MayBePseudoDestructor);
14636 if (Base.isInvalid())
14637 return ExprError();
14638
14639 QualType ObjectType = ObjectTypePtr.get();
14640 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14641 if (QualifierLoc) {
14642 QualifierLoc
14643 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14644 if (!QualifierLoc)
14645 return ExprError();
14646 }
14647 CXXScopeSpec SS;
14648 SS.Adopt(QualifierLoc);
14649
14650 PseudoDestructorTypeStorage Destroyed;
14651 if (E->getDestroyedTypeInfo()) {
14652 TypeSourceInfo *DestroyedTypeInfo
14653 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
14654 ObjectType, nullptr, SS);
14655 if (!DestroyedTypeInfo)
14656 return ExprError();
14657 Destroyed = DestroyedTypeInfo;
14658 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14659 // We aren't likely to be able to resolve the identifier down to a type
14660 // now anyway, so just retain the identifier.
14661 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14662 E->getDestroyedTypeLoc());
14663 } else {
14664 // Look for a destructor known with the given name.
14665 ParsedType T = SemaRef.getDestructorName(
14666 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
14667 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
14668 if (!T)
14669 return ExprError();
14670
14671 Destroyed
14672 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
14673 E->getDestroyedTypeLoc());
14674 }
14675
14676 TypeSourceInfo *ScopeTypeInfo = nullptr;
14677 if (E->getScopeTypeInfo()) {
14678 CXXScopeSpec EmptySS;
14679 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14680 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14681 if (!ScopeTypeInfo)
14682 return ExprError();
14683 }
14684
14685 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14686 E->getOperatorLoc(),
14687 E->isArrow(),
14688 SS,
14689 ScopeTypeInfo,
14690 E->getColonColonLoc(),
14691 E->getTildeLoc(),
14692 Destroyed);
14693 }
14694
14695 template <typename Derived>
TransformOverloadExprDecls(OverloadExpr * Old,bool RequiresADL,LookupResult & R)14696 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14697 bool RequiresADL,
14698 LookupResult &R) {
14699 // Transform all the decls.
14700 bool AllEmptyPacks = true;
14701 for (auto *OldD : Old->decls()) {
14702 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14703 if (!InstD) {
14704 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14705 // This can happen because of dependent hiding.
14706 if (isa<UsingShadowDecl>(OldD))
14707 continue;
14708 else {
14709 R.clear();
14710 return true;
14711 }
14712 }
14713
14714 // Expand using pack declarations.
14715 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
14716 ArrayRef<NamedDecl*> Decls = SingleDecl;
14717 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
14718 Decls = UPD->expansions();
14719
14720 // Expand using declarations.
14721 for (auto *D : Decls) {
14722 if (auto *UD = dyn_cast<UsingDecl>(D)) {
14723 for (auto *SD : UD->shadows())
14724 R.addDecl(SD);
14725 } else {
14726 R.addDecl(D);
14727 }
14728 }
14729
14730 AllEmptyPacks &= Decls.empty();
14731 }
14732
14733 // C++ [temp.res]/8.4.2:
14734 // The program is ill-formed, no diagnostic required, if [...] lookup for
14735 // a name in the template definition found a using-declaration, but the
14736 // lookup in the corresponding scope in the instantiation odoes not find
14737 // any declarations because the using-declaration was a pack expansion and
14738 // the corresponding pack is empty
14739 if (AllEmptyPacks && !RequiresADL) {
14740 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14741 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
14742 return true;
14743 }
14744
14745 // Resolve a kind, but don't do any further analysis. If it's
14746 // ambiguous, the callee needs to deal with it.
14747 R.resolveKind();
14748
14749 if (Old->hasTemplateKeyword() && !R.empty()) {
14750 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14751 getSema().FilterAcceptableTemplateNames(R,
14752 /*AllowFunctionTemplates=*/true,
14753 /*AllowDependent=*/true);
14754 if (R.empty()) {
14755 // If a 'template' keyword was used, a lookup that finds only non-template
14756 // names is an error.
14757 getSema().Diag(R.getNameLoc(),
14758 diag::err_template_kw_refers_to_non_template)
14759 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14760 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14761 getSema().Diag(FoundDecl->getLocation(),
14762 diag::note_template_kw_refers_to_non_template)
14763 << R.getLookupName();
14764 return true;
14765 }
14766 }
14767
14768 return false;
14769 }
14770
14771 template <typename Derived>
TransformUnresolvedLookupExpr(UnresolvedLookupExpr * Old)14772 ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14773 UnresolvedLookupExpr *Old) {
14774 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14775 }
14776
14777 template <typename Derived>
14778 ExprResult
TransformUnresolvedLookupExpr(UnresolvedLookupExpr * Old,bool IsAddressOfOperand)14779 TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
14780 bool IsAddressOfOperand) {
14781 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14782 Sema::LookupOrdinaryName);
14783
14784 // Transform the declaration set.
14785 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
14786 return ExprError();
14787
14788 // Rebuild the nested-name qualifier, if present.
14789 CXXScopeSpec SS;
14790 if (Old->getQualifierLoc()) {
14791 NestedNameSpecifierLoc QualifierLoc
14792 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14793 if (!QualifierLoc)
14794 return ExprError();
14795
14796 SS.Adopt(QualifierLoc);
14797 }
14798
14799 if (Old->getNamingClass()) {
14800 CXXRecordDecl *NamingClass
14801 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14802 Old->getNameLoc(),
14803 Old->getNamingClass()));
14804 if (!NamingClass) {
14805 R.clear();
14806 return ExprError();
14807 }
14808
14809 R.setNamingClass(NamingClass);
14810 }
14811
14812 // Rebuild the template arguments, if any.
14813 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14814 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14815 if (Old->hasExplicitTemplateArgs() &&
14816 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14817 Old->getNumTemplateArgs(),
14818 TransArgs)) {
14819 R.clear();
14820 return ExprError();
14821 }
14822
14823 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14824 // a non-static data member is named in an unevaluated operand, or when
14825 // a member is named in a dependent class scope function template explicit
14826 // specialization that is neither declared static nor with an explicit object
14827 // parameter.
14828 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14829 return SemaRef.BuildPossibleImplicitMemberExpr(
14830 SS, TemplateKWLoc, R,
14831 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14832 /*S=*/nullptr);
14833
14834 // If we have neither explicit template arguments, nor the template keyword,
14835 // it's a normal declaration name or member reference.
14836 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14837 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14838
14839 // If we have template arguments, then rebuild the template-id expression.
14840 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14841 Old->requiresADL(), &TransArgs);
14842 }
14843
14844 template<typename Derived>
14845 ExprResult
TransformTypeTraitExpr(TypeTraitExpr * E)14846 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14847 bool ArgChanged = false;
14848 SmallVector<TypeSourceInfo *, 4> Args;
14849 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14850 TypeSourceInfo *From = E->getArg(I);
14851 TypeLoc FromTL = From->getTypeLoc();
14852 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14853 TypeLocBuilder TLB;
14854 TLB.reserve(FromTL.getFullDataSize());
14855 QualType To = getDerived().TransformType(TLB, FromTL);
14856 if (To.isNull())
14857 return ExprError();
14858
14859 if (To == From->getType())
14860 Args.push_back(From);
14861 else {
14862 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14863 ArgChanged = true;
14864 }
14865 continue;
14866 }
14867
14868 ArgChanged = true;
14869
14870 // We have a pack expansion. Instantiate it.
14871 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14872 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14873 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14874 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
14875
14876 // Determine whether the set of unexpanded parameter packs can and should
14877 // be expanded.
14878 bool Expand = true;
14879 bool RetainExpansion = false;
14880 UnsignedOrNone OrigNumExpansions =
14881 ExpansionTL.getTypePtr()->getNumExpansions();
14882 UnsignedOrNone NumExpansions = OrigNumExpansions;
14883 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14884 PatternTL.getSourceRange(),
14885 Unexpanded,
14886 Expand, RetainExpansion,
14887 NumExpansions))
14888 return ExprError();
14889
14890 if (!Expand) {
14891 // The transform has determined that we should perform a simple
14892 // transformation on the pack expansion, producing another pack
14893 // expansion.
14894 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
14895
14896 TypeLocBuilder TLB;
14897 TLB.reserve(From->getTypeLoc().getFullDataSize());
14898
14899 QualType To = getDerived().TransformType(TLB, PatternTL);
14900 if (To.isNull())
14901 return ExprError();
14902
14903 To = getDerived().RebuildPackExpansionType(To,
14904 PatternTL.getSourceRange(),
14905 ExpansionTL.getEllipsisLoc(),
14906 NumExpansions);
14907 if (To.isNull())
14908 return ExprError();
14909
14910 PackExpansionTypeLoc ToExpansionTL
14911 = TLB.push<PackExpansionTypeLoc>(To);
14912 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14913 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14914 continue;
14915 }
14916
14917 // Expand the pack expansion by substituting for each argument in the
14918 // pack(s).
14919 for (unsigned I = 0; I != *NumExpansions; ++I) {
14920 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
14921 TypeLocBuilder TLB;
14922 TLB.reserve(PatternTL.getFullDataSize());
14923 QualType To = getDerived().TransformType(TLB, PatternTL);
14924 if (To.isNull())
14925 return ExprError();
14926
14927 if (To->containsUnexpandedParameterPack()) {
14928 To = getDerived().RebuildPackExpansionType(To,
14929 PatternTL.getSourceRange(),
14930 ExpansionTL.getEllipsisLoc(),
14931 NumExpansions);
14932 if (To.isNull())
14933 return ExprError();
14934
14935 PackExpansionTypeLoc ToExpansionTL
14936 = TLB.push<PackExpansionTypeLoc>(To);
14937 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14938 }
14939
14940 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14941 }
14942
14943 if (!RetainExpansion)
14944 continue;
14945
14946 // If we're supposed to retain a pack expansion, do so by temporarily
14947 // forgetting the partially-substituted parameter pack.
14948 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14949
14950 TypeLocBuilder TLB;
14951 TLB.reserve(From->getTypeLoc().getFullDataSize());
14952
14953 QualType To = getDerived().TransformType(TLB, PatternTL);
14954 if (To.isNull())
14955 return ExprError();
14956
14957 To = getDerived().RebuildPackExpansionType(To,
14958 PatternTL.getSourceRange(),
14959 ExpansionTL.getEllipsisLoc(),
14960 NumExpansions);
14961 if (To.isNull())
14962 return ExprError();
14963
14964 PackExpansionTypeLoc ToExpansionTL
14965 = TLB.push<PackExpansionTypeLoc>(To);
14966 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14967 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14968 }
14969
14970 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14971 return E;
14972
14973 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14974 E->getEndLoc());
14975 }
14976
14977 template<typename Derived>
14978 ExprResult
TransformConceptSpecializationExpr(ConceptSpecializationExpr * E)14979 TreeTransform<Derived>::TransformConceptSpecializationExpr(
14980 ConceptSpecializationExpr *E) {
14981 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14982 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14983 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14984 Old->NumTemplateArgs, TransArgs))
14985 return ExprError();
14986
14987 return getDerived().RebuildConceptSpecializationExpr(
14988 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14989 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14990 &TransArgs);
14991 }
14992
14993 template<typename Derived>
14994 ExprResult
TransformRequiresExpr(RequiresExpr * E)14995 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14996 SmallVector<ParmVarDecl*, 4> TransParams;
14997 SmallVector<QualType, 4> TransParamTypes;
14998 Sema::ExtParameterInfoBuilder ExtParamInfos;
14999
15000 // C++2a [expr.prim.req]p2
15001 // Expressions appearing within a requirement-body are unevaluated operands.
15002 EnterExpressionEvaluationContext Ctx(
15003 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15004 Sema::ReuseLambdaContextDecl);
15005
15006 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15007 getSema().Context, getSema().CurContext,
15008 E->getBody()->getBeginLoc());
15009
15010 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15011
15012 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15013 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15014 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15015
15016 for (ParmVarDecl *Param : TransParams)
15017 if (Param)
15018 Param->setDeclContext(Body);
15019
15020 // On failure to transform, TransformRequiresTypeParams returns an expression
15021 // in the event that the transformation of the type params failed in some way.
15022 // It is expected that this will result in a 'not satisfied' Requires clause
15023 // when instantiating.
15024 if (!TypeParamResult.isUnset())
15025 return TypeParamResult;
15026
15027 SmallVector<concepts::Requirement *, 4> TransReqs;
15028 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15029 TransReqs))
15030 return ExprError();
15031
15032 for (concepts::Requirement *Req : TransReqs) {
15033 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
15034 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15035 ER->getReturnTypeRequirement()
15036 .getTypeConstraintTemplateParameterList()->getParam(0)
15037 ->setDeclContext(Body);
15038 }
15039 }
15040 }
15041
15042 return getDerived().RebuildRequiresExpr(
15043 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15044 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15045 }
15046
15047 template<typename Derived>
TransformRequiresExprRequirements(ArrayRef<concepts::Requirement * > Reqs,SmallVectorImpl<concepts::Requirement * > & Transformed)15048 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15049 ArrayRef<concepts::Requirement *> Reqs,
15050 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15051 for (concepts::Requirement *Req : Reqs) {
15052 concepts::Requirement *TransReq = nullptr;
15053 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
15054 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15055 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
15056 TransReq = getDerived().TransformExprRequirement(ExprReq);
15057 else
15058 TransReq = getDerived().TransformNestedRequirement(
15059 cast<concepts::NestedRequirement>(Req));
15060 if (!TransReq)
15061 return true;
15062 Transformed.push_back(TransReq);
15063 }
15064 return false;
15065 }
15066
15067 template<typename Derived>
15068 concepts::TypeRequirement *
TransformTypeRequirement(concepts::TypeRequirement * Req)15069 TreeTransform<Derived>::TransformTypeRequirement(
15070 concepts::TypeRequirement *Req) {
15071 if (Req->isSubstitutionFailure()) {
15072 if (getDerived().AlwaysRebuild())
15073 return getDerived().RebuildTypeRequirement(
15074 Req->getSubstitutionDiagnostic());
15075 return Req;
15076 }
15077 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15078 if (!TransType)
15079 return nullptr;
15080 return getDerived().RebuildTypeRequirement(TransType);
15081 }
15082
15083 template<typename Derived>
15084 concepts::ExprRequirement *
TransformExprRequirement(concepts::ExprRequirement * Req)15085 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15086 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15087 if (Req->isExprSubstitutionFailure())
15088 TransExpr = Req->getExprSubstitutionDiagnostic();
15089 else {
15090 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15091 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15092 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
15093 if (TransExprRes.isInvalid())
15094 return nullptr;
15095 TransExpr = TransExprRes.get();
15096 }
15097
15098 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15099 const auto &RetReq = Req->getReturnTypeRequirement();
15100 if (RetReq.isEmpty())
15101 TransRetReq.emplace();
15102 else if (RetReq.isSubstitutionFailure())
15103 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
15104 else if (RetReq.isTypeConstraint()) {
15105 TemplateParameterList *OrigTPL =
15106 RetReq.getTypeConstraintTemplateParameterList();
15107 TemplateParameterList *TPL =
15108 getDerived().TransformTemplateParameterList(OrigTPL);
15109 if (!TPL)
15110 return nullptr;
15111 TransRetReq.emplace(TPL);
15112 }
15113 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15114 if (Expr *E = dyn_cast<Expr *>(TransExpr))
15115 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15116 Req->getNoexceptLoc(),
15117 std::move(*TransRetReq));
15118 return getDerived().RebuildExprRequirement(
15119 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),
15120 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15121 }
15122
15123 template<typename Derived>
15124 concepts::NestedRequirement *
TransformNestedRequirement(concepts::NestedRequirement * Req)15125 TreeTransform<Derived>::TransformNestedRequirement(
15126 concepts::NestedRequirement *Req) {
15127 if (Req->hasInvalidConstraint()) {
15128 if (getDerived().AlwaysRebuild())
15129 return getDerived().RebuildNestedRequirement(
15130 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15131 return Req;
15132 }
15133 ExprResult TransConstraint =
15134 getDerived().TransformExpr(Req->getConstraintExpr());
15135 if (TransConstraint.isInvalid())
15136 return nullptr;
15137 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15138 }
15139
15140 template<typename Derived>
15141 ExprResult
TransformArrayTypeTraitExpr(ArrayTypeTraitExpr * E)15142 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15143 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15144 if (!T)
15145 return ExprError();
15146
15147 if (!getDerived().AlwaysRebuild() &&
15148 T == E->getQueriedTypeSourceInfo())
15149 return E;
15150
15151 ExprResult SubExpr;
15152 {
15153 EnterExpressionEvaluationContext Unevaluated(
15154 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15155 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15156 if (SubExpr.isInvalid())
15157 return ExprError();
15158 }
15159
15160 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15161 SubExpr.get(), E->getEndLoc());
15162 }
15163
15164 template<typename Derived>
15165 ExprResult
TransformExpressionTraitExpr(ExpressionTraitExpr * E)15166 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15167 ExprResult SubExpr;
15168 {
15169 EnterExpressionEvaluationContext Unevaluated(
15170 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15171 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15172 if (SubExpr.isInvalid())
15173 return ExprError();
15174
15175 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15176 return E;
15177 }
15178
15179 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15180 SubExpr.get(), E->getEndLoc());
15181 }
15182
15183 template <typename Derived>
TransformParenDependentScopeDeclRefExpr(ParenExpr * PE,DependentScopeDeclRefExpr * DRE,bool AddrTaken,TypeSourceInfo ** RecoveryTSI)15184 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15185 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15186 TypeSourceInfo **RecoveryTSI) {
15187 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15188 DRE, AddrTaken, RecoveryTSI);
15189
15190 // Propagate both errors and recovered types, which return ExprEmpty.
15191 if (!NewDRE.isUsable())
15192 return NewDRE;
15193
15194 // We got an expr, wrap it up in parens.
15195 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15196 return PE;
15197 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15198 PE->getRParen());
15199 }
15200
15201 template <typename Derived>
TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr * E)15202 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15203 DependentScopeDeclRefExpr *E) {
15204 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15205 nullptr);
15206 }
15207
15208 template <typename Derived>
TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr * E,bool IsAddressOfOperand,TypeSourceInfo ** RecoveryTSI)15209 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15210 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15211 TypeSourceInfo **RecoveryTSI) {
15212 assert(E->getQualifierLoc());
15213 NestedNameSpecifierLoc QualifierLoc =
15214 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15215 if (!QualifierLoc)
15216 return ExprError();
15217 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15218
15219 // TODO: If this is a conversion-function-id, verify that the
15220 // destination type name (if present) resolves the same way after
15221 // instantiation as it did in the local scope.
15222
15223 DeclarationNameInfo NameInfo =
15224 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15225 if (!NameInfo.getName())
15226 return ExprError();
15227
15228 if (!E->hasExplicitTemplateArgs()) {
15229 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15230 // Note: it is sufficient to compare the Name component of NameInfo:
15231 // if name has not changed, DNLoc has not changed either.
15232 NameInfo.getName() == E->getDeclName())
15233 return E;
15234
15235 return getDerived().RebuildDependentScopeDeclRefExpr(
15236 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15237 IsAddressOfOperand, RecoveryTSI);
15238 }
15239
15240 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15241 if (getDerived().TransformTemplateArguments(
15242 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15243 return ExprError();
15244
15245 return getDerived().RebuildDependentScopeDeclRefExpr(
15246 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15247 RecoveryTSI);
15248 }
15249
15250 template<typename Derived>
15251 ExprResult
TransformCXXConstructExpr(CXXConstructExpr * E)15252 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15253 // CXXConstructExprs other than for list-initialization and
15254 // CXXTemporaryObjectExpr are always implicit, so when we have
15255 // a 1-argument construction we just transform that argument.
15256 if (getDerived().AllowSkippingCXXConstructExpr() &&
15257 ((E->getNumArgs() == 1 ||
15258 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
15259 (!getDerived().DropCallArgument(E->getArg(0))) &&
15260 !E->isListInitialization()))
15261 return getDerived().TransformInitializer(E->getArg(0),
15262 /*DirectInit*/ false);
15263
15264 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15265
15266 QualType T = getDerived().TransformType(E->getType());
15267 if (T.isNull())
15268 return ExprError();
15269
15270 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15271 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15272 if (!Constructor)
15273 return ExprError();
15274
15275 bool ArgumentChanged = false;
15276 SmallVector<Expr*, 8> Args;
15277 {
15278 EnterExpressionEvaluationContext Context(
15279 getSema(), EnterExpressionEvaluationContext::InitList,
15280 E->isListInitialization());
15281 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15282 &ArgumentChanged))
15283 return ExprError();
15284 }
15285
15286 if (!getDerived().AlwaysRebuild() &&
15287 T == E->getType() &&
15288 Constructor == E->getConstructor() &&
15289 !ArgumentChanged) {
15290 // Mark the constructor as referenced.
15291 // FIXME: Instantiation-specific
15292 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15293 return E;
15294 }
15295
15296 return getDerived().RebuildCXXConstructExpr(
15297 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15298 E->hadMultipleCandidates(), E->isListInitialization(),
15299 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15300 E->getConstructionKind(), E->getParenOrBraceRange());
15301 }
15302
15303 template<typename Derived>
TransformCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr * E)15304 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15305 CXXInheritedCtorInitExpr *E) {
15306 QualType T = getDerived().TransformType(E->getType());
15307 if (T.isNull())
15308 return ExprError();
15309
15310 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15311 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15312 if (!Constructor)
15313 return ExprError();
15314
15315 if (!getDerived().AlwaysRebuild() &&
15316 T == E->getType() &&
15317 Constructor == E->getConstructor()) {
15318 // Mark the constructor as referenced.
15319 // FIXME: Instantiation-specific
15320 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15321 return E;
15322 }
15323
15324 return getDerived().RebuildCXXInheritedCtorInitExpr(
15325 T, E->getLocation(), Constructor,
15326 E->constructsVBase(), E->inheritedFromVBase());
15327 }
15328
15329 /// Transform a C++ temporary-binding expression.
15330 ///
15331 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15332 /// transform the subexpression and return that.
15333 template<typename Derived>
15334 ExprResult
TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr * E)15335 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15336 if (auto *Dtor = E->getTemporary()->getDestructor())
15337 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
15338 const_cast<CXXDestructorDecl *>(Dtor));
15339 return getDerived().TransformExpr(E->getSubExpr());
15340 }
15341
15342 /// Transform a C++ expression that contains cleanups that should
15343 /// be run after the expression is evaluated.
15344 ///
15345 /// Since ExprWithCleanups nodes are implicitly generated, we
15346 /// just transform the subexpression and return that.
15347 template<typename Derived>
15348 ExprResult
TransformExprWithCleanups(ExprWithCleanups * E)15349 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15350 return getDerived().TransformExpr(E->getSubExpr());
15351 }
15352
15353 template<typename Derived>
15354 ExprResult
TransformCXXTemporaryObjectExpr(CXXTemporaryObjectExpr * E)15355 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15356 CXXTemporaryObjectExpr *E) {
15357 TypeSourceInfo *T =
15358 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15359 if (!T)
15360 return ExprError();
15361
15362 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15363 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15364 if (!Constructor)
15365 return ExprError();
15366
15367 bool ArgumentChanged = false;
15368 SmallVector<Expr*, 8> Args;
15369 Args.reserve(E->getNumArgs());
15370 {
15371 EnterExpressionEvaluationContext Context(
15372 getSema(), EnterExpressionEvaluationContext::InitList,
15373 E->isListInitialization());
15374 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15375 &ArgumentChanged))
15376 return ExprError();
15377
15378 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15379 ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc());
15380 if (Res.isInvalid())
15381 return ExprError();
15382 Args = {Res.get()};
15383 }
15384 }
15385
15386 if (!getDerived().AlwaysRebuild() &&
15387 T == E->getTypeSourceInfo() &&
15388 Constructor == E->getConstructor() &&
15389 !ArgumentChanged) {
15390 // FIXME: Instantiation-specific
15391 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15392 return SemaRef.MaybeBindToTemporary(E);
15393 }
15394
15395 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15396 return getDerived().RebuildCXXTemporaryObjectExpr(
15397 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15398 }
15399
15400 template<typename Derived>
15401 ExprResult
TransformLambdaExpr(LambdaExpr * E)15402 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15403 // Transform any init-capture expressions before entering the scope of the
15404 // lambda body, because they are not semantically within that scope.
15405 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15406 struct TransformedInitCapture {
15407 // The location of the ... if the result is retaining a pack expansion.
15408 SourceLocation EllipsisLoc;
15409 // Zero or more expansions of the init-capture.
15410 SmallVector<InitCaptureInfoTy, 4> Expansions;
15411 };
15412 SmallVector<TransformedInitCapture, 4> InitCaptures;
15413 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15414 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15415 CEnd = E->capture_end();
15416 C != CEnd; ++C) {
15417 if (!E->isInitCapture(C))
15418 continue;
15419
15420 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15421 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15422
15423 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15424 UnsignedOrNone NumExpansions) {
15425 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15426 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15427
15428 if (NewExprInitResult.isInvalid()) {
15429 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15430 return;
15431 }
15432 Expr *NewExprInit = NewExprInitResult.get();
15433
15434 QualType NewInitCaptureType =
15435 getSema().buildLambdaInitCaptureInitialization(
15436 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15437 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15438 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
15439 VarDecl::CInit,
15440 NewExprInit);
15441 Result.Expansions.push_back(
15442 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15443 };
15444
15445 // If this is an init-capture pack, consider expanding the pack now.
15446 if (OldVD->isParameterPack()) {
15447 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15448 ->getTypeLoc()
15449 .castAs<PackExpansionTypeLoc>();
15450 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15451 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
15452
15453 // Determine whether the set of unexpanded parameter packs can and should
15454 // be expanded.
15455 bool Expand = true;
15456 bool RetainExpansion = false;
15457 UnsignedOrNone OrigNumExpansions =
15458 ExpansionTL.getTypePtr()->getNumExpansions();
15459 UnsignedOrNone NumExpansions = OrigNumExpansions;
15460 if (getDerived().TryExpandParameterPacks(
15461 ExpansionTL.getEllipsisLoc(),
15462 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
15463 RetainExpansion, NumExpansions))
15464 return ExprError();
15465 assert(!RetainExpansion && "Should not need to retain expansion after a "
15466 "capture since it cannot be extended");
15467 if (Expand) {
15468 for (unsigned I = 0; I != *NumExpansions; ++I) {
15469 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15470 SubstInitCapture(SourceLocation(), std::nullopt);
15471 }
15472 } else {
15473 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15474 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15475 }
15476 } else {
15477 SubstInitCapture(SourceLocation(), std::nullopt);
15478 }
15479 }
15480
15481 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15482 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15483
15484 // Create the local class that will describe the lambda.
15485
15486 // FIXME: DependencyKind below is wrong when substituting inside a templated
15487 // context that isn't a DeclContext (such as a variable template), or when
15488 // substituting an unevaluated lambda inside of a function's parameter's type
15489 // - as parameter types are not instantiated from within a function's DC. We
15490 // use evaluation contexts to distinguish the function parameter case.
15491 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15492 CXXRecordDecl::LDK_Unknown;
15493 DeclContext *DC = getSema().CurContext;
15494 // A RequiresExprBodyDecl is not interesting for dependencies.
15495 // For the following case,
15496 //
15497 // template <typename>
15498 // concept C = requires { [] {}; };
15499 //
15500 // template <class F>
15501 // struct Widget;
15502 //
15503 // template <C F>
15504 // struct Widget<F> {};
15505 //
15506 // While we are substituting Widget<F>, the parent of DC would be
15507 // the template specialization itself. Thus, the lambda expression
15508 // will be deemed as dependent even if there are no dependent template
15509 // arguments.
15510 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15511 while (DC->isRequiresExprBody())
15512 DC = DC->getParent();
15513 if ((getSema().isUnevaluatedContext() ||
15514 getSema().isConstantEvaluatedContext()) &&
15515 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15516 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15517
15518 CXXRecordDecl *OldClass = E->getLambdaClass();
15519 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15520 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15521 E->getCaptureDefault());
15522 getDerived().transformedLocalDecl(OldClass, {Class});
15523
15524 CXXMethodDecl *NewCallOperator =
15525 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15526
15527 // Enter the scope of the lambda.
15528 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15529 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15530 E->hasExplicitParameters(), E->isMutable());
15531
15532 // Introduce the context of the call operator.
15533 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15534 /*NewThisContext*/false);
15535
15536 bool Invalid = false;
15537
15538 // Transform captures.
15539 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15540 CEnd = E->capture_end();
15541 C != CEnd; ++C) {
15542 // When we hit the first implicit capture, tell Sema that we've finished
15543 // the list of explicit captures.
15544 if (C->isImplicit())
15545 break;
15546
15547 // Capturing 'this' is trivial.
15548 if (C->capturesThis()) {
15549 // If this is a lambda that is part of a default member initialiser
15550 // and which we're instantiating outside the class that 'this' is
15551 // supposed to refer to, adjust the type of 'this' accordingly.
15552 //
15553 // Otherwise, leave the type of 'this' as-is.
15554 Sema::CXXThisScopeRAII ThisScope(
15555 getSema(),
15556 dyn_cast_if_present<CXXRecordDecl>(
15557 getSema().getFunctionLevelDeclContext()),
15558 Qualifiers());
15559 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15560 /*BuildAndDiagnose*/ true, nullptr,
15561 C->getCaptureKind() == LCK_StarThis);
15562 continue;
15563 }
15564 // Captured expression will be recaptured during captured variables
15565 // rebuilding.
15566 if (C->capturesVLAType())
15567 continue;
15568
15569 // Rebuild init-captures, including the implied field declaration.
15570 if (E->isInitCapture(C)) {
15571 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15572
15573 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15574 llvm::SmallVector<Decl*, 4> NewVDs;
15575
15576 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15577 ExprResult Init = Info.first;
15578 QualType InitQualType = Info.second;
15579 if (Init.isInvalid() || InitQualType.isNull()) {
15580 Invalid = true;
15581 break;
15582 }
15583 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15584 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15585 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15586 getSema().CurContext);
15587 if (!NewVD) {
15588 Invalid = true;
15589 break;
15590 }
15591 NewVDs.push_back(NewVD);
15592 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15593 // Cases we want to tackle:
15594 // ([C(Pack)] {}, ...)
15595 // But rule out cases e.g.
15596 // [...C = Pack()] {}
15597 if (NewC.EllipsisLoc.isInvalid())
15598 LSI->ContainsUnexpandedParameterPack |=
15599 Init.get()->containsUnexpandedParameterPack();
15600 }
15601
15602 if (Invalid)
15603 break;
15604
15605 getDerived().transformedLocalDecl(OldVD, NewVDs);
15606 continue;
15607 }
15608
15609 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15610
15611 // Determine the capture kind for Sema.
15612 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15613 : C->getCaptureKind() == LCK_ByCopy
15614 ? TryCaptureKind::ExplicitByVal
15615 : TryCaptureKind::ExplicitByRef;
15616 SourceLocation EllipsisLoc;
15617 if (C->isPackExpansion()) {
15618 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15619 bool ShouldExpand = false;
15620 bool RetainExpansion = false;
15621 UnsignedOrNone NumExpansions = std::nullopt;
15622 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
15623 C->getLocation(),
15624 Unexpanded,
15625 ShouldExpand, RetainExpansion,
15626 NumExpansions)) {
15627 Invalid = true;
15628 continue;
15629 }
15630
15631 if (ShouldExpand) {
15632 // The transform has determined that we should perform an expansion;
15633 // transform and capture each of the arguments.
15634 // expansion of the pattern. Do so.
15635 auto *Pack = cast<ValueDecl>(C->getCapturedVar());
15636 for (unsigned I = 0; I != *NumExpansions; ++I) {
15637 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15638 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15639 getDerived().TransformDecl(C->getLocation(), Pack));
15640 if (!CapturedVar) {
15641 Invalid = true;
15642 continue;
15643 }
15644
15645 // Capture the transformed variable.
15646 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15647 }
15648
15649 // FIXME: Retain a pack expansion if RetainExpansion is true.
15650
15651 continue;
15652 }
15653
15654 EllipsisLoc = C->getEllipsisLoc();
15655 }
15656
15657 // Transform the captured variable.
15658 auto *CapturedVar = cast_or_null<ValueDecl>(
15659 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15660 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15661 Invalid = true;
15662 continue;
15663 }
15664
15665 // This is not an init-capture; however it contains an unexpanded pack e.g.
15666 // ([Pack] {}(), ...)
15667 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15668 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15669
15670 // Capture the transformed variable.
15671 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15672 EllipsisLoc);
15673 }
15674 getSema().finishLambdaExplicitCaptures(LSI);
15675
15676 // Transform the template parameters, and add them to the current
15677 // instantiation scope. The null case is handled correctly.
15678 auto TPL = getDerived().TransformTemplateParameterList(
15679 E->getTemplateParameterList());
15680 LSI->GLTemplateParameterList = TPL;
15681 if (TPL) {
15682 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15683 TPL);
15684 LSI->ContainsUnexpandedParameterPack |=
15685 TPL->containsUnexpandedParameterPack();
15686 }
15687
15688 TypeLocBuilder NewCallOpTLBuilder;
15689 TypeLoc OldCallOpTypeLoc =
15690 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15691 QualType NewCallOpType =
15692 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15693 if (NewCallOpType.isNull())
15694 return ExprError();
15695 LSI->ContainsUnexpandedParameterPack |=
15696 NewCallOpType->containsUnexpandedParameterPack();
15697 TypeSourceInfo *NewCallOpTSI =
15698 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
15699
15700 // The type may be an AttributedType or some other kind of sugar;
15701 // get the actual underlying FunctionProtoType.
15702 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15703 assert(FPTL && "Not a FunctionProtoType?");
15704
15705 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
15706 if (!TRC.ArgPackSubstIndex)
15707 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
15708
15709 getSema().CompleteLambdaCallOperator(
15710 NewCallOperator, E->getCallOperator()->getLocation(),
15711 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
15712 E->getCallOperator()->getConstexprKind(),
15713 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15714 E->hasExplicitResultType());
15715
15716 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15717 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15718
15719 {
15720 // Number the lambda for linkage purposes if necessary.
15721 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15722
15723 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15724 if (getDerived().ReplacingOriginal()) {
15725 Numbering = OldClass->getLambdaNumbering();
15726 }
15727
15728 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15729 }
15730
15731 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15732 // evaluation context even if we're not transforming the function body.
15733 getSema().PushExpressionEvaluationContextForFunction(
15734 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
15735 E->getCallOperator());
15736
15737 Sema::CodeSynthesisContext C;
15738 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
15739 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15740 getSema().pushCodeSynthesisContext(C);
15741
15742 // Instantiate the body of the lambda expression.
15743 StmtResult Body =
15744 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
15745
15746 getSema().popCodeSynthesisContext();
15747
15748 // ActOnLambda* will pop the function scope for us.
15749 FuncScopeCleanup.disable();
15750
15751 if (Body.isInvalid()) {
15752 SavedContext.pop();
15753 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15754 /*IsInstantiation=*/true);
15755 return ExprError();
15756 }
15757
15758 // Copy the LSI before ActOnFinishFunctionBody removes it.
15759 // FIXME: This is dumb. Store the lambda information somewhere that outlives
15760 // the call operator.
15761 auto LSICopy = *LSI;
15762 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15763 /*IsInstantiation*/ true);
15764 SavedContext.pop();
15765
15766 // Recompute the dependency of the lambda so that we can defer the lambda call
15767 // construction until after we have all the necessary template arguments. For
15768 // example, given
15769 //
15770 // template <class> struct S {
15771 // template <class U>
15772 // using Type = decltype([](U){}(42.0));
15773 // };
15774 // void foo() {
15775 // using T = S<int>::Type<float>;
15776 // ^~~~~~
15777 // }
15778 //
15779 // We would end up here from instantiating S<int> when ensuring its
15780 // completeness. That would transform the lambda call expression regardless of
15781 // the absence of the corresponding argument for U.
15782 //
15783 // Going ahead with unsubstituted type U makes things worse: we would soon
15784 // compare the argument type (which is float) against the parameter U
15785 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
15786 // error suggesting unmatched types 'U' and 'float'!
15787 //
15788 // That said, everything will be fine if we defer that semantic checking.
15789 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
15790 // dependent. Since the CallExpr's dependency boils down to the lambda's
15791 // dependency in this case, we can harness that by recomputing the dependency
15792 // from the instantiation arguments.
15793 //
15794 // FIXME: Creating the type of a lambda requires us to have a dependency
15795 // value, which happens before its substitution. We update its dependency
15796 // *after* the substitution in case we can't decide the dependency
15797 // so early, e.g. because we want to see if any of the *substituted*
15798 // parameters are dependent.
15799 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
15800 Class->setLambdaDependencyKind(DependencyKind);
15801 // Clean up the type cache created previously. Then, we re-create a type for
15802 // such Decl with the new DependencyKind.
15803 Class->setTypeForDecl(nullptr);
15804 getSema().Context.getTypeDeclType(Class);
15805
15806 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
15807 Body.get()->getEndLoc(), &LSICopy);
15808 }
15809
15810 template<typename Derived>
15811 StmtResult
TransformLambdaBody(LambdaExpr * E,Stmt * S)15812 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
15813 return TransformStmt(S);
15814 }
15815
15816 template<typename Derived>
15817 StmtResult
SkipLambdaBody(LambdaExpr * E,Stmt * S)15818 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
15819 // Transform captures.
15820 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15821 CEnd = E->capture_end();
15822 C != CEnd; ++C) {
15823 // When we hit the first implicit capture, tell Sema that we've finished
15824 // the list of explicit captures.
15825 if (!C->isImplicit())
15826 continue;
15827
15828 // Capturing 'this' is trivial.
15829 if (C->capturesThis()) {
15830 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15831 /*BuildAndDiagnose*/ true, nullptr,
15832 C->getCaptureKind() == LCK_StarThis);
15833 continue;
15834 }
15835 // Captured expression will be recaptured during captured variables
15836 // rebuilding.
15837 if (C->capturesVLAType())
15838 continue;
15839
15840 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15841 assert(!E->isInitCapture(C) && "implicit init-capture?");
15842
15843 // Transform the captured variable.
15844 VarDecl *CapturedVar = cast_or_null<VarDecl>(
15845 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15846 if (!CapturedVar || CapturedVar->isInvalidDecl())
15847 return StmtError();
15848
15849 // Capture the transformed variable.
15850 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
15851 }
15852
15853 return S;
15854 }
15855
15856 template<typename Derived>
15857 ExprResult
TransformCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr * E)15858 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
15859 CXXUnresolvedConstructExpr *E) {
15860 TypeSourceInfo *T =
15861 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15862 if (!T)
15863 return ExprError();
15864
15865 bool ArgumentChanged = false;
15866 SmallVector<Expr*, 8> Args;
15867 Args.reserve(E->getNumArgs());
15868 {
15869 EnterExpressionEvaluationContext Context(
15870 getSema(), EnterExpressionEvaluationContext::InitList,
15871 E->isListInitialization());
15872 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
15873 &ArgumentChanged))
15874 return ExprError();
15875 }
15876
15877 if (!getDerived().AlwaysRebuild() &&
15878 T == E->getTypeSourceInfo() &&
15879 !ArgumentChanged)
15880 return E;
15881
15882 // FIXME: we're faking the locations of the commas
15883 return getDerived().RebuildCXXUnresolvedConstructExpr(
15884 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
15885 }
15886
15887 template<typename Derived>
15888 ExprResult
TransformCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr * E)15889 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
15890 CXXDependentScopeMemberExpr *E) {
15891 // Transform the base of the expression.
15892 ExprResult Base((Expr*) nullptr);
15893 Expr *OldBase;
15894 QualType BaseType;
15895 QualType ObjectType;
15896 if (!E->isImplicitAccess()) {
15897 OldBase = E->getBase();
15898 Base = getDerived().TransformExpr(OldBase);
15899 if (Base.isInvalid())
15900 return ExprError();
15901
15902 // Start the member reference and compute the object's type.
15903 ParsedType ObjectTy;
15904 bool MayBePseudoDestructor = false;
15905 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
15906 E->getOperatorLoc(),
15907 E->isArrow()? tok::arrow : tok::period,
15908 ObjectTy,
15909 MayBePseudoDestructor);
15910 if (Base.isInvalid())
15911 return ExprError();
15912
15913 ObjectType = ObjectTy.get();
15914 BaseType = ((Expr*) Base.get())->getType();
15915 } else {
15916 OldBase = nullptr;
15917 BaseType = getDerived().TransformType(E->getBaseType());
15918 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
15919 }
15920
15921 // Transform the first part of the nested-name-specifier that qualifies
15922 // the member name.
15923 NamedDecl *FirstQualifierInScope
15924 = getDerived().TransformFirstQualifierInScope(
15925 E->getFirstQualifierFoundInScope(),
15926 E->getQualifierLoc().getBeginLoc());
15927
15928 NestedNameSpecifierLoc QualifierLoc;
15929 if (E->getQualifier()) {
15930 QualifierLoc
15931 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15932 ObjectType,
15933 FirstQualifierInScope);
15934 if (!QualifierLoc)
15935 return ExprError();
15936 }
15937
15938 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15939
15940 // TODO: If this is a conversion-function-id, verify that the
15941 // destination type name (if present) resolves the same way after
15942 // instantiation as it did in the local scope.
15943
15944 DeclarationNameInfo NameInfo
15945 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15946 if (!NameInfo.getName())
15947 return ExprError();
15948
15949 if (!E->hasExplicitTemplateArgs()) {
15950 // This is a reference to a member without an explicitly-specified
15951 // template argument list. Optimize for this common case.
15952 if (!getDerived().AlwaysRebuild() &&
15953 Base.get() == OldBase &&
15954 BaseType == E->getBaseType() &&
15955 QualifierLoc == E->getQualifierLoc() &&
15956 NameInfo.getName() == E->getMember() &&
15957 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15958 return E;
15959
15960 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15961 BaseType,
15962 E->isArrow(),
15963 E->getOperatorLoc(),
15964 QualifierLoc,
15965 TemplateKWLoc,
15966 FirstQualifierInScope,
15967 NameInfo,
15968 /*TemplateArgs*/nullptr);
15969 }
15970
15971 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15972 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15973 E->getNumTemplateArgs(),
15974 TransArgs))
15975 return ExprError();
15976
15977 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15978 BaseType,
15979 E->isArrow(),
15980 E->getOperatorLoc(),
15981 QualifierLoc,
15982 TemplateKWLoc,
15983 FirstQualifierInScope,
15984 NameInfo,
15985 &TransArgs);
15986 }
15987
15988 template <typename Derived>
TransformUnresolvedMemberExpr(UnresolvedMemberExpr * Old)15989 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15990 UnresolvedMemberExpr *Old) {
15991 // Transform the base of the expression.
15992 ExprResult Base((Expr *)nullptr);
15993 QualType BaseType;
15994 if (!Old->isImplicitAccess()) {
15995 Base = getDerived().TransformExpr(Old->getBase());
15996 if (Base.isInvalid())
15997 return ExprError();
15998 Base =
15999 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16000 if (Base.isInvalid())
16001 return ExprError();
16002 BaseType = Base.get()->getType();
16003 } else {
16004 BaseType = getDerived().TransformType(Old->getBaseType());
16005 }
16006
16007 NestedNameSpecifierLoc QualifierLoc;
16008 if (Old->getQualifierLoc()) {
16009 QualifierLoc =
16010 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16011 if (!QualifierLoc)
16012 return ExprError();
16013 }
16014
16015 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16016
16017 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16018
16019 // Transform the declaration set.
16020 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
16021 return ExprError();
16022
16023 // Determine the naming class.
16024 if (Old->getNamingClass()) {
16025 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16026 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16027 if (!NamingClass)
16028 return ExprError();
16029
16030 R.setNamingClass(NamingClass);
16031 }
16032
16033 TemplateArgumentListInfo TransArgs;
16034 if (Old->hasExplicitTemplateArgs()) {
16035 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16036 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16037 if (getDerived().TransformTemplateArguments(
16038 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16039 return ExprError();
16040 }
16041
16042 // FIXME: to do this check properly, we will need to preserve the
16043 // first-qualifier-in-scope here, just in case we had a dependent
16044 // base (and therefore couldn't do the check) and a
16045 // nested-name-qualifier (and therefore could do the lookup).
16046 NamedDecl *FirstQualifierInScope = nullptr;
16047
16048 return getDerived().RebuildUnresolvedMemberExpr(
16049 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16050 TemplateKWLoc, FirstQualifierInScope, R,
16051 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16052 }
16053
16054 template<typename Derived>
16055 ExprResult
TransformCXXNoexceptExpr(CXXNoexceptExpr * E)16056 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16057 EnterExpressionEvaluationContext Unevaluated(
16058 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16059 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16060 if (SubExpr.isInvalid())
16061 return ExprError();
16062
16063 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16064 return E;
16065
16066 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16067 }
16068
16069 template<typename Derived>
16070 ExprResult
TransformPackExpansionExpr(PackExpansionExpr * E)16071 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16072 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16073 if (Pattern.isInvalid())
16074 return ExprError();
16075
16076 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16077 return E;
16078
16079 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16080 E->getNumExpansions());
16081 }
16082
16083 template <typename Derived>
ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs)16084 UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16085 ArrayRef<TemplateArgument> PackArgs) {
16086 UnsignedOrNone Result = 0u;
16087 for (const TemplateArgument &Arg : PackArgs) {
16088 if (!Arg.isPackExpansion()) {
16089 Result = *Result + 1;
16090 continue;
16091 }
16092
16093 TemplateArgumentLoc ArgLoc;
16094 InventTemplateArgumentLoc(Arg, ArgLoc);
16095
16096 // Find the pattern of the pack expansion.
16097 SourceLocation Ellipsis;
16098 UnsignedOrNone OrigNumExpansions = std::nullopt;
16099 TemplateArgumentLoc Pattern =
16100 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16101 OrigNumExpansions);
16102
16103 // Substitute under the pack expansion. Do not expand the pack (yet).
16104 TemplateArgumentLoc OutPattern;
16105 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16106 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16107 /*Uneval*/ true))
16108 return 1u;
16109
16110 // See if we can determine the number of arguments from the result.
16111 UnsignedOrNone NumExpansions =
16112 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16113 if (!NumExpansions) {
16114 // No: we must be in an alias template expansion, and we're going to
16115 // need to actually expand the packs.
16116 Result = std::nullopt;
16117 break;
16118 }
16119
16120 Result = *Result + *NumExpansions;
16121 }
16122 return Result;
16123 }
16124
16125 template<typename Derived>
16126 ExprResult
TransformSizeOfPackExpr(SizeOfPackExpr * E)16127 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16128 // If E is not value-dependent, then nothing will change when we transform it.
16129 // Note: This is an instantiation-centric view.
16130 if (!E->isValueDependent())
16131 return E;
16132
16133 EnterExpressionEvaluationContext Unevaluated(
16134 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16135
16136 ArrayRef<TemplateArgument> PackArgs;
16137 TemplateArgument ArgStorage;
16138
16139 // Find the argument list to transform.
16140 if (E->isPartiallySubstituted()) {
16141 PackArgs = E->getPartialArguments();
16142 } else if (E->isValueDependent()) {
16143 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16144 bool ShouldExpand = false;
16145 bool RetainExpansion = false;
16146 UnsignedOrNone NumExpansions = std::nullopt;
16147 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
16148 Unexpanded,
16149 ShouldExpand, RetainExpansion,
16150 NumExpansions))
16151 return ExprError();
16152
16153 // If we need to expand the pack, build a template argument from it and
16154 // expand that.
16155 if (ShouldExpand) {
16156 auto *Pack = E->getPack();
16157 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
16158 ArgStorage = getSema().Context.getPackExpansionType(
16159 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16160 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
16161 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16162 } else {
16163 auto *VD = cast<ValueDecl>(Pack);
16164 ExprResult DRE = getSema().BuildDeclRefExpr(
16165 VD, VD->getType().getNonLValueExprType(getSema().Context),
16166 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16167 E->getPackLoc());
16168 if (DRE.isInvalid())
16169 return ExprError();
16170 ArgStorage = TemplateArgument(
16171 new (getSema().Context)
16172 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16173 /*IsCanonical=*/false);
16174 }
16175 PackArgs = ArgStorage;
16176 }
16177 }
16178
16179 // If we're not expanding the pack, just transform the decl.
16180 if (!PackArgs.size()) {
16181 auto *Pack = cast_or_null<NamedDecl>(
16182 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16183 if (!Pack)
16184 return ExprError();
16185 return getDerived().RebuildSizeOfPackExpr(
16186 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16187 std::nullopt, {});
16188 }
16189
16190 // Try to compute the result without performing a partial substitution.
16191 UnsignedOrNone Result =
16192 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16193
16194 // Common case: we could determine the number of expansions without
16195 // substituting.
16196 if (Result)
16197 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16198 E->getPackLoc(),
16199 E->getRParenLoc(), *Result, {});
16200
16201 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16202 E->getPackLoc());
16203 {
16204 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16205 typedef TemplateArgumentLocInventIterator<
16206 Derived, const TemplateArgument*> PackLocIterator;
16207 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16208 PackLocIterator(*this, PackArgs.end()),
16209 TransformedPackArgs, /*Uneval*/true))
16210 return ExprError();
16211 }
16212
16213 // Check whether we managed to fully-expand the pack.
16214 // FIXME: Is it possible for us to do so and not hit the early exit path?
16215 SmallVector<TemplateArgument, 8> Args;
16216 bool PartialSubstitution = false;
16217 for (auto &Loc : TransformedPackArgs.arguments()) {
16218 Args.push_back(Loc.getArgument());
16219 if (Loc.getArgument().isPackExpansion())
16220 PartialSubstitution = true;
16221 }
16222
16223 if (PartialSubstitution)
16224 return getDerived().RebuildSizeOfPackExpr(
16225 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16226 std::nullopt, Args);
16227
16228 return getDerived().RebuildSizeOfPackExpr(
16229 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16230 /*Length=*/static_cast<unsigned>(Args.size()),
16231 /*PartialArgs=*/{});
16232 }
16233
16234 template <typename Derived>
16235 ExprResult
TransformPackIndexingExpr(PackIndexingExpr * E)16236 TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16237 if (!E->isValueDependent())
16238 return E;
16239
16240 // Transform the index
16241 ExprResult IndexExpr;
16242 {
16243 EnterExpressionEvaluationContext ConstantContext(
16244 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16245 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16246 if (IndexExpr.isInvalid())
16247 return ExprError();
16248 }
16249
16250 SmallVector<Expr *, 5> ExpandedExprs;
16251 bool FullySubstituted = true;
16252 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16253 Expr *Pattern = E->getPackIdExpression();
16254 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16255 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16256 Unexpanded);
16257 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16258
16259 // Determine whether the set of unexpanded parameter packs can and should
16260 // be expanded.
16261 bool ShouldExpand = true;
16262 bool RetainExpansion = false;
16263 UnsignedOrNone OrigNumExpansions = std::nullopt,
16264 NumExpansions = std::nullopt;
16265 if (getDerived().TryExpandParameterPacks(
16266 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16267 ShouldExpand, RetainExpansion, NumExpansions))
16268 return true;
16269 if (!ShouldExpand) {
16270 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16271 ExprResult Pack = getDerived().TransformExpr(Pattern);
16272 if (Pack.isInvalid())
16273 return ExprError();
16274 return getDerived().RebuildPackIndexingExpr(
16275 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16276 {}, /*FullySubstituted=*/false);
16277 }
16278 for (unsigned I = 0; I != *NumExpansions; ++I) {
16279 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16280 ExprResult Out = getDerived().TransformExpr(Pattern);
16281 if (Out.isInvalid())
16282 return true;
16283 if (Out.get()->containsUnexpandedParameterPack()) {
16284 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16285 OrigNumExpansions);
16286 if (Out.isInvalid())
16287 return true;
16288 FullySubstituted = false;
16289 }
16290 ExpandedExprs.push_back(Out.get());
16291 }
16292 // If we're supposed to retain a pack expansion, do so by temporarily
16293 // forgetting the partially-substituted parameter pack.
16294 if (RetainExpansion) {
16295 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16296
16297 ExprResult Out = getDerived().TransformExpr(Pattern);
16298 if (Out.isInvalid())
16299 return true;
16300
16301 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16302 OrigNumExpansions);
16303 if (Out.isInvalid())
16304 return true;
16305 FullySubstituted = false;
16306 ExpandedExprs.push_back(Out.get());
16307 }
16308 } else if (!E->expandsToEmptyPack()) {
16309 if (getDerived().TransformExprs(E->getExpressions().data(),
16310 E->getExpressions().size(), false,
16311 ExpandedExprs))
16312 return ExprError();
16313 }
16314
16315 return getDerived().RebuildPackIndexingExpr(
16316 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16317 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16318 }
16319
16320 template<typename Derived>
16321 ExprResult
TransformSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr * E)16322 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16323 SubstNonTypeTemplateParmPackExpr *E) {
16324 // Default behavior is to do nothing with this transformation.
16325 return E;
16326 }
16327
16328 template<typename Derived>
16329 ExprResult
TransformSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)16330 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16331 SubstNonTypeTemplateParmExpr *E) {
16332 // Default behavior is to do nothing with this transformation.
16333 return E;
16334 }
16335
16336 template<typename Derived>
16337 ExprResult
TransformFunctionParmPackExpr(FunctionParmPackExpr * E)16338 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16339 // Default behavior is to do nothing with this transformation.
16340 return E;
16341 }
16342
16343 template<typename Derived>
16344 ExprResult
TransformMaterializeTemporaryExpr(MaterializeTemporaryExpr * E)16345 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16346 MaterializeTemporaryExpr *E) {
16347 return getDerived().TransformExpr(E->getSubExpr());
16348 }
16349
16350 template<typename Derived>
16351 ExprResult
TransformCXXFoldExpr(CXXFoldExpr * E)16352 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16353 UnresolvedLookupExpr *Callee = nullptr;
16354 if (Expr *OldCallee = E->getCallee()) {
16355 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16356 if (CalleeResult.isInvalid())
16357 return ExprError();
16358 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
16359 }
16360
16361 Expr *Pattern = E->getPattern();
16362
16363 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16364 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16365 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16366
16367 // Determine whether the set of unexpanded parameter packs can and should
16368 // be expanded.
16369 bool Expand = true;
16370 bool RetainExpansion = false;
16371 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16372 NumExpansions = OrigNumExpansions;
16373 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
16374 Pattern->getSourceRange(),
16375 Unexpanded,
16376 Expand, RetainExpansion,
16377 NumExpansions))
16378 return true;
16379
16380 if (!Expand) {
16381 // Do not expand any packs here, just transform and rebuild a fold
16382 // expression.
16383 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16384
16385 ExprResult LHS =
16386 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16387 if (LHS.isInvalid())
16388 return true;
16389
16390 ExprResult RHS =
16391 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16392 if (RHS.isInvalid())
16393 return true;
16394
16395 if (!getDerived().AlwaysRebuild() &&
16396 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16397 return E;
16398
16399 return getDerived().RebuildCXXFoldExpr(
16400 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16401 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16402 }
16403
16404 // Formally a fold expression expands to nested parenthesized expressions.
16405 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16406 // them.
16407 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16408 SemaRef.Diag(E->getEllipsisLoc(),
16409 clang::diag::err_fold_expression_limit_exceeded)
16410 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16411 << E->getSourceRange();
16412 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
16413 return ExprError();
16414 }
16415
16416 // The transform has determined that we should perform an elementwise
16417 // expansion of the pattern. Do so.
16418 ExprResult Result = getDerived().TransformExpr(E->getInit());
16419 if (Result.isInvalid())
16420 return true;
16421 bool LeftFold = E->isLeftFold();
16422
16423 // If we're retaining an expansion for a right fold, it is the innermost
16424 // component and takes the init (if any).
16425 if (!LeftFold && RetainExpansion) {
16426 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16427
16428 ExprResult Out = getDerived().TransformExpr(Pattern);
16429 if (Out.isInvalid())
16430 return true;
16431
16432 Result = getDerived().RebuildCXXFoldExpr(
16433 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16434 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16435 if (Result.isInvalid())
16436 return true;
16437 }
16438
16439 bool WarnedOnComparison = false;
16440 for (unsigned I = 0; I != *NumExpansions; ++I) {
16441 Sema::ArgPackSubstIndexRAII SubstIndex(
16442 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16443 ExprResult Out = getDerived().TransformExpr(Pattern);
16444 if (Out.isInvalid())
16445 return true;
16446
16447 if (Out.get()->containsUnexpandedParameterPack()) {
16448 // We still have a pack; retain a pack expansion for this slice.
16449 Result = getDerived().RebuildCXXFoldExpr(
16450 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16451 E->getOperator(), E->getEllipsisLoc(),
16452 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16453 OrigNumExpansions);
16454 } else if (Result.isUsable()) {
16455 // We've got down to a single element; build a binary operator.
16456 Expr *LHS = LeftFold ? Result.get() : Out.get();
16457 Expr *RHS = LeftFold ? Out.get() : Result.get();
16458 if (Callee) {
16459 UnresolvedSet<16> Functions;
16460 Functions.append(Callee->decls_begin(), Callee->decls_end());
16461 Result = getDerived().RebuildCXXOperatorCallExpr(
16462 BinaryOperator::getOverloadedOperator(E->getOperator()),
16463 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16464 Functions, LHS, RHS);
16465 } else {
16466 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16467 E->getOperator(), LHS, RHS,
16468 /*ForFoldExpresion=*/true);
16469 if (!WarnedOnComparison && Result.isUsable()) {
16470 if (auto *BO = dyn_cast<BinaryOperator>(Result.get());
16471 BO && BO->isComparisonOp()) {
16472 WarnedOnComparison = true;
16473 SemaRef.Diag(BO->getBeginLoc(),
16474 diag::warn_comparison_in_fold_expression)
16475 << BO->getOpcodeStr();
16476 }
16477 }
16478 }
16479 } else
16480 Result = Out;
16481
16482 if (Result.isInvalid())
16483 return true;
16484 }
16485
16486 // If we're retaining an expansion for a left fold, it is the outermost
16487 // component and takes the complete expansion so far as its init (if any).
16488 if (LeftFold && RetainExpansion) {
16489 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16490
16491 ExprResult Out = getDerived().TransformExpr(Pattern);
16492 if (Out.isInvalid())
16493 return true;
16494
16495 Result = getDerived().RebuildCXXFoldExpr(
16496 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16497 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16498 if (Result.isInvalid())
16499 return true;
16500 }
16501
16502 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Result.get()))
16503 PE->setIsProducedByFoldExpansion();
16504
16505 // If we had no init and an empty pack, and we're not retaining an expansion,
16506 // then produce a fallback value or error.
16507 if (Result.isUnset())
16508 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16509 E->getOperator());
16510 return Result;
16511 }
16512
16513 template <typename Derived>
16514 ExprResult
TransformCXXParenListInitExpr(CXXParenListInitExpr * E)16515 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16516 SmallVector<Expr *, 4> TransformedInits;
16517 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16518
16519 QualType T = getDerived().TransformType(E->getType());
16520
16521 bool ArgChanged = false;
16522
16523 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16524 TransformedInits, &ArgChanged))
16525 return ExprError();
16526
16527 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16528 return E;
16529
16530 return getDerived().RebuildCXXParenListInitExpr(
16531 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16532 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16533 }
16534
16535 template<typename Derived>
16536 ExprResult
TransformCXXStdInitializerListExpr(CXXStdInitializerListExpr * E)16537 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16538 CXXStdInitializerListExpr *E) {
16539 return getDerived().TransformExpr(E->getSubExpr());
16540 }
16541
16542 template<typename Derived>
16543 ExprResult
TransformObjCStringLiteral(ObjCStringLiteral * E)16544 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16545 return SemaRef.MaybeBindToTemporary(E);
16546 }
16547
16548 template<typename Derived>
16549 ExprResult
TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr * E)16550 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16551 return E;
16552 }
16553
16554 template<typename Derived>
16555 ExprResult
TransformObjCBoxedExpr(ObjCBoxedExpr * E)16556 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16557 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16558 if (SubExpr.isInvalid())
16559 return ExprError();
16560
16561 if (!getDerived().AlwaysRebuild() &&
16562 SubExpr.get() == E->getSubExpr())
16563 return E;
16564
16565 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16566 }
16567
16568 template<typename Derived>
16569 ExprResult
TransformObjCArrayLiteral(ObjCArrayLiteral * E)16570 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16571 // Transform each of the elements.
16572 SmallVector<Expr *, 8> Elements;
16573 bool ArgChanged = false;
16574 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16575 /*IsCall=*/false, Elements, &ArgChanged))
16576 return ExprError();
16577
16578 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16579 return SemaRef.MaybeBindToTemporary(E);
16580
16581 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16582 Elements.data(),
16583 Elements.size());
16584 }
16585
16586 template<typename Derived>
16587 ExprResult
TransformObjCDictionaryLiteral(ObjCDictionaryLiteral * E)16588 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16589 ObjCDictionaryLiteral *E) {
16590 // Transform each of the elements.
16591 SmallVector<ObjCDictionaryElement, 8> Elements;
16592 bool ArgChanged = false;
16593 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16594 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
16595
16596 if (OrigElement.isPackExpansion()) {
16597 // This key/value element is a pack expansion.
16598 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16599 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16600 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16601 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16602
16603 // Determine whether the set of unexpanded parameter packs can
16604 // and should be expanded.
16605 bool Expand = true;
16606 bool RetainExpansion = false;
16607 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
16608 UnsignedOrNone NumExpansions = OrigNumExpansions;
16609 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16610 OrigElement.Value->getEndLoc());
16611 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
16612 PatternRange, Unexpanded, Expand,
16613 RetainExpansion, NumExpansions))
16614 return ExprError();
16615
16616 if (!Expand) {
16617 // The transform has determined that we should perform a simple
16618 // transformation on the pack expansion, producing another pack
16619 // expansion.
16620 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16621 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16622 if (Key.isInvalid())
16623 return ExprError();
16624
16625 if (Key.get() != OrigElement.Key)
16626 ArgChanged = true;
16627
16628 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16629 if (Value.isInvalid())
16630 return ExprError();
16631
16632 if (Value.get() != OrigElement.Value)
16633 ArgChanged = true;
16634
16635 ObjCDictionaryElement Expansion = {
16636 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
16637 };
16638 Elements.push_back(Expansion);
16639 continue;
16640 }
16641
16642 // Record right away that the argument was changed. This needs
16643 // to happen even if the array expands to nothing.
16644 ArgChanged = true;
16645
16646 // The transform has determined that we should perform an elementwise
16647 // expansion of the pattern. Do so.
16648 for (unsigned I = 0; I != *NumExpansions; ++I) {
16649 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16650 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16651 if (Key.isInvalid())
16652 return ExprError();
16653
16654 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16655 if (Value.isInvalid())
16656 return ExprError();
16657
16658 ObjCDictionaryElement Element = {
16659 Key.get(), Value.get(), SourceLocation(), NumExpansions
16660 };
16661
16662 // If any unexpanded parameter packs remain, we still have a
16663 // pack expansion.
16664 // FIXME: Can this really happen?
16665 if (Key.get()->containsUnexpandedParameterPack() ||
16666 Value.get()->containsUnexpandedParameterPack())
16667 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16668
16669 Elements.push_back(Element);
16670 }
16671
16672 // FIXME: Retain a pack expansion if RetainExpansion is true.
16673
16674 // We've finished with this pack expansion.
16675 continue;
16676 }
16677
16678 // Transform and check key.
16679 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16680 if (Key.isInvalid())
16681 return ExprError();
16682
16683 if (Key.get() != OrigElement.Key)
16684 ArgChanged = true;
16685
16686 // Transform and check value.
16687 ExprResult Value
16688 = getDerived().TransformExpr(OrigElement.Value);
16689 if (Value.isInvalid())
16690 return ExprError();
16691
16692 if (Value.get() != OrigElement.Value)
16693 ArgChanged = true;
16694
16695 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
16696 std::nullopt};
16697 Elements.push_back(Element);
16698 }
16699
16700 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16701 return SemaRef.MaybeBindToTemporary(E);
16702
16703 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16704 Elements);
16705 }
16706
16707 template<typename Derived>
16708 ExprResult
TransformObjCEncodeExpr(ObjCEncodeExpr * E)16709 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16710 TypeSourceInfo *EncodedTypeInfo
16711 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16712 if (!EncodedTypeInfo)
16713 return ExprError();
16714
16715 if (!getDerived().AlwaysRebuild() &&
16716 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16717 return E;
16718
16719 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16720 EncodedTypeInfo,
16721 E->getRParenLoc());
16722 }
16723
16724 template<typename Derived>
16725 ExprResult TreeTransform<Derived>::
TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr * E)16726 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
16727 // This is a kind of implicit conversion, and it needs to get dropped
16728 // and recomputed for the same general reasons that ImplicitCastExprs
16729 // do, as well a more specific one: this expression is only valid when
16730 // it appears *immediately* as an argument expression.
16731 return getDerived().TransformExpr(E->getSubExpr());
16732 }
16733
16734 template<typename Derived>
16735 ExprResult TreeTransform<Derived>::
TransformObjCBridgedCastExpr(ObjCBridgedCastExpr * E)16736 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
16737 TypeSourceInfo *TSInfo
16738 = getDerived().TransformType(E->getTypeInfoAsWritten());
16739 if (!TSInfo)
16740 return ExprError();
16741
16742 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
16743 if (Result.isInvalid())
16744 return ExprError();
16745
16746 if (!getDerived().AlwaysRebuild() &&
16747 TSInfo == E->getTypeInfoAsWritten() &&
16748 Result.get() == E->getSubExpr())
16749 return E;
16750
16751 return SemaRef.ObjC().BuildObjCBridgedCast(
16752 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,
16753 Result.get());
16754 }
16755
16756 template <typename Derived>
TransformObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * E)16757 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
16758 ObjCAvailabilityCheckExpr *E) {
16759 return E;
16760 }
16761
16762 template<typename Derived>
16763 ExprResult
TransformObjCMessageExpr(ObjCMessageExpr * E)16764 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
16765 // Transform arguments.
16766 bool ArgChanged = false;
16767 SmallVector<Expr*, 8> Args;
16768 Args.reserve(E->getNumArgs());
16769 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
16770 &ArgChanged))
16771 return ExprError();
16772
16773 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
16774 // Class message: transform the receiver type.
16775 TypeSourceInfo *ReceiverTypeInfo
16776 = getDerived().TransformType(E->getClassReceiverTypeInfo());
16777 if (!ReceiverTypeInfo)
16778 return ExprError();
16779
16780 // If nothing changed, just retain the existing message send.
16781 if (!getDerived().AlwaysRebuild() &&
16782 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
16783 return SemaRef.MaybeBindToTemporary(E);
16784
16785 // Build a new class message send.
16786 SmallVector<SourceLocation, 16> SelLocs;
16787 E->getSelectorLocs(SelLocs);
16788 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
16789 E->getSelector(),
16790 SelLocs,
16791 E->getMethodDecl(),
16792 E->getLeftLoc(),
16793 Args,
16794 E->getRightLoc());
16795 }
16796 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
16797 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
16798 if (!E->getMethodDecl())
16799 return ExprError();
16800
16801 // Build a new class message send to 'super'.
16802 SmallVector<SourceLocation, 16> SelLocs;
16803 E->getSelectorLocs(SelLocs);
16804 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
16805 E->getSelector(),
16806 SelLocs,
16807 E->getReceiverType(),
16808 E->getMethodDecl(),
16809 E->getLeftLoc(),
16810 Args,
16811 E->getRightLoc());
16812 }
16813
16814 // Instance message: transform the receiver
16815 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
16816 "Only class and instance messages may be instantiated");
16817 ExprResult Receiver
16818 = getDerived().TransformExpr(E->getInstanceReceiver());
16819 if (Receiver.isInvalid())
16820 return ExprError();
16821
16822 // If nothing changed, just retain the existing message send.
16823 if (!getDerived().AlwaysRebuild() &&
16824 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
16825 return SemaRef.MaybeBindToTemporary(E);
16826
16827 // Build a new instance message send.
16828 SmallVector<SourceLocation, 16> SelLocs;
16829 E->getSelectorLocs(SelLocs);
16830 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
16831 E->getSelector(),
16832 SelLocs,
16833 E->getMethodDecl(),
16834 E->getLeftLoc(),
16835 Args,
16836 E->getRightLoc());
16837 }
16838
16839 template<typename Derived>
16840 ExprResult
TransformObjCSelectorExpr(ObjCSelectorExpr * E)16841 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
16842 return E;
16843 }
16844
16845 template<typename Derived>
16846 ExprResult
TransformObjCProtocolExpr(ObjCProtocolExpr * E)16847 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
16848 return E;
16849 }
16850
16851 template<typename Derived>
16852 ExprResult
TransformObjCIvarRefExpr(ObjCIvarRefExpr * E)16853 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
16854 // Transform the base expression.
16855 ExprResult Base = getDerived().TransformExpr(E->getBase());
16856 if (Base.isInvalid())
16857 return ExprError();
16858
16859 // We don't need to transform the ivar; it will never change.
16860
16861 // If nothing changed, just retain the existing expression.
16862 if (!getDerived().AlwaysRebuild() &&
16863 Base.get() == E->getBase())
16864 return E;
16865
16866 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
16867 E->getLocation(),
16868 E->isArrow(), E->isFreeIvar());
16869 }
16870
16871 template<typename Derived>
16872 ExprResult
TransformObjCPropertyRefExpr(ObjCPropertyRefExpr * E)16873 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
16874 // 'super' and types never change. Property never changes. Just
16875 // retain the existing expression.
16876 if (!E->isObjectReceiver())
16877 return E;
16878
16879 // Transform the base expression.
16880 ExprResult Base = getDerived().TransformExpr(E->getBase());
16881 if (Base.isInvalid())
16882 return ExprError();
16883
16884 // We don't need to transform the property; it will never change.
16885
16886 // If nothing changed, just retain the existing expression.
16887 if (!getDerived().AlwaysRebuild() &&
16888 Base.get() == E->getBase())
16889 return E;
16890
16891 if (E->isExplicitProperty())
16892 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16893 E->getExplicitProperty(),
16894 E->getLocation());
16895
16896 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16897 SemaRef.Context.PseudoObjectTy,
16898 E->getImplicitPropertyGetter(),
16899 E->getImplicitPropertySetter(),
16900 E->getLocation());
16901 }
16902
16903 template<typename Derived>
16904 ExprResult
TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr * E)16905 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
16906 // Transform the base expression.
16907 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
16908 if (Base.isInvalid())
16909 return ExprError();
16910
16911 // Transform the key expression.
16912 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
16913 if (Key.isInvalid())
16914 return ExprError();
16915
16916 // If nothing changed, just retain the existing expression.
16917 if (!getDerived().AlwaysRebuild() &&
16918 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
16919 return E;
16920
16921 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
16922 Base.get(), Key.get(),
16923 E->getAtIndexMethodDecl(),
16924 E->setAtIndexMethodDecl());
16925 }
16926
16927 template<typename Derived>
16928 ExprResult
TransformObjCIsaExpr(ObjCIsaExpr * E)16929 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
16930 // Transform the base expression.
16931 ExprResult Base = getDerived().TransformExpr(E->getBase());
16932 if (Base.isInvalid())
16933 return ExprError();
16934
16935 // If nothing changed, just retain the existing expression.
16936 if (!getDerived().AlwaysRebuild() &&
16937 Base.get() == E->getBase())
16938 return E;
16939
16940 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
16941 E->getOpLoc(),
16942 E->isArrow());
16943 }
16944
16945 template<typename Derived>
16946 ExprResult
TransformShuffleVectorExpr(ShuffleVectorExpr * E)16947 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
16948 bool ArgumentChanged = false;
16949 SmallVector<Expr*, 8> SubExprs;
16950 SubExprs.reserve(E->getNumSubExprs());
16951 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16952 SubExprs, &ArgumentChanged))
16953 return ExprError();
16954
16955 if (!getDerived().AlwaysRebuild() &&
16956 !ArgumentChanged)
16957 return E;
16958
16959 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
16960 SubExprs,
16961 E->getRParenLoc());
16962 }
16963
16964 template<typename Derived>
16965 ExprResult
TransformConvertVectorExpr(ConvertVectorExpr * E)16966 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
16967 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16968 if (SrcExpr.isInvalid())
16969 return ExprError();
16970
16971 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16972 if (!Type)
16973 return ExprError();
16974
16975 if (!getDerived().AlwaysRebuild() &&
16976 Type == E->getTypeSourceInfo() &&
16977 SrcExpr.get() == E->getSrcExpr())
16978 return E;
16979
16980 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16981 SrcExpr.get(), Type,
16982 E->getRParenLoc());
16983 }
16984
16985 template<typename Derived>
16986 ExprResult
TransformBlockExpr(BlockExpr * E)16987 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16988 BlockDecl *oldBlock = E->getBlockDecl();
16989
16990 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
16991 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16992
16993 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16994 blockScope->TheDecl->setBlockMissingReturnType(
16995 oldBlock->blockMissingReturnType());
16996
16997 SmallVector<ParmVarDecl*, 4> params;
16998 SmallVector<QualType, 4> paramTypes;
16999
17000 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17001
17002 // Parameter substitution.
17003 Sema::ExtParameterInfoBuilder extParamInfos;
17004 if (getDerived().TransformFunctionTypeParams(
17005 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17006 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, ¶ms,
17007 extParamInfos)) {
17008 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17009 return ExprError();
17010 }
17011
17012 QualType exprResultType =
17013 getDerived().TransformType(exprFunctionType->getReturnType());
17014
17015 auto epi = exprFunctionType->getExtProtoInfo();
17016 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
17017
17018 QualType functionType =
17019 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17020 blockScope->FunctionType = functionType;
17021
17022 // Set the parameters on the block decl.
17023 if (!params.empty())
17024 blockScope->TheDecl->setParams(params);
17025
17026 if (!oldBlock->blockMissingReturnType()) {
17027 blockScope->HasImplicitReturnType = false;
17028 blockScope->ReturnType = exprResultType;
17029 }
17030
17031 // Transform the body
17032 StmtResult body = getDerived().TransformStmt(E->getBody());
17033 if (body.isInvalid()) {
17034 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17035 return ExprError();
17036 }
17037
17038 #ifndef NDEBUG
17039 // In builds with assertions, make sure that we captured everything we
17040 // captured before.
17041 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17042 for (const auto &I : oldBlock->captures()) {
17043 VarDecl *oldCapture = I.getVariable();
17044
17045 // Ignore parameter packs.
17046 if (oldCapture->isParameterPack())
17047 continue;
17048
17049 VarDecl *newCapture =
17050 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17051 oldCapture));
17052 assert(blockScope->CaptureMap.count(newCapture));
17053 }
17054
17055 // The this pointer may not be captured by the instantiated block, even when
17056 // it's captured by the original block, if the expression causing the
17057 // capture is in the discarded branch of a constexpr if statement.
17058 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17059 "this pointer isn't captured in the old block");
17060 }
17061 #endif
17062
17063 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
17064 /*Scope=*/nullptr);
17065 }
17066
17067 template<typename Derived>
17068 ExprResult
TransformAsTypeExpr(AsTypeExpr * E)17069 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17070 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17071 if (SrcExpr.isInvalid())
17072 return ExprError();
17073
17074 QualType Type = getDerived().TransformType(E->getType());
17075
17076 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
17077 E->getRParenLoc());
17078 }
17079
17080 template<typename Derived>
17081 ExprResult
TransformAtomicExpr(AtomicExpr * E)17082 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17083 bool ArgumentChanged = false;
17084 SmallVector<Expr*, 8> SubExprs;
17085 SubExprs.reserve(E->getNumSubExprs());
17086 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17087 SubExprs, &ArgumentChanged))
17088 return ExprError();
17089
17090 if (!getDerived().AlwaysRebuild() &&
17091 !ArgumentChanged)
17092 return E;
17093
17094 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17095 E->getOp(), E->getRParenLoc());
17096 }
17097
17098 //===----------------------------------------------------------------------===//
17099 // Type reconstruction
17100 //===----------------------------------------------------------------------===//
17101
17102 template<typename Derived>
RebuildPointerType(QualType PointeeType,SourceLocation Star)17103 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17104 SourceLocation Star) {
17105 return SemaRef.BuildPointerType(PointeeType, Star,
17106 getDerived().getBaseEntity());
17107 }
17108
17109 template<typename Derived>
RebuildBlockPointerType(QualType PointeeType,SourceLocation Star)17110 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17111 SourceLocation Star) {
17112 return SemaRef.BuildBlockPointerType(PointeeType, Star,
17113 getDerived().getBaseEntity());
17114 }
17115
17116 template<typename Derived>
17117 QualType
RebuildReferenceType(QualType ReferentType,bool WrittenAsLValue,SourceLocation Sigil)17118 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17119 bool WrittenAsLValue,
17120 SourceLocation Sigil) {
17121 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
17122 Sigil, getDerived().getBaseEntity());
17123 }
17124
17125 template <typename Derived>
RebuildMemberPointerType(QualType PointeeType,const CXXScopeSpec & SS,CXXRecordDecl * Cls,SourceLocation Sigil)17126 QualType TreeTransform<Derived>::RebuildMemberPointerType(
17127 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17128 SourceLocation Sigil) {
17129 return SemaRef.BuildMemberPointerType(PointeeType, SS, Cls, Sigil,
17130 getDerived().getBaseEntity());
17131 }
17132
17133 template<typename Derived>
RebuildObjCTypeParamType(const ObjCTypeParamDecl * Decl,SourceLocation ProtocolLAngleLoc,ArrayRef<ObjCProtocolDecl * > Protocols,ArrayRef<SourceLocation> ProtocolLocs,SourceLocation ProtocolRAngleLoc)17134 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17135 const ObjCTypeParamDecl *Decl,
17136 SourceLocation ProtocolLAngleLoc,
17137 ArrayRef<ObjCProtocolDecl *> Protocols,
17138 ArrayRef<SourceLocation> ProtocolLocs,
17139 SourceLocation ProtocolRAngleLoc) {
17140 return SemaRef.ObjC().BuildObjCTypeParamType(
17141 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17142 /*FailOnError=*/true);
17143 }
17144
17145 template<typename Derived>
RebuildObjCObjectType(QualType BaseType,SourceLocation Loc,SourceLocation TypeArgsLAngleLoc,ArrayRef<TypeSourceInfo * > TypeArgs,SourceLocation TypeArgsRAngleLoc,SourceLocation ProtocolLAngleLoc,ArrayRef<ObjCProtocolDecl * > Protocols,ArrayRef<SourceLocation> ProtocolLocs,SourceLocation ProtocolRAngleLoc)17146 QualType TreeTransform<Derived>::RebuildObjCObjectType(
17147 QualType BaseType,
17148 SourceLocation Loc,
17149 SourceLocation TypeArgsLAngleLoc,
17150 ArrayRef<TypeSourceInfo *> TypeArgs,
17151 SourceLocation TypeArgsRAngleLoc,
17152 SourceLocation ProtocolLAngleLoc,
17153 ArrayRef<ObjCProtocolDecl *> Protocols,
17154 ArrayRef<SourceLocation> ProtocolLocs,
17155 SourceLocation ProtocolRAngleLoc) {
17156 return SemaRef.ObjC().BuildObjCObjectType(
17157 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17158 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17159 /*FailOnError=*/true,
17160 /*Rebuilding=*/true);
17161 }
17162
17163 template<typename Derived>
RebuildObjCObjectPointerType(QualType PointeeType,SourceLocation Star)17164 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17165 QualType PointeeType,
17166 SourceLocation Star) {
17167 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
17168 }
17169
17170 template <typename Derived>
RebuildArrayType(QualType ElementType,ArraySizeModifier SizeMod,const llvm::APInt * Size,Expr * SizeExpr,unsigned IndexTypeQuals,SourceRange BracketsRange)17171 QualType TreeTransform<Derived>::RebuildArrayType(
17172 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17173 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17174 if (SizeExpr || !Size)
17175 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
17176 IndexTypeQuals, BracketsRange,
17177 getDerived().getBaseEntity());
17178
17179 QualType Types[] = {
17180 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17181 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17182 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17183 };
17184 QualType SizeType;
17185 for (const auto &T : Types)
17186 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17187 SizeType = T;
17188 break;
17189 }
17190
17191 // Note that we can return a VariableArrayType here in the case where
17192 // the element type was a dependent VariableArrayType.
17193 IntegerLiteral *ArraySize
17194 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
17195 /*FIXME*/BracketsRange.getBegin());
17196 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
17197 IndexTypeQuals, BracketsRange,
17198 getDerived().getBaseEntity());
17199 }
17200
17201 template <typename Derived>
RebuildConstantArrayType(QualType ElementType,ArraySizeModifier SizeMod,const llvm::APInt & Size,Expr * SizeExpr,unsigned IndexTypeQuals,SourceRange BracketsRange)17202 QualType TreeTransform<Derived>::RebuildConstantArrayType(
17203 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17204 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17205 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17206 IndexTypeQuals, BracketsRange);
17207 }
17208
17209 template <typename Derived>
RebuildIncompleteArrayType(QualType ElementType,ArraySizeModifier SizeMod,unsigned IndexTypeQuals,SourceRange BracketsRange)17210 QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17211 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17212 SourceRange BracketsRange) {
17213 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17214 IndexTypeQuals, BracketsRange);
17215 }
17216
17217 template <typename Derived>
RebuildVariableArrayType(QualType ElementType,ArraySizeModifier SizeMod,Expr * SizeExpr,unsigned IndexTypeQuals,SourceRange BracketsRange)17218 QualType TreeTransform<Derived>::RebuildVariableArrayType(
17219 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17220 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17221 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17222 SizeExpr,
17223 IndexTypeQuals, BracketsRange);
17224 }
17225
17226 template <typename Derived>
RebuildDependentSizedArrayType(QualType ElementType,ArraySizeModifier SizeMod,Expr * SizeExpr,unsigned IndexTypeQuals,SourceRange BracketsRange)17227 QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17228 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17229 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17230 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17231 SizeExpr,
17232 IndexTypeQuals, BracketsRange);
17233 }
17234
17235 template <typename Derived>
RebuildDependentAddressSpaceType(QualType PointeeType,Expr * AddrSpaceExpr,SourceLocation AttributeLoc)17236 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17237 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17238 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
17239 AttributeLoc);
17240 }
17241
17242 template <typename Derived>
RebuildVectorType(QualType ElementType,unsigned NumElements,VectorKind VecKind)17243 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17244 unsigned NumElements,
17245 VectorKind VecKind) {
17246 // FIXME: semantic checking!
17247 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
17248 }
17249
17250 template <typename Derived>
RebuildDependentVectorType(QualType ElementType,Expr * SizeExpr,SourceLocation AttributeLoc,VectorKind VecKind)17251 QualType TreeTransform<Derived>::RebuildDependentVectorType(
17252 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17253 VectorKind VecKind) {
17254 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
17255 }
17256
17257 template<typename Derived>
RebuildExtVectorType(QualType ElementType,unsigned NumElements,SourceLocation AttributeLoc)17258 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17259 unsigned NumElements,
17260 SourceLocation AttributeLoc) {
17261 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
17262 NumElements, true);
17263 IntegerLiteral *VectorSize
17264 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
17265 AttributeLoc);
17266 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
17267 }
17268
17269 template<typename Derived>
17270 QualType
RebuildDependentSizedExtVectorType(QualType ElementType,Expr * SizeExpr,SourceLocation AttributeLoc)17271 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17272 Expr *SizeExpr,
17273 SourceLocation AttributeLoc) {
17274 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
17275 }
17276
17277 template <typename Derived>
RebuildConstantMatrixType(QualType ElementType,unsigned NumRows,unsigned NumColumns)17278 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17279 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17280 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17281 NumColumns);
17282 }
17283
17284 template <typename Derived>
RebuildDependentSizedMatrixType(QualType ElementType,Expr * RowExpr,Expr * ColumnExpr,SourceLocation AttributeLoc)17285 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17286 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17287 SourceLocation AttributeLoc) {
17288 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
17289 AttributeLoc);
17290 }
17291
17292 template <typename Derived>
RebuildFunctionProtoType(QualType T,MutableArrayRef<QualType> ParamTypes,const FunctionProtoType::ExtProtoInfo & EPI)17293 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17294 QualType T, MutableArrayRef<QualType> ParamTypes,
17295 const FunctionProtoType::ExtProtoInfo &EPI) {
17296 return SemaRef.BuildFunctionType(T, ParamTypes,
17297 getDerived().getBaseLocation(),
17298 getDerived().getBaseEntity(),
17299 EPI);
17300 }
17301
17302 template<typename Derived>
RebuildFunctionNoProtoType(QualType T)17303 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17304 return SemaRef.Context.getFunctionNoProtoType(T);
17305 }
17306
17307 template<typename Derived>
RebuildUnresolvedUsingType(SourceLocation Loc,Decl * D)17308 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
17309 Decl *D) {
17310 assert(D && "no decl found");
17311 if (D->isInvalidDecl()) return QualType();
17312
17313 // FIXME: Doesn't account for ObjCInterfaceDecl!
17314 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
17315 // A valid resolved using typename pack expansion decl can have multiple
17316 // UsingDecls, but they must each have exactly one type, and it must be
17317 // the same type in every case. But we must have at least one expansion!
17318 if (UPD->expansions().empty()) {
17319 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
17320 << UPD->isCXXClassMember() << UPD;
17321 return QualType();
17322 }
17323
17324 // We might still have some unresolved types. Try to pick a resolved type
17325 // if we can. The final instantiation will check that the remaining
17326 // unresolved types instantiate to the type we pick.
17327 QualType FallbackT;
17328 QualType T;
17329 for (auto *E : UPD->expansions()) {
17330 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
17331 if (ThisT.isNull())
17332 continue;
17333 else if (ThisT->getAs<UnresolvedUsingType>())
17334 FallbackT = ThisT;
17335 else if (T.isNull())
17336 T = ThisT;
17337 else
17338 assert(getSema().Context.hasSameType(ThisT, T) &&
17339 "mismatched resolved types in using pack expansion");
17340 }
17341 return T.isNull() ? FallbackT : T;
17342 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
17343 assert(Using->hasTypename() &&
17344 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17345
17346 // A valid resolved using typename decl points to exactly one type decl.
17347 assert(++Using->shadow_begin() == Using->shadow_end());
17348
17349 UsingShadowDecl *Shadow = *Using->shadow_begin();
17350 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
17351 return QualType();
17352 return SemaRef.Context.getUsingType(
17353 Shadow, SemaRef.Context.getTypeDeclType(
17354 cast<TypeDecl>(Shadow->getTargetDecl())));
17355 } else {
17356 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17357 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17358 return SemaRef.Context.getTypeDeclType(
17359 cast<UnresolvedUsingTypenameDecl>(D));
17360 }
17361 }
17362
17363 template <typename Derived>
RebuildTypeOfExprType(Expr * E,SourceLocation,TypeOfKind Kind)17364 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17365 TypeOfKind Kind) {
17366 return SemaRef.BuildTypeofExprType(E, Kind);
17367 }
17368
17369 template<typename Derived>
RebuildTypeOfType(QualType Underlying,TypeOfKind Kind)17370 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17371 TypeOfKind Kind) {
17372 return SemaRef.Context.getTypeOfType(Underlying, Kind);
17373 }
17374
17375 template <typename Derived>
RebuildDecltypeType(Expr * E,SourceLocation)17376 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17377 return SemaRef.BuildDecltypeType(E);
17378 }
17379
17380 template <typename Derived>
RebuildPackIndexingType(QualType Pattern,Expr * IndexExpr,SourceLocation Loc,SourceLocation EllipsisLoc,bool FullySubstituted,ArrayRef<QualType> Expansions)17381 QualType TreeTransform<Derived>::RebuildPackIndexingType(
17382 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17383 SourceLocation EllipsisLoc, bool FullySubstituted,
17384 ArrayRef<QualType> Expansions) {
17385 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17386 FullySubstituted, Expansions);
17387 }
17388
17389 template<typename Derived>
RebuildUnaryTransformType(QualType BaseType,UnaryTransformType::UTTKind UKind,SourceLocation Loc)17390 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17391 UnaryTransformType::UTTKind UKind,
17392 SourceLocation Loc) {
17393 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17394 }
17395
17396 template<typename Derived>
RebuildTemplateSpecializationType(TemplateName Template,SourceLocation TemplateNameLoc,TemplateArgumentListInfo & TemplateArgs)17397 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17398 TemplateName Template,
17399 SourceLocation TemplateNameLoc,
17400 TemplateArgumentListInfo &TemplateArgs) {
17401 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
17402 }
17403
17404 template<typename Derived>
RebuildAtomicType(QualType ValueType,SourceLocation KWLoc)17405 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17406 SourceLocation KWLoc) {
17407 return SemaRef.BuildAtomicType(ValueType, KWLoc);
17408 }
17409
17410 template<typename Derived>
RebuildPipeType(QualType ValueType,SourceLocation KWLoc,bool isReadPipe)17411 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17412 SourceLocation KWLoc,
17413 bool isReadPipe) {
17414 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
17415 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
17416 }
17417
17418 template <typename Derived>
RebuildBitIntType(bool IsUnsigned,unsigned NumBits,SourceLocation Loc)17419 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17420 unsigned NumBits,
17421 SourceLocation Loc) {
17422 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
17423 NumBits, true);
17424 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
17425 SemaRef.Context.IntTy, Loc);
17426 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
17427 }
17428
17429 template <typename Derived>
RebuildDependentBitIntType(bool IsUnsigned,Expr * NumBitsExpr,SourceLocation Loc)17430 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17431 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17432 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
17433 }
17434
17435 template<typename Derived>
17436 TemplateName
RebuildTemplateName(CXXScopeSpec & SS,bool TemplateKW,TemplateDecl * Template)17437 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17438 bool TemplateKW,
17439 TemplateDecl *Template) {
17440 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
17441 TemplateName(Template));
17442 }
17443
17444 template<typename Derived>
17445 TemplateName
RebuildTemplateName(CXXScopeSpec & SS,SourceLocation TemplateKWLoc,const IdentifierInfo & Name,SourceLocation NameLoc,QualType ObjectType,NamedDecl * FirstQualifierInScope,bool AllowInjectedClassName)17446 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17447 SourceLocation TemplateKWLoc,
17448 const IdentifierInfo &Name,
17449 SourceLocation NameLoc,
17450 QualType ObjectType,
17451 NamedDecl *FirstQualifierInScope,
17452 bool AllowInjectedClassName) {
17453 UnqualifiedId TemplateName;
17454 TemplateName.setIdentifier(&Name, NameLoc);
17455 Sema::TemplateTy Template;
17456 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17457 TemplateName, ParsedType::make(ObjectType),
17458 /*EnteringContext=*/false, Template,
17459 AllowInjectedClassName);
17460 return Template.get();
17461 }
17462
17463 template<typename Derived>
17464 TemplateName
RebuildTemplateName(CXXScopeSpec & SS,SourceLocation TemplateKWLoc,OverloadedOperatorKind Operator,SourceLocation NameLoc,QualType ObjectType,bool AllowInjectedClassName)17465 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17466 SourceLocation TemplateKWLoc,
17467 OverloadedOperatorKind Operator,
17468 SourceLocation NameLoc,
17469 QualType ObjectType,
17470 bool AllowInjectedClassName) {
17471 UnqualifiedId Name;
17472 // FIXME: Bogus location information.
17473 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17474 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
17475 Sema::TemplateTy Template;
17476 getSema().ActOnTemplateName(
17477 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
17478 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17479 return Template.get();
17480 }
17481
17482 template <typename Derived>
RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,SourceLocation OpLoc,SourceLocation CalleeLoc,bool RequiresADL,const UnresolvedSetImpl & Functions,Expr * First,Expr * Second)17483 ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17484 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17485 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17486 Expr *Second) {
17487 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17488
17489 if (First->getObjectKind() == OK_ObjCProperty) {
17490 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
17491 if (BinaryOperator::isAssignmentOp(Opc))
17492 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc,
17493 Opc, First, Second);
17494 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
17495 if (Result.isInvalid())
17496 return ExprError();
17497 First = Result.get();
17498 }
17499
17500 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17501 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
17502 if (Result.isInvalid())
17503 return ExprError();
17504 Second = Result.get();
17505 }
17506
17507 // Determine whether this should be a builtin operation.
17508 if (Op == OO_Subscript) {
17509 if (!First->getType()->isOverloadableType() &&
17510 !Second->getType()->isOverloadableType())
17511 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17512 OpLoc);
17513 } else if (Op == OO_Arrow) {
17514 // It is possible that the type refers to a RecoveryExpr created earlier
17515 // in the tree transformation.
17516 if (First->getType()->isDependentType())
17517 return ExprError();
17518 // -> is never a builtin operation.
17519 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
17520 } else if (Second == nullptr || isPostIncDec) {
17521 if (!First->getType()->isOverloadableType() ||
17522 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17523 // The argument is not of overloadable type, or this is an expression
17524 // of the form &Class::member, so try to create a built-in unary
17525 // operation.
17526 UnaryOperatorKind Opc
17527 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
17528
17529 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17530 }
17531 } else {
17532 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17533 !First->getType()->isOverloadableType() &&
17534 !Second->getType()->isOverloadableType()) {
17535 // Neither of the arguments is type-dependent or has an overloadable
17536 // type, so try to create a built-in binary operation.
17537 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
17538 ExprResult Result
17539 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
17540 if (Result.isInvalid())
17541 return ExprError();
17542
17543 return Result;
17544 }
17545 }
17546
17547 // Create the overloaded operator invocation for unary operators.
17548 if (!Second || isPostIncDec) {
17549 UnaryOperatorKind Opc
17550 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
17551 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
17552 RequiresADL);
17553 }
17554
17555 // Create the overloaded operator invocation for binary operators.
17556 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
17557 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
17558 First, Second, RequiresADL);
17559 if (Result.isInvalid())
17560 return ExprError();
17561
17562 return Result;
17563 }
17564
17565 template<typename Derived>
17566 ExprResult
RebuildCXXPseudoDestructorExpr(Expr * Base,SourceLocation OperatorLoc,bool isArrow,CXXScopeSpec & SS,TypeSourceInfo * ScopeType,SourceLocation CCLoc,SourceLocation TildeLoc,PseudoDestructorTypeStorage Destroyed)17567 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17568 SourceLocation OperatorLoc,
17569 bool isArrow,
17570 CXXScopeSpec &SS,
17571 TypeSourceInfo *ScopeType,
17572 SourceLocation CCLoc,
17573 SourceLocation TildeLoc,
17574 PseudoDestructorTypeStorage Destroyed) {
17575 QualType BaseType = Base->getType();
17576 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17577 (!isArrow && !BaseType->getAs<RecordType>()) ||
17578 (isArrow && BaseType->getAs<PointerType>() &&
17579 !BaseType->castAs<PointerType>()->getPointeeType()
17580 ->template getAs<RecordType>())){
17581 // This pseudo-destructor expression is still a pseudo-destructor.
17582 return SemaRef.BuildPseudoDestructorExpr(
17583 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
17584 CCLoc, TildeLoc, Destroyed);
17585 }
17586
17587 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17588 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17589 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
17590 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17591 NameInfo.setNamedTypeInfo(DestroyedType);
17592
17593 // The scope type is now known to be a valid nested name specifier
17594 // component. Tack it on to the end of the nested name specifier.
17595 if (ScopeType) {
17596 if (!ScopeType->getType()->getAs<TagType>()) {
17597 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17598 diag::err_expected_class_or_namespace)
17599 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17600 return ExprError();
17601 }
17602 SS.Extend(SemaRef.Context, ScopeType->getTypeLoc(), CCLoc);
17603 }
17604
17605 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17606 return getSema().BuildMemberReferenceExpr(Base, BaseType,
17607 OperatorLoc, isArrow,
17608 SS, TemplateKWLoc,
17609 /*FIXME: FirstQualifier*/ nullptr,
17610 NameInfo,
17611 /*TemplateArgs*/ nullptr,
17612 /*S*/nullptr);
17613 }
17614
17615 template<typename Derived>
17616 StmtResult
TransformCapturedStmt(CapturedStmt * S)17617 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17618 SourceLocation Loc = S->getBeginLoc();
17619 CapturedDecl *CD = S->getCapturedDecl();
17620 unsigned NumParams = CD->getNumParams();
17621 unsigned ContextParamPos = CD->getContextParamPosition();
17622 SmallVector<Sema::CapturedParamNameType, 4> Params;
17623 for (unsigned I = 0; I < NumParams; ++I) {
17624 if (I != ContextParamPos) {
17625 Params.push_back(
17626 std::make_pair(
17627 CD->getParam(I)->getName(),
17628 getDerived().TransformType(CD->getParam(I)->getType())));
17629 } else {
17630 Params.push_back(std::make_pair(StringRef(), QualType()));
17631 }
17632 }
17633 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17634 S->getCapturedRegionKind(), Params);
17635 StmtResult Body;
17636 {
17637 Sema::CompoundScopeRAII CompoundScope(getSema());
17638 Body = getDerived().TransformStmt(S->getCapturedStmt());
17639 }
17640
17641 if (Body.isInvalid()) {
17642 getSema().ActOnCapturedRegionError();
17643 return StmtError();
17644 }
17645
17646 return getSema().ActOnCapturedRegionEnd(Body.get());
17647 }
17648
17649 template <typename Derived>
17650 StmtResult
TransformSYCLKernelCallStmt(SYCLKernelCallStmt * S)17651 TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17652 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17653 // function definition or instantiation of a function template specialization
17654 // and will therefore never appear in a dependent context.
17655 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17656 "context");
17657 }
17658
17659 template <typename Derived>
TransformHLSLOutArgExpr(HLSLOutArgExpr * E)17660 ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17661 // We can transform the base expression and allow argument resolution to fill
17662 // in the rest.
17663 return getDerived().TransformExpr(E->getArgLValue());
17664 }
17665
17666 } // end namespace clang
17667
17668 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
17669