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/Basic/DiagnosticParse.h"
33#include "clang/Basic/OpenMPKinds.h"
34#include "clang/Sema/Designator.h"
35#include "clang/Sema/EnterExpressionEvaluationContext.h"
36#include "clang/Sema/Lookup.h"
37#include "clang/Sema/Ownership.h"
38#include "clang/Sema/ParsedTemplate.h"
39#include "clang/Sema/ScopeInfo.h"
40#include "clang/Sema/SemaDiagnostic.h"
41#include "clang/Sema/SemaInternal.h"
42#include "clang/Sema/SemaObjC.h"
43#include "clang/Sema/SemaOpenACC.h"
44#include "clang/Sema/SemaOpenMP.h"
45#include "clang/Sema/SemaPseudoObject.h"
46#include "clang/Sema/SemaSYCL.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/Support/ErrorHandling.h"
49#include <algorithm>
50#include <optional>
51
52using namespace llvm::omp;
53
54namespace clang {
55using namespace sema;
56
57/// A semantic tree transformation that allows one to transform one
58/// abstract syntax tree into another.
59///
60/// A new tree transformation is defined by creating a new subclass \c X of
61/// \c TreeTransform<X> and then overriding certain operations to provide
62/// behavior specific to that transformation. For example, template
63/// instantiation is implemented as a tree transformation where the
64/// transformation of TemplateTypeParmType nodes involves substituting the
65/// template arguments for their corresponding template parameters; a similar
66/// transformation is performed for non-type template parameters and
67/// template template parameters.
68///
69/// This tree-transformation template uses static polymorphism to allow
70/// subclasses to customize any of its operations. Thus, a subclass can
71/// override any of the transformation or rebuild operators by providing an
72/// operation with the same signature as the default implementation. The
73/// overriding function should not be virtual.
74///
75/// Semantic tree transformations are split into two stages, either of which
76/// can be replaced by a subclass. The "transform" step transforms an AST node
77/// or the parts of an AST node using the various transformation functions,
78/// then passes the pieces on to the "rebuild" step, which constructs a new AST
79/// node of the appropriate kind from the pieces. The default transformation
80/// routines recursively transform the operands to composite AST nodes (e.g.,
81/// the pointee type of a PointerType node) and, if any of those operand nodes
82/// were changed by the transformation, invokes the rebuild operation to create
83/// a new AST node.
84///
85/// Subclasses can customize the transformation at various levels. The
86/// most coarse-grained transformations involve replacing TransformType(),
87/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
88/// TransformTemplateName(), or TransformTemplateArgument() with entirely
89/// new implementations.
90///
91/// For more fine-grained transformations, subclasses can replace any of the
92/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
93/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
94/// replacing TransformTemplateTypeParmType() allows template instantiation
95/// to substitute template arguments for their corresponding template
96/// parameters. Additionally, subclasses can override the \c RebuildXXX
97/// functions to control how AST nodes are rebuilt when their operands change.
98/// By default, \c TreeTransform will invoke semantic analysis to rebuild
99/// AST nodes. However, certain other tree transformations (e.g, cloning) may
100/// be able to use more efficient rebuild steps.
101///
102/// There are a handful of other functions that can be overridden, allowing one
103/// to avoid traversing nodes that don't need any transformation
104/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
105/// operands have not changed (\c AlwaysRebuild()), and customize the
106/// default locations and entity names used for type-checking
107/// (\c getBaseLocation(), \c getBaseEntity()).
108template<typename Derived>
109class TreeTransform {
110 /// Private RAII object that helps us forget and then re-remember
111 /// the template argument corresponding to a partially-substituted parameter
112 /// pack.
113 class ForgetPartiallySubstitutedPackRAII {
114 Derived &Self;
115 TemplateArgument Old;
116
117 public:
118 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
119 Old = Self.ForgetPartiallySubstitutedPack();
120 }
121
122 ~ForgetPartiallySubstitutedPackRAII() {
123 Self.RememberPartiallySubstitutedPack(Old);
124 }
125 };
126
127protected:
128 Sema &SemaRef;
129
130 /// The set of local declarations that have been transformed, for
131 /// cases where we are forced to build new declarations within the transformer
132 /// rather than in the subclass (e.g., lambda closure types).
133 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
134
135public:
136 /// Initializes a new tree transformer.
137 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
138
139 /// Retrieves a reference to the derived class.
140 Derived &getDerived() { return static_cast<Derived&>(*this); }
141
142 /// Retrieves a reference to the derived class.
143 const Derived &getDerived() const {
144 return static_cast<const Derived&>(*this);
145 }
146
147 static inline ExprResult Owned(Expr *E) { return E; }
148 static inline StmtResult Owned(Stmt *S) { return S; }
149
150 /// Retrieves a reference to the semantic analysis object used for
151 /// this tree transform.
152 Sema &getSema() const { return SemaRef; }
153
154 /// Whether the transformation should always rebuild AST nodes, even
155 /// if none of the children have changed.
156 ///
157 /// Subclasses may override this function to specify when the transformation
158 /// should rebuild all AST nodes.
159 ///
160 /// We must always rebuild all AST nodes when performing variadic template
161 /// pack expansion, in order to avoid violating the AST invariant that each
162 /// statement node appears at most once in its containing declaration.
163 bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
164
165 /// Whether the transformation is forming an expression or statement that
166 /// replaces the original. In this case, we'll reuse mangling numbers from
167 /// existing lambdas.
168 bool ReplacingOriginal() { return false; }
169
170 /// Wether CXXConstructExpr can be skipped when they are implicit.
171 /// They will be reconstructed when used if needed.
172 /// This is useful when the user that cause rebuilding of the
173 /// CXXConstructExpr is outside of the expression at which the TreeTransform
174 /// started.
175 bool AllowSkippingCXXConstructExpr() { return true; }
176
177 /// Returns the location of the entity being transformed, if that
178 /// information was not available elsewhere in the AST.
179 ///
180 /// By default, returns no source-location information. Subclasses can
181 /// provide an alternative implementation that provides better location
182 /// information.
183 SourceLocation getBaseLocation() { return SourceLocation(); }
184
185 /// Returns the name of the entity being transformed, if that
186 /// information was not available elsewhere in the AST.
187 ///
188 /// By default, returns an empty name. Subclasses can provide an alternative
189 /// implementation with a more precise name.
190 DeclarationName getBaseEntity() { return DeclarationName(); }
191
192 /// Sets the "base" location and entity when that
193 /// information is known based on another transformation.
194 ///
195 /// By default, the source location and entity are ignored. Subclasses can
196 /// override this function to provide a customized implementation.
197 void setBase(SourceLocation Loc, DeclarationName Entity) { }
198
199 /// RAII object that temporarily sets the base location and entity
200 /// used for reporting diagnostics in types.
201 class TemporaryBase {
202 TreeTransform &Self;
203 SourceLocation OldLocation;
204 DeclarationName OldEntity;
205
206 public:
207 TemporaryBase(TreeTransform &Self, SourceLocation Location,
208 DeclarationName Entity) : Self(Self) {
209 OldLocation = Self.getDerived().getBaseLocation();
210 OldEntity = Self.getDerived().getBaseEntity();
211
212 if (Location.isValid())
213 Self.getDerived().setBase(Location, Entity);
214 }
215
216 ~TemporaryBase() {
217 Self.getDerived().setBase(OldLocation, OldEntity);
218 }
219 };
220
221 /// Determine whether the given type \p T has already been
222 /// transformed.
223 ///
224 /// Subclasses can provide an alternative implementation of this routine
225 /// to short-circuit evaluation when it is known that a given type will
226 /// not change. For example, template instantiation need not traverse
227 /// non-dependent types.
228 bool AlreadyTransformed(QualType T) {
229 return T.isNull();
230 }
231
232 /// Transform a template parameter depth level.
233 ///
234 /// During a transformation that transforms template parameters, this maps
235 /// an old template parameter depth to a new depth.
236 unsigned TransformTemplateDepth(unsigned Depth) {
237 return Depth;
238 }
239
240 /// Determine whether the given call argument should be dropped, e.g.,
241 /// because it is a default argument.
242 ///
243 /// Subclasses can provide an alternative implementation of this routine to
244 /// determine which kinds of call arguments get dropped. By default,
245 /// CXXDefaultArgument nodes are dropped (prior to transformation).
246 bool DropCallArgument(Expr *E) {
247 return E->isDefaultArgument();
248 }
249
250 /// Determine whether we should expand a pack expansion with the
251 /// given set of parameter packs into separate arguments by repeatedly
252 /// transforming the pattern.
253 ///
254 /// By default, the transformer never tries to expand pack expansions.
255 /// Subclasses can override this routine to provide different behavior.
256 ///
257 /// \param EllipsisLoc The location of the ellipsis that identifies the
258 /// pack expansion.
259 ///
260 /// \param PatternRange The source range that covers the entire pattern of
261 /// the pack expansion.
262 ///
263 /// \param Unexpanded The set of unexpanded parameter packs within the
264 /// pattern.
265 ///
266 /// \param ShouldExpand Will be set to \c true if the transformer should
267 /// expand the corresponding pack expansions into separate arguments. When
268 /// set, \c NumExpansions must also be set.
269 ///
270 /// \param RetainExpansion Whether the caller should add an unexpanded
271 /// pack expansion after all of the expanded arguments. This is used
272 /// when extending explicitly-specified template argument packs per
273 /// C++0x [temp.arg.explicit]p9.
274 ///
275 /// \param NumExpansions The number of separate arguments that will be in
276 /// the expanded form of the corresponding pack expansion. This is both an
277 /// input and an output parameter, which can be set by the caller if the
278 /// number of expansions is known a priori (e.g., due to a prior substitution)
279 /// and will be set by the callee when the number of expansions is known.
280 /// The callee must set this value when \c ShouldExpand is \c true; it may
281 /// set this value in other cases.
282 ///
283 /// \returns true if an error occurred (e.g., because the parameter packs
284 /// are to be instantiated with arguments of different lengths), false
285 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
286 /// must be set.
287 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
288 SourceRange PatternRange,
289 ArrayRef<UnexpandedParameterPack> Unexpanded,
290 bool &ShouldExpand, bool &RetainExpansion,
291 std::optional<unsigned> &NumExpansions) {
292 ShouldExpand = false;
293 return false;
294 }
295
296 /// "Forget" about the partially-substituted pack template argument,
297 /// when performing an instantiation that must preserve the parameter pack
298 /// use.
299 ///
300 /// This routine is meant to be overridden by the template instantiator.
301 TemplateArgument ForgetPartiallySubstitutedPack() {
302 return TemplateArgument();
303 }
304
305 /// "Remember" the partially-substituted pack template argument
306 /// after performing an instantiation that must preserve the parameter pack
307 /// use.
308 ///
309 /// This routine is meant to be overridden by the template instantiator.
310 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
311
312 /// Note to the derived class when a function parameter pack is
313 /// being expanded.
314 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
315
316 /// Transforms the given type into another type.
317 ///
318 /// By default, this routine transforms a type by creating a
319 /// TypeSourceInfo for it and delegating to the appropriate
320 /// function. This is expensive, but we don't mind, because
321 /// this method is deprecated anyway; all users should be
322 /// switched to storing TypeSourceInfos.
323 ///
324 /// \returns the transformed type.
325 QualType TransformType(QualType T);
326
327 /// Transforms the given type-with-location into a new
328 /// type-with-location.
329 ///
330 /// By default, this routine transforms a type by delegating to the
331 /// appropriate TransformXXXType to build a new type. Subclasses
332 /// may override this function (to take over all type
333 /// transformations) or some set of the TransformXXXType functions
334 /// to alter the transformation.
335 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
336
337 /// Transform the given type-with-location into a new
338 /// type, collecting location information in the given builder
339 /// as necessary.
340 ///
341 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
342
343 /// Transform a type that is permitted to produce a
344 /// DeducedTemplateSpecializationType.
345 ///
346 /// This is used in the (relatively rare) contexts where it is acceptable
347 /// for transformation to produce a class template type with deduced
348 /// template arguments.
349 /// @{
350 QualType TransformTypeWithDeducedTST(QualType T);
351 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
352 /// @}
353
354 /// The reason why the value of a statement is not discarded, if any.
355 enum StmtDiscardKind {
356 SDK_Discarded,
357 SDK_NotDiscarded,
358 SDK_StmtExprResult,
359 };
360
361 /// Transform the given statement.
362 ///
363 /// By default, this routine transforms a statement by delegating to the
364 /// appropriate TransformXXXStmt function to transform a specific kind of
365 /// statement or the TransformExpr() function to transform an expression.
366 /// Subclasses may override this function to transform statements using some
367 /// other mechanism.
368 ///
369 /// \returns the transformed statement.
370 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
371
372 /// Transform the given statement.
373 ///
374 /// By default, this routine transforms a statement by delegating to the
375 /// appropriate TransformOMPXXXClause function to transform a specific kind
376 /// of clause. Subclasses may override this function to transform statements
377 /// using some other mechanism.
378 ///
379 /// \returns the transformed OpenMP clause.
380 OMPClause *TransformOMPClause(OMPClause *S);
381
382 /// Transform the given attribute.
383 ///
384 /// By default, this routine transforms a statement by delegating to the
385 /// appropriate TransformXXXAttr function to transform a specific kind
386 /// of attribute. Subclasses may override this function to transform
387 /// attributed statements/types using some other mechanism.
388 ///
389 /// \returns the transformed attribute
390 const Attr *TransformAttr(const Attr *S);
391
392 // Transform the given statement attribute.
393 //
394 // Delegates to the appropriate TransformXXXAttr function to transform a
395 // specific kind of statement attribute. Unlike the non-statement taking
396 // version of this, this implements all attributes, not just pragmas.
397 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
398 const Attr *A);
399
400 // Transform the specified attribute.
401 //
402 // Subclasses should override the transformation of attributes with a pragma
403 // spelling to transform expressions stored within the attribute.
404 //
405 // \returns the transformed attribute.
406#define ATTR(X) \
407 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
408#include "clang/Basic/AttrList.inc"
409
410 // Transform the specified attribute.
411 //
412 // Subclasses should override the transformation of attributes to do
413 // transformation and checking of statement attributes. By default, this
414 // delegates to the non-statement taking version.
415 //
416 // \returns the transformed attribute.
417#define ATTR(X) \
418 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
419 const X##Attr *A) { \
420 return getDerived().Transform##X##Attr(A); \
421 }
422#include "clang/Basic/AttrList.inc"
423
424 /// Transform the given expression.
425 ///
426 /// By default, this routine transforms an expression by delegating to the
427 /// appropriate TransformXXXExpr function to build a new expression.
428 /// Subclasses may override this function to transform expressions using some
429 /// other mechanism.
430 ///
431 /// \returns the transformed expression.
432 ExprResult TransformExpr(Expr *E);
433
434 /// Transform the given initializer.
435 ///
436 /// By default, this routine transforms an initializer by stripping off the
437 /// semantic nodes added by initialization, then passing the result to
438 /// TransformExpr or TransformExprs.
439 ///
440 /// \returns the transformed initializer.
441 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
442
443 /// Transform the given list of expressions.
444 ///
445 /// This routine transforms a list of expressions by invoking
446 /// \c TransformExpr() for each subexpression. However, it also provides
447 /// support for variadic templates by expanding any pack expansions (if the
448 /// derived class permits such expansion) along the way. When pack expansions
449 /// are present, the number of outputs may not equal the number of inputs.
450 ///
451 /// \param Inputs The set of expressions to be transformed.
452 ///
453 /// \param NumInputs The number of expressions in \c Inputs.
454 ///
455 /// \param IsCall If \c true, then this transform is being performed on
456 /// function-call arguments, and any arguments that should be dropped, will
457 /// be.
458 ///
459 /// \param Outputs The transformed input expressions will be added to this
460 /// vector.
461 ///
462 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
463 /// due to transformation.
464 ///
465 /// \returns true if an error occurred, false otherwise.
466 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
467 SmallVectorImpl<Expr *> &Outputs,
468 bool *ArgChanged = nullptr);
469
470 /// Transform the given declaration, which is referenced from a type
471 /// or expression.
472 ///
473 /// By default, acts as the identity function on declarations, unless the
474 /// transformer has had to transform the declaration itself. Subclasses
475 /// may override this function to provide alternate behavior.
476 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
477 llvm::DenseMap<Decl *, Decl *>::iterator Known
478 = TransformedLocalDecls.find(Val: D);
479 if (Known != TransformedLocalDecls.end())
480 return Known->second;
481
482 return D;
483 }
484
485 /// Transform the specified condition.
486 ///
487 /// By default, this transforms the variable and expression and rebuilds
488 /// the condition.
489 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
490 Expr *Expr,
491 Sema::ConditionKind Kind);
492
493 /// Transform the attributes associated with the given declaration and
494 /// place them on the new declaration.
495 ///
496 /// By default, this operation does nothing. Subclasses may override this
497 /// behavior to transform attributes.
498 void transformAttrs(Decl *Old, Decl *New) { }
499
500 /// Note that a local declaration has been transformed by this
501 /// transformer.
502 ///
503 /// Local declarations are typically transformed via a call to
504 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
505 /// the transformer itself has to transform the declarations. This routine
506 /// can be overridden by a subclass that keeps track of such mappings.
507 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
508 assert(New.size() == 1 &&
509 "must override transformedLocalDecl if performing pack expansion");
510 TransformedLocalDecls[Old] = New.front();
511 }
512
513 /// Transform the definition of the given declaration.
514 ///
515 /// By default, invokes TransformDecl() to transform the declaration.
516 /// Subclasses may override this function to provide alternate behavior.
517 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
518 return getDerived().TransformDecl(Loc, D);
519 }
520
521 /// Transform the given declaration, which was the first part of a
522 /// nested-name-specifier in a member access expression.
523 ///
524 /// This specific declaration transformation only applies to the first
525 /// identifier in a nested-name-specifier of a member access expression, e.g.,
526 /// the \c T in \c x->T::member
527 ///
528 /// By default, invokes TransformDecl() to transform the declaration.
529 /// Subclasses may override this function to provide alternate behavior.
530 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
531 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
532 }
533
534 /// Transform the set of declarations in an OverloadExpr.
535 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
536 LookupResult &R);
537
538 /// Transform the given nested-name-specifier with source-location
539 /// information.
540 ///
541 /// By default, transforms all of the types and declarations within the
542 /// nested-name-specifier. Subclasses may override this function to provide
543 /// alternate behavior.
544 NestedNameSpecifierLoc
545 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
546 QualType ObjectType = QualType(),
547 NamedDecl *FirstQualifierInScope = nullptr);
548
549 /// Transform the given declaration name.
550 ///
551 /// By default, transforms the types of conversion function, constructor,
552 /// and destructor names and then (if needed) rebuilds the declaration name.
553 /// Identifiers and selectors are returned unmodified. Subclasses may
554 /// override this function to provide alternate behavior.
555 DeclarationNameInfo
556 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
557
558 bool TransformRequiresExprRequirements(
559 ArrayRef<concepts::Requirement *> Reqs,
560 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
561 concepts::TypeRequirement *
562 TransformTypeRequirement(concepts::TypeRequirement *Req);
563 concepts::ExprRequirement *
564 TransformExprRequirement(concepts::ExprRequirement *Req);
565 concepts::NestedRequirement *
566 TransformNestedRequirement(concepts::NestedRequirement *Req);
567
568 /// Transform the given template name.
569 ///
570 /// \param SS The nested-name-specifier that qualifies the template
571 /// name. This nested-name-specifier must already have been transformed.
572 ///
573 /// \param Name The template name to transform.
574 ///
575 /// \param NameLoc The source location of the template name.
576 ///
577 /// \param ObjectType If we're translating a template name within a member
578 /// access expression, this is the type of the object whose member template
579 /// is being referenced.
580 ///
581 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
582 /// also refers to a name within the current (lexical) scope, this is the
583 /// declaration it refers to.
584 ///
585 /// By default, transforms the template name by transforming the declarations
586 /// and nested-name-specifiers that occur within the template name.
587 /// Subclasses may override this function to provide alternate behavior.
588 TemplateName
589 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
590 SourceLocation NameLoc,
591 QualType ObjectType = QualType(),
592 NamedDecl *FirstQualifierInScope = nullptr,
593 bool AllowInjectedClassName = false);
594
595 /// Transform the given template argument.
596 ///
597 /// By default, this operation transforms the type, expression, or
598 /// declaration stored within the template argument and constructs a
599 /// new template argument from the transformed result. Subclasses may
600 /// override this function to provide alternate behavior.
601 ///
602 /// Returns true if there was an error.
603 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
604 TemplateArgumentLoc &Output,
605 bool Uneval = false);
606
607 /// Transform the given set of template arguments.
608 ///
609 /// By default, this operation transforms all of the template arguments
610 /// in the input set using \c TransformTemplateArgument(), and appends
611 /// the transformed arguments to the output list.
612 ///
613 /// Note that this overload of \c TransformTemplateArguments() is merely
614 /// a convenience function. Subclasses that wish to override this behavior
615 /// should override the iterator-based member template version.
616 ///
617 /// \param Inputs The set of template arguments to be transformed.
618 ///
619 /// \param NumInputs The number of template arguments in \p Inputs.
620 ///
621 /// \param Outputs The set of transformed template arguments output by this
622 /// routine.
623 ///
624 /// Returns true if an error occurred.
625 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
626 unsigned NumInputs,
627 TemplateArgumentListInfo &Outputs,
628 bool Uneval = false) {
629 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
630 Uneval);
631 }
632
633 /// Transform the given set of template arguments.
634 ///
635 /// By default, this operation transforms all of the template arguments
636 /// in the input set using \c TransformTemplateArgument(), and appends
637 /// the transformed arguments to the output list.
638 ///
639 /// \param First An iterator to the first template argument.
640 ///
641 /// \param Last An iterator one step past the last template argument.
642 ///
643 /// \param Outputs The set of transformed template arguments output by this
644 /// routine.
645 ///
646 /// Returns true if an error occurred.
647 template<typename InputIterator>
648 bool TransformTemplateArguments(InputIterator First,
649 InputIterator Last,
650 TemplateArgumentListInfo &Outputs,
651 bool Uneval = false);
652
653 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
654 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
655 TemplateArgumentLoc &ArgLoc);
656
657 /// Fakes up a TypeSourceInfo for a type.
658 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
659 return SemaRef.Context.getTrivialTypeSourceInfo(T,
660 Loc: getDerived().getBaseLocation());
661 }
662
663#define ABSTRACT_TYPELOC(CLASS, PARENT)
664#define TYPELOC(CLASS, PARENT) \
665 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
666#include "clang/AST/TypeLocNodes.def"
667
668 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
669 TemplateTypeParmTypeLoc TL,
670 bool SuppressObjCLifetime);
671 QualType
672 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
673 SubstTemplateTypeParmPackTypeLoc TL,
674 bool SuppressObjCLifetime);
675
676 template<typename Fn>
677 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
678 FunctionProtoTypeLoc TL,
679 CXXRecordDecl *ThisContext,
680 Qualifiers ThisTypeQuals,
681 Fn TransformExceptionSpec);
682
683 template <typename Fn>
684 QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL,
685 Fn TransformModifiedType);
686
687 bool TransformExceptionSpec(SourceLocation Loc,
688 FunctionProtoType::ExceptionSpecInfo &ESI,
689 SmallVectorImpl<QualType> &Exceptions,
690 bool &Changed);
691
692 StmtResult TransformSEHHandler(Stmt *Handler);
693
694 QualType
695 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
696 TemplateSpecializationTypeLoc TL,
697 TemplateName Template);
698
699 QualType
700 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
701 DependentTemplateSpecializationTypeLoc TL,
702 TemplateName Template,
703 CXXScopeSpec &SS);
704
705 QualType TransformDependentTemplateSpecializationType(
706 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
707 NestedNameSpecifierLoc QualifierLoc);
708
709 /// Transforms the parameters of a function type into the
710 /// given vectors.
711 ///
712 /// The result vectors should be kept in sync; null entries in the
713 /// variables vector are acceptable.
714 ///
715 /// LastParamTransformed, if non-null, will be set to the index of the last
716 /// parameter on which transfromation was started. In the event of an error,
717 /// this will contain the parameter which failed to instantiate.
718 ///
719 /// Return true on error.
720 bool TransformFunctionTypeParams(
721 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
722 const QualType *ParamTypes,
723 const FunctionProtoType::ExtParameterInfo *ParamInfos,
724 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
725 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
726
727 bool TransformFunctionTypeParams(
728 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
729 const QualType *ParamTypes,
730 const FunctionProtoType::ExtParameterInfo *ParamInfos,
731 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
732 Sema::ExtParameterInfoBuilder &PInfos) {
733 return getDerived().TransformFunctionTypeParams(
734 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
735 }
736
737 /// Transforms the parameters of a requires expresison into the given vectors.
738 ///
739 /// The result vectors should be kept in sync; null entries in the
740 /// variables vector are acceptable.
741 ///
742 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
743 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
744 /// which are cases where transformation shouldn't continue.
745 ExprResult TransformRequiresTypeParams(
746 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
747 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
748 SmallVectorImpl<QualType> &PTypes,
749 SmallVectorImpl<ParmVarDecl *> &TransParams,
750 Sema::ExtParameterInfoBuilder &PInfos) {
751 if (getDerived().TransformFunctionTypeParams(
752 KWLoc, Params, /*ParamTypes=*/nullptr,
753 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
754 return ExprError();
755
756 return ExprResult{};
757 }
758
759 /// Transforms a single function-type parameter. Return null
760 /// on error.
761 ///
762 /// \param indexAdjustment - A number to add to the parameter's
763 /// scope index; can be negative
764 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
765 int indexAdjustment,
766 std::optional<unsigned> NumExpansions,
767 bool ExpectParameterPack);
768
769 /// Transform the body of a lambda-expression.
770 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
771 /// Alternative implementation of TransformLambdaBody that skips transforming
772 /// the body.
773 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
774
775 CXXRecordDecl::LambdaDependencyKind
776 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
777 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
778 LSI->Lambda->getLambdaDependencyKind());
779 }
780
781 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
782
783 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
784 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
785
786 TemplateParameterList *TransformTemplateParameterList(
787 TemplateParameterList *TPL) {
788 return TPL;
789 }
790
791 ExprResult TransformAddressOfOperand(Expr *E);
792
793 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
794 bool IsAddressOfOperand,
795 TypeSourceInfo **RecoveryTSI);
796
797 ExprResult TransformParenDependentScopeDeclRefExpr(
798 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
799 TypeSourceInfo **RecoveryTSI);
800
801 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
802 bool IsAddressOfOperand);
803
804 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
805
806// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
807// amount of stack usage with clang.
808#define STMT(Node, Parent) \
809 LLVM_ATTRIBUTE_NOINLINE \
810 StmtResult Transform##Node(Node *S);
811#define VALUESTMT(Node, Parent) \
812 LLVM_ATTRIBUTE_NOINLINE \
813 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
814#define EXPR(Node, Parent) \
815 LLVM_ATTRIBUTE_NOINLINE \
816 ExprResult Transform##Node(Node *E);
817#define ABSTRACT_STMT(Stmt)
818#include "clang/AST/StmtNodes.inc"
819
820#define GEN_CLANG_CLAUSE_CLASS
821#define CLAUSE_CLASS(Enum, Str, Class) \
822 LLVM_ATTRIBUTE_NOINLINE \
823 OMPClause *Transform##Class(Class *S);
824#include "llvm/Frontend/OpenMP/OMP.inc"
825
826 /// Build a new qualified type given its unqualified type and type location.
827 ///
828 /// By default, this routine adds type qualifiers only to types that can
829 /// have qualifiers, and silently suppresses those qualifiers that are not
830 /// permitted. Subclasses may override this routine to provide different
831 /// behavior.
832 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
833
834 /// Build a new pointer type given its pointee type.
835 ///
836 /// By default, performs semantic analysis when building the pointer type.
837 /// Subclasses may override this routine to provide different behavior.
838 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
839
840 /// Build a new block pointer type given its pointee type.
841 ///
842 /// By default, performs semantic analysis when building the block pointer
843 /// type. Subclasses may override this routine to provide different behavior.
844 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
845
846 /// Build a new reference type given the type it references.
847 ///
848 /// By default, performs semantic analysis when building the
849 /// reference type. Subclasses may override this routine to provide
850 /// different behavior.
851 ///
852 /// \param LValue whether the type was written with an lvalue sigil
853 /// or an rvalue sigil.
854 QualType RebuildReferenceType(QualType ReferentType,
855 bool LValue,
856 SourceLocation Sigil);
857
858 /// Build a new member pointer type given the pointee type and the
859 /// class type it refers into.
860 ///
861 /// By default, performs semantic analysis when building the member pointer
862 /// type. Subclasses may override this routine to provide different behavior.
863 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
864 SourceLocation Sigil);
865
866 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
867 SourceLocation ProtocolLAngleLoc,
868 ArrayRef<ObjCProtocolDecl *> Protocols,
869 ArrayRef<SourceLocation> ProtocolLocs,
870 SourceLocation ProtocolRAngleLoc);
871
872 /// Build an Objective-C object type.
873 ///
874 /// By default, performs semantic analysis when building the object type.
875 /// Subclasses may override this routine to provide different behavior.
876 QualType RebuildObjCObjectType(QualType BaseType,
877 SourceLocation Loc,
878 SourceLocation TypeArgsLAngleLoc,
879 ArrayRef<TypeSourceInfo *> TypeArgs,
880 SourceLocation TypeArgsRAngleLoc,
881 SourceLocation ProtocolLAngleLoc,
882 ArrayRef<ObjCProtocolDecl *> Protocols,
883 ArrayRef<SourceLocation> ProtocolLocs,
884 SourceLocation ProtocolRAngleLoc);
885
886 /// Build a new Objective-C object pointer type given the pointee type.
887 ///
888 /// By default, directly builds the pointer type, with no additional semantic
889 /// analysis.
890 QualType RebuildObjCObjectPointerType(QualType PointeeType,
891 SourceLocation Star);
892
893 /// Build a new array type given the element type, size
894 /// modifier, size of the array (if known), size expression, and index type
895 /// qualifiers.
896 ///
897 /// By default, performs semantic analysis when building the array type.
898 /// Subclasses may override this routine to provide different behavior.
899 /// Also by default, all of the other Rebuild*Array
900 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
901 const llvm::APInt *Size, Expr *SizeExpr,
902 unsigned IndexTypeQuals, SourceRange BracketsRange);
903
904 /// Build a new constant array type given the element type, size
905 /// modifier, (known) size of the array, and index type qualifiers.
906 ///
907 /// By default, performs semantic analysis when building the array type.
908 /// Subclasses may override this routine to provide different behavior.
909 QualType RebuildConstantArrayType(QualType ElementType,
910 ArraySizeModifier SizeMod,
911 const llvm::APInt &Size, Expr *SizeExpr,
912 unsigned IndexTypeQuals,
913 SourceRange BracketsRange);
914
915 /// Build a new incomplete array type given the element type, size
916 /// modifier, and index type qualifiers.
917 ///
918 /// By default, performs semantic analysis when building the array type.
919 /// Subclasses may override this routine to provide different behavior.
920 QualType RebuildIncompleteArrayType(QualType ElementType,
921 ArraySizeModifier SizeMod,
922 unsigned IndexTypeQuals,
923 SourceRange BracketsRange);
924
925 /// Build a new variable-length array type given the element type,
926 /// size modifier, size expression, and index type qualifiers.
927 ///
928 /// By default, performs semantic analysis when building the array type.
929 /// Subclasses may override this routine to provide different behavior.
930 QualType RebuildVariableArrayType(QualType ElementType,
931 ArraySizeModifier SizeMod, Expr *SizeExpr,
932 unsigned IndexTypeQuals,
933 SourceRange BracketsRange);
934
935 /// Build a new dependent-sized array type given the element type,
936 /// size modifier, size expression, and index type qualifiers.
937 ///
938 /// By default, performs semantic analysis when building the array type.
939 /// Subclasses may override this routine to provide different behavior.
940 QualType RebuildDependentSizedArrayType(QualType ElementType,
941 ArraySizeModifier SizeMod,
942 Expr *SizeExpr,
943 unsigned IndexTypeQuals,
944 SourceRange BracketsRange);
945
946 /// Build a new vector type given the element type and
947 /// number of elements.
948 ///
949 /// By default, performs semantic analysis when building the vector type.
950 /// Subclasses may override this routine to provide different behavior.
951 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
952 VectorKind VecKind);
953
954 /// Build a new potentially dependently-sized extended vector type
955 /// given the element type and number of elements.
956 ///
957 /// By default, performs semantic analysis when building the vector type.
958 /// Subclasses may override this routine to provide different behavior.
959 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
960 SourceLocation AttributeLoc, VectorKind);
961
962 /// Build a new extended vector type given the element type and
963 /// number of elements.
964 ///
965 /// By default, performs semantic analysis when building the vector type.
966 /// Subclasses may override this routine to provide different behavior.
967 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
968 SourceLocation AttributeLoc);
969
970 /// Build a new potentially dependently-sized extended vector type
971 /// given the element type and number of elements.
972 ///
973 /// By default, performs semantic analysis when building the vector type.
974 /// Subclasses may override this routine to provide different behavior.
975 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
976 Expr *SizeExpr,
977 SourceLocation AttributeLoc);
978
979 /// Build a new matrix type given the element type and dimensions.
980 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
981 unsigned NumColumns);
982
983 /// Build a new matrix type given the type and dependently-defined
984 /// dimensions.
985 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
986 Expr *ColumnExpr,
987 SourceLocation AttributeLoc);
988
989 /// Build a new DependentAddressSpaceType or return the pointee
990 /// type variable with the correct address space (retrieved from
991 /// AddrSpaceExpr) applied to it. The former will be returned in cases
992 /// where the address space remains dependent.
993 ///
994 /// By default, performs semantic analysis when building the type with address
995 /// space applied. Subclasses may override this routine to provide different
996 /// behavior.
997 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
998 Expr *AddrSpaceExpr,
999 SourceLocation AttributeLoc);
1000
1001 /// Build a new function type.
1002 ///
1003 /// By default, performs semantic analysis when building the function type.
1004 /// Subclasses may override this routine to provide different behavior.
1005 QualType RebuildFunctionProtoType(QualType T,
1006 MutableArrayRef<QualType> ParamTypes,
1007 const FunctionProtoType::ExtProtoInfo &EPI);
1008
1009 /// Build a new unprototyped function type.
1010 QualType RebuildFunctionNoProtoType(QualType ResultType);
1011
1012 /// Rebuild an unresolved typename type, given the decl that
1013 /// the UnresolvedUsingTypenameDecl was transformed to.
1014 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1015
1016 /// Build a new type found via an alias.
1017 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1018 return SemaRef.Context.getUsingType(Found, Underlying);
1019 }
1020
1021 /// Build a new typedef type.
1022 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1023 return SemaRef.Context.getTypeDeclType(Decl: Typedef);
1024 }
1025
1026 /// Build a new MacroDefined type.
1027 QualType RebuildMacroQualifiedType(QualType T,
1028 const IdentifierInfo *MacroII) {
1029 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1030 }
1031
1032 /// Build a new class/struct/union type.
1033 QualType RebuildRecordType(RecordDecl *Record) {
1034 return SemaRef.Context.getTypeDeclType(Decl: Record);
1035 }
1036
1037 /// Build a new Enum type.
1038 QualType RebuildEnumType(EnumDecl *Enum) {
1039 return SemaRef.Context.getTypeDeclType(Decl: Enum);
1040 }
1041
1042 /// Build a new typeof(expr) type.
1043 ///
1044 /// By default, performs semantic analysis when building the typeof type.
1045 /// Subclasses may override this routine to provide different behavior.
1046 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1047 TypeOfKind Kind);
1048
1049 /// Build a new typeof(type) type.
1050 ///
1051 /// By default, builds a new TypeOfType with the given underlying type.
1052 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1053
1054 /// Build a new unary transform type.
1055 QualType RebuildUnaryTransformType(QualType BaseType,
1056 UnaryTransformType::UTTKind UKind,
1057 SourceLocation Loc);
1058
1059 /// Build a new C++11 decltype type.
1060 ///
1061 /// By default, performs semantic analysis when building the decltype type.
1062 /// Subclasses may override this routine to provide different behavior.
1063 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1064
1065 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1066 SourceLocation Loc,
1067 SourceLocation EllipsisLoc,
1068 bool FullySubstituted,
1069 ArrayRef<QualType> Expansions = {});
1070
1071 /// Build a new C++11 auto type.
1072 ///
1073 /// By default, builds a new AutoType with the given deduced type.
1074 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1075 ConceptDecl *TypeConstraintConcept,
1076 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1077 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1078 // which has been deduced to a dependent type into an undeduced 'auto', so
1079 // that we'll retry deduction after the transformation.
1080 return SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword,
1081 /*IsDependent*/ IsDependent: false, /*IsPack=*/IsPack: false,
1082 TypeConstraintConcept,
1083 TypeConstraintArgs);
1084 }
1085
1086 /// By default, builds a new DeducedTemplateSpecializationType with the given
1087 /// deduced type.
1088 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1089 QualType Deduced) {
1090 return SemaRef.Context.getDeducedTemplateSpecializationType(
1091 Template, DeducedType: Deduced, /*IsDependent*/ IsDependent: false);
1092 }
1093
1094 /// Build a new template specialization type.
1095 ///
1096 /// By default, performs semantic analysis when building the template
1097 /// specialization type. Subclasses may override this routine to provide
1098 /// different behavior.
1099 QualType RebuildTemplateSpecializationType(TemplateName Template,
1100 SourceLocation TemplateLoc,
1101 TemplateArgumentListInfo &Args);
1102
1103 /// Build a new parenthesized type.
1104 ///
1105 /// By default, builds a new ParenType type from the inner type.
1106 /// Subclasses may override this routine to provide different behavior.
1107 QualType RebuildParenType(QualType InnerType) {
1108 return SemaRef.BuildParenType(T: InnerType);
1109 }
1110
1111 /// Build a new qualified name type.
1112 ///
1113 /// By default, builds a new ElaboratedType type from the keyword,
1114 /// the nested-name-specifier and the named type.
1115 /// Subclasses may override this routine to provide different behavior.
1116 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1117 ElaboratedTypeKeyword Keyword,
1118 NestedNameSpecifierLoc QualifierLoc,
1119 QualType Named) {
1120 return SemaRef.Context.getElaboratedType(Keyword,
1121 NNS: QualifierLoc.getNestedNameSpecifier(),
1122 NamedType: Named);
1123 }
1124
1125 /// Build a new typename type that refers to a template-id.
1126 ///
1127 /// By default, builds a new DependentNameType type from the
1128 /// nested-name-specifier and the given type. Subclasses may override
1129 /// this routine to provide different behavior.
1130 QualType RebuildDependentTemplateSpecializationType(
1131 ElaboratedTypeKeyword Keyword,
1132 NestedNameSpecifierLoc QualifierLoc,
1133 SourceLocation TemplateKWLoc,
1134 const IdentifierInfo *Name,
1135 SourceLocation NameLoc,
1136 TemplateArgumentListInfo &Args,
1137 bool AllowInjectedClassName) {
1138 // Rebuild the template name.
1139 // TODO: avoid TemplateName abstraction
1140 CXXScopeSpec SS;
1141 SS.Adopt(Other: QualifierLoc);
1142 TemplateName InstName = getDerived().RebuildTemplateName(
1143 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1144 AllowInjectedClassName);
1145
1146 if (InstName.isNull())
1147 return QualType();
1148
1149 // If it's still dependent, make a dependent specialization.
1150 if (InstName.getAsDependentTemplateName())
1151 return SemaRef.Context.getDependentTemplateSpecializationType(
1152 Keyword, NNS: QualifierLoc.getNestedNameSpecifier(), Name,
1153 Args: Args.arguments());
1154
1155 // Otherwise, make an elaborated type wrapping a non-dependent
1156 // specialization.
1157 QualType T =
1158 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1159 if (T.isNull())
1160 return QualType();
1161 return SemaRef.Context.getElaboratedType(
1162 Keyword, NNS: QualifierLoc.getNestedNameSpecifier(), NamedType: T);
1163 }
1164
1165 /// Build a new typename type that refers to an identifier.
1166 ///
1167 /// By default, performs semantic analysis when building the typename type
1168 /// (or elaborated type). Subclasses may override this routine to provide
1169 /// different behavior.
1170 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1171 SourceLocation KeywordLoc,
1172 NestedNameSpecifierLoc QualifierLoc,
1173 const IdentifierInfo *Id,
1174 SourceLocation IdLoc,
1175 bool DeducedTSTContext) {
1176 CXXScopeSpec SS;
1177 SS.Adopt(Other: QualifierLoc);
1178
1179 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1180 // If the name is still dependent, just build a new dependent name type.
1181 if (!SemaRef.computeDeclContext(SS))
1182 return SemaRef.Context.getDependentNameType(Keyword,
1183 NNS: QualifierLoc.getNestedNameSpecifier(),
1184 Name: Id);
1185 }
1186
1187 if (Keyword == ElaboratedTypeKeyword::None ||
1188 Keyword == ElaboratedTypeKeyword::Typename) {
1189 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1190 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1191 }
1192
1193 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1194
1195 // We had a dependent elaborated-type-specifier that has been transformed
1196 // into a non-dependent elaborated-type-specifier. Find the tag we're
1197 // referring to.
1198 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1199 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1200 if (!DC)
1201 return QualType();
1202
1203 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1204 return QualType();
1205
1206 TagDecl *Tag = nullptr;
1207 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1208 switch (Result.getResultKind()) {
1209 case LookupResult::NotFound:
1210 case LookupResult::NotFoundInCurrentInstantiation:
1211 break;
1212
1213 case LookupResult::Found:
1214 Tag = Result.getAsSingle<TagDecl>();
1215 break;
1216
1217 case LookupResult::FoundOverloaded:
1218 case LookupResult::FoundUnresolvedValue:
1219 llvm_unreachable("Tag lookup cannot find non-tags");
1220
1221 case LookupResult::Ambiguous:
1222 // Let the LookupResult structure handle ambiguities.
1223 return QualType();
1224 }
1225
1226 if (!Tag) {
1227 // Check where the name exists but isn't a tag type and use that to emit
1228 // better diagnostics.
1229 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1230 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1231 switch (Result.getResultKind()) {
1232 case LookupResult::Found:
1233 case LookupResult::FoundOverloaded:
1234 case LookupResult::FoundUnresolvedValue: {
1235 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1236 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1237 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1238 << SomeDecl << NTK << llvm::to_underlying(E: Kind);
1239 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1240 break;
1241 }
1242 default:
1243 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1244 << llvm::to_underlying(E: Kind) << Id << DC
1245 << QualifierLoc.getSourceRange();
1246 break;
1247 }
1248 return QualType();
1249 }
1250
1251 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1252 NewTagLoc: IdLoc, Name: Id)) {
1253 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1254 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1255 return QualType();
1256 }
1257
1258 // Build the elaborated-type-specifier type.
1259 QualType T = SemaRef.Context.getTypeDeclType(Decl: Tag);
1260 return SemaRef.Context.getElaboratedType(Keyword,
1261 NNS: QualifierLoc.getNestedNameSpecifier(),
1262 NamedType: T);
1263 }
1264
1265 /// Build a new pack expansion type.
1266 ///
1267 /// By default, builds a new PackExpansionType type from the given pattern.
1268 /// Subclasses may override this routine to provide different behavior.
1269 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1270 SourceLocation EllipsisLoc,
1271 std::optional<unsigned> NumExpansions) {
1272 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1273 NumExpansions);
1274 }
1275
1276 /// Build a new atomic type given its value type.
1277 ///
1278 /// By default, performs semantic analysis when building the atomic type.
1279 /// Subclasses may override this routine to provide different behavior.
1280 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1281
1282 /// Build a new pipe type given its value type.
1283 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1284 bool isReadPipe);
1285
1286 /// Build a bit-precise int given its value type.
1287 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1288 SourceLocation Loc);
1289
1290 /// Build a dependent bit-precise int given its value type.
1291 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1292 SourceLocation Loc);
1293
1294 /// Build a new template name given a nested name specifier, a flag
1295 /// indicating whether the "template" keyword was provided, and the template
1296 /// that the template name refers to.
1297 ///
1298 /// By default, builds the new template name directly. Subclasses may override
1299 /// this routine to provide different behavior.
1300 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1301 bool TemplateKW,
1302 TemplateDecl *Template);
1303
1304 /// Build a new template name given a nested name specifier and the
1305 /// name that is referred to as a template.
1306 ///
1307 /// By default, performs semantic analysis to determine whether the name can
1308 /// be resolved to a specific template, then builds the appropriate kind of
1309 /// template name. Subclasses may override this routine to provide different
1310 /// behavior.
1311 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1312 SourceLocation TemplateKWLoc,
1313 const IdentifierInfo &Name,
1314 SourceLocation NameLoc, QualType ObjectType,
1315 NamedDecl *FirstQualifierInScope,
1316 bool AllowInjectedClassName);
1317
1318 /// Build a new template name given a nested name specifier and the
1319 /// overloaded operator name that is referred to as a template.
1320 ///
1321 /// By default, performs semantic analysis to determine whether the name can
1322 /// be resolved to a specific template, then builds the appropriate kind of
1323 /// template name. Subclasses may override this routine to provide different
1324 /// behavior.
1325 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1326 SourceLocation TemplateKWLoc,
1327 OverloadedOperatorKind Operator,
1328 SourceLocation NameLoc, QualType ObjectType,
1329 bool AllowInjectedClassName);
1330
1331 /// Build a new template name given a template template parameter pack
1332 /// and the
1333 ///
1334 /// By default, performs semantic analysis to determine whether the name can
1335 /// be resolved to a specific template, then builds the appropriate kind of
1336 /// template name. Subclasses may override this routine to provide different
1337 /// behavior.
1338 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1339 Decl *AssociatedDecl, unsigned Index,
1340 bool Final) {
1341 return getSema().Context.getSubstTemplateTemplateParmPack(
1342 ArgPack, AssociatedDecl, Index, Final);
1343 }
1344
1345 /// Build a new compound statement.
1346 ///
1347 /// By default, performs semantic analysis to build the new statement.
1348 /// Subclasses may override this routine to provide different behavior.
1349 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1350 MultiStmtArg Statements,
1351 SourceLocation RBraceLoc,
1352 bool IsStmtExpr) {
1353 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1354 IsStmtExpr);
1355 }
1356
1357 /// Build a new case statement.
1358 ///
1359 /// By default, performs semantic analysis to build the new statement.
1360 /// Subclasses may override this routine to provide different behavior.
1361 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1362 Expr *LHS,
1363 SourceLocation EllipsisLoc,
1364 Expr *RHS,
1365 SourceLocation ColonLoc) {
1366 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1367 ColonLoc);
1368 }
1369
1370 /// Attach the body to a new case statement.
1371 ///
1372 /// By default, performs semantic analysis to build the new statement.
1373 /// Subclasses may override this routine to provide different behavior.
1374 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1375 getSema().ActOnCaseStmtBody(S, Body);
1376 return S;
1377 }
1378
1379 /// Build a new default statement.
1380 ///
1381 /// By default, performs semantic analysis to build the new statement.
1382 /// Subclasses may override this routine to provide different behavior.
1383 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1384 SourceLocation ColonLoc,
1385 Stmt *SubStmt) {
1386 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1387 /*CurScope=*/nullptr);
1388 }
1389
1390 /// Build a new label statement.
1391 ///
1392 /// By default, performs semantic analysis to build the new statement.
1393 /// Subclasses may override this routine to provide different behavior.
1394 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1395 SourceLocation ColonLoc, Stmt *SubStmt) {
1396 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1397 }
1398
1399 /// Build a new attributed statement.
1400 ///
1401 /// By default, performs semantic analysis to build the new statement.
1402 /// Subclasses may override this routine to provide different behavior.
1403 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1404 ArrayRef<const Attr *> Attrs,
1405 Stmt *SubStmt) {
1406 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1407 return StmtError();
1408 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1409 }
1410
1411 /// Build a new "if" statement.
1412 ///
1413 /// By default, performs semantic analysis to build the new statement.
1414 /// Subclasses may override this routine to provide different behavior.
1415 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1416 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1417 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1418 SourceLocation ElseLoc, Stmt *Else) {
1419 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1420 Then, ElseLoc, Else);
1421 }
1422
1423 /// Start building a new switch statement.
1424 ///
1425 /// By default, performs semantic analysis to build the new statement.
1426 /// Subclasses may override this routine to provide different behavior.
1427 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1428 SourceLocation LParenLoc, Stmt *Init,
1429 Sema::ConditionResult Cond,
1430 SourceLocation RParenLoc) {
1431 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1432 RParenLoc);
1433 }
1434
1435 /// Attach the body to the switch statement.
1436 ///
1437 /// By default, performs semantic analysis to build the new statement.
1438 /// Subclasses may override this routine to provide different behavior.
1439 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1440 Stmt *Switch, Stmt *Body) {
1441 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1442 }
1443
1444 /// Build a new while statement.
1445 ///
1446 /// By default, performs semantic analysis to build the new statement.
1447 /// Subclasses may override this routine to provide different behavior.
1448 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1449 Sema::ConditionResult Cond,
1450 SourceLocation RParenLoc, Stmt *Body) {
1451 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1452 }
1453
1454 /// Build a new do-while statement.
1455 ///
1456 /// By default, performs semantic analysis to build the new statement.
1457 /// Subclasses may override this routine to provide different behavior.
1458 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1459 SourceLocation WhileLoc, SourceLocation LParenLoc,
1460 Expr *Cond, SourceLocation RParenLoc) {
1461 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1462 Cond, RParenLoc);
1463 }
1464
1465 /// Build a new for statement.
1466 ///
1467 /// By default, performs semantic analysis to build the new statement.
1468 /// Subclasses may override this routine to provide different behavior.
1469 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1470 Stmt *Init, Sema::ConditionResult Cond,
1471 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1472 Stmt *Body) {
1473 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1474 Inc, RParenLoc, Body);
1475 }
1476
1477 /// Build a new goto statement.
1478 ///
1479 /// By default, performs semantic analysis to build the new statement.
1480 /// Subclasses may override this routine to provide different behavior.
1481 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1482 LabelDecl *Label) {
1483 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1484 }
1485
1486 /// Build a new indirect goto statement.
1487 ///
1488 /// By default, performs semantic analysis to build the new statement.
1489 /// Subclasses may override this routine to provide different behavior.
1490 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1491 SourceLocation StarLoc,
1492 Expr *Target) {
1493 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1494 }
1495
1496 /// Build a new return statement.
1497 ///
1498 /// By default, performs semantic analysis to build the new statement.
1499 /// Subclasses may override this routine to provide different behavior.
1500 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1501 return getSema().BuildReturnStmt(ReturnLoc, Result);
1502 }
1503
1504 /// Build a new declaration statement.
1505 ///
1506 /// By default, performs semantic analysis to build the new statement.
1507 /// Subclasses may override this routine to provide different behavior.
1508 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1509 SourceLocation StartLoc, SourceLocation EndLoc) {
1510 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1511 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1512 }
1513
1514 /// Build a new inline asm statement.
1515 ///
1516 /// By default, performs semantic analysis to build the new statement.
1517 /// Subclasses may override this routine to provide different behavior.
1518 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1519 bool IsVolatile, unsigned NumOutputs,
1520 unsigned NumInputs, IdentifierInfo **Names,
1521 MultiExprArg Constraints, MultiExprArg Exprs,
1522 Expr *AsmString, MultiExprArg Clobbers,
1523 unsigned NumLabels,
1524 SourceLocation RParenLoc) {
1525 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1526 NumInputs, Names, Constraints, Exprs,
1527 AsmString, Clobbers, NumLabels, RParenLoc);
1528 }
1529
1530 /// Build a new MS style inline asm statement.
1531 ///
1532 /// By default, performs semantic analysis to build the new statement.
1533 /// Subclasses may override this routine to provide different behavior.
1534 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1535 ArrayRef<Token> AsmToks,
1536 StringRef AsmString,
1537 unsigned NumOutputs, unsigned NumInputs,
1538 ArrayRef<StringRef> Constraints,
1539 ArrayRef<StringRef> Clobbers,
1540 ArrayRef<Expr*> Exprs,
1541 SourceLocation EndLoc) {
1542 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1543 NumOutputs, NumInputs,
1544 Constraints, Clobbers, Exprs, EndLoc);
1545 }
1546
1547 /// Build a new co_return statement.
1548 ///
1549 /// By default, performs semantic analysis to build the new statement.
1550 /// Subclasses may override this routine to provide different behavior.
1551 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1552 bool IsImplicit) {
1553 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1554 }
1555
1556 /// Build a new co_await expression.
1557 ///
1558 /// By default, performs semantic analysis to build the new expression.
1559 /// Subclasses may override this routine to provide different behavior.
1560 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1561 UnresolvedLookupExpr *OpCoawaitLookup,
1562 bool IsImplicit) {
1563 // This function rebuilds a coawait-expr given its operator.
1564 // For an explicit coawait-expr, the rebuild involves the full set
1565 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1566 // including calling await_transform().
1567 // For an implicit coawait-expr, we need to rebuild the "operator
1568 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1569 // This mirrors how the implicit CoawaitExpr is originally created
1570 // in Sema::ActOnCoroutineBodyStart().
1571 if (IsImplicit) {
1572 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1573 CoawaitLoc, Operand, OpCoawaitLookup);
1574 if (Suspend.isInvalid())
1575 return ExprError();
1576 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1577 Suspend.get(), true);
1578 }
1579
1580 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1581 OpCoawaitLookup);
1582 }
1583
1584 /// Build a new co_await expression.
1585 ///
1586 /// By default, performs semantic analysis to build the new expression.
1587 /// Subclasses may override this routine to provide different behavior.
1588 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1589 Expr *Result,
1590 UnresolvedLookupExpr *Lookup) {
1591 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1592 }
1593
1594 /// Build a new co_yield expression.
1595 ///
1596 /// By default, performs semantic analysis to build the new expression.
1597 /// Subclasses may override this routine to provide different behavior.
1598 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1599 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1600 }
1601
1602 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1603 return getSema().BuildCoroutineBodyStmt(Args);
1604 }
1605
1606 /// Build a new Objective-C \@try statement.
1607 ///
1608 /// By default, performs semantic analysis to build the new statement.
1609 /// Subclasses may override this routine to provide different behavior.
1610 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1611 Stmt *TryBody,
1612 MultiStmtArg CatchStmts,
1613 Stmt *Finally) {
1614 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1615 Finally);
1616 }
1617
1618 /// Rebuild an Objective-C exception declaration.
1619 ///
1620 /// By default, performs semantic analysis to build the new declaration.
1621 /// Subclasses may override this routine to provide different behavior.
1622 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1623 TypeSourceInfo *TInfo, QualType T) {
1624 return getSema().ObjC().BuildObjCExceptionDecl(
1625 TInfo, T, ExceptionDecl->getInnerLocStart(),
1626 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1627 }
1628
1629 /// Build a new Objective-C \@catch statement.
1630 ///
1631 /// By default, performs semantic analysis to build the new statement.
1632 /// Subclasses may override this routine to provide different behavior.
1633 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1634 SourceLocation RParenLoc,
1635 VarDecl *Var,
1636 Stmt *Body) {
1637 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1638 }
1639
1640 /// Build a new Objective-C \@finally statement.
1641 ///
1642 /// By default, performs semantic analysis to build the new statement.
1643 /// Subclasses may override this routine to provide different behavior.
1644 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1645 Stmt *Body) {
1646 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1647 }
1648
1649 /// Build a new Objective-C \@throw statement.
1650 ///
1651 /// By default, performs semantic analysis to build the new statement.
1652 /// Subclasses may override this routine to provide different behavior.
1653 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1654 Expr *Operand) {
1655 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1656 }
1657
1658 /// Build a new OpenMP Canonical loop.
1659 ///
1660 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1661 /// OMPCanonicalLoop.
1662 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1663 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1664 }
1665
1666 /// Build a new OpenMP executable directive.
1667 ///
1668 /// By default, performs semantic analysis to build the new statement.
1669 /// Subclasses may override this routine to provide different behavior.
1670 StmtResult RebuildOMPExecutableDirective(
1671 OpenMPDirectiveKind Kind, DeclarationNameInfo DirName,
1672 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1673 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
1674 OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) {
1675
1676 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1677 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc,
1678 PrevMappedDirective);
1679 }
1680
1681 /// Build a new OpenMP 'if' clause.
1682 ///
1683 /// By default, performs semantic analysis to build the new OpenMP clause.
1684 /// Subclasses may override this routine to provide different behavior.
1685 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1686 Expr *Condition, SourceLocation StartLoc,
1687 SourceLocation LParenLoc,
1688 SourceLocation NameModifierLoc,
1689 SourceLocation ColonLoc,
1690 SourceLocation EndLoc) {
1691 return getSema().OpenMP().ActOnOpenMPIfClause(
1692 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1693 EndLoc);
1694 }
1695
1696 /// Build a new OpenMP 'final' clause.
1697 ///
1698 /// By default, performs semantic analysis to build the new OpenMP clause.
1699 /// Subclasses may override this routine to provide different behavior.
1700 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1701 SourceLocation LParenLoc,
1702 SourceLocation EndLoc) {
1703 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1704 LParenLoc, EndLoc);
1705 }
1706
1707 /// Build a new OpenMP 'num_threads' clause.
1708 ///
1709 /// By default, performs semantic analysis to build the new OpenMP clause.
1710 /// Subclasses may override this routine to provide different behavior.
1711 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1712 SourceLocation StartLoc,
1713 SourceLocation LParenLoc,
1714 SourceLocation EndLoc) {
1715 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1716 LParenLoc, EndLoc);
1717 }
1718
1719 /// Build a new OpenMP 'safelen' clause.
1720 ///
1721 /// By default, performs semantic analysis to build the new OpenMP clause.
1722 /// Subclasses may override this routine to provide different behavior.
1723 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1724 SourceLocation LParenLoc,
1725 SourceLocation EndLoc) {
1726 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1727 EndLoc);
1728 }
1729
1730 /// Build a new OpenMP 'simdlen' clause.
1731 ///
1732 /// By default, performs semantic analysis to build the new OpenMP clause.
1733 /// Subclasses may override this routine to provide different behavior.
1734 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1735 SourceLocation LParenLoc,
1736 SourceLocation EndLoc) {
1737 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1738 EndLoc);
1739 }
1740
1741 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1742 SourceLocation StartLoc,
1743 SourceLocation LParenLoc,
1744 SourceLocation EndLoc) {
1745 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1746 EndLoc);
1747 }
1748
1749 /// Build a new OpenMP 'full' clause.
1750 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1751 SourceLocation EndLoc) {
1752 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1753 }
1754
1755 /// Build a new OpenMP 'partial' clause.
1756 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1757 SourceLocation LParenLoc,
1758 SourceLocation EndLoc) {
1759 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1760 LParenLoc, EndLoc);
1761 }
1762
1763 /// Build a new OpenMP 'allocator' clause.
1764 ///
1765 /// By default, performs semantic analysis to build the new OpenMP clause.
1766 /// Subclasses may override this routine to provide different behavior.
1767 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1768 SourceLocation LParenLoc,
1769 SourceLocation EndLoc) {
1770 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1771 EndLoc);
1772 }
1773
1774 /// Build a new OpenMP 'collapse' clause.
1775 ///
1776 /// By default, performs semantic analysis to build the new OpenMP clause.
1777 /// Subclasses may override this routine to provide different behavior.
1778 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1779 SourceLocation LParenLoc,
1780 SourceLocation EndLoc) {
1781 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1782 LParenLoc, EndLoc);
1783 }
1784
1785 /// Build a new OpenMP 'default' clause.
1786 ///
1787 /// By default, performs semantic analysis to build the new OpenMP clause.
1788 /// Subclasses may override this routine to provide different behavior.
1789 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1790 SourceLocation StartLoc,
1791 SourceLocation LParenLoc,
1792 SourceLocation EndLoc) {
1793 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1794 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1795 }
1796
1797 /// Build a new OpenMP 'proc_bind' clause.
1798 ///
1799 /// By default, performs semantic analysis to build the new OpenMP clause.
1800 /// Subclasses may override this routine to provide different behavior.
1801 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1802 SourceLocation KindKwLoc,
1803 SourceLocation StartLoc,
1804 SourceLocation LParenLoc,
1805 SourceLocation EndLoc) {
1806 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1807 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1808 }
1809
1810 /// Build a new OpenMP 'schedule' clause.
1811 ///
1812 /// By default, performs semantic analysis to build the new OpenMP clause.
1813 /// Subclasses may override this routine to provide different behavior.
1814 OMPClause *RebuildOMPScheduleClause(
1815 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1816 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1817 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1818 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1819 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1820 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1821 CommaLoc, EndLoc);
1822 }
1823
1824 /// Build a new OpenMP 'ordered' clause.
1825 ///
1826 /// By default, performs semantic analysis to build the new OpenMP clause.
1827 /// Subclasses may override this routine to provide different behavior.
1828 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1829 SourceLocation EndLoc,
1830 SourceLocation LParenLoc, Expr *Num) {
1831 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1832 LParenLoc, Num);
1833 }
1834
1835 /// Build a new OpenMP 'private' clause.
1836 ///
1837 /// By default, performs semantic analysis to build the new OpenMP clause.
1838 /// Subclasses may override this routine to provide different behavior.
1839 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1840 SourceLocation StartLoc,
1841 SourceLocation LParenLoc,
1842 SourceLocation EndLoc) {
1843 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1844 LParenLoc, EndLoc);
1845 }
1846
1847 /// Build a new OpenMP 'firstprivate' clause.
1848 ///
1849 /// By default, performs semantic analysis to build the new OpenMP clause.
1850 /// Subclasses may override this routine to provide different behavior.
1851 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1852 SourceLocation StartLoc,
1853 SourceLocation LParenLoc,
1854 SourceLocation EndLoc) {
1855 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1856 LParenLoc, EndLoc);
1857 }
1858
1859 /// Build a new OpenMP 'lastprivate' clause.
1860 ///
1861 /// By default, performs semantic analysis to build the new OpenMP clause.
1862 /// Subclasses may override this routine to provide different behavior.
1863 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1864 OpenMPLastprivateModifier LPKind,
1865 SourceLocation LPKindLoc,
1866 SourceLocation ColonLoc,
1867 SourceLocation StartLoc,
1868 SourceLocation LParenLoc,
1869 SourceLocation EndLoc) {
1870 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1871 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1872 }
1873
1874 /// Build a new OpenMP 'shared' clause.
1875 ///
1876 /// By default, performs semantic analysis to build the new OpenMP clause.
1877 /// Subclasses may override this routine to provide different behavior.
1878 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1879 SourceLocation StartLoc,
1880 SourceLocation LParenLoc,
1881 SourceLocation EndLoc) {
1882 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1883 LParenLoc, EndLoc);
1884 }
1885
1886 /// Build a new OpenMP 'reduction' clause.
1887 ///
1888 /// By default, performs semantic analysis to build the new statement.
1889 /// Subclasses may override this routine to provide different behavior.
1890 OMPClause *RebuildOMPReductionClause(
1891 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1892 SourceLocation StartLoc, SourceLocation LParenLoc,
1893 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1894 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1895 const DeclarationNameInfo &ReductionId,
1896 ArrayRef<Expr *> UnresolvedReductions) {
1897 return getSema().OpenMP().ActOnOpenMPReductionClause(
1898 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1899 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1900 }
1901
1902 /// Build a new OpenMP 'task_reduction' clause.
1903 ///
1904 /// By default, performs semantic analysis to build the new statement.
1905 /// Subclasses may override this routine to provide different behavior.
1906 OMPClause *RebuildOMPTaskReductionClause(
1907 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1908 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1909 CXXScopeSpec &ReductionIdScopeSpec,
1910 const DeclarationNameInfo &ReductionId,
1911 ArrayRef<Expr *> UnresolvedReductions) {
1912 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1913 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1914 ReductionId, UnresolvedReductions);
1915 }
1916
1917 /// Build a new OpenMP 'in_reduction' clause.
1918 ///
1919 /// By default, performs semantic analysis to build the new statement.
1920 /// Subclasses may override this routine to provide different behavior.
1921 OMPClause *
1922 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1923 SourceLocation LParenLoc, SourceLocation ColonLoc,
1924 SourceLocation EndLoc,
1925 CXXScopeSpec &ReductionIdScopeSpec,
1926 const DeclarationNameInfo &ReductionId,
1927 ArrayRef<Expr *> UnresolvedReductions) {
1928 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1929 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1930 ReductionId, UnresolvedReductions);
1931 }
1932
1933 /// Build a new OpenMP 'linear' clause.
1934 ///
1935 /// By default, performs semantic analysis to build the new OpenMP clause.
1936 /// Subclasses may override this routine to provide different behavior.
1937 OMPClause *RebuildOMPLinearClause(
1938 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1939 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1940 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1941 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1942 return getSema().OpenMP().ActOnOpenMPLinearClause(
1943 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1944 StepModifierLoc, EndLoc);
1945 }
1946
1947 /// Build a new OpenMP 'aligned' clause.
1948 ///
1949 /// By default, performs semantic analysis to build the new OpenMP clause.
1950 /// Subclasses may override this routine to provide different behavior.
1951 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1952 SourceLocation StartLoc,
1953 SourceLocation LParenLoc,
1954 SourceLocation ColonLoc,
1955 SourceLocation EndLoc) {
1956 return getSema().OpenMP().ActOnOpenMPAlignedClause(
1957 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1958 }
1959
1960 /// Build a new OpenMP 'copyin' clause.
1961 ///
1962 /// By default, performs semantic analysis to build the new OpenMP clause.
1963 /// Subclasses may override this routine to provide different behavior.
1964 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1965 SourceLocation StartLoc,
1966 SourceLocation LParenLoc,
1967 SourceLocation EndLoc) {
1968 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1969 LParenLoc, EndLoc);
1970 }
1971
1972 /// Build a new OpenMP 'copyprivate' clause.
1973 ///
1974 /// By default, performs semantic analysis to build the new OpenMP clause.
1975 /// Subclasses may override this routine to provide different behavior.
1976 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1977 SourceLocation StartLoc,
1978 SourceLocation LParenLoc,
1979 SourceLocation EndLoc) {
1980 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
1981 LParenLoc, EndLoc);
1982 }
1983
1984 /// Build a new OpenMP 'flush' pseudo clause.
1985 ///
1986 /// By default, performs semantic analysis to build the new OpenMP clause.
1987 /// Subclasses may override this routine to provide different behavior.
1988 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
1989 SourceLocation StartLoc,
1990 SourceLocation LParenLoc,
1991 SourceLocation EndLoc) {
1992 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
1993 LParenLoc, EndLoc);
1994 }
1995
1996 /// Build a new OpenMP 'depobj' pseudo clause.
1997 ///
1998 /// By default, performs semantic analysis to build the new OpenMP clause.
1999 /// Subclasses may override this routine to provide different behavior.
2000 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2001 SourceLocation LParenLoc,
2002 SourceLocation EndLoc) {
2003 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2004 LParenLoc, EndLoc);
2005 }
2006
2007 /// Build a new OpenMP 'depend' pseudo clause.
2008 ///
2009 /// By default, performs semantic analysis to build the new OpenMP clause.
2010 /// Subclasses may override this routine to provide different behavior.
2011 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2012 Expr *DepModifier, ArrayRef<Expr *> VarList,
2013 SourceLocation StartLoc,
2014 SourceLocation LParenLoc,
2015 SourceLocation EndLoc) {
2016 return getSema().OpenMP().ActOnOpenMPDependClause(
2017 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2018 }
2019
2020 /// Build a new OpenMP 'device' clause.
2021 ///
2022 /// By default, performs semantic analysis to build the new statement.
2023 /// Subclasses may override this routine to provide different behavior.
2024 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2025 Expr *Device, SourceLocation StartLoc,
2026 SourceLocation LParenLoc,
2027 SourceLocation ModifierLoc,
2028 SourceLocation EndLoc) {
2029 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2030 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2031 }
2032
2033 /// Build a new OpenMP 'map' clause.
2034 ///
2035 /// By default, performs semantic analysis to build the new OpenMP clause.
2036 /// Subclasses may override this routine to provide different behavior.
2037 OMPClause *RebuildOMPMapClause(
2038 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2039 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2040 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2041 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2042 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2043 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2044 return getSema().OpenMP().ActOnOpenMPMapClause(
2045 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2046 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2047 ColonLoc, VarList, Locs,
2048 /*NoDiagnose=*/false, UnresolvedMappers);
2049 }
2050
2051 /// Build a new OpenMP 'allocate' clause.
2052 ///
2053 /// By default, performs semantic analysis to build the new OpenMP clause.
2054 /// Subclasses may override this routine to provide different behavior.
2055 OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2056 SourceLocation StartLoc,
2057 SourceLocation LParenLoc,
2058 SourceLocation ColonLoc,
2059 SourceLocation EndLoc) {
2060 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2061 Allocate, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2062 }
2063
2064 /// Build a new OpenMP 'num_teams' clause.
2065 ///
2066 /// By default, performs semantic analysis to build the new statement.
2067 /// Subclasses may override this routine to provide different behavior.
2068 OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
2069 SourceLocation LParenLoc,
2070 SourceLocation EndLoc) {
2071 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc,
2072 LParenLoc, EndLoc);
2073 }
2074
2075 /// Build a new OpenMP 'thread_limit' clause.
2076 ///
2077 /// By default, performs semantic analysis to build the new statement.
2078 /// Subclasses may override this routine to provide different behavior.
2079 OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit,
2080 SourceLocation StartLoc,
2081 SourceLocation LParenLoc,
2082 SourceLocation EndLoc) {
2083 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(
2084 ThreadLimit, StartLoc, LParenLoc, EndLoc);
2085 }
2086
2087 /// Build a new OpenMP 'priority' clause.
2088 ///
2089 /// By default, performs semantic analysis to build the new statement.
2090 /// Subclasses may override this routine to provide different behavior.
2091 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2092 SourceLocation LParenLoc,
2093 SourceLocation EndLoc) {
2094 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2095 LParenLoc, EndLoc);
2096 }
2097
2098 /// Build a new OpenMP 'grainsize' clause.
2099 ///
2100 /// By default, performs semantic analysis to build the new statement.
2101 /// Subclasses may override this routine to provide different behavior.
2102 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2103 Expr *Device, SourceLocation StartLoc,
2104 SourceLocation LParenLoc,
2105 SourceLocation ModifierLoc,
2106 SourceLocation EndLoc) {
2107 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2108 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2109 }
2110
2111 /// Build a new OpenMP 'num_tasks' clause.
2112 ///
2113 /// By default, performs semantic analysis to build the new statement.
2114 /// Subclasses may override this routine to provide different behavior.
2115 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2116 Expr *NumTasks, SourceLocation StartLoc,
2117 SourceLocation LParenLoc,
2118 SourceLocation ModifierLoc,
2119 SourceLocation EndLoc) {
2120 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2121 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2122 }
2123
2124 /// Build a new OpenMP 'hint' clause.
2125 ///
2126 /// By default, performs semantic analysis to build the new statement.
2127 /// Subclasses may override this routine to provide different behavior.
2128 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2129 SourceLocation LParenLoc,
2130 SourceLocation EndLoc) {
2131 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2132 EndLoc);
2133 }
2134
2135 /// Build a new OpenMP 'detach' clause.
2136 ///
2137 /// By default, performs semantic analysis to build the new statement.
2138 /// Subclasses may override this routine to provide different behavior.
2139 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2140 SourceLocation LParenLoc,
2141 SourceLocation EndLoc) {
2142 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2143 EndLoc);
2144 }
2145
2146 /// Build a new OpenMP 'dist_schedule' clause.
2147 ///
2148 /// By default, performs semantic analysis to build the new OpenMP clause.
2149 /// Subclasses may override this routine to provide different behavior.
2150 OMPClause *
2151 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2152 Expr *ChunkSize, SourceLocation StartLoc,
2153 SourceLocation LParenLoc, SourceLocation KindLoc,
2154 SourceLocation CommaLoc, SourceLocation EndLoc) {
2155 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2156 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2157 }
2158
2159 /// Build a new OpenMP 'to' clause.
2160 ///
2161 /// By default, performs semantic analysis to build the new statement.
2162 /// Subclasses may override this routine to provide different behavior.
2163 OMPClause *
2164 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2165 ArrayRef<SourceLocation> MotionModifiersLoc,
2166 CXXScopeSpec &MapperIdScopeSpec,
2167 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2168 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2169 ArrayRef<Expr *> UnresolvedMappers) {
2170 return getSema().OpenMP().ActOnOpenMPToClause(
2171 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2172 ColonLoc, VarList, Locs, UnresolvedMappers);
2173 }
2174
2175 /// Build a new OpenMP 'from' clause.
2176 ///
2177 /// By default, performs semantic analysis to build the new statement.
2178 /// Subclasses may override this routine to provide different behavior.
2179 OMPClause *
2180 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2181 ArrayRef<SourceLocation> MotionModifiersLoc,
2182 CXXScopeSpec &MapperIdScopeSpec,
2183 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2184 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2185 ArrayRef<Expr *> UnresolvedMappers) {
2186 return getSema().OpenMP().ActOnOpenMPFromClause(
2187 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2188 ColonLoc, VarList, Locs, UnresolvedMappers);
2189 }
2190
2191 /// Build a new OpenMP 'use_device_ptr' clause.
2192 ///
2193 /// By default, performs semantic analysis to build the new OpenMP clause.
2194 /// Subclasses may override this routine to provide different behavior.
2195 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2196 const OMPVarListLocTy &Locs) {
2197 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2198 }
2199
2200 /// Build a new OpenMP 'use_device_addr' clause.
2201 ///
2202 /// By default, performs semantic analysis to build the new OpenMP clause.
2203 /// Subclasses may override this routine to provide different behavior.
2204 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2205 const OMPVarListLocTy &Locs) {
2206 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2207 }
2208
2209 /// Build a new OpenMP 'is_device_ptr' clause.
2210 ///
2211 /// By default, performs semantic analysis to build the new OpenMP clause.
2212 /// Subclasses may override this routine to provide different behavior.
2213 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2214 const OMPVarListLocTy &Locs) {
2215 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2216 }
2217
2218 /// Build a new OpenMP 'has_device_addr' clause.
2219 ///
2220 /// By default, performs semantic analysis to build the new OpenMP clause.
2221 /// Subclasses may override this routine to provide different behavior.
2222 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2223 const OMPVarListLocTy &Locs) {
2224 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2225 }
2226
2227 /// Build a new OpenMP 'defaultmap' clause.
2228 ///
2229 /// By default, performs semantic analysis to build the new OpenMP clause.
2230 /// Subclasses may override this routine to provide different behavior.
2231 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2232 OpenMPDefaultmapClauseKind Kind,
2233 SourceLocation StartLoc,
2234 SourceLocation LParenLoc,
2235 SourceLocation MLoc,
2236 SourceLocation KindLoc,
2237 SourceLocation EndLoc) {
2238 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2239 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2240 }
2241
2242 /// Build a new OpenMP 'nontemporal' clause.
2243 ///
2244 /// By default, performs semantic analysis to build the new OpenMP clause.
2245 /// Subclasses may override this routine to provide different behavior.
2246 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2247 SourceLocation StartLoc,
2248 SourceLocation LParenLoc,
2249 SourceLocation EndLoc) {
2250 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2251 LParenLoc, EndLoc);
2252 }
2253
2254 /// Build a new OpenMP 'inclusive' clause.
2255 ///
2256 /// By default, performs semantic analysis to build the new OpenMP clause.
2257 /// Subclasses may override this routine to provide different behavior.
2258 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2259 SourceLocation StartLoc,
2260 SourceLocation LParenLoc,
2261 SourceLocation EndLoc) {
2262 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2263 LParenLoc, EndLoc);
2264 }
2265
2266 /// Build a new OpenMP 'exclusive' clause.
2267 ///
2268 /// By default, performs semantic analysis to build the new OpenMP clause.
2269 /// Subclasses may override this routine to provide different behavior.
2270 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2271 SourceLocation StartLoc,
2272 SourceLocation LParenLoc,
2273 SourceLocation EndLoc) {
2274 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2275 LParenLoc, EndLoc);
2276 }
2277
2278 /// Build a new OpenMP 'uses_allocators' clause.
2279 ///
2280 /// By default, performs semantic analysis to build the new OpenMP clause.
2281 /// Subclasses may override this routine to provide different behavior.
2282 OMPClause *RebuildOMPUsesAllocatorsClause(
2283 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2284 SourceLocation LParenLoc, SourceLocation EndLoc) {
2285 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2286 StartLoc, LParenLoc, EndLoc, Data);
2287 }
2288
2289 /// Build a new OpenMP 'affinity' clause.
2290 ///
2291 /// By default, performs semantic analysis to build the new OpenMP clause.
2292 /// Subclasses may override this routine to provide different behavior.
2293 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2294 SourceLocation LParenLoc,
2295 SourceLocation ColonLoc,
2296 SourceLocation EndLoc, Expr *Modifier,
2297 ArrayRef<Expr *> Locators) {
2298 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2299 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2300 }
2301
2302 /// Build a new OpenMP 'order' clause.
2303 ///
2304 /// By default, performs semantic analysis to build the new OpenMP clause.
2305 /// Subclasses may override this routine to provide different behavior.
2306 OMPClause *RebuildOMPOrderClause(
2307 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2308 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2309 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2310 return getSema().OpenMP().ActOnOpenMPOrderClause(
2311 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2312 }
2313
2314 /// Build a new OpenMP 'init' clause.
2315 ///
2316 /// By default, performs semantic analysis to build the new OpenMP clause.
2317 /// Subclasses may override this routine to provide different behavior.
2318 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2319 SourceLocation StartLoc,
2320 SourceLocation LParenLoc,
2321 SourceLocation VarLoc,
2322 SourceLocation EndLoc) {
2323 return getSema().OpenMP().ActOnOpenMPInitClause(
2324 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2325 }
2326
2327 /// Build a new OpenMP 'use' clause.
2328 ///
2329 /// By default, performs semantic analysis to build the new OpenMP clause.
2330 /// Subclasses may override this routine to provide different behavior.
2331 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2332 SourceLocation LParenLoc,
2333 SourceLocation VarLoc, SourceLocation EndLoc) {
2334 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2335 LParenLoc, VarLoc, EndLoc);
2336 }
2337
2338 /// Build a new OpenMP 'destroy' clause.
2339 ///
2340 /// By default, performs semantic analysis to build the new OpenMP clause.
2341 /// Subclasses may override this routine to provide different behavior.
2342 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2343 SourceLocation LParenLoc,
2344 SourceLocation VarLoc,
2345 SourceLocation EndLoc) {
2346 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2347 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2348 }
2349
2350 /// Build a new OpenMP 'novariants' clause.
2351 ///
2352 /// By default, performs semantic analysis to build the new OpenMP clause.
2353 /// Subclasses may override this routine to provide different behavior.
2354 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2355 SourceLocation StartLoc,
2356 SourceLocation LParenLoc,
2357 SourceLocation EndLoc) {
2358 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2359 LParenLoc, EndLoc);
2360 }
2361
2362 /// Build a new OpenMP 'nocontext' clause.
2363 ///
2364 /// By default, performs semantic analysis to build the new OpenMP clause.
2365 /// Subclasses may override this routine to provide different behavior.
2366 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2367 SourceLocation LParenLoc,
2368 SourceLocation EndLoc) {
2369 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2370 LParenLoc, EndLoc);
2371 }
2372
2373 /// Build a new OpenMP 'filter' clause.
2374 ///
2375 /// By default, performs semantic analysis to build the new OpenMP clause.
2376 /// Subclasses may override this routine to provide different behavior.
2377 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2378 SourceLocation LParenLoc,
2379 SourceLocation EndLoc) {
2380 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2381 LParenLoc, EndLoc);
2382 }
2383
2384 /// Build a new OpenMP 'bind' clause.
2385 ///
2386 /// By default, performs semantic analysis to build the new OpenMP clause.
2387 /// Subclasses may override this routine to provide different behavior.
2388 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2389 SourceLocation KindLoc,
2390 SourceLocation StartLoc,
2391 SourceLocation LParenLoc,
2392 SourceLocation EndLoc) {
2393 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2394 LParenLoc, EndLoc);
2395 }
2396
2397 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2398 ///
2399 /// By default, performs semantic analysis to build the new OpenMP clause.
2400 /// Subclasses may override this routine to provide different behavior.
2401 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2402 SourceLocation LParenLoc,
2403 SourceLocation EndLoc) {
2404 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2405 LParenLoc, EndLoc);
2406 }
2407
2408 /// Build a new OpenMP 'ompx_attribute' clause.
2409 ///
2410 /// By default, performs semantic analysis to build the new OpenMP clause.
2411 /// Subclasses may override this routine to provide different behavior.
2412 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2413 SourceLocation StartLoc,
2414 SourceLocation LParenLoc,
2415 SourceLocation EndLoc) {
2416 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2417 LParenLoc, EndLoc);
2418 }
2419
2420 /// Build a new OpenMP 'ompx_bare' clause.
2421 ///
2422 /// By default, performs semantic analysis to build the new OpenMP clause.
2423 /// Subclasses may override this routine to provide different behavior.
2424 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2425 SourceLocation EndLoc) {
2426 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2427 }
2428
2429 /// Build a new OpenMP 'align' clause.
2430 ///
2431 /// By default, performs semantic analysis to build the new OpenMP clause.
2432 /// Subclasses may override this routine to provide different behavior.
2433 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2434 SourceLocation LParenLoc,
2435 SourceLocation EndLoc) {
2436 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2437 EndLoc);
2438 }
2439
2440 /// Build a new OpenMP 'at' clause.
2441 ///
2442 /// By default, performs semantic analysis to build the new OpenMP clause.
2443 /// Subclasses may override this routine to provide different behavior.
2444 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2445 SourceLocation StartLoc,
2446 SourceLocation LParenLoc,
2447 SourceLocation EndLoc) {
2448 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2449 LParenLoc, EndLoc);
2450 }
2451
2452 /// Build a new OpenMP 'severity' clause.
2453 ///
2454 /// By default, performs semantic analysis to build the new OpenMP clause.
2455 /// Subclasses may override this routine to provide different behavior.
2456 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2457 SourceLocation KwLoc,
2458 SourceLocation StartLoc,
2459 SourceLocation LParenLoc,
2460 SourceLocation EndLoc) {
2461 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2462 LParenLoc, EndLoc);
2463 }
2464
2465 /// Build a new OpenMP 'message' clause.
2466 ///
2467 /// By default, performs semantic analysis to build the new OpenMP clause.
2468 /// Subclasses may override this routine to provide different behavior.
2469 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2470 SourceLocation LParenLoc,
2471 SourceLocation EndLoc) {
2472 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2473 EndLoc);
2474 }
2475
2476 /// Build a new OpenMP 'doacross' clause.
2477 ///
2478 /// By default, performs semantic analysis to build the new OpenMP clause.
2479 /// Subclasses may override this routine to provide different behavior.
2480 OMPClause *
2481 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2482 SourceLocation DepLoc, SourceLocation ColonLoc,
2483 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2484 SourceLocation LParenLoc, SourceLocation EndLoc) {
2485 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2486 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2487 }
2488
2489 /// Rebuild the operand to an Objective-C \@synchronized statement.
2490 ///
2491 /// By default, performs semantic analysis to build the new statement.
2492 /// Subclasses may override this routine to provide different behavior.
2493 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2494 Expr *object) {
2495 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2496 }
2497
2498 /// Build a new Objective-C \@synchronized statement.
2499 ///
2500 /// By default, performs semantic analysis to build the new statement.
2501 /// Subclasses may override this routine to provide different behavior.
2502 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2503 Expr *Object, Stmt *Body) {
2504 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2505 }
2506
2507 /// Build a new Objective-C \@autoreleasepool statement.
2508 ///
2509 /// By default, performs semantic analysis to build the new statement.
2510 /// Subclasses may override this routine to provide different behavior.
2511 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2512 Stmt *Body) {
2513 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2514 }
2515
2516 /// Build a new Objective-C fast enumeration statement.
2517 ///
2518 /// By default, performs semantic analysis to build the new statement.
2519 /// Subclasses may override this routine to provide different behavior.
2520 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2521 Stmt *Element,
2522 Expr *Collection,
2523 SourceLocation RParenLoc,
2524 Stmt *Body) {
2525 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2526 ForLoc, Element, Collection, RParenLoc);
2527 if (ForEachStmt.isInvalid())
2528 return StmtError();
2529
2530 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2531 Body);
2532 }
2533
2534 /// Build a new C++ exception declaration.
2535 ///
2536 /// By default, performs semantic analysis to build the new decaration.
2537 /// Subclasses may override this routine to provide different behavior.
2538 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2539 TypeSourceInfo *Declarator,
2540 SourceLocation StartLoc,
2541 SourceLocation IdLoc,
2542 IdentifierInfo *Id) {
2543 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2544 StartLoc, IdLoc, Id);
2545 if (Var)
2546 getSema().CurContext->addDecl(Var);
2547 return Var;
2548 }
2549
2550 /// Build a new C++ catch statement.
2551 ///
2552 /// By default, performs semantic analysis to build the new statement.
2553 /// Subclasses may override this routine to provide different behavior.
2554 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2555 VarDecl *ExceptionDecl,
2556 Stmt *Handler) {
2557 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2558 Handler));
2559 }
2560
2561 /// Build a new C++ try statement.
2562 ///
2563 /// By default, performs semantic analysis to build the new statement.
2564 /// Subclasses may override this routine to provide different behavior.
2565 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2566 ArrayRef<Stmt *> Handlers) {
2567 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2568 }
2569
2570 /// Build a new C++0x range-based for statement.
2571 ///
2572 /// By default, performs semantic analysis to build the new statement.
2573 /// Subclasses may override this routine to provide different behavior.
2574 StmtResult RebuildCXXForRangeStmt(
2575 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2576 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2577 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2578 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2579 // If we've just learned that the range is actually an Objective-C
2580 // collection, treat this as an Objective-C fast enumeration loop.
2581 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2582 if (RangeStmt->isSingleDecl()) {
2583 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2584 if (RangeVar->isInvalidDecl())
2585 return StmtError();
2586
2587 Expr *RangeExpr = RangeVar->getInit();
2588 if (!RangeExpr->isTypeDependent() &&
2589 RangeExpr->getType()->isObjCObjectPointerType()) {
2590 // FIXME: Support init-statements in Objective-C++20 ranged for
2591 // statement.
2592 if (Init) {
2593 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2594 DiagID: diag::err_objc_for_range_init_stmt)
2595 << Init->getSourceRange();
2596 }
2597 return getSema().ObjC().ActOnObjCForCollectionStmt(
2598 ForLoc, LoopVar, RangeExpr, RParenLoc);
2599 }
2600 }
2601 }
2602 }
2603
2604 return getSema().BuildCXXForRangeStmt(
2605 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2606 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2607 }
2608
2609 /// Build a new C++0x range-based for statement.
2610 ///
2611 /// By default, performs semantic analysis to build the new statement.
2612 /// Subclasses may override this routine to provide different behavior.
2613 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2614 bool IsIfExists,
2615 NestedNameSpecifierLoc QualifierLoc,
2616 DeclarationNameInfo NameInfo,
2617 Stmt *Nested) {
2618 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2619 QualifierLoc, NameInfo, Nested);
2620 }
2621
2622 /// Attach body to a C++0x range-based for statement.
2623 ///
2624 /// By default, performs semantic analysis to finish the new statement.
2625 /// Subclasses may override this routine to provide different behavior.
2626 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2627 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2628 }
2629
2630 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2631 Stmt *TryBlock, Stmt *Handler) {
2632 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2633 }
2634
2635 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2636 Stmt *Block) {
2637 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2638 }
2639
2640 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2641 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2642 }
2643
2644 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2645 SourceLocation LParen,
2646 SourceLocation RParen,
2647 TypeSourceInfo *TSI) {
2648 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2649 TSI);
2650 }
2651
2652 /// Build a new predefined expression.
2653 ///
2654 /// By default, performs semantic analysis to build the new expression.
2655 /// Subclasses may override this routine to provide different behavior.
2656 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2657 return getSema().BuildPredefinedExpr(Loc, IK);
2658 }
2659
2660 /// Build a new expression that references a declaration.
2661 ///
2662 /// By default, performs semantic analysis to build the new expression.
2663 /// Subclasses may override this routine to provide different behavior.
2664 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2665 LookupResult &R,
2666 bool RequiresADL) {
2667 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2668 }
2669
2670
2671 /// Build a new expression that references a declaration.
2672 ///
2673 /// By default, performs semantic analysis to build the new expression.
2674 /// Subclasses may override this routine to provide different behavior.
2675 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2676 ValueDecl *VD,
2677 const DeclarationNameInfo &NameInfo,
2678 NamedDecl *Found,
2679 TemplateArgumentListInfo *TemplateArgs) {
2680 CXXScopeSpec SS;
2681 SS.Adopt(Other: QualifierLoc);
2682 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2683 TemplateArgs);
2684 }
2685
2686 /// Build a new expression in parentheses.
2687 ///
2688 /// By default, performs semantic analysis to build the new expression.
2689 /// Subclasses may override this routine to provide different behavior.
2690 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2691 SourceLocation RParen) {
2692 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2693 }
2694
2695 /// Build a new pseudo-destructor expression.
2696 ///
2697 /// By default, performs semantic analysis to build the new expression.
2698 /// Subclasses may override this routine to provide different behavior.
2699 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2700 SourceLocation OperatorLoc,
2701 bool isArrow,
2702 CXXScopeSpec &SS,
2703 TypeSourceInfo *ScopeType,
2704 SourceLocation CCLoc,
2705 SourceLocation TildeLoc,
2706 PseudoDestructorTypeStorage Destroyed);
2707
2708 /// Build a new unary operator expression.
2709 ///
2710 /// By default, performs semantic analysis to build the new expression.
2711 /// Subclasses may override this routine to provide different behavior.
2712 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2713 UnaryOperatorKind Opc,
2714 Expr *SubExpr) {
2715 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2716 }
2717
2718 /// Build a new builtin offsetof expression.
2719 ///
2720 /// By default, performs semantic analysis to build the new expression.
2721 /// Subclasses may override this routine to provide different behavior.
2722 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2723 TypeSourceInfo *Type,
2724 ArrayRef<Sema::OffsetOfComponent> Components,
2725 SourceLocation RParenLoc) {
2726 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2727 RParenLoc);
2728 }
2729
2730 /// Build a new sizeof, alignof or vec_step expression with a
2731 /// type argument.
2732 ///
2733 /// By default, performs semantic analysis to build the new expression.
2734 /// Subclasses may override this routine to provide different behavior.
2735 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2736 SourceLocation OpLoc,
2737 UnaryExprOrTypeTrait ExprKind,
2738 SourceRange R) {
2739 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2740 }
2741
2742 /// Build a new sizeof, alignof or vec step expression with an
2743 /// expression argument.
2744 ///
2745 /// By default, performs semantic analysis to build the new expression.
2746 /// Subclasses may override this routine to provide different behavior.
2747 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2748 UnaryExprOrTypeTrait ExprKind,
2749 SourceRange R) {
2750 ExprResult Result
2751 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2752 if (Result.isInvalid())
2753 return ExprError();
2754
2755 return Result;
2756 }
2757
2758 /// Build a new array subscript expression.
2759 ///
2760 /// By default, performs semantic analysis to build the new expression.
2761 /// Subclasses may override this routine to provide different behavior.
2762 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2763 SourceLocation LBracketLoc,
2764 Expr *RHS,
2765 SourceLocation RBracketLoc) {
2766 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2767 LBracketLoc, RHS,
2768 RBracketLoc);
2769 }
2770
2771 /// Build a new matrix subscript expression.
2772 ///
2773 /// By default, performs semantic analysis to build the new expression.
2774 /// Subclasses may override this routine to provide different behavior.
2775 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2776 Expr *ColumnIdx,
2777 SourceLocation RBracketLoc) {
2778 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2779 RBracketLoc);
2780 }
2781
2782 /// Build a new array section expression.
2783 ///
2784 /// By default, performs semantic analysis to build the new expression.
2785 /// Subclasses may override this routine to provide different behavior.
2786 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2787 SourceLocation LBracketLoc,
2788 Expr *LowerBound,
2789 SourceLocation ColonLocFirst,
2790 SourceLocation ColonLocSecond,
2791 Expr *Length, Expr *Stride,
2792 SourceLocation RBracketLoc) {
2793 if (IsOMPArraySection)
2794 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2795 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2796 Stride, RBracketLoc);
2797
2798 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2799 "Stride/second colon not allowed for OpenACC");
2800
2801 return getSema().OpenACC().ActOnArraySectionExpr(
2802 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2803 }
2804
2805 /// Build a new array shaping expression.
2806 ///
2807 /// By default, performs semantic analysis to build the new expression.
2808 /// Subclasses may override this routine to provide different behavior.
2809 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2810 SourceLocation RParenLoc,
2811 ArrayRef<Expr *> Dims,
2812 ArrayRef<SourceRange> BracketsRanges) {
2813 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2814 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2815 }
2816
2817 /// Build a new iterator expression.
2818 ///
2819 /// By default, performs semantic analysis to build the new expression.
2820 /// Subclasses may override this routine to provide different behavior.
2821 ExprResult
2822 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2823 SourceLocation RLoc,
2824 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2825 return getSema().OpenMP().ActOnOMPIteratorExpr(
2826 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2827 }
2828
2829 /// Build a new call expression.
2830 ///
2831 /// By default, performs semantic analysis to build the new expression.
2832 /// Subclasses may override this routine to provide different behavior.
2833 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2834 MultiExprArg Args,
2835 SourceLocation RParenLoc,
2836 Expr *ExecConfig = nullptr) {
2837 return getSema().ActOnCallExpr(
2838 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2839 }
2840
2841 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2842 MultiExprArg Args,
2843 SourceLocation RParenLoc) {
2844 return getSema().ActOnArraySubscriptExpr(
2845 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2846 }
2847
2848 /// Build a new member access expression.
2849 ///
2850 /// By default, performs semantic analysis to build the new expression.
2851 /// Subclasses may override this routine to provide different behavior.
2852 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2853 bool isArrow,
2854 NestedNameSpecifierLoc QualifierLoc,
2855 SourceLocation TemplateKWLoc,
2856 const DeclarationNameInfo &MemberNameInfo,
2857 ValueDecl *Member,
2858 NamedDecl *FoundDecl,
2859 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2860 NamedDecl *FirstQualifierInScope) {
2861 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2862 isArrow);
2863 if (!Member->getDeclName()) {
2864 // We have a reference to an unnamed field. This is always the
2865 // base of an anonymous struct/union member access, i.e. the
2866 // field is always of record type.
2867 assert(Member->getType()->isRecordType() &&
2868 "unnamed member not of record type?");
2869
2870 BaseResult =
2871 getSema().PerformObjectMemberConversion(BaseResult.get(),
2872 QualifierLoc.getNestedNameSpecifier(),
2873 FoundDecl, Member);
2874 if (BaseResult.isInvalid())
2875 return ExprError();
2876 Base = BaseResult.get();
2877
2878 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2879 // from the AST, so we need to re-insert them if needed (since
2880 // `BuildFieldRefereneExpr()` doesn't do this).
2881 if (!isArrow && Base->isPRValue()) {
2882 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2883 if (BaseResult.isInvalid())
2884 return ExprError();
2885 Base = BaseResult.get();
2886 }
2887
2888 CXXScopeSpec EmptySS;
2889 return getSema().BuildFieldReferenceExpr(
2890 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
2891 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
2892 MemberNameInfo);
2893 }
2894
2895 CXXScopeSpec SS;
2896 SS.Adopt(Other: QualifierLoc);
2897
2898 Base = BaseResult.get();
2899 if (Base->containsErrors())
2900 return ExprError();
2901
2902 QualType BaseType = Base->getType();
2903
2904 if (isArrow && !BaseType->isPointerType())
2905 return ExprError();
2906
2907 // FIXME: this involves duplicating earlier analysis in a lot of
2908 // cases; we should avoid this when possible.
2909 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2910 R.addDecl(D: FoundDecl);
2911 R.resolveKind();
2912
2913 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2914 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
2915 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
2916 ->getType()
2917 ->getPointeeType()
2918 ->getAsCXXRecordDecl()) {
2919 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
2920 // In unevaluated contexts, an expression supposed to be a member access
2921 // might reference a member in an unrelated class.
2922 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
2923 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2924 VK_LValue, Member->getLocation());
2925 }
2926 }
2927
2928 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2929 SS, TemplateKWLoc,
2930 FirstQualifierInScope,
2931 R, ExplicitTemplateArgs,
2932 /*S*/nullptr);
2933 }
2934
2935 /// Build a new binary operator expression.
2936 ///
2937 /// By default, performs semantic analysis to build the new expression.
2938 /// Subclasses may override this routine to provide different behavior.
2939 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2940 BinaryOperatorKind Opc,
2941 Expr *LHS, Expr *RHS) {
2942 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2943 }
2944
2945 /// Build a new rewritten operator expression.
2946 ///
2947 /// By default, performs semantic analysis to build the new expression.
2948 /// Subclasses may override this routine to provide different behavior.
2949 ExprResult RebuildCXXRewrittenBinaryOperator(
2950 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2951 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2952 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2953 RHS, /*RequiresADL*/false);
2954 }
2955
2956 /// Build a new conditional operator expression.
2957 ///
2958 /// By default, performs semantic analysis to build the new expression.
2959 /// Subclasses may override this routine to provide different behavior.
2960 ExprResult RebuildConditionalOperator(Expr *Cond,
2961 SourceLocation QuestionLoc,
2962 Expr *LHS,
2963 SourceLocation ColonLoc,
2964 Expr *RHS) {
2965 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2966 LHS, RHS);
2967 }
2968
2969 /// Build a new C-style cast expression.
2970 ///
2971 /// By default, performs semantic analysis to build the new expression.
2972 /// Subclasses may override this routine to provide different behavior.
2973 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2974 TypeSourceInfo *TInfo,
2975 SourceLocation RParenLoc,
2976 Expr *SubExpr) {
2977 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2978 SubExpr);
2979 }
2980
2981 /// Build a new compound literal expression.
2982 ///
2983 /// By default, performs semantic analysis to build the new expression.
2984 /// Subclasses may override this routine to provide different behavior.
2985 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2986 TypeSourceInfo *TInfo,
2987 SourceLocation RParenLoc,
2988 Expr *Init) {
2989 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2990 Init);
2991 }
2992
2993 /// Build a new extended vector element access expression.
2994 ///
2995 /// By default, performs semantic analysis to build the new expression.
2996 /// Subclasses may override this routine to provide different behavior.
2997 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2998 bool IsArrow,
2999 SourceLocation AccessorLoc,
3000 IdentifierInfo &Accessor) {
3001
3002 CXXScopeSpec SS;
3003 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3004 return getSema().BuildMemberReferenceExpr(
3005 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3006 /*FirstQualifierInScope*/ nullptr, NameInfo,
3007 /* TemplateArgs */ nullptr,
3008 /*S*/ nullptr);
3009 }
3010
3011 /// Build a new initializer list expression.
3012 ///
3013 /// By default, performs semantic analysis to build the new expression.
3014 /// Subclasses may override this routine to provide different behavior.
3015 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3016 MultiExprArg Inits,
3017 SourceLocation RBraceLoc) {
3018 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
3019 }
3020
3021 /// Build a new designated initializer expression.
3022 ///
3023 /// By default, performs semantic analysis to build the new expression.
3024 /// Subclasses may override this routine to provide different behavior.
3025 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3026 MultiExprArg ArrayExprs,
3027 SourceLocation EqualOrColonLoc,
3028 bool GNUSyntax,
3029 Expr *Init) {
3030 ExprResult Result
3031 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3032 Init);
3033 if (Result.isInvalid())
3034 return ExprError();
3035
3036 return Result;
3037 }
3038
3039 /// Build a new value-initialized expression.
3040 ///
3041 /// By default, builds the implicit value initialization without performing
3042 /// any semantic analysis. Subclasses may override this routine to provide
3043 /// different behavior.
3044 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3045 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3046 }
3047
3048 /// Build a new \c va_arg expression.
3049 ///
3050 /// By default, performs semantic analysis to build the new expression.
3051 /// Subclasses may override this routine to provide different behavior.
3052 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3053 Expr *SubExpr, TypeSourceInfo *TInfo,
3054 SourceLocation RParenLoc) {
3055 return getSema().BuildVAArgExpr(BuiltinLoc,
3056 SubExpr, TInfo,
3057 RParenLoc);
3058 }
3059
3060 /// Build a new expression list in parentheses.
3061 ///
3062 /// By default, performs semantic analysis to build the new expression.
3063 /// Subclasses may override this routine to provide different behavior.
3064 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3065 MultiExprArg SubExprs,
3066 SourceLocation RParenLoc) {
3067 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3068 }
3069
3070 /// Build a new address-of-label expression.
3071 ///
3072 /// By default, performs semantic analysis, using the name of the label
3073 /// rather than attempting to map the label statement itself.
3074 /// Subclasses may override this routine to provide different behavior.
3075 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3076 SourceLocation LabelLoc, LabelDecl *Label) {
3077 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3078 }
3079
3080 /// Build a new GNU statement expression.
3081 ///
3082 /// By default, performs semantic analysis to build the new expression.
3083 /// Subclasses may override this routine to provide different behavior.
3084 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3085 SourceLocation RParenLoc, unsigned TemplateDepth) {
3086 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3087 TemplateDepth);
3088 }
3089
3090 /// Build a new __builtin_choose_expr expression.
3091 ///
3092 /// By default, performs semantic analysis to build the new expression.
3093 /// Subclasses may override this routine to provide different behavior.
3094 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3095 Expr *Cond, Expr *LHS, Expr *RHS,
3096 SourceLocation RParenLoc) {
3097 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3098 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3099 RPLoc: RParenLoc);
3100 }
3101
3102 /// Build a new generic selection expression with an expression predicate.
3103 ///
3104 /// By default, performs semantic analysis to build the new expression.
3105 /// Subclasses may override this routine to provide different behavior.
3106 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3107 SourceLocation DefaultLoc,
3108 SourceLocation RParenLoc,
3109 Expr *ControllingExpr,
3110 ArrayRef<TypeSourceInfo *> Types,
3111 ArrayRef<Expr *> Exprs) {
3112 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3113 /*PredicateIsExpr=*/true,
3114 ControllingExpr, Types, Exprs);
3115 }
3116
3117 /// Build a new generic selection expression with a type predicate.
3118 ///
3119 /// By default, performs semantic analysis to build the new expression.
3120 /// Subclasses may override this routine to provide different behavior.
3121 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3122 SourceLocation DefaultLoc,
3123 SourceLocation RParenLoc,
3124 TypeSourceInfo *ControllingType,
3125 ArrayRef<TypeSourceInfo *> Types,
3126 ArrayRef<Expr *> Exprs) {
3127 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3128 /*PredicateIsExpr=*/false,
3129 ControllingType, Types, Exprs);
3130 }
3131
3132 /// Build a new overloaded operator call expression.
3133 ///
3134 /// By default, performs semantic analysis to build the new expression.
3135 /// The semantic analysis provides the behavior of template instantiation,
3136 /// copying with transformations that turn what looks like an overloaded
3137 /// operator call into a use of a builtin operator, performing
3138 /// argument-dependent lookup, etc. Subclasses may override this routine to
3139 /// provide different behavior.
3140 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3141 SourceLocation OpLoc,
3142 SourceLocation CalleeLoc,
3143 bool RequiresADL,
3144 const UnresolvedSetImpl &Functions,
3145 Expr *First, Expr *Second);
3146
3147 /// Build a new C++ "named" cast expression, such as static_cast or
3148 /// reinterpret_cast.
3149 ///
3150 /// By default, this routine dispatches to one of the more-specific routines
3151 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3152 /// Subclasses may override this routine to provide different behavior.
3153 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3154 Stmt::StmtClass Class,
3155 SourceLocation LAngleLoc,
3156 TypeSourceInfo *TInfo,
3157 SourceLocation RAngleLoc,
3158 SourceLocation LParenLoc,
3159 Expr *SubExpr,
3160 SourceLocation RParenLoc) {
3161 switch (Class) {
3162 case Stmt::CXXStaticCastExprClass:
3163 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3164 RAngleLoc, LParenLoc,
3165 SubExpr, RParenLoc);
3166
3167 case Stmt::CXXDynamicCastExprClass:
3168 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3169 RAngleLoc, LParenLoc,
3170 SubExpr, RParenLoc);
3171
3172 case Stmt::CXXReinterpretCastExprClass:
3173 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3174 RAngleLoc, LParenLoc,
3175 SubExpr,
3176 RParenLoc);
3177
3178 case Stmt::CXXConstCastExprClass:
3179 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3180 RAngleLoc, LParenLoc,
3181 SubExpr, RParenLoc);
3182
3183 case Stmt::CXXAddrspaceCastExprClass:
3184 return getDerived().RebuildCXXAddrspaceCastExpr(
3185 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3186
3187 default:
3188 llvm_unreachable("Invalid C++ named cast");
3189 }
3190 }
3191
3192 /// Build a new C++ static_cast expression.
3193 ///
3194 /// By default, performs semantic analysis to build the new expression.
3195 /// Subclasses may override this routine to provide different behavior.
3196 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3197 SourceLocation LAngleLoc,
3198 TypeSourceInfo *TInfo,
3199 SourceLocation RAngleLoc,
3200 SourceLocation LParenLoc,
3201 Expr *SubExpr,
3202 SourceLocation RParenLoc) {
3203 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3204 TInfo, SubExpr,
3205 SourceRange(LAngleLoc, RAngleLoc),
3206 SourceRange(LParenLoc, RParenLoc));
3207 }
3208
3209 /// Build a new C++ dynamic_cast expression.
3210 ///
3211 /// By default, performs semantic analysis to build the new expression.
3212 /// Subclasses may override this routine to provide different behavior.
3213 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3214 SourceLocation LAngleLoc,
3215 TypeSourceInfo *TInfo,
3216 SourceLocation RAngleLoc,
3217 SourceLocation LParenLoc,
3218 Expr *SubExpr,
3219 SourceLocation RParenLoc) {
3220 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3221 TInfo, SubExpr,
3222 SourceRange(LAngleLoc, RAngleLoc),
3223 SourceRange(LParenLoc, RParenLoc));
3224 }
3225
3226 /// Build a new C++ reinterpret_cast expression.
3227 ///
3228 /// By default, performs semantic analysis to build the new expression.
3229 /// Subclasses may override this routine to provide different behavior.
3230 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3231 SourceLocation LAngleLoc,
3232 TypeSourceInfo *TInfo,
3233 SourceLocation RAngleLoc,
3234 SourceLocation LParenLoc,
3235 Expr *SubExpr,
3236 SourceLocation RParenLoc) {
3237 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3238 TInfo, SubExpr,
3239 SourceRange(LAngleLoc, RAngleLoc),
3240 SourceRange(LParenLoc, RParenLoc));
3241 }
3242
3243 /// Build a new C++ const_cast expression.
3244 ///
3245 /// By default, performs semantic analysis to build the new expression.
3246 /// Subclasses may override this routine to provide different behavior.
3247 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3248 SourceLocation LAngleLoc,
3249 TypeSourceInfo *TInfo,
3250 SourceLocation RAngleLoc,
3251 SourceLocation LParenLoc,
3252 Expr *SubExpr,
3253 SourceLocation RParenLoc) {
3254 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3255 TInfo, SubExpr,
3256 SourceRange(LAngleLoc, RAngleLoc),
3257 SourceRange(LParenLoc, RParenLoc));
3258 }
3259
3260 ExprResult
3261 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3262 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3263 SourceLocation LParenLoc, Expr *SubExpr,
3264 SourceLocation RParenLoc) {
3265 return getSema().BuildCXXNamedCast(
3266 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3267 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3268 }
3269
3270 /// Build a new C++ functional-style cast expression.
3271 ///
3272 /// By default, performs semantic analysis to build the new expression.
3273 /// Subclasses may override this routine to provide different behavior.
3274 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3275 SourceLocation LParenLoc,
3276 Expr *Sub,
3277 SourceLocation RParenLoc,
3278 bool ListInitialization) {
3279 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3280 // CXXParenListInitExpr. Pass its expanded arguments so that the
3281 // CXXParenListInitExpr can be rebuilt.
3282 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3283 return getSema().BuildCXXTypeConstructExpr(
3284 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3285 RParenLoc, ListInitialization);
3286 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3287 MultiExprArg(&Sub, 1), RParenLoc,
3288 ListInitialization);
3289 }
3290
3291 /// Build a new C++ __builtin_bit_cast expression.
3292 ///
3293 /// By default, performs semantic analysis to build the new expression.
3294 /// Subclasses may override this routine to provide different behavior.
3295 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3296 TypeSourceInfo *TSI, Expr *Sub,
3297 SourceLocation RParenLoc) {
3298 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3299 }
3300
3301 /// Build a new C++ typeid(type) expression.
3302 ///
3303 /// By default, performs semantic analysis to build the new expression.
3304 /// Subclasses may override this routine to provide different behavior.
3305 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3306 SourceLocation TypeidLoc,
3307 TypeSourceInfo *Operand,
3308 SourceLocation RParenLoc) {
3309 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3310 RParenLoc);
3311 }
3312
3313
3314 /// Build a new C++ typeid(expr) expression.
3315 ///
3316 /// By default, performs semantic analysis to build the new expression.
3317 /// Subclasses may override this routine to provide different behavior.
3318 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3319 SourceLocation TypeidLoc,
3320 Expr *Operand,
3321 SourceLocation RParenLoc) {
3322 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3323 RParenLoc);
3324 }
3325
3326 /// Build a new C++ __uuidof(type) expression.
3327 ///
3328 /// By default, performs semantic analysis to build the new expression.
3329 /// Subclasses may override this routine to provide different behavior.
3330 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3331 TypeSourceInfo *Operand,
3332 SourceLocation RParenLoc) {
3333 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3334 }
3335
3336 /// Build a new C++ __uuidof(expr) expression.
3337 ///
3338 /// By default, performs semantic analysis to build the new expression.
3339 /// Subclasses may override this routine to provide different behavior.
3340 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3341 Expr *Operand, SourceLocation RParenLoc) {
3342 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3343 }
3344
3345 /// Build a new C++ "this" expression.
3346 ///
3347 /// By default, performs semantic analysis to build a new "this" expression.
3348 /// Subclasses may override this routine to provide different behavior.
3349 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3350 QualType ThisType,
3351 bool isImplicit) {
3352 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3353 return ExprError();
3354 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3355 }
3356
3357 /// Build a new C++ throw expression.
3358 ///
3359 /// By default, performs semantic analysis to build the new expression.
3360 /// Subclasses may override this routine to provide different behavior.
3361 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3362 bool IsThrownVariableInScope) {
3363 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3364 }
3365
3366 /// Build a new C++ default-argument expression.
3367 ///
3368 /// By default, builds a new default-argument expression, which does not
3369 /// require any semantic analysis. Subclasses may override this routine to
3370 /// provide different behavior.
3371 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3372 Expr *RewrittenExpr) {
3373 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3374 RewrittenExpr, UsedContext: getSema().CurContext);
3375 }
3376
3377 /// Build a new C++11 default-initialization expression.
3378 ///
3379 /// By default, builds a new default field initialization expression, which
3380 /// does not require any semantic analysis. Subclasses may override this
3381 /// routine to provide different behavior.
3382 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3383 FieldDecl *Field) {
3384 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3385 }
3386
3387 /// Build a new C++ zero-initialization expression.
3388 ///
3389 /// By default, performs semantic analysis to build the new expression.
3390 /// Subclasses may override this routine to provide different behavior.
3391 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3392 SourceLocation LParenLoc,
3393 SourceLocation RParenLoc) {
3394 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3395 RParenLoc,
3396 /*ListInitialization=*/false);
3397 }
3398
3399 /// Build a new C++ "new" expression.
3400 ///
3401 /// By default, performs semantic analysis to build the new expression.
3402 /// Subclasses may override this routine to provide different behavior.
3403 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3404 SourceLocation PlacementLParen,
3405 MultiExprArg PlacementArgs,
3406 SourceLocation PlacementRParen,
3407 SourceRange TypeIdParens, QualType AllocatedType,
3408 TypeSourceInfo *AllocatedTypeInfo,
3409 std::optional<Expr *> ArraySize,
3410 SourceRange DirectInitRange, Expr *Initializer) {
3411 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3412 PlacementLParen,
3413 PlacementArgs,
3414 PlacementRParen,
3415 TypeIdParens,
3416 AllocatedType,
3417 AllocatedTypeInfo,
3418 ArraySize,
3419 DirectInitRange,
3420 Initializer);
3421 }
3422
3423 /// Build a new C++ "delete" expression.
3424 ///
3425 /// By default, performs semantic analysis to build the new expression.
3426 /// Subclasses may override this routine to provide different behavior.
3427 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3428 bool IsGlobalDelete,
3429 bool IsArrayForm,
3430 Expr *Operand) {
3431 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3432 Operand);
3433 }
3434
3435 /// Build a new type trait expression.
3436 ///
3437 /// By default, performs semantic analysis to build the new expression.
3438 /// Subclasses may override this routine to provide different behavior.
3439 ExprResult RebuildTypeTrait(TypeTrait Trait,
3440 SourceLocation StartLoc,
3441 ArrayRef<TypeSourceInfo *> Args,
3442 SourceLocation RParenLoc) {
3443 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3444 }
3445
3446 /// Build a new array type trait expression.
3447 ///
3448 /// By default, performs semantic analysis to build the new expression.
3449 /// Subclasses may override this routine to provide different behavior.
3450 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3451 SourceLocation StartLoc,
3452 TypeSourceInfo *TSInfo,
3453 Expr *DimExpr,
3454 SourceLocation RParenLoc) {
3455 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3456 }
3457
3458 /// Build a new expression trait expression.
3459 ///
3460 /// By default, performs semantic analysis to build the new expression.
3461 /// Subclasses may override this routine to provide different behavior.
3462 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3463 SourceLocation StartLoc,
3464 Expr *Queried,
3465 SourceLocation RParenLoc) {
3466 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3467 }
3468
3469 /// Build a new (previously unresolved) declaration reference
3470 /// expression.
3471 ///
3472 /// By default, performs semantic analysis to build the new expression.
3473 /// Subclasses may override this routine to provide different behavior.
3474 ExprResult RebuildDependentScopeDeclRefExpr(
3475 NestedNameSpecifierLoc QualifierLoc,
3476 SourceLocation TemplateKWLoc,
3477 const DeclarationNameInfo &NameInfo,
3478 const TemplateArgumentListInfo *TemplateArgs,
3479 bool IsAddressOfOperand,
3480 TypeSourceInfo **RecoveryTSI) {
3481 CXXScopeSpec SS;
3482 SS.Adopt(Other: QualifierLoc);
3483
3484 if (TemplateArgs || TemplateKWLoc.isValid())
3485 return getSema().BuildQualifiedTemplateIdExpr(
3486 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3487
3488 return getSema().BuildQualifiedDeclarationNameExpr(
3489 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3490 }
3491
3492 /// Build a new template-id expression.
3493 ///
3494 /// By default, performs semantic analysis to build the new expression.
3495 /// Subclasses may override this routine to provide different behavior.
3496 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3497 SourceLocation TemplateKWLoc,
3498 LookupResult &R,
3499 bool RequiresADL,
3500 const TemplateArgumentListInfo *TemplateArgs) {
3501 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3502 TemplateArgs);
3503 }
3504
3505 /// Build a new object-construction expression.
3506 ///
3507 /// By default, performs semantic analysis to build the new expression.
3508 /// Subclasses may override this routine to provide different behavior.
3509 ExprResult RebuildCXXConstructExpr(
3510 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3511 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3512 bool ListInitialization, bool StdInitListInitialization,
3513 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3514 SourceRange ParenRange) {
3515 // Reconstruct the constructor we originally found, which might be
3516 // different if this is a call to an inherited constructor.
3517 CXXConstructorDecl *FoundCtor = Constructor;
3518 if (Constructor->isInheritingConstructor())
3519 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3520
3521 SmallVector<Expr *, 8> ConvertedArgs;
3522 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3523 ConvertedArgs))
3524 return ExprError();
3525
3526 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3527 IsElidable,
3528 ConvertedArgs,
3529 HadMultipleCandidates,
3530 ListInitialization,
3531 StdInitListInitialization,
3532 RequiresZeroInit, ConstructKind,
3533 ParenRange);
3534 }
3535
3536 /// Build a new implicit construction via inherited constructor
3537 /// expression.
3538 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3539 CXXConstructorDecl *Constructor,
3540 bool ConstructsVBase,
3541 bool InheritedFromVBase) {
3542 return new (getSema().Context) CXXInheritedCtorInitExpr(
3543 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3544 }
3545
3546 /// Build a new object-construction expression.
3547 ///
3548 /// By default, performs semantic analysis to build the new expression.
3549 /// Subclasses may override this routine to provide different behavior.
3550 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3551 SourceLocation LParenOrBraceLoc,
3552 MultiExprArg Args,
3553 SourceLocation RParenOrBraceLoc,
3554 bool ListInitialization) {
3555 return getSema().BuildCXXTypeConstructExpr(
3556 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3557 }
3558
3559 /// Build a new object-construction expression.
3560 ///
3561 /// By default, performs semantic analysis to build the new expression.
3562 /// Subclasses may override this routine to provide different behavior.
3563 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3564 SourceLocation LParenLoc,
3565 MultiExprArg Args,
3566 SourceLocation RParenLoc,
3567 bool ListInitialization) {
3568 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3569 RParenLoc, ListInitialization);
3570 }
3571
3572 /// Build a new member reference expression.
3573 ///
3574 /// By default, performs semantic analysis to build the new expression.
3575 /// Subclasses may override this routine to provide different behavior.
3576 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3577 QualType BaseType,
3578 bool IsArrow,
3579 SourceLocation OperatorLoc,
3580 NestedNameSpecifierLoc QualifierLoc,
3581 SourceLocation TemplateKWLoc,
3582 NamedDecl *FirstQualifierInScope,
3583 const DeclarationNameInfo &MemberNameInfo,
3584 const TemplateArgumentListInfo *TemplateArgs) {
3585 CXXScopeSpec SS;
3586 SS.Adopt(Other: QualifierLoc);
3587
3588 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3589 OpLoc: OperatorLoc, IsArrow,
3590 SS, TemplateKWLoc,
3591 FirstQualifierInScope,
3592 NameInfo: MemberNameInfo,
3593 TemplateArgs, /*S*/S: nullptr);
3594 }
3595
3596 /// Build a new member reference expression.
3597 ///
3598 /// By default, performs semantic analysis to build the new expression.
3599 /// Subclasses may override this routine to provide different behavior.
3600 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3601 SourceLocation OperatorLoc,
3602 bool IsArrow,
3603 NestedNameSpecifierLoc QualifierLoc,
3604 SourceLocation TemplateKWLoc,
3605 NamedDecl *FirstQualifierInScope,
3606 LookupResult &R,
3607 const TemplateArgumentListInfo *TemplateArgs) {
3608 CXXScopeSpec SS;
3609 SS.Adopt(Other: QualifierLoc);
3610
3611 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3612 OpLoc: OperatorLoc, IsArrow,
3613 SS, TemplateKWLoc,
3614 FirstQualifierInScope,
3615 R, TemplateArgs, /*S*/S: nullptr);
3616 }
3617
3618 /// Build a new noexcept expression.
3619 ///
3620 /// By default, performs semantic analysis to build the new expression.
3621 /// Subclasses may override this routine to provide different behavior.
3622 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3623 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3624 }
3625
3626 /// Build a new expression to compute the length of a parameter pack.
3627 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3628 SourceLocation PackLoc,
3629 SourceLocation RParenLoc,
3630 std::optional<unsigned> Length,
3631 ArrayRef<TemplateArgument> PartialArgs) {
3632 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3633 RParenLoc, Length, PartialArgs);
3634 }
3635
3636 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3637 SourceLocation RSquareLoc,
3638 Expr *PackIdExpression, Expr *IndexExpr,
3639 ArrayRef<Expr *> ExpandedExprs,
3640 bool EmptyPack = false) {
3641 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3642 IndexExpr, RSquareLoc, ExpandedExprs,
3643 EmptyPack);
3644 }
3645
3646 /// Build a new expression representing a call to a source location
3647 /// builtin.
3648 ///
3649 /// By default, performs semantic analysis to build the new expression.
3650 /// Subclasses may override this routine to provide different behavior.
3651 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3652 SourceLocation BuiltinLoc,
3653 SourceLocation RPLoc,
3654 DeclContext *ParentContext) {
3655 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3656 ParentContext);
3657 }
3658
3659 /// Build a new Objective-C boxed expression.
3660 ///
3661 /// By default, performs semantic analysis to build the new expression.
3662 /// Subclasses may override this routine to provide different behavior.
3663 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3664 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3665 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3666 TemplateArgumentListInfo *TALI) {
3667 CXXScopeSpec SS;
3668 SS.Adopt(Other: NNS);
3669 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3670 ConceptNameInfo,
3671 FoundDecl,
3672 NamedConcept, TALI);
3673 if (Result.isInvalid())
3674 return ExprError();
3675 return Result;
3676 }
3677
3678 /// \brief Build a new requires expression.
3679 ///
3680 /// By default, performs semantic analysis to build the new expression.
3681 /// Subclasses may override this routine to provide different behavior.
3682 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3683 RequiresExprBodyDecl *Body,
3684 SourceLocation LParenLoc,
3685 ArrayRef<ParmVarDecl *> LocalParameters,
3686 SourceLocation RParenLoc,
3687 ArrayRef<concepts::Requirement *> Requirements,
3688 SourceLocation ClosingBraceLoc) {
3689 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3690 LocalParameters, RParenLoc, Requirements,
3691 RBraceLoc: ClosingBraceLoc);
3692 }
3693
3694 concepts::TypeRequirement *
3695 RebuildTypeRequirement(
3696 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3697 return SemaRef.BuildTypeRequirement(SubstDiag);
3698 }
3699
3700 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3701 return SemaRef.BuildTypeRequirement(Type: T);
3702 }
3703
3704 concepts::ExprRequirement *
3705 RebuildExprRequirement(
3706 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3707 SourceLocation NoexceptLoc,
3708 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3709 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3710 ReturnTypeRequirement: std::move(Ret));
3711 }
3712
3713 concepts::ExprRequirement *
3714 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3715 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3716 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3717 ReturnTypeRequirement: std::move(Ret));
3718 }
3719
3720 concepts::NestedRequirement *
3721 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3722 const ASTConstraintSatisfaction &Satisfaction) {
3723 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3724 Satisfaction);
3725 }
3726
3727 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3728 return SemaRef.BuildNestedRequirement(E: Constraint);
3729 }
3730
3731 /// \brief Build a new Objective-C boxed expression.
3732 ///
3733 /// By default, performs semantic analysis to build the new expression.
3734 /// Subclasses may override this routine to provide different behavior.
3735 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3736 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3737 }
3738
3739 /// Build a new Objective-C array literal.
3740 ///
3741 /// By default, performs semantic analysis to build the new expression.
3742 /// Subclasses may override this routine to provide different behavior.
3743 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3744 Expr **Elements, unsigned NumElements) {
3745 return getSema().ObjC().BuildObjCArrayLiteral(
3746 Range, MultiExprArg(Elements, NumElements));
3747 }
3748
3749 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3750 Expr *Base, Expr *Key,
3751 ObjCMethodDecl *getterMethod,
3752 ObjCMethodDecl *setterMethod) {
3753 return getSema().ObjC().BuildObjCSubscriptExpression(
3754 RB, Base, Key, getterMethod, setterMethod);
3755 }
3756
3757 /// Build a new Objective-C dictionary literal.
3758 ///
3759 /// By default, performs semantic analysis to build the new expression.
3760 /// Subclasses may override this routine to provide different behavior.
3761 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3762 MutableArrayRef<ObjCDictionaryElement> Elements) {
3763 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3764 }
3765
3766 /// Build a new Objective-C \@encode expression.
3767 ///
3768 /// By default, performs semantic analysis to build the new expression.
3769 /// Subclasses may override this routine to provide different behavior.
3770 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3771 TypeSourceInfo *EncodeTypeInfo,
3772 SourceLocation RParenLoc) {
3773 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3774 RParenLoc);
3775 }
3776
3777 /// Build a new Objective-C class message.
3778 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3779 Selector Sel,
3780 ArrayRef<SourceLocation> SelectorLocs,
3781 ObjCMethodDecl *Method,
3782 SourceLocation LBracLoc,
3783 MultiExprArg Args,
3784 SourceLocation RBracLoc) {
3785 return SemaRef.ObjC().BuildClassMessage(
3786 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3787 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3788 RBracLoc, Args);
3789 }
3790
3791 /// Build a new Objective-C instance message.
3792 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3793 Selector Sel,
3794 ArrayRef<SourceLocation> SelectorLocs,
3795 ObjCMethodDecl *Method,
3796 SourceLocation LBracLoc,
3797 MultiExprArg Args,
3798 SourceLocation RBracLoc) {
3799 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3800 /*SuperLoc=*/SuperLoc: SourceLocation(),
3801 Sel, Method, LBracLoc,
3802 SelectorLocs, RBracLoc, Args);
3803 }
3804
3805 /// Build a new Objective-C instance/class message to 'super'.
3806 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3807 Selector Sel,
3808 ArrayRef<SourceLocation> SelectorLocs,
3809 QualType SuperType,
3810 ObjCMethodDecl *Method,
3811 SourceLocation LBracLoc,
3812 MultiExprArg Args,
3813 SourceLocation RBracLoc) {
3814 return Method->isInstanceMethod()
3815 ? SemaRef.ObjC().BuildInstanceMessage(
3816 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3817 SelectorLocs, RBracLoc, Args)
3818 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3819 Sel, Method, LBracLoc,
3820 SelectorLocs, RBracLoc, Args);
3821 }
3822
3823 /// Build a new Objective-C ivar reference expression.
3824 ///
3825 /// By default, performs semantic analysis to build the new expression.
3826 /// Subclasses may override this routine to provide different behavior.
3827 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3828 SourceLocation IvarLoc,
3829 bool IsArrow, bool IsFreeIvar) {
3830 CXXScopeSpec SS;
3831 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3832 ExprResult Result = getSema().BuildMemberReferenceExpr(
3833 BaseArg, BaseArg->getType(),
3834 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3835 /*FirstQualifierInScope=*/nullptr, NameInfo,
3836 /*TemplateArgs=*/nullptr,
3837 /*S=*/nullptr);
3838 if (IsFreeIvar && Result.isUsable())
3839 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3840 return Result;
3841 }
3842
3843 /// Build a new Objective-C property reference expression.
3844 ///
3845 /// By default, performs semantic analysis to build the new expression.
3846 /// Subclasses may override this routine to provide different behavior.
3847 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3848 ObjCPropertyDecl *Property,
3849 SourceLocation PropertyLoc) {
3850 CXXScopeSpec SS;
3851 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3852 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3853 /*FIXME:*/PropertyLoc,
3854 /*IsArrow=*/false,
3855 SS, SourceLocation(),
3856 /*FirstQualifierInScope=*/nullptr,
3857 NameInfo,
3858 /*TemplateArgs=*/nullptr,
3859 /*S=*/nullptr);
3860 }
3861
3862 /// Build a new Objective-C property reference expression.
3863 ///
3864 /// By default, performs semantic analysis to build the new expression.
3865 /// Subclasses may override this routine to provide different behavior.
3866 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3867 ObjCMethodDecl *Getter,
3868 ObjCMethodDecl *Setter,
3869 SourceLocation PropertyLoc) {
3870 // Since these expressions can only be value-dependent, we do not
3871 // need to perform semantic analysis again.
3872 return Owned(
3873 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3874 VK_LValue, OK_ObjCProperty,
3875 PropertyLoc, Base));
3876 }
3877
3878 /// Build a new Objective-C "isa" expression.
3879 ///
3880 /// By default, performs semantic analysis to build the new expression.
3881 /// Subclasses may override this routine to provide different behavior.
3882 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3883 SourceLocation OpLoc, bool IsArrow) {
3884 CXXScopeSpec SS;
3885 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3886 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3887 OpLoc, IsArrow,
3888 SS, SourceLocation(),
3889 /*FirstQualifierInScope=*/nullptr,
3890 NameInfo,
3891 /*TemplateArgs=*/nullptr,
3892 /*S=*/nullptr);
3893 }
3894
3895 /// Build a new shuffle vector expression.
3896 ///
3897 /// By default, performs semantic analysis to build the new expression.
3898 /// Subclasses may override this routine to provide different behavior.
3899 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3900 MultiExprArg SubExprs,
3901 SourceLocation RParenLoc) {
3902 // Find the declaration for __builtin_shufflevector
3903 const IdentifierInfo &Name
3904 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
3905 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3906 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
3907 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3908
3909 // Build a reference to the __builtin_shufflevector builtin
3910 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
3911 Expr *Callee = new (SemaRef.Context)
3912 DeclRefExpr(SemaRef.Context, Builtin, false,
3913 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3914 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
3915 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
3916 CK: CK_BuiltinFnToFnPtr).get();
3917
3918 // Build the CallExpr
3919 ExprResult TheCall = CallExpr::Create(
3920 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
3921 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
3922 FPFeatures: FPOptionsOverride());
3923
3924 // Type-check the __builtin_shufflevector expression.
3925 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
3926 }
3927
3928 /// Build a new convert vector expression.
3929 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3930 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3931 SourceLocation RParenLoc) {
3932 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
3933 }
3934
3935 /// Build a new template argument pack expansion.
3936 ///
3937 /// By default, performs semantic analysis to build a new pack expansion
3938 /// for a template argument. Subclasses may override this routine to provide
3939 /// different behavior.
3940 TemplateArgumentLoc
3941 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3942 std::optional<unsigned> NumExpansions) {
3943 switch (Pattern.getArgument().getKind()) {
3944 case TemplateArgument::Expression: {
3945 ExprResult Result
3946 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3947 EllipsisLoc, NumExpansions);
3948 if (Result.isInvalid())
3949 return TemplateArgumentLoc();
3950
3951 return TemplateArgumentLoc(Result.get(), Result.get());
3952 }
3953
3954 case TemplateArgument::Template:
3955 return TemplateArgumentLoc(
3956 SemaRef.Context,
3957 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3958 NumExpansions),
3959 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3960 EllipsisLoc);
3961
3962 case TemplateArgument::Null:
3963 case TemplateArgument::Integral:
3964 case TemplateArgument::Declaration:
3965 case TemplateArgument::StructuralValue:
3966 case TemplateArgument::Pack:
3967 case TemplateArgument::TemplateExpansion:
3968 case TemplateArgument::NullPtr:
3969 llvm_unreachable("Pack expansion pattern has no parameter packs");
3970
3971 case TemplateArgument::Type:
3972 if (TypeSourceInfo *Expansion
3973 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3974 EllipsisLoc,
3975 NumExpansions))
3976 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3977 Expansion);
3978 break;
3979 }
3980
3981 return TemplateArgumentLoc();
3982 }
3983
3984 /// Build a new expression pack expansion.
3985 ///
3986 /// By default, performs semantic analysis to build a new pack expansion
3987 /// for an expression. Subclasses may override this routine to provide
3988 /// different behavior.
3989 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3990 std::optional<unsigned> NumExpansions) {
3991 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3992 }
3993
3994 /// Build a new C++1z fold-expression.
3995 ///
3996 /// By default, performs semantic analysis in order to build a new fold
3997 /// expression.
3998 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3999 SourceLocation LParenLoc, Expr *LHS,
4000 BinaryOperatorKind Operator,
4001 SourceLocation EllipsisLoc, Expr *RHS,
4002 SourceLocation RParenLoc,
4003 std::optional<unsigned> NumExpansions) {
4004 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4005 EllipsisLoc, RHS, RParenLoc,
4006 NumExpansions);
4007 }
4008
4009 /// Build an empty C++1z fold-expression with the given operator.
4010 ///
4011 /// By default, produces the fallback value for the fold-expression, or
4012 /// produce an error if there is no fallback value.
4013 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4014 BinaryOperatorKind Operator) {
4015 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4016 }
4017
4018 /// Build a new atomic operation expression.
4019 ///
4020 /// By default, performs semantic analysis to build the new expression.
4021 /// Subclasses may override this routine to provide different behavior.
4022 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4023 AtomicExpr::AtomicOp Op,
4024 SourceLocation RParenLoc) {
4025 // Use this for all of the locations, since we don't know the difference
4026 // between the call and the expr at this point.
4027 SourceRange Range{BuiltinLoc, RParenLoc};
4028 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4029 Sema::AtomicArgumentOrder::AST);
4030 }
4031
4032 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4033 ArrayRef<Expr *> SubExprs, QualType Type) {
4034 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4035 }
4036
4037 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4038 SourceLocation BeginLoc,
4039 SourceLocation DirLoc,
4040 SourceLocation EndLoc,
4041 ArrayRef<OpenACCClause *> Clauses,
4042 StmtResult StrBlock) {
4043 return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, DirLoc,
4044 EndLoc, Clauses, StrBlock);
4045 }
4046
4047 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4048 SourceLocation DirLoc,
4049 SourceLocation EndLoc,
4050 ArrayRef<OpenACCClause *> Clauses,
4051 StmtResult Loop) {
4052 return getSema().OpenACC().ActOnEndStmtDirective(
4053 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, EndLoc, Clauses, Loop);
4054 }
4055
4056private:
4057 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4058 QualType ObjectType,
4059 NamedDecl *FirstQualifierInScope,
4060 CXXScopeSpec &SS);
4061
4062 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4063 QualType ObjectType,
4064 NamedDecl *FirstQualifierInScope,
4065 CXXScopeSpec &SS);
4066
4067 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4068 NamedDecl *FirstQualifierInScope,
4069 CXXScopeSpec &SS);
4070
4071 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4072 DependentNameTypeLoc TL,
4073 bool DeducibleTSTContext);
4074
4075 llvm::SmallVector<OpenACCClause *>
4076 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4077 ArrayRef<const OpenACCClause *> OldClauses);
4078
4079 OpenACCClause *
4080 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4081 OpenACCDirectiveKind DirKind,
4082 const OpenACCClause *OldClause);
4083};
4084
4085template <typename Derived>
4086StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4087 if (!S)
4088 return S;
4089
4090 switch (S->getStmtClass()) {
4091 case Stmt::NoStmtClass: break;
4092
4093 // Transform individual statement nodes
4094 // Pass SDK into statements that can produce a value
4095#define STMT(Node, Parent) \
4096 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4097#define VALUESTMT(Node, Parent) \
4098 case Stmt::Node##Class: \
4099 return getDerived().Transform##Node(cast<Node>(S), SDK);
4100#define ABSTRACT_STMT(Node)
4101#define EXPR(Node, Parent)
4102#include "clang/AST/StmtNodes.inc"
4103
4104 // Transform expressions by calling TransformExpr.
4105#define STMT(Node, Parent)
4106#define ABSTRACT_STMT(Stmt)
4107#define EXPR(Node, Parent) case Stmt::Node##Class:
4108#include "clang/AST/StmtNodes.inc"
4109 {
4110 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4111
4112 if (SDK == SDK_StmtExprResult)
4113 E = getSema().ActOnStmtExprResult(E);
4114 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4115 }
4116 }
4117
4118 return S;
4119}
4120
4121template<typename Derived>
4122OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4123 if (!S)
4124 return S;
4125
4126 switch (S->getClauseKind()) {
4127 default: break;
4128 // Transform individual clause nodes
4129#define GEN_CLANG_CLAUSE_CLASS
4130#define CLAUSE_CLASS(Enum, Str, Class) \
4131 case Enum: \
4132 return getDerived().Transform##Class(cast<Class>(S));
4133#include "llvm/Frontend/OpenMP/OMP.inc"
4134 }
4135
4136 return S;
4137}
4138
4139
4140template<typename Derived>
4141ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4142 if (!E)
4143 return E;
4144
4145 switch (E->getStmtClass()) {
4146 case Stmt::NoStmtClass: break;
4147#define STMT(Node, Parent) case Stmt::Node##Class: break;
4148#define ABSTRACT_STMT(Stmt)
4149#define EXPR(Node, Parent) \
4150 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4151#include "clang/AST/StmtNodes.inc"
4152 }
4153
4154 return E;
4155}
4156
4157template<typename Derived>
4158ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4159 bool NotCopyInit) {
4160 // Initializers are instantiated like expressions, except that various outer
4161 // layers are stripped.
4162 if (!Init)
4163 return Init;
4164
4165 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4166 Init = FE->getSubExpr();
4167
4168 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4169 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4170 Init = OVE->getSourceExpr();
4171 }
4172
4173 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4174 Init = MTE->getSubExpr();
4175
4176 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4177 Init = Binder->getSubExpr();
4178
4179 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4180 Init = ICE->getSubExprAsWritten();
4181
4182 if (CXXStdInitializerListExpr *ILE =
4183 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4184 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4185
4186 // If this is copy-initialization, we only need to reconstruct
4187 // InitListExprs. Other forms of copy-initialization will be a no-op if
4188 // the initializer is already the right type.
4189 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4190 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4191 return getDerived().TransformExpr(Init);
4192
4193 // Revert value-initialization back to empty parens.
4194 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4195 SourceRange Parens = VIE->getSourceRange();
4196 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4197 Parens.getEnd());
4198 }
4199
4200 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4201 if (isa<ImplicitValueInitExpr>(Val: Init))
4202 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4203 SourceLocation());
4204
4205 // Revert initialization by constructor back to a parenthesized or braced list
4206 // of expressions. Any other form of initializer can just be reused directly.
4207 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4208 return getDerived().TransformExpr(Init);
4209
4210 // If the initialization implicitly converted an initializer list to a
4211 // std::initializer_list object, unwrap the std::initializer_list too.
4212 if (Construct && Construct->isStdInitListInitialization())
4213 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4214
4215 // Enter a list-init context if this was list initialization.
4216 EnterExpressionEvaluationContext Context(
4217 getSema(), EnterExpressionEvaluationContext::InitList,
4218 Construct->isListInitialization());
4219
4220 getSema().keepInLifetimeExtendingContext();
4221 SmallVector<Expr*, 8> NewArgs;
4222 bool ArgChanged = false;
4223 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4224 /*IsCall*/true, NewArgs, &ArgChanged))
4225 return ExprError();
4226
4227 // If this was list initialization, revert to syntactic list form.
4228 if (Construct->isListInitialization())
4229 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4230 Construct->getEndLoc());
4231
4232 // Build a ParenListExpr to represent anything else.
4233 SourceRange Parens = Construct->getParenOrBraceRange();
4234 if (Parens.isInvalid()) {
4235 // This was a variable declaration's initialization for which no initializer
4236 // was specified.
4237 assert(NewArgs.empty() &&
4238 "no parens or braces but have direct init with arguments?");
4239 return ExprEmpty();
4240 }
4241 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4242 Parens.getEnd());
4243}
4244
4245template<typename Derived>
4246bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4247 unsigned NumInputs,
4248 bool IsCall,
4249 SmallVectorImpl<Expr *> &Outputs,
4250 bool *ArgChanged) {
4251 for (unsigned I = 0; I != NumInputs; ++I) {
4252 // If requested, drop call arguments that need to be dropped.
4253 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4254 if (ArgChanged)
4255 *ArgChanged = true;
4256
4257 break;
4258 }
4259
4260 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4261 Expr *Pattern = Expansion->getPattern();
4262
4263 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4264 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4265 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4266
4267 // Determine whether the set of unexpanded parameter packs can and should
4268 // be expanded.
4269 bool Expand = true;
4270 bool RetainExpansion = false;
4271 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4272 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4273 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4274 Pattern->getSourceRange(),
4275 Unexpanded,
4276 Expand, RetainExpansion,
4277 NumExpansions))
4278 return true;
4279
4280 if (!Expand) {
4281 // The transform has determined that we should perform a simple
4282 // transformation on the pack expansion, producing another pack
4283 // expansion.
4284 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4285 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4286 if (OutPattern.isInvalid())
4287 return true;
4288
4289 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4290 Expansion->getEllipsisLoc(),
4291 NumExpansions);
4292 if (Out.isInvalid())
4293 return true;
4294
4295 if (ArgChanged)
4296 *ArgChanged = true;
4297 Outputs.push_back(Elt: Out.get());
4298 continue;
4299 }
4300
4301 // Record right away that the argument was changed. This needs
4302 // to happen even if the array expands to nothing.
4303 if (ArgChanged) *ArgChanged = true;
4304
4305 // The transform has determined that we should perform an elementwise
4306 // expansion of the pattern. Do so.
4307 for (unsigned I = 0; I != *NumExpansions; ++I) {
4308 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4309 ExprResult Out = getDerived().TransformExpr(Pattern);
4310 if (Out.isInvalid())
4311 return true;
4312
4313 if (Out.get()->containsUnexpandedParameterPack()) {
4314 Out = getDerived().RebuildPackExpansion(
4315 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4316 if (Out.isInvalid())
4317 return true;
4318 }
4319
4320 Outputs.push_back(Elt: Out.get());
4321 }
4322
4323 // If we're supposed to retain a pack expansion, do so by temporarily
4324 // forgetting the partially-substituted parameter pack.
4325 if (RetainExpansion) {
4326 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4327
4328 ExprResult Out = getDerived().TransformExpr(Pattern);
4329 if (Out.isInvalid())
4330 return true;
4331
4332 Out = getDerived().RebuildPackExpansion(
4333 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4334 if (Out.isInvalid())
4335 return true;
4336
4337 Outputs.push_back(Elt: Out.get());
4338 }
4339
4340 continue;
4341 }
4342
4343 ExprResult Result =
4344 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4345 : getDerived().TransformExpr(Inputs[I]);
4346 if (Result.isInvalid())
4347 return true;
4348
4349 if (Result.get() != Inputs[I] && ArgChanged)
4350 *ArgChanged = true;
4351
4352 Outputs.push_back(Elt: Result.get());
4353 }
4354
4355 return false;
4356}
4357
4358template <typename Derived>
4359Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4360 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4361 if (Var) {
4362 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4363 getDerived().TransformDefinition(Var->getLocation(), Var));
4364
4365 if (!ConditionVar)
4366 return Sema::ConditionError();
4367
4368 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4369 }
4370
4371 if (Expr) {
4372 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4373
4374 if (CondExpr.isInvalid())
4375 return Sema::ConditionError();
4376
4377 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4378 /*MissingOK=*/true);
4379 }
4380
4381 return Sema::ConditionResult();
4382}
4383
4384template <typename Derived>
4385NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4386 NestedNameSpecifierLoc NNS, QualType ObjectType,
4387 NamedDecl *FirstQualifierInScope) {
4388 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4389
4390 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4391 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4392 Qualifier = Qualifier.getPrefix())
4393 Qualifiers.push_back(Elt: Qualifier);
4394 };
4395 insertNNS(NNS);
4396
4397 CXXScopeSpec SS;
4398 while (!Qualifiers.empty()) {
4399 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4400 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4401
4402 switch (QNNS->getKind()) {
4403 case NestedNameSpecifier::Identifier: {
4404 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4405 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4406 ObjectType);
4407 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo, EnteringContext: false,
4408 SS, ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4409 return NestedNameSpecifierLoc();
4410 break;
4411 }
4412
4413 case NestedNameSpecifier::Namespace: {
4414 NamespaceDecl *NS =
4415 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4416 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4417 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4418 break;
4419 }
4420
4421 case NestedNameSpecifier::NamespaceAlias: {
4422 NamespaceAliasDecl *Alias =
4423 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4424 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4425 SS.Extend(Context&: SemaRef.Context, Alias, AliasLoc: Q.getLocalBeginLoc(),
4426 ColonColonLoc: Q.getLocalEndLoc());
4427 break;
4428 }
4429
4430 case NestedNameSpecifier::Global:
4431 // There is no meaningful transformation that one could perform on the
4432 // global scope.
4433 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4434 break;
4435
4436 case NestedNameSpecifier::Super: {
4437 CXXRecordDecl *RD =
4438 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4439 SourceLocation(), QNNS->getAsRecordDecl()));
4440 SS.MakeSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(), ColonColonLoc: Q.getEndLoc());
4441 break;
4442 }
4443
4444 case NestedNameSpecifier::TypeSpecWithTemplate:
4445 case NestedNameSpecifier::TypeSpec: {
4446 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4447 FirstQualifierInScope, SS);
4448
4449 if (!TL)
4450 return NestedNameSpecifierLoc();
4451
4452 QualType T = TL.getType();
4453 if (T->isDependentType() || T->isRecordType() ||
4454 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4455 if (T->isEnumeralType())
4456 SemaRef.Diag(Loc: TL.getBeginLoc(),
4457 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4458
4459 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4460 SS.Adopt(Other: ETL.getQualifierLoc());
4461 TL = ETL.getNamedTypeLoc();
4462 }
4463
4464 SS.Extend(Context&: SemaRef.Context, TemplateKWLoc: TL.getTemplateKeywordLoc(), TL,
4465 ColonColonLoc: Q.getLocalEndLoc());
4466 break;
4467 }
4468 // If the nested-name-specifier is an invalid type def, don't emit an
4469 // error because a previous error should have already been emitted.
4470 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4471 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4472 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4473 << T << SS.getRange();
4474 }
4475 return NestedNameSpecifierLoc();
4476 }
4477 }
4478
4479 // The qualifier-in-scope and object type only apply to the leftmost entity.
4480 FirstQualifierInScope = nullptr;
4481 ObjectType = QualType();
4482 }
4483
4484 // Don't rebuild the nested-name-specifier if we don't have to.
4485 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4486 !getDerived().AlwaysRebuild())
4487 return NNS;
4488
4489 // If we can re-use the source-location data from the original
4490 // nested-name-specifier, do so.
4491 if (SS.location_size() == NNS.getDataLength() &&
4492 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4493 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4494
4495 // Allocate new nested-name-specifier location information.
4496 return SS.getWithLocInContext(Context&: SemaRef.Context);
4497}
4498
4499template<typename Derived>
4500DeclarationNameInfo
4501TreeTransform<Derived>
4502::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4503 DeclarationName Name = NameInfo.getName();
4504 if (!Name)
4505 return DeclarationNameInfo();
4506
4507 switch (Name.getNameKind()) {
4508 case DeclarationName::Identifier:
4509 case DeclarationName::ObjCZeroArgSelector:
4510 case DeclarationName::ObjCOneArgSelector:
4511 case DeclarationName::ObjCMultiArgSelector:
4512 case DeclarationName::CXXOperatorName:
4513 case DeclarationName::CXXLiteralOperatorName:
4514 case DeclarationName::CXXUsingDirective:
4515 return NameInfo;
4516
4517 case DeclarationName::CXXDeductionGuideName: {
4518 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4519 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4520 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4521 if (!NewTemplate)
4522 return DeclarationNameInfo();
4523
4524 DeclarationNameInfo NewNameInfo(NameInfo);
4525 NewNameInfo.setName(
4526 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4527 return NewNameInfo;
4528 }
4529
4530 case DeclarationName::CXXConstructorName:
4531 case DeclarationName::CXXDestructorName:
4532 case DeclarationName::CXXConversionFunctionName: {
4533 TypeSourceInfo *NewTInfo;
4534 CanQualType NewCanTy;
4535 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4536 NewTInfo = getDerived().TransformType(OldTInfo);
4537 if (!NewTInfo)
4538 return DeclarationNameInfo();
4539 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4540 }
4541 else {
4542 NewTInfo = nullptr;
4543 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4544 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4545 if (NewT.isNull())
4546 return DeclarationNameInfo();
4547 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4548 }
4549
4550 DeclarationName NewName
4551 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4552 Ty: NewCanTy);
4553 DeclarationNameInfo NewNameInfo(NameInfo);
4554 NewNameInfo.setName(NewName);
4555 NewNameInfo.setNamedTypeInfo(NewTInfo);
4556 return NewNameInfo;
4557 }
4558 }
4559
4560 llvm_unreachable("Unknown name kind.");
4561}
4562
4563template<typename Derived>
4564TemplateName
4565TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4566 TemplateName Name,
4567 SourceLocation NameLoc,
4568 QualType ObjectType,
4569 NamedDecl *FirstQualifierInScope,
4570 bool AllowInjectedClassName) {
4571 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4572 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4573 assert(Template && "qualified template name must refer to a template");
4574
4575 TemplateDecl *TransTemplate
4576 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4577 Template));
4578 if (!TransTemplate)
4579 return TemplateName();
4580
4581 if (!getDerived().AlwaysRebuild() &&
4582 SS.getScopeRep() == QTN->getQualifier() &&
4583 TransTemplate == Template)
4584 return Name;
4585
4586 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4587 TransTemplate);
4588 }
4589
4590 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4591 if (SS.getScopeRep()) {
4592 // These apply to the scope specifier, not the template.
4593 ObjectType = QualType();
4594 FirstQualifierInScope = nullptr;
4595 }
4596
4597 if (!getDerived().AlwaysRebuild() &&
4598 SS.getScopeRep() == DTN->getQualifier() &&
4599 ObjectType.isNull())
4600 return Name;
4601
4602 // FIXME: Preserve the location of the "template" keyword.
4603 SourceLocation TemplateKWLoc = NameLoc;
4604
4605 if (DTN->isIdentifier()) {
4606 return getDerived().RebuildTemplateName(SS,
4607 TemplateKWLoc,
4608 *DTN->getIdentifier(),
4609 NameLoc,
4610 ObjectType,
4611 FirstQualifierInScope,
4612 AllowInjectedClassName);
4613 }
4614
4615 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4616 DTN->getOperator(), NameLoc,
4617 ObjectType, AllowInjectedClassName);
4618 }
4619
4620 // FIXME: Try to preserve more of the TemplateName.
4621 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4622 TemplateDecl *TransTemplate
4623 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4624 Template));
4625 if (!TransTemplate)
4626 return TemplateName();
4627
4628 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4629 TransTemplate);
4630 }
4631
4632 if (SubstTemplateTemplateParmPackStorage *SubstPack
4633 = Name.getAsSubstTemplateTemplateParmPack()) {
4634 return getDerived().RebuildTemplateName(
4635 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4636 SubstPack->getIndex(), SubstPack->getFinal());
4637 }
4638
4639 // These should be getting filtered out before they reach the AST.
4640 llvm_unreachable("overloaded function decl survived to here");
4641}
4642
4643template<typename Derived>
4644void TreeTransform<Derived>::InventTemplateArgumentLoc(
4645 const TemplateArgument &Arg,
4646 TemplateArgumentLoc &Output) {
4647 Output = getSema().getTrivialTemplateArgumentLoc(
4648 Arg, QualType(), getDerived().getBaseLocation());
4649}
4650
4651template <typename Derived>
4652bool TreeTransform<Derived>::TransformTemplateArgument(
4653 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4654 bool Uneval) {
4655 const TemplateArgument &Arg = Input.getArgument();
4656 switch (Arg.getKind()) {
4657 case TemplateArgument::Null:
4658 case TemplateArgument::Pack:
4659 llvm_unreachable("Unexpected TemplateArgument");
4660
4661 case TemplateArgument::Integral:
4662 case TemplateArgument::NullPtr:
4663 case TemplateArgument::Declaration:
4664 case TemplateArgument::StructuralValue: {
4665 // Transform a resolved template argument straight to a resolved template
4666 // argument. We get here when substituting into an already-substituted
4667 // template type argument during concept satisfaction checking.
4668 QualType T = Arg.getNonTypeTemplateArgumentType();
4669 QualType NewT = getDerived().TransformType(T);
4670 if (NewT.isNull())
4671 return true;
4672
4673 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4674 ? Arg.getAsDecl()
4675 : nullptr;
4676 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4677 getDerived().getBaseLocation(), D))
4678 : nullptr;
4679 if (D && !NewD)
4680 return true;
4681
4682 if (NewT == T && D == NewD)
4683 Output = Input;
4684 else if (Arg.getKind() == TemplateArgument::Integral)
4685 Output = TemplateArgumentLoc(
4686 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4687 TemplateArgumentLocInfo());
4688 else if (Arg.getKind() == TemplateArgument::NullPtr)
4689 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4690 TemplateArgumentLocInfo());
4691 else if (Arg.getKind() == TemplateArgument::Declaration)
4692 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4693 TemplateArgumentLocInfo());
4694 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4695 Output = TemplateArgumentLoc(
4696 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4697 TemplateArgumentLocInfo());
4698 else
4699 llvm_unreachable("unexpected template argument kind");
4700
4701 return false;
4702 }
4703
4704 case TemplateArgument::Type: {
4705 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4706 if (!DI)
4707 DI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
4708
4709 DI = getDerived().TransformType(DI);
4710 if (!DI)
4711 return true;
4712
4713 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4714 return false;
4715 }
4716
4717 case TemplateArgument::Template: {
4718 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4719 if (QualifierLoc) {
4720 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4721 if (!QualifierLoc)
4722 return true;
4723 }
4724
4725 CXXScopeSpec SS;
4726 SS.Adopt(Other: QualifierLoc);
4727 TemplateName Template = getDerived().TransformTemplateName(
4728 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4729 if (Template.isNull())
4730 return true;
4731
4732 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4733 QualifierLoc, Input.getTemplateNameLoc());
4734 return false;
4735 }
4736
4737 case TemplateArgument::TemplateExpansion:
4738 llvm_unreachable("Caller should expand pack expansions");
4739
4740 case TemplateArgument::Expression: {
4741 // Template argument expressions are constant expressions.
4742 EnterExpressionEvaluationContext Unevaluated(
4743 getSema(),
4744 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4745 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4746 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4747 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4748
4749 Expr *InputExpr = Input.getSourceExpression();
4750 if (!InputExpr)
4751 InputExpr = Input.getArgument().getAsExpr();
4752
4753 ExprResult E = getDerived().TransformExpr(InputExpr);
4754 E = SemaRef.ActOnConstantExpression(Res: E);
4755 if (E.isInvalid())
4756 return true;
4757 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4758 return false;
4759 }
4760 }
4761
4762 // Work around bogus GCC warning
4763 return true;
4764}
4765
4766/// Iterator adaptor that invents template argument location information
4767/// for each of the template arguments in its underlying iterator.
4768template<typename Derived, typename InputIterator>
4769class TemplateArgumentLocInventIterator {
4770 TreeTransform<Derived> &Self;
4771 InputIterator Iter;
4772
4773public:
4774 typedef TemplateArgumentLoc value_type;
4775 typedef TemplateArgumentLoc reference;
4776 typedef typename std::iterator_traits<InputIterator>::difference_type
4777 difference_type;
4778 typedef std::input_iterator_tag iterator_category;
4779
4780 class pointer {
4781 TemplateArgumentLoc Arg;
4782
4783 public:
4784 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4785
4786 const TemplateArgumentLoc *operator->() const { return &Arg; }
4787 };
4788
4789 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4790 InputIterator Iter)
4791 : Self(Self), Iter(Iter) { }
4792
4793 TemplateArgumentLocInventIterator &operator++() {
4794 ++Iter;
4795 return *this;
4796 }
4797
4798 TemplateArgumentLocInventIterator operator++(int) {
4799 TemplateArgumentLocInventIterator Old(*this);
4800 ++(*this);
4801 return Old;
4802 }
4803
4804 reference operator*() const {
4805 TemplateArgumentLoc Result;
4806 Self.InventTemplateArgumentLoc(*Iter, Result);
4807 return Result;
4808 }
4809
4810 pointer operator->() const { return pointer(**this); }
4811
4812 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4813 const TemplateArgumentLocInventIterator &Y) {
4814 return X.Iter == Y.Iter;
4815 }
4816
4817 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4818 const TemplateArgumentLocInventIterator &Y) {
4819 return X.Iter != Y.Iter;
4820 }
4821};
4822
4823template<typename Derived>
4824template<typename InputIterator>
4825bool TreeTransform<Derived>::TransformTemplateArguments(
4826 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4827 bool Uneval) {
4828 for (; First != Last; ++First) {
4829 TemplateArgumentLoc Out;
4830 TemplateArgumentLoc In = *First;
4831
4832 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4833 // Unpack argument packs, which we translate them into separate
4834 // arguments.
4835 // FIXME: We could do much better if we could guarantee that the
4836 // TemplateArgumentLocInfo for the pack expansion would be usable for
4837 // all of the template arguments in the argument pack.
4838 typedef TemplateArgumentLocInventIterator<Derived,
4839 TemplateArgument::pack_iterator>
4840 PackLocIterator;
4841 if (TransformTemplateArguments(PackLocIterator(*this,
4842 In.getArgument().pack_begin()),
4843 PackLocIterator(*this,
4844 In.getArgument().pack_end()),
4845 Outputs, Uneval))
4846 return true;
4847
4848 continue;
4849 }
4850
4851 if (In.getArgument().isPackExpansion()) {
4852 // We have a pack expansion, for which we will be substituting into
4853 // the pattern.
4854 SourceLocation Ellipsis;
4855 std::optional<unsigned> OrigNumExpansions;
4856 TemplateArgumentLoc Pattern
4857 = getSema().getTemplateArgumentPackExpansionPattern(
4858 In, Ellipsis, OrigNumExpansions);
4859
4860 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4861 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4862 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4863
4864 // Determine whether the set of unexpanded parameter packs can and should
4865 // be expanded.
4866 bool Expand = true;
4867 bool RetainExpansion = false;
4868 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4869 if (getDerived().TryExpandParameterPacks(Ellipsis,
4870 Pattern.getSourceRange(),
4871 Unexpanded,
4872 Expand,
4873 RetainExpansion,
4874 NumExpansions))
4875 return true;
4876
4877 if (!Expand) {
4878 // The transform has determined that we should perform a simple
4879 // transformation on the pack expansion, producing another pack
4880 // expansion.
4881 TemplateArgumentLoc OutPattern;
4882 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4883 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4884 return true;
4885
4886 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4887 NumExpansions);
4888 if (Out.getArgument().isNull())
4889 return true;
4890
4891 Outputs.addArgument(Loc: Out);
4892 continue;
4893 }
4894
4895 // The transform has determined that we should perform an elementwise
4896 // expansion of the pattern. Do so.
4897 for (unsigned I = 0; I != *NumExpansions; ++I) {
4898 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4899
4900 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4901 return true;
4902
4903 if (Out.getArgument().containsUnexpandedParameterPack()) {
4904 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4905 OrigNumExpansions);
4906 if (Out.getArgument().isNull())
4907 return true;
4908 }
4909
4910 Outputs.addArgument(Loc: Out);
4911 }
4912
4913 // If we're supposed to retain a pack expansion, do so by temporarily
4914 // forgetting the partially-substituted parameter pack.
4915 if (RetainExpansion) {
4916 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4917
4918 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4919 return true;
4920
4921 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4922 OrigNumExpansions);
4923 if (Out.getArgument().isNull())
4924 return true;
4925
4926 Outputs.addArgument(Loc: Out);
4927 }
4928
4929 continue;
4930 }
4931
4932 // The simple case:
4933 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4934 return true;
4935
4936 Outputs.addArgument(Loc: Out);
4937 }
4938
4939 return false;
4940
4941}
4942
4943//===----------------------------------------------------------------------===//
4944// Type transformation
4945//===----------------------------------------------------------------------===//
4946
4947template<typename Derived>
4948QualType TreeTransform<Derived>::TransformType(QualType T) {
4949 if (getDerived().AlreadyTransformed(T))
4950 return T;
4951
4952 // Temporary workaround. All of these transformations should
4953 // eventually turn into transformations on TypeLocs.
4954 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4955 getDerived().getBaseLocation());
4956
4957 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4958
4959 if (!NewDI)
4960 return QualType();
4961
4962 return NewDI->getType();
4963}
4964
4965template<typename Derived>
4966TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4967 // Refine the base location to the type's location.
4968 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4969 getDerived().getBaseEntity());
4970 if (getDerived().AlreadyTransformed(DI->getType()))
4971 return DI;
4972
4973 TypeLocBuilder TLB;
4974
4975 TypeLoc TL = DI->getTypeLoc();
4976 TLB.reserve(Requested: TL.getFullDataSize());
4977
4978 QualType Result = getDerived().TransformType(TLB, TL);
4979 if (Result.isNull())
4980 return nullptr;
4981
4982 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
4983}
4984
4985template<typename Derived>
4986QualType
4987TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4988 switch (T.getTypeLocClass()) {
4989#define ABSTRACT_TYPELOC(CLASS, PARENT)
4990#define TYPELOC(CLASS, PARENT) \
4991 case TypeLoc::CLASS: \
4992 return getDerived().Transform##CLASS##Type(TLB, \
4993 T.castAs<CLASS##TypeLoc>());
4994#include "clang/AST/TypeLocNodes.def"
4995 }
4996
4997 llvm_unreachable("unhandled type loc!");
4998}
4999
5000template<typename Derived>
5001QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5002 if (!isa<DependentNameType>(Val: T))
5003 return TransformType(T);
5004
5005 if (getDerived().AlreadyTransformed(T))
5006 return T;
5007 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5008 getDerived().getBaseLocation());
5009 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5010 return NewDI ? NewDI->getType() : QualType();
5011}
5012
5013template<typename Derived>
5014TypeSourceInfo *
5015TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5016 if (!isa<DependentNameType>(Val: DI->getType()))
5017 return TransformType(DI);
5018
5019 // Refine the base location to the type's location.
5020 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5021 getDerived().getBaseEntity());
5022 if (getDerived().AlreadyTransformed(DI->getType()))
5023 return DI;
5024
5025 TypeLocBuilder TLB;
5026
5027 TypeLoc TL = DI->getTypeLoc();
5028 TLB.reserve(Requested: TL.getFullDataSize());
5029
5030 auto QTL = TL.getAs<QualifiedTypeLoc>();
5031 if (QTL)
5032 TL = QTL.getUnqualifiedLoc();
5033
5034 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5035
5036 QualType Result = getDerived().TransformDependentNameType(
5037 TLB, DNTL, /*DeducedTSTContext*/true);
5038 if (Result.isNull())
5039 return nullptr;
5040
5041 if (QTL) {
5042 Result = getDerived().RebuildQualifiedType(Result, QTL);
5043 if (Result.isNull())
5044 return nullptr;
5045 TLB.TypeWasModifiedSafely(T: Result);
5046 }
5047
5048 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5049}
5050
5051template<typename Derived>
5052QualType
5053TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5054 QualifiedTypeLoc T) {
5055 QualType Result;
5056 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5057 auto SuppressObjCLifetime =
5058 T.getType().getLocalQualifiers().hasObjCLifetime();
5059 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5060 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5061 SuppressObjCLifetime);
5062 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5063 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5064 TLB, STTP, SuppressObjCLifetime);
5065 } else {
5066 Result = getDerived().TransformType(TLB, UnqualTL);
5067 }
5068
5069 if (Result.isNull())
5070 return QualType();
5071
5072 Result = getDerived().RebuildQualifiedType(Result, T);
5073
5074 if (Result.isNull())
5075 return QualType();
5076
5077 // RebuildQualifiedType might have updated the type, but not in a way
5078 // that invalidates the TypeLoc. (There's no location information for
5079 // qualifiers.)
5080 TLB.TypeWasModifiedSafely(T: Result);
5081
5082 return Result;
5083}
5084
5085template <typename Derived>
5086QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5087 QualifiedTypeLoc TL) {
5088
5089 SourceLocation Loc = TL.getBeginLoc();
5090 Qualifiers Quals = TL.getType().getLocalQualifiers();
5091
5092 if ((T.getAddressSpace() != LangAS::Default &&
5093 Quals.getAddressSpace() != LangAS::Default) &&
5094 T.getAddressSpace() != Quals.getAddressSpace()) {
5095 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5096 << TL.getType() << T;
5097 return QualType();
5098 }
5099
5100 // C++ [dcl.fct]p7:
5101 // [When] adding cv-qualifications on top of the function type [...] the
5102 // cv-qualifiers are ignored.
5103 if (T->isFunctionType()) {
5104 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5105 AddressSpace: Quals.getAddressSpace());
5106 return T;
5107 }
5108
5109 // C++ [dcl.ref]p1:
5110 // when the cv-qualifiers are introduced through the use of a typedef-name
5111 // or decltype-specifier [...] the cv-qualifiers are ignored.
5112 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5113 // applied to a reference type.
5114 if (T->isReferenceType()) {
5115 // The only qualifier that applies to a reference type is restrict.
5116 if (!Quals.hasRestrict())
5117 return T;
5118 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5119 }
5120
5121 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5122 // resulting type.
5123 if (Quals.hasObjCLifetime()) {
5124 if (!T->isObjCLifetimeType() && !T->isDependentType())
5125 Quals.removeObjCLifetime();
5126 else if (T.getObjCLifetime()) {
5127 // Objective-C ARC:
5128 // A lifetime qualifier applied to a substituted template parameter
5129 // overrides the lifetime qualifier from the template argument.
5130 const AutoType *AutoTy;
5131 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5132 // 'auto' types behave the same way as template parameters.
5133 QualType Deduced = AutoTy->getDeducedType();
5134 Qualifiers Qs = Deduced.getQualifiers();
5135 Qs.removeObjCLifetime();
5136 Deduced =
5137 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5138 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5139 IsDependent: AutoTy->isDependentType(),
5140 /*isPack=*/IsPack: false,
5141 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5142 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5143 } else {
5144 // Otherwise, complain about the addition of a qualifier to an
5145 // already-qualified type.
5146 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5147 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5148 Quals.removeObjCLifetime();
5149 }
5150 }
5151 }
5152
5153 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5154}
5155
5156template<typename Derived>
5157TypeLoc
5158TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5159 QualType ObjectType,
5160 NamedDecl *UnqualLookup,
5161 CXXScopeSpec &SS) {
5162 if (getDerived().AlreadyTransformed(TL.getType()))
5163 return TL;
5164
5165 TypeSourceInfo *TSI =
5166 TransformTSIInObjectScope(TL, ObjectType, FirstQualifierInScope: UnqualLookup, SS);
5167 if (TSI)
5168 return TSI->getTypeLoc();
5169 return TypeLoc();
5170}
5171
5172template<typename Derived>
5173TypeSourceInfo *
5174TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5175 QualType ObjectType,
5176 NamedDecl *UnqualLookup,
5177 CXXScopeSpec &SS) {
5178 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5179 return TSInfo;
5180
5181 return TransformTSIInObjectScope(TL: TSInfo->getTypeLoc(), ObjectType,
5182 FirstQualifierInScope: UnqualLookup, SS);
5183}
5184
5185template <typename Derived>
5186TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5187 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5188 CXXScopeSpec &SS) {
5189 QualType T = TL.getType();
5190 assert(!getDerived().AlreadyTransformed(T));
5191
5192 TypeLocBuilder TLB;
5193 QualType Result;
5194
5195 if (isa<TemplateSpecializationType>(Val: T)) {
5196 TemplateSpecializationTypeLoc SpecTL =
5197 TL.castAs<TemplateSpecializationTypeLoc>();
5198
5199 TemplateName Template = getDerived().TransformTemplateName(
5200 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5201 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5202 if (Template.isNull())
5203 return nullptr;
5204
5205 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5206 Template);
5207 } else if (isa<DependentTemplateSpecializationType>(Val: T)) {
5208 DependentTemplateSpecializationTypeLoc SpecTL =
5209 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5210
5211 TemplateName Template
5212 = getDerived().RebuildTemplateName(SS,
5213 SpecTL.getTemplateKeywordLoc(),
5214 *SpecTL.getTypePtr()->getIdentifier(),
5215 SpecTL.getTemplateNameLoc(),
5216 ObjectType, UnqualLookup,
5217 /*AllowInjectedClassName*/true);
5218 if (Template.isNull())
5219 return nullptr;
5220
5221 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5222 SpecTL,
5223 Template,
5224 SS);
5225 } else {
5226 // Nothing special needs to be done for these.
5227 Result = getDerived().TransformType(TLB, TL);
5228 }
5229
5230 if (Result.isNull())
5231 return nullptr;
5232
5233 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5234}
5235
5236template <class TyLoc> static inline
5237QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5238 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5239 NewT.setNameLoc(T.getNameLoc());
5240 return T.getType();
5241}
5242
5243template<typename Derived>
5244QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5245 BuiltinTypeLoc T) {
5246 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5247 NewT.setBuiltinLoc(T.getBuiltinLoc());
5248 if (T.needsExtraLocalData())
5249 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5250 return T.getType();
5251}
5252
5253template<typename Derived>
5254QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5255 ComplexTypeLoc T) {
5256 // FIXME: recurse?
5257 return TransformTypeSpecType(TLB, T);
5258}
5259
5260template <typename Derived>
5261QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5262 AdjustedTypeLoc TL) {
5263 // Adjustments applied during transformation are handled elsewhere.
5264 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5265}
5266
5267template<typename Derived>
5268QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5269 DecayedTypeLoc TL) {
5270 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5271 if (OriginalType.isNull())
5272 return QualType();
5273
5274 QualType Result = TL.getType();
5275 if (getDerived().AlwaysRebuild() ||
5276 OriginalType != TL.getOriginalLoc().getType())
5277 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5278 TLB.push<DecayedTypeLoc>(T: Result);
5279 // Nothing to set for DecayedTypeLoc.
5280 return Result;
5281}
5282
5283template <typename Derived>
5284QualType
5285TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5286 ArrayParameterTypeLoc TL) {
5287 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5288 if (OriginalType.isNull())
5289 return QualType();
5290
5291 QualType Result = TL.getType();
5292 if (getDerived().AlwaysRebuild() ||
5293 OriginalType != TL.getElementLoc().getType())
5294 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5295 TLB.push<ArrayParameterTypeLoc>(T: Result);
5296 // Nothing to set for ArrayParameterTypeLoc.
5297 return Result;
5298}
5299
5300template<typename Derived>
5301QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5302 PointerTypeLoc TL) {
5303 QualType PointeeType
5304 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5305 if (PointeeType.isNull())
5306 return QualType();
5307
5308 QualType Result = TL.getType();
5309 if (PointeeType->getAs<ObjCObjectType>()) {
5310 // A dependent pointer type 'T *' has is being transformed such
5311 // that an Objective-C class type is being replaced for 'T'. The
5312 // resulting pointer type is an ObjCObjectPointerType, not a
5313 // PointerType.
5314 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5315
5316 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5317 NewT.setStarLoc(TL.getStarLoc());
5318 return Result;
5319 }
5320
5321 if (getDerived().AlwaysRebuild() ||
5322 PointeeType != TL.getPointeeLoc().getType()) {
5323 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5324 if (Result.isNull())
5325 return QualType();
5326 }
5327
5328 // Objective-C ARC can add lifetime qualifiers to the type that we're
5329 // pointing to.
5330 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5331
5332 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5333 NewT.setSigilLoc(TL.getSigilLoc());
5334 return Result;
5335}
5336
5337template<typename Derived>
5338QualType
5339TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5340 BlockPointerTypeLoc TL) {
5341 QualType PointeeType
5342 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5343 if (PointeeType.isNull())
5344 return QualType();
5345
5346 QualType Result = TL.getType();
5347 if (getDerived().AlwaysRebuild() ||
5348 PointeeType != TL.getPointeeLoc().getType()) {
5349 Result = getDerived().RebuildBlockPointerType(PointeeType,
5350 TL.getSigilLoc());
5351 if (Result.isNull())
5352 return QualType();
5353 }
5354
5355 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5356 NewT.setSigilLoc(TL.getSigilLoc());
5357 return Result;
5358}
5359
5360/// Transforms a reference type. Note that somewhat paradoxically we
5361/// don't care whether the type itself is an l-value type or an r-value
5362/// type; we only care if the type was *written* as an l-value type
5363/// or an r-value type.
5364template<typename Derived>
5365QualType
5366TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5367 ReferenceTypeLoc TL) {
5368 const ReferenceType *T = TL.getTypePtr();
5369
5370 // Note that this works with the pointee-as-written.
5371 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5372 if (PointeeType.isNull())
5373 return QualType();
5374
5375 QualType Result = TL.getType();
5376 if (getDerived().AlwaysRebuild() ||
5377 PointeeType != T->getPointeeTypeAsWritten()) {
5378 Result = getDerived().RebuildReferenceType(PointeeType,
5379 T->isSpelledAsLValue(),
5380 TL.getSigilLoc());
5381 if (Result.isNull())
5382 return QualType();
5383 }
5384
5385 // Objective-C ARC can add lifetime qualifiers to the type that we're
5386 // referring to.
5387 TLB.TypeWasModifiedSafely(
5388 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5389
5390 // r-value references can be rebuilt as l-value references.
5391 ReferenceTypeLoc NewTL;
5392 if (isa<LValueReferenceType>(Val: Result))
5393 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5394 else
5395 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5396 NewTL.setSigilLoc(TL.getSigilLoc());
5397
5398 return Result;
5399}
5400
5401template<typename Derived>
5402QualType
5403TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5404 LValueReferenceTypeLoc TL) {
5405 return TransformReferenceType(TLB, TL);
5406}
5407
5408template<typename Derived>
5409QualType
5410TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5411 RValueReferenceTypeLoc TL) {
5412 return TransformReferenceType(TLB, TL);
5413}
5414
5415template<typename Derived>
5416QualType
5417TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5418 MemberPointerTypeLoc TL) {
5419 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5420 if (PointeeType.isNull())
5421 return QualType();
5422
5423 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5424 TypeSourceInfo *NewClsTInfo = nullptr;
5425 if (OldClsTInfo) {
5426 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5427 if (!NewClsTInfo)
5428 return QualType();
5429 }
5430
5431 const MemberPointerType *T = TL.getTypePtr();
5432 QualType OldClsType = QualType(T->getClass(), 0);
5433 QualType NewClsType;
5434 if (NewClsTInfo)
5435 NewClsType = NewClsTInfo->getType();
5436 else {
5437 NewClsType = getDerived().TransformType(OldClsType);
5438 if (NewClsType.isNull())
5439 return QualType();
5440 }
5441
5442 QualType Result = TL.getType();
5443 if (getDerived().AlwaysRebuild() ||
5444 PointeeType != T->getPointeeType() ||
5445 NewClsType != OldClsType) {
5446 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5447 TL.getStarLoc());
5448 if (Result.isNull())
5449 return QualType();
5450 }
5451
5452 // If we had to adjust the pointee type when building a member pointer, make
5453 // sure to push TypeLoc info for it.
5454 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5455 if (MPT && PointeeType != MPT->getPointeeType()) {
5456 assert(isa<AdjustedType>(MPT->getPointeeType()));
5457 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5458 }
5459
5460 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5461 NewTL.setSigilLoc(TL.getSigilLoc());
5462 NewTL.setClassTInfo(NewClsTInfo);
5463
5464 return Result;
5465}
5466
5467template<typename Derived>
5468QualType
5469TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5470 ConstantArrayTypeLoc TL) {
5471 const ConstantArrayType *T = TL.getTypePtr();
5472 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5473 if (ElementType.isNull())
5474 return QualType();
5475
5476 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5477 Expr *OldSize = TL.getSizeExpr();
5478 if (!OldSize)
5479 OldSize = const_cast<Expr*>(T->getSizeExpr());
5480 Expr *NewSize = nullptr;
5481 if (OldSize) {
5482 EnterExpressionEvaluationContext Unevaluated(
5483 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5484 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5485 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5486 }
5487
5488 QualType Result = TL.getType();
5489 if (getDerived().AlwaysRebuild() ||
5490 ElementType != T->getElementType() ||
5491 (T->getSizeExpr() && NewSize != OldSize)) {
5492 Result = getDerived().RebuildConstantArrayType(ElementType,
5493 T->getSizeModifier(),
5494 T->getSize(), NewSize,
5495 T->getIndexTypeCVRQualifiers(),
5496 TL.getBracketsRange());
5497 if (Result.isNull())
5498 return QualType();
5499 }
5500
5501 // We might have either a ConstantArrayType or a VariableArrayType now:
5502 // a ConstantArrayType is allowed to have an element type which is a
5503 // VariableArrayType if the type is dependent. Fortunately, all array
5504 // types have the same location layout.
5505 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5506 NewTL.setLBracketLoc(TL.getLBracketLoc());
5507 NewTL.setRBracketLoc(TL.getRBracketLoc());
5508 NewTL.setSizeExpr(NewSize);
5509
5510 return Result;
5511}
5512
5513template<typename Derived>
5514QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5515 TypeLocBuilder &TLB,
5516 IncompleteArrayTypeLoc TL) {
5517 const IncompleteArrayType *T = TL.getTypePtr();
5518 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5519 if (ElementType.isNull())
5520 return QualType();
5521
5522 QualType Result = TL.getType();
5523 if (getDerived().AlwaysRebuild() ||
5524 ElementType != T->getElementType()) {
5525 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5526 T->getSizeModifier(),
5527 T->getIndexTypeCVRQualifiers(),
5528 TL.getBracketsRange());
5529 if (Result.isNull())
5530 return QualType();
5531 }
5532
5533 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5534 NewTL.setLBracketLoc(TL.getLBracketLoc());
5535 NewTL.setRBracketLoc(TL.getRBracketLoc());
5536 NewTL.setSizeExpr(nullptr);
5537
5538 return Result;
5539}
5540
5541template<typename Derived>
5542QualType
5543TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5544 VariableArrayTypeLoc TL) {
5545 const VariableArrayType *T = TL.getTypePtr();
5546 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5547 if (ElementType.isNull())
5548 return QualType();
5549
5550 ExprResult SizeResult;
5551 {
5552 EnterExpressionEvaluationContext Context(
5553 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5554 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5555 }
5556 if (SizeResult.isInvalid())
5557 return QualType();
5558 SizeResult =
5559 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5560 if (SizeResult.isInvalid())
5561 return QualType();
5562
5563 Expr *Size = SizeResult.get();
5564
5565 QualType Result = TL.getType();
5566 if (getDerived().AlwaysRebuild() ||
5567 ElementType != T->getElementType() ||
5568 Size != T->getSizeExpr()) {
5569 Result = getDerived().RebuildVariableArrayType(ElementType,
5570 T->getSizeModifier(),
5571 Size,
5572 T->getIndexTypeCVRQualifiers(),
5573 TL.getBracketsRange());
5574 if (Result.isNull())
5575 return QualType();
5576 }
5577
5578 // We might have constant size array now, but fortunately it has the same
5579 // location layout.
5580 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5581 NewTL.setLBracketLoc(TL.getLBracketLoc());
5582 NewTL.setRBracketLoc(TL.getRBracketLoc());
5583 NewTL.setSizeExpr(Size);
5584
5585 return Result;
5586}
5587
5588template<typename Derived>
5589QualType
5590TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5591 DependentSizedArrayTypeLoc TL) {
5592 const DependentSizedArrayType *T = TL.getTypePtr();
5593 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5594 if (ElementType.isNull())
5595 return QualType();
5596
5597 // Array bounds are constant expressions.
5598 EnterExpressionEvaluationContext Unevaluated(
5599 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5600
5601 // If we have a VLA then it won't be a constant.
5602 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5603
5604 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5605 Expr *origSize = TL.getSizeExpr();
5606 if (!origSize) origSize = T->getSizeExpr();
5607
5608 ExprResult sizeResult
5609 = getDerived().TransformExpr(origSize);
5610 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
5611 if (sizeResult.isInvalid())
5612 return QualType();
5613
5614 Expr *size = sizeResult.get();
5615
5616 QualType Result = TL.getType();
5617 if (getDerived().AlwaysRebuild() ||
5618 ElementType != T->getElementType() ||
5619 size != origSize) {
5620 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5621 T->getSizeModifier(),
5622 size,
5623 T->getIndexTypeCVRQualifiers(),
5624 TL.getBracketsRange());
5625 if (Result.isNull())
5626 return QualType();
5627 }
5628
5629 // We might have any sort of array type now, but fortunately they
5630 // all have the same location layout.
5631 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5632 NewTL.setLBracketLoc(TL.getLBracketLoc());
5633 NewTL.setRBracketLoc(TL.getRBracketLoc());
5634 NewTL.setSizeExpr(size);
5635
5636 return Result;
5637}
5638
5639template <typename Derived>
5640QualType TreeTransform<Derived>::TransformDependentVectorType(
5641 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5642 const DependentVectorType *T = TL.getTypePtr();
5643 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5644 if (ElementType.isNull())
5645 return QualType();
5646
5647 EnterExpressionEvaluationContext Unevaluated(
5648 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5649
5650 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5651 Size = SemaRef.ActOnConstantExpression(Res: Size);
5652 if (Size.isInvalid())
5653 return QualType();
5654
5655 QualType Result = TL.getType();
5656 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5657 Size.get() != T->getSizeExpr()) {
5658 Result = getDerived().RebuildDependentVectorType(
5659 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5660 if (Result.isNull())
5661 return QualType();
5662 }
5663
5664 // Result might be dependent or not.
5665 if (isa<DependentVectorType>(Val: Result)) {
5666 DependentVectorTypeLoc NewTL =
5667 TLB.push<DependentVectorTypeLoc>(T: Result);
5668 NewTL.setNameLoc(TL.getNameLoc());
5669 } else {
5670 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
5671 NewTL.setNameLoc(TL.getNameLoc());
5672 }
5673
5674 return Result;
5675}
5676
5677template<typename Derived>
5678QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5679 TypeLocBuilder &TLB,
5680 DependentSizedExtVectorTypeLoc TL) {
5681 const DependentSizedExtVectorType *T = TL.getTypePtr();
5682
5683 // FIXME: ext vector locs should be nested
5684 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5685 if (ElementType.isNull())
5686 return QualType();
5687
5688 // Vector sizes are constant expressions.
5689 EnterExpressionEvaluationContext Unevaluated(
5690 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5691
5692 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5693 Size = SemaRef.ActOnConstantExpression(Res: Size);
5694 if (Size.isInvalid())
5695 return QualType();
5696
5697 QualType Result = TL.getType();
5698 if (getDerived().AlwaysRebuild() ||
5699 ElementType != T->getElementType() ||
5700 Size.get() != T->getSizeExpr()) {
5701 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5702 Size.get(),
5703 T->getAttributeLoc());
5704 if (Result.isNull())
5705 return QualType();
5706 }
5707
5708 // Result might be dependent or not.
5709 if (isa<DependentSizedExtVectorType>(Val: Result)) {
5710 DependentSizedExtVectorTypeLoc NewTL
5711 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
5712 NewTL.setNameLoc(TL.getNameLoc());
5713 } else {
5714 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
5715 NewTL.setNameLoc(TL.getNameLoc());
5716 }
5717
5718 return Result;
5719}
5720
5721template <typename Derived>
5722QualType
5723TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5724 ConstantMatrixTypeLoc TL) {
5725 const ConstantMatrixType *T = TL.getTypePtr();
5726 QualType ElementType = getDerived().TransformType(T->getElementType());
5727 if (ElementType.isNull())
5728 return QualType();
5729
5730 QualType Result = TL.getType();
5731 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5732 Result = getDerived().RebuildConstantMatrixType(
5733 ElementType, T->getNumRows(), T->getNumColumns());
5734 if (Result.isNull())
5735 return QualType();
5736 }
5737
5738 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
5739 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5740 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5741 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5742 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5743
5744 return Result;
5745}
5746
5747template <typename Derived>
5748QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5749 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5750 const DependentSizedMatrixType *T = TL.getTypePtr();
5751
5752 QualType ElementType = getDerived().TransformType(T->getElementType());
5753 if (ElementType.isNull()) {
5754 return QualType();
5755 }
5756
5757 // Matrix dimensions are constant expressions.
5758 EnterExpressionEvaluationContext Unevaluated(
5759 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5760
5761 Expr *origRows = TL.getAttrRowOperand();
5762 if (!origRows)
5763 origRows = T->getRowExpr();
5764 Expr *origColumns = TL.getAttrColumnOperand();
5765 if (!origColumns)
5766 origColumns = T->getColumnExpr();
5767
5768 ExprResult rowResult = getDerived().TransformExpr(origRows);
5769 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
5770 if (rowResult.isInvalid())
5771 return QualType();
5772
5773 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5774 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
5775 if (columnResult.isInvalid())
5776 return QualType();
5777
5778 Expr *rows = rowResult.get();
5779 Expr *columns = columnResult.get();
5780
5781 QualType Result = TL.getType();
5782 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5783 rows != origRows || columns != origColumns) {
5784 Result = getDerived().RebuildDependentSizedMatrixType(
5785 ElementType, rows, columns, T->getAttributeLoc());
5786
5787 if (Result.isNull())
5788 return QualType();
5789 }
5790
5791 // We might have any sort of matrix type now, but fortunately they
5792 // all have the same location layout.
5793 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
5794 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5795 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5796 NewTL.setAttrRowOperand(rows);
5797 NewTL.setAttrColumnOperand(columns);
5798 return Result;
5799}
5800
5801template <typename Derived>
5802QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5803 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5804 const DependentAddressSpaceType *T = TL.getTypePtr();
5805
5806 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5807
5808 if (pointeeType.isNull())
5809 return QualType();
5810
5811 // Address spaces are constant expressions.
5812 EnterExpressionEvaluationContext Unevaluated(
5813 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5814
5815 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5816 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
5817 if (AddrSpace.isInvalid())
5818 return QualType();
5819
5820 QualType Result = TL.getType();
5821 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5822 AddrSpace.get() != T->getAddrSpaceExpr()) {
5823 Result = getDerived().RebuildDependentAddressSpaceType(
5824 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5825 if (Result.isNull())
5826 return QualType();
5827 }
5828
5829 // Result might be dependent or not.
5830 if (isa<DependentAddressSpaceType>(Val: Result)) {
5831 DependentAddressSpaceTypeLoc NewTL =
5832 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
5833
5834 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5835 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5836 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5837
5838 } else {
5839 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5840 Result, getDerived().getBaseLocation());
5841 TransformType(TLB, DI->getTypeLoc());
5842 }
5843
5844 return Result;
5845}
5846
5847template <typename Derived>
5848QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5849 VectorTypeLoc TL) {
5850 const VectorType *T = TL.getTypePtr();
5851 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5852 if (ElementType.isNull())
5853 return QualType();
5854
5855 QualType Result = TL.getType();
5856 if (getDerived().AlwaysRebuild() ||
5857 ElementType != T->getElementType()) {
5858 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5859 T->getVectorKind());
5860 if (Result.isNull())
5861 return QualType();
5862 }
5863
5864 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
5865 NewTL.setNameLoc(TL.getNameLoc());
5866
5867 return Result;
5868}
5869
5870template<typename Derived>
5871QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5872 ExtVectorTypeLoc TL) {
5873 const VectorType *T = TL.getTypePtr();
5874 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5875 if (ElementType.isNull())
5876 return QualType();
5877
5878 QualType Result = TL.getType();
5879 if (getDerived().AlwaysRebuild() ||
5880 ElementType != T->getElementType()) {
5881 Result = getDerived().RebuildExtVectorType(ElementType,
5882 T->getNumElements(),
5883 /*FIXME*/ SourceLocation());
5884 if (Result.isNull())
5885 return QualType();
5886 }
5887
5888 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
5889 NewTL.setNameLoc(TL.getNameLoc());
5890
5891 return Result;
5892}
5893
5894template <typename Derived>
5895ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5896 ParmVarDecl *OldParm, int indexAdjustment,
5897 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5898 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5899 TypeSourceInfo *NewDI = nullptr;
5900
5901 if (NumExpansions && isa<PackExpansionType>(Val: OldDI->getType())) {
5902 // If we're substituting into a pack expansion type and we know the
5903 // length we want to expand to, just substitute for the pattern.
5904 TypeLoc OldTL = OldDI->getTypeLoc();
5905 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5906
5907 TypeLocBuilder TLB;
5908 TypeLoc NewTL = OldDI->getTypeLoc();
5909 TLB.reserve(Requested: NewTL.getFullDataSize());
5910
5911 QualType Result = getDerived().TransformType(TLB,
5912 OldExpansionTL.getPatternLoc());
5913 if (Result.isNull())
5914 return nullptr;
5915
5916 Result = RebuildPackExpansionType(Pattern: Result,
5917 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
5918 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
5919 NumExpansions);
5920 if (Result.isNull())
5921 return nullptr;
5922
5923 PackExpansionTypeLoc NewExpansionTL
5924 = TLB.push<PackExpansionTypeLoc>(T: Result);
5925 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5926 NewDI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5927 } else
5928 NewDI = getDerived().TransformType(OldDI);
5929 if (!NewDI)
5930 return nullptr;
5931
5932 if (NewDI == OldDI && indexAdjustment == 0)
5933 return OldParm;
5934
5935 ParmVarDecl *newParm = ParmVarDecl::Create(C&: SemaRef.Context,
5936 DC: OldParm->getDeclContext(),
5937 StartLoc: OldParm->getInnerLocStart(),
5938 IdLoc: OldParm->getLocation(),
5939 Id: OldParm->getIdentifier(),
5940 T: NewDI->getType(),
5941 TInfo: NewDI,
5942 S: OldParm->getStorageClass(),
5943 /* DefArg */ DefArg: nullptr);
5944 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
5945 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
5946 transformedLocalDecl(Old: OldParm, New: {newParm});
5947 return newParm;
5948}
5949
5950template <typename Derived>
5951bool TreeTransform<Derived>::TransformFunctionTypeParams(
5952 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5953 const QualType *ParamTypes,
5954 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5955 SmallVectorImpl<QualType> &OutParamTypes,
5956 SmallVectorImpl<ParmVarDecl *> *PVars,
5957 Sema::ExtParameterInfoBuilder &PInfos,
5958 unsigned *LastParamTransformed) {
5959 int indexAdjustment = 0;
5960
5961 unsigned NumParams = Params.size();
5962 for (unsigned i = 0; i != NumParams; ++i) {
5963 if (LastParamTransformed)
5964 *LastParamTransformed = i;
5965 if (ParmVarDecl *OldParm = Params[i]) {
5966 assert(OldParm->getFunctionScopeIndex() == i);
5967
5968 std::optional<unsigned> NumExpansions;
5969 ParmVarDecl *NewParm = nullptr;
5970 if (OldParm->isParameterPack()) {
5971 // We have a function parameter pack that may need to be expanded.
5972 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5973
5974 // Find the parameter packs that could be expanded.
5975 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5976 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5977 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5978 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
5979
5980 // Determine whether we should expand the parameter packs.
5981 bool ShouldExpand = false;
5982 bool RetainExpansion = false;
5983 std::optional<unsigned> OrigNumExpansions;
5984 if (Unexpanded.size() > 0) {
5985 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5986 NumExpansions = OrigNumExpansions;
5987 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5988 Pattern.getSourceRange(),
5989 Unexpanded,
5990 ShouldExpand,
5991 RetainExpansion,
5992 NumExpansions)) {
5993 return true;
5994 }
5995 } else {
5996#ifndef NDEBUG
5997 const AutoType *AT =
5998 Pattern.getType().getTypePtr()->getContainedAutoType();
5999 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6000 "Could not find parameter packs or undeduced auto type!");
6001#endif
6002 }
6003
6004 if (ShouldExpand) {
6005 // Expand the function parameter pack into multiple, separate
6006 // parameters.
6007 getDerived().ExpandingFunctionParameterPack(OldParm);
6008 for (unsigned I = 0; I != *NumExpansions; ++I) {
6009 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6010 ParmVarDecl *NewParm
6011 = getDerived().TransformFunctionTypeParam(OldParm,
6012 indexAdjustment++,
6013 OrigNumExpansions,
6014 /*ExpectParameterPack=*/false);
6015 if (!NewParm)
6016 return true;
6017
6018 if (ParamInfos)
6019 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6020 OutParamTypes.push_back(Elt: NewParm->getType());
6021 if (PVars)
6022 PVars->push_back(Elt: NewParm);
6023 }
6024
6025 // If we're supposed to retain a pack expansion, do so by temporarily
6026 // forgetting the partially-substituted parameter pack.
6027 if (RetainExpansion) {
6028 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6029 ParmVarDecl *NewParm
6030 = getDerived().TransformFunctionTypeParam(OldParm,
6031 indexAdjustment++,
6032 OrigNumExpansions,
6033 /*ExpectParameterPack=*/false);
6034 if (!NewParm)
6035 return true;
6036
6037 if (ParamInfos)
6038 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6039 OutParamTypes.push_back(Elt: NewParm->getType());
6040 if (PVars)
6041 PVars->push_back(Elt: NewParm);
6042 }
6043
6044 // The next parameter should have the same adjustment as the
6045 // last thing we pushed, but we post-incremented indexAdjustment
6046 // on every push. Also, if we push nothing, the adjustment should
6047 // go down by one.
6048 indexAdjustment--;
6049
6050 // We're done with the pack expansion.
6051 continue;
6052 }
6053
6054 // We'll substitute the parameter now without expanding the pack
6055 // expansion.
6056 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6057 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6058 indexAdjustment,
6059 NumExpansions,
6060 /*ExpectParameterPack=*/true);
6061 assert(NewParm->isParameterPack() &&
6062 "Parameter pack no longer a parameter pack after "
6063 "transformation.");
6064 } else {
6065 NewParm = getDerived().TransformFunctionTypeParam(
6066 OldParm, indexAdjustment, std::nullopt,
6067 /*ExpectParameterPack=*/false);
6068 }
6069
6070 if (!NewParm)
6071 return true;
6072
6073 if (ParamInfos)
6074 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6075 OutParamTypes.push_back(Elt: NewParm->getType());
6076 if (PVars)
6077 PVars->push_back(Elt: NewParm);
6078 continue;
6079 }
6080
6081 // Deal with the possibility that we don't have a parameter
6082 // declaration for this parameter.
6083 assert(ParamTypes);
6084 QualType OldType = ParamTypes[i];
6085 bool IsPackExpansion = false;
6086 std::optional<unsigned> NumExpansions;
6087 QualType NewType;
6088 if (const PackExpansionType *Expansion
6089 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6090 // We have a function parameter pack that may need to be expanded.
6091 QualType Pattern = Expansion->getPattern();
6092 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6093 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6094
6095 // Determine whether we should expand the parameter packs.
6096 bool ShouldExpand = false;
6097 bool RetainExpansion = false;
6098 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6099 Unexpanded,
6100 ShouldExpand,
6101 RetainExpansion,
6102 NumExpansions)) {
6103 return true;
6104 }
6105
6106 if (ShouldExpand) {
6107 // Expand the function parameter pack into multiple, separate
6108 // parameters.
6109 for (unsigned I = 0; I != *NumExpansions; ++I) {
6110 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6111 QualType NewType = getDerived().TransformType(Pattern);
6112 if (NewType.isNull())
6113 return true;
6114
6115 if (NewType->containsUnexpandedParameterPack()) {
6116 NewType = getSema().getASTContext().getPackExpansionType(
6117 NewType, std::nullopt);
6118
6119 if (NewType.isNull())
6120 return true;
6121 }
6122
6123 if (ParamInfos)
6124 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6125 OutParamTypes.push_back(Elt: NewType);
6126 if (PVars)
6127 PVars->push_back(Elt: nullptr);
6128 }
6129
6130 // We're done with the pack expansion.
6131 continue;
6132 }
6133
6134 // If we're supposed to retain a pack expansion, do so by temporarily
6135 // forgetting the partially-substituted parameter pack.
6136 if (RetainExpansion) {
6137 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6138 QualType NewType = getDerived().TransformType(Pattern);
6139 if (NewType.isNull())
6140 return true;
6141
6142 if (ParamInfos)
6143 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6144 OutParamTypes.push_back(Elt: NewType);
6145 if (PVars)
6146 PVars->push_back(Elt: nullptr);
6147 }
6148
6149 // We'll substitute the parameter now without expanding the pack
6150 // expansion.
6151 OldType = Expansion->getPattern();
6152 IsPackExpansion = true;
6153 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6154 NewType = getDerived().TransformType(OldType);
6155 } else {
6156 NewType = getDerived().TransformType(OldType);
6157 }
6158
6159 if (NewType.isNull())
6160 return true;
6161
6162 if (IsPackExpansion)
6163 NewType = getSema().Context.getPackExpansionType(NewType,
6164 NumExpansions);
6165
6166 if (ParamInfos)
6167 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6168 OutParamTypes.push_back(Elt: NewType);
6169 if (PVars)
6170 PVars->push_back(Elt: nullptr);
6171 }
6172
6173#ifndef NDEBUG
6174 if (PVars) {
6175 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6176 if (ParmVarDecl *parm = (*PVars)[i])
6177 assert(parm->getFunctionScopeIndex() == i);
6178 }
6179#endif
6180
6181 return false;
6182}
6183
6184template<typename Derived>
6185QualType
6186TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6187 FunctionProtoTypeLoc TL) {
6188 SmallVector<QualType, 4> ExceptionStorage;
6189 return getDerived().TransformFunctionProtoType(
6190 TLB, TL, nullptr, Qualifiers(),
6191 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6192 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6193 ExceptionStorage, Changed);
6194 });
6195}
6196
6197template<typename Derived> template<typename Fn>
6198QualType TreeTransform<Derived>::TransformFunctionProtoType(
6199 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6200 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6201
6202 // Transform the parameters and return type.
6203 //
6204 // We are required to instantiate the params and return type in source order.
6205 // When the function has a trailing return type, we instantiate the
6206 // parameters before the return type, since the return type can then refer
6207 // to the parameters themselves (via decltype, sizeof, etc.).
6208 //
6209 SmallVector<QualType, 4> ParamTypes;
6210 SmallVector<ParmVarDecl*, 4> ParamDecls;
6211 Sema::ExtParameterInfoBuilder ExtParamInfos;
6212 const FunctionProtoType *T = TL.getTypePtr();
6213
6214 QualType ResultType;
6215
6216 if (T->hasTrailingReturn()) {
6217 if (getDerived().TransformFunctionTypeParams(
6218 TL.getBeginLoc(), TL.getParams(),
6219 TL.getTypePtr()->param_type_begin(),
6220 T->getExtParameterInfosOrNull(),
6221 ParamTypes, &ParamDecls, ExtParamInfos))
6222 return QualType();
6223
6224 {
6225 // C++11 [expr.prim.general]p3:
6226 // If a declaration declares a member function or member function
6227 // template of a class X, the expression this is a prvalue of type
6228 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6229 // and the end of the function-definition, member-declarator, or
6230 // declarator.
6231 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6232 Sema::CXXThisScopeRAII ThisScope(
6233 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6234
6235 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6236 if (ResultType.isNull())
6237 return QualType();
6238 }
6239 }
6240 else {
6241 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6242 if (ResultType.isNull())
6243 return QualType();
6244
6245 if (getDerived().TransformFunctionTypeParams(
6246 TL.getBeginLoc(), TL.getParams(),
6247 TL.getTypePtr()->param_type_begin(),
6248 T->getExtParameterInfosOrNull(),
6249 ParamTypes, &ParamDecls, ExtParamInfos))
6250 return QualType();
6251 }
6252
6253 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6254
6255 bool EPIChanged = false;
6256 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6257 return QualType();
6258
6259 // Handle extended parameter information.
6260 if (auto NewExtParamInfos =
6261 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6262 if (!EPI.ExtParameterInfos ||
6263 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6264 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6265 EPIChanged = true;
6266 }
6267 EPI.ExtParameterInfos = NewExtParamInfos;
6268 } else if (EPI.ExtParameterInfos) {
6269 EPIChanged = true;
6270 EPI.ExtParameterInfos = nullptr;
6271 }
6272
6273 // Transform any function effects with unevaluated conditions.
6274 // Hold this set in a local for the rest of this function, since EPI
6275 // may need to hold a FunctionEffectsRef pointing into it.
6276 std::optional<FunctionEffectSet> NewFX;
6277 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6278 NewFX.emplace();
6279 EnterExpressionEvaluationContext Unevaluated(
6280 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6281
6282 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6283 FunctionEffectWithCondition NewEC = PrevEC;
6284 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6285 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6286 if (NewExpr.isInvalid())
6287 return QualType();
6288 std::optional<FunctionEffectMode> Mode =
6289 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6290 if (!Mode)
6291 return QualType();
6292
6293 // The condition expression has been transformed, and re-evaluated.
6294 // It may or may not have become constant.
6295 switch (*Mode) {
6296 case FunctionEffectMode::True:
6297 NewEC.Cond = {};
6298 break;
6299 case FunctionEffectMode::False:
6300 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6301 NewEC.Cond = {};
6302 break;
6303 case FunctionEffectMode::Dependent:
6304 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6305 break;
6306 case FunctionEffectMode::None:
6307 llvm_unreachable(
6308 "FunctionEffectMode::None shouldn't be possible here");
6309 }
6310 }
6311 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6312 NewAttrLoc: TL.getBeginLoc())) {
6313 FunctionEffectSet::Conflicts Errs;
6314 NewFX->insert(NewEC, Errs);
6315 assert(Errs.empty());
6316 }
6317 }
6318 EPI.FunctionEffects = *NewFX;
6319 EPIChanged = true;
6320 }
6321
6322 QualType Result = TL.getType();
6323 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6324 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6325 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6326 if (Result.isNull())
6327 return QualType();
6328 }
6329
6330 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6331 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6332 NewTL.setLParenLoc(TL.getLParenLoc());
6333 NewTL.setRParenLoc(TL.getRParenLoc());
6334 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6335 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6336 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6337 NewTL.setParam(i, VD: ParamDecls[i]);
6338
6339 return Result;
6340}
6341
6342template<typename Derived>
6343bool TreeTransform<Derived>::TransformExceptionSpec(
6344 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6345 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6346 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6347
6348 // Instantiate a dynamic noexcept expression, if any.
6349 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6350 // Update this scrope because ContextDecl in Sema will be used in
6351 // TransformExpr.
6352 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6353 Sema::CXXThisScopeRAII ThisScope(
6354 SemaRef, Method ? Method->getParent() : nullptr,
6355 Method ? Method->getMethodQualifiers() : Qualifiers{},
6356 Method != nullptr);
6357 EnterExpressionEvaluationContext Unevaluated(
6358 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6359 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6360 if (NoexceptExpr.isInvalid())
6361 return true;
6362
6363 ExceptionSpecificationType EST = ESI.Type;
6364 NoexceptExpr =
6365 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6366 if (NoexceptExpr.isInvalid())
6367 return true;
6368
6369 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6370 Changed = true;
6371 ESI.NoexceptExpr = NoexceptExpr.get();
6372 ESI.Type = EST;
6373 }
6374
6375 if (ESI.Type != EST_Dynamic)
6376 return false;
6377
6378 // Instantiate a dynamic exception specification's type.
6379 for (QualType T : ESI.Exceptions) {
6380 if (const PackExpansionType *PackExpansion =
6381 T->getAs<PackExpansionType>()) {
6382 Changed = true;
6383
6384 // We have a pack expansion. Instantiate it.
6385 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6386 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6387 Unexpanded);
6388 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6389
6390 // Determine whether the set of unexpanded parameter packs can and
6391 // should
6392 // be expanded.
6393 bool Expand = false;
6394 bool RetainExpansion = false;
6395 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6396 // FIXME: Track the location of the ellipsis (and track source location
6397 // information for the types in the exception specification in general).
6398 if (getDerived().TryExpandParameterPacks(
6399 Loc, SourceRange(), Unexpanded, Expand,
6400 RetainExpansion, NumExpansions))
6401 return true;
6402
6403 if (!Expand) {
6404 // We can't expand this pack expansion into separate arguments yet;
6405 // just substitute into the pattern and create a new pack expansion
6406 // type.
6407 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6408 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6409 if (U.isNull())
6410 return true;
6411
6412 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6413 Exceptions.push_back(Elt: U);
6414 continue;
6415 }
6416
6417 // Substitute into the pack expansion pattern for each slice of the
6418 // pack.
6419 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6420 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6421
6422 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6423 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6424 return true;
6425
6426 Exceptions.push_back(Elt: U);
6427 }
6428 } else {
6429 QualType U = getDerived().TransformType(T);
6430 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6431 return true;
6432 if (T != U)
6433 Changed = true;
6434
6435 Exceptions.push_back(Elt: U);
6436 }
6437 }
6438
6439 ESI.Exceptions = Exceptions;
6440 if (ESI.Exceptions.empty())
6441 ESI.Type = EST_DynamicNone;
6442 return false;
6443}
6444
6445template<typename Derived>
6446QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6447 TypeLocBuilder &TLB,
6448 FunctionNoProtoTypeLoc TL) {
6449 const FunctionNoProtoType *T = TL.getTypePtr();
6450 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6451 if (ResultType.isNull())
6452 return QualType();
6453
6454 QualType Result = TL.getType();
6455 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6456 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6457
6458 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6459 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6460 NewTL.setLParenLoc(TL.getLParenLoc());
6461 NewTL.setRParenLoc(TL.getRParenLoc());
6462 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6463
6464 return Result;
6465}
6466
6467template <typename Derived>
6468QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6469 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6470 const UnresolvedUsingType *T = TL.getTypePtr();
6471 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6472 if (!D)
6473 return QualType();
6474
6475 QualType Result = TL.getType();
6476 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6477 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6478 if (Result.isNull())
6479 return QualType();
6480 }
6481
6482 // We might get an arbitrary type spec type back. We should at
6483 // least always get a type spec type, though.
6484 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(T: Result);
6485 NewTL.setNameLoc(TL.getNameLoc());
6486
6487 return Result;
6488}
6489
6490template <typename Derived>
6491QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6492 UsingTypeLoc TL) {
6493 const UsingType *T = TL.getTypePtr();
6494
6495 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6496 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6497 if (!Found)
6498 return QualType();
6499
6500 QualType Underlying = getDerived().TransformType(T->desugar());
6501 if (Underlying.isNull())
6502 return QualType();
6503
6504 QualType Result = TL.getType();
6505 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6506 Underlying != T->getUnderlyingType()) {
6507 Result = getDerived().RebuildUsingType(Found, Underlying);
6508 if (Result.isNull())
6509 return QualType();
6510 }
6511
6512 TLB.pushTypeSpec(T: Result).setNameLoc(TL.getNameLoc());
6513 return Result;
6514}
6515
6516template<typename Derived>
6517QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6518 TypedefTypeLoc TL) {
6519 const TypedefType *T = TL.getTypePtr();
6520 TypedefNameDecl *Typedef
6521 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6522 T->getDecl()));
6523 if (!Typedef)
6524 return QualType();
6525
6526 QualType Result = TL.getType();
6527 if (getDerived().AlwaysRebuild() ||
6528 Typedef != T->getDecl()) {
6529 Result = getDerived().RebuildTypedefType(Typedef);
6530 if (Result.isNull())
6531 return QualType();
6532 }
6533
6534 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(T: Result);
6535 NewTL.setNameLoc(TL.getNameLoc());
6536
6537 return Result;
6538}
6539
6540template<typename Derived>
6541QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6542 TypeOfExprTypeLoc TL) {
6543 // typeof expressions are not potentially evaluated contexts
6544 EnterExpressionEvaluationContext Unevaluated(
6545 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6546 Sema::ReuseLambdaContextDecl);
6547
6548 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6549 if (E.isInvalid())
6550 return QualType();
6551
6552 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
6553 if (E.isInvalid())
6554 return QualType();
6555
6556 QualType Result = TL.getType();
6557 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6558 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6559 Result =
6560 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6561 if (Result.isNull())
6562 return QualType();
6563 }
6564
6565 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
6566 NewTL.setTypeofLoc(TL.getTypeofLoc());
6567 NewTL.setLParenLoc(TL.getLParenLoc());
6568 NewTL.setRParenLoc(TL.getRParenLoc());
6569
6570 return Result;
6571}
6572
6573template<typename Derived>
6574QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6575 TypeOfTypeLoc TL) {
6576 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6577 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6578 if (!New_Under_TI)
6579 return QualType();
6580
6581 QualType Result = TL.getType();
6582 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6583 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6584 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6585 if (Result.isNull())
6586 return QualType();
6587 }
6588
6589 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
6590 NewTL.setTypeofLoc(TL.getTypeofLoc());
6591 NewTL.setLParenLoc(TL.getLParenLoc());
6592 NewTL.setRParenLoc(TL.getRParenLoc());
6593 NewTL.setUnmodifiedTInfo(New_Under_TI);
6594
6595 return Result;
6596}
6597
6598template<typename Derived>
6599QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6600 DecltypeTypeLoc TL) {
6601 const DecltypeType *T = TL.getTypePtr();
6602
6603 // decltype expressions are not potentially evaluated contexts
6604 EnterExpressionEvaluationContext Unevaluated(
6605 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6606 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6607
6608 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6609 if (E.isInvalid())
6610 return QualType();
6611
6612 E = getSema().ActOnDecltypeExpression(E.get());
6613 if (E.isInvalid())
6614 return QualType();
6615
6616 QualType Result = TL.getType();
6617 if (getDerived().AlwaysRebuild() ||
6618 E.get() != T->getUnderlyingExpr()) {
6619 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6620 if (Result.isNull())
6621 return QualType();
6622 }
6623 else E.get();
6624
6625 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
6626 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6627 NewTL.setRParenLoc(TL.getRParenLoc());
6628 return Result;
6629}
6630
6631template <typename Derived>
6632QualType
6633TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6634 PackIndexingTypeLoc TL) {
6635 // Transform the index
6636 ExprResult IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6637 if (IndexExpr.isInvalid())
6638 return QualType();
6639 QualType Pattern = TL.getPattern();
6640
6641 const PackIndexingType *PIT = TL.getTypePtr();
6642 SmallVector<QualType, 5> SubtitutedTypes;
6643 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6644
6645 bool NotYetExpanded = Types.empty();
6646 bool FullySubstituted = true;
6647
6648 if (Types.empty())
6649 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6650
6651 for (const QualType &T : Types) {
6652 if (!T->containsUnexpandedParameterPack()) {
6653 QualType Transformed = getDerived().TransformType(T);
6654 if (Transformed.isNull())
6655 return QualType();
6656 SubtitutedTypes.push_back(Elt: Transformed);
6657 continue;
6658 }
6659
6660 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6661 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6662 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6663 // Determine whether the set of unexpanded parameter packs can and should
6664 // be expanded.
6665 bool ShouldExpand = true;
6666 bool RetainExpansion = false;
6667 std::optional<unsigned> OrigNumExpansions;
6668 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6669 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6670 Unexpanded, ShouldExpand,
6671 RetainExpansion, NumExpansions))
6672 return QualType();
6673 if (!ShouldExpand) {
6674 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6675 // FIXME: should we keep TypeLoc for individual expansions in
6676 // PackIndexingTypeLoc?
6677 TypeSourceInfo *TI =
6678 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
6679 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6680 if (Pack.isNull())
6681 return QualType();
6682 if (NotYetExpanded) {
6683 FullySubstituted = false;
6684 QualType Out = getDerived().RebuildPackIndexingType(
6685 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6686 FullySubstituted);
6687 if (Out.isNull())
6688 return QualType();
6689
6690 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
6691 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6692 return Out;
6693 }
6694 SubtitutedTypes.push_back(Elt: Pack);
6695 continue;
6696 }
6697 for (unsigned I = 0; I != *NumExpansions; ++I) {
6698 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6699 QualType Out = getDerived().TransformType(T);
6700 if (Out.isNull())
6701 return QualType();
6702 SubtitutedTypes.push_back(Elt: Out);
6703 }
6704 // If we're supposed to retain a pack expansion, do so by temporarily
6705 // forgetting the partially-substituted parameter pack.
6706 if (RetainExpansion) {
6707 FullySubstituted = false;
6708 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6709 QualType Out = getDerived().TransformType(T);
6710 if (Out.isNull())
6711 return QualType();
6712 SubtitutedTypes.push_back(Elt: Out);
6713 }
6714 }
6715
6716 // A pack indexing type can appear in a larger pack expansion,
6717 // e.g. `Pack...[pack_of_indexes]...`
6718 // so we need to temporarily disable substitution of pack elements
6719 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6720 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6721
6722 QualType Out = getDerived().RebuildPackIndexingType(
6723 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6724 FullySubstituted, SubtitutedTypes);
6725 if (Out.isNull())
6726 return Out;
6727
6728 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
6729 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6730 return Out;
6731}
6732
6733template<typename Derived>
6734QualType TreeTransform<Derived>::TransformUnaryTransformType(
6735 TypeLocBuilder &TLB,
6736 UnaryTransformTypeLoc TL) {
6737 QualType Result = TL.getType();
6738 if (Result->isDependentType()) {
6739 const UnaryTransformType *T = TL.getTypePtr();
6740
6741 TypeSourceInfo *NewBaseTSI =
6742 getDerived().TransformType(TL.getUnderlyingTInfo());
6743 if (!NewBaseTSI)
6744 return QualType();
6745 QualType NewBase = NewBaseTSI->getType();
6746
6747 Result = getDerived().RebuildUnaryTransformType(NewBase,
6748 T->getUTTKind(),
6749 TL.getKWLoc());
6750 if (Result.isNull())
6751 return QualType();
6752 }
6753
6754 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
6755 NewTL.setKWLoc(TL.getKWLoc());
6756 NewTL.setParensRange(TL.getParensRange());
6757 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6758 return Result;
6759}
6760
6761template<typename Derived>
6762QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6763 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6764 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6765
6766 CXXScopeSpec SS;
6767 TemplateName TemplateName = getDerived().TransformTemplateName(
6768 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6769 if (TemplateName.isNull())
6770 return QualType();
6771
6772 QualType OldDeduced = T->getDeducedType();
6773 QualType NewDeduced;
6774 if (!OldDeduced.isNull()) {
6775 NewDeduced = getDerived().TransformType(OldDeduced);
6776 if (NewDeduced.isNull())
6777 return QualType();
6778 }
6779
6780 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6781 TemplateName, NewDeduced);
6782 if (Result.isNull())
6783 return QualType();
6784
6785 DeducedTemplateSpecializationTypeLoc NewTL =
6786 TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
6787 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6788
6789 return Result;
6790}
6791
6792template<typename Derived>
6793QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6794 RecordTypeLoc TL) {
6795 const RecordType *T = TL.getTypePtr();
6796 RecordDecl *Record
6797 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6798 T->getDecl()));
6799 if (!Record)
6800 return QualType();
6801
6802 QualType Result = TL.getType();
6803 if (getDerived().AlwaysRebuild() ||
6804 Record != T->getDecl()) {
6805 Result = getDerived().RebuildRecordType(Record);
6806 if (Result.isNull())
6807 return QualType();
6808 }
6809
6810 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(T: Result);
6811 NewTL.setNameLoc(TL.getNameLoc());
6812
6813 return Result;
6814}
6815
6816template<typename Derived>
6817QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6818 EnumTypeLoc TL) {
6819 const EnumType *T = TL.getTypePtr();
6820 EnumDecl *Enum
6821 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6822 T->getDecl()));
6823 if (!Enum)
6824 return QualType();
6825
6826 QualType Result = TL.getType();
6827 if (getDerived().AlwaysRebuild() ||
6828 Enum != T->getDecl()) {
6829 Result = getDerived().RebuildEnumType(Enum);
6830 if (Result.isNull())
6831 return QualType();
6832 }
6833
6834 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(T: Result);
6835 NewTL.setNameLoc(TL.getNameLoc());
6836
6837 return Result;
6838}
6839
6840template<typename Derived>
6841QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6842 TypeLocBuilder &TLB,
6843 InjectedClassNameTypeLoc TL) {
6844 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6845 TL.getTypePtr()->getDecl());
6846 if (!D) return QualType();
6847
6848 QualType T = SemaRef.Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: D));
6849 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6850 return T;
6851}
6852
6853template<typename Derived>
6854QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6855 TypeLocBuilder &TLB,
6856 TemplateTypeParmTypeLoc TL) {
6857 return getDerived().TransformTemplateTypeParmType(
6858 TLB, TL,
6859 /*SuppressObjCLifetime=*/false);
6860}
6861
6862template <typename Derived>
6863QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6864 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6865 return TransformTypeSpecType(TLB, T: TL);
6866}
6867
6868template<typename Derived>
6869QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6870 TypeLocBuilder &TLB,
6871 SubstTemplateTypeParmTypeLoc TL) {
6872 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6873
6874 Decl *NewReplaced =
6875 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6876
6877 // Substitute into the replacement type, which itself might involve something
6878 // that needs to be transformed. This only tends to occur with default
6879 // template arguments of template template parameters.
6880 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6881 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6882 if (Replacement.isNull())
6883 return QualType();
6884
6885 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6886 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex());
6887
6888 // Propagate type-source information.
6889 SubstTemplateTypeParmTypeLoc NewTL
6890 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
6891 NewTL.setNameLoc(TL.getNameLoc());
6892 return Result;
6893
6894}
6895
6896template<typename Derived>
6897QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6898 TypeLocBuilder &TLB,
6899 SubstTemplateTypeParmPackTypeLoc TL) {
6900 return getDerived().TransformSubstTemplateTypeParmPackType(
6901 TLB, TL, /*SuppressObjCLifetime=*/false);
6902}
6903
6904template <typename Derived>
6905QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6906 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6907 return TransformTypeSpecType(TLB, T: TL);
6908}
6909
6910template<typename Derived>
6911QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6912 TypeLocBuilder &TLB,
6913 TemplateSpecializationTypeLoc TL) {
6914 const TemplateSpecializationType *T = TL.getTypePtr();
6915
6916 // The nested-name-specifier never matters in a TemplateSpecializationType,
6917 // because we can't have a dependent nested-name-specifier anyway.
6918 CXXScopeSpec SS;
6919 TemplateName Template
6920 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6921 TL.getTemplateNameLoc());
6922 if (Template.isNull())
6923 return QualType();
6924
6925 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6926}
6927
6928template<typename Derived>
6929QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6930 AtomicTypeLoc TL) {
6931 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6932 if (ValueType.isNull())
6933 return QualType();
6934
6935 QualType Result = TL.getType();
6936 if (getDerived().AlwaysRebuild() ||
6937 ValueType != TL.getValueLoc().getType()) {
6938 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6939 if (Result.isNull())
6940 return QualType();
6941 }
6942
6943 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
6944 NewTL.setKWLoc(TL.getKWLoc());
6945 NewTL.setLParenLoc(TL.getLParenLoc());
6946 NewTL.setRParenLoc(TL.getRParenLoc());
6947
6948 return Result;
6949}
6950
6951template <typename Derived>
6952QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6953 PipeTypeLoc TL) {
6954 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6955 if (ValueType.isNull())
6956 return QualType();
6957
6958 QualType Result = TL.getType();
6959 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6960 const PipeType *PT = Result->castAs<PipeType>();
6961 bool isReadPipe = PT->isReadOnly();
6962 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6963 if (Result.isNull())
6964 return QualType();
6965 }
6966
6967 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
6968 NewTL.setKWLoc(TL.getKWLoc());
6969
6970 return Result;
6971}
6972
6973template <typename Derived>
6974QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6975 BitIntTypeLoc TL) {
6976 const BitIntType *EIT = TL.getTypePtr();
6977 QualType Result = TL.getType();
6978
6979 if (getDerived().AlwaysRebuild()) {
6980 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6981 EIT->getNumBits(), TL.getNameLoc());
6982 if (Result.isNull())
6983 return QualType();
6984 }
6985
6986 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
6987 NewTL.setNameLoc(TL.getNameLoc());
6988 return Result;
6989}
6990
6991template <typename Derived>
6992QualType TreeTransform<Derived>::TransformDependentBitIntType(
6993 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6994 const DependentBitIntType *EIT = TL.getTypePtr();
6995
6996 EnterExpressionEvaluationContext Unevaluated(
6997 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6998 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6999 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7000
7001 if (BitsExpr.isInvalid())
7002 return QualType();
7003
7004 QualType Result = TL.getType();
7005
7006 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7007 Result = getDerived().RebuildDependentBitIntType(
7008 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7009
7010 if (Result.isNull())
7011 return QualType();
7012 }
7013
7014 if (isa<DependentBitIntType>(Val: Result)) {
7015 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7016 NewTL.setNameLoc(TL.getNameLoc());
7017 } else {
7018 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7019 NewTL.setNameLoc(TL.getNameLoc());
7020 }
7021 return Result;
7022}
7023
7024 /// Simple iterator that traverses the template arguments in a
7025 /// container that provides a \c getArgLoc() member function.
7026 ///
7027 /// This iterator is intended to be used with the iterator form of
7028 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7029 template<typename ArgLocContainer>
7030 class TemplateArgumentLocContainerIterator {
7031 ArgLocContainer *Container;
7032 unsigned Index;
7033
7034 public:
7035 typedef TemplateArgumentLoc value_type;
7036 typedef TemplateArgumentLoc reference;
7037 typedef int difference_type;
7038 typedef std::input_iterator_tag iterator_category;
7039
7040 class pointer {
7041 TemplateArgumentLoc Arg;
7042
7043 public:
7044 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7045
7046 const TemplateArgumentLoc *operator->() const {
7047 return &Arg;
7048 }
7049 };
7050
7051
7052 TemplateArgumentLocContainerIterator() {}
7053
7054 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7055 unsigned Index)
7056 : Container(&Container), Index(Index) { }
7057
7058 TemplateArgumentLocContainerIterator &operator++() {
7059 ++Index;
7060 return *this;
7061 }
7062
7063 TemplateArgumentLocContainerIterator operator++(int) {
7064 TemplateArgumentLocContainerIterator Old(*this);
7065 ++(*this);
7066 return Old;
7067 }
7068
7069 TemplateArgumentLoc operator*() const {
7070 return Container->getArgLoc(Index);
7071 }
7072
7073 pointer operator->() const {
7074 return pointer(Container->getArgLoc(Index));
7075 }
7076
7077 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7078 const TemplateArgumentLocContainerIterator &Y) {
7079 return X.Container == Y.Container && X.Index == Y.Index;
7080 }
7081
7082 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7083 const TemplateArgumentLocContainerIterator &Y) {
7084 return !(X == Y);
7085 }
7086 };
7087
7088template<typename Derived>
7089QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7090 AutoTypeLoc TL) {
7091 const AutoType *T = TL.getTypePtr();
7092 QualType OldDeduced = T->getDeducedType();
7093 QualType NewDeduced;
7094 if (!OldDeduced.isNull()) {
7095 NewDeduced = getDerived().TransformType(OldDeduced);
7096 if (NewDeduced.isNull())
7097 return QualType();
7098 }
7099
7100 ConceptDecl *NewCD = nullptr;
7101 TemplateArgumentListInfo NewTemplateArgs;
7102 NestedNameSpecifierLoc NewNestedNameSpec;
7103 if (T->isConstrained()) {
7104 assert(TL.getConceptReference());
7105 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7106 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7107
7108 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7109 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7110 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7111 if (getDerived().TransformTemplateArguments(
7112 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7113 NewTemplateArgs))
7114 return QualType();
7115
7116 if (TL.getNestedNameSpecifierLoc()) {
7117 NewNestedNameSpec
7118 = getDerived().TransformNestedNameSpecifierLoc(
7119 TL.getNestedNameSpecifierLoc());
7120 if (!NewNestedNameSpec)
7121 return QualType();
7122 }
7123 }
7124
7125 QualType Result = TL.getType();
7126 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7127 T->isDependentType() || T->isConstrained()) {
7128 // FIXME: Maybe don't rebuild if all template arguments are the same.
7129 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7130 NewArgList.reserve(N: NewTemplateArgs.size());
7131 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7132 NewArgList.push_back(Elt: ArgLoc.getArgument());
7133 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7134 NewArgList);
7135 if (Result.isNull())
7136 return QualType();
7137 }
7138
7139 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7140 NewTL.setNameLoc(TL.getNameLoc());
7141 NewTL.setRParenLoc(TL.getRParenLoc());
7142 NewTL.setConceptReference(nullptr);
7143
7144 if (T->isConstrained()) {
7145 DeclarationNameInfo DNI = DeclarationNameInfo(
7146 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7147 TL.getConceptNameLoc(),
7148 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7149 auto *CR = ConceptReference::Create(
7150 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7151 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7152 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7153 NewTL.setConceptReference(CR);
7154 }
7155
7156 return Result;
7157}
7158
7159template <typename Derived>
7160QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7161 TypeLocBuilder &TLB,
7162 TemplateSpecializationTypeLoc TL,
7163 TemplateName Template) {
7164 TemplateArgumentListInfo NewTemplateArgs;
7165 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7166 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7167 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7168 ArgIterator;
7169 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7170 ArgIterator(TL, TL.getNumArgs()),
7171 NewTemplateArgs))
7172 return QualType();
7173
7174 // FIXME: maybe don't rebuild if all the template arguments are the same.
7175
7176 QualType Result =
7177 getDerived().RebuildTemplateSpecializationType(Template,
7178 TL.getTemplateNameLoc(),
7179 NewTemplateArgs);
7180
7181 if (!Result.isNull()) {
7182 // Specializations of template template parameters are represented as
7183 // TemplateSpecializationTypes, and substitution of type alias templates
7184 // within a dependent context can transform them into
7185 // DependentTemplateSpecializationTypes.
7186 if (isa<DependentTemplateSpecializationType>(Val: Result)) {
7187 DependentTemplateSpecializationTypeLoc NewTL
7188 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7189 NewTL.setElaboratedKeywordLoc(SourceLocation());
7190 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7191 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7192 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7193 NewTL.setLAngleLoc(TL.getLAngleLoc());
7194 NewTL.setRAngleLoc(TL.getRAngleLoc());
7195 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7196 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7197 return Result;
7198 }
7199
7200 TemplateSpecializationTypeLoc NewTL
7201 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7202 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7203 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7204 NewTL.setLAngleLoc(TL.getLAngleLoc());
7205 NewTL.setRAngleLoc(TL.getRAngleLoc());
7206 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7207 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7208 }
7209
7210 return Result;
7211}
7212
7213template <typename Derived>
7214QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7215 TypeLocBuilder &TLB,
7216 DependentTemplateSpecializationTypeLoc TL,
7217 TemplateName Template,
7218 CXXScopeSpec &SS) {
7219 TemplateArgumentListInfo NewTemplateArgs;
7220 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7221 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7222 typedef TemplateArgumentLocContainerIterator<
7223 DependentTemplateSpecializationTypeLoc> ArgIterator;
7224 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7225 ArgIterator(TL, TL.getNumArgs()),
7226 NewTemplateArgs))
7227 return QualType();
7228
7229 // FIXME: maybe don't rebuild if all the template arguments are the same.
7230
7231 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7232 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7233 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7234 DTN->getIdentifier(), NewTemplateArgs.arguments());
7235
7236 DependentTemplateSpecializationTypeLoc NewTL
7237 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7238 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7239 NewTL.setQualifierLoc(SS.getWithLocInContext(Context&: SemaRef.Context));
7240 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7241 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7242 NewTL.setLAngleLoc(TL.getLAngleLoc());
7243 NewTL.setRAngleLoc(TL.getRAngleLoc());
7244 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7245 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7246 return Result;
7247 }
7248
7249 QualType Result
7250 = getDerived().RebuildTemplateSpecializationType(Template,
7251 TL.getTemplateNameLoc(),
7252 NewTemplateArgs);
7253
7254 if (!Result.isNull()) {
7255 /// FIXME: Wrap this in an elaborated-type-specifier?
7256 TemplateSpecializationTypeLoc NewTL
7257 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7258 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7259 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7260 NewTL.setLAngleLoc(TL.getLAngleLoc());
7261 NewTL.setRAngleLoc(TL.getRAngleLoc());
7262 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7263 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7264 }
7265
7266 return Result;
7267}
7268
7269template<typename Derived>
7270QualType
7271TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7272 ElaboratedTypeLoc TL) {
7273 const ElaboratedType *T = TL.getTypePtr();
7274
7275 NestedNameSpecifierLoc QualifierLoc;
7276 // NOTE: the qualifier in an ElaboratedType is optional.
7277 if (TL.getQualifierLoc()) {
7278 QualifierLoc
7279 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7280 if (!QualifierLoc)
7281 return QualType();
7282 }
7283
7284 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7285 if (NamedT.isNull())
7286 return QualType();
7287
7288 // C++0x [dcl.type.elab]p2:
7289 // If the identifier resolves to a typedef-name or the simple-template-id
7290 // resolves to an alias template specialization, the
7291 // elaborated-type-specifier is ill-formed.
7292 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7293 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7294 if (const TemplateSpecializationType *TST =
7295 NamedT->getAs<TemplateSpecializationType>()) {
7296 TemplateName Template = TST->getTemplateName();
7297 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7298 Val: Template.getAsTemplateDecl())) {
7299 SemaRef.Diag(Loc: TL.getNamedTypeLoc().getBeginLoc(),
7300 DiagID: diag::err_tag_reference_non_tag)
7301 << TAT << Sema::NTK_TypeAliasTemplate
7302 << llvm::to_underlying(
7303 E: ElaboratedType::getTagTypeKindForKeyword(Keyword: T->getKeyword()));
7304 SemaRef.Diag(Loc: TAT->getLocation(), DiagID: diag::note_declared_at);
7305 }
7306 }
7307 }
7308
7309 QualType Result = TL.getType();
7310 if (getDerived().AlwaysRebuild() ||
7311 QualifierLoc != TL.getQualifierLoc() ||
7312 NamedT != T->getNamedType()) {
7313 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7314 T->getKeyword(),
7315 QualifierLoc, NamedT);
7316 if (Result.isNull())
7317 return QualType();
7318 }
7319
7320 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7321 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7322 NewTL.setQualifierLoc(QualifierLoc);
7323 return Result;
7324}
7325
7326template <typename Derived>
7327template <typename Fn>
7328QualType TreeTransform<Derived>::TransformAttributedType(
7329 TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
7330 const AttributedType *oldType = TL.getTypePtr();
7331 QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc());
7332 if (modifiedType.isNull())
7333 return QualType();
7334
7335 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7336 const Attr *oldAttr = TL.getAttr();
7337 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7338 if (oldAttr && !newAttr)
7339 return QualType();
7340
7341 QualType result = TL.getType();
7342
7343 // FIXME: dependent operand expressions?
7344 if (getDerived().AlwaysRebuild() ||
7345 modifiedType != oldType->getModifiedType()) {
7346 TypeLocBuilder AuxiliaryTLB;
7347 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7348 QualType equivalentType =
7349 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7350 if (equivalentType.isNull())
7351 return QualType();
7352
7353 // Check whether we can add nullability; it is only represented as
7354 // type sugar, and therefore cannot be diagnosed in any other way.
7355 if (auto nullability = oldType->getImmediateNullability()) {
7356 if (!modifiedType->canHaveNullability()) {
7357 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7358 : TL.getModifiedLoc().getBeginLoc()),
7359 DiagID: diag::err_nullability_nonpointer)
7360 << DiagNullabilityKind(*nullability, false) << modifiedType;
7361 return QualType();
7362 }
7363 }
7364
7365 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7366 modifiedType,
7367 equivalentType);
7368 }
7369
7370 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7371 newTL.setAttr(newAttr);
7372 return result;
7373}
7374
7375template <typename Derived>
7376QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7377 AttributedTypeLoc TL) {
7378 return getDerived().TransformAttributedType(
7379 TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7380 return getDerived().TransformType(TLB, ModifiedLoc);
7381 });
7382}
7383
7384template <typename Derived>
7385QualType TreeTransform<Derived>::TransformCountAttributedType(
7386 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7387 const CountAttributedType *OldTy = TL.getTypePtr();
7388 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7389 if (InnerTy.isNull())
7390 return QualType();
7391
7392 Expr *OldCount = TL.getCountExpr();
7393 Expr *NewCount = nullptr;
7394 if (OldCount) {
7395 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7396 if (CountResult.isInvalid())
7397 return QualType();
7398 NewCount = CountResult.get();
7399 }
7400
7401 QualType Result = TL.getType();
7402 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7403 OldCount != NewCount) {
7404 // Currently, CountAttributedType can only wrap incomplete array types.
7405 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7406 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7407 }
7408
7409 TLB.push<CountAttributedTypeLoc>(T: Result);
7410 return Result;
7411}
7412
7413template <typename Derived>
7414QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7415 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7416 // The BTFTagAttributedType is available for C only.
7417 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7418}
7419
7420template<typename Derived>
7421QualType
7422TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7423 ParenTypeLoc TL) {
7424 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7425 if (Inner.isNull())
7426 return QualType();
7427
7428 QualType Result = TL.getType();
7429 if (getDerived().AlwaysRebuild() ||
7430 Inner != TL.getInnerLoc().getType()) {
7431 Result = getDerived().RebuildParenType(Inner);
7432 if (Result.isNull())
7433 return QualType();
7434 }
7435
7436 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7437 NewTL.setLParenLoc(TL.getLParenLoc());
7438 NewTL.setRParenLoc(TL.getRParenLoc());
7439 return Result;
7440}
7441
7442template <typename Derived>
7443QualType
7444TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7445 MacroQualifiedTypeLoc TL) {
7446 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7447 if (Inner.isNull())
7448 return QualType();
7449
7450 QualType Result = TL.getType();
7451 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7452 Result =
7453 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7454 if (Result.isNull())
7455 return QualType();
7456 }
7457
7458 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7459 NewTL.setExpansionLoc(TL.getExpansionLoc());
7460 return Result;
7461}
7462
7463template<typename Derived>
7464QualType TreeTransform<Derived>::TransformDependentNameType(
7465 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7466 return TransformDependentNameType(TLB, TL, false);
7467}
7468
7469template<typename Derived>
7470QualType TreeTransform<Derived>::TransformDependentNameType(
7471 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7472 const DependentNameType *T = TL.getTypePtr();
7473
7474 NestedNameSpecifierLoc QualifierLoc
7475 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7476 if (!QualifierLoc)
7477 return QualType();
7478
7479 QualType Result
7480 = getDerived().RebuildDependentNameType(T->getKeyword(),
7481 TL.getElaboratedKeywordLoc(),
7482 QualifierLoc,
7483 T->getIdentifier(),
7484 TL.getNameLoc(),
7485 DeducedTSTContext);
7486 if (Result.isNull())
7487 return QualType();
7488
7489 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7490 QualType NamedT = ElabT->getNamedType();
7491 TLB.pushTypeSpec(T: NamedT).setNameLoc(TL.getNameLoc());
7492
7493 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7494 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7495 NewTL.setQualifierLoc(QualifierLoc);
7496 } else {
7497 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7498 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7499 NewTL.setQualifierLoc(QualifierLoc);
7500 NewTL.setNameLoc(TL.getNameLoc());
7501 }
7502 return Result;
7503}
7504
7505template<typename Derived>
7506QualType TreeTransform<Derived>::
7507 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7508 DependentTemplateSpecializationTypeLoc TL) {
7509 NestedNameSpecifierLoc QualifierLoc;
7510 if (TL.getQualifierLoc()) {
7511 QualifierLoc
7512 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7513 if (!QualifierLoc)
7514 return QualType();
7515 }
7516
7517 return getDerived()
7518 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7519}
7520
7521template<typename Derived>
7522QualType TreeTransform<Derived>::
7523TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7524 DependentTemplateSpecializationTypeLoc TL,
7525 NestedNameSpecifierLoc QualifierLoc) {
7526 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7527
7528 TemplateArgumentListInfo NewTemplateArgs;
7529 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7530 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7531
7532 typedef TemplateArgumentLocContainerIterator<
7533 DependentTemplateSpecializationTypeLoc> ArgIterator;
7534 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7535 ArgIterator(TL, TL.getNumArgs()),
7536 NewTemplateArgs))
7537 return QualType();
7538
7539 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7540 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7541 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7542 /*AllowInjectedClassName*/ false);
7543 if (Result.isNull())
7544 return QualType();
7545
7546 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Val&: Result)) {
7547 QualType NamedT = ElabT->getNamedType();
7548
7549 // Copy information relevant to the template specialization.
7550 TemplateSpecializationTypeLoc NamedTL
7551 = TLB.push<TemplateSpecializationTypeLoc>(T: NamedT);
7552 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7553 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7554 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7555 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7556 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7557 NamedTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7558
7559 // Copy information relevant to the elaborated type.
7560 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7561 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7562 NewTL.setQualifierLoc(QualifierLoc);
7563 } else if (isa<DependentTemplateSpecializationType>(Val: Result)) {
7564 DependentTemplateSpecializationTypeLoc SpecTL
7565 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7566 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7567 SpecTL.setQualifierLoc(QualifierLoc);
7568 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7569 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7570 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7571 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7572 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7573 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7574 } else {
7575 TemplateSpecializationTypeLoc SpecTL
7576 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7577 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7578 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7579 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7580 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7581 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7582 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7583 }
7584 return Result;
7585}
7586
7587template<typename Derived>
7588QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7589 PackExpansionTypeLoc TL) {
7590 QualType Pattern
7591 = getDerived().TransformType(TLB, TL.getPatternLoc());
7592 if (Pattern.isNull())
7593 return QualType();
7594
7595 QualType Result = TL.getType();
7596 if (getDerived().AlwaysRebuild() ||
7597 Pattern != TL.getPatternLoc().getType()) {
7598 Result = getDerived().RebuildPackExpansionType(Pattern,
7599 TL.getPatternLoc().getSourceRange(),
7600 TL.getEllipsisLoc(),
7601 TL.getTypePtr()->getNumExpansions());
7602 if (Result.isNull())
7603 return QualType();
7604 }
7605
7606 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7607 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7608 return Result;
7609}
7610
7611template<typename Derived>
7612QualType
7613TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7614 ObjCInterfaceTypeLoc TL) {
7615 // ObjCInterfaceType is never dependent.
7616 TLB.pushFullCopy(L: TL);
7617 return TL.getType();
7618}
7619
7620template<typename Derived>
7621QualType
7622TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7623 ObjCTypeParamTypeLoc TL) {
7624 const ObjCTypeParamType *T = TL.getTypePtr();
7625 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7626 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7627 if (!OTP)
7628 return QualType();
7629
7630 QualType Result = TL.getType();
7631 if (getDerived().AlwaysRebuild() ||
7632 OTP != T->getDecl()) {
7633 Result = getDerived().RebuildObjCTypeParamType(
7634 OTP, TL.getProtocolLAngleLoc(),
7635 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7636 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7637 if (Result.isNull())
7638 return QualType();
7639 }
7640
7641 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7642 if (TL.getNumProtocols()) {
7643 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7644 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7645 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7646 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7647 }
7648 return Result;
7649}
7650
7651template<typename Derived>
7652QualType
7653TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7654 ObjCObjectTypeLoc TL) {
7655 // Transform base type.
7656 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7657 if (BaseType.isNull())
7658 return QualType();
7659
7660 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7661
7662 // Transform type arguments.
7663 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7664 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7665 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7666 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7667 QualType TypeArg = TypeArgInfo->getType();
7668 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7669 AnyChanged = true;
7670
7671 // We have a pack expansion. Instantiate it.
7672 const auto *PackExpansion = PackExpansionLoc.getType()
7673 ->castAs<PackExpansionType>();
7674 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7675 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
7676 Unexpanded);
7677 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7678
7679 // Determine whether the set of unexpanded parameter packs can
7680 // and should be expanded.
7681 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7682 bool Expand = false;
7683 bool RetainExpansion = false;
7684 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7685 if (getDerived().TryExpandParameterPacks(
7686 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7687 Unexpanded, Expand, RetainExpansion, NumExpansions))
7688 return QualType();
7689
7690 if (!Expand) {
7691 // We can't expand this pack expansion into separate arguments yet;
7692 // just substitute into the pattern and create a new pack expansion
7693 // type.
7694 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7695
7696 TypeLocBuilder TypeArgBuilder;
7697 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7698 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7699 PatternLoc);
7700 if (NewPatternType.isNull())
7701 return QualType();
7702
7703 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7704 Pattern: NewPatternType, NumExpansions);
7705 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
7706 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7707 NewTypeArgInfos.push_back(
7708 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
7709 continue;
7710 }
7711
7712 // Substitute into the pack expansion pattern for each slice of the
7713 // pack.
7714 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7715 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7716
7717 TypeLocBuilder TypeArgBuilder;
7718 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7719
7720 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7721 PatternLoc);
7722 if (NewTypeArg.isNull())
7723 return QualType();
7724
7725 NewTypeArgInfos.push_back(
7726 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
7727 }
7728
7729 continue;
7730 }
7731
7732 TypeLocBuilder TypeArgBuilder;
7733 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
7734 QualType NewTypeArg =
7735 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7736 if (NewTypeArg.isNull())
7737 return QualType();
7738
7739 // If nothing changed, just keep the old TypeSourceInfo.
7740 if (NewTypeArg == TypeArg) {
7741 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
7742 continue;
7743 }
7744
7745 NewTypeArgInfos.push_back(
7746 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
7747 AnyChanged = true;
7748 }
7749
7750 QualType Result = TL.getType();
7751 if (getDerived().AlwaysRebuild() || AnyChanged) {
7752 // Rebuild the type.
7753 Result = getDerived().RebuildObjCObjectType(
7754 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7755 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7756 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7757 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7758
7759 if (Result.isNull())
7760 return QualType();
7761 }
7762
7763 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
7764 NewT.setHasBaseTypeAsWritten(true);
7765 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7766 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7767 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
7768 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7769 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7770 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7771 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7772 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7773 return Result;
7774}
7775
7776template<typename Derived>
7777QualType
7778TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7779 ObjCObjectPointerTypeLoc TL) {
7780 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7781 if (PointeeType.isNull())
7782 return QualType();
7783
7784 QualType Result = TL.getType();
7785 if (getDerived().AlwaysRebuild() ||
7786 PointeeType != TL.getPointeeLoc().getType()) {
7787 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7788 TL.getStarLoc());
7789 if (Result.isNull())
7790 return QualType();
7791 }
7792
7793 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
7794 NewT.setStarLoc(TL.getStarLoc());
7795 return Result;
7796}
7797
7798//===----------------------------------------------------------------------===//
7799// Statement transformation
7800//===----------------------------------------------------------------------===//
7801template<typename Derived>
7802StmtResult
7803TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7804 return S;
7805}
7806
7807template<typename Derived>
7808StmtResult
7809TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7810 return getDerived().TransformCompoundStmt(S, false);
7811}
7812
7813template<typename Derived>
7814StmtResult
7815TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7816 bool IsStmtExpr) {
7817 Sema::CompoundScopeRAII CompoundScope(getSema());
7818 Sema::FPFeaturesStateRAII FPSave(getSema());
7819 if (S->hasStoredFPFeatures())
7820 getSema().resetFPOptions(
7821 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7822
7823 const Stmt *ExprResult = S->getStmtExprResult();
7824 bool SubStmtInvalid = false;
7825 bool SubStmtChanged = false;
7826 SmallVector<Stmt*, 8> Statements;
7827 for (auto *B : S->body()) {
7828 StmtResult Result = getDerived().TransformStmt(
7829 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7830
7831 if (Result.isInvalid()) {
7832 // Immediately fail if this was a DeclStmt, since it's very
7833 // likely that this will cause problems for future statements.
7834 if (isa<DeclStmt>(Val: B))
7835 return StmtError();
7836
7837 // Otherwise, just keep processing substatements and fail later.
7838 SubStmtInvalid = true;
7839 continue;
7840 }
7841
7842 SubStmtChanged = SubStmtChanged || Result.get() != B;
7843 Statements.push_back(Elt: Result.getAs<Stmt>());
7844 }
7845
7846 if (SubStmtInvalid)
7847 return StmtError();
7848
7849 if (!getDerived().AlwaysRebuild() &&
7850 !SubStmtChanged)
7851 return S;
7852
7853 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7854 Statements,
7855 S->getRBracLoc(),
7856 IsStmtExpr);
7857}
7858
7859template<typename Derived>
7860StmtResult
7861TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7862 ExprResult LHS, RHS;
7863 {
7864 EnterExpressionEvaluationContext Unevaluated(
7865 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7866
7867 // Transform the left-hand case value.
7868 LHS = getDerived().TransformExpr(S->getLHS());
7869 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
7870 if (LHS.isInvalid())
7871 return StmtError();
7872
7873 // Transform the right-hand case value (for the GNU case-range extension).
7874 RHS = getDerived().TransformExpr(S->getRHS());
7875 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
7876 if (RHS.isInvalid())
7877 return StmtError();
7878 }
7879
7880 // Build the case statement.
7881 // Case statements are always rebuilt so that they will attached to their
7882 // transformed switch statement.
7883 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7884 LHS.get(),
7885 S->getEllipsisLoc(),
7886 RHS.get(),
7887 S->getColonLoc());
7888 if (Case.isInvalid())
7889 return StmtError();
7890
7891 // Transform the statement following the case
7892 StmtResult SubStmt =
7893 getDerived().TransformStmt(S->getSubStmt());
7894 if (SubStmt.isInvalid())
7895 return StmtError();
7896
7897 // Attach the body to the case statement
7898 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7899}
7900
7901template <typename Derived>
7902StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7903 // Transform the statement following the default case
7904 StmtResult SubStmt =
7905 getDerived().TransformStmt(S->getSubStmt());
7906 if (SubStmt.isInvalid())
7907 return StmtError();
7908
7909 // Default statements are always rebuilt
7910 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7911 SubStmt.get());
7912}
7913
7914template<typename Derived>
7915StmtResult
7916TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7917 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7918 if (SubStmt.isInvalid())
7919 return StmtError();
7920
7921 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7922 S->getDecl());
7923 if (!LD)
7924 return StmtError();
7925
7926 // If we're transforming "in-place" (we're not creating new local
7927 // declarations), assume we're replacing the old label statement
7928 // and clear out the reference to it.
7929 if (LD == S->getDecl())
7930 S->getDecl()->setStmt(nullptr);
7931
7932 // FIXME: Pass the real colon location in.
7933 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7934 cast<LabelDecl>(Val: LD), SourceLocation(),
7935 SubStmt.get());
7936}
7937
7938template <typename Derived>
7939const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7940 if (!R)
7941 return R;
7942
7943 switch (R->getKind()) {
7944// Transform attributes by calling TransformXXXAttr.
7945#define ATTR(X) \
7946 case attr::X: \
7947 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7948#include "clang/Basic/AttrList.inc"
7949 }
7950 return R;
7951}
7952
7953template <typename Derived>
7954const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
7955 const Stmt *InstS,
7956 const Attr *R) {
7957 if (!R)
7958 return R;
7959
7960 switch (R->getKind()) {
7961// Transform attributes by calling TransformStmtXXXAttr.
7962#define ATTR(X) \
7963 case attr::X: \
7964 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7965#include "clang/Basic/AttrList.inc"
7966 }
7967 return TransformAttr(R);
7968}
7969
7970template <typename Derived>
7971StmtResult
7972TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7973 StmtDiscardKind SDK) {
7974 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7975 if (SubStmt.isInvalid())
7976 return StmtError();
7977
7978 bool AttrsChanged = false;
7979 SmallVector<const Attr *, 1> Attrs;
7980
7981 // Visit attributes and keep track if any are transformed.
7982 for (const auto *I : S->getAttrs()) {
7983 const Attr *R =
7984 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7985 AttrsChanged |= (I != R);
7986 if (R)
7987 Attrs.push_back(Elt: R);
7988 }
7989
7990 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7991 return S;
7992
7993 // If transforming the attributes failed for all of the attributes in the
7994 // statement, don't make an AttributedStmt without attributes.
7995 if (Attrs.empty())
7996 return SubStmt;
7997
7998 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7999 SubStmt.get());
8000}
8001
8002template<typename Derived>
8003StmtResult
8004TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8005 // Transform the initialization statement
8006 StmtResult Init = getDerived().TransformStmt(S->getInit());
8007 if (Init.isInvalid())
8008 return StmtError();
8009
8010 Sema::ConditionResult Cond;
8011 if (!S->isConsteval()) {
8012 // Transform the condition
8013 Cond = getDerived().TransformCondition(
8014 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8015 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8016 : Sema::ConditionKind::Boolean);
8017 if (Cond.isInvalid())
8018 return StmtError();
8019 }
8020
8021 // If this is a constexpr if, determine which arm we should instantiate.
8022 std::optional<bool> ConstexprConditionValue;
8023 if (S->isConstexpr())
8024 ConstexprConditionValue = Cond.getKnownValue();
8025
8026 // Transform the "then" branch.
8027 StmtResult Then;
8028 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8029 EnterExpressionEvaluationContext Ctx(
8030 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8031 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8032 S->isNonNegatedConsteval());
8033
8034 Then = getDerived().TransformStmt(S->getThen());
8035 if (Then.isInvalid())
8036 return StmtError();
8037 } else {
8038 // Discarded branch is replaced with empty CompoundStmt so we can keep
8039 // proper source location for start and end of original branch, so
8040 // subsequent transformations like CoverageMapping work properly
8041 Then = new (getSema().Context)
8042 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8043 }
8044
8045 // Transform the "else" branch.
8046 StmtResult Else;
8047 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8048 EnterExpressionEvaluationContext Ctx(
8049 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8050 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8051 S->isNegatedConsteval());
8052
8053 Else = getDerived().TransformStmt(S->getElse());
8054 if (Else.isInvalid())
8055 return StmtError();
8056 } else if (S->getElse() && ConstexprConditionValue &&
8057 *ConstexprConditionValue) {
8058 // Same thing here as with <then> branch, we are discarding it, we can't
8059 // replace it with NULL nor NullStmt as we need to keep for source location
8060 // range, for CoverageMapping
8061 Else = new (getSema().Context)
8062 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8063 }
8064
8065 if (!getDerived().AlwaysRebuild() &&
8066 Init.get() == S->getInit() &&
8067 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8068 Then.get() == S->getThen() &&
8069 Else.get() == S->getElse())
8070 return S;
8071
8072 return getDerived().RebuildIfStmt(
8073 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8074 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8075}
8076
8077template<typename Derived>
8078StmtResult
8079TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8080 // Transform the initialization statement
8081 StmtResult Init = getDerived().TransformStmt(S->getInit());
8082 if (Init.isInvalid())
8083 return StmtError();
8084
8085 // Transform the condition.
8086 Sema::ConditionResult Cond = getDerived().TransformCondition(
8087 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8088 Sema::ConditionKind::Switch);
8089 if (Cond.isInvalid())
8090 return StmtError();
8091
8092 // Rebuild the switch statement.
8093 StmtResult Switch =
8094 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8095 Init.get(), Cond, S->getRParenLoc());
8096 if (Switch.isInvalid())
8097 return StmtError();
8098
8099 // Transform the body of the switch statement.
8100 StmtResult Body = getDerived().TransformStmt(S->getBody());
8101 if (Body.isInvalid())
8102 return StmtError();
8103
8104 // Complete the switch statement.
8105 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8106 Body.get());
8107}
8108
8109template<typename Derived>
8110StmtResult
8111TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8112 // Transform the condition
8113 Sema::ConditionResult Cond = getDerived().TransformCondition(
8114 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8115 Sema::ConditionKind::Boolean);
8116 if (Cond.isInvalid())
8117 return StmtError();
8118
8119 // Transform the body
8120 StmtResult Body = getDerived().TransformStmt(S->getBody());
8121 if (Body.isInvalid())
8122 return StmtError();
8123
8124 if (!getDerived().AlwaysRebuild() &&
8125 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8126 Body.get() == S->getBody())
8127 return Owned(S);
8128
8129 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8130 Cond, S->getRParenLoc(), Body.get());
8131}
8132
8133template<typename Derived>
8134StmtResult
8135TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8136 // Transform the body
8137 StmtResult Body = getDerived().TransformStmt(S->getBody());
8138 if (Body.isInvalid())
8139 return StmtError();
8140
8141 // Transform the condition
8142 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8143 if (Cond.isInvalid())
8144 return StmtError();
8145
8146 if (!getDerived().AlwaysRebuild() &&
8147 Cond.get() == S->getCond() &&
8148 Body.get() == S->getBody())
8149 return S;
8150
8151 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8152 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8153 S->getRParenLoc());
8154}
8155
8156template<typename Derived>
8157StmtResult
8158TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8159 if (getSema().getLangOpts().OpenMP)
8160 getSema().OpenMP().startOpenMPLoop();
8161
8162 // Transform the initialization statement
8163 StmtResult Init = getDerived().TransformStmt(S->getInit());
8164 if (Init.isInvalid())
8165 return StmtError();
8166
8167 // In OpenMP loop region loop control variable must be captured and be
8168 // private. Perform analysis of first part (if any).
8169 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8170 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8171 Init.get());
8172
8173 // Transform the condition
8174 Sema::ConditionResult Cond = getDerived().TransformCondition(
8175 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8176 Sema::ConditionKind::Boolean);
8177 if (Cond.isInvalid())
8178 return StmtError();
8179
8180 // Transform the increment
8181 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8182 if (Inc.isInvalid())
8183 return StmtError();
8184
8185 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8186 if (S->getInc() && !FullInc.get())
8187 return StmtError();
8188
8189 // Transform the body
8190 StmtResult Body = getDerived().TransformStmt(S->getBody());
8191 if (Body.isInvalid())
8192 return StmtError();
8193
8194 if (!getDerived().AlwaysRebuild() &&
8195 Init.get() == S->getInit() &&
8196 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8197 Inc.get() == S->getInc() &&
8198 Body.get() == S->getBody())
8199 return S;
8200
8201 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8202 Init.get(), Cond, FullInc,
8203 S->getRParenLoc(), Body.get());
8204}
8205
8206template<typename Derived>
8207StmtResult
8208TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8209 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8210 S->getLabel());
8211 if (!LD)
8212 return StmtError();
8213
8214 // Goto statements must always be rebuilt, to resolve the label.
8215 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8216 cast<LabelDecl>(Val: LD));
8217}
8218
8219template<typename Derived>
8220StmtResult
8221TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8222 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8223 if (Target.isInvalid())
8224 return StmtError();
8225 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8226
8227 if (!getDerived().AlwaysRebuild() &&
8228 Target.get() == S->getTarget())
8229 return S;
8230
8231 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8232 Target.get());
8233}
8234
8235template<typename Derived>
8236StmtResult
8237TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8238 return S;
8239}
8240
8241template<typename Derived>
8242StmtResult
8243TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8244 return S;
8245}
8246
8247template<typename Derived>
8248StmtResult
8249TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8250 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8251 /*NotCopyInit*/false);
8252 if (Result.isInvalid())
8253 return StmtError();
8254
8255 // FIXME: We always rebuild the return statement because there is no way
8256 // to tell whether the return type of the function has changed.
8257 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8258}
8259
8260template<typename Derived>
8261StmtResult
8262TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8263 bool DeclChanged = false;
8264 SmallVector<Decl *, 4> Decls;
8265 for (auto *D : S->decls()) {
8266 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8267 if (!Transformed)
8268 return StmtError();
8269
8270 if (Transformed != D)
8271 DeclChanged = true;
8272
8273 Decls.push_back(Elt: Transformed);
8274 }
8275
8276 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8277 return S;
8278
8279 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8280}
8281
8282template<typename Derived>
8283StmtResult
8284TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8285
8286 SmallVector<Expr*, 8> Constraints;
8287 SmallVector<Expr*, 8> Exprs;
8288 SmallVector<IdentifierInfo *, 4> Names;
8289
8290 ExprResult AsmString;
8291 SmallVector<Expr*, 8> Clobbers;
8292
8293 bool ExprsChanged = false;
8294
8295 // Go through the outputs.
8296 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8297 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8298
8299 // No need to transform the constraint literal.
8300 Constraints.push_back(Elt: S->getOutputConstraintLiteral(i: I));
8301
8302 // Transform the output expr.
8303 Expr *OutputExpr = S->getOutputExpr(i: I);
8304 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8305 if (Result.isInvalid())
8306 return StmtError();
8307
8308 ExprsChanged |= Result.get() != OutputExpr;
8309
8310 Exprs.push_back(Elt: Result.get());
8311 }
8312
8313 // Go through the inputs.
8314 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8315 Names.push_back(Elt: S->getInputIdentifier(i: I));
8316
8317 // No need to transform the constraint literal.
8318 Constraints.push_back(Elt: S->getInputConstraintLiteral(i: I));
8319
8320 // Transform the input expr.
8321 Expr *InputExpr = S->getInputExpr(i: I);
8322 ExprResult Result = getDerived().TransformExpr(InputExpr);
8323 if (Result.isInvalid())
8324 return StmtError();
8325
8326 ExprsChanged |= Result.get() != InputExpr;
8327
8328 Exprs.push_back(Elt: Result.get());
8329 }
8330
8331 // Go through the Labels.
8332 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8333 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8334
8335 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8336 if (Result.isInvalid())
8337 return StmtError();
8338 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8339 Exprs.push_back(Elt: Result.get());
8340 }
8341 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8342 return S;
8343
8344 // Go through the clobbers.
8345 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8346 Clobbers.push_back(Elt: S->getClobberStringLiteral(i: I));
8347
8348 // No need to transform the asm string literal.
8349 AsmString = S->getAsmString();
8350 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8351 S->isVolatile(), S->getNumOutputs(),
8352 S->getNumInputs(), Names.data(),
8353 Constraints, Exprs, AsmString.get(),
8354 Clobbers, S->getNumLabels(),
8355 S->getRParenLoc());
8356}
8357
8358template<typename Derived>
8359StmtResult
8360TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8361 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8362
8363 bool HadError = false, HadChange = false;
8364
8365 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8366 SmallVector<Expr*, 8> TransformedExprs;
8367 TransformedExprs.reserve(N: SrcExprs.size());
8368 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8369 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8370 if (!Result.isUsable()) {
8371 HadError = true;
8372 } else {
8373 HadChange |= (Result.get() != SrcExprs[i]);
8374 TransformedExprs.push_back(Elt: Result.get());
8375 }
8376 }
8377
8378 if (HadError) return StmtError();
8379 if (!HadChange && !getDerived().AlwaysRebuild())
8380 return Owned(S);
8381
8382 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8383 AsmToks, S->getAsmString(),
8384 S->getNumOutputs(), S->getNumInputs(),
8385 S->getAllConstraints(), S->getClobbers(),
8386 TransformedExprs, S->getEndLoc());
8387}
8388
8389// C++ Coroutines
8390template<typename Derived>
8391StmtResult
8392TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8393 auto *ScopeInfo = SemaRef.getCurFunction();
8394 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8395 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8396 ScopeInfo->NeedsCoroutineSuspends &&
8397 ScopeInfo->CoroutineSuspends.first == nullptr &&
8398 ScopeInfo->CoroutineSuspends.second == nullptr &&
8399 "expected clean scope info");
8400
8401 // Set that we have (possibly-invalid) suspend points before we do anything
8402 // that may fail.
8403 ScopeInfo->setNeedsCoroutineSuspends(false);
8404
8405 // We re-build the coroutine promise object (and the coroutine parameters its
8406 // type and constructor depend on) based on the types used in our current
8407 // function. We must do so, and set it on the current FunctionScopeInfo,
8408 // before attempting to transform the other parts of the coroutine body
8409 // statement, such as the implicit suspend statements (because those
8410 // statements reference the FunctionScopeInfo::CoroutinePromise).
8411 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8412 return StmtError();
8413 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8414 if (!Promise)
8415 return StmtError();
8416 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8417 ScopeInfo->CoroutinePromise = Promise;
8418
8419 // Transform the implicit coroutine statements constructed using dependent
8420 // types during the previous parse: initial and final suspensions, the return
8421 // object, and others. We also transform the coroutine function's body.
8422 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8423 if (InitSuspend.isInvalid())
8424 return StmtError();
8425 StmtResult FinalSuspend =
8426 getDerived().TransformStmt(S->getFinalSuspendStmt());
8427 if (FinalSuspend.isInvalid() ||
8428 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8429 return StmtError();
8430 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8431 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8432
8433 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8434 if (BodyRes.isInvalid())
8435 return StmtError();
8436
8437 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8438 if (Builder.isInvalid())
8439 return StmtError();
8440
8441 Expr *ReturnObject = S->getReturnValueInit();
8442 assert(ReturnObject && "the return object is expected to be valid");
8443 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8444 /*NoCopyInit*/ false);
8445 if (Res.isInvalid())
8446 return StmtError();
8447 Builder.ReturnValue = Res.get();
8448
8449 // If during the previous parse the coroutine still had a dependent promise
8450 // statement, we may need to build some implicit coroutine statements
8451 // (such as exception and fallthrough handlers) for the first time.
8452 if (S->hasDependentPromiseType()) {
8453 // We can only build these statements, however, if the current promise type
8454 // is not dependent.
8455 if (!Promise->getType()->isDependentType()) {
8456 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8457 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8458 "these nodes should not have been built yet");
8459 if (!Builder.buildDependentStatements())
8460 return StmtError();
8461 }
8462 } else {
8463 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8464 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8465 if (Res.isInvalid())
8466 return StmtError();
8467 Builder.OnFallthrough = Res.get();
8468 }
8469
8470 if (auto *OnException = S->getExceptionHandler()) {
8471 StmtResult Res = getDerived().TransformStmt(OnException);
8472 if (Res.isInvalid())
8473 return StmtError();
8474 Builder.OnException = Res.get();
8475 }
8476
8477 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8478 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8479 if (Res.isInvalid())
8480 return StmtError();
8481 Builder.ReturnStmtOnAllocFailure = Res.get();
8482 }
8483
8484 // Transform any additional statements we may have already built
8485 assert(S->getAllocate() && S->getDeallocate() &&
8486 "allocation and deallocation calls must already be built");
8487 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8488 if (AllocRes.isInvalid())
8489 return StmtError();
8490 Builder.Allocate = AllocRes.get();
8491
8492 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8493 if (DeallocRes.isInvalid())
8494 return StmtError();
8495 Builder.Deallocate = DeallocRes.get();
8496
8497 if (auto *ResultDecl = S->getResultDecl()) {
8498 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8499 if (Res.isInvalid())
8500 return StmtError();
8501 Builder.ResultDecl = Res.get();
8502 }
8503
8504 if (auto *ReturnStmt = S->getReturnStmt()) {
8505 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8506 if (Res.isInvalid())
8507 return StmtError();
8508 Builder.ReturnStmt = Res.get();
8509 }
8510 }
8511
8512 return getDerived().RebuildCoroutineBodyStmt(Builder);
8513}
8514
8515template<typename Derived>
8516StmtResult
8517TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8518 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8519 /*NotCopyInit*/false);
8520 if (Result.isInvalid())
8521 return StmtError();
8522
8523 // Always rebuild; we don't know if this needs to be injected into a new
8524 // context or if the promise type has changed.
8525 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8526 S->isImplicit());
8527}
8528
8529template <typename Derived>
8530ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8531 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8532 /*NotCopyInit*/ false);
8533 if (Operand.isInvalid())
8534 return ExprError();
8535
8536 // Rebuild the common-expr from the operand rather than transforming it
8537 // separately.
8538
8539 // FIXME: getCurScope() should not be used during template instantiation.
8540 // We should pick up the set of unqualified lookup results for operator
8541 // co_await during the initial parse.
8542 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8543 getSema().getCurScope(), E->getKeywordLoc());
8544
8545 // Always rebuild; we don't know if this needs to be injected into a new
8546 // context or if the promise type has changed.
8547 return getDerived().RebuildCoawaitExpr(
8548 E->getKeywordLoc(), Operand.get(),
8549 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8550}
8551
8552template <typename Derived>
8553ExprResult
8554TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8555 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8556 /*NotCopyInit*/ false);
8557 if (OperandResult.isInvalid())
8558 return ExprError();
8559
8560 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8561 E->getOperatorCoawaitLookup());
8562
8563 if (LookupResult.isInvalid())
8564 return ExprError();
8565
8566 // Always rebuild; we don't know if this needs to be injected into a new
8567 // context or if the promise type has changed.
8568 return getDerived().RebuildDependentCoawaitExpr(
8569 E->getKeywordLoc(), OperandResult.get(),
8570 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
8571}
8572
8573template<typename Derived>
8574ExprResult
8575TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8576 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8577 /*NotCopyInit*/false);
8578 if (Result.isInvalid())
8579 return ExprError();
8580
8581 // Always rebuild; we don't know if this needs to be injected into a new
8582 // context or if the promise type has changed.
8583 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8584}
8585
8586// Objective-C Statements.
8587
8588template<typename Derived>
8589StmtResult
8590TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8591 // Transform the body of the @try.
8592 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8593 if (TryBody.isInvalid())
8594 return StmtError();
8595
8596 // Transform the @catch statements (if present).
8597 bool AnyCatchChanged = false;
8598 SmallVector<Stmt*, 8> CatchStmts;
8599 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8600 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8601 if (Catch.isInvalid())
8602 return StmtError();
8603 if (Catch.get() != S->getCatchStmt(I))
8604 AnyCatchChanged = true;
8605 CatchStmts.push_back(Elt: Catch.get());
8606 }
8607
8608 // Transform the @finally statement (if present).
8609 StmtResult Finally;
8610 if (S->getFinallyStmt()) {
8611 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8612 if (Finally.isInvalid())
8613 return StmtError();
8614 }
8615
8616 // If nothing changed, just retain this statement.
8617 if (!getDerived().AlwaysRebuild() &&
8618 TryBody.get() == S->getTryBody() &&
8619 !AnyCatchChanged &&
8620 Finally.get() == S->getFinallyStmt())
8621 return S;
8622
8623 // Build a new statement.
8624 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8625 CatchStmts, Finally.get());
8626}
8627
8628template<typename Derived>
8629StmtResult
8630TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8631 // Transform the @catch parameter, if there is one.
8632 VarDecl *Var = nullptr;
8633 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8634 TypeSourceInfo *TSInfo = nullptr;
8635 if (FromVar->getTypeSourceInfo()) {
8636 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8637 if (!TSInfo)
8638 return StmtError();
8639 }
8640
8641 QualType T;
8642 if (TSInfo)
8643 T = TSInfo->getType();
8644 else {
8645 T = getDerived().TransformType(FromVar->getType());
8646 if (T.isNull())
8647 return StmtError();
8648 }
8649
8650 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8651 if (!Var)
8652 return StmtError();
8653 }
8654
8655 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8656 if (Body.isInvalid())
8657 return StmtError();
8658
8659 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8660 S->getRParenLoc(),
8661 Var, Body.get());
8662}
8663
8664template<typename Derived>
8665StmtResult
8666TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8667 // Transform the body.
8668 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8669 if (Body.isInvalid())
8670 return StmtError();
8671
8672 // If nothing changed, just retain this statement.
8673 if (!getDerived().AlwaysRebuild() &&
8674 Body.get() == S->getFinallyBody())
8675 return S;
8676
8677 // Build a new statement.
8678 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8679 Body.get());
8680}
8681
8682template<typename Derived>
8683StmtResult
8684TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8685 ExprResult Operand;
8686 if (S->getThrowExpr()) {
8687 Operand = getDerived().TransformExpr(S->getThrowExpr());
8688 if (Operand.isInvalid())
8689 return StmtError();
8690 }
8691
8692 if (!getDerived().AlwaysRebuild() &&
8693 Operand.get() == S->getThrowExpr())
8694 return S;
8695
8696 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8697}
8698
8699template<typename Derived>
8700StmtResult
8701TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8702 ObjCAtSynchronizedStmt *S) {
8703 // Transform the object we are locking.
8704 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8705 if (Object.isInvalid())
8706 return StmtError();
8707 Object =
8708 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8709 Object.get());
8710 if (Object.isInvalid())
8711 return StmtError();
8712
8713 // Transform the body.
8714 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8715 if (Body.isInvalid())
8716 return StmtError();
8717
8718 // If nothing change, just retain the current statement.
8719 if (!getDerived().AlwaysRebuild() &&
8720 Object.get() == S->getSynchExpr() &&
8721 Body.get() == S->getSynchBody())
8722 return S;
8723
8724 // Build a new statement.
8725 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8726 Object.get(), Body.get());
8727}
8728
8729template<typename Derived>
8730StmtResult
8731TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8732 ObjCAutoreleasePoolStmt *S) {
8733 // Transform the body.
8734 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8735 if (Body.isInvalid())
8736 return StmtError();
8737
8738 // If nothing changed, just retain this statement.
8739 if (!getDerived().AlwaysRebuild() &&
8740 Body.get() == S->getSubStmt())
8741 return S;
8742
8743 // Build a new statement.
8744 return getDerived().RebuildObjCAutoreleasePoolStmt(
8745 S->getAtLoc(), Body.get());
8746}
8747
8748template<typename Derived>
8749StmtResult
8750TreeTransform<Derived>::TransformObjCForCollectionStmt(
8751 ObjCForCollectionStmt *S) {
8752 // Transform the element statement.
8753 StmtResult Element =
8754 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8755 if (Element.isInvalid())
8756 return StmtError();
8757
8758 // Transform the collection expression.
8759 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8760 if (Collection.isInvalid())
8761 return StmtError();
8762
8763 // Transform the body.
8764 StmtResult Body = getDerived().TransformStmt(S->getBody());
8765 if (Body.isInvalid())
8766 return StmtError();
8767
8768 // If nothing changed, just retain this statement.
8769 if (!getDerived().AlwaysRebuild() &&
8770 Element.get() == S->getElement() &&
8771 Collection.get() == S->getCollection() &&
8772 Body.get() == S->getBody())
8773 return S;
8774
8775 // Build a new statement.
8776 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8777 Element.get(),
8778 Collection.get(),
8779 S->getRParenLoc(),
8780 Body.get());
8781}
8782
8783template <typename Derived>
8784StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8785 // Transform the exception declaration, if any.
8786 VarDecl *Var = nullptr;
8787 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8788 TypeSourceInfo *T =
8789 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8790 if (!T)
8791 return StmtError();
8792
8793 Var = getDerived().RebuildExceptionDecl(
8794 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8795 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8796 if (!Var || Var->isInvalidDecl())
8797 return StmtError();
8798 }
8799
8800 // Transform the actual exception handler.
8801 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8802 if (Handler.isInvalid())
8803 return StmtError();
8804
8805 if (!getDerived().AlwaysRebuild() && !Var &&
8806 Handler.get() == S->getHandlerBlock())
8807 return S;
8808
8809 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8810}
8811
8812template <typename Derived>
8813StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8814 // Transform the try block itself.
8815 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8816 if (TryBlock.isInvalid())
8817 return StmtError();
8818
8819 // Transform the handlers.
8820 bool HandlerChanged = false;
8821 SmallVector<Stmt *, 8> Handlers;
8822 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8823 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
8824 if (Handler.isInvalid())
8825 return StmtError();
8826
8827 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
8828 Handlers.push_back(Elt: Handler.getAs<Stmt>());
8829 }
8830
8831 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8832 !HandlerChanged)
8833 return S;
8834
8835 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8836 Handlers);
8837}
8838
8839template<typename Derived>
8840StmtResult
8841TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8842 EnterExpressionEvaluationContext ForRangeInitContext(
8843 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
8844 /*LambdaContextDecl=*/nullptr,
8845 Sema::ExpressionEvaluationContextRecord::EK_Other,
8846 getSema().getLangOpts().CPlusPlus23);
8847
8848 // P2718R0 - Lifetime extension in range-based for loops.
8849 if (getSema().getLangOpts().CPlusPlus23) {
8850 auto &LastRecord = getSema().ExprEvalContexts.back();
8851 LastRecord.InLifetimeExtendingContext = true;
8852 }
8853 StmtResult Init =
8854 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8855 if (Init.isInvalid())
8856 return StmtError();
8857
8858 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8859 if (Range.isInvalid())
8860 return StmtError();
8861
8862 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
8863 assert(getSema().getLangOpts().CPlusPlus23 ||
8864 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
8865 auto ForRangeLifetimeExtendTemps =
8866 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
8867
8868 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8869 if (Begin.isInvalid())
8870 return StmtError();
8871 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8872 if (End.isInvalid())
8873 return StmtError();
8874
8875 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8876 if (Cond.isInvalid())
8877 return StmtError();
8878 if (Cond.get())
8879 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
8880 if (Cond.isInvalid())
8881 return StmtError();
8882 if (Cond.get())
8883 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
8884
8885 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8886 if (Inc.isInvalid())
8887 return StmtError();
8888 if (Inc.get())
8889 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
8890
8891 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8892 if (LoopVar.isInvalid())
8893 return StmtError();
8894
8895 StmtResult NewStmt = S;
8896 if (getDerived().AlwaysRebuild() ||
8897 Init.get() != S->getInit() ||
8898 Range.get() != S->getRangeStmt() ||
8899 Begin.get() != S->getBeginStmt() ||
8900 End.get() != S->getEndStmt() ||
8901 Cond.get() != S->getCond() ||
8902 Inc.get() != S->getInc() ||
8903 LoopVar.get() != S->getLoopVarStmt()) {
8904 NewStmt = getDerived().RebuildCXXForRangeStmt(
8905 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8906 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8907 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8908 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8909 // Might not have attached any initializer to the loop variable.
8910 getSema().ActOnInitializerError(
8911 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
8912 return StmtError();
8913 }
8914 }
8915
8916 StmtResult Body = getDerived().TransformStmt(S->getBody());
8917 if (Body.isInvalid())
8918 return StmtError();
8919
8920 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8921 // it now so we have a new statement to attach the body to.
8922 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8923 NewStmt = getDerived().RebuildCXXForRangeStmt(
8924 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8925 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8926 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8927 if (NewStmt.isInvalid())
8928 return StmtError();
8929 }
8930
8931 if (NewStmt.get() == S)
8932 return S;
8933
8934 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
8935}
8936
8937template<typename Derived>
8938StmtResult
8939TreeTransform<Derived>::TransformMSDependentExistsStmt(
8940 MSDependentExistsStmt *S) {
8941 // Transform the nested-name-specifier, if any.
8942 NestedNameSpecifierLoc QualifierLoc;
8943 if (S->getQualifierLoc()) {
8944 QualifierLoc
8945 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8946 if (!QualifierLoc)
8947 return StmtError();
8948 }
8949
8950 // Transform the declaration name.
8951 DeclarationNameInfo NameInfo = S->getNameInfo();
8952 if (NameInfo.getName()) {
8953 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8954 if (!NameInfo.getName())
8955 return StmtError();
8956 }
8957
8958 // Check whether anything changed.
8959 if (!getDerived().AlwaysRebuild() &&
8960 QualifierLoc == S->getQualifierLoc() &&
8961 NameInfo.getName() == S->getNameInfo().getName())
8962 return S;
8963
8964 // Determine whether this name exists, if we can.
8965 CXXScopeSpec SS;
8966 SS.Adopt(Other: QualifierLoc);
8967 bool Dependent = false;
8968 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8969 case Sema::IER_Exists:
8970 if (S->isIfExists())
8971 break;
8972
8973 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8974
8975 case Sema::IER_DoesNotExist:
8976 if (S->isIfNotExists())
8977 break;
8978
8979 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8980
8981 case Sema::IER_Dependent:
8982 Dependent = true;
8983 break;
8984
8985 case Sema::IER_Error:
8986 return StmtError();
8987 }
8988
8989 // We need to continue with the instantiation, so do so now.
8990 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8991 if (SubStmt.isInvalid())
8992 return StmtError();
8993
8994 // If we have resolved the name, just transform to the substatement.
8995 if (!Dependent)
8996 return SubStmt;
8997
8998 // The name is still dependent, so build a dependent expression again.
8999 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9000 S->isIfExists(),
9001 QualifierLoc,
9002 NameInfo,
9003 SubStmt.get());
9004}
9005
9006template<typename Derived>
9007ExprResult
9008TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9009 NestedNameSpecifierLoc QualifierLoc;
9010 if (E->getQualifierLoc()) {
9011 QualifierLoc
9012 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9013 if (!QualifierLoc)
9014 return ExprError();
9015 }
9016
9017 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9018 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9019 if (!PD)
9020 return ExprError();
9021
9022 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9023 if (Base.isInvalid())
9024 return ExprError();
9025
9026 return new (SemaRef.getASTContext())
9027 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9028 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9029 QualifierLoc, E->getMemberLoc());
9030}
9031
9032template <typename Derived>
9033ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9034 MSPropertySubscriptExpr *E) {
9035 auto BaseRes = getDerived().TransformExpr(E->getBase());
9036 if (BaseRes.isInvalid())
9037 return ExprError();
9038 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9039 if (IdxRes.isInvalid())
9040 return ExprError();
9041
9042 if (!getDerived().AlwaysRebuild() &&
9043 BaseRes.get() == E->getBase() &&
9044 IdxRes.get() == E->getIdx())
9045 return E;
9046
9047 return getDerived().RebuildArraySubscriptExpr(
9048 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9049}
9050
9051template <typename Derived>
9052StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9053 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9054 if (TryBlock.isInvalid())
9055 return StmtError();
9056
9057 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9058 if (Handler.isInvalid())
9059 return StmtError();
9060
9061 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9062 Handler.get() == S->getHandler())
9063 return S;
9064
9065 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9066 TryBlock.get(), Handler.get());
9067}
9068
9069template <typename Derived>
9070StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9071 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9072 if (Block.isInvalid())
9073 return StmtError();
9074
9075 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9076}
9077
9078template <typename Derived>
9079StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9080 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9081 if (FilterExpr.isInvalid())
9082 return StmtError();
9083
9084 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9085 if (Block.isInvalid())
9086 return StmtError();
9087
9088 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9089 Block.get());
9090}
9091
9092template <typename Derived>
9093StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9094 if (isa<SEHFinallyStmt>(Val: Handler))
9095 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9096 else
9097 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9098}
9099
9100template<typename Derived>
9101StmtResult
9102TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9103 return S;
9104}
9105
9106//===----------------------------------------------------------------------===//
9107// OpenMP directive transformation
9108//===----------------------------------------------------------------------===//
9109
9110template <typename Derived>
9111StmtResult
9112TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9113 // OMPCanonicalLoops are eliminated during transformation, since they will be
9114 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9115 // after transformation.
9116 return getDerived().TransformStmt(L->getLoopStmt());
9117}
9118
9119template <typename Derived>
9120StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9121 OMPExecutableDirective *D) {
9122
9123 // Transform the clauses
9124 llvm::SmallVector<OMPClause *, 16> TClauses;
9125 ArrayRef<OMPClause *> Clauses = D->clauses();
9126 TClauses.reserve(N: Clauses.size());
9127 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9128 I != E; ++I) {
9129 if (*I) {
9130 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9131 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9132 getDerived().getSema().OpenMP().EndOpenMPClause();
9133 if (Clause)
9134 TClauses.push_back(Elt: Clause);
9135 } else {
9136 TClauses.push_back(Elt: nullptr);
9137 }
9138 }
9139 StmtResult AssociatedStmt;
9140 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9141 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9142 D->getDirectiveKind(),
9143 /*CurScope=*/nullptr);
9144 StmtResult Body;
9145 {
9146 Sema::CompoundScopeRAII CompoundScope(getSema());
9147 Stmt *CS;
9148 if (D->getDirectiveKind() == OMPD_atomic ||
9149 D->getDirectiveKind() == OMPD_critical ||
9150 D->getDirectiveKind() == OMPD_section ||
9151 D->getDirectiveKind() == OMPD_master)
9152 CS = D->getAssociatedStmt();
9153 else
9154 CS = D->getRawStmt();
9155 Body = getDerived().TransformStmt(CS);
9156 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9157 getSema().getLangOpts().OpenMPIRBuilder)
9158 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9159 }
9160 AssociatedStmt =
9161 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9162 if (AssociatedStmt.isInvalid()) {
9163 return StmtError();
9164 }
9165 }
9166 if (TClauses.size() != Clauses.size()) {
9167 return StmtError();
9168 }
9169
9170 // Transform directive name for 'omp critical' directive.
9171 DeclarationNameInfo DirName;
9172 if (D->getDirectiveKind() == OMPD_critical) {
9173 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9174 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9175 }
9176 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9177 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9178 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9179 } else if (D->getDirectiveKind() == OMPD_cancel) {
9180 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9181 }
9182
9183 return getDerived().RebuildOMPExecutableDirective(
9184 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9185 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
9186 D->getMappedDirective());
9187}
9188
9189template <typename Derived>
9190StmtResult
9191TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9192 // TODO: Fix This
9193 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9194 << getOpenMPDirectiveName(D: D->getDirectiveKind());
9195 return StmtError();
9196}
9197
9198template <typename Derived>
9199StmtResult
9200TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9201 DeclarationNameInfo DirName;
9202 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9203 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9204 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9205 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9206 return Res;
9207}
9208
9209template <typename Derived>
9210StmtResult
9211TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9212 DeclarationNameInfo DirName;
9213 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9214 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9215 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9216 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9217 return Res;
9218}
9219
9220template <typename Derived>
9221StmtResult
9222TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9223 DeclarationNameInfo DirName;
9224 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9225 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9226 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9227 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9228 return Res;
9229}
9230
9231template <typename Derived>
9232StmtResult
9233TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9234 DeclarationNameInfo DirName;
9235 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9236 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9237 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9238 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9239 return Res;
9240}
9241
9242template <typename Derived>
9243StmtResult
9244TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9245 DeclarationNameInfo DirName;
9246 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9247 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9248 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9249 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9250 return Res;
9251}
9252
9253template <typename Derived>
9254StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9255 OMPInterchangeDirective *D) {
9256 DeclarationNameInfo DirName;
9257 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9258 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9259 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9260 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9261 return Res;
9262}
9263
9264template <typename Derived>
9265StmtResult
9266TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9267 DeclarationNameInfo DirName;
9268 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9269 OMPD_for, DirName, nullptr, D->getBeginLoc());
9270 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9271 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9272 return Res;
9273}
9274
9275template <typename Derived>
9276StmtResult
9277TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9278 DeclarationNameInfo DirName;
9279 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9280 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9281 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9282 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9283 return Res;
9284}
9285
9286template <typename Derived>
9287StmtResult
9288TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9289 DeclarationNameInfo DirName;
9290 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9291 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9292 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9293 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9294 return Res;
9295}
9296
9297template <typename Derived>
9298StmtResult
9299TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9300 DeclarationNameInfo DirName;
9301 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9302 OMPD_section, DirName, nullptr, D->getBeginLoc());
9303 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9304 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9305 return Res;
9306}
9307
9308template <typename Derived>
9309StmtResult
9310TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9311 DeclarationNameInfo DirName;
9312 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9313 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9314 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9315 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9316 return Res;
9317}
9318
9319template <typename Derived>
9320StmtResult
9321TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9322 DeclarationNameInfo DirName;
9323 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9324 OMPD_single, DirName, nullptr, D->getBeginLoc());
9325 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9326 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9327 return Res;
9328}
9329
9330template <typename Derived>
9331StmtResult
9332TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9333 DeclarationNameInfo DirName;
9334 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9335 OMPD_master, DirName, nullptr, D->getBeginLoc());
9336 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9337 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9338 return Res;
9339}
9340
9341template <typename Derived>
9342StmtResult
9343TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9344 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9345 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9346 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9347 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9348 return Res;
9349}
9350
9351template <typename Derived>
9352StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9353 OMPParallelForDirective *D) {
9354 DeclarationNameInfo DirName;
9355 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9356 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9357 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9358 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9359 return Res;
9360}
9361
9362template <typename Derived>
9363StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9364 OMPParallelForSimdDirective *D) {
9365 DeclarationNameInfo DirName;
9366 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9367 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9368 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9369 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9370 return Res;
9371}
9372
9373template <typename Derived>
9374StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9375 OMPParallelMasterDirective *D) {
9376 DeclarationNameInfo DirName;
9377 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9378 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9379 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9380 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9381 return Res;
9382}
9383
9384template <typename Derived>
9385StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9386 OMPParallelMaskedDirective *D) {
9387 DeclarationNameInfo DirName;
9388 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9389 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9390 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9391 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9392 return Res;
9393}
9394
9395template <typename Derived>
9396StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9397 OMPParallelSectionsDirective *D) {
9398 DeclarationNameInfo DirName;
9399 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9400 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9401 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9402 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9403 return Res;
9404}
9405
9406template <typename Derived>
9407StmtResult
9408TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9409 DeclarationNameInfo DirName;
9410 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9411 OMPD_task, DirName, nullptr, D->getBeginLoc());
9412 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9413 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9414 return Res;
9415}
9416
9417template <typename Derived>
9418StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9419 OMPTaskyieldDirective *D) {
9420 DeclarationNameInfo DirName;
9421 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9422 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9423 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9424 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9425 return Res;
9426}
9427
9428template <typename Derived>
9429StmtResult
9430TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9431 DeclarationNameInfo DirName;
9432 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9433 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9434 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9435 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9436 return Res;
9437}
9438
9439template <typename Derived>
9440StmtResult
9441TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9442 DeclarationNameInfo DirName;
9443 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9444 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9445 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9446 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9447 return Res;
9448}
9449
9450template <typename Derived>
9451StmtResult
9452TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9453 DeclarationNameInfo DirName;
9454 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9455 OMPD_error, DirName, nullptr, D->getBeginLoc());
9456 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9457 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9458 return Res;
9459}
9460
9461template <typename Derived>
9462StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9463 OMPTaskgroupDirective *D) {
9464 DeclarationNameInfo DirName;
9465 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9466 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9467 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9468 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9469 return Res;
9470}
9471
9472template <typename Derived>
9473StmtResult
9474TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9475 DeclarationNameInfo DirName;
9476 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9477 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9478 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9479 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9480 return Res;
9481}
9482
9483template <typename Derived>
9484StmtResult
9485TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9486 DeclarationNameInfo DirName;
9487 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9488 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9489 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9490 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9491 return Res;
9492}
9493
9494template <typename Derived>
9495StmtResult
9496TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9497 DeclarationNameInfo DirName;
9498 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9499 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9500 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9501 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9502 return Res;
9503}
9504
9505template <typename Derived>
9506StmtResult
9507TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9508 DeclarationNameInfo DirName;
9509 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9510 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9511 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9512 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9513 return Res;
9514}
9515
9516template <typename Derived>
9517StmtResult
9518TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9519 DeclarationNameInfo DirName;
9520 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9521 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9522 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9523 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9524 return Res;
9525}
9526
9527template <typename Derived>
9528StmtResult
9529TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9530 DeclarationNameInfo DirName;
9531 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9532 OMPD_target, DirName, nullptr, D->getBeginLoc());
9533 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9534 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9535 return Res;
9536}
9537
9538template <typename Derived>
9539StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9540 OMPTargetDataDirective *D) {
9541 DeclarationNameInfo DirName;
9542 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9543 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9544 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9545 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9546 return Res;
9547}
9548
9549template <typename Derived>
9550StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9551 OMPTargetEnterDataDirective *D) {
9552 DeclarationNameInfo DirName;
9553 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9554 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9555 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9556 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9557 return Res;
9558}
9559
9560template <typename Derived>
9561StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9562 OMPTargetExitDataDirective *D) {
9563 DeclarationNameInfo DirName;
9564 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9565 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9566 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9567 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9568 return Res;
9569}
9570
9571template <typename Derived>
9572StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9573 OMPTargetParallelDirective *D) {
9574 DeclarationNameInfo DirName;
9575 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9576 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9577 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9578 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9579 return Res;
9580}
9581
9582template <typename Derived>
9583StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9584 OMPTargetParallelForDirective *D) {
9585 DeclarationNameInfo DirName;
9586 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9587 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9588 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9589 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9590 return Res;
9591}
9592
9593template <typename Derived>
9594StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9595 OMPTargetUpdateDirective *D) {
9596 DeclarationNameInfo DirName;
9597 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9598 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
9599 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9600 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9601 return Res;
9602}
9603
9604template <typename Derived>
9605StmtResult
9606TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9607 DeclarationNameInfo DirName;
9608 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9609 OMPD_teams, DirName, nullptr, D->getBeginLoc());
9610 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9611 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9612 return Res;
9613}
9614
9615template <typename Derived>
9616StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9617 OMPCancellationPointDirective *D) {
9618 DeclarationNameInfo DirName;
9619 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9620 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
9621 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9622 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9623 return Res;
9624}
9625
9626template <typename Derived>
9627StmtResult
9628TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9629 DeclarationNameInfo DirName;
9630 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9631 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
9632 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9633 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9634 return Res;
9635}
9636
9637template <typename Derived>
9638StmtResult
9639TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9640 DeclarationNameInfo DirName;
9641 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9642 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
9643 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9644 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9645 return Res;
9646}
9647
9648template <typename Derived>
9649StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9650 OMPTaskLoopSimdDirective *D) {
9651 DeclarationNameInfo DirName;
9652 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9653 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9654 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9655 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9656 return Res;
9657}
9658
9659template <typename Derived>
9660StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9661 OMPMasterTaskLoopDirective *D) {
9662 DeclarationNameInfo DirName;
9663 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9664 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
9665 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9666 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9667 return Res;
9668}
9669
9670template <typename Derived>
9671StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9672 OMPMaskedTaskLoopDirective *D) {
9673 DeclarationNameInfo DirName;
9674 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9675 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9676 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9677 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9678 return Res;
9679}
9680
9681template <typename Derived>
9682StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9683 OMPMasterTaskLoopSimdDirective *D) {
9684 DeclarationNameInfo DirName;
9685 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9686 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9687 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9688 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9689 return Res;
9690}
9691
9692template <typename Derived>
9693StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9694 OMPMaskedTaskLoopSimdDirective *D) {
9695 DeclarationNameInfo DirName;
9696 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9697 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9698 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9699 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9700 return Res;
9701}
9702
9703template <typename Derived>
9704StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9705 OMPParallelMasterTaskLoopDirective *D) {
9706 DeclarationNameInfo DirName;
9707 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9708 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9709 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9710 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9711 return Res;
9712}
9713
9714template <typename Derived>
9715StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9716 OMPParallelMaskedTaskLoopDirective *D) {
9717 DeclarationNameInfo DirName;
9718 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9719 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9720 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9721 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9722 return Res;
9723}
9724
9725template <typename Derived>
9726StmtResult
9727TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9728 OMPParallelMasterTaskLoopSimdDirective *D) {
9729 DeclarationNameInfo DirName;
9730 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9731 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9732 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9733 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9734 return Res;
9735}
9736
9737template <typename Derived>
9738StmtResult
9739TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9740 OMPParallelMaskedTaskLoopSimdDirective *D) {
9741 DeclarationNameInfo DirName;
9742 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9743 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9744 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9745 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9746 return Res;
9747}
9748
9749template <typename Derived>
9750StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9751 OMPDistributeDirective *D) {
9752 DeclarationNameInfo DirName;
9753 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9754 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
9755 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9756 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9757 return Res;
9758}
9759
9760template <typename Derived>
9761StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9762 OMPDistributeParallelForDirective *D) {
9763 DeclarationNameInfo DirName;
9764 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9765 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9766 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9767 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9768 return Res;
9769}
9770
9771template <typename Derived>
9772StmtResult
9773TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9774 OMPDistributeParallelForSimdDirective *D) {
9775 DeclarationNameInfo DirName;
9776 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9777 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9778 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9779 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9780 return Res;
9781}
9782
9783template <typename Derived>
9784StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9785 OMPDistributeSimdDirective *D) {
9786 DeclarationNameInfo DirName;
9787 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9788 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
9789 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9790 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9791 return Res;
9792}
9793
9794template <typename Derived>
9795StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9796 OMPTargetParallelForSimdDirective *D) {
9797 DeclarationNameInfo DirName;
9798 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9799 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9800 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9801 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9802 return Res;
9803}
9804
9805template <typename Derived>
9806StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9807 OMPTargetSimdDirective *D) {
9808 DeclarationNameInfo DirName;
9809 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9810 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
9811 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9812 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9813 return Res;
9814}
9815
9816template <typename Derived>
9817StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9818 OMPTeamsDistributeDirective *D) {
9819 DeclarationNameInfo DirName;
9820 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9821 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
9822 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9823 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9824 return Res;
9825}
9826
9827template <typename Derived>
9828StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9829 OMPTeamsDistributeSimdDirective *D) {
9830 DeclarationNameInfo DirName;
9831 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9832 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9833 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9834 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9835 return Res;
9836}
9837
9838template <typename Derived>
9839StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9840 OMPTeamsDistributeParallelForSimdDirective *D) {
9841 DeclarationNameInfo DirName;
9842 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9843 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9844 D->getBeginLoc());
9845 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9846 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9847 return Res;
9848}
9849
9850template <typename Derived>
9851StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9852 OMPTeamsDistributeParallelForDirective *D) {
9853 DeclarationNameInfo DirName;
9854 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9855 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9856 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9857 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9858 return Res;
9859}
9860
9861template <typename Derived>
9862StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9863 OMPTargetTeamsDirective *D) {
9864 DeclarationNameInfo DirName;
9865 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9866 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
9867 auto Res = getDerived().TransformOMPExecutableDirective(D);
9868 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9869 return Res;
9870}
9871
9872template <typename Derived>
9873StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9874 OMPTargetTeamsDistributeDirective *D) {
9875 DeclarationNameInfo DirName;
9876 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9877 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9878 auto Res = getDerived().TransformOMPExecutableDirective(D);
9879 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9880 return Res;
9881}
9882
9883template <typename Derived>
9884StmtResult
9885TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9886 OMPTargetTeamsDistributeParallelForDirective *D) {
9887 DeclarationNameInfo DirName;
9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9889 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9890 D->getBeginLoc());
9891 auto Res = getDerived().TransformOMPExecutableDirective(D);
9892 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9893 return Res;
9894}
9895
9896template <typename Derived>
9897StmtResult TreeTransform<Derived>::
9898 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9899 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9900 DeclarationNameInfo DirName;
9901 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9902 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9903 D->getBeginLoc());
9904 auto Res = getDerived().TransformOMPExecutableDirective(D);
9905 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9906 return Res;
9907}
9908
9909template <typename Derived>
9910StmtResult
9911TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9912 OMPTargetTeamsDistributeSimdDirective *D) {
9913 DeclarationNameInfo DirName;
9914 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9915 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9916 auto Res = getDerived().TransformOMPExecutableDirective(D);
9917 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9918 return Res;
9919}
9920
9921template <typename Derived>
9922StmtResult
9923TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9924 DeclarationNameInfo DirName;
9925 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9926 OMPD_interop, DirName, nullptr, D->getBeginLoc());
9927 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9928 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9929 return Res;
9930}
9931
9932template <typename Derived>
9933StmtResult
9934TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9935 DeclarationNameInfo DirName;
9936 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9937 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
9938 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9939 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9940 return Res;
9941}
9942
9943template <typename Derived>
9944StmtResult
9945TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9946 DeclarationNameInfo DirName;
9947 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9948 OMPD_masked, DirName, nullptr, D->getBeginLoc());
9949 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9950 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9951 return Res;
9952}
9953
9954template <typename Derived>
9955StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9956 OMPGenericLoopDirective *D) {
9957 DeclarationNameInfo DirName;
9958 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9959 OMPD_loop, DirName, nullptr, D->getBeginLoc());
9960 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9961 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9962 return Res;
9963}
9964
9965template <typename Derived>
9966StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9967 OMPTeamsGenericLoopDirective *D) {
9968 DeclarationNameInfo DirName;
9969 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9970 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
9971 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9972 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9973 return Res;
9974}
9975
9976template <typename Derived>
9977StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9978 OMPTargetTeamsGenericLoopDirective *D) {
9979 DeclarationNameInfo DirName;
9980 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9981 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
9982 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9983 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9984 return Res;
9985}
9986
9987template <typename Derived>
9988StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9989 OMPParallelGenericLoopDirective *D) {
9990 DeclarationNameInfo DirName;
9991 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9992 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
9993 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9994 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9995 return Res;
9996}
9997
9998template <typename Derived>
9999StmtResult
10000TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10001 OMPTargetParallelGenericLoopDirective *D) {
10002 DeclarationNameInfo DirName;
10003 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10004 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10005 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10006 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10007 return Res;
10008}
10009
10010//===----------------------------------------------------------------------===//
10011// OpenMP clause transformation
10012//===----------------------------------------------------------------------===//
10013template <typename Derived>
10014OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10015 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10016 if (Cond.isInvalid())
10017 return nullptr;
10018 return getDerived().RebuildOMPIfClause(
10019 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10020 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10021}
10022
10023template <typename Derived>
10024OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10025 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10026 if (Cond.isInvalid())
10027 return nullptr;
10028 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10029 C->getLParenLoc(), C->getEndLoc());
10030}
10031
10032template <typename Derived>
10033OMPClause *
10034TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10035 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10036 if (NumThreads.isInvalid())
10037 return nullptr;
10038 return getDerived().RebuildOMPNumThreadsClause(
10039 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10040}
10041
10042template <typename Derived>
10043OMPClause *
10044TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10045 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10046 if (E.isInvalid())
10047 return nullptr;
10048 return getDerived().RebuildOMPSafelenClause(
10049 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10050}
10051
10052template <typename Derived>
10053OMPClause *
10054TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10055 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10056 if (E.isInvalid())
10057 return nullptr;
10058 return getDerived().RebuildOMPAllocatorClause(
10059 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10060}
10061
10062template <typename Derived>
10063OMPClause *
10064TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10065 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10066 if (E.isInvalid())
10067 return nullptr;
10068 return getDerived().RebuildOMPSimdlenClause(
10069 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10070}
10071
10072template <typename Derived>
10073OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10074 SmallVector<Expr *, 4> TransformedSizes;
10075 TransformedSizes.reserve(N: C->getNumSizes());
10076 bool Changed = false;
10077 for (Expr *E : C->getSizesRefs()) {
10078 if (!E) {
10079 TransformedSizes.push_back(Elt: nullptr);
10080 continue;
10081 }
10082
10083 ExprResult T = getDerived().TransformExpr(E);
10084 if (T.isInvalid())
10085 return nullptr;
10086 if (E != T.get())
10087 Changed = true;
10088 TransformedSizes.push_back(Elt: T.get());
10089 }
10090
10091 if (!Changed && !getDerived().AlwaysRebuild())
10092 return C;
10093 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10094 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10095}
10096
10097template <typename Derived>
10098OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10099 if (!getDerived().AlwaysRebuild())
10100 return C;
10101 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10102}
10103
10104template <typename Derived>
10105OMPClause *
10106TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10107 ExprResult T = getDerived().TransformExpr(C->getFactor());
10108 if (T.isInvalid())
10109 return nullptr;
10110 Expr *Factor = T.get();
10111 bool Changed = Factor != C->getFactor();
10112
10113 if (!Changed && !getDerived().AlwaysRebuild())
10114 return C;
10115 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10116 EndLoc: C->getEndLoc());
10117}
10118
10119template <typename Derived>
10120OMPClause *
10121TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10122 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10123 if (E.isInvalid())
10124 return nullptr;
10125 return getDerived().RebuildOMPCollapseClause(
10126 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10127}
10128
10129template <typename Derived>
10130OMPClause *
10131TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10132 return getDerived().RebuildOMPDefaultClause(
10133 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10134 C->getLParenLoc(), C->getEndLoc());
10135}
10136
10137template <typename Derived>
10138OMPClause *
10139TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10140 return getDerived().RebuildOMPProcBindClause(
10141 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10142 C->getLParenLoc(), C->getEndLoc());
10143}
10144
10145template <typename Derived>
10146OMPClause *
10147TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10148 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10149 if (E.isInvalid())
10150 return nullptr;
10151 return getDerived().RebuildOMPScheduleClause(
10152 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10153 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10154 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10155 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10156}
10157
10158template <typename Derived>
10159OMPClause *
10160TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10161 ExprResult E;
10162 if (auto *Num = C->getNumForLoops()) {
10163 E = getDerived().TransformExpr(Num);
10164 if (E.isInvalid())
10165 return nullptr;
10166 }
10167 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10168 C->getLParenLoc(), E.get());
10169}
10170
10171template <typename Derived>
10172OMPClause *
10173TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10174 ExprResult E;
10175 if (Expr *Evt = C->getEventHandler()) {
10176 E = getDerived().TransformExpr(Evt);
10177 if (E.isInvalid())
10178 return nullptr;
10179 }
10180 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10181 C->getLParenLoc(), C->getEndLoc());
10182}
10183
10184template <typename Derived>
10185OMPClause *
10186TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10187 // No need to rebuild this clause, no template-dependent parameters.
10188 return C;
10189}
10190
10191template <typename Derived>
10192OMPClause *
10193TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10194 // No need to rebuild this clause, no template-dependent parameters.
10195 return C;
10196}
10197
10198template <typename Derived>
10199OMPClause *
10200TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10201 // No need to rebuild this clause, no template-dependent parameters.
10202 return C;
10203}
10204
10205template <typename Derived>
10206OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10207 // No need to rebuild this clause, no template-dependent parameters.
10208 return C;
10209}
10210
10211template <typename Derived>
10212OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10213 // No need to rebuild this clause, no template-dependent parameters.
10214 return C;
10215}
10216
10217template <typename Derived>
10218OMPClause *
10219TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10220 // No need to rebuild this clause, no template-dependent parameters.
10221 return C;
10222}
10223
10224template <typename Derived>
10225OMPClause *
10226TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10227 // No need to rebuild this clause, no template-dependent parameters.
10228 return C;
10229}
10230
10231template <typename Derived>
10232OMPClause *
10233TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10234 // No need to rebuild this clause, no template-dependent parameters.
10235 return C;
10236}
10237
10238template <typename Derived>
10239OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10240 // No need to rebuild this clause, no template-dependent parameters.
10241 return C;
10242}
10243
10244template <typename Derived>
10245OMPClause *
10246TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10247 // No need to rebuild this clause, no template-dependent parameters.
10248 return C;
10249}
10250
10251template <typename Derived>
10252OMPClause *
10253TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10254 // No need to rebuild this clause, no template-dependent parameters.
10255 return C;
10256}
10257
10258template <typename Derived>
10259OMPClause *
10260TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10261 // No need to rebuild this clause, no template-dependent parameters.
10262 return C;
10263}
10264
10265template <typename Derived>
10266OMPClause *
10267TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10268 // No need to rebuild this clause, no template-dependent parameters.
10269 return C;
10270}
10271
10272template <typename Derived>
10273OMPClause *
10274TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10275 // No need to rebuild this clause, no template-dependent parameters.
10276 return C;
10277}
10278
10279template <typename Derived>
10280OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10281 // No need to rebuild this clause, no template-dependent parameters.
10282 return C;
10283}
10284
10285template <typename Derived>
10286OMPClause *
10287TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10288 // No need to rebuild this clause, no template-dependent parameters.
10289 return C;
10290}
10291
10292template <typename Derived>
10293OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10294 // No need to rebuild this clause, no template-dependent parameters.
10295 return C;
10296}
10297
10298template <typename Derived>
10299OMPClause *
10300TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10301 // No need to rebuild this clause, no template-dependent parameters.
10302 return C;
10303}
10304
10305template <typename Derived>
10306OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10307 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10308 if (IVR.isInvalid())
10309 return nullptr;
10310
10311 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10312 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10313 for (Expr *E : llvm::drop_begin(RangeOrContainer: C->varlists())) {
10314 ExprResult ER = getDerived().TransformExpr(cast<Expr>(Val: E));
10315 if (ER.isInvalid())
10316 return nullptr;
10317 InteropInfo.PreferTypes.push_back(Elt: ER.get());
10318 }
10319 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10320 C->getBeginLoc(), C->getLParenLoc(),
10321 C->getVarLoc(), C->getEndLoc());
10322}
10323
10324template <typename Derived>
10325OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10326 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10327 if (ER.isInvalid())
10328 return nullptr;
10329 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10330 C->getLParenLoc(), C->getVarLoc(),
10331 C->getEndLoc());
10332}
10333
10334template <typename Derived>
10335OMPClause *
10336TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10337 ExprResult ER;
10338 if (Expr *IV = C->getInteropVar()) {
10339 ER = getDerived().TransformExpr(IV);
10340 if (ER.isInvalid())
10341 return nullptr;
10342 }
10343 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10344 C->getLParenLoc(), C->getVarLoc(),
10345 C->getEndLoc());
10346}
10347
10348template <typename Derived>
10349OMPClause *
10350TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10351 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10352 if (Cond.isInvalid())
10353 return nullptr;
10354 return getDerived().RebuildOMPNovariantsClause(
10355 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10356}
10357
10358template <typename Derived>
10359OMPClause *
10360TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10361 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10362 if (Cond.isInvalid())
10363 return nullptr;
10364 return getDerived().RebuildOMPNocontextClause(
10365 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10366}
10367
10368template <typename Derived>
10369OMPClause *
10370TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10371 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10372 if (ThreadID.isInvalid())
10373 return nullptr;
10374 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10375 C->getLParenLoc(), C->getEndLoc());
10376}
10377
10378template <typename Derived>
10379OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10380 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10381 if (E.isInvalid())
10382 return nullptr;
10383 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10384 C->getLParenLoc(), C->getEndLoc());
10385}
10386
10387template <typename Derived>
10388OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10389 OMPUnifiedAddressClause *C) {
10390 llvm_unreachable("unified_address clause cannot appear in dependent context");
10391}
10392
10393template <typename Derived>
10394OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10395 OMPUnifiedSharedMemoryClause *C) {
10396 llvm_unreachable(
10397 "unified_shared_memory clause cannot appear in dependent context");
10398}
10399
10400template <typename Derived>
10401OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10402 OMPReverseOffloadClause *C) {
10403 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10404}
10405
10406template <typename Derived>
10407OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10408 OMPDynamicAllocatorsClause *C) {
10409 llvm_unreachable(
10410 "dynamic_allocators clause cannot appear in dependent context");
10411}
10412
10413template <typename Derived>
10414OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10415 OMPAtomicDefaultMemOrderClause *C) {
10416 llvm_unreachable(
10417 "atomic_default_mem_order clause cannot appear in dependent context");
10418}
10419
10420template <typename Derived>
10421OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10422 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10423 C->getBeginLoc(), C->getLParenLoc(),
10424 C->getEndLoc());
10425}
10426
10427template <typename Derived>
10428OMPClause *
10429TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10430 return getDerived().RebuildOMPSeverityClause(
10431 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10432 C->getLParenLoc(), C->getEndLoc());
10433}
10434
10435template <typename Derived>
10436OMPClause *
10437TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10438 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10439 if (E.isInvalid())
10440 return nullptr;
10441 return getDerived().RebuildOMPMessageClause(
10442 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10443 C->getEndLoc());
10444}
10445
10446template <typename Derived>
10447OMPClause *
10448TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10449 llvm::SmallVector<Expr *, 16> Vars;
10450 Vars.reserve(N: C->varlist_size());
10451 for (auto *VE : C->varlists()) {
10452 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10453 if (EVar.isInvalid())
10454 return nullptr;
10455 Vars.push_back(Elt: EVar.get());
10456 }
10457 return getDerived().RebuildOMPPrivateClause(
10458 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10459}
10460
10461template <typename Derived>
10462OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10463 OMPFirstprivateClause *C) {
10464 llvm::SmallVector<Expr *, 16> Vars;
10465 Vars.reserve(N: C->varlist_size());
10466 for (auto *VE : C->varlists()) {
10467 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10468 if (EVar.isInvalid())
10469 return nullptr;
10470 Vars.push_back(Elt: EVar.get());
10471 }
10472 return getDerived().RebuildOMPFirstprivateClause(
10473 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10474}
10475
10476template <typename Derived>
10477OMPClause *
10478TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10479 llvm::SmallVector<Expr *, 16> Vars;
10480 Vars.reserve(N: C->varlist_size());
10481 for (auto *VE : C->varlists()) {
10482 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10483 if (EVar.isInvalid())
10484 return nullptr;
10485 Vars.push_back(Elt: EVar.get());
10486 }
10487 return getDerived().RebuildOMPLastprivateClause(
10488 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10489 C->getLParenLoc(), C->getEndLoc());
10490}
10491
10492template <typename Derived>
10493OMPClause *
10494TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10495 llvm::SmallVector<Expr *, 16> Vars;
10496 Vars.reserve(N: C->varlist_size());
10497 for (auto *VE : C->varlists()) {
10498 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10499 if (EVar.isInvalid())
10500 return nullptr;
10501 Vars.push_back(Elt: EVar.get());
10502 }
10503 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10504 C->getLParenLoc(), C->getEndLoc());
10505}
10506
10507template <typename Derived>
10508OMPClause *
10509TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10510 llvm::SmallVector<Expr *, 16> Vars;
10511 Vars.reserve(N: C->varlist_size());
10512 for (auto *VE : C->varlists()) {
10513 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10514 if (EVar.isInvalid())
10515 return nullptr;
10516 Vars.push_back(Elt: EVar.get());
10517 }
10518 CXXScopeSpec ReductionIdScopeSpec;
10519 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10520
10521 DeclarationNameInfo NameInfo = C->getNameInfo();
10522 if (NameInfo.getName()) {
10523 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10524 if (!NameInfo.getName())
10525 return nullptr;
10526 }
10527 // Build a list of all UDR decls with the same names ranged by the Scopes.
10528 // The Scope boundary is a duplication of the previous decl.
10529 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10530 for (auto *E : C->reduction_ops()) {
10531 // Transform all the decls.
10532 if (E) {
10533 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
10534 UnresolvedSet<8> Decls;
10535 for (auto *D : ULE->decls()) {
10536 NamedDecl *InstD =
10537 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10538 Decls.addDecl(D: InstD, AS: InstD->getAccess());
10539 }
10540 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
10541 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
10542 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
10543 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
10544 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
10545 } else
10546 UnresolvedReductions.push_back(Elt: nullptr);
10547 }
10548 return getDerived().RebuildOMPReductionClause(
10549 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10550 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10551 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10552}
10553
10554template <typename Derived>
10555OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10556 OMPTaskReductionClause *C) {
10557 llvm::SmallVector<Expr *, 16> Vars;
10558 Vars.reserve(N: C->varlist_size());
10559 for (auto *VE : C->varlists()) {
10560 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10561 if (EVar.isInvalid())
10562 return nullptr;
10563 Vars.push_back(Elt: EVar.get());
10564 }
10565 CXXScopeSpec ReductionIdScopeSpec;
10566 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10567
10568 DeclarationNameInfo NameInfo = C->getNameInfo();
10569 if (NameInfo.getName()) {
10570 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10571 if (!NameInfo.getName())
10572 return nullptr;
10573 }
10574 // Build a list of all UDR decls with the same names ranged by the Scopes.
10575 // The Scope boundary is a duplication of the previous decl.
10576 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10577 for (auto *E : C->reduction_ops()) {
10578 // Transform all the decls.
10579 if (E) {
10580 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
10581 UnresolvedSet<8> Decls;
10582 for (auto *D : ULE->decls()) {
10583 NamedDecl *InstD =
10584 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10585 Decls.addDecl(D: InstD, AS: InstD->getAccess());
10586 }
10587 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
10588 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
10589 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
10590 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
10591 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
10592 } else
10593 UnresolvedReductions.push_back(Elt: nullptr);
10594 }
10595 return getDerived().RebuildOMPTaskReductionClause(
10596 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10597 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10598}
10599
10600template <typename Derived>
10601OMPClause *
10602TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10603 llvm::SmallVector<Expr *, 16> Vars;
10604 Vars.reserve(N: C->varlist_size());
10605 for (auto *VE : C->varlists()) {
10606 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10607 if (EVar.isInvalid())
10608 return nullptr;
10609 Vars.push_back(Elt: EVar.get());
10610 }
10611 CXXScopeSpec ReductionIdScopeSpec;
10612 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10613
10614 DeclarationNameInfo NameInfo = C->getNameInfo();
10615 if (NameInfo.getName()) {
10616 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10617 if (!NameInfo.getName())
10618 return nullptr;
10619 }
10620 // Build a list of all UDR decls with the same names ranged by the Scopes.
10621 // The Scope boundary is a duplication of the previous decl.
10622 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10623 for (auto *E : C->reduction_ops()) {
10624 // Transform all the decls.
10625 if (E) {
10626 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
10627 UnresolvedSet<8> Decls;
10628 for (auto *D : ULE->decls()) {
10629 NamedDecl *InstD =
10630 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10631 Decls.addDecl(D: InstD, AS: InstD->getAccess());
10632 }
10633 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
10634 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
10635 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
10636 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
10637 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
10638 } else
10639 UnresolvedReductions.push_back(Elt: nullptr);
10640 }
10641 return getDerived().RebuildOMPInReductionClause(
10642 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10643 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10644}
10645
10646template <typename Derived>
10647OMPClause *
10648TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10649 llvm::SmallVector<Expr *, 16> Vars;
10650 Vars.reserve(N: C->varlist_size());
10651 for (auto *VE : C->varlists()) {
10652 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10653 if (EVar.isInvalid())
10654 return nullptr;
10655 Vars.push_back(Elt: EVar.get());
10656 }
10657 ExprResult Step = getDerived().TransformExpr(C->getStep());
10658 if (Step.isInvalid())
10659 return nullptr;
10660 return getDerived().RebuildOMPLinearClause(
10661 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10662 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10663 C->getEndLoc());
10664}
10665
10666template <typename Derived>
10667OMPClause *
10668TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10669 llvm::SmallVector<Expr *, 16> Vars;
10670 Vars.reserve(N: C->varlist_size());
10671 for (auto *VE : C->varlists()) {
10672 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10673 if (EVar.isInvalid())
10674 return nullptr;
10675 Vars.push_back(Elt: EVar.get());
10676 }
10677 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10678 if (Alignment.isInvalid())
10679 return nullptr;
10680 return getDerived().RebuildOMPAlignedClause(
10681 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10682 C->getColonLoc(), C->getEndLoc());
10683}
10684
10685template <typename Derived>
10686OMPClause *
10687TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10688 llvm::SmallVector<Expr *, 16> Vars;
10689 Vars.reserve(N: C->varlist_size());
10690 for (auto *VE : C->varlists()) {
10691 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10692 if (EVar.isInvalid())
10693 return nullptr;
10694 Vars.push_back(Elt: EVar.get());
10695 }
10696 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10697 C->getLParenLoc(), C->getEndLoc());
10698}
10699
10700template <typename Derived>
10701OMPClause *
10702TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10703 llvm::SmallVector<Expr *, 16> Vars;
10704 Vars.reserve(N: C->varlist_size());
10705 for (auto *VE : C->varlists()) {
10706 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10707 if (EVar.isInvalid())
10708 return nullptr;
10709 Vars.push_back(Elt: EVar.get());
10710 }
10711 return getDerived().RebuildOMPCopyprivateClause(
10712 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10713}
10714
10715template <typename Derived>
10716OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10717 llvm::SmallVector<Expr *, 16> Vars;
10718 Vars.reserve(N: C->varlist_size());
10719 for (auto *VE : C->varlists()) {
10720 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10721 if (EVar.isInvalid())
10722 return nullptr;
10723 Vars.push_back(Elt: EVar.get());
10724 }
10725 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10726 C->getLParenLoc(), C->getEndLoc());
10727}
10728
10729template <typename Derived>
10730OMPClause *
10731TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10732 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10733 if (E.isInvalid())
10734 return nullptr;
10735 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10736 C->getLParenLoc(), C->getEndLoc());
10737}
10738
10739template <typename Derived>
10740OMPClause *
10741TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10742 llvm::SmallVector<Expr *, 16> Vars;
10743 Expr *DepModifier = C->getModifier();
10744 if (DepModifier) {
10745 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10746 if (DepModRes.isInvalid())
10747 return nullptr;
10748 DepModifier = DepModRes.get();
10749 }
10750 Vars.reserve(N: C->varlist_size());
10751 for (auto *VE : C->varlists()) {
10752 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10753 if (EVar.isInvalid())
10754 return nullptr;
10755 Vars.push_back(Elt: EVar.get());
10756 }
10757 return getDerived().RebuildOMPDependClause(
10758 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10759 C->getOmpAllMemoryLoc()},
10760 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10761}
10762
10763template <typename Derived>
10764OMPClause *
10765TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10766 ExprResult E = getDerived().TransformExpr(C->getDevice());
10767 if (E.isInvalid())
10768 return nullptr;
10769 return getDerived().RebuildOMPDeviceClause(
10770 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10771 C->getModifierLoc(), C->getEndLoc());
10772}
10773
10774template <typename Derived, class T>
10775bool transformOMPMappableExprListClause(
10776 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10777 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10778 DeclarationNameInfo &MapperIdInfo,
10779 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10780 // Transform expressions in the list.
10781 Vars.reserve(N: C->varlist_size());
10782 for (auto *VE : C->varlists()) {
10783 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10784 if (EVar.isInvalid())
10785 return true;
10786 Vars.push_back(Elt: EVar.get());
10787 }
10788 // Transform mapper scope specifier and identifier.
10789 NestedNameSpecifierLoc QualifierLoc;
10790 if (C->getMapperQualifierLoc()) {
10791 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10792 C->getMapperQualifierLoc());
10793 if (!QualifierLoc)
10794 return true;
10795 }
10796 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
10797 MapperIdInfo = C->getMapperIdInfo();
10798 if (MapperIdInfo.getName()) {
10799 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10800 if (!MapperIdInfo.getName())
10801 return true;
10802 }
10803 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10804 // the previous user-defined mapper lookup in dependent environment.
10805 for (auto *E : C->mapperlists()) {
10806 // Transform all the decls.
10807 if (E) {
10808 auto *ULE = cast<UnresolvedLookupExpr>(E);
10809 UnresolvedSet<8> Decls;
10810 for (auto *D : ULE->decls()) {
10811 NamedDecl *InstD =
10812 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10813 Decls.addDecl(D: InstD, AS: InstD->getAccess());
10814 }
10815 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
10816 TT.getSema().Context, /*NamingClass=*/nullptr,
10817 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
10818 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
10819 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10820 } else {
10821 UnresolvedMappers.push_back(Elt: nullptr);
10822 }
10823 }
10824 return false;
10825}
10826
10827template <typename Derived>
10828OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10829 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10830 llvm::SmallVector<Expr *, 16> Vars;
10831 Expr *IteratorModifier = C->getIteratorModifier();
10832 if (IteratorModifier) {
10833 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10834 if (MapModRes.isInvalid())
10835 return nullptr;
10836 IteratorModifier = MapModRes.get();
10837 }
10838 CXXScopeSpec MapperIdScopeSpec;
10839 DeclarationNameInfo MapperIdInfo;
10840 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10841 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10842 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10843 return nullptr;
10844 return getDerived().RebuildOMPMapClause(
10845 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10846 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10847 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10848}
10849
10850template <typename Derived>
10851OMPClause *
10852TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10853 Expr *Allocator = C->getAllocator();
10854 if (Allocator) {
10855 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10856 if (AllocatorRes.isInvalid())
10857 return nullptr;
10858 Allocator = AllocatorRes.get();
10859 }
10860 llvm::SmallVector<Expr *, 16> Vars;
10861 Vars.reserve(N: C->varlist_size());
10862 for (auto *VE : C->varlists()) {
10863 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10864 if (EVar.isInvalid())
10865 return nullptr;
10866 Vars.push_back(Elt: EVar.get());
10867 }
10868 return getDerived().RebuildOMPAllocateClause(
10869 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10870 C->getEndLoc());
10871}
10872
10873template <typename Derived>
10874OMPClause *
10875TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10876 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10877 if (E.isInvalid())
10878 return nullptr;
10879 return getDerived().RebuildOMPNumTeamsClause(
10880 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10881}
10882
10883template <typename Derived>
10884OMPClause *
10885TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10886 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10887 if (E.isInvalid())
10888 return nullptr;
10889 return getDerived().RebuildOMPThreadLimitClause(
10890 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10891}
10892
10893template <typename Derived>
10894OMPClause *
10895TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10896 ExprResult E = getDerived().TransformExpr(C->getPriority());
10897 if (E.isInvalid())
10898 return nullptr;
10899 return getDerived().RebuildOMPPriorityClause(
10900 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10901}
10902
10903template <typename Derived>
10904OMPClause *
10905TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10906 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10907 if (E.isInvalid())
10908 return nullptr;
10909 return getDerived().RebuildOMPGrainsizeClause(
10910 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10911 C->getModifierLoc(), C->getEndLoc());
10912}
10913
10914template <typename Derived>
10915OMPClause *
10916TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10917 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10918 if (E.isInvalid())
10919 return nullptr;
10920 return getDerived().RebuildOMPNumTasksClause(
10921 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10922 C->getModifierLoc(), C->getEndLoc());
10923}
10924
10925template <typename Derived>
10926OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10927 ExprResult E = getDerived().TransformExpr(C->getHint());
10928 if (E.isInvalid())
10929 return nullptr;
10930 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10931 C->getLParenLoc(), C->getEndLoc());
10932}
10933
10934template <typename Derived>
10935OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10936 OMPDistScheduleClause *C) {
10937 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10938 if (E.isInvalid())
10939 return nullptr;
10940 return getDerived().RebuildOMPDistScheduleClause(
10941 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10942 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10943}
10944
10945template <typename Derived>
10946OMPClause *
10947TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10948 // Rebuild Defaultmap Clause since we need to invoke the checking of
10949 // defaultmap(none:variable-category) after template initialization.
10950 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10951 C->getDefaultmapKind(),
10952 C->getBeginLoc(),
10953 C->getLParenLoc(),
10954 C->getDefaultmapModifierLoc(),
10955 C->getDefaultmapKindLoc(),
10956 C->getEndLoc());
10957}
10958
10959template <typename Derived>
10960OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10961 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10962 llvm::SmallVector<Expr *, 16> Vars;
10963 CXXScopeSpec MapperIdScopeSpec;
10964 DeclarationNameInfo MapperIdInfo;
10965 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10966 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10967 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10968 return nullptr;
10969 return getDerived().RebuildOMPToClause(
10970 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10971 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10972}
10973
10974template <typename Derived>
10975OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10976 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10977 llvm::SmallVector<Expr *, 16> Vars;
10978 CXXScopeSpec MapperIdScopeSpec;
10979 DeclarationNameInfo MapperIdInfo;
10980 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10981 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10982 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10983 return nullptr;
10984 return getDerived().RebuildOMPFromClause(
10985 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10986 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10987}
10988
10989template <typename Derived>
10990OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10991 OMPUseDevicePtrClause *C) {
10992 llvm::SmallVector<Expr *, 16> Vars;
10993 Vars.reserve(N: C->varlist_size());
10994 for (auto *VE : C->varlists()) {
10995 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10996 if (EVar.isInvalid())
10997 return nullptr;
10998 Vars.push_back(Elt: EVar.get());
10999 }
11000 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11001 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11002}
11003
11004template <typename Derived>
11005OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11006 OMPUseDeviceAddrClause *C) {
11007 llvm::SmallVector<Expr *, 16> Vars;
11008 Vars.reserve(N: C->varlist_size());
11009 for (auto *VE : C->varlists()) {
11010 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11011 if (EVar.isInvalid())
11012 return nullptr;
11013 Vars.push_back(Elt: EVar.get());
11014 }
11015 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11016 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11017}
11018
11019template <typename Derived>
11020OMPClause *
11021TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11022 llvm::SmallVector<Expr *, 16> Vars;
11023 Vars.reserve(N: C->varlist_size());
11024 for (auto *VE : C->varlists()) {
11025 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11026 if (EVar.isInvalid())
11027 return nullptr;
11028 Vars.push_back(Elt: EVar.get());
11029 }
11030 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11031 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11032}
11033
11034template <typename Derived>
11035OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11036 OMPHasDeviceAddrClause *C) {
11037 llvm::SmallVector<Expr *, 16> Vars;
11038 Vars.reserve(N: C->varlist_size());
11039 for (auto *VE : C->varlists()) {
11040 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11041 if (EVar.isInvalid())
11042 return nullptr;
11043 Vars.push_back(Elt: EVar.get());
11044 }
11045 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11046 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11047}
11048
11049template <typename Derived>
11050OMPClause *
11051TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11052 llvm::SmallVector<Expr *, 16> Vars;
11053 Vars.reserve(N: C->varlist_size());
11054 for (auto *VE : C->varlists()) {
11055 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11056 if (EVar.isInvalid())
11057 return nullptr;
11058 Vars.push_back(Elt: EVar.get());
11059 }
11060 return getDerived().RebuildOMPNontemporalClause(
11061 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11062}
11063
11064template <typename Derived>
11065OMPClause *
11066TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11067 llvm::SmallVector<Expr *, 16> Vars;
11068 Vars.reserve(N: C->varlist_size());
11069 for (auto *VE : C->varlists()) {
11070 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11071 if (EVar.isInvalid())
11072 return nullptr;
11073 Vars.push_back(Elt: EVar.get());
11074 }
11075 return getDerived().RebuildOMPInclusiveClause(
11076 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11077}
11078
11079template <typename Derived>
11080OMPClause *
11081TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11082 llvm::SmallVector<Expr *, 16> Vars;
11083 Vars.reserve(N: C->varlist_size());
11084 for (auto *VE : C->varlists()) {
11085 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11086 if (EVar.isInvalid())
11087 return nullptr;
11088 Vars.push_back(Elt: EVar.get());
11089 }
11090 return getDerived().RebuildOMPExclusiveClause(
11091 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11092}
11093
11094template <typename Derived>
11095OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11096 OMPUsesAllocatorsClause *C) {
11097 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11098 Data.reserve(N: C->getNumberOfAllocators());
11099 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11100 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11101 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11102 if (Allocator.isInvalid())
11103 continue;
11104 ExprResult AllocatorTraits;
11105 if (Expr *AT = D.AllocatorTraits) {
11106 AllocatorTraits = getDerived().TransformExpr(AT);
11107 if (AllocatorTraits.isInvalid())
11108 continue;
11109 }
11110 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11111 NewD.Allocator = Allocator.get();
11112 NewD.AllocatorTraits = AllocatorTraits.get();
11113 NewD.LParenLoc = D.LParenLoc;
11114 NewD.RParenLoc = D.RParenLoc;
11115 }
11116 return getDerived().RebuildOMPUsesAllocatorsClause(
11117 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11118}
11119
11120template <typename Derived>
11121OMPClause *
11122TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11123 SmallVector<Expr *, 4> Locators;
11124 Locators.reserve(N: C->varlist_size());
11125 ExprResult ModifierRes;
11126 if (Expr *Modifier = C->getModifier()) {
11127 ModifierRes = getDerived().TransformExpr(Modifier);
11128 if (ModifierRes.isInvalid())
11129 return nullptr;
11130 }
11131 for (Expr *E : C->varlists()) {
11132 ExprResult Locator = getDerived().TransformExpr(E);
11133 if (Locator.isInvalid())
11134 continue;
11135 Locators.push_back(Elt: Locator.get());
11136 }
11137 return getDerived().RebuildOMPAffinityClause(
11138 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11139 ModifierRes.get(), Locators);
11140}
11141
11142template <typename Derived>
11143OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11144 return getDerived().RebuildOMPOrderClause(
11145 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11146 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11147}
11148
11149template <typename Derived>
11150OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11151 return getDerived().RebuildOMPBindClause(
11152 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11153 C->getLParenLoc(), C->getEndLoc());
11154}
11155
11156template <typename Derived>
11157OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11158 OMPXDynCGroupMemClause *C) {
11159 ExprResult Size = getDerived().TransformExpr(C->getSize());
11160 if (Size.isInvalid())
11161 return nullptr;
11162 return getDerived().RebuildOMPXDynCGroupMemClause(
11163 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11164}
11165
11166template <typename Derived>
11167OMPClause *
11168TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11169 llvm::SmallVector<Expr *, 16> Vars;
11170 Vars.reserve(N: C->varlist_size());
11171 for (auto *VE : C->varlists()) {
11172 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11173 if (EVar.isInvalid())
11174 return nullptr;
11175 Vars.push_back(Elt: EVar.get());
11176 }
11177 return getDerived().RebuildOMPDoacrossClause(
11178 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11179 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11180}
11181
11182template <typename Derived>
11183OMPClause *
11184TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11185 SmallVector<const Attr *> NewAttrs;
11186 for (auto *A : C->getAttrs())
11187 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11188 return getDerived().RebuildOMPXAttributeClause(
11189 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11190}
11191
11192template <typename Derived>
11193OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11194 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11195}
11196
11197//===----------------------------------------------------------------------===//
11198// OpenACC transformation
11199//===----------------------------------------------------------------------===//
11200namespace {
11201template <typename Derived>
11202class OpenACCClauseTransform final
11203 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11204 TreeTransform<Derived> &Self;
11205 ArrayRef<const OpenACCClause *> ExistingClauses;
11206 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11207 OpenACCClause *NewClause = nullptr;
11208
11209 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11210 llvm::SmallVector<Expr *> InstantiatedVarList;
11211 for (Expr *CurVar : VarList) {
11212 ExprResult Res = Self.TransformExpr(CurVar);
11213
11214 if (!Res.isUsable())
11215 continue;
11216
11217 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11218 Res.get());
11219
11220 if (Res.isUsable())
11221 InstantiatedVarList.push_back(Elt: Res.get());
11222 }
11223
11224 return InstantiatedVarList;
11225 }
11226
11227public:
11228 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11229 ArrayRef<const OpenACCClause *> ExistingClauses,
11230 SemaOpenACC::OpenACCParsedClause &PC)
11231 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11232
11233 OpenACCClause *CreatedClause() const { return NewClause; }
11234
11235#define VISIT_CLAUSE(CLAUSE_NAME) \
11236 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11237#include "clang/Basic/OpenACCClauses.def"
11238};
11239
11240template <typename Derived>
11241void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11242 const OpenACCDefaultClause &C) {
11243 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11244
11245 NewClause = OpenACCDefaultClause::Create(
11246 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11247 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11248 EndLoc: ParsedClause.getEndLoc());
11249}
11250
11251template <typename Derived>
11252void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11253 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11254 assert(Cond && "If constructed with invalid Condition");
11255 Sema::ConditionResult Res = Self.TransformCondition(
11256 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11257
11258 if (Res.isInvalid() || !Res.get().second)
11259 return;
11260
11261 ParsedClause.setConditionDetails(Res.get().second);
11262
11263 NewClause = OpenACCIfClause::Create(
11264 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11265 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11266 EndLoc: ParsedClause.getEndLoc());
11267}
11268
11269template <typename Derived>
11270void OpenACCClauseTransform<Derived>::VisitSelfClause(
11271 const OpenACCSelfClause &C) {
11272
11273 if (C.hasConditionExpr()) {
11274 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11275 Sema::ConditionResult Res =
11276 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11277 Sema::ConditionKind::Boolean);
11278
11279 if (Res.isInvalid() || !Res.get().second)
11280 return;
11281
11282 ParsedClause.setConditionDetails(Res.get().second);
11283 }
11284
11285 NewClause = OpenACCSelfClause::Create(
11286 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11287 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11288 EndLoc: ParsedClause.getEndLoc());
11289}
11290
11291template <typename Derived>
11292void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11293 const OpenACCNumGangsClause &C) {
11294 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11295
11296 for (Expr *CurIntExpr : C.getIntExprs()) {
11297 ExprResult Res = Self.TransformExpr(CurIntExpr);
11298
11299 if (!Res.isUsable())
11300 return;
11301
11302 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11303 C.getClauseKind(),
11304 C.getBeginLoc(), Res.get());
11305 if (!Res.isUsable())
11306 return;
11307
11308 InstantiatedIntExprs.push_back(Elt: Res.get());
11309 }
11310
11311 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11312 NewClause = OpenACCNumGangsClause::Create(
11313 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11314 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
11315 EndLoc: ParsedClause.getEndLoc());
11316}
11317
11318template <typename Derived>
11319void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11320 const OpenACCPrivateClause &C) {
11321 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11322 /*IsReadOnly=*/false, /*IsZero=*/false);
11323
11324 NewClause = OpenACCPrivateClause::Create(
11325 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11326 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11327 EndLoc: ParsedClause.getEndLoc());
11328}
11329
11330template <typename Derived>
11331void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11332 const OpenACCFirstPrivateClause &C) {
11333 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11334 /*IsReadOnly=*/false, /*IsZero=*/false);
11335
11336 NewClause = OpenACCFirstPrivateClause::Create(
11337 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11338 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11339 EndLoc: ParsedClause.getEndLoc());
11340}
11341
11342template <typename Derived>
11343void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11344 const OpenACCNoCreateClause &C) {
11345 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11346 /*IsReadOnly=*/false, /*IsZero=*/false);
11347
11348 NewClause = OpenACCNoCreateClause::Create(
11349 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11350 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11351 EndLoc: ParsedClause.getEndLoc());
11352}
11353
11354template <typename Derived>
11355void OpenACCClauseTransform<Derived>::VisitPresentClause(
11356 const OpenACCPresentClause &C) {
11357 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11358 /*IsReadOnly=*/false, /*IsZero=*/false);
11359
11360 NewClause = OpenACCPresentClause::Create(
11361 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11362 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11363 EndLoc: ParsedClause.getEndLoc());
11364}
11365
11366template <typename Derived>
11367void OpenACCClauseTransform<Derived>::VisitCopyClause(
11368 const OpenACCCopyClause &C) {
11369 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11370 /*IsReadOnly=*/false, /*IsZero=*/false);
11371
11372 NewClause = OpenACCCopyClause::Create(
11373 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11374 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11375 VarList: ParsedClause.getVarList(), EndLoc: ParsedClause.getEndLoc());
11376}
11377
11378template <typename Derived>
11379void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11380 const OpenACCCopyInClause &C) {
11381 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()), C.isReadOnly(),
11382 /*IsZero=*/false);
11383
11384 NewClause = OpenACCCopyInClause::Create(
11385 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11386 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11387 IsReadOnly: ParsedClause.isReadOnly(), VarList: ParsedClause.getVarList(),
11388 EndLoc: ParsedClause.getEndLoc());
11389}
11390
11391template <typename Derived>
11392void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11393 const OpenACCCopyOutClause &C) {
11394 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11395 /*IsReadOnly=*/false, C.isZero());
11396
11397 NewClause = OpenACCCopyOutClause::Create(
11398 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11399 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11400 IsZero: ParsedClause.isZero(), VarList: ParsedClause.getVarList(),
11401 EndLoc: ParsedClause.getEndLoc());
11402}
11403
11404template <typename Derived>
11405void OpenACCClauseTransform<Derived>::VisitCreateClause(
11406 const OpenACCCreateClause &C) {
11407 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11408 /*IsReadOnly=*/false, C.isZero());
11409
11410 NewClause = OpenACCCreateClause::Create(
11411 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11412 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11413 IsZero: ParsedClause.isZero(), VarList: ParsedClause.getVarList(),
11414 EndLoc: ParsedClause.getEndLoc());
11415}
11416template <typename Derived>
11417void OpenACCClauseTransform<Derived>::VisitAttachClause(
11418 const OpenACCAttachClause &C) {
11419 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
11420
11421 // Ensure each var is a pointer type.
11422 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11423 return Self.getSema().OpenACC().CheckVarIsPointerType(
11424 OpenACCClauseKind::Attach, E);
11425 }), VarList.end());
11426
11427 ParsedClause.setVarListDetails(VarList,
11428 /*IsReadOnly=*/IsReadOnly: false, /*IsZero=*/IsZero: false);
11429 NewClause = OpenACCAttachClause::Create(
11430 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11431 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11432 EndLoc: ParsedClause.getEndLoc());
11433}
11434
11435template <typename Derived>
11436void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
11437 const OpenACCDevicePtrClause &C) {
11438 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
11439
11440 // Ensure each var is a pointer type.
11441 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11442 return Self.getSema().OpenACC().CheckVarIsPointerType(
11443 OpenACCClauseKind::DevicePtr, E);
11444 }), VarList.end());
11445
11446 ParsedClause.setVarListDetails(VarList,
11447 /*IsReadOnly=*/IsReadOnly: false, /*IsZero=*/IsZero: false);
11448 NewClause = OpenACCDevicePtrClause::Create(
11449 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11450 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11451 EndLoc: ParsedClause.getEndLoc());
11452}
11453
11454template <typename Derived>
11455void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11456 const OpenACCNumWorkersClause &C) {
11457 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11458 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11459
11460 ExprResult Res = Self.TransformExpr(IntExpr);
11461 if (!Res.isUsable())
11462 return;
11463
11464 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11465 C.getClauseKind(),
11466 C.getBeginLoc(), Res.get());
11467 if (!Res.isUsable())
11468 return;
11469
11470 ParsedClause.setIntExprDetails(Res.get());
11471 NewClause = OpenACCNumWorkersClause::Create(
11472 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11473 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
11474 EndLoc: ParsedClause.getEndLoc());
11475}
11476
11477template <typename Derived>
11478void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
11479 const OpenACCVectorLengthClause &C) {
11480 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11481 assert(IntExpr && "vector_length clause constructed with invalid int expr");
11482
11483 ExprResult Res = Self.TransformExpr(IntExpr);
11484 if (!Res.isUsable())
11485 return;
11486
11487 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11488 C.getClauseKind(),
11489 C.getBeginLoc(), Res.get());
11490 if (!Res.isUsable())
11491 return;
11492
11493 ParsedClause.setIntExprDetails(Res.get());
11494 NewClause = OpenACCVectorLengthClause::Create(
11495 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11496 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
11497 EndLoc: ParsedClause.getEndLoc());
11498}
11499
11500template <typename Derived>
11501void OpenACCClauseTransform<Derived>::VisitAsyncClause(
11502 const OpenACCAsyncClause &C) {
11503 if (C.hasIntExpr()) {
11504 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
11505 if (!Res.isUsable())
11506 return;
11507
11508 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11509 C.getClauseKind(),
11510 C.getBeginLoc(), Res.get());
11511 if (!Res.isUsable())
11512 return;
11513 ParsedClause.setIntExprDetails(Res.get());
11514 }
11515
11516 NewClause = OpenACCAsyncClause::Create(
11517 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11518 LParenLoc: ParsedClause.getLParenLoc(),
11519 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
11520 : nullptr,
11521 EndLoc: ParsedClause.getEndLoc());
11522}
11523template <typename Derived>
11524void OpenACCClauseTransform<Derived>::VisitWaitClause(
11525 const OpenACCWaitClause &C) {
11526 if (!C.getLParenLoc().isInvalid()) {
11527 Expr *DevNumExpr = nullptr;
11528 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
11529
11530 // Instantiate devnum expr if it exists.
11531 if (C.getDevNumExpr()) {
11532 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
11533 if (!Res.isUsable())
11534 return;
11535 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11536 C.getClauseKind(),
11537 C.getBeginLoc(), Res.get());
11538 if (!Res.isUsable())
11539 return;
11540
11541 DevNumExpr = Res.get();
11542 }
11543
11544 // Instantiate queue ids.
11545 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
11546 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
11547 if (!Res.isUsable())
11548 return;
11549 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11550 C.getClauseKind(),
11551 C.getBeginLoc(), Res.get());
11552 if (!Res.isUsable())
11553 return;
11554
11555 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
11556 }
11557
11558 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
11559 IntExprs: std::move(InstantiatedQueueIdExprs));
11560 }
11561
11562 NewClause = OpenACCWaitClause::Create(
11563 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11564 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
11565 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
11566 EndLoc: ParsedClause.getEndLoc());
11567}
11568
11569template <typename Derived>
11570void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
11571 const OpenACCDeviceTypeClause &C) {
11572 // Nothing to transform here, just create a new version of 'C'.
11573 NewClause = OpenACCDeviceTypeClause::Create(
11574 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
11575 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11576 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
11577}
11578
11579template <typename Derived>
11580void OpenACCClauseTransform<Derived>::VisitAutoClause(
11581 const OpenACCAutoClause &C) {
11582 // Nothing to do, so just create a new node.
11583 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
11584 BeginLoc: ParsedClause.getBeginLoc(),
11585 EndLoc: ParsedClause.getEndLoc());
11586}
11587
11588template <typename Derived>
11589void OpenACCClauseTransform<Derived>::VisitIndependentClause(
11590 const OpenACCIndependentClause &C) {
11591 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
11592 BeginLoc: ParsedClause.getBeginLoc(),
11593 EndLoc: ParsedClause.getEndLoc());
11594}
11595
11596template <typename Derived>
11597void OpenACCClauseTransform<Derived>::VisitSeqClause(
11598 const OpenACCSeqClause &C) {
11599 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
11600 BeginLoc: ParsedClause.getBeginLoc(),
11601 EndLoc: ParsedClause.getEndLoc());
11602}
11603
11604template <typename Derived>
11605void OpenACCClauseTransform<Derived>::VisitReductionClause(
11606 const OpenACCReductionClause &C) {
11607 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
11608 SmallVector<Expr *> ValidVars;
11609
11610 for (Expr *Var : TransformedVars) {
11611 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(Var);
11612 if (Res.isUsable())
11613 ValidVars.push_back(Elt: Res.get());
11614 }
11615
11616 NewClause = OpenACCReductionClause::Create(
11617 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11618 LParenLoc: ParsedClause.getLParenLoc(), Operator: C.getReductionOp(), VarList: ValidVars,
11619 EndLoc: ParsedClause.getEndLoc());
11620}
11621} // namespace
11622template <typename Derived>
11623OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
11624 ArrayRef<const OpenACCClause *> ExistingClauses,
11625 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
11626
11627 SemaOpenACC::OpenACCParsedClause ParsedClause(
11628 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
11629 ParsedClause.setEndLoc(OldClause->getEndLoc());
11630
11631 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
11632 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
11633
11634 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
11635 ParsedClause};
11636 Transform.Visit(OldClause);
11637
11638 return Transform.CreatedClause();
11639}
11640
11641template <typename Derived>
11642llvm::SmallVector<OpenACCClause *>
11643TreeTransform<Derived>::TransformOpenACCClauseList(
11644 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
11645 llvm::SmallVector<OpenACCClause *> TransformedClauses;
11646 for (const auto *Clause : OldClauses) {
11647 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
11648 TransformedClauses, DirKind, Clause))
11649 TransformedClauses.push_back(Elt: TransformedClause);
11650 }
11651 return TransformedClauses;
11652}
11653
11654template <typename Derived>
11655StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
11656 OpenACCComputeConstruct *C) {
11657 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
11658
11659 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
11660 C->getBeginLoc()))
11661 return StmtError();
11662
11663 llvm::SmallVector<OpenACCClause *> TransformedClauses =
11664 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
11665 C->clauses());
11666 // Transform Structured Block.
11667 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getSema().OpenACC(),
11668 C->getDirectiveKind());
11669 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
11670 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
11671 C->getBeginLoc(), C->getDirectiveKind(), StrBlock);
11672
11673 return getDerived().RebuildOpenACCComputeConstruct(
11674 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
11675 C->getEndLoc(), TransformedClauses, StrBlock);
11676}
11677
11678template <typename Derived>
11679StmtResult
11680TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
11681
11682 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
11683
11684 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
11685 C->getBeginLoc()))
11686 return StmtError();
11687
11688 llvm::SmallVector<OpenACCClause *> TransformedClauses =
11689 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
11690 C->clauses());
11691
11692 // Transform Loop.
11693 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getSema().OpenACC(),
11694 C->getDirectiveKind());
11695 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
11696 Loop = getSema().OpenACC().ActOnAssociatedStmt(C->getBeginLoc(),
11697 C->getDirectiveKind(), Loop);
11698
11699 return getDerived().RebuildOpenACCLoopConstruct(
11700 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
11701 TransformedClauses, Loop);
11702}
11703
11704//===----------------------------------------------------------------------===//
11705// Expression transformation
11706//===----------------------------------------------------------------------===//
11707template<typename Derived>
11708ExprResult
11709TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
11710 return TransformExpr(E: E->getSubExpr());
11711}
11712
11713template <typename Derived>
11714ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
11715 SYCLUniqueStableNameExpr *E) {
11716 if (!E->isTypeDependent())
11717 return E;
11718
11719 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
11720
11721 if (!NewT)
11722 return ExprError();
11723
11724 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
11725 return E;
11726
11727 return getDerived().RebuildSYCLUniqueStableNameExpr(
11728 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
11729}
11730
11731template<typename Derived>
11732ExprResult
11733TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
11734 if (!E->isTypeDependent())
11735 return E;
11736
11737 return getDerived().RebuildPredefinedExpr(E->getLocation(),
11738 E->getIdentKind());
11739}
11740
11741template<typename Derived>
11742ExprResult
11743TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
11744 NestedNameSpecifierLoc QualifierLoc;
11745 if (E->getQualifierLoc()) {
11746 QualifierLoc
11747 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11748 if (!QualifierLoc)
11749 return ExprError();
11750 }
11751
11752 ValueDecl *ND
11753 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
11754 E->getDecl()));
11755 if (!ND)
11756 return ExprError();
11757
11758 NamedDecl *Found = ND;
11759 if (E->getFoundDecl() != E->getDecl()) {
11760 Found = cast_or_null<NamedDecl>(
11761 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
11762 if (!Found)
11763 return ExprError();
11764 }
11765
11766 DeclarationNameInfo NameInfo = E->getNameInfo();
11767 if (NameInfo.getName()) {
11768 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11769 if (!NameInfo.getName())
11770 return ExprError();
11771 }
11772
11773 if (!getDerived().AlwaysRebuild() &&
11774 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
11775 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
11776 Found == E->getFoundDecl() &&
11777 NameInfo.getName() == E->getDecl()->getDeclName() &&
11778 !E->hasExplicitTemplateArgs()) {
11779
11780 // Mark it referenced in the new context regardless.
11781 // FIXME: this is a bit instantiation-specific.
11782 SemaRef.MarkDeclRefReferenced(E);
11783
11784 return E;
11785 }
11786
11787 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
11788 if (E->hasExplicitTemplateArgs()) {
11789 TemplateArgs = &TransArgs;
11790 TransArgs.setLAngleLoc(E->getLAngleLoc());
11791 TransArgs.setRAngleLoc(E->getRAngleLoc());
11792 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11793 E->getNumTemplateArgs(),
11794 TransArgs))
11795 return ExprError();
11796 }
11797
11798 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
11799 Found, TemplateArgs);
11800}
11801
11802template<typename Derived>
11803ExprResult
11804TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
11805 return E;
11806}
11807
11808template <typename Derived>
11809ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
11810 FixedPointLiteral *E) {
11811 return E;
11812}
11813
11814template<typename Derived>
11815ExprResult
11816TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
11817 return E;
11818}
11819
11820template<typename Derived>
11821ExprResult
11822TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
11823 return E;
11824}
11825
11826template<typename Derived>
11827ExprResult
11828TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
11829 return E;
11830}
11831
11832template<typename Derived>
11833ExprResult
11834TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
11835 return E;
11836}
11837
11838template<typename Derived>
11839ExprResult
11840TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
11841 return getDerived().TransformCallExpr(E);
11842}
11843
11844template<typename Derived>
11845ExprResult
11846TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
11847 ExprResult ControllingExpr;
11848 TypeSourceInfo *ControllingType = nullptr;
11849 if (E->isExprPredicate())
11850 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
11851 else
11852 ControllingType = getDerived().TransformType(E->getControllingType());
11853
11854 if (ControllingExpr.isInvalid() && !ControllingType)
11855 return ExprError();
11856
11857 SmallVector<Expr *, 4> AssocExprs;
11858 SmallVector<TypeSourceInfo *, 4> AssocTypes;
11859 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
11860 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
11861 if (TSI) {
11862 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
11863 if (!AssocType)
11864 return ExprError();
11865 AssocTypes.push_back(Elt: AssocType);
11866 } else {
11867 AssocTypes.push_back(Elt: nullptr);
11868 }
11869
11870 ExprResult AssocExpr =
11871 getDerived().TransformExpr(Assoc.getAssociationExpr());
11872 if (AssocExpr.isInvalid())
11873 return ExprError();
11874 AssocExprs.push_back(Elt: AssocExpr.get());
11875 }
11876
11877 if (!ControllingType)
11878 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
11879 E->getDefaultLoc(),
11880 E->getRParenLoc(),
11881 ControllingExpr.get(),
11882 AssocTypes,
11883 AssocExprs);
11884 return getDerived().RebuildGenericSelectionExpr(
11885 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11886 ControllingType, AssocTypes, AssocExprs);
11887}
11888
11889template<typename Derived>
11890ExprResult
11891TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11892 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11893 if (SubExpr.isInvalid())
11894 return ExprError();
11895
11896 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11897 return E;
11898
11899 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11900 E->getRParen());
11901}
11902
11903/// The operand of a unary address-of operator has special rules: it's
11904/// allowed to refer to a non-static member of a class even if there's no 'this'
11905/// object available.
11906template<typename Derived>
11907ExprResult
11908TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
11909 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
11910 return getDerived().TransformDependentScopeDeclRefExpr(
11911 DRE, /*IsAddressOfOperand=*/true, nullptr);
11912 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
11913 return getDerived().TransformUnresolvedLookupExpr(
11914 ULE, /*IsAddressOfOperand=*/true);
11915 else
11916 return getDerived().TransformExpr(E);
11917}
11918
11919template<typename Derived>
11920ExprResult
11921TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
11922 ExprResult SubExpr;
11923 if (E->getOpcode() == UO_AddrOf)
11924 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
11925 else
11926 SubExpr = TransformExpr(E: E->getSubExpr());
11927 if (SubExpr.isInvalid())
11928 return ExprError();
11929
11930 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11931 return E;
11932
11933 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11934 E->getOpcode(),
11935 SubExpr.get());
11936}
11937
11938template<typename Derived>
11939ExprResult
11940TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11941 // Transform the type.
11942 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11943 if (!Type)
11944 return ExprError();
11945
11946 // Transform all of the components into components similar to what the
11947 // parser uses.
11948 // FIXME: It would be slightly more efficient in the non-dependent case to
11949 // just map FieldDecls, rather than requiring the rebuilder to look for
11950 // the fields again. However, __builtin_offsetof is rare enough in
11951 // template code that we don't care.
11952 bool ExprChanged = false;
11953 typedef Sema::OffsetOfComponent Component;
11954 SmallVector<Component, 4> Components;
11955 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11956 const OffsetOfNode &ON = E->getComponent(Idx: I);
11957 Component Comp;
11958 Comp.isBrackets = true;
11959 Comp.LocStart = ON.getSourceRange().getBegin();
11960 Comp.LocEnd = ON.getSourceRange().getEnd();
11961 switch (ON.getKind()) {
11962 case OffsetOfNode::Array: {
11963 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
11964 ExprResult Index = getDerived().TransformExpr(FromIndex);
11965 if (Index.isInvalid())
11966 return ExprError();
11967
11968 ExprChanged = ExprChanged || Index.get() != FromIndex;
11969 Comp.isBrackets = true;
11970 Comp.U.E = Index.get();
11971 break;
11972 }
11973
11974 case OffsetOfNode::Field:
11975 case OffsetOfNode::Identifier:
11976 Comp.isBrackets = false;
11977 Comp.U.IdentInfo = ON.getFieldName();
11978 if (!Comp.U.IdentInfo)
11979 continue;
11980
11981 break;
11982
11983 case OffsetOfNode::Base:
11984 // Will be recomputed during the rebuild.
11985 continue;
11986 }
11987
11988 Components.push_back(Elt: Comp);
11989 }
11990
11991 // If nothing changed, retain the existing expression.
11992 if (!getDerived().AlwaysRebuild() &&
11993 Type == E->getTypeSourceInfo() &&
11994 !ExprChanged)
11995 return E;
11996
11997 // Build a new offsetof expression.
11998 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11999 Components, E->getRParenLoc());
12000}
12001
12002template<typename Derived>
12003ExprResult
12004TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
12005 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
12006 "opaque value expression requires transformation");
12007 return E;
12008}
12009
12010template<typename Derived>
12011ExprResult
12012TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
12013 return E;
12014}
12015
12016template <typename Derived>
12017ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
12018 llvm::SmallVector<Expr *, 8> Children;
12019 bool Changed = false;
12020 for (Expr *C : E->subExpressions()) {
12021 ExprResult NewC = getDerived().TransformExpr(C);
12022 if (NewC.isInvalid())
12023 return ExprError();
12024 Children.push_back(Elt: NewC.get());
12025
12026 Changed |= NewC.get() != C;
12027 }
12028 if (!getDerived().AlwaysRebuild() && !Changed)
12029 return E;
12030 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
12031 Children, E->getType());
12032}
12033
12034template<typename Derived>
12035ExprResult
12036TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
12037 // Rebuild the syntactic form. The original syntactic form has
12038 // opaque-value expressions in it, so strip those away and rebuild
12039 // the result. This is a really awful way of doing this, but the
12040 // better solution (rebuilding the semantic expressions and
12041 // rebinding OVEs as necessary) doesn't work; we'd need
12042 // TreeTransform to not strip away implicit conversions.
12043 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
12044 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
12045 if (result.isInvalid()) return ExprError();
12046
12047 // If that gives us a pseudo-object result back, the pseudo-object
12048 // expression must have been an lvalue-to-rvalue conversion which we
12049 // should reapply.
12050 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
12051 result = SemaRef.PseudoObject().checkRValue(E: result.get());
12052
12053 return result;
12054}
12055
12056template<typename Derived>
12057ExprResult
12058TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
12059 UnaryExprOrTypeTraitExpr *E) {
12060 if (E->isArgumentType()) {
12061 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
12062
12063 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12064 if (!NewT)
12065 return ExprError();
12066
12067 if (!getDerived().AlwaysRebuild() && OldT == NewT)
12068 return E;
12069
12070 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
12071 E->getKind(),
12072 E->getSourceRange());
12073 }
12074
12075 // C++0x [expr.sizeof]p1:
12076 // The operand is either an expression, which is an unevaluated operand
12077 // [...]
12078 EnterExpressionEvaluationContext Unevaluated(
12079 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
12080 Sema::ReuseLambdaContextDecl);
12081
12082 // Try to recover if we have something like sizeof(T::X) where X is a type.
12083 // Notably, there must be *exactly* one set of parens if X is a type.
12084 TypeSourceInfo *RecoveryTSI = nullptr;
12085 ExprResult SubExpr;
12086 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
12087 if (auto *DRE =
12088 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
12089 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
12090 PE, DRE, false, &RecoveryTSI);
12091 else
12092 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
12093
12094 if (RecoveryTSI) {
12095 return getDerived().RebuildUnaryExprOrTypeTrait(
12096 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
12097 } else if (SubExpr.isInvalid())
12098 return ExprError();
12099
12100 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
12101 return E;
12102
12103 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
12104 E->getOperatorLoc(),
12105 E->getKind(),
12106 E->getSourceRange());
12107}
12108
12109template<typename Derived>
12110ExprResult
12111TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
12112 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12113 if (LHS.isInvalid())
12114 return ExprError();
12115
12116 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12117 if (RHS.isInvalid())
12118 return ExprError();
12119
12120
12121 if (!getDerived().AlwaysRebuild() &&
12122 LHS.get() == E->getLHS() &&
12123 RHS.get() == E->getRHS())
12124 return E;
12125
12126 return getDerived().RebuildArraySubscriptExpr(
12127 LHS.get(),
12128 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
12129}
12130
12131template <typename Derived>
12132ExprResult
12133TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
12134 ExprResult Base = getDerived().TransformExpr(E->getBase());
12135 if (Base.isInvalid())
12136 return ExprError();
12137
12138 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
12139 if (RowIdx.isInvalid())
12140 return ExprError();
12141
12142 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
12143 if (ColumnIdx.isInvalid())
12144 return ExprError();
12145
12146 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12147 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
12148 return E;
12149
12150 return getDerived().RebuildMatrixSubscriptExpr(
12151 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
12152}
12153
12154template <typename Derived>
12155ExprResult
12156TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
12157 ExprResult Base = getDerived().TransformExpr(E->getBase());
12158 if (Base.isInvalid())
12159 return ExprError();
12160
12161 ExprResult LowerBound;
12162 if (E->getLowerBound()) {
12163 LowerBound = getDerived().TransformExpr(E->getLowerBound());
12164 if (LowerBound.isInvalid())
12165 return ExprError();
12166 }
12167
12168 ExprResult Length;
12169 if (E->getLength()) {
12170 Length = getDerived().TransformExpr(E->getLength());
12171 if (Length.isInvalid())
12172 return ExprError();
12173 }
12174
12175 ExprResult Stride;
12176 if (E->isOMPArraySection()) {
12177 if (Expr *Str = E->getStride()) {
12178 Stride = getDerived().TransformExpr(Str);
12179 if (Stride.isInvalid())
12180 return ExprError();
12181 }
12182 }
12183
12184 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12185 LowerBound.get() == E->getLowerBound() &&
12186 Length.get() == E->getLength() &&
12187 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
12188 return E;
12189
12190 return getDerived().RebuildArraySectionExpr(
12191 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
12192 LowerBound.get(), E->getColonLocFirst(),
12193 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
12194 Length.get(), Stride.get(), E->getRBracketLoc());
12195}
12196
12197template <typename Derived>
12198ExprResult
12199TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
12200 ExprResult Base = getDerived().TransformExpr(E->getBase());
12201 if (Base.isInvalid())
12202 return ExprError();
12203
12204 SmallVector<Expr *, 4> Dims;
12205 bool ErrorFound = false;
12206 for (Expr *Dim : E->getDimensions()) {
12207 ExprResult DimRes = getDerived().TransformExpr(Dim);
12208 if (DimRes.isInvalid()) {
12209 ErrorFound = true;
12210 continue;
12211 }
12212 Dims.push_back(Elt: DimRes.get());
12213 }
12214
12215 if (ErrorFound)
12216 return ExprError();
12217 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
12218 E->getRParenLoc(), Dims,
12219 E->getBracketsRanges());
12220}
12221
12222template <typename Derived>
12223ExprResult
12224TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
12225 unsigned NumIterators = E->numOfIterators();
12226 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
12227
12228 bool ErrorFound = false;
12229 bool NeedToRebuild = getDerived().AlwaysRebuild();
12230 for (unsigned I = 0; I < NumIterators; ++I) {
12231 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
12232 Data[I].DeclIdent = D->getIdentifier();
12233 Data[I].DeclIdentLoc = D->getLocation();
12234 if (D->getLocation() == D->getBeginLoc()) {
12235 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
12236 "Implicit type must be int.");
12237 } else {
12238 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
12239 QualType DeclTy = getDerived().TransformType(D->getType());
12240 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
12241 }
12242 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
12243 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
12244 ExprResult End = getDerived().TransformExpr(Range.End);
12245 ExprResult Step = getDerived().TransformExpr(Range.Step);
12246 ErrorFound = ErrorFound ||
12247 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
12248 !Data[I].Type.get().isNull())) ||
12249 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
12250 if (ErrorFound)
12251 continue;
12252 Data[I].Range.Begin = Begin.get();
12253 Data[I].Range.End = End.get();
12254 Data[I].Range.Step = Step.get();
12255 Data[I].AssignLoc = E->getAssignLoc(I);
12256 Data[I].ColonLoc = E->getColonLoc(I);
12257 Data[I].SecColonLoc = E->getSecondColonLoc(I);
12258 NeedToRebuild =
12259 NeedToRebuild ||
12260 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
12261 D->getType().getTypePtrOrNull()) ||
12262 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
12263 Range.Step != Data[I].Range.Step;
12264 }
12265 if (ErrorFound)
12266 return ExprError();
12267 if (!NeedToRebuild)
12268 return E;
12269
12270 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
12271 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
12272 if (!Res.isUsable())
12273 return Res;
12274 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
12275 for (unsigned I = 0; I < NumIterators; ++I)
12276 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
12277 IE->getIteratorDecl(I));
12278 return Res;
12279}
12280
12281template<typename Derived>
12282ExprResult
12283TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
12284 // Transform the callee.
12285 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12286 if (Callee.isInvalid())
12287 return ExprError();
12288
12289 // Transform arguments.
12290 bool ArgChanged = false;
12291 SmallVector<Expr*, 8> Args;
12292 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12293 &ArgChanged))
12294 return ExprError();
12295
12296 if (!getDerived().AlwaysRebuild() &&
12297 Callee.get() == E->getCallee() &&
12298 !ArgChanged)
12299 return SemaRef.MaybeBindToTemporary(E);
12300
12301 // FIXME: Wrong source location information for the '('.
12302 SourceLocation FakeLParenLoc
12303 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12304
12305 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12306 if (E->hasStoredFPFeatures()) {
12307 FPOptionsOverride NewOverrides = E->getFPFeatures();
12308 getSema().CurFPFeatures =
12309 NewOverrides.applyOverrides(getSema().getLangOpts());
12310 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12311 }
12312
12313 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12314 Args,
12315 E->getRParenLoc());
12316}
12317
12318template<typename Derived>
12319ExprResult
12320TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
12321 ExprResult Base = getDerived().TransformExpr(E->getBase());
12322 if (Base.isInvalid())
12323 return ExprError();
12324
12325 NestedNameSpecifierLoc QualifierLoc;
12326 if (E->hasQualifier()) {
12327 QualifierLoc
12328 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12329
12330 if (!QualifierLoc)
12331 return ExprError();
12332 }
12333 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
12334
12335 ValueDecl *Member
12336 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
12337 E->getMemberDecl()));
12338 if (!Member)
12339 return ExprError();
12340
12341 NamedDecl *FoundDecl = E->getFoundDecl();
12342 if (FoundDecl == E->getMemberDecl()) {
12343 FoundDecl = Member;
12344 } else {
12345 FoundDecl = cast_or_null<NamedDecl>(
12346 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
12347 if (!FoundDecl)
12348 return ExprError();
12349 }
12350
12351 if (!getDerived().AlwaysRebuild() &&
12352 Base.get() == E->getBase() &&
12353 QualifierLoc == E->getQualifierLoc() &&
12354 Member == E->getMemberDecl() &&
12355 FoundDecl == E->getFoundDecl() &&
12356 !E->hasExplicitTemplateArgs()) {
12357
12358 // Skip for member expression of (this->f), rebuilt thisi->f is needed
12359 // for Openmp where the field need to be privatizized in the case.
12360 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
12361 getSema().OpenMP().isOpenMPRebuildMemberExpr(
12362 cast<ValueDecl>(Val: Member)))) {
12363 // Mark it referenced in the new context regardless.
12364 // FIXME: this is a bit instantiation-specific.
12365 SemaRef.MarkMemberReferenced(E);
12366 return E;
12367 }
12368 }
12369
12370 TemplateArgumentListInfo TransArgs;
12371 if (E->hasExplicitTemplateArgs()) {
12372 TransArgs.setLAngleLoc(E->getLAngleLoc());
12373 TransArgs.setRAngleLoc(E->getRAngleLoc());
12374 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12375 E->getNumTemplateArgs(),
12376 TransArgs))
12377 return ExprError();
12378 }
12379
12380 // FIXME: Bogus source location for the operator
12381 SourceLocation FakeOperatorLoc =
12382 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
12383
12384 // FIXME: to do this check properly, we will need to preserve the
12385 // first-qualifier-in-scope here, just in case we had a dependent
12386 // base (and therefore couldn't do the check) and a
12387 // nested-name-qualifier (and therefore could do the lookup).
12388 NamedDecl *FirstQualifierInScope = nullptr;
12389 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
12390 if (MemberNameInfo.getName()) {
12391 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
12392 if (!MemberNameInfo.getName())
12393 return ExprError();
12394 }
12395
12396 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
12397 E->isArrow(),
12398 QualifierLoc,
12399 TemplateKWLoc,
12400 MemberNameInfo,
12401 Member,
12402 FoundDecl,
12403 (E->hasExplicitTemplateArgs()
12404 ? &TransArgs : nullptr),
12405 FirstQualifierInScope);
12406}
12407
12408template<typename Derived>
12409ExprResult
12410TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
12411 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12412 if (LHS.isInvalid())
12413 return ExprError();
12414
12415 ExprResult RHS =
12416 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
12417 if (RHS.isInvalid())
12418 return ExprError();
12419
12420 if (!getDerived().AlwaysRebuild() &&
12421 LHS.get() == E->getLHS() &&
12422 RHS.get() == E->getRHS())
12423 return E;
12424
12425 if (E->isCompoundAssignmentOp())
12426 // FPFeatures has already been established from trailing storage
12427 return getDerived().RebuildBinaryOperator(
12428 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
12429 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12430 FPOptionsOverride NewOverrides(E->getFPFeatures());
12431 getSema().CurFPFeatures =
12432 NewOverrides.applyOverrides(getSema().getLangOpts());
12433 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12434 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
12435 LHS.get(), RHS.get());
12436}
12437
12438template <typename Derived>
12439ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
12440 CXXRewrittenBinaryOperator *E) {
12441 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
12442
12443 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
12444 if (LHS.isInvalid())
12445 return ExprError();
12446
12447 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
12448 if (RHS.isInvalid())
12449 return ExprError();
12450
12451 // Extract the already-resolved callee declarations so that we can restrict
12452 // ourselves to using them as the unqualified lookup results when rebuilding.
12453 UnresolvedSet<2> UnqualLookups;
12454 bool ChangedAnyLookups = false;
12455 Expr *PossibleBinOps[] = {E->getSemanticForm(),
12456 const_cast<Expr *>(Decomp.InnerBinOp)};
12457 for (Expr *PossibleBinOp : PossibleBinOps) {
12458 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
12459 if (!Op)
12460 continue;
12461 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
12462 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
12463 continue;
12464
12465 // Transform the callee in case we built a call to a local extern
12466 // declaration.
12467 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
12468 E->getOperatorLoc(), Callee->getFoundDecl()));
12469 if (!Found)
12470 return ExprError();
12471 if (Found != Callee->getFoundDecl())
12472 ChangedAnyLookups = true;
12473 UnqualLookups.addDecl(D: Found);
12474 }
12475
12476 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
12477 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
12478 // Mark all functions used in the rewrite as referenced. Note that when
12479 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
12480 // function calls, and/or there might be a user-defined conversion sequence
12481 // applied to the operands of the <.
12482 // FIXME: this is a bit instantiation-specific.
12483 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
12484 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
12485 return E;
12486 }
12487
12488 return getDerived().RebuildCXXRewrittenBinaryOperator(
12489 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
12490}
12491
12492template<typename Derived>
12493ExprResult
12494TreeTransform<Derived>::TransformCompoundAssignOperator(
12495 CompoundAssignOperator *E) {
12496 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12497 FPOptionsOverride NewOverrides(E->getFPFeatures());
12498 getSema().CurFPFeatures =
12499 NewOverrides.applyOverrides(getSema().getLangOpts());
12500 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12501 return getDerived().TransformBinaryOperator(E);
12502}
12503
12504template<typename Derived>
12505ExprResult TreeTransform<Derived>::
12506TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
12507 // Just rebuild the common and RHS expressions and see whether we
12508 // get any changes.
12509
12510 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
12511 if (commonExpr.isInvalid())
12512 return ExprError();
12513
12514 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
12515 if (rhs.isInvalid())
12516 return ExprError();
12517
12518 if (!getDerived().AlwaysRebuild() &&
12519 commonExpr.get() == e->getCommon() &&
12520 rhs.get() == e->getFalseExpr())
12521 return e;
12522
12523 return getDerived().RebuildConditionalOperator(commonExpr.get(),
12524 e->getQuestionLoc(),
12525 nullptr,
12526 e->getColonLoc(),
12527 rhs.get());
12528}
12529
12530template<typename Derived>
12531ExprResult
12532TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
12533 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12534 if (Cond.isInvalid())
12535 return ExprError();
12536
12537 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12538 if (LHS.isInvalid())
12539 return ExprError();
12540
12541 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12542 if (RHS.isInvalid())
12543 return ExprError();
12544
12545 if (!getDerived().AlwaysRebuild() &&
12546 Cond.get() == E->getCond() &&
12547 LHS.get() == E->getLHS() &&
12548 RHS.get() == E->getRHS())
12549 return E;
12550
12551 return getDerived().RebuildConditionalOperator(Cond.get(),
12552 E->getQuestionLoc(),
12553 LHS.get(),
12554 E->getColonLoc(),
12555 RHS.get());
12556}
12557
12558template<typename Derived>
12559ExprResult
12560TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
12561 // Implicit casts are eliminated during transformation, since they
12562 // will be recomputed by semantic analysis after transformation.
12563 return getDerived().TransformExpr(E->getSubExprAsWritten());
12564}
12565
12566template<typename Derived>
12567ExprResult
12568TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
12569 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12570 if (!Type)
12571 return ExprError();
12572
12573 ExprResult SubExpr
12574 = getDerived().TransformExpr(E->getSubExprAsWritten());
12575 if (SubExpr.isInvalid())
12576 return ExprError();
12577
12578 if (!getDerived().AlwaysRebuild() &&
12579 Type == E->getTypeInfoAsWritten() &&
12580 SubExpr.get() == E->getSubExpr())
12581 return E;
12582
12583 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
12584 Type,
12585 E->getRParenLoc(),
12586 SubExpr.get());
12587}
12588
12589template<typename Derived>
12590ExprResult
12591TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
12592 TypeSourceInfo *OldT = E->getTypeSourceInfo();
12593 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12594 if (!NewT)
12595 return ExprError();
12596
12597 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
12598 if (Init.isInvalid())
12599 return ExprError();
12600
12601 if (!getDerived().AlwaysRebuild() &&
12602 OldT == NewT &&
12603 Init.get() == E->getInitializer())
12604 return SemaRef.MaybeBindToTemporary(E);
12605
12606 // Note: the expression type doesn't necessarily match the
12607 // type-as-written, but that's okay, because it should always be
12608 // derivable from the initializer.
12609
12610 return getDerived().RebuildCompoundLiteralExpr(
12611 E->getLParenLoc(), NewT,
12612 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
12613}
12614
12615template<typename Derived>
12616ExprResult
12617TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
12618 ExprResult Base = getDerived().TransformExpr(E->getBase());
12619 if (Base.isInvalid())
12620 return ExprError();
12621
12622 if (!getDerived().AlwaysRebuild() &&
12623 Base.get() == E->getBase())
12624 return E;
12625
12626 // FIXME: Bad source location
12627 SourceLocation FakeOperatorLoc =
12628 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
12629 return getDerived().RebuildExtVectorElementExpr(
12630 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
12631 E->getAccessor());
12632}
12633
12634template<typename Derived>
12635ExprResult
12636TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
12637 if (InitListExpr *Syntactic = E->getSyntacticForm())
12638 E = Syntactic;
12639
12640 bool InitChanged = false;
12641
12642 EnterExpressionEvaluationContext Context(
12643 getSema(), EnterExpressionEvaluationContext::InitList);
12644
12645 SmallVector<Expr*, 4> Inits;
12646 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
12647 Inits, &InitChanged))
12648 return ExprError();
12649
12650 if (!getDerived().AlwaysRebuild() && !InitChanged) {
12651 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
12652 // in some cases. We can't reuse it in general, because the syntactic and
12653 // semantic forms are linked, and we can't know that semantic form will
12654 // match even if the syntactic form does.
12655 }
12656
12657 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
12658 E->getRBraceLoc());
12659}
12660
12661template<typename Derived>
12662ExprResult
12663TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
12664 Designation Desig;
12665
12666 // transform the initializer value
12667 ExprResult Init = getDerived().TransformExpr(E->getInit());
12668 if (Init.isInvalid())
12669 return ExprError();
12670
12671 // transform the designators.
12672 SmallVector<Expr*, 4> ArrayExprs;
12673 bool ExprChanged = false;
12674 for (const DesignatedInitExpr::Designator &D : E->designators()) {
12675 if (D.isFieldDesignator()) {
12676 if (D.getFieldDecl()) {
12677 FieldDecl *Field = cast_or_null<FieldDecl>(
12678 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
12679 if (Field != D.getFieldDecl())
12680 // Rebuild the expression when the transformed FieldDecl is
12681 // different to the already assigned FieldDecl.
12682 ExprChanged = true;
12683 if (Field->isAnonymousStructOrUnion())
12684 continue;
12685 } else {
12686 // Ensure that the designator expression is rebuilt when there isn't
12687 // a resolved FieldDecl in the designator as we don't want to assign
12688 // a FieldDecl to a pattern designator that will be instantiated again.
12689 ExprChanged = true;
12690 }
12691 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
12692 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
12693 continue;
12694 }
12695
12696 if (D.isArrayDesignator()) {
12697 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
12698 if (Index.isInvalid())
12699 return ExprError();
12700
12701 Desig.AddDesignator(
12702 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
12703
12704 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
12705 ArrayExprs.push_back(Elt: Index.get());
12706 continue;
12707 }
12708
12709 assert(D.isArrayRangeDesignator() && "New kind of designator?");
12710 ExprResult Start
12711 = getDerived().TransformExpr(E->getArrayRangeStart(D));
12712 if (Start.isInvalid())
12713 return ExprError();
12714
12715 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
12716 if (End.isInvalid())
12717 return ExprError();
12718
12719 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
12720 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
12721
12722 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
12723 End.get() != E->getArrayRangeEnd(D);
12724
12725 ArrayExprs.push_back(Elt: Start.get());
12726 ArrayExprs.push_back(Elt: End.get());
12727 }
12728
12729 if (!getDerived().AlwaysRebuild() &&
12730 Init.get() == E->getInit() &&
12731 !ExprChanged)
12732 return E;
12733
12734 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
12735 E->getEqualOrColonLoc(),
12736 E->usesGNUSyntax(), Init.get());
12737}
12738
12739// Seems that if TransformInitListExpr() only works on the syntactic form of an
12740// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
12741template<typename Derived>
12742ExprResult
12743TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
12744 DesignatedInitUpdateExpr *E) {
12745 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
12746 "initializer");
12747 return ExprError();
12748}
12749
12750template<typename Derived>
12751ExprResult
12752TreeTransform<Derived>::TransformNoInitExpr(
12753 NoInitExpr *E) {
12754 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
12755 return ExprError();
12756}
12757
12758template<typename Derived>
12759ExprResult
12760TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
12761 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
12762 return ExprError();
12763}
12764
12765template<typename Derived>
12766ExprResult
12767TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
12768 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
12769 return ExprError();
12770}
12771
12772template<typename Derived>
12773ExprResult
12774TreeTransform<Derived>::TransformImplicitValueInitExpr(
12775 ImplicitValueInitExpr *E) {
12776 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
12777
12778 // FIXME: Will we ever have proper type location here? Will we actually
12779 // need to transform the type?
12780 QualType T = getDerived().TransformType(E->getType());
12781 if (T.isNull())
12782 return ExprError();
12783
12784 if (!getDerived().AlwaysRebuild() &&
12785 T == E->getType())
12786 return E;
12787
12788 return getDerived().RebuildImplicitValueInitExpr(T);
12789}
12790
12791template<typename Derived>
12792ExprResult
12793TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
12794 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
12795 if (!TInfo)
12796 return ExprError();
12797
12798 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12799 if (SubExpr.isInvalid())
12800 return ExprError();
12801
12802 if (!getDerived().AlwaysRebuild() &&
12803 TInfo == E->getWrittenTypeInfo() &&
12804 SubExpr.get() == E->getSubExpr())
12805 return E;
12806
12807 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
12808 TInfo, E->getRParenLoc());
12809}
12810
12811template<typename Derived>
12812ExprResult
12813TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
12814 bool ArgumentChanged = false;
12815 SmallVector<Expr*, 4> Inits;
12816 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
12817 ArgChanged: &ArgumentChanged))
12818 return ExprError();
12819
12820 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
12821 Inits,
12822 E->getRParenLoc());
12823}
12824
12825/// Transform an address-of-label expression.
12826///
12827/// By default, the transformation of an address-of-label expression always
12828/// rebuilds the expression, so that the label identifier can be resolved to
12829/// the corresponding label statement by semantic analysis.
12830template<typename Derived>
12831ExprResult
12832TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
12833 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
12834 E->getLabel());
12835 if (!LD)
12836 return ExprError();
12837
12838 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
12839 cast<LabelDecl>(Val: LD));
12840}
12841
12842template<typename Derived>
12843ExprResult
12844TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
12845 SemaRef.ActOnStartStmtExpr();
12846 StmtResult SubStmt
12847 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
12848 if (SubStmt.isInvalid()) {
12849 SemaRef.ActOnStmtExprError();
12850 return ExprError();
12851 }
12852
12853 unsigned OldDepth = E->getTemplateDepth();
12854 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
12855
12856 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
12857 SubStmt.get() == E->getSubStmt()) {
12858 // Calling this an 'error' is unintuitive, but it does the right thing.
12859 SemaRef.ActOnStmtExprError();
12860 return SemaRef.MaybeBindToTemporary(E);
12861 }
12862
12863 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
12864 E->getRParenLoc(), NewDepth);
12865}
12866
12867template<typename Derived>
12868ExprResult
12869TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
12870 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12871 if (Cond.isInvalid())
12872 return ExprError();
12873
12874 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12875 if (LHS.isInvalid())
12876 return ExprError();
12877
12878 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12879 if (RHS.isInvalid())
12880 return ExprError();
12881
12882 if (!getDerived().AlwaysRebuild() &&
12883 Cond.get() == E->getCond() &&
12884 LHS.get() == E->getLHS() &&
12885 RHS.get() == E->getRHS())
12886 return E;
12887
12888 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
12889 Cond.get(), LHS.get(), RHS.get(),
12890 E->getRParenLoc());
12891}
12892
12893template<typename Derived>
12894ExprResult
12895TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12896 return E;
12897}
12898
12899template<typename Derived>
12900ExprResult
12901TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12902 switch (E->getOperator()) {
12903 case OO_New:
12904 case OO_Delete:
12905 case OO_Array_New:
12906 case OO_Array_Delete:
12907 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12908
12909 case OO_Subscript:
12910 case OO_Call: {
12911 // This is a call to an object's operator().
12912 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12913
12914 // Transform the object itself.
12915 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
12916 if (Object.isInvalid())
12917 return ExprError();
12918
12919 // FIXME: Poor location information
12920 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12921 Loc: static_cast<Expr *>(Object.get())->getEndLoc());
12922
12923 // Transform the call arguments.
12924 SmallVector<Expr*, 8> Args;
12925 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12926 Args))
12927 return ExprError();
12928
12929 if (E->getOperator() == OO_Subscript)
12930 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12931 Args, E->getEndLoc());
12932
12933 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12934 E->getEndLoc());
12935 }
12936
12937#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12938 case OO_##Name: \
12939 break;
12940
12941#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12942#include "clang/Basic/OperatorKinds.def"
12943
12944 case OO_Conditional:
12945 llvm_unreachable("conditional operator is not actually overloadable");
12946
12947 case OO_None:
12948 case NUM_OVERLOADED_OPERATORS:
12949 llvm_unreachable("not an overloaded operator?");
12950 }
12951
12952 ExprResult First;
12953 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
12954 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
12955 else
12956 First = getDerived().TransformExpr(E->getArg(Arg: 0));
12957 if (First.isInvalid())
12958 return ExprError();
12959
12960 ExprResult Second;
12961 if (E->getNumArgs() == 2) {
12962 Second =
12963 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
12964 if (Second.isInvalid())
12965 return ExprError();
12966 }
12967
12968 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12969 FPOptionsOverride NewOverrides(E->getFPFeatures());
12970 getSema().CurFPFeatures =
12971 NewOverrides.applyOverrides(getSema().getLangOpts());
12972 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12973
12974 Expr *Callee = E->getCallee();
12975 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
12976 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12977 Sema::LookupOrdinaryName);
12978 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12979 return ExprError();
12980
12981 return getDerived().RebuildCXXOperatorCallExpr(
12982 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12983 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12984 }
12985
12986 UnresolvedSet<1> Functions;
12987 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
12988 Callee = ICE->getSubExprAsWritten();
12989 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
12990 ValueDecl *VD = cast_or_null<ValueDecl>(
12991 getDerived().TransformDecl(DR->getLocation(), DR));
12992 if (!VD)
12993 return ExprError();
12994
12995 if (!isa<CXXMethodDecl>(Val: VD))
12996 Functions.addDecl(D: VD);
12997
12998 return getDerived().RebuildCXXOperatorCallExpr(
12999 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13000 /*RequiresADL=*/false, Functions, First.get(), Second.get());
13001}
13002
13003template<typename Derived>
13004ExprResult
13005TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
13006 return getDerived().TransformCallExpr(E);
13007}
13008
13009template <typename Derived>
13010ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
13011 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
13012 getSema().CurContext != E->getParentContext();
13013
13014 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
13015 return E;
13016
13017 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
13018 E->getBeginLoc(), E->getEndLoc(),
13019 getSema().CurContext);
13020}
13021
13022template <typename Derived>
13023ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
13024 return E;
13025}
13026
13027template<typename Derived>
13028ExprResult
13029TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
13030 // Transform the callee.
13031 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13032 if (Callee.isInvalid())
13033 return ExprError();
13034
13035 // Transform exec config.
13036 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
13037 if (EC.isInvalid())
13038 return ExprError();
13039
13040 // Transform arguments.
13041 bool ArgChanged = false;
13042 SmallVector<Expr*, 8> Args;
13043 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13044 &ArgChanged))
13045 return ExprError();
13046
13047 if (!getDerived().AlwaysRebuild() &&
13048 Callee.get() == E->getCallee() &&
13049 !ArgChanged)
13050 return SemaRef.MaybeBindToTemporary(E);
13051
13052 // FIXME: Wrong source location information for the '('.
13053 SourceLocation FakeLParenLoc
13054 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13055 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13056 Args,
13057 E->getRParenLoc(), EC.get());
13058}
13059
13060template<typename Derived>
13061ExprResult
13062TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
13063 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13064 if (!Type)
13065 return ExprError();
13066
13067 ExprResult SubExpr
13068 = getDerived().TransformExpr(E->getSubExprAsWritten());
13069 if (SubExpr.isInvalid())
13070 return ExprError();
13071
13072 if (!getDerived().AlwaysRebuild() &&
13073 Type == E->getTypeInfoAsWritten() &&
13074 SubExpr.get() == E->getSubExpr())
13075 return E;
13076 return getDerived().RebuildCXXNamedCastExpr(
13077 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
13078 Type, E->getAngleBrackets().getEnd(),
13079 // FIXME. this should be '(' location
13080 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
13081}
13082
13083template<typename Derived>
13084ExprResult
13085TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
13086 TypeSourceInfo *TSI =
13087 getDerived().TransformType(BCE->getTypeInfoAsWritten());
13088 if (!TSI)
13089 return ExprError();
13090
13091 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
13092 if (Sub.isInvalid())
13093 return ExprError();
13094
13095 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
13096 Sub.get(), BCE->getEndLoc());
13097}
13098
13099template<typename Derived>
13100ExprResult
13101TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
13102 return getDerived().TransformCXXNamedCastExpr(E);
13103}
13104
13105template<typename Derived>
13106ExprResult
13107TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
13108 return getDerived().TransformCXXNamedCastExpr(E);
13109}
13110
13111template<typename Derived>
13112ExprResult
13113TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
13114 CXXReinterpretCastExpr *E) {
13115 return getDerived().TransformCXXNamedCastExpr(E);
13116}
13117
13118template<typename Derived>
13119ExprResult
13120TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
13121 return getDerived().TransformCXXNamedCastExpr(E);
13122}
13123
13124template<typename Derived>
13125ExprResult
13126TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
13127 return getDerived().TransformCXXNamedCastExpr(E);
13128}
13129
13130template<typename Derived>
13131ExprResult
13132TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
13133 CXXFunctionalCastExpr *E) {
13134 TypeSourceInfo *Type =
13135 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
13136 if (!Type)
13137 return ExprError();
13138
13139 ExprResult SubExpr
13140 = getDerived().TransformExpr(E->getSubExprAsWritten());
13141 if (SubExpr.isInvalid())
13142 return ExprError();
13143
13144 if (!getDerived().AlwaysRebuild() &&
13145 Type == E->getTypeInfoAsWritten() &&
13146 SubExpr.get() == E->getSubExpr())
13147 return E;
13148
13149 return getDerived().RebuildCXXFunctionalCastExpr(Type,
13150 E->getLParenLoc(),
13151 SubExpr.get(),
13152 E->getRParenLoc(),
13153 E->isListInitialization());
13154}
13155
13156template<typename Derived>
13157ExprResult
13158TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
13159 if (E->isTypeOperand()) {
13160 TypeSourceInfo *TInfo
13161 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13162 if (!TInfo)
13163 return ExprError();
13164
13165 if (!getDerived().AlwaysRebuild() &&
13166 TInfo == E->getTypeOperandSourceInfo())
13167 return E;
13168
13169 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13170 TInfo, E->getEndLoc());
13171 }
13172
13173 // Typeid's operand is an unevaluated context, unless it's a polymorphic
13174 // type. We must not unilaterally enter unevaluated context here, as then
13175 // semantic processing can re-transform an already transformed operand.
13176 Expr *Op = E->getExprOperand();
13177 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
13178 if (E->isGLValue())
13179 if (auto *RecordT = Op->getType()->getAs<RecordType>())
13180 if (cast<CXXRecordDecl>(Val: RecordT->getDecl())->isPolymorphic())
13181 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
13182
13183 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
13184 Sema::ReuseLambdaContextDecl);
13185
13186 ExprResult SubExpr = getDerived().TransformExpr(Op);
13187 if (SubExpr.isInvalid())
13188 return ExprError();
13189
13190 if (!getDerived().AlwaysRebuild() &&
13191 SubExpr.get() == E->getExprOperand())
13192 return E;
13193
13194 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13195 SubExpr.get(), E->getEndLoc());
13196}
13197
13198template<typename Derived>
13199ExprResult
13200TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
13201 if (E->isTypeOperand()) {
13202 TypeSourceInfo *TInfo
13203 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13204 if (!TInfo)
13205 return ExprError();
13206
13207 if (!getDerived().AlwaysRebuild() &&
13208 TInfo == E->getTypeOperandSourceInfo())
13209 return E;
13210
13211 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13212 TInfo, E->getEndLoc());
13213 }
13214
13215 EnterExpressionEvaluationContext Unevaluated(
13216 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13217
13218 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
13219 if (SubExpr.isInvalid())
13220 return ExprError();
13221
13222 if (!getDerived().AlwaysRebuild() &&
13223 SubExpr.get() == E->getExprOperand())
13224 return E;
13225
13226 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13227 SubExpr.get(), E->getEndLoc());
13228}
13229
13230template<typename Derived>
13231ExprResult
13232TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
13233 return E;
13234}
13235
13236template<typename Derived>
13237ExprResult
13238TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
13239 CXXNullPtrLiteralExpr *E) {
13240 return E;
13241}
13242
13243template<typename Derived>
13244ExprResult
13245TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
13246
13247 // In lambdas, the qualifiers of the type depends of where in
13248 // the call operator `this` appear, and we do not have a good way to
13249 // rebuild this information, so we transform the type.
13250 //
13251 // In other contexts, the type of `this` may be overrided
13252 // for type deduction, so we need to recompute it.
13253 //
13254 // Always recompute the type if we're in the body of a lambda, and
13255 // 'this' is dependent on a lambda's explicit object parameter.
13256 QualType T = [&]() {
13257 auto &S = getSema();
13258 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
13259 return S.getCurrentThisType();
13260 if (S.getCurLambda())
13261 return getDerived().TransformType(E->getType());
13262 return S.getCurrentThisType();
13263 }();
13264
13265 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
13266 // Mark it referenced in the new context regardless.
13267 // FIXME: this is a bit instantiation-specific.
13268 getSema().MarkThisReferenced(E);
13269 return E;
13270 }
13271
13272 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
13273}
13274
13275template<typename Derived>
13276ExprResult
13277TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
13278 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13279 if (SubExpr.isInvalid())
13280 return ExprError();
13281
13282 if (!getDerived().AlwaysRebuild() &&
13283 SubExpr.get() == E->getSubExpr())
13284 return E;
13285
13286 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
13287 E->isThrownVariableInScope());
13288}
13289
13290template<typename Derived>
13291ExprResult
13292TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
13293 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
13294 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
13295 if (!Param)
13296 return ExprError();
13297
13298 ExprResult InitRes;
13299 if (E->hasRewrittenInit()) {
13300 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
13301 if (InitRes.isInvalid())
13302 return ExprError();
13303 }
13304
13305 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
13306 E->getUsedContext() == SemaRef.CurContext &&
13307 InitRes.get() == E->getRewrittenExpr())
13308 return E;
13309
13310 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
13311 InitRes.get());
13312}
13313
13314template<typename Derived>
13315ExprResult
13316TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
13317 FieldDecl *Field = cast_or_null<FieldDecl>(
13318 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
13319 if (!Field)
13320 return ExprError();
13321
13322 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
13323 E->getUsedContext() == SemaRef.CurContext)
13324 return E;
13325
13326 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
13327}
13328
13329template<typename Derived>
13330ExprResult
13331TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
13332 CXXScalarValueInitExpr *E) {
13333 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
13334 if (!T)
13335 return ExprError();
13336
13337 if (!getDerived().AlwaysRebuild() &&
13338 T == E->getTypeSourceInfo())
13339 return E;
13340
13341 return getDerived().RebuildCXXScalarValueInitExpr(T,
13342 /*FIXME:*/T->getTypeLoc().getEndLoc(),
13343 E->getRParenLoc());
13344}
13345
13346template<typename Derived>
13347ExprResult
13348TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
13349 // Transform the type that we're allocating
13350 TypeSourceInfo *AllocTypeInfo =
13351 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
13352 if (!AllocTypeInfo)
13353 return ExprError();
13354
13355 // Transform the size of the array we're allocating (if any).
13356 std::optional<Expr *> ArraySize;
13357 if (E->isArray()) {
13358 ExprResult NewArraySize;
13359 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
13360 NewArraySize = getDerived().TransformExpr(*OldArraySize);
13361 if (NewArraySize.isInvalid())
13362 return ExprError();
13363 }
13364 ArraySize = NewArraySize.get();
13365 }
13366
13367 // Transform the placement arguments (if any).
13368 bool ArgumentChanged = false;
13369 SmallVector<Expr*, 8> PlacementArgs;
13370 if (getDerived().TransformExprs(E->getPlacementArgs(),
13371 E->getNumPlacementArgs(), true,
13372 PlacementArgs, &ArgumentChanged))
13373 return ExprError();
13374
13375 // Transform the initializer (if any).
13376 Expr *OldInit = E->getInitializer();
13377 ExprResult NewInit;
13378 if (OldInit)
13379 NewInit = getDerived().TransformInitializer(OldInit, true);
13380 if (NewInit.isInvalid())
13381 return ExprError();
13382
13383 // Transform new operator and delete operator.
13384 FunctionDecl *OperatorNew = nullptr;
13385 if (E->getOperatorNew()) {
13386 OperatorNew = cast_or_null<FunctionDecl>(
13387 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
13388 if (!OperatorNew)
13389 return ExprError();
13390 }
13391
13392 FunctionDecl *OperatorDelete = nullptr;
13393 if (E->getOperatorDelete()) {
13394 OperatorDelete = cast_or_null<FunctionDecl>(
13395 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13396 if (!OperatorDelete)
13397 return ExprError();
13398 }
13399
13400 if (!getDerived().AlwaysRebuild() &&
13401 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
13402 ArraySize == E->getArraySize() &&
13403 NewInit.get() == OldInit &&
13404 OperatorNew == E->getOperatorNew() &&
13405 OperatorDelete == E->getOperatorDelete() &&
13406 !ArgumentChanged) {
13407 // Mark any declarations we need as referenced.
13408 // FIXME: instantiation-specific.
13409 if (OperatorNew)
13410 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
13411 if (OperatorDelete)
13412 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
13413
13414 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
13415 QualType ElementType
13416 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
13417 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
13418 CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: RecordT->getDecl());
13419 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record)) {
13420 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
13421 }
13422 }
13423 }
13424
13425 return E;
13426 }
13427
13428 QualType AllocType = AllocTypeInfo->getType();
13429 if (!ArraySize) {
13430 // If no array size was specified, but the new expression was
13431 // instantiated with an array type (e.g., "new T" where T is
13432 // instantiated with "int[4]"), extract the outer bound from the
13433 // array type as our array size. We do this with constant and
13434 // dependently-sized array types.
13435 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
13436 if (!ArrayT) {
13437 // Do nothing
13438 } else if (const ConstantArrayType *ConsArrayT
13439 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
13440 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
13441 type: SemaRef.Context.getSizeType(),
13442 /*FIXME:*/ l: E->getBeginLoc());
13443 AllocType = ConsArrayT->getElementType();
13444 } else if (const DependentSizedArrayType *DepArrayT
13445 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
13446 if (DepArrayT->getSizeExpr()) {
13447 ArraySize = DepArrayT->getSizeExpr();
13448 AllocType = DepArrayT->getElementType();
13449 }
13450 }
13451 }
13452
13453 return getDerived().RebuildCXXNewExpr(
13454 E->getBeginLoc(), E->isGlobalNew(),
13455 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
13456 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
13457 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
13458}
13459
13460template<typename Derived>
13461ExprResult
13462TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
13463 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
13464 if (Operand.isInvalid())
13465 return ExprError();
13466
13467 // Transform the delete operator, if known.
13468 FunctionDecl *OperatorDelete = nullptr;
13469 if (E->getOperatorDelete()) {
13470 OperatorDelete = cast_or_null<FunctionDecl>(
13471 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13472 if (!OperatorDelete)
13473 return ExprError();
13474 }
13475
13476 if (!getDerived().AlwaysRebuild() &&
13477 Operand.get() == E->getArgument() &&
13478 OperatorDelete == E->getOperatorDelete()) {
13479 // Mark any declarations we need as referenced.
13480 // FIXME: instantiation-specific.
13481 if (OperatorDelete)
13482 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
13483
13484 if (!E->getArgument()->isTypeDependent()) {
13485 QualType Destroyed = SemaRef.Context.getBaseElementType(
13486 QT: E->getDestroyedType());
13487 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
13488 CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: DestroyedRec->getDecl());
13489 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
13490 Func: SemaRef.LookupDestructor(Class: Record));
13491 }
13492 }
13493
13494 return E;
13495 }
13496
13497 return getDerived().RebuildCXXDeleteExpr(
13498 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
13499}
13500
13501template<typename Derived>
13502ExprResult
13503TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
13504 CXXPseudoDestructorExpr *E) {
13505 ExprResult Base = getDerived().TransformExpr(E->getBase());
13506 if (Base.isInvalid())
13507 return ExprError();
13508
13509 ParsedType ObjectTypePtr;
13510 bool MayBePseudoDestructor = false;
13511 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
13512 OpLoc: E->getOperatorLoc(),
13513 OpKind: E->isArrow()? tok::arrow : tok::period,
13514 ObjectType&: ObjectTypePtr,
13515 MayBePseudoDestructor);
13516 if (Base.isInvalid())
13517 return ExprError();
13518
13519 QualType ObjectType = ObjectTypePtr.get();
13520 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
13521 if (QualifierLoc) {
13522 QualifierLoc
13523 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
13524 if (!QualifierLoc)
13525 return ExprError();
13526 }
13527 CXXScopeSpec SS;
13528 SS.Adopt(Other: QualifierLoc);
13529
13530 PseudoDestructorTypeStorage Destroyed;
13531 if (E->getDestroyedTypeInfo()) {
13532 TypeSourceInfo *DestroyedTypeInfo
13533 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
13534 ObjectType, nullptr, SS);
13535 if (!DestroyedTypeInfo)
13536 return ExprError();
13537 Destroyed = DestroyedTypeInfo;
13538 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
13539 // We aren't likely to be able to resolve the identifier down to a type
13540 // now anyway, so just retain the identifier.
13541 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
13542 E->getDestroyedTypeLoc());
13543 } else {
13544 // Look for a destructor known with the given name.
13545 ParsedType T = SemaRef.getDestructorName(
13546 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
13547 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
13548 if (!T)
13549 return ExprError();
13550
13551 Destroyed
13552 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
13553 Loc: E->getDestroyedTypeLoc());
13554 }
13555
13556 TypeSourceInfo *ScopeTypeInfo = nullptr;
13557 if (E->getScopeTypeInfo()) {
13558 CXXScopeSpec EmptySS;
13559 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
13560 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
13561 if (!ScopeTypeInfo)
13562 return ExprError();
13563 }
13564
13565 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
13566 E->getOperatorLoc(),
13567 E->isArrow(),
13568 SS,
13569 ScopeTypeInfo,
13570 E->getColonColonLoc(),
13571 E->getTildeLoc(),
13572 Destroyed);
13573}
13574
13575template <typename Derived>
13576bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
13577 bool RequiresADL,
13578 LookupResult &R) {
13579 // Transform all the decls.
13580 bool AllEmptyPacks = true;
13581 for (auto *OldD : Old->decls()) {
13582 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
13583 if (!InstD) {
13584 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
13585 // This can happen because of dependent hiding.
13586 if (isa<UsingShadowDecl>(Val: OldD))
13587 continue;
13588 else {
13589 R.clear();
13590 return true;
13591 }
13592 }
13593
13594 // Expand using pack declarations.
13595 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
13596 ArrayRef<NamedDecl*> Decls = SingleDecl;
13597 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
13598 Decls = UPD->expansions();
13599
13600 // Expand using declarations.
13601 for (auto *D : Decls) {
13602 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
13603 for (auto *SD : UD->shadows())
13604 R.addDecl(D: SD);
13605 } else {
13606 R.addDecl(D);
13607 }
13608 }
13609
13610 AllEmptyPacks &= Decls.empty();
13611 };
13612
13613 // C++ [temp.res]/8.4.2:
13614 // The program is ill-formed, no diagnostic required, if [...] lookup for
13615 // a name in the template definition found a using-declaration, but the
13616 // lookup in the corresponding scope in the instantiation odoes not find
13617 // any declarations because the using-declaration was a pack expansion and
13618 // the corresponding pack is empty
13619 if (AllEmptyPacks && !RequiresADL) {
13620 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
13621 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
13622 return true;
13623 }
13624
13625 // Resolve a kind, but don't do any further analysis. If it's
13626 // ambiguous, the callee needs to deal with it.
13627 R.resolveKind();
13628
13629 if (Old->hasTemplateKeyword() && !R.empty()) {
13630 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
13631 getSema().FilterAcceptableTemplateNames(R,
13632 /*AllowFunctionTemplates=*/true,
13633 /*AllowDependent=*/true);
13634 if (R.empty()) {
13635 // If a 'template' keyword was used, a lookup that finds only non-template
13636 // names is an error.
13637 getSema().Diag(R.getNameLoc(),
13638 diag::err_template_kw_refers_to_non_template)
13639 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
13640 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
13641 getSema().Diag(FoundDecl->getLocation(),
13642 diag::note_template_kw_refers_to_non_template)
13643 << R.getLookupName();
13644 return true;
13645 }
13646 }
13647
13648 return false;
13649}
13650
13651template <typename Derived>
13652ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
13653 UnresolvedLookupExpr *Old) {
13654 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
13655}
13656
13657template <typename Derived>
13658ExprResult
13659TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
13660 bool IsAddressOfOperand) {
13661 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
13662 Sema::LookupOrdinaryName);
13663
13664 // Transform the declaration set.
13665 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
13666 return ExprError();
13667
13668 // Rebuild the nested-name qualifier, if present.
13669 CXXScopeSpec SS;
13670 if (Old->getQualifierLoc()) {
13671 NestedNameSpecifierLoc QualifierLoc
13672 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13673 if (!QualifierLoc)
13674 return ExprError();
13675
13676 SS.Adopt(Other: QualifierLoc);
13677 }
13678
13679 if (Old->getNamingClass()) {
13680 CXXRecordDecl *NamingClass
13681 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
13682 Old->getNameLoc(),
13683 Old->getNamingClass()));
13684 if (!NamingClass) {
13685 R.clear();
13686 return ExprError();
13687 }
13688
13689 R.setNamingClass(NamingClass);
13690 }
13691
13692 // Rebuild the template arguments, if any.
13693 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13694 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
13695 if (Old->hasExplicitTemplateArgs() &&
13696 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13697 Old->getNumTemplateArgs(),
13698 TransArgs)) {
13699 R.clear();
13700 return ExprError();
13701 }
13702
13703 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
13704 // a non-static data member is named in an unevaluated operand, or when
13705 // a member is named in a dependent class scope function template explicit
13706 // specialization that is neither declared static nor with an explicit object
13707 // parameter.
13708 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
13709 return SemaRef.BuildPossibleImplicitMemberExpr(
13710 SS, TemplateKWLoc, R,
13711 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
13712 /*S=*/S: nullptr);
13713
13714 // If we have neither explicit template arguments, nor the template keyword,
13715 // it's a normal declaration name or member reference.
13716 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
13717 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
13718
13719 // If we have template arguments, then rebuild the template-id expression.
13720 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
13721 Old->requiresADL(), &TransArgs);
13722}
13723
13724template<typename Derived>
13725ExprResult
13726TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
13727 bool ArgChanged = false;
13728 SmallVector<TypeSourceInfo *, 4> Args;
13729 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
13730 TypeSourceInfo *From = E->getArg(I);
13731 TypeLoc FromTL = From->getTypeLoc();
13732 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
13733 TypeLocBuilder TLB;
13734 TLB.reserve(Requested: FromTL.getFullDataSize());
13735 QualType To = getDerived().TransformType(TLB, FromTL);
13736 if (To.isNull())
13737 return ExprError();
13738
13739 if (To == From->getType())
13740 Args.push_back(Elt: From);
13741 else {
13742 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13743 ArgChanged = true;
13744 }
13745 continue;
13746 }
13747
13748 ArgChanged = true;
13749
13750 // We have a pack expansion. Instantiate it.
13751 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
13752 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
13753 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13754 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
13755
13756 // Determine whether the set of unexpanded parameter packs can and should
13757 // be expanded.
13758 bool Expand = true;
13759 bool RetainExpansion = false;
13760 std::optional<unsigned> OrigNumExpansions =
13761 ExpansionTL.getTypePtr()->getNumExpansions();
13762 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13763 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
13764 PatternTL.getSourceRange(),
13765 Unexpanded,
13766 Expand, RetainExpansion,
13767 NumExpansions))
13768 return ExprError();
13769
13770 if (!Expand) {
13771 // The transform has determined that we should perform a simple
13772 // transformation on the pack expansion, producing another pack
13773 // expansion.
13774 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13775
13776 TypeLocBuilder TLB;
13777 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
13778
13779 QualType To = getDerived().TransformType(TLB, PatternTL);
13780 if (To.isNull())
13781 return ExprError();
13782
13783 To = getDerived().RebuildPackExpansionType(To,
13784 PatternTL.getSourceRange(),
13785 ExpansionTL.getEllipsisLoc(),
13786 NumExpansions);
13787 if (To.isNull())
13788 return ExprError();
13789
13790 PackExpansionTypeLoc ToExpansionTL
13791 = TLB.push<PackExpansionTypeLoc>(T: To);
13792 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13793 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13794 continue;
13795 }
13796
13797 // Expand the pack expansion by substituting for each argument in the
13798 // pack(s).
13799 for (unsigned I = 0; I != *NumExpansions; ++I) {
13800 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
13801 TypeLocBuilder TLB;
13802 TLB.reserve(Requested: PatternTL.getFullDataSize());
13803 QualType To = getDerived().TransformType(TLB, PatternTL);
13804 if (To.isNull())
13805 return ExprError();
13806
13807 if (To->containsUnexpandedParameterPack()) {
13808 To = getDerived().RebuildPackExpansionType(To,
13809 PatternTL.getSourceRange(),
13810 ExpansionTL.getEllipsisLoc(),
13811 NumExpansions);
13812 if (To.isNull())
13813 return ExprError();
13814
13815 PackExpansionTypeLoc ToExpansionTL
13816 = TLB.push<PackExpansionTypeLoc>(T: To);
13817 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13818 }
13819
13820 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13821 }
13822
13823 if (!RetainExpansion)
13824 continue;
13825
13826 // If we're supposed to retain a pack expansion, do so by temporarily
13827 // forgetting the partially-substituted parameter pack.
13828 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13829
13830 TypeLocBuilder TLB;
13831 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
13832
13833 QualType To = getDerived().TransformType(TLB, PatternTL);
13834 if (To.isNull())
13835 return ExprError();
13836
13837 To = getDerived().RebuildPackExpansionType(To,
13838 PatternTL.getSourceRange(),
13839 ExpansionTL.getEllipsisLoc(),
13840 NumExpansions);
13841 if (To.isNull())
13842 return ExprError();
13843
13844 PackExpansionTypeLoc ToExpansionTL
13845 = TLB.push<PackExpansionTypeLoc>(T: To);
13846 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13847 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13848 }
13849
13850 if (!getDerived().AlwaysRebuild() && !ArgChanged)
13851 return E;
13852
13853 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
13854 E->getEndLoc());
13855}
13856
13857template<typename Derived>
13858ExprResult
13859TreeTransform<Derived>::TransformConceptSpecializationExpr(
13860 ConceptSpecializationExpr *E) {
13861 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
13862 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
13863 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13864 Old->NumTemplateArgs, TransArgs))
13865 return ExprError();
13866
13867 return getDerived().RebuildConceptSpecializationExpr(
13868 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
13869 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
13870 &TransArgs);
13871}
13872
13873template<typename Derived>
13874ExprResult
13875TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
13876 SmallVector<ParmVarDecl*, 4> TransParams;
13877 SmallVector<QualType, 4> TransParamTypes;
13878 Sema::ExtParameterInfoBuilder ExtParamInfos;
13879
13880 // C++2a [expr.prim.req]p2
13881 // Expressions appearing within a requirement-body are unevaluated operands.
13882 EnterExpressionEvaluationContext Ctx(
13883 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13884 Sema::ReuseLambdaContextDecl);
13885
13886 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
13887 C&: getSema().Context, DC: getSema().CurContext,
13888 StartLoc: E->getBody()->getBeginLoc());
13889
13890 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
13891
13892 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
13893 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
13894 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
13895
13896 for (ParmVarDecl *Param : TransParams)
13897 if (Param)
13898 Param->setDeclContext(Body);
13899
13900 // On failure to transform, TransformRequiresTypeParams returns an expression
13901 // in the event that the transformation of the type params failed in some way.
13902 // It is expected that this will result in a 'not satisfied' Requires clause
13903 // when instantiating.
13904 if (!TypeParamResult.isUnset())
13905 return TypeParamResult;
13906
13907 SmallVector<concepts::Requirement *, 4> TransReqs;
13908 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
13909 TransReqs))
13910 return ExprError();
13911
13912 for (concepts::Requirement *Req : TransReqs) {
13913 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
13914 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
13915 ER->getReturnTypeRequirement()
13916 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
13917 ->setDeclContext(Body);
13918 }
13919 }
13920 }
13921
13922 return getDerived().RebuildRequiresExpr(
13923 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
13924 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
13925}
13926
13927template<typename Derived>
13928bool TreeTransform<Derived>::TransformRequiresExprRequirements(
13929 ArrayRef<concepts::Requirement *> Reqs,
13930 SmallVectorImpl<concepts::Requirement *> &Transformed) {
13931 for (concepts::Requirement *Req : Reqs) {
13932 concepts::Requirement *TransReq = nullptr;
13933 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
13934 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13935 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
13936 TransReq = getDerived().TransformExprRequirement(ExprReq);
13937 else
13938 TransReq = getDerived().TransformNestedRequirement(
13939 cast<concepts::NestedRequirement>(Val: Req));
13940 if (!TransReq)
13941 return true;
13942 Transformed.push_back(Elt: TransReq);
13943 }
13944 return false;
13945}
13946
13947template<typename Derived>
13948concepts::TypeRequirement *
13949TreeTransform<Derived>::TransformTypeRequirement(
13950 concepts::TypeRequirement *Req) {
13951 if (Req->isSubstitutionFailure()) {
13952 if (getDerived().AlwaysRebuild())
13953 return getDerived().RebuildTypeRequirement(
13954 Req->getSubstitutionDiagnostic());
13955 return Req;
13956 }
13957 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13958 if (!TransType)
13959 return nullptr;
13960 return getDerived().RebuildTypeRequirement(TransType);
13961}
13962
13963template<typename Derived>
13964concepts::ExprRequirement *
13965TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
13966 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13967 if (Req->isExprSubstitutionFailure())
13968 TransExpr = Req->getExprSubstitutionDiagnostic();
13969 else {
13970 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13971 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13972 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
13973 if (TransExprRes.isInvalid())
13974 return nullptr;
13975 TransExpr = TransExprRes.get();
13976 }
13977
13978 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13979 const auto &RetReq = Req->getReturnTypeRequirement();
13980 if (RetReq.isEmpty())
13981 TransRetReq.emplace();
13982 else if (RetReq.isSubstitutionFailure())
13983 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
13984 else if (RetReq.isTypeConstraint()) {
13985 TemplateParameterList *OrigTPL =
13986 RetReq.getTypeConstraintTemplateParameterList();
13987 TemplateParameterList *TPL =
13988 getDerived().TransformTemplateParameterList(OrigTPL);
13989 if (!TPL)
13990 return nullptr;
13991 TransRetReq.emplace(args&: TPL);
13992 }
13993 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13994 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13995 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13996 Req->getNoexceptLoc(),
13997 std::move(*TransRetReq));
13998 return getDerived().RebuildExprRequirement(
13999 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
14000 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
14001}
14002
14003template<typename Derived>
14004concepts::NestedRequirement *
14005TreeTransform<Derived>::TransformNestedRequirement(
14006 concepts::NestedRequirement *Req) {
14007 if (Req->hasInvalidConstraint()) {
14008 if (getDerived().AlwaysRebuild())
14009 return getDerived().RebuildNestedRequirement(
14010 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
14011 return Req;
14012 }
14013 ExprResult TransConstraint =
14014 getDerived().TransformExpr(Req->getConstraintExpr());
14015 if (TransConstraint.isInvalid())
14016 return nullptr;
14017 return getDerived().RebuildNestedRequirement(TransConstraint.get());
14018}
14019
14020template<typename Derived>
14021ExprResult
14022TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
14023 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
14024 if (!T)
14025 return ExprError();
14026
14027 if (!getDerived().AlwaysRebuild() &&
14028 T == E->getQueriedTypeSourceInfo())
14029 return E;
14030
14031 ExprResult SubExpr;
14032 {
14033 EnterExpressionEvaluationContext Unevaluated(
14034 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14035 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
14036 if (SubExpr.isInvalid())
14037 return ExprError();
14038
14039 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
14040 return E;
14041 }
14042
14043 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
14044 SubExpr.get(), E->getEndLoc());
14045}
14046
14047template<typename Derived>
14048ExprResult
14049TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
14050 ExprResult SubExpr;
14051 {
14052 EnterExpressionEvaluationContext Unevaluated(
14053 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14054 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
14055 if (SubExpr.isInvalid())
14056 return ExprError();
14057
14058 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
14059 return E;
14060 }
14061
14062 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
14063 SubExpr.get(), E->getEndLoc());
14064}
14065
14066template <typename Derived>
14067ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
14068 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
14069 TypeSourceInfo **RecoveryTSI) {
14070 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
14071 DRE, AddrTaken, RecoveryTSI);
14072
14073 // Propagate both errors and recovered types, which return ExprEmpty.
14074 if (!NewDRE.isUsable())
14075 return NewDRE;
14076
14077 // We got an expr, wrap it up in parens.
14078 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
14079 return PE;
14080 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
14081 PE->getRParen());
14082}
14083
14084template <typename Derived>
14085ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
14086 DependentScopeDeclRefExpr *E) {
14087 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
14088 nullptr);
14089}
14090
14091template <typename Derived>
14092ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
14093 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
14094 TypeSourceInfo **RecoveryTSI) {
14095 assert(E->getQualifierLoc());
14096 NestedNameSpecifierLoc QualifierLoc =
14097 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14098 if (!QualifierLoc)
14099 return ExprError();
14100 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14101
14102 // TODO: If this is a conversion-function-id, verify that the
14103 // destination type name (if present) resolves the same way after
14104 // instantiation as it did in the local scope.
14105
14106 DeclarationNameInfo NameInfo =
14107 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
14108 if (!NameInfo.getName())
14109 return ExprError();
14110
14111 if (!E->hasExplicitTemplateArgs()) {
14112 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
14113 // Note: it is sufficient to compare the Name component of NameInfo:
14114 // if name has not changed, DNLoc has not changed either.
14115 NameInfo.getName() == E->getDeclName())
14116 return E;
14117
14118 return getDerived().RebuildDependentScopeDeclRefExpr(
14119 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
14120 IsAddressOfOperand, RecoveryTSI);
14121 }
14122
14123 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14124 if (getDerived().TransformTemplateArguments(
14125 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
14126 return ExprError();
14127
14128 return getDerived().RebuildDependentScopeDeclRefExpr(
14129 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
14130 RecoveryTSI);
14131}
14132
14133template<typename Derived>
14134ExprResult
14135TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
14136 // CXXConstructExprs other than for list-initialization and
14137 // CXXTemporaryObjectExpr are always implicit, so when we have
14138 // a 1-argument construction we just transform that argument.
14139 if (getDerived().AllowSkippingCXXConstructExpr() &&
14140 ((E->getNumArgs() == 1 ||
14141 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
14142 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
14143 !E->isListInitialization()))
14144 return getDerived().TransformInitializer(E->getArg(Arg: 0),
14145 /*DirectInit*/ false);
14146
14147 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
14148
14149 QualType T = getDerived().TransformType(E->getType());
14150 if (T.isNull())
14151 return ExprError();
14152
14153 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14154 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14155 if (!Constructor)
14156 return ExprError();
14157
14158 bool ArgumentChanged = false;
14159 SmallVector<Expr*, 8> Args;
14160 {
14161 EnterExpressionEvaluationContext Context(
14162 getSema(), EnterExpressionEvaluationContext::InitList,
14163 E->isListInitialization());
14164 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14165 &ArgumentChanged))
14166 return ExprError();
14167 }
14168
14169 if (!getDerived().AlwaysRebuild() &&
14170 T == E->getType() &&
14171 Constructor == E->getConstructor() &&
14172 !ArgumentChanged) {
14173 // Mark the constructor as referenced.
14174 // FIXME: Instantiation-specific
14175 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
14176 return E;
14177 }
14178
14179 return getDerived().RebuildCXXConstructExpr(
14180 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
14181 E->hadMultipleCandidates(), E->isListInitialization(),
14182 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
14183 E->getConstructionKind(), E->getParenOrBraceRange());
14184}
14185
14186template<typename Derived>
14187ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
14188 CXXInheritedCtorInitExpr *E) {
14189 QualType T = getDerived().TransformType(E->getType());
14190 if (T.isNull())
14191 return ExprError();
14192
14193 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14194 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14195 if (!Constructor)
14196 return ExprError();
14197
14198 if (!getDerived().AlwaysRebuild() &&
14199 T == E->getType() &&
14200 Constructor == E->getConstructor()) {
14201 // Mark the constructor as referenced.
14202 // FIXME: Instantiation-specific
14203 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
14204 return E;
14205 }
14206
14207 return getDerived().RebuildCXXInheritedCtorInitExpr(
14208 T, E->getLocation(), Constructor,
14209 E->constructsVBase(), E->inheritedFromVBase());
14210}
14211
14212/// Transform a C++ temporary-binding expression.
14213///
14214/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
14215/// transform the subexpression and return that.
14216template<typename Derived>
14217ExprResult
14218TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
14219 if (auto *Dtor = E->getTemporary()->getDestructor())
14220 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
14221 Func: const_cast<CXXDestructorDecl *>(Dtor));
14222 return getDerived().TransformExpr(E->getSubExpr());
14223}
14224
14225/// Transform a C++ expression that contains cleanups that should
14226/// be run after the expression is evaluated.
14227///
14228/// Since ExprWithCleanups nodes are implicitly generated, we
14229/// just transform the subexpression and return that.
14230template<typename Derived>
14231ExprResult
14232TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
14233 return getDerived().TransformExpr(E->getSubExpr());
14234}
14235
14236template<typename Derived>
14237ExprResult
14238TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
14239 CXXTemporaryObjectExpr *E) {
14240 TypeSourceInfo *T =
14241 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14242 if (!T)
14243 return ExprError();
14244
14245 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14246 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14247 if (!Constructor)
14248 return ExprError();
14249
14250 bool ArgumentChanged = false;
14251 SmallVector<Expr*, 8> Args;
14252 Args.reserve(N: E->getNumArgs());
14253 {
14254 EnterExpressionEvaluationContext Context(
14255 getSema(), EnterExpressionEvaluationContext::InitList,
14256 E->isListInitialization());
14257 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
14258 ArgChanged: &ArgumentChanged))
14259 return ExprError();
14260 }
14261
14262 if (!getDerived().AlwaysRebuild() &&
14263 T == E->getTypeSourceInfo() &&
14264 Constructor == E->getConstructor() &&
14265 !ArgumentChanged) {
14266 // FIXME: Instantiation-specific
14267 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
14268 return SemaRef.MaybeBindToTemporary(E);
14269 }
14270
14271 // FIXME: We should just pass E->isListInitialization(), but we're not
14272 // prepared to handle list-initialization without a child InitListExpr.
14273 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
14274 return getDerived().RebuildCXXTemporaryObjectExpr(
14275 T, LParenLoc, Args, E->getEndLoc(),
14276 /*ListInitialization=*/LParenLoc.isInvalid());
14277}
14278
14279template<typename Derived>
14280ExprResult
14281TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
14282 // Transform any init-capture expressions before entering the scope of the
14283 // lambda body, because they are not semantically within that scope.
14284 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
14285 struct TransformedInitCapture {
14286 // The location of the ... if the result is retaining a pack expansion.
14287 SourceLocation EllipsisLoc;
14288 // Zero or more expansions of the init-capture.
14289 SmallVector<InitCaptureInfoTy, 4> Expansions;
14290 };
14291 SmallVector<TransformedInitCapture, 4> InitCaptures;
14292 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
14293 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14294 CEnd = E->capture_end();
14295 C != CEnd; ++C) {
14296 if (!E->isInitCapture(Capture: C))
14297 continue;
14298
14299 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
14300 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
14301
14302 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
14303 std::optional<unsigned> NumExpansions) {
14304 ExprResult NewExprInitResult = getDerived().TransformInitializer(
14305 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
14306
14307 if (NewExprInitResult.isInvalid()) {
14308 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
14309 return;
14310 }
14311 Expr *NewExprInit = NewExprInitResult.get();
14312
14313 QualType NewInitCaptureType =
14314 getSema().buildLambdaInitCaptureInitialization(
14315 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
14316 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
14317 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
14318 VarDecl::CInit,
14319 NewExprInit);
14320 Result.Expansions.push_back(
14321 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
14322 };
14323
14324 // If this is an init-capture pack, consider expanding the pack now.
14325 if (OldVD->isParameterPack()) {
14326 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
14327 ->getTypeLoc()
14328 .castAs<PackExpansionTypeLoc>();
14329 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14330 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
14331
14332 // Determine whether the set of unexpanded parameter packs can and should
14333 // be expanded.
14334 bool Expand = true;
14335 bool RetainExpansion = false;
14336 std::optional<unsigned> OrigNumExpansions =
14337 ExpansionTL.getTypePtr()->getNumExpansions();
14338 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14339 if (getDerived().TryExpandParameterPacks(
14340 ExpansionTL.getEllipsisLoc(),
14341 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
14342 RetainExpansion, NumExpansions))
14343 return ExprError();
14344 if (Expand) {
14345 for (unsigned I = 0; I != *NumExpansions; ++I) {
14346 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14347 SubstInitCapture(SourceLocation(), std::nullopt);
14348 }
14349 }
14350 if (!Expand || RetainExpansion) {
14351 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14352 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
14353 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
14354 }
14355 } else {
14356 SubstInitCapture(SourceLocation(), std::nullopt);
14357 }
14358 }
14359
14360 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
14361 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
14362
14363 // Create the local class that will describe the lambda.
14364
14365 // FIXME: DependencyKind below is wrong when substituting inside a templated
14366 // context that isn't a DeclContext (such as a variable template), or when
14367 // substituting an unevaluated lambda inside of a function's parameter's type
14368 // - as parameter types are not instantiated from within a function's DC. We
14369 // use evaluation contexts to distinguish the function parameter case.
14370 CXXRecordDecl::LambdaDependencyKind DependencyKind =
14371 CXXRecordDecl::LDK_Unknown;
14372 DeclContext *DC = getSema().CurContext;
14373 // A RequiresExprBodyDecl is not interesting for dependencies.
14374 // For the following case,
14375 //
14376 // template <typename>
14377 // concept C = requires { [] {}; };
14378 //
14379 // template <class F>
14380 // struct Widget;
14381 //
14382 // template <C F>
14383 // struct Widget<F> {};
14384 //
14385 // While we are substituting Widget<F>, the parent of DC would be
14386 // the template specialization itself. Thus, the lambda expression
14387 // will be deemed as dependent even if there are no dependent template
14388 // arguments.
14389 // (A ClassTemplateSpecializationDecl is always a dependent context.)
14390 while (DC->isRequiresExprBody())
14391 DC = DC->getParent();
14392 if ((getSema().isUnevaluatedContext() ||
14393 getSema().isConstantEvaluatedContext()) &&
14394 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
14395 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
14396
14397 CXXRecordDecl *OldClass = E->getLambdaClass();
14398 CXXRecordDecl *Class = getSema().createLambdaClosureType(
14399 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
14400 E->getCaptureDefault());
14401 getDerived().transformedLocalDecl(OldClass, {Class});
14402
14403 CXXMethodDecl *NewCallOperator =
14404 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
14405 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
14406
14407 // Enter the scope of the lambda.
14408 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
14409 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
14410 E->hasExplicitParameters(), E->isMutable());
14411
14412 // Introduce the context of the call operator.
14413 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
14414 /*NewThisContext*/false);
14415
14416 bool Invalid = false;
14417
14418 // Transform captures.
14419 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14420 CEnd = E->capture_end();
14421 C != CEnd; ++C) {
14422 // When we hit the first implicit capture, tell Sema that we've finished
14423 // the list of explicit captures.
14424 if (C->isImplicit())
14425 break;
14426
14427 // Capturing 'this' is trivial.
14428 if (C->capturesThis()) {
14429 // If this is a lambda that is part of a default member initialiser
14430 // and which we're instantiating outside the class that 'this' is
14431 // supposed to refer to, adjust the type of 'this' accordingly.
14432 //
14433 // Otherwise, leave the type of 'this' as-is.
14434 Sema::CXXThisScopeRAII ThisScope(
14435 getSema(),
14436 dyn_cast_if_present<CXXRecordDecl>(
14437 getSema().getFunctionLevelDeclContext()),
14438 Qualifiers());
14439 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14440 /*BuildAndDiagnose*/ true, nullptr,
14441 C->getCaptureKind() == LCK_StarThis);
14442 continue;
14443 }
14444 // Captured expression will be recaptured during captured variables
14445 // rebuilding.
14446 if (C->capturesVLAType())
14447 continue;
14448
14449 // Rebuild init-captures, including the implied field declaration.
14450 if (E->isInitCapture(Capture: C)) {
14451 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
14452
14453 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
14454 llvm::SmallVector<Decl*, 4> NewVDs;
14455
14456 for (InitCaptureInfoTy &Info : NewC.Expansions) {
14457 ExprResult Init = Info.first;
14458 QualType InitQualType = Info.second;
14459 if (Init.isInvalid() || InitQualType.isNull()) {
14460 Invalid = true;
14461 break;
14462 }
14463 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
14464 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
14465 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
14466 getSema().CurContext);
14467 if (!NewVD) {
14468 Invalid = true;
14469 break;
14470 }
14471 NewVDs.push_back(Elt: NewVD);
14472 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
14473 }
14474
14475 if (Invalid)
14476 break;
14477
14478 getDerived().transformedLocalDecl(OldVD, NewVDs);
14479 continue;
14480 }
14481
14482 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14483
14484 // Determine the capture kind for Sema.
14485 Sema::TryCaptureKind Kind
14486 = C->isImplicit()? Sema::TryCapture_Implicit
14487 : C->getCaptureKind() == LCK_ByCopy
14488 ? Sema::TryCapture_ExplicitByVal
14489 : Sema::TryCapture_ExplicitByRef;
14490 SourceLocation EllipsisLoc;
14491 if (C->isPackExpansion()) {
14492 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
14493 bool ShouldExpand = false;
14494 bool RetainExpansion = false;
14495 std::optional<unsigned> NumExpansions;
14496 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
14497 C->getLocation(),
14498 Unexpanded,
14499 ShouldExpand, RetainExpansion,
14500 NumExpansions)) {
14501 Invalid = true;
14502 continue;
14503 }
14504
14505 if (ShouldExpand) {
14506 // The transform has determined that we should perform an expansion;
14507 // transform and capture each of the arguments.
14508 // expansion of the pattern. Do so.
14509 auto *Pack = cast<VarDecl>(Val: C->getCapturedVar());
14510 for (unsigned I = 0; I != *NumExpansions; ++I) {
14511 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14512 VarDecl *CapturedVar
14513 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
14514 Pack));
14515 if (!CapturedVar) {
14516 Invalid = true;
14517 continue;
14518 }
14519
14520 // Capture the transformed variable.
14521 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
14522 }
14523
14524 // FIXME: Retain a pack expansion if RetainExpansion is true.
14525
14526 continue;
14527 }
14528
14529 EllipsisLoc = C->getEllipsisLoc();
14530 }
14531
14532 // Transform the captured variable.
14533 auto *CapturedVar = cast_or_null<ValueDecl>(
14534 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14535 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
14536 Invalid = true;
14537 continue;
14538 }
14539
14540 // Capture the transformed variable.
14541 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
14542 EllipsisLoc);
14543 }
14544 getSema().finishLambdaExplicitCaptures(LSI);
14545
14546 // Transform the template parameters, and add them to the current
14547 // instantiation scope. The null case is handled correctly.
14548 auto TPL = getDerived().TransformTemplateParameterList(
14549 E->getTemplateParameterList());
14550 LSI->GLTemplateParameterList = TPL;
14551 if (TPL)
14552 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
14553 TPL);
14554
14555 // Transform the type of the original lambda's call operator.
14556 // The transformation MUST be done in the CurrentInstantiationScope since
14557 // it introduces a mapping of the original to the newly created
14558 // transformed parameters.
14559 TypeSourceInfo *NewCallOpTSI = nullptr;
14560 {
14561 auto OldCallOpTypeLoc =
14562 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
14563
14564 auto TransformFunctionProtoTypeLoc =
14565 [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
14566 SmallVector<QualType, 4> ExceptionStorage;
14567 return this->TransformFunctionProtoType(
14568 TLB, FPTL, nullptr, Qualifiers(),
14569 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
14570 return TransformExceptionSpec(Loc: FPTL.getBeginLoc(), ESI,
14571 Exceptions&: ExceptionStorage, Changed);
14572 });
14573 };
14574
14575 QualType NewCallOpType;
14576 TypeLocBuilder NewCallOpTLBuilder;
14577
14578 if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
14579 NewCallOpType = this->TransformAttributedType(
14580 NewCallOpTLBuilder, ATL,
14581 [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
14582 return TransformFunctionProtoTypeLoc(
14583 TLB, TL.castAs<FunctionProtoTypeLoc>());
14584 });
14585 } else {
14586 auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
14587 NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
14588 }
14589
14590 if (NewCallOpType.isNull())
14591 return ExprError();
14592 NewCallOpTSI =
14593 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
14594 }
14595
14596 ArrayRef<ParmVarDecl *> Params;
14597 if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
14598 Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
14599 } else {
14600 auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
14601 Params = FPTL.getParams();
14602 }
14603
14604 getSema().CompleteLambdaCallOperator(
14605 NewCallOperator, E->getCallOperator()->getLocation(),
14606 E->getCallOperator()->getInnerLocStart(),
14607 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
14608 E->getCallOperator()->getConstexprKind(),
14609 E->getCallOperator()->getStorageClass(), Params,
14610 E->hasExplicitResultType());
14611
14612 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
14613 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
14614
14615 {
14616 // Number the lambda for linkage purposes if necessary.
14617 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
14618
14619 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
14620 if (getDerived().ReplacingOriginal()) {
14621 Numbering = OldClass->getLambdaNumbering();
14622 }
14623
14624 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
14625 }
14626
14627 // FIXME: Sema's lambda-building mechanism expects us to push an expression
14628 // evaluation context even if we're not transforming the function body.
14629 getSema().PushExpressionEvaluationContext(
14630 E->getCallOperator()->isConsteval() ?
14631 Sema::ExpressionEvaluationContext::ImmediateFunctionContext :
14632 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
14633 getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
14634 getSema().getLangOpts().CPlusPlus20 &&
14635 E->getCallOperator()->isImmediateEscalating();
14636
14637 Sema::CodeSynthesisContext C;
14638 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
14639 C.PointOfInstantiation = E->getBody()->getBeginLoc();
14640 getSema().pushCodeSynthesisContext(C);
14641
14642 // Instantiate the body of the lambda expression.
14643 StmtResult Body =
14644 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
14645
14646 getSema().popCodeSynthesisContext();
14647
14648 // ActOnLambda* will pop the function scope for us.
14649 FuncScopeCleanup.disable();
14650
14651 if (Body.isInvalid()) {
14652 SavedContext.pop();
14653 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
14654 /*IsInstantiation=*/true);
14655 return ExprError();
14656 }
14657
14658 // Copy the LSI before ActOnFinishFunctionBody removes it.
14659 // FIXME: This is dumb. Store the lambda information somewhere that outlives
14660 // the call operator.
14661 auto LSICopy = *LSI;
14662 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
14663 /*IsInstantiation*/ true);
14664 SavedContext.pop();
14665
14666 // Recompute the dependency of the lambda so that we can defer the lambda call
14667 // construction until after we have all the necessary template arguments. For
14668 // example, given
14669 //
14670 // template <class> struct S {
14671 // template <class U>
14672 // using Type = decltype([](U){}(42.0));
14673 // };
14674 // void foo() {
14675 // using T = S<int>::Type<float>;
14676 // ^~~~~~
14677 // }
14678 //
14679 // We would end up here from instantiating S<int> when ensuring its
14680 // completeness. That would transform the lambda call expression regardless of
14681 // the absence of the corresponding argument for U.
14682 //
14683 // Going ahead with unsubstituted type U makes things worse: we would soon
14684 // compare the argument type (which is float) against the parameter U
14685 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
14686 // error suggesting unmatched types 'U' and 'float'!
14687 //
14688 // That said, everything will be fine if we defer that semantic checking.
14689 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
14690 // dependent. Since the CallExpr's dependency boils down to the lambda's
14691 // dependency in this case, we can harness that by recomputing the dependency
14692 // from the instantiation arguments.
14693 //
14694 // FIXME: Creating the type of a lambda requires us to have a dependency
14695 // value, which happens before its substitution. We update its dependency
14696 // *after* the substitution in case we can't decide the dependency
14697 // so early, e.g. because we want to see if any of the *substituted*
14698 // parameters are dependent.
14699 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
14700 Class->setLambdaDependencyKind(DependencyKind);
14701 // Clean up the type cache created previously. Then, we re-create a type for
14702 // such Decl with the new DependencyKind.
14703 Class->setTypeForDecl(nullptr);
14704 getSema().Context.getTypeDeclType(Class);
14705
14706 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
14707 &LSICopy);
14708}
14709
14710template<typename Derived>
14711StmtResult
14712TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
14713 return TransformStmt(S);
14714}
14715
14716template<typename Derived>
14717StmtResult
14718TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
14719 // Transform captures.
14720 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14721 CEnd = E->capture_end();
14722 C != CEnd; ++C) {
14723 // When we hit the first implicit capture, tell Sema that we've finished
14724 // the list of explicit captures.
14725 if (!C->isImplicit())
14726 continue;
14727
14728 // Capturing 'this' is trivial.
14729 if (C->capturesThis()) {
14730 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14731 /*BuildAndDiagnose*/ true, nullptr,
14732 C->getCaptureKind() == LCK_StarThis);
14733 continue;
14734 }
14735 // Captured expression will be recaptured during captured variables
14736 // rebuilding.
14737 if (C->capturesVLAType())
14738 continue;
14739
14740 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14741 assert(!E->isInitCapture(C) && "implicit init-capture?");
14742
14743 // Transform the captured variable.
14744 VarDecl *CapturedVar = cast_or_null<VarDecl>(
14745 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14746 if (!CapturedVar || CapturedVar->isInvalidDecl())
14747 return StmtError();
14748
14749 // Capture the transformed variable.
14750 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
14751 }
14752
14753 return S;
14754}
14755
14756template<typename Derived>
14757ExprResult
14758TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
14759 CXXUnresolvedConstructExpr *E) {
14760 TypeSourceInfo *T =
14761 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14762 if (!T)
14763 return ExprError();
14764
14765 bool ArgumentChanged = false;
14766 SmallVector<Expr*, 8> Args;
14767 Args.reserve(N: E->getNumArgs());
14768 {
14769 EnterExpressionEvaluationContext Context(
14770 getSema(), EnterExpressionEvaluationContext::InitList,
14771 E->isListInitialization());
14772 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
14773 &ArgumentChanged))
14774 return ExprError();
14775 }
14776
14777 if (!getDerived().AlwaysRebuild() &&
14778 T == E->getTypeSourceInfo() &&
14779 !ArgumentChanged)
14780 return E;
14781
14782 // FIXME: we're faking the locations of the commas
14783 return getDerived().RebuildCXXUnresolvedConstructExpr(
14784 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
14785}
14786
14787template<typename Derived>
14788ExprResult
14789TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
14790 CXXDependentScopeMemberExpr *E) {
14791 // Transform the base of the expression.
14792 ExprResult Base((Expr*) nullptr);
14793 Expr *OldBase;
14794 QualType BaseType;
14795 QualType ObjectType;
14796 if (!E->isImplicitAccess()) {
14797 OldBase = E->getBase();
14798 Base = getDerived().TransformExpr(OldBase);
14799 if (Base.isInvalid())
14800 return ExprError();
14801
14802 // Start the member reference and compute the object's type.
14803 ParsedType ObjectTy;
14804 bool MayBePseudoDestructor = false;
14805 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14806 OpLoc: E->getOperatorLoc(),
14807 OpKind: E->isArrow()? tok::arrow : tok::period,
14808 ObjectType&: ObjectTy,
14809 MayBePseudoDestructor);
14810 if (Base.isInvalid())
14811 return ExprError();
14812
14813 ObjectType = ObjectTy.get();
14814 BaseType = ((Expr*) Base.get())->getType();
14815 } else {
14816 OldBase = nullptr;
14817 BaseType = getDerived().TransformType(E->getBaseType());
14818 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
14819 }
14820
14821 // Transform the first part of the nested-name-specifier that qualifies
14822 // the member name.
14823 NamedDecl *FirstQualifierInScope
14824 = getDerived().TransformFirstQualifierInScope(
14825 E->getFirstQualifierFoundInScope(),
14826 E->getQualifierLoc().getBeginLoc());
14827
14828 NestedNameSpecifierLoc QualifierLoc;
14829 if (E->getQualifier()) {
14830 QualifierLoc
14831 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
14832 ObjectType,
14833 FirstQualifierInScope);
14834 if (!QualifierLoc)
14835 return ExprError();
14836 }
14837
14838 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14839
14840 // TODO: If this is a conversion-function-id, verify that the
14841 // destination type name (if present) resolves the same way after
14842 // instantiation as it did in the local scope.
14843
14844 DeclarationNameInfo NameInfo
14845 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
14846 if (!NameInfo.getName())
14847 return ExprError();
14848
14849 if (!E->hasExplicitTemplateArgs()) {
14850 // This is a reference to a member without an explicitly-specified
14851 // template argument list. Optimize for this common case.
14852 if (!getDerived().AlwaysRebuild() &&
14853 Base.get() == OldBase &&
14854 BaseType == E->getBaseType() &&
14855 QualifierLoc == E->getQualifierLoc() &&
14856 NameInfo.getName() == E->getMember() &&
14857 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
14858 return E;
14859
14860 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14861 BaseType,
14862 E->isArrow(),
14863 E->getOperatorLoc(),
14864 QualifierLoc,
14865 TemplateKWLoc,
14866 FirstQualifierInScope,
14867 NameInfo,
14868 /*TemplateArgs*/nullptr);
14869 }
14870
14871 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14872 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14873 E->getNumTemplateArgs(),
14874 TransArgs))
14875 return ExprError();
14876
14877 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14878 BaseType,
14879 E->isArrow(),
14880 E->getOperatorLoc(),
14881 QualifierLoc,
14882 TemplateKWLoc,
14883 FirstQualifierInScope,
14884 NameInfo,
14885 &TransArgs);
14886}
14887
14888template <typename Derived>
14889ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
14890 UnresolvedMemberExpr *Old) {
14891 // Transform the base of the expression.
14892 ExprResult Base((Expr *)nullptr);
14893 QualType BaseType;
14894 if (!Old->isImplicitAccess()) {
14895 Base = getDerived().TransformExpr(Old->getBase());
14896 if (Base.isInvalid())
14897 return ExprError();
14898 Base =
14899 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
14900 if (Base.isInvalid())
14901 return ExprError();
14902 BaseType = Base.get()->getType();
14903 } else {
14904 BaseType = getDerived().TransformType(Old->getBaseType());
14905 }
14906
14907 NestedNameSpecifierLoc QualifierLoc;
14908 if (Old->getQualifierLoc()) {
14909 QualifierLoc =
14910 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14911 if (!QualifierLoc)
14912 return ExprError();
14913 }
14914
14915 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14916
14917 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
14918
14919 // Transform the declaration set.
14920 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
14921 return ExprError();
14922
14923 // Determine the naming class.
14924 if (Old->getNamingClass()) {
14925 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
14926 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
14927 if (!NamingClass)
14928 return ExprError();
14929
14930 R.setNamingClass(NamingClass);
14931 }
14932
14933 TemplateArgumentListInfo TransArgs;
14934 if (Old->hasExplicitTemplateArgs()) {
14935 TransArgs.setLAngleLoc(Old->getLAngleLoc());
14936 TransArgs.setRAngleLoc(Old->getRAngleLoc());
14937 if (getDerived().TransformTemplateArguments(
14938 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
14939 return ExprError();
14940 }
14941
14942 // FIXME: to do this check properly, we will need to preserve the
14943 // first-qualifier-in-scope here, just in case we had a dependent
14944 // base (and therefore couldn't do the check) and a
14945 // nested-name-qualifier (and therefore could do the lookup).
14946 NamedDecl *FirstQualifierInScope = nullptr;
14947
14948 return getDerived().RebuildUnresolvedMemberExpr(
14949 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
14950 TemplateKWLoc, FirstQualifierInScope, R,
14951 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
14952}
14953
14954template<typename Derived>
14955ExprResult
14956TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
14957 EnterExpressionEvaluationContext Unevaluated(
14958 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14959 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
14960 if (SubExpr.isInvalid())
14961 return ExprError();
14962
14963 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
14964 return E;
14965
14966 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
14967}
14968
14969template<typename Derived>
14970ExprResult
14971TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
14972 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
14973 if (Pattern.isInvalid())
14974 return ExprError();
14975
14976 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
14977 return E;
14978
14979 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
14980 E->getNumExpansions());
14981}
14982
14983template<typename Derived>
14984ExprResult
14985TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
14986 // If E is not value-dependent, then nothing will change when we transform it.
14987 // Note: This is an instantiation-centric view.
14988 if (!E->isValueDependent())
14989 return E;
14990
14991 EnterExpressionEvaluationContext Unevaluated(
14992 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
14993
14994 ArrayRef<TemplateArgument> PackArgs;
14995 TemplateArgument ArgStorage;
14996
14997 // Find the argument list to transform.
14998 if (E->isPartiallySubstituted()) {
14999 PackArgs = E->getPartialArguments();
15000 } else if (E->isValueDependent()) {
15001 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
15002 bool ShouldExpand = false;
15003 bool RetainExpansion = false;
15004 std::optional<unsigned> NumExpansions;
15005 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
15006 Unexpanded,
15007 ShouldExpand, RetainExpansion,
15008 NumExpansions))
15009 return ExprError();
15010
15011 // If we need to expand the pack, build a template argument from it and
15012 // expand that.
15013 if (ShouldExpand) {
15014 auto *Pack = E->getPack();
15015 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
15016 ArgStorage = getSema().Context.getPackExpansionType(
15017 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
15018 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
15019 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
15020 } else {
15021 auto *VD = cast<ValueDecl>(Val: Pack);
15022 ExprResult DRE = getSema().BuildDeclRefExpr(
15023 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
15024 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
15025 E->getPackLoc());
15026 if (DRE.isInvalid())
15027 return ExprError();
15028 ArgStorage = new (getSema().Context)
15029 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
15030 E->getPackLoc(), std::nullopt);
15031 }
15032 PackArgs = ArgStorage;
15033 }
15034 }
15035
15036 // If we're not expanding the pack, just transform the decl.
15037 if (!PackArgs.size()) {
15038 auto *Pack = cast_or_null<NamedDecl>(
15039 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
15040 if (!Pack)
15041 return ExprError();
15042 return getDerived().RebuildSizeOfPackExpr(
15043 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
15044 std::nullopt, std::nullopt);
15045 }
15046
15047 // Try to compute the result without performing a partial substitution.
15048 std::optional<unsigned> Result = 0;
15049 for (const TemplateArgument &Arg : PackArgs) {
15050 if (!Arg.isPackExpansion()) {
15051 Result = *Result + 1;
15052 continue;
15053 }
15054
15055 TemplateArgumentLoc ArgLoc;
15056 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
15057
15058 // Find the pattern of the pack expansion.
15059 SourceLocation Ellipsis;
15060 std::optional<unsigned> OrigNumExpansions;
15061 TemplateArgumentLoc Pattern =
15062 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
15063 OrigNumExpansions);
15064
15065 // Substitute under the pack expansion. Do not expand the pack (yet).
15066 TemplateArgumentLoc OutPattern;
15067 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15068 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
15069 /*Uneval*/ true))
15070 return true;
15071
15072 // See if we can determine the number of arguments from the result.
15073 std::optional<unsigned> NumExpansions =
15074 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
15075 if (!NumExpansions) {
15076 // No: we must be in an alias template expansion, and we're going to need
15077 // to actually expand the packs.
15078 Result = std::nullopt;
15079 break;
15080 }
15081
15082 Result = *Result + *NumExpansions;
15083 }
15084
15085 // Common case: we could determine the number of expansions without
15086 // substituting.
15087 if (Result)
15088 return getDerived().RebuildSizeOfPackExpr(
15089 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
15090 *Result, std::nullopt);
15091
15092 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
15093 E->getPackLoc());
15094 {
15095 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
15096 typedef TemplateArgumentLocInventIterator<
15097 Derived, const TemplateArgument*> PackLocIterator;
15098 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
15099 PackLocIterator(*this, PackArgs.end()),
15100 TransformedPackArgs, /*Uneval*/true))
15101 return ExprError();
15102 }
15103
15104 // Check whether we managed to fully-expand the pack.
15105 // FIXME: Is it possible for us to do so and not hit the early exit path?
15106 SmallVector<TemplateArgument, 8> Args;
15107 bool PartialSubstitution = false;
15108 for (auto &Loc : TransformedPackArgs.arguments()) {
15109 Args.push_back(Elt: Loc.getArgument());
15110 if (Loc.getArgument().isPackExpansion())
15111 PartialSubstitution = true;
15112 }
15113
15114 if (PartialSubstitution)
15115 return getDerived().RebuildSizeOfPackExpr(
15116 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
15117 std::nullopt, Args);
15118
15119 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
15120 E->getPackLoc(), E->getRParenLoc(),
15121 Args.size(), std::nullopt);
15122}
15123
15124template <typename Derived>
15125ExprResult
15126TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
15127 if (!E->isValueDependent())
15128 return E;
15129
15130 // Transform the index
15131 ExprResult IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
15132 if (IndexExpr.isInvalid())
15133 return ExprError();
15134
15135 SmallVector<Expr *, 5> ExpandedExprs;
15136 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
15137 Expr *Pattern = E->getPackIdExpression();
15138 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15139 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
15140 Unexpanded);
15141 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15142
15143 // Determine whether the set of unexpanded parameter packs can and should
15144 // be expanded.
15145 bool ShouldExpand = true;
15146 bool RetainExpansion = false;
15147 std::optional<unsigned> OrigNumExpansions;
15148 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15149 if (getDerived().TryExpandParameterPacks(
15150 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
15151 ShouldExpand, RetainExpansion, NumExpansions))
15152 return true;
15153 if (!ShouldExpand) {
15154 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15155 ExprResult Pack = getDerived().TransformExpr(Pattern);
15156 if (Pack.isInvalid())
15157 return ExprError();
15158 return getDerived().RebuildPackIndexingExpr(
15159 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
15160 std::nullopt);
15161 }
15162 for (unsigned I = 0; I != *NumExpansions; ++I) {
15163 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15164 ExprResult Out = getDerived().TransformExpr(Pattern);
15165 if (Out.isInvalid())
15166 return true;
15167 if (Out.get()->containsUnexpandedParameterPack()) {
15168 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15169 OrigNumExpansions);
15170 if (Out.isInvalid())
15171 return true;
15172 }
15173 ExpandedExprs.push_back(Elt: Out.get());
15174 }
15175 // If we're supposed to retain a pack expansion, do so by temporarily
15176 // forgetting the partially-substituted parameter pack.
15177 if (RetainExpansion) {
15178 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15179
15180 ExprResult Out = getDerived().TransformExpr(Pattern);
15181 if (Out.isInvalid())
15182 return true;
15183
15184 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15185 OrigNumExpansions);
15186 if (Out.isInvalid())
15187 return true;
15188 ExpandedExprs.push_back(Elt: Out.get());
15189 }
15190 } else if (!E->expandsToEmptyPack()) {
15191 if (getDerived().TransformExprs(E->getExpressions().data(),
15192 E->getExpressions().size(), false,
15193 ExpandedExprs))
15194 return ExprError();
15195 }
15196
15197 return getDerived().RebuildPackIndexingExpr(
15198 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
15199 IndexExpr.get(), ExpandedExprs,
15200 /*EmptyPack=*/ExpandedExprs.size() == 0);
15201}
15202
15203template<typename Derived>
15204ExprResult
15205TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
15206 SubstNonTypeTemplateParmPackExpr *E) {
15207 // Default behavior is to do nothing with this transformation.
15208 return E;
15209}
15210
15211template<typename Derived>
15212ExprResult
15213TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
15214 SubstNonTypeTemplateParmExpr *E) {
15215 // Default behavior is to do nothing with this transformation.
15216 return E;
15217}
15218
15219template<typename Derived>
15220ExprResult
15221TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
15222 // Default behavior is to do nothing with this transformation.
15223 return E;
15224}
15225
15226template<typename Derived>
15227ExprResult
15228TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
15229 MaterializeTemporaryExpr *E) {
15230 return getDerived().TransformExpr(E->getSubExpr());
15231}
15232
15233template<typename Derived>
15234ExprResult
15235TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
15236 UnresolvedLookupExpr *Callee = nullptr;
15237 if (Expr *OldCallee = E->getCallee()) {
15238 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
15239 if (CalleeResult.isInvalid())
15240 return ExprError();
15241 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
15242 }
15243
15244 Expr *Pattern = E->getPattern();
15245
15246 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15247 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
15248 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15249
15250 // Determine whether the set of unexpanded parameter packs can and should
15251 // be expanded.
15252 bool Expand = true;
15253 bool RetainExpansion = false;
15254 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
15255 NumExpansions = OrigNumExpansions;
15256 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
15257 Pattern->getSourceRange(),
15258 Unexpanded,
15259 Expand, RetainExpansion,
15260 NumExpansions))
15261 return true;
15262
15263 if (!Expand) {
15264 // Do not expand any packs here, just transform and rebuild a fold
15265 // expression.
15266 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15267
15268 ExprResult LHS =
15269 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
15270 if (LHS.isInvalid())
15271 return true;
15272
15273 ExprResult RHS =
15274 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
15275 if (RHS.isInvalid())
15276 return true;
15277
15278 if (!getDerived().AlwaysRebuild() &&
15279 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
15280 return E;
15281
15282 return getDerived().RebuildCXXFoldExpr(
15283 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
15284 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
15285 }
15286
15287 // Formally a fold expression expands to nested parenthesized expressions.
15288 // Enforce this limit to avoid creating trees so deep we can't safely traverse
15289 // them.
15290 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
15291 SemaRef.Diag(Loc: E->getEllipsisLoc(),
15292 DiagID: clang::diag::err_fold_expression_limit_exceeded)
15293 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
15294 << E->getSourceRange();
15295 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
15296 return ExprError();
15297 }
15298
15299 // The transform has determined that we should perform an elementwise
15300 // expansion of the pattern. Do so.
15301 ExprResult Result = getDerived().TransformExpr(E->getInit());
15302 if (Result.isInvalid())
15303 return true;
15304 bool LeftFold = E->isLeftFold();
15305
15306 // If we're retaining an expansion for a right fold, it is the innermost
15307 // component and takes the init (if any).
15308 if (!LeftFold && RetainExpansion) {
15309 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15310
15311 ExprResult Out = getDerived().TransformExpr(Pattern);
15312 if (Out.isInvalid())
15313 return true;
15314
15315 Result = getDerived().RebuildCXXFoldExpr(
15316 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
15317 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
15318 if (Result.isInvalid())
15319 return true;
15320 }
15321
15322 for (unsigned I = 0; I != *NumExpansions; ++I) {
15323 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
15324 getSema(), LeftFold ? I : *NumExpansions - I - 1);
15325 ExprResult Out = getDerived().TransformExpr(Pattern);
15326 if (Out.isInvalid())
15327 return true;
15328
15329 if (Out.get()->containsUnexpandedParameterPack()) {
15330 // We still have a pack; retain a pack expansion for this slice.
15331 Result = getDerived().RebuildCXXFoldExpr(
15332 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
15333 E->getOperator(), E->getEllipsisLoc(),
15334 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
15335 OrigNumExpansions);
15336 } else if (Result.isUsable()) {
15337 // We've got down to a single element; build a binary operator.
15338 Expr *LHS = LeftFold ? Result.get() : Out.get();
15339 Expr *RHS = LeftFold ? Out.get() : Result.get();
15340 if (Callee) {
15341 UnresolvedSet<16> Functions;
15342 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
15343 Result = getDerived().RebuildCXXOperatorCallExpr(
15344 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
15345 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
15346 Functions, LHS, RHS);
15347 } else {
15348 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
15349 E->getOperator(), LHS, RHS);
15350 }
15351 } else
15352 Result = Out;
15353
15354 if (Result.isInvalid())
15355 return true;
15356 }
15357
15358 // If we're retaining an expansion for a left fold, it is the outermost
15359 // component and takes the complete expansion so far as its init (if any).
15360 if (LeftFold && RetainExpansion) {
15361 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15362
15363 ExprResult Out = getDerived().TransformExpr(Pattern);
15364 if (Out.isInvalid())
15365 return true;
15366
15367 Result = getDerived().RebuildCXXFoldExpr(
15368 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
15369 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
15370 if (Result.isInvalid())
15371 return true;
15372 }
15373
15374 // If we had no init and an empty pack, and we're not retaining an expansion,
15375 // then produce a fallback value or error.
15376 if (Result.isUnset())
15377 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
15378 E->getOperator());
15379
15380 return Result;
15381}
15382
15383template <typename Derived>
15384ExprResult
15385TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
15386 SmallVector<Expr *, 4> TransformedInits;
15387 ArrayRef<Expr *> InitExprs = E->getInitExprs();
15388 if (TransformExprs(Inputs: InitExprs.data(), NumInputs: InitExprs.size(), IsCall: true,
15389 Outputs&: TransformedInits))
15390 return ExprError();
15391
15392 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
15393 E->getEndLoc());
15394}
15395
15396template<typename Derived>
15397ExprResult
15398TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
15399 CXXStdInitializerListExpr *E) {
15400 return getDerived().TransformExpr(E->getSubExpr());
15401}
15402
15403template<typename Derived>
15404ExprResult
15405TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
15406 return SemaRef.MaybeBindToTemporary(E);
15407}
15408
15409template<typename Derived>
15410ExprResult
15411TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
15412 return E;
15413}
15414
15415template<typename Derived>
15416ExprResult
15417TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
15418 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15419 if (SubExpr.isInvalid())
15420 return ExprError();
15421
15422 if (!getDerived().AlwaysRebuild() &&
15423 SubExpr.get() == E->getSubExpr())
15424 return E;
15425
15426 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
15427}
15428
15429template<typename Derived>
15430ExprResult
15431TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
15432 // Transform each of the elements.
15433 SmallVector<Expr *, 8> Elements;
15434 bool ArgChanged = false;
15435 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
15436 /*IsCall=*/false, Elements, &ArgChanged))
15437 return ExprError();
15438
15439 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15440 return SemaRef.MaybeBindToTemporary(E);
15441
15442 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
15443 Elements.data(),
15444 Elements.size());
15445}
15446
15447template<typename Derived>
15448ExprResult
15449TreeTransform<Derived>::TransformObjCDictionaryLiteral(
15450 ObjCDictionaryLiteral *E) {
15451 // Transform each of the elements.
15452 SmallVector<ObjCDictionaryElement, 8> Elements;
15453 bool ArgChanged = false;
15454 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
15455 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
15456
15457 if (OrigElement.isPackExpansion()) {
15458 // This key/value element is a pack expansion.
15459 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15460 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
15461 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
15462 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15463
15464 // Determine whether the set of unexpanded parameter packs can
15465 // and should be expanded.
15466 bool Expand = true;
15467 bool RetainExpansion = false;
15468 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
15469 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15470 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
15471 OrigElement.Value->getEndLoc());
15472 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
15473 PatternRange, Unexpanded, Expand,
15474 RetainExpansion, NumExpansions))
15475 return ExprError();
15476
15477 if (!Expand) {
15478 // The transform has determined that we should perform a simple
15479 // transformation on the pack expansion, producing another pack
15480 // expansion.
15481 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15482 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15483 if (Key.isInvalid())
15484 return ExprError();
15485
15486 if (Key.get() != OrigElement.Key)
15487 ArgChanged = true;
15488
15489 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15490 if (Value.isInvalid())
15491 return ExprError();
15492
15493 if (Value.get() != OrigElement.Value)
15494 ArgChanged = true;
15495
15496 ObjCDictionaryElement Expansion = {
15497 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
15498 };
15499 Elements.push_back(Elt: Expansion);
15500 continue;
15501 }
15502
15503 // Record right away that the argument was changed. This needs
15504 // to happen even if the array expands to nothing.
15505 ArgChanged = true;
15506
15507 // The transform has determined that we should perform an elementwise
15508 // expansion of the pattern. Do so.
15509 for (unsigned I = 0; I != *NumExpansions; ++I) {
15510 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15511 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15512 if (Key.isInvalid())
15513 return ExprError();
15514
15515 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15516 if (Value.isInvalid())
15517 return ExprError();
15518
15519 ObjCDictionaryElement Element = {
15520 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
15521 };
15522
15523 // If any unexpanded parameter packs remain, we still have a
15524 // pack expansion.
15525 // FIXME: Can this really happen?
15526 if (Key.get()->containsUnexpandedParameterPack() ||
15527 Value.get()->containsUnexpandedParameterPack())
15528 Element.EllipsisLoc = OrigElement.EllipsisLoc;
15529
15530 Elements.push_back(Elt: Element);
15531 }
15532
15533 // FIXME: Retain a pack expansion if RetainExpansion is true.
15534
15535 // We've finished with this pack expansion.
15536 continue;
15537 }
15538
15539 // Transform and check key.
15540 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15541 if (Key.isInvalid())
15542 return ExprError();
15543
15544 if (Key.get() != OrigElement.Key)
15545 ArgChanged = true;
15546
15547 // Transform and check value.
15548 ExprResult Value
15549 = getDerived().TransformExpr(OrigElement.Value);
15550 if (Value.isInvalid())
15551 return ExprError();
15552
15553 if (Value.get() != OrigElement.Value)
15554 ArgChanged = true;
15555
15556 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
15557 .NumExpansions: std::nullopt};
15558 Elements.push_back(Elt: Element);
15559 }
15560
15561 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15562 return SemaRef.MaybeBindToTemporary(E);
15563
15564 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
15565 Elements);
15566}
15567
15568template<typename Derived>
15569ExprResult
15570TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
15571 TypeSourceInfo *EncodedTypeInfo
15572 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
15573 if (!EncodedTypeInfo)
15574 return ExprError();
15575
15576 if (!getDerived().AlwaysRebuild() &&
15577 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
15578 return E;
15579
15580 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
15581 EncodedTypeInfo,
15582 E->getRParenLoc());
15583}
15584
15585template<typename Derived>
15586ExprResult TreeTransform<Derived>::
15587TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
15588 // This is a kind of implicit conversion, and it needs to get dropped
15589 // and recomputed for the same general reasons that ImplicitCastExprs
15590 // do, as well a more specific one: this expression is only valid when
15591 // it appears *immediately* as an argument expression.
15592 return getDerived().TransformExpr(E->getSubExpr());
15593}
15594
15595template<typename Derived>
15596ExprResult TreeTransform<Derived>::
15597TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
15598 TypeSourceInfo *TSInfo
15599 = getDerived().TransformType(E->getTypeInfoAsWritten());
15600 if (!TSInfo)
15601 return ExprError();
15602
15603 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
15604 if (Result.isInvalid())
15605 return ExprError();
15606
15607 if (!getDerived().AlwaysRebuild() &&
15608 TSInfo == E->getTypeInfoAsWritten() &&
15609 Result.get() == E->getSubExpr())
15610 return E;
15611
15612 return SemaRef.ObjC().BuildObjCBridgedCast(
15613 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
15614 SubExpr: Result.get());
15615}
15616
15617template <typename Derived>
15618ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
15619 ObjCAvailabilityCheckExpr *E) {
15620 return E;
15621}
15622
15623template<typename Derived>
15624ExprResult
15625TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
15626 // Transform arguments.
15627 bool ArgChanged = false;
15628 SmallVector<Expr*, 8> Args;
15629 Args.reserve(N: E->getNumArgs());
15630 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
15631 &ArgChanged))
15632 return ExprError();
15633
15634 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
15635 // Class message: transform the receiver type.
15636 TypeSourceInfo *ReceiverTypeInfo
15637 = getDerived().TransformType(E->getClassReceiverTypeInfo());
15638 if (!ReceiverTypeInfo)
15639 return ExprError();
15640
15641 // If nothing changed, just retain the existing message send.
15642 if (!getDerived().AlwaysRebuild() &&
15643 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
15644 return SemaRef.MaybeBindToTemporary(E);
15645
15646 // Build a new class message send.
15647 SmallVector<SourceLocation, 16> SelLocs;
15648 E->getSelectorLocs(SelLocs);
15649 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
15650 E->getSelector(),
15651 SelLocs,
15652 E->getMethodDecl(),
15653 E->getLeftLoc(),
15654 Args,
15655 E->getRightLoc());
15656 }
15657 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
15658 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
15659 if (!E->getMethodDecl())
15660 return ExprError();
15661
15662 // Build a new class message send to 'super'.
15663 SmallVector<SourceLocation, 16> SelLocs;
15664 E->getSelectorLocs(SelLocs);
15665 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
15666 E->getSelector(),
15667 SelLocs,
15668 E->getReceiverType(),
15669 E->getMethodDecl(),
15670 E->getLeftLoc(),
15671 Args,
15672 E->getRightLoc());
15673 }
15674
15675 // Instance message: transform the receiver
15676 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
15677 "Only class and instance messages may be instantiated");
15678 ExprResult Receiver
15679 = getDerived().TransformExpr(E->getInstanceReceiver());
15680 if (Receiver.isInvalid())
15681 return ExprError();
15682
15683 // If nothing changed, just retain the existing message send.
15684 if (!getDerived().AlwaysRebuild() &&
15685 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
15686 return SemaRef.MaybeBindToTemporary(E);
15687
15688 // Build a new instance message send.
15689 SmallVector<SourceLocation, 16> SelLocs;
15690 E->getSelectorLocs(SelLocs);
15691 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
15692 E->getSelector(),
15693 SelLocs,
15694 E->getMethodDecl(),
15695 E->getLeftLoc(),
15696 Args,
15697 E->getRightLoc());
15698}
15699
15700template<typename Derived>
15701ExprResult
15702TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
15703 return E;
15704}
15705
15706template<typename Derived>
15707ExprResult
15708TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
15709 return E;
15710}
15711
15712template<typename Derived>
15713ExprResult
15714TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
15715 // Transform the base expression.
15716 ExprResult Base = getDerived().TransformExpr(E->getBase());
15717 if (Base.isInvalid())
15718 return ExprError();
15719
15720 // We don't need to transform the ivar; it will never change.
15721
15722 // If nothing changed, just retain the existing expression.
15723 if (!getDerived().AlwaysRebuild() &&
15724 Base.get() == E->getBase())
15725 return E;
15726
15727 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
15728 E->getLocation(),
15729 E->isArrow(), E->isFreeIvar());
15730}
15731
15732template<typename Derived>
15733ExprResult
15734TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
15735 // 'super' and types never change. Property never changes. Just
15736 // retain the existing expression.
15737 if (!E->isObjectReceiver())
15738 return E;
15739
15740 // Transform the base expression.
15741 ExprResult Base = getDerived().TransformExpr(E->getBase());
15742 if (Base.isInvalid())
15743 return ExprError();
15744
15745 // We don't need to transform the property; it will never change.
15746
15747 // If nothing changed, just retain the existing expression.
15748 if (!getDerived().AlwaysRebuild() &&
15749 Base.get() == E->getBase())
15750 return E;
15751
15752 if (E->isExplicitProperty())
15753 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15754 E->getExplicitProperty(),
15755 E->getLocation());
15756
15757 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15758 SemaRef.Context.PseudoObjectTy,
15759 E->getImplicitPropertyGetter(),
15760 E->getImplicitPropertySetter(),
15761 E->getLocation());
15762}
15763
15764template<typename Derived>
15765ExprResult
15766TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
15767 // Transform the base expression.
15768 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
15769 if (Base.isInvalid())
15770 return ExprError();
15771
15772 // Transform the key expression.
15773 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
15774 if (Key.isInvalid())
15775 return ExprError();
15776
15777 // If nothing changed, just retain the existing expression.
15778 if (!getDerived().AlwaysRebuild() &&
15779 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
15780 return E;
15781
15782 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
15783 Base.get(), Key.get(),
15784 E->getAtIndexMethodDecl(),
15785 E->setAtIndexMethodDecl());
15786}
15787
15788template<typename Derived>
15789ExprResult
15790TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
15791 // Transform the base expression.
15792 ExprResult Base = getDerived().TransformExpr(E->getBase());
15793 if (Base.isInvalid())
15794 return ExprError();
15795
15796 // If nothing changed, just retain the existing expression.
15797 if (!getDerived().AlwaysRebuild() &&
15798 Base.get() == E->getBase())
15799 return E;
15800
15801 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
15802 E->getOpLoc(),
15803 E->isArrow());
15804}
15805
15806template<typename Derived>
15807ExprResult
15808TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
15809 bool ArgumentChanged = false;
15810 SmallVector<Expr*, 8> SubExprs;
15811 SubExprs.reserve(N: E->getNumSubExprs());
15812 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15813 SubExprs, &ArgumentChanged))
15814 return ExprError();
15815
15816 if (!getDerived().AlwaysRebuild() &&
15817 !ArgumentChanged)
15818 return E;
15819
15820 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
15821 SubExprs,
15822 E->getRParenLoc());
15823}
15824
15825template<typename Derived>
15826ExprResult
15827TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
15828 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15829 if (SrcExpr.isInvalid())
15830 return ExprError();
15831
15832 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
15833 if (!Type)
15834 return ExprError();
15835
15836 if (!getDerived().AlwaysRebuild() &&
15837 Type == E->getTypeSourceInfo() &&
15838 SrcExpr.get() == E->getSrcExpr())
15839 return E;
15840
15841 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
15842 SrcExpr.get(), Type,
15843 E->getRParenLoc());
15844}
15845
15846template<typename Derived>
15847ExprResult
15848TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
15849 BlockDecl *oldBlock = E->getBlockDecl();
15850
15851 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
15852 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
15853
15854 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
15855 blockScope->TheDecl->setBlockMissingReturnType(
15856 oldBlock->blockMissingReturnType());
15857
15858 SmallVector<ParmVarDecl*, 4> params;
15859 SmallVector<QualType, 4> paramTypes;
15860
15861 const FunctionProtoType *exprFunctionType = E->getFunctionType();
15862
15863 // Parameter substitution.
15864 Sema::ExtParameterInfoBuilder extParamInfos;
15865 if (getDerived().TransformFunctionTypeParams(
15866 E->getCaretLocation(), oldBlock->parameters(), nullptr,
15867 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
15868 extParamInfos)) {
15869 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15870 return ExprError();
15871 }
15872
15873 QualType exprResultType =
15874 getDerived().TransformType(exprFunctionType->getReturnType());
15875
15876 auto epi = exprFunctionType->getExtProtoInfo();
15877 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
15878
15879 QualType functionType =
15880 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
15881 blockScope->FunctionType = functionType;
15882
15883 // Set the parameters on the block decl.
15884 if (!params.empty())
15885 blockScope->TheDecl->setParams(params);
15886
15887 if (!oldBlock->blockMissingReturnType()) {
15888 blockScope->HasImplicitReturnType = false;
15889 blockScope->ReturnType = exprResultType;
15890 }
15891
15892 // Transform the body
15893 StmtResult body = getDerived().TransformStmt(E->getBody());
15894 if (body.isInvalid()) {
15895 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15896 return ExprError();
15897 }
15898
15899#ifndef NDEBUG
15900 // In builds with assertions, make sure that we captured everything we
15901 // captured before.
15902 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
15903 for (const auto &I : oldBlock->captures()) {
15904 VarDecl *oldCapture = I.getVariable();
15905
15906 // Ignore parameter packs.
15907 if (oldCapture->isParameterPack())
15908 continue;
15909
15910 VarDecl *newCapture =
15911 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
15912 oldCapture));
15913 assert(blockScope->CaptureMap.count(newCapture));
15914 }
15915
15916 // The this pointer may not be captured by the instantiated block, even when
15917 // it's captured by the original block, if the expression causing the
15918 // capture is in the discarded branch of a constexpr if statement.
15919 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
15920 "this pointer isn't captured in the old block");
15921 }
15922#endif
15923
15924 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
15925 /*Scope=*/CurScope: nullptr);
15926}
15927
15928template<typename Derived>
15929ExprResult
15930TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
15931 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15932 if (SrcExpr.isInvalid())
15933 return ExprError();
15934
15935 QualType Type = getDerived().TransformType(E->getType());
15936
15937 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
15938 RParenLoc: E->getRParenLoc());
15939}
15940
15941template<typename Derived>
15942ExprResult
15943TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
15944 bool ArgumentChanged = false;
15945 SmallVector<Expr*, 8> SubExprs;
15946 SubExprs.reserve(N: E->getNumSubExprs());
15947 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15948 SubExprs, &ArgumentChanged))
15949 return ExprError();
15950
15951 if (!getDerived().AlwaysRebuild() &&
15952 !ArgumentChanged)
15953 return E;
15954
15955 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
15956 E->getOp(), E->getRParenLoc());
15957}
15958
15959//===----------------------------------------------------------------------===//
15960// Type reconstruction
15961//===----------------------------------------------------------------------===//
15962
15963template<typename Derived>
15964QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
15965 SourceLocation Star) {
15966 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
15967 Entity: getDerived().getBaseEntity());
15968}
15969
15970template<typename Derived>
15971QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
15972 SourceLocation Star) {
15973 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
15974 Entity: getDerived().getBaseEntity());
15975}
15976
15977template<typename Derived>
15978QualType
15979TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
15980 bool WrittenAsLValue,
15981 SourceLocation Sigil) {
15982 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
15983 Loc: Sigil, Entity: getDerived().getBaseEntity());
15984}
15985
15986template<typename Derived>
15987QualType
15988TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
15989 QualType ClassType,
15990 SourceLocation Sigil) {
15991 return SemaRef.BuildMemberPointerType(T: PointeeType, Class: ClassType, Loc: Sigil,
15992 Entity: getDerived().getBaseEntity());
15993}
15994
15995template<typename Derived>
15996QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
15997 const ObjCTypeParamDecl *Decl,
15998 SourceLocation ProtocolLAngleLoc,
15999 ArrayRef<ObjCProtocolDecl *> Protocols,
16000 ArrayRef<SourceLocation> ProtocolLocs,
16001 SourceLocation ProtocolRAngleLoc) {
16002 return SemaRef.ObjC().BuildObjCTypeParamType(
16003 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16004 /*FailOnError=*/FailOnError: true);
16005}
16006
16007template<typename Derived>
16008QualType TreeTransform<Derived>::RebuildObjCObjectType(
16009 QualType BaseType,
16010 SourceLocation Loc,
16011 SourceLocation TypeArgsLAngleLoc,
16012 ArrayRef<TypeSourceInfo *> TypeArgs,
16013 SourceLocation TypeArgsRAngleLoc,
16014 SourceLocation ProtocolLAngleLoc,
16015 ArrayRef<ObjCProtocolDecl *> Protocols,
16016 ArrayRef<SourceLocation> ProtocolLocs,
16017 SourceLocation ProtocolRAngleLoc) {
16018 return SemaRef.ObjC().BuildObjCObjectType(
16019 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
16020 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16021 /*FailOnError=*/FailOnError: true,
16022 /*Rebuilding=*/Rebuilding: true);
16023}
16024
16025template<typename Derived>
16026QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
16027 QualType PointeeType,
16028 SourceLocation Star) {
16029 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
16030}
16031
16032template <typename Derived>
16033QualType TreeTransform<Derived>::RebuildArrayType(
16034 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
16035 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16036 if (SizeExpr || !Size)
16037 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
16038 Quals: IndexTypeQuals, Brackets: BracketsRange,
16039 Entity: getDerived().getBaseEntity());
16040
16041 QualType Types[] = {
16042 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
16043 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
16044 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
16045 };
16046 QualType SizeType;
16047 for (const auto &T : Types)
16048 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
16049 SizeType = T;
16050 break;
16051 }
16052
16053 // Note that we can return a VariableArrayType here in the case where
16054 // the element type was a dependent VariableArrayType.
16055 IntegerLiteral *ArraySize
16056 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
16057 /*FIXME*/l: BracketsRange.getBegin());
16058 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
16059 Quals: IndexTypeQuals, Brackets: BracketsRange,
16060 Entity: getDerived().getBaseEntity());
16061}
16062
16063template <typename Derived>
16064QualType TreeTransform<Derived>::RebuildConstantArrayType(
16065 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
16066 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16067 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
16068 IndexTypeQuals, BracketsRange);
16069}
16070
16071template <typename Derived>
16072QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
16073 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
16074 SourceRange BracketsRange) {
16075 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
16076 IndexTypeQuals, BracketsRange);
16077}
16078
16079template <typename Derived>
16080QualType TreeTransform<Derived>::RebuildVariableArrayType(
16081 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
16082 unsigned IndexTypeQuals, SourceRange BracketsRange) {
16083 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
16084 SizeExpr,
16085 IndexTypeQuals, BracketsRange);
16086}
16087
16088template <typename Derived>
16089QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
16090 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
16091 unsigned IndexTypeQuals, SourceRange BracketsRange) {
16092 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
16093 SizeExpr,
16094 IndexTypeQuals, BracketsRange);
16095}
16096
16097template <typename Derived>
16098QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
16099 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
16100 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
16101 AttrLoc: AttributeLoc);
16102}
16103
16104template <typename Derived>
16105QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
16106 unsigned NumElements,
16107 VectorKind VecKind) {
16108 // FIXME: semantic checking!
16109 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
16110}
16111
16112template <typename Derived>
16113QualType TreeTransform<Derived>::RebuildDependentVectorType(
16114 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
16115 VectorKind VecKind) {
16116 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
16117}
16118
16119template<typename Derived>
16120QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
16121 unsigned NumElements,
16122 SourceLocation AttributeLoc) {
16123 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
16124 NumElements, true);
16125 IntegerLiteral *VectorSize
16126 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
16127 l: AttributeLoc);
16128 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
16129}
16130
16131template<typename Derived>
16132QualType
16133TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
16134 Expr *SizeExpr,
16135 SourceLocation AttributeLoc) {
16136 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
16137}
16138
16139template <typename Derived>
16140QualType TreeTransform<Derived>::RebuildConstantMatrixType(
16141 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
16142 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
16143 NumColumns);
16144}
16145
16146template <typename Derived>
16147QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
16148 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
16149 SourceLocation AttributeLoc) {
16150 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
16151 AttrLoc: AttributeLoc);
16152}
16153
16154template<typename Derived>
16155QualType TreeTransform<Derived>::RebuildFunctionProtoType(
16156 QualType T,
16157 MutableArrayRef<QualType> ParamTypes,
16158 const FunctionProtoType::ExtProtoInfo &EPI) {
16159 return SemaRef.BuildFunctionType(T, ParamTypes,
16160 Loc: getDerived().getBaseLocation(),
16161 Entity: getDerived().getBaseEntity(),
16162 EPI);
16163}
16164
16165template<typename Derived>
16166QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
16167 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
16168}
16169
16170template<typename Derived>
16171QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
16172 Decl *D) {
16173 assert(D && "no decl found");
16174 if (D->isInvalidDecl()) return QualType();
16175
16176 // FIXME: Doesn't account for ObjCInterfaceDecl!
16177 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
16178 // A valid resolved using typename pack expansion decl can have multiple
16179 // UsingDecls, but they must each have exactly one type, and it must be
16180 // the same type in every case. But we must have at least one expansion!
16181 if (UPD->expansions().empty()) {
16182 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
16183 << UPD->isCXXClassMember() << UPD;
16184 return QualType();
16185 }
16186
16187 // We might still have some unresolved types. Try to pick a resolved type
16188 // if we can. The final instantiation will check that the remaining
16189 // unresolved types instantiate to the type we pick.
16190 QualType FallbackT;
16191 QualType T;
16192 for (auto *E : UPD->expansions()) {
16193 QualType ThisT = RebuildUnresolvedUsingType(Loc, D: E);
16194 if (ThisT.isNull())
16195 continue;
16196 else if (ThisT->getAs<UnresolvedUsingType>())
16197 FallbackT = ThisT;
16198 else if (T.isNull())
16199 T = ThisT;
16200 else
16201 assert(getSema().Context.hasSameType(ThisT, T) &&
16202 "mismatched resolved types in using pack expansion");
16203 }
16204 return T.isNull() ? FallbackT : T;
16205 } else if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
16206 assert(Using->hasTypename() &&
16207 "UnresolvedUsingTypenameDecl transformed to non-typename using");
16208
16209 // A valid resolved using typename decl points to exactly one type decl.
16210 assert(++Using->shadow_begin() == Using->shadow_end());
16211
16212 UsingShadowDecl *Shadow = *Using->shadow_begin();
16213 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: Loc))
16214 return QualType();
16215 return SemaRef.Context.getUsingType(
16216 Found: Shadow, Underlying: SemaRef.Context.getTypeDeclType(
16217 Decl: cast<TypeDecl>(Val: Shadow->getTargetDecl())));
16218 } else {
16219 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
16220 "UnresolvedUsingTypenameDecl transformed to non-using decl");
16221 return SemaRef.Context.getTypeDeclType(
16222 Decl: cast<UnresolvedUsingTypenameDecl>(Val: D));
16223 }
16224}
16225
16226template <typename Derived>
16227QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
16228 TypeOfKind Kind) {
16229 return SemaRef.BuildTypeofExprType(E, Kind);
16230}
16231
16232template<typename Derived>
16233QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
16234 TypeOfKind Kind) {
16235 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
16236}
16237
16238template <typename Derived>
16239QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
16240 return SemaRef.BuildDecltypeType(E);
16241}
16242
16243template <typename Derived>
16244QualType TreeTransform<Derived>::RebuildPackIndexingType(
16245 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
16246 SourceLocation EllipsisLoc, bool FullySubstituted,
16247 ArrayRef<QualType> Expansions) {
16248 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
16249 FullySubstituted, Expansions);
16250}
16251
16252template<typename Derived>
16253QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
16254 UnaryTransformType::UTTKind UKind,
16255 SourceLocation Loc) {
16256 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
16257}
16258
16259template<typename Derived>
16260QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
16261 TemplateName Template,
16262 SourceLocation TemplateNameLoc,
16263 TemplateArgumentListInfo &TemplateArgs) {
16264 return SemaRef.CheckTemplateIdType(Template, TemplateLoc: TemplateNameLoc, TemplateArgs);
16265}
16266
16267template<typename Derived>
16268QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
16269 SourceLocation KWLoc) {
16270 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
16271}
16272
16273template<typename Derived>
16274QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
16275 SourceLocation KWLoc,
16276 bool isReadPipe) {
16277 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
16278 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
16279}
16280
16281template <typename Derived>
16282QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
16283 unsigned NumBits,
16284 SourceLocation Loc) {
16285 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
16286 NumBits, true);
16287 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
16288 type: SemaRef.Context.IntTy, l: Loc);
16289 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
16290}
16291
16292template <typename Derived>
16293QualType TreeTransform<Derived>::RebuildDependentBitIntType(
16294 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
16295 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
16296}
16297
16298template<typename Derived>
16299TemplateName
16300TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
16301 bool TemplateKW,
16302 TemplateDecl *Template) {
16303 return SemaRef.Context.getQualifiedTemplateName(NNS: SS.getScopeRep(), TemplateKeyword: TemplateKW,
16304 Template: TemplateName(Template));
16305}
16306
16307template<typename Derived>
16308TemplateName
16309TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
16310 SourceLocation TemplateKWLoc,
16311 const IdentifierInfo &Name,
16312 SourceLocation NameLoc,
16313 QualType ObjectType,
16314 NamedDecl *FirstQualifierInScope,
16315 bool AllowInjectedClassName) {
16316 UnqualifiedId TemplateName;
16317 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
16318 Sema::TemplateTy Template;
16319 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
16320 TemplateName, ParsedType::make(P: ObjectType),
16321 /*EnteringContext=*/false, Template,
16322 AllowInjectedClassName);
16323 return Template.get();
16324}
16325
16326template<typename Derived>
16327TemplateName
16328TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
16329 SourceLocation TemplateKWLoc,
16330 OverloadedOperatorKind Operator,
16331 SourceLocation NameLoc,
16332 QualType ObjectType,
16333 bool AllowInjectedClassName) {
16334 UnqualifiedId Name;
16335 // FIXME: Bogus location information.
16336 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
16337 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
16338 Sema::TemplateTy Template;
16339 getSema().ActOnTemplateName(
16340 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
16341 /*EnteringContext=*/false, Template, AllowInjectedClassName);
16342 return Template.get();
16343}
16344
16345template <typename Derived>
16346ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
16347 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
16348 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
16349 Expr *Second) {
16350 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
16351
16352 if (First->getObjectKind() == OK_ObjCProperty) {
16353 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
16354 if (BinaryOperator::isAssignmentOp(Opc))
16355 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
16356 Opcode: Opc, LHS: First, RHS: Second);
16357 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
16358 if (Result.isInvalid())
16359 return ExprError();
16360 First = Result.get();
16361 }
16362
16363 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
16364 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
16365 if (Result.isInvalid())
16366 return ExprError();
16367 Second = Result.get();
16368 }
16369
16370 // Determine whether this should be a builtin operation.
16371 if (Op == OO_Subscript) {
16372 if (!First->getType()->isOverloadableType() &&
16373 !Second->getType()->isOverloadableType())
16374 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
16375 OpLoc);
16376 } else if (Op == OO_Arrow) {
16377 // It is possible that the type refers to a RecoveryExpr created earlier
16378 // in the tree transformation.
16379 if (First->getType()->isDependentType())
16380 return ExprError();
16381 // -> is never a builtin operation.
16382 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
16383 } else if (Second == nullptr || isPostIncDec) {
16384 if (!First->getType()->isOverloadableType() ||
16385 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
16386 // The argument is not of overloadable type, or this is an expression
16387 // of the form &Class::member, so try to create a built-in unary
16388 // operation.
16389 UnaryOperatorKind Opc
16390 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
16391
16392 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
16393 }
16394 } else {
16395 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
16396 !First->getType()->isOverloadableType() &&
16397 !Second->getType()->isOverloadableType()) {
16398 // Neither of the arguments is type-dependent or has an overloadable
16399 // type, so try to create a built-in binary operation.
16400 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
16401 ExprResult Result
16402 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
16403 if (Result.isInvalid())
16404 return ExprError();
16405
16406 return Result;
16407 }
16408 }
16409
16410 // Create the overloaded operator invocation for unary operators.
16411 if (!Second || isPostIncDec) {
16412 UnaryOperatorKind Opc
16413 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
16414 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
16415 RequiresADL);
16416 }
16417
16418 // Create the overloaded operator invocation for binary operators.
16419 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
16420 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
16421 LHS: First, RHS: Second, RequiresADL);
16422 if (Result.isInvalid())
16423 return ExprError();
16424
16425 return Result;
16426}
16427
16428template<typename Derived>
16429ExprResult
16430TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
16431 SourceLocation OperatorLoc,
16432 bool isArrow,
16433 CXXScopeSpec &SS,
16434 TypeSourceInfo *ScopeType,
16435 SourceLocation CCLoc,
16436 SourceLocation TildeLoc,
16437 PseudoDestructorTypeStorage Destroyed) {
16438 QualType BaseType = Base->getType();
16439 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
16440 (!isArrow && !BaseType->getAs<RecordType>()) ||
16441 (isArrow && BaseType->getAs<PointerType>() &&
16442 !BaseType->castAs<PointerType>()->getPointeeType()
16443 ->template getAs<RecordType>())){
16444 // This pseudo-destructor expression is still a pseudo-destructor.
16445 return SemaRef.BuildPseudoDestructorExpr(
16446 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
16447 CCLoc, TildeLoc, DestroyedType: Destroyed);
16448 }
16449
16450 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
16451 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
16452 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
16453 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
16454 NameInfo.setNamedTypeInfo(DestroyedType);
16455
16456 // The scope type is now known to be a valid nested name specifier
16457 // component. Tack it on to the end of the nested name specifier.
16458 if (ScopeType) {
16459 if (!ScopeType->getType()->getAs<TagType>()) {
16460 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
16461 diag::err_expected_class_or_namespace)
16462 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
16463 return ExprError();
16464 }
16465 SS.Extend(Context&: SemaRef.Context, TemplateKWLoc: SourceLocation(), TL: ScopeType->getTypeLoc(),
16466 ColonColonLoc: CCLoc);
16467 }
16468
16469 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
16470 return getSema().BuildMemberReferenceExpr(Base, BaseType,
16471 OperatorLoc, isArrow,
16472 SS, TemplateKWLoc,
16473 /*FIXME: FirstQualifier*/ nullptr,
16474 NameInfo,
16475 /*TemplateArgs*/ nullptr,
16476 /*S*/nullptr);
16477}
16478
16479template<typename Derived>
16480StmtResult
16481TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
16482 SourceLocation Loc = S->getBeginLoc();
16483 CapturedDecl *CD = S->getCapturedDecl();
16484 unsigned NumParams = CD->getNumParams();
16485 unsigned ContextParamPos = CD->getContextParamPosition();
16486 SmallVector<Sema::CapturedParamNameType, 4> Params;
16487 for (unsigned I = 0; I < NumParams; ++I) {
16488 if (I != ContextParamPos) {
16489 Params.push_back(
16490 Elt: std::make_pair(
16491 CD->getParam(i: I)->getName(),
16492 getDerived().TransformType(CD->getParam(i: I)->getType())));
16493 } else {
16494 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
16495 }
16496 }
16497 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
16498 S->getCapturedRegionKind(), Params);
16499 StmtResult Body;
16500 {
16501 Sema::CompoundScopeRAII CompoundScope(getSema());
16502 Body = getDerived().TransformStmt(S->getCapturedStmt());
16503 }
16504
16505 if (Body.isInvalid()) {
16506 getSema().ActOnCapturedRegionError();
16507 return StmtError();
16508 }
16509
16510 return getSema().ActOnCapturedRegionEnd(Body.get());
16511}
16512
16513} // end namespace clang
16514
16515#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
16516