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/SemaOpenACC.h"
43#include "clang/Sema/SemaOpenMP.h"
44#include "clang/Sema/SemaSYCL.h"
45#include "llvm/ADT/ArrayRef.h"
46#include "llvm/Support/ErrorHandling.h"
47#include <algorithm>
48#include <optional>
49
50using namespace llvm::omp;
51
52namespace clang {
53using namespace sema;
54
55/// A semantic tree transformation that allows one to transform one
56/// abstract syntax tree into another.
57///
58/// A new tree transformation is defined by creating a new subclass \c X of
59/// \c TreeTransform<X> and then overriding certain operations to provide
60/// behavior specific to that transformation. For example, template
61/// instantiation is implemented as a tree transformation where the
62/// transformation of TemplateTypeParmType nodes involves substituting the
63/// template arguments for their corresponding template parameters; a similar
64/// transformation is performed for non-type template parameters and
65/// template template parameters.
66///
67/// This tree-transformation template uses static polymorphism to allow
68/// subclasses to customize any of its operations. Thus, a subclass can
69/// override any of the transformation or rebuild operators by providing an
70/// operation with the same signature as the default implementation. The
71/// overriding function should not be virtual.
72///
73/// Semantic tree transformations are split into two stages, either of which
74/// can be replaced by a subclass. The "transform" step transforms an AST node
75/// or the parts of an AST node using the various transformation functions,
76/// then passes the pieces on to the "rebuild" step, which constructs a new AST
77/// node of the appropriate kind from the pieces. The default transformation
78/// routines recursively transform the operands to composite AST nodes (e.g.,
79/// the pointee type of a PointerType node) and, if any of those operand nodes
80/// were changed by the transformation, invokes the rebuild operation to create
81/// a new AST node.
82///
83/// Subclasses can customize the transformation at various levels. The
84/// most coarse-grained transformations involve replacing TransformType(),
85/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
86/// TransformTemplateName(), or TransformTemplateArgument() with entirely
87/// new implementations.
88///
89/// For more fine-grained transformations, subclasses can replace any of the
90/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
91/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
92/// replacing TransformTemplateTypeParmType() allows template instantiation
93/// to substitute template arguments for their corresponding template
94/// parameters. Additionally, subclasses can override the \c RebuildXXX
95/// functions to control how AST nodes are rebuilt when their operands change.
96/// By default, \c TreeTransform will invoke semantic analysis to rebuild
97/// AST nodes. However, certain other tree transformations (e.g, cloning) may
98/// be able to use more efficient rebuild steps.
99///
100/// There are a handful of other functions that can be overridden, allowing one
101/// to avoid traversing nodes that don't need any transformation
102/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
103/// operands have not changed (\c AlwaysRebuild()), and customize the
104/// default locations and entity names used for type-checking
105/// (\c getBaseLocation(), \c getBaseEntity()).
106template<typename Derived>
107class TreeTransform {
108 /// Private RAII object that helps us forget and then re-remember
109 /// the template argument corresponding to a partially-substituted parameter
110 /// pack.
111 class ForgetPartiallySubstitutedPackRAII {
112 Derived &Self;
113 TemplateArgument Old;
114
115 public:
116 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
117 Old = Self.ForgetPartiallySubstitutedPack();
118 }
119
120 ~ForgetPartiallySubstitutedPackRAII() {
121 Self.RememberPartiallySubstitutedPack(Old);
122 }
123 };
124
125protected:
126 Sema &SemaRef;
127
128 /// The set of local declarations that have been transformed, for
129 /// cases where we are forced to build new declarations within the transformer
130 /// rather than in the subclass (e.g., lambda closure types).
131 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
132
133public:
134 /// Initializes a new tree transformer.
135 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
136
137 /// Retrieves a reference to the derived class.
138 Derived &getDerived() { return static_cast<Derived&>(*this); }
139
140 /// Retrieves a reference to the derived class.
141 const Derived &getDerived() const {
142 return static_cast<const Derived&>(*this);
143 }
144
145 static inline ExprResult Owned(Expr *E) { return E; }
146 static inline StmtResult Owned(Stmt *S) { return S; }
147
148 /// Retrieves a reference to the semantic analysis object used for
149 /// this tree transform.
150 Sema &getSema() const { return SemaRef; }
151
152 /// Whether the transformation should always rebuild AST nodes, even
153 /// if none of the children have changed.
154 ///
155 /// Subclasses may override this function to specify when the transformation
156 /// should rebuild all AST nodes.
157 ///
158 /// We must always rebuild all AST nodes when performing variadic template
159 /// pack expansion, in order to avoid violating the AST invariant that each
160 /// statement node appears at most once in its containing declaration.
161 bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
162
163 /// Whether the transformation is forming an expression or statement that
164 /// replaces the original. In this case, we'll reuse mangling numbers from
165 /// existing lambdas.
166 bool ReplacingOriginal() { return false; }
167
168 /// Wether CXXConstructExpr can be skipped when they are implicit.
169 /// They will be reconstructed when used if needed.
170 /// This is useful when the user that cause rebuilding of the
171 /// CXXConstructExpr is outside of the expression at which the TreeTransform
172 /// started.
173 bool AllowSkippingCXXConstructExpr() { return true; }
174
175 /// Returns the location of the entity being transformed, if that
176 /// information was not available elsewhere in the AST.
177 ///
178 /// By default, returns no source-location information. Subclasses can
179 /// provide an alternative implementation that provides better location
180 /// information.
181 SourceLocation getBaseLocation() { return SourceLocation(); }
182
183 /// Returns the name of the entity being transformed, if that
184 /// information was not available elsewhere in the AST.
185 ///
186 /// By default, returns an empty name. Subclasses can provide an alternative
187 /// implementation with a more precise name.
188 DeclarationName getBaseEntity() { return DeclarationName(); }
189
190 /// Sets the "base" location and entity when that
191 /// information is known based on another transformation.
192 ///
193 /// By default, the source location and entity are ignored. Subclasses can
194 /// override this function to provide a customized implementation.
195 void setBase(SourceLocation Loc, DeclarationName Entity) { }
196
197 /// RAII object that temporarily sets the base location and entity
198 /// used for reporting diagnostics in types.
199 class TemporaryBase {
200 TreeTransform &Self;
201 SourceLocation OldLocation;
202 DeclarationName OldEntity;
203
204 public:
205 TemporaryBase(TreeTransform &Self, SourceLocation Location,
206 DeclarationName Entity) : Self(Self) {
207 OldLocation = Self.getDerived().getBaseLocation();
208 OldEntity = Self.getDerived().getBaseEntity();
209
210 if (Location.isValid())
211 Self.getDerived().setBase(Location, Entity);
212 }
213
214 ~TemporaryBase() {
215 Self.getDerived().setBase(OldLocation, OldEntity);
216 }
217 };
218
219 /// Determine whether the given type \p T has already been
220 /// transformed.
221 ///
222 /// Subclasses can provide an alternative implementation of this routine
223 /// to short-circuit evaluation when it is known that a given type will
224 /// not change. For example, template instantiation need not traverse
225 /// non-dependent types.
226 bool AlreadyTransformed(QualType T) {
227 return T.isNull();
228 }
229
230 /// Transform a template parameter depth level.
231 ///
232 /// During a transformation that transforms template parameters, this maps
233 /// an old template parameter depth to a new depth.
234 unsigned TransformTemplateDepth(unsigned Depth) {
235 return Depth;
236 }
237
238 /// Determine whether the given call argument should be dropped, e.g.,
239 /// because it is a default argument.
240 ///
241 /// Subclasses can provide an alternative implementation of this routine to
242 /// determine which kinds of call arguments get dropped. By default,
243 /// CXXDefaultArgument nodes are dropped (prior to transformation).
244 bool DropCallArgument(Expr *E) {
245 return E->isDefaultArgument();
246 }
247
248 /// Determine whether we should expand a pack expansion with the
249 /// given set of parameter packs into separate arguments by repeatedly
250 /// transforming the pattern.
251 ///
252 /// By default, the transformer never tries to expand pack expansions.
253 /// Subclasses can override this routine to provide different behavior.
254 ///
255 /// \param EllipsisLoc The location of the ellipsis that identifies the
256 /// pack expansion.
257 ///
258 /// \param PatternRange The source range that covers the entire pattern of
259 /// the pack expansion.
260 ///
261 /// \param Unexpanded The set of unexpanded parameter packs within the
262 /// pattern.
263 ///
264 /// \param ShouldExpand Will be set to \c true if the transformer should
265 /// expand the corresponding pack expansions into separate arguments. When
266 /// set, \c NumExpansions must also be set.
267 ///
268 /// \param RetainExpansion Whether the caller should add an unexpanded
269 /// pack expansion after all of the expanded arguments. This is used
270 /// when extending explicitly-specified template argument packs per
271 /// C++0x [temp.arg.explicit]p9.
272 ///
273 /// \param NumExpansions The number of separate arguments that will be in
274 /// the expanded form of the corresponding pack expansion. This is both an
275 /// input and an output parameter, which can be set by the caller if the
276 /// number of expansions is known a priori (e.g., due to a prior substitution)
277 /// and will be set by the callee when the number of expansions is known.
278 /// The callee must set this value when \c ShouldExpand is \c true; it may
279 /// set this value in other cases.
280 ///
281 /// \returns true if an error occurred (e.g., because the parameter packs
282 /// are to be instantiated with arguments of different lengths), false
283 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
284 /// must be set.
285 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
286 SourceRange PatternRange,
287 ArrayRef<UnexpandedParameterPack> Unexpanded,
288 bool &ShouldExpand, bool &RetainExpansion,
289 std::optional<unsigned> &NumExpansions) {
290 ShouldExpand = false;
291 return false;
292 }
293
294 /// "Forget" about the partially-substituted pack template argument,
295 /// when performing an instantiation that must preserve the parameter pack
296 /// use.
297 ///
298 /// This routine is meant to be overridden by the template instantiator.
299 TemplateArgument ForgetPartiallySubstitutedPack() {
300 return TemplateArgument();
301 }
302
303 /// "Remember" the partially-substituted pack template argument
304 /// after performing an instantiation that must preserve the parameter pack
305 /// use.
306 ///
307 /// This routine is meant to be overridden by the template instantiator.
308 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
309
310 /// Note to the derived class when a function parameter pack is
311 /// being expanded.
312 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
313
314 /// Transforms the given type into another type.
315 ///
316 /// By default, this routine transforms a type by creating a
317 /// TypeSourceInfo for it and delegating to the appropriate
318 /// function. This is expensive, but we don't mind, because
319 /// this method is deprecated anyway; all users should be
320 /// switched to storing TypeSourceInfos.
321 ///
322 /// \returns the transformed type.
323 QualType TransformType(QualType T);
324
325 /// Transforms the given type-with-location into a new
326 /// type-with-location.
327 ///
328 /// By default, this routine transforms a type by delegating to the
329 /// appropriate TransformXXXType to build a new type. Subclasses
330 /// may override this function (to take over all type
331 /// transformations) or some set of the TransformXXXType functions
332 /// to alter the transformation.
333 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
334
335 /// Transform the given type-with-location into a new
336 /// type, collecting location information in the given builder
337 /// as necessary.
338 ///
339 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
340
341 /// Transform a type that is permitted to produce a
342 /// DeducedTemplateSpecializationType.
343 ///
344 /// This is used in the (relatively rare) contexts where it is acceptable
345 /// for transformation to produce a class template type with deduced
346 /// template arguments.
347 /// @{
348 QualType TransformTypeWithDeducedTST(QualType T);
349 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
350 /// @}
351
352 /// The reason why the value of a statement is not discarded, if any.
353 enum StmtDiscardKind {
354 SDK_Discarded,
355 SDK_NotDiscarded,
356 SDK_StmtExprResult,
357 };
358
359 /// Transform the given statement.
360 ///
361 /// By default, this routine transforms a statement by delegating to the
362 /// appropriate TransformXXXStmt function to transform a specific kind of
363 /// statement or the TransformExpr() function to transform an expression.
364 /// Subclasses may override this function to transform statements using some
365 /// other mechanism.
366 ///
367 /// \returns the transformed statement.
368 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
369
370 /// Transform the given statement.
371 ///
372 /// By default, this routine transforms a statement by delegating to the
373 /// appropriate TransformOMPXXXClause function to transform a specific kind
374 /// of clause. Subclasses may override this function to transform statements
375 /// using some other mechanism.
376 ///
377 /// \returns the transformed OpenMP clause.
378 OMPClause *TransformOMPClause(OMPClause *S);
379
380 /// Transform the given attribute.
381 ///
382 /// By default, this routine transforms a statement by delegating to the
383 /// appropriate TransformXXXAttr function to transform a specific kind
384 /// of attribute. Subclasses may override this function to transform
385 /// attributed statements/types using some other mechanism.
386 ///
387 /// \returns the transformed attribute
388 const Attr *TransformAttr(const Attr *S);
389
390 // Transform the given statement attribute.
391 //
392 // Delegates to the appropriate TransformXXXAttr function to transform a
393 // specific kind of statement attribute. Unlike the non-statement taking
394 // version of this, this implements all attributes, not just pragmas.
395 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
396 const Attr *A);
397
398 // Transform the specified attribute.
399 //
400 // Subclasses should override the transformation of attributes with a pragma
401 // spelling to transform expressions stored within the attribute.
402 //
403 // \returns the transformed attribute.
404#define ATTR(X) \
405 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
406#include "clang/Basic/AttrList.inc"
407
408 // Transform the specified attribute.
409 //
410 // Subclasses should override the transformation of attributes to do
411 // transformation and checking of statement attributes. By default, this
412 // delegates to the non-statement taking version.
413 //
414 // \returns the transformed attribute.
415#define ATTR(X) \
416 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
417 const X##Attr *A) { \
418 return getDerived().Transform##X##Attr(A); \
419 }
420#include "clang/Basic/AttrList.inc"
421
422 /// Transform the given expression.
423 ///
424 /// By default, this routine transforms an expression by delegating to the
425 /// appropriate TransformXXXExpr function to build a new expression.
426 /// Subclasses may override this function to transform expressions using some
427 /// other mechanism.
428 ///
429 /// \returns the transformed expression.
430 ExprResult TransformExpr(Expr *E);
431
432 /// Transform the given initializer.
433 ///
434 /// By default, this routine transforms an initializer by stripping off the
435 /// semantic nodes added by initialization, then passing the result to
436 /// TransformExpr or TransformExprs.
437 ///
438 /// \returns the transformed initializer.
439 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
440
441 /// Transform the given list of expressions.
442 ///
443 /// This routine transforms a list of expressions by invoking
444 /// \c TransformExpr() for each subexpression. However, it also provides
445 /// support for variadic templates by expanding any pack expansions (if the
446 /// derived class permits such expansion) along the way. When pack expansions
447 /// are present, the number of outputs may not equal the number of inputs.
448 ///
449 /// \param Inputs The set of expressions to be transformed.
450 ///
451 /// \param NumInputs The number of expressions in \c Inputs.
452 ///
453 /// \param IsCall If \c true, then this transform is being performed on
454 /// function-call arguments, and any arguments that should be dropped, will
455 /// be.
456 ///
457 /// \param Outputs The transformed input expressions will be added to this
458 /// vector.
459 ///
460 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
461 /// due to transformation.
462 ///
463 /// \returns true if an error occurred, false otherwise.
464 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
465 SmallVectorImpl<Expr *> &Outputs,
466 bool *ArgChanged = nullptr);
467
468 /// Transform the given declaration, which is referenced from a type
469 /// or expression.
470 ///
471 /// By default, acts as the identity function on declarations, unless the
472 /// transformer has had to transform the declaration itself. Subclasses
473 /// may override this function to provide alternate behavior.
474 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
475 llvm::DenseMap<Decl *, Decl *>::iterator Known
476 = TransformedLocalDecls.find(D);
477 if (Known != TransformedLocalDecls.end())
478 return Known->second;
479
480 return D;
481 }
482
483 /// Transform the specified condition.
484 ///
485 /// By default, this transforms the variable and expression and rebuilds
486 /// the condition.
487 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
488 Expr *Expr,
489 Sema::ConditionKind Kind);
490
491 /// Transform the attributes associated with the given declaration and
492 /// place them on the new declaration.
493 ///
494 /// By default, this operation does nothing. Subclasses may override this
495 /// behavior to transform attributes.
496 void transformAttrs(Decl *Old, Decl *New) { }
497
498 /// Note that a local declaration has been transformed by this
499 /// transformer.
500 ///
501 /// Local declarations are typically transformed via a call to
502 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
503 /// the transformer itself has to transform the declarations. This routine
504 /// can be overridden by a subclass that keeps track of such mappings.
505 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
506 assert(New.size() == 1 &&
507 "must override transformedLocalDecl if performing pack expansion");
508 TransformedLocalDecls[Old] = New.front();
509 }
510
511 /// Transform the definition of the given declaration.
512 ///
513 /// By default, invokes TransformDecl() to transform the declaration.
514 /// Subclasses may override this function to provide alternate behavior.
515 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
516 return getDerived().TransformDecl(Loc, D);
517 }
518
519 /// Transform the given declaration, which was the first part of a
520 /// nested-name-specifier in a member access expression.
521 ///
522 /// This specific declaration transformation only applies to the first
523 /// identifier in a nested-name-specifier of a member access expression, e.g.,
524 /// the \c T in \c x->T::member
525 ///
526 /// By default, invokes TransformDecl() to transform the declaration.
527 /// Subclasses may override this function to provide alternate behavior.
528 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
529 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
530 }
531
532 /// Transform the set of declarations in an OverloadExpr.
533 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
534 LookupResult &R);
535
536 /// Transform the given nested-name-specifier with source-location
537 /// information.
538 ///
539 /// By default, transforms all of the types and declarations within the
540 /// nested-name-specifier. Subclasses may override this function to provide
541 /// alternate behavior.
542 NestedNameSpecifierLoc
543 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
544 QualType ObjectType = QualType(),
545 NamedDecl *FirstQualifierInScope = nullptr);
546
547 /// Transform the given declaration name.
548 ///
549 /// By default, transforms the types of conversion function, constructor,
550 /// and destructor names and then (if needed) rebuilds the declaration name.
551 /// Identifiers and selectors are returned unmodified. Subclasses may
552 /// override this function to provide alternate behavior.
553 DeclarationNameInfo
554 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
555
556 bool TransformRequiresExprRequirements(
557 ArrayRef<concepts::Requirement *> Reqs,
558 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
559 concepts::TypeRequirement *
560 TransformTypeRequirement(concepts::TypeRequirement *Req);
561 concepts::ExprRequirement *
562 TransformExprRequirement(concepts::ExprRequirement *Req);
563 concepts::NestedRequirement *
564 TransformNestedRequirement(concepts::NestedRequirement *Req);
565
566 /// Transform the given template name.
567 ///
568 /// \param SS The nested-name-specifier that qualifies the template
569 /// name. This nested-name-specifier must already have been transformed.
570 ///
571 /// \param Name The template name to transform.
572 ///
573 /// \param NameLoc The source location of the template name.
574 ///
575 /// \param ObjectType If we're translating a template name within a member
576 /// access expression, this is the type of the object whose member template
577 /// is being referenced.
578 ///
579 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
580 /// also refers to a name within the current (lexical) scope, this is the
581 /// declaration it refers to.
582 ///
583 /// By default, transforms the template name by transforming the declarations
584 /// and nested-name-specifiers that occur within the template name.
585 /// Subclasses may override this function to provide alternate behavior.
586 TemplateName
587 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
588 SourceLocation NameLoc,
589 QualType ObjectType = QualType(),
590 NamedDecl *FirstQualifierInScope = nullptr,
591 bool AllowInjectedClassName = false);
592
593 /// Transform the given template argument.
594 ///
595 /// By default, this operation transforms the type, expression, or
596 /// declaration stored within the template argument and constructs a
597 /// new template argument from the transformed result. Subclasses may
598 /// override this function to provide alternate behavior.
599 ///
600 /// Returns true if there was an error.
601 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
602 TemplateArgumentLoc &Output,
603 bool Uneval = false);
604
605 /// Transform the given set of template arguments.
606 ///
607 /// By default, this operation transforms all of the template arguments
608 /// in the input set using \c TransformTemplateArgument(), and appends
609 /// the transformed arguments to the output list.
610 ///
611 /// Note that this overload of \c TransformTemplateArguments() is merely
612 /// a convenience function. Subclasses that wish to override this behavior
613 /// should override the iterator-based member template version.
614 ///
615 /// \param Inputs The set of template arguments to be transformed.
616 ///
617 /// \param NumInputs The number of template arguments in \p Inputs.
618 ///
619 /// \param Outputs The set of transformed template arguments output by this
620 /// routine.
621 ///
622 /// Returns true if an error occurred.
623 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
624 unsigned NumInputs,
625 TemplateArgumentListInfo &Outputs,
626 bool Uneval = false) {
627 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
628 Uneval);
629 }
630
631 /// Transform the given set of template arguments.
632 ///
633 /// By default, this operation transforms all of the template arguments
634 /// in the input set using \c TransformTemplateArgument(), and appends
635 /// the transformed arguments to the output list.
636 ///
637 /// \param First An iterator to the first template argument.
638 ///
639 /// \param Last An iterator one step past the last template argument.
640 ///
641 /// \param Outputs The set of transformed template arguments output by this
642 /// routine.
643 ///
644 /// Returns true if an error occurred.
645 template<typename InputIterator>
646 bool TransformTemplateArguments(InputIterator First,
647 InputIterator Last,
648 TemplateArgumentListInfo &Outputs,
649 bool Uneval = false);
650
651 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
652 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
653 TemplateArgumentLoc &ArgLoc);
654
655 /// Fakes up a TypeSourceInfo for a type.
656 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
657 return SemaRef.Context.getTrivialTypeSourceInfo(T,
658 Loc: getDerived().getBaseLocation());
659 }
660
661#define ABSTRACT_TYPELOC(CLASS, PARENT)
662#define TYPELOC(CLASS, PARENT) \
663 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
664#include "clang/AST/TypeLocNodes.def"
665
666 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
667 TemplateTypeParmTypeLoc TL,
668 bool SuppressObjCLifetime);
669 QualType
670 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
671 SubstTemplateTypeParmPackTypeLoc TL,
672 bool SuppressObjCLifetime);
673
674 template<typename Fn>
675 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
676 FunctionProtoTypeLoc TL,
677 CXXRecordDecl *ThisContext,
678 Qualifiers ThisTypeQuals,
679 Fn TransformExceptionSpec);
680
681 template <typename Fn>
682 QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL,
683 Fn TransformModifiedType);
684
685 bool TransformExceptionSpec(SourceLocation Loc,
686 FunctionProtoType::ExceptionSpecInfo &ESI,
687 SmallVectorImpl<QualType> &Exceptions,
688 bool &Changed);
689
690 StmtResult TransformSEHHandler(Stmt *Handler);
691
692 QualType
693 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
694 TemplateSpecializationTypeLoc TL,
695 TemplateName Template);
696
697 QualType
698 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
699 DependentTemplateSpecializationTypeLoc TL,
700 TemplateName Template,
701 CXXScopeSpec &SS);
702
703 QualType TransformDependentTemplateSpecializationType(
704 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
705 NestedNameSpecifierLoc QualifierLoc);
706
707 /// Transforms the parameters of a function type into the
708 /// given vectors.
709 ///
710 /// The result vectors should be kept in sync; null entries in the
711 /// variables vector are acceptable.
712 ///
713 /// LastParamTransformed, if non-null, will be set to the index of the last
714 /// parameter on which transfromation was started. In the event of an error,
715 /// this will contain the parameter which failed to instantiate.
716 ///
717 /// Return true on error.
718 bool TransformFunctionTypeParams(
719 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
720 const QualType *ParamTypes,
721 const FunctionProtoType::ExtParameterInfo *ParamInfos,
722 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
723 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
724
725 bool TransformFunctionTypeParams(
726 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
727 const QualType *ParamTypes,
728 const FunctionProtoType::ExtParameterInfo *ParamInfos,
729 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
730 Sema::ExtParameterInfoBuilder &PInfos) {
731 return getDerived().TransformFunctionTypeParams(
732 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
733 }
734
735 /// Transforms the parameters of a requires expresison into the given vectors.
736 ///
737 /// The result vectors should be kept in sync; null entries in the
738 /// variables vector are acceptable.
739 ///
740 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
741 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
742 /// which are cases where transformation shouldn't continue.
743 ExprResult TransformRequiresTypeParams(
744 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
745 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
746 SmallVectorImpl<QualType> &PTypes,
747 SmallVectorImpl<ParmVarDecl *> &TransParams,
748 Sema::ExtParameterInfoBuilder &PInfos) {
749 if (getDerived().TransformFunctionTypeParams(
750 KWLoc, Params, /*ParamTypes=*/nullptr,
751 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
752 return ExprError();
753
754 return ExprResult{};
755 }
756
757 /// Transforms a single function-type parameter. Return null
758 /// on error.
759 ///
760 /// \param indexAdjustment - A number to add to the parameter's
761 /// scope index; can be negative
762 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
763 int indexAdjustment,
764 std::optional<unsigned> NumExpansions,
765 bool ExpectParameterPack);
766
767 /// Transform the body of a lambda-expression.
768 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
769 /// Alternative implementation of TransformLambdaBody that skips transforming
770 /// the body.
771 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
772
773 CXXRecordDecl::LambdaDependencyKind
774 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
775 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
776 LSI->Lambda->getLambdaDependencyKind());
777 }
778
779 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
780
781 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
782 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
783
784 TemplateParameterList *TransformTemplateParameterList(
785 TemplateParameterList *TPL) {
786 return TPL;
787 }
788
789 ExprResult TransformAddressOfOperand(Expr *E);
790
791 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
792 bool IsAddressOfOperand,
793 TypeSourceInfo **RecoveryTSI);
794
795 ExprResult TransformParenDependentScopeDeclRefExpr(
796 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
797 TypeSourceInfo **RecoveryTSI);
798
799 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
800 bool IsAddressOfOperand);
801
802 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
803
804// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
805// amount of stack usage with clang.
806#define STMT(Node, Parent) \
807 LLVM_ATTRIBUTE_NOINLINE \
808 StmtResult Transform##Node(Node *S);
809#define VALUESTMT(Node, Parent) \
810 LLVM_ATTRIBUTE_NOINLINE \
811 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
812#define EXPR(Node, Parent) \
813 LLVM_ATTRIBUTE_NOINLINE \
814 ExprResult Transform##Node(Node *E);
815#define ABSTRACT_STMT(Stmt)
816#include "clang/AST/StmtNodes.inc"
817
818#define GEN_CLANG_CLAUSE_CLASS
819#define CLAUSE_CLASS(Enum, Str, Class) \
820 LLVM_ATTRIBUTE_NOINLINE \
821 OMPClause *Transform##Class(Class *S);
822#include "llvm/Frontend/OpenMP/OMP.inc"
823
824 /// Build a new qualified type given its unqualified type and type location.
825 ///
826 /// By default, this routine adds type qualifiers only to types that can
827 /// have qualifiers, and silently suppresses those qualifiers that are not
828 /// permitted. Subclasses may override this routine to provide different
829 /// behavior.
830 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
831
832 /// Build a new pointer type given its pointee type.
833 ///
834 /// By default, performs semantic analysis when building the pointer type.
835 /// Subclasses may override this routine to provide different behavior.
836 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
837
838 /// Build a new block pointer type given its pointee type.
839 ///
840 /// By default, performs semantic analysis when building the block pointer
841 /// type. Subclasses may override this routine to provide different behavior.
842 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
843
844 /// Build a new reference type given the type it references.
845 ///
846 /// By default, performs semantic analysis when building the
847 /// reference type. Subclasses may override this routine to provide
848 /// different behavior.
849 ///
850 /// \param LValue whether the type was written with an lvalue sigil
851 /// or an rvalue sigil.
852 QualType RebuildReferenceType(QualType ReferentType,
853 bool LValue,
854 SourceLocation Sigil);
855
856 /// Build a new member pointer type given the pointee type and the
857 /// class type it refers into.
858 ///
859 /// By default, performs semantic analysis when building the member pointer
860 /// type. Subclasses may override this routine to provide different behavior.
861 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
862 SourceLocation Sigil);
863
864 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
865 SourceLocation ProtocolLAngleLoc,
866 ArrayRef<ObjCProtocolDecl *> Protocols,
867 ArrayRef<SourceLocation> ProtocolLocs,
868 SourceLocation ProtocolRAngleLoc);
869
870 /// Build an Objective-C object type.
871 ///
872 /// By default, performs semantic analysis when building the object type.
873 /// Subclasses may override this routine to provide different behavior.
874 QualType RebuildObjCObjectType(QualType BaseType,
875 SourceLocation Loc,
876 SourceLocation TypeArgsLAngleLoc,
877 ArrayRef<TypeSourceInfo *> TypeArgs,
878 SourceLocation TypeArgsRAngleLoc,
879 SourceLocation ProtocolLAngleLoc,
880 ArrayRef<ObjCProtocolDecl *> Protocols,
881 ArrayRef<SourceLocation> ProtocolLocs,
882 SourceLocation ProtocolRAngleLoc);
883
884 /// Build a new Objective-C object pointer type given the pointee type.
885 ///
886 /// By default, directly builds the pointer type, with no additional semantic
887 /// analysis.
888 QualType RebuildObjCObjectPointerType(QualType PointeeType,
889 SourceLocation Star);
890
891 /// Build a new array type given the element type, size
892 /// modifier, size of the array (if known), size expression, and index type
893 /// qualifiers.
894 ///
895 /// By default, performs semantic analysis when building the array type.
896 /// Subclasses may override this routine to provide different behavior.
897 /// Also by default, all of the other Rebuild*Array
898 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
899 const llvm::APInt *Size, Expr *SizeExpr,
900 unsigned IndexTypeQuals, SourceRange BracketsRange);
901
902 /// Build a new constant array type given the element type, size
903 /// modifier, (known) size of the array, and index type qualifiers.
904 ///
905 /// By default, performs semantic analysis when building the array type.
906 /// Subclasses may override this routine to provide different behavior.
907 QualType RebuildConstantArrayType(QualType ElementType,
908 ArraySizeModifier SizeMod,
909 const llvm::APInt &Size, Expr *SizeExpr,
910 unsigned IndexTypeQuals,
911 SourceRange BracketsRange);
912
913 /// Build a new incomplete array type given the element type, size
914 /// modifier, and index type qualifiers.
915 ///
916 /// By default, performs semantic analysis when building the array type.
917 /// Subclasses may override this routine to provide different behavior.
918 QualType RebuildIncompleteArrayType(QualType ElementType,
919 ArraySizeModifier SizeMod,
920 unsigned IndexTypeQuals,
921 SourceRange BracketsRange);
922
923 /// Build a new variable-length array type given the element type,
924 /// size modifier, size expression, and index type qualifiers.
925 ///
926 /// By default, performs semantic analysis when building the array type.
927 /// Subclasses may override this routine to provide different behavior.
928 QualType RebuildVariableArrayType(QualType ElementType,
929 ArraySizeModifier SizeMod, Expr *SizeExpr,
930 unsigned IndexTypeQuals,
931 SourceRange BracketsRange);
932
933 /// Build a new dependent-sized array type given the element type,
934 /// size modifier, size expression, and index type qualifiers.
935 ///
936 /// By default, performs semantic analysis when building the array type.
937 /// Subclasses may override this routine to provide different behavior.
938 QualType RebuildDependentSizedArrayType(QualType ElementType,
939 ArraySizeModifier SizeMod,
940 Expr *SizeExpr,
941 unsigned IndexTypeQuals,
942 SourceRange BracketsRange);
943
944 /// Build a new vector type given the element type and
945 /// number of elements.
946 ///
947 /// By default, performs semantic analysis when building the vector type.
948 /// Subclasses may override this routine to provide different behavior.
949 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
950 VectorKind VecKind);
951
952 /// Build a new potentially dependently-sized extended vector type
953 /// given the element type and number of elements.
954 ///
955 /// By default, performs semantic analysis when building the vector type.
956 /// Subclasses may override this routine to provide different behavior.
957 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
958 SourceLocation AttributeLoc, VectorKind);
959
960 /// Build a new extended vector type given the element type and
961 /// number of elements.
962 ///
963 /// By default, performs semantic analysis when building the vector type.
964 /// Subclasses may override this routine to provide different behavior.
965 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
966 SourceLocation AttributeLoc);
967
968 /// Build a new potentially dependently-sized extended vector type
969 /// given the element type and number of elements.
970 ///
971 /// By default, performs semantic analysis when building the vector type.
972 /// Subclasses may override this routine to provide different behavior.
973 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
974 Expr *SizeExpr,
975 SourceLocation AttributeLoc);
976
977 /// Build a new matrix type given the element type and dimensions.
978 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
979 unsigned NumColumns);
980
981 /// Build a new matrix type given the type and dependently-defined
982 /// dimensions.
983 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
984 Expr *ColumnExpr,
985 SourceLocation AttributeLoc);
986
987 /// Build a new DependentAddressSpaceType or return the pointee
988 /// type variable with the correct address space (retrieved from
989 /// AddrSpaceExpr) applied to it. The former will be returned in cases
990 /// where the address space remains dependent.
991 ///
992 /// By default, performs semantic analysis when building the type with address
993 /// space applied. Subclasses may override this routine to provide different
994 /// behavior.
995 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
996 Expr *AddrSpaceExpr,
997 SourceLocation AttributeLoc);
998
999 /// Build a new function type.
1000 ///
1001 /// By default, performs semantic analysis when building the function type.
1002 /// Subclasses may override this routine to provide different behavior.
1003 QualType RebuildFunctionProtoType(QualType T,
1004 MutableArrayRef<QualType> ParamTypes,
1005 const FunctionProtoType::ExtProtoInfo &EPI);
1006
1007 /// Build a new unprototyped function type.
1008 QualType RebuildFunctionNoProtoType(QualType ResultType);
1009
1010 /// Rebuild an unresolved typename type, given the decl that
1011 /// the UnresolvedUsingTypenameDecl was transformed to.
1012 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1013
1014 /// Build a new type found via an alias.
1015 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1016 return SemaRef.Context.getUsingType(Found, Underlying);
1017 }
1018
1019 /// Build a new typedef type.
1020 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1021 return SemaRef.Context.getTypeDeclType(Typedef);
1022 }
1023
1024 /// Build a new MacroDefined type.
1025 QualType RebuildMacroQualifiedType(QualType T,
1026 const IdentifierInfo *MacroII) {
1027 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1028 }
1029
1030 /// Build a new class/struct/union type.
1031 QualType RebuildRecordType(RecordDecl *Record) {
1032 return SemaRef.Context.getTypeDeclType(Record);
1033 }
1034
1035 /// Build a new Enum type.
1036 QualType RebuildEnumType(EnumDecl *Enum) {
1037 return SemaRef.Context.getTypeDeclType(Enum);
1038 }
1039
1040 /// Build a new typeof(expr) type.
1041 ///
1042 /// By default, performs semantic analysis when building the typeof type.
1043 /// Subclasses may override this routine to provide different behavior.
1044 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1045 TypeOfKind Kind);
1046
1047 /// Build a new typeof(type) type.
1048 ///
1049 /// By default, builds a new TypeOfType with the given underlying type.
1050 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1051
1052 /// Build a new unary transform type.
1053 QualType RebuildUnaryTransformType(QualType BaseType,
1054 UnaryTransformType::UTTKind UKind,
1055 SourceLocation Loc);
1056
1057 /// Build a new C++11 decltype type.
1058 ///
1059 /// By default, performs semantic analysis when building the decltype type.
1060 /// Subclasses may override this routine to provide different behavior.
1061 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1062
1063 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1064 SourceLocation Loc,
1065 SourceLocation EllipsisLoc,
1066 bool FullySubstituted,
1067 ArrayRef<QualType> Expansions = {});
1068
1069 /// Build a new C++11 auto type.
1070 ///
1071 /// By default, builds a new AutoType with the given deduced type.
1072 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1073 ConceptDecl *TypeConstraintConcept,
1074 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1075 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1076 // which has been deduced to a dependent type into an undeduced 'auto', so
1077 // that we'll retry deduction after the transformation.
1078 return SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword,
1079 /*IsDependent*/ IsDependent: false, /*IsPack=*/IsPack: false,
1080 TypeConstraintConcept,
1081 TypeConstraintArgs);
1082 }
1083
1084 /// By default, builds a new DeducedTemplateSpecializationType with the given
1085 /// deduced type.
1086 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1087 QualType Deduced) {
1088 return SemaRef.Context.getDeducedTemplateSpecializationType(
1089 Template, DeducedType: Deduced, /*IsDependent*/ IsDependent: false);
1090 }
1091
1092 /// Build a new template specialization type.
1093 ///
1094 /// By default, performs semantic analysis when building the template
1095 /// specialization type. Subclasses may override this routine to provide
1096 /// different behavior.
1097 QualType RebuildTemplateSpecializationType(TemplateName Template,
1098 SourceLocation TemplateLoc,
1099 TemplateArgumentListInfo &Args);
1100
1101 /// Build a new parenthesized type.
1102 ///
1103 /// By default, builds a new ParenType type from the inner type.
1104 /// Subclasses may override this routine to provide different behavior.
1105 QualType RebuildParenType(QualType InnerType) {
1106 return SemaRef.BuildParenType(T: InnerType);
1107 }
1108
1109 /// Build a new qualified name type.
1110 ///
1111 /// By default, builds a new ElaboratedType type from the keyword,
1112 /// the nested-name-specifier and the named type.
1113 /// Subclasses may override this routine to provide different behavior.
1114 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1115 ElaboratedTypeKeyword Keyword,
1116 NestedNameSpecifierLoc QualifierLoc,
1117 QualType Named) {
1118 return SemaRef.Context.getElaboratedType(Keyword,
1119 NNS: QualifierLoc.getNestedNameSpecifier(),
1120 NamedType: Named);
1121 }
1122
1123 /// Build a new typename type that refers to a template-id.
1124 ///
1125 /// By default, builds a new DependentNameType type from the
1126 /// nested-name-specifier and the given type. Subclasses may override
1127 /// this routine to provide different behavior.
1128 QualType RebuildDependentTemplateSpecializationType(
1129 ElaboratedTypeKeyword Keyword,
1130 NestedNameSpecifierLoc QualifierLoc,
1131 SourceLocation TemplateKWLoc,
1132 const IdentifierInfo *Name,
1133 SourceLocation NameLoc,
1134 TemplateArgumentListInfo &Args,
1135 bool AllowInjectedClassName) {
1136 // Rebuild the template name.
1137 // TODO: avoid TemplateName abstraction
1138 CXXScopeSpec SS;
1139 SS.Adopt(Other: QualifierLoc);
1140 TemplateName InstName = getDerived().RebuildTemplateName(
1141 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1142 AllowInjectedClassName);
1143
1144 if (InstName.isNull())
1145 return QualType();
1146
1147 // If it's still dependent, make a dependent specialization.
1148 if (InstName.getAsDependentTemplateName())
1149 return SemaRef.Context.getDependentTemplateSpecializationType(
1150 Keyword, NNS: QualifierLoc.getNestedNameSpecifier(), Name,
1151 Args: Args.arguments());
1152
1153 // Otherwise, make an elaborated type wrapping a non-dependent
1154 // specialization.
1155 QualType T =
1156 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1157 if (T.isNull())
1158 return QualType();
1159 return SemaRef.Context.getElaboratedType(
1160 Keyword, NNS: QualifierLoc.getNestedNameSpecifier(), NamedType: T);
1161 }
1162
1163 /// Build a new typename type that refers to an identifier.
1164 ///
1165 /// By default, performs semantic analysis when building the typename type
1166 /// (or elaborated type). Subclasses may override this routine to provide
1167 /// different behavior.
1168 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1169 SourceLocation KeywordLoc,
1170 NestedNameSpecifierLoc QualifierLoc,
1171 const IdentifierInfo *Id,
1172 SourceLocation IdLoc,
1173 bool DeducedTSTContext) {
1174 CXXScopeSpec SS;
1175 SS.Adopt(Other: QualifierLoc);
1176
1177 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1178 // If the name is still dependent, just build a new dependent name type.
1179 if (!SemaRef.computeDeclContext(SS))
1180 return SemaRef.Context.getDependentNameType(Keyword,
1181 NNS: QualifierLoc.getNestedNameSpecifier(),
1182 Name: Id);
1183 }
1184
1185 if (Keyword == ElaboratedTypeKeyword::None ||
1186 Keyword == ElaboratedTypeKeyword::Typename) {
1187 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1188 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1189 }
1190
1191 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1192
1193 // We had a dependent elaborated-type-specifier that has been transformed
1194 // into a non-dependent elaborated-type-specifier. Find the tag we're
1195 // referring to.
1196 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1197 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1198 if (!DC)
1199 return QualType();
1200
1201 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1202 return QualType();
1203
1204 TagDecl *Tag = nullptr;
1205 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1206 switch (Result.getResultKind()) {
1207 case LookupResult::NotFound:
1208 case LookupResult::NotFoundInCurrentInstantiation:
1209 break;
1210
1211 case LookupResult::Found:
1212 Tag = Result.getAsSingle<TagDecl>();
1213 break;
1214
1215 case LookupResult::FoundOverloaded:
1216 case LookupResult::FoundUnresolvedValue:
1217 llvm_unreachable("Tag lookup cannot find non-tags");
1218
1219 case LookupResult::Ambiguous:
1220 // Let the LookupResult structure handle ambiguities.
1221 return QualType();
1222 }
1223
1224 if (!Tag) {
1225 // Check where the name exists but isn't a tag type and use that to emit
1226 // better diagnostics.
1227 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1228 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1229 switch (Result.getResultKind()) {
1230 case LookupResult::Found:
1231 case LookupResult::FoundOverloaded:
1232 case LookupResult::FoundUnresolvedValue: {
1233 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1234 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1235 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1236 << SomeDecl << NTK << llvm::to_underlying(Kind);
1237 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1238 break;
1239 }
1240 default:
1241 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1242 << llvm::to_underlying(Kind) << Id << DC
1243 << QualifierLoc.getSourceRange();
1244 break;
1245 }
1246 return QualType();
1247 }
1248
1249 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1250 NewTagLoc: IdLoc, Name: Id)) {
1251 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1252 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1253 return QualType();
1254 }
1255
1256 // Build the elaborated-type-specifier type.
1257 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1258 return SemaRef.Context.getElaboratedType(Keyword,
1259 NNS: QualifierLoc.getNestedNameSpecifier(),
1260 NamedType: T);
1261 }
1262
1263 /// Build a new pack expansion type.
1264 ///
1265 /// By default, builds a new PackExpansionType type from the given pattern.
1266 /// Subclasses may override this routine to provide different behavior.
1267 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1268 SourceLocation EllipsisLoc,
1269 std::optional<unsigned> NumExpansions) {
1270 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1271 NumExpansions);
1272 }
1273
1274 /// Build a new atomic type given its value type.
1275 ///
1276 /// By default, performs semantic analysis when building the atomic type.
1277 /// Subclasses may override this routine to provide different behavior.
1278 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1279
1280 /// Build a new pipe type given its value type.
1281 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1282 bool isReadPipe);
1283
1284 /// Build a bit-precise int given its value type.
1285 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1286 SourceLocation Loc);
1287
1288 /// Build a dependent bit-precise int given its value type.
1289 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1290 SourceLocation Loc);
1291
1292 /// Build a new template name given a nested name specifier, a flag
1293 /// indicating whether the "template" keyword was provided, and the template
1294 /// that the template name refers to.
1295 ///
1296 /// By default, builds the new template name directly. Subclasses may override
1297 /// this routine to provide different behavior.
1298 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1299 bool TemplateKW,
1300 TemplateDecl *Template);
1301
1302 /// Build a new template name given a nested name specifier and the
1303 /// name that is referred to as a template.
1304 ///
1305 /// By default, performs semantic analysis to determine whether the name can
1306 /// be resolved to a specific template, then builds the appropriate kind of
1307 /// template name. Subclasses may override this routine to provide different
1308 /// behavior.
1309 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1310 SourceLocation TemplateKWLoc,
1311 const IdentifierInfo &Name,
1312 SourceLocation NameLoc, QualType ObjectType,
1313 NamedDecl *FirstQualifierInScope,
1314 bool AllowInjectedClassName);
1315
1316 /// Build a new template name given a nested name specifier and the
1317 /// overloaded operator name that is referred to as a template.
1318 ///
1319 /// By default, performs semantic analysis to determine whether the name can
1320 /// be resolved to a specific template, then builds the appropriate kind of
1321 /// template name. Subclasses may override this routine to provide different
1322 /// behavior.
1323 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1324 SourceLocation TemplateKWLoc,
1325 OverloadedOperatorKind Operator,
1326 SourceLocation NameLoc, QualType ObjectType,
1327 bool AllowInjectedClassName);
1328
1329 /// Build a new template name given a template template parameter pack
1330 /// and the
1331 ///
1332 /// By default, performs semantic analysis to determine whether the name can
1333 /// be resolved to a specific template, then builds the appropriate kind of
1334 /// template name. Subclasses may override this routine to provide different
1335 /// behavior.
1336 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1337 Decl *AssociatedDecl, unsigned Index,
1338 bool Final) {
1339 return getSema().Context.getSubstTemplateTemplateParmPack(
1340 ArgPack, AssociatedDecl, Index, Final);
1341 }
1342
1343 /// Build a new compound statement.
1344 ///
1345 /// By default, performs semantic analysis to build the new statement.
1346 /// Subclasses may override this routine to provide different behavior.
1347 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1348 MultiStmtArg Statements,
1349 SourceLocation RBraceLoc,
1350 bool IsStmtExpr) {
1351 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1352 IsStmtExpr);
1353 }
1354
1355 /// Build a new case statement.
1356 ///
1357 /// By default, performs semantic analysis to build the new statement.
1358 /// Subclasses may override this routine to provide different behavior.
1359 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1360 Expr *LHS,
1361 SourceLocation EllipsisLoc,
1362 Expr *RHS,
1363 SourceLocation ColonLoc) {
1364 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1365 ColonLoc);
1366 }
1367
1368 /// Attach the body to a new case statement.
1369 ///
1370 /// By default, performs semantic analysis to build the new statement.
1371 /// Subclasses may override this routine to provide different behavior.
1372 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1373 getSema().ActOnCaseStmtBody(S, Body);
1374 return S;
1375 }
1376
1377 /// Build a new default statement.
1378 ///
1379 /// By default, performs semantic analysis to build the new statement.
1380 /// Subclasses may override this routine to provide different behavior.
1381 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1382 SourceLocation ColonLoc,
1383 Stmt *SubStmt) {
1384 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1385 /*CurScope=*/nullptr);
1386 }
1387
1388 /// Build a new label statement.
1389 ///
1390 /// By default, performs semantic analysis to build the new statement.
1391 /// Subclasses may override this routine to provide different behavior.
1392 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1393 SourceLocation ColonLoc, Stmt *SubStmt) {
1394 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1395 }
1396
1397 /// Build a new attributed statement.
1398 ///
1399 /// By default, performs semantic analysis to build the new statement.
1400 /// Subclasses may override this routine to provide different behavior.
1401 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1402 ArrayRef<const Attr *> Attrs,
1403 Stmt *SubStmt) {
1404 if (SemaRef.CheckRebuiltStmtAttributes(Attrs: Attrs))
1405 return StmtError();
1406 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs: Attrs, SubStmt);
1407 }
1408
1409 /// Build a new "if" statement.
1410 ///
1411 /// By default, performs semantic analysis to build the new statement.
1412 /// Subclasses may override this routine to provide different behavior.
1413 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1414 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1415 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1416 SourceLocation ElseLoc, Stmt *Else) {
1417 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1418 Then, ElseLoc, Else);
1419 }
1420
1421 /// Start building a new switch statement.
1422 ///
1423 /// By default, performs semantic analysis to build the new statement.
1424 /// Subclasses may override this routine to provide different behavior.
1425 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1426 SourceLocation LParenLoc, Stmt *Init,
1427 Sema::ConditionResult Cond,
1428 SourceLocation RParenLoc) {
1429 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1430 RParenLoc);
1431 }
1432
1433 /// Attach the body to the switch statement.
1434 ///
1435 /// By default, performs semantic analysis to build the new statement.
1436 /// Subclasses may override this routine to provide different behavior.
1437 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1438 Stmt *Switch, Stmt *Body) {
1439 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1440 }
1441
1442 /// Build a new while statement.
1443 ///
1444 /// By default, performs semantic analysis to build the new statement.
1445 /// Subclasses may override this routine to provide different behavior.
1446 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1447 Sema::ConditionResult Cond,
1448 SourceLocation RParenLoc, Stmt *Body) {
1449 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1450 }
1451
1452 /// Build a new do-while statement.
1453 ///
1454 /// By default, performs semantic analysis to build the new statement.
1455 /// Subclasses may override this routine to provide different behavior.
1456 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1457 SourceLocation WhileLoc, SourceLocation LParenLoc,
1458 Expr *Cond, SourceLocation RParenLoc) {
1459 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1460 Cond, RParenLoc);
1461 }
1462
1463 /// Build a new for statement.
1464 ///
1465 /// By default, performs semantic analysis to build the new statement.
1466 /// Subclasses may override this routine to provide different behavior.
1467 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1468 Stmt *Init, Sema::ConditionResult Cond,
1469 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1470 Stmt *Body) {
1471 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1472 Inc, RParenLoc, Body);
1473 }
1474
1475 /// Build a new goto statement.
1476 ///
1477 /// By default, performs semantic analysis to build the new statement.
1478 /// Subclasses may override this routine to provide different behavior.
1479 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1480 LabelDecl *Label) {
1481 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1482 }
1483
1484 /// Build a new indirect goto statement.
1485 ///
1486 /// By default, performs semantic analysis to build the new statement.
1487 /// Subclasses may override this routine to provide different behavior.
1488 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1489 SourceLocation StarLoc,
1490 Expr *Target) {
1491 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1492 }
1493
1494 /// Build a new return statement.
1495 ///
1496 /// By default, performs semantic analysis to build the new statement.
1497 /// Subclasses may override this routine to provide different behavior.
1498 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1499 return getSema().BuildReturnStmt(ReturnLoc, Result);
1500 }
1501
1502 /// Build a new declaration statement.
1503 ///
1504 /// By default, performs semantic analysis to build the new statement.
1505 /// Subclasses may override this routine to provide different behavior.
1506 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1507 SourceLocation StartLoc, SourceLocation EndLoc) {
1508 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1509 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1510 }
1511
1512 /// Build a new inline asm statement.
1513 ///
1514 /// By default, performs semantic analysis to build the new statement.
1515 /// Subclasses may override this routine to provide different behavior.
1516 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1517 bool IsVolatile, unsigned NumOutputs,
1518 unsigned NumInputs, IdentifierInfo **Names,
1519 MultiExprArg Constraints, MultiExprArg Exprs,
1520 Expr *AsmString, MultiExprArg Clobbers,
1521 unsigned NumLabels,
1522 SourceLocation RParenLoc) {
1523 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1524 NumInputs, Names, Constraints, Exprs,
1525 AsmString, Clobbers, NumLabels, RParenLoc);
1526 }
1527
1528 /// Build a new MS style inline asm statement.
1529 ///
1530 /// By default, performs semantic analysis to build the new statement.
1531 /// Subclasses may override this routine to provide different behavior.
1532 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1533 ArrayRef<Token> AsmToks,
1534 StringRef AsmString,
1535 unsigned NumOutputs, unsigned NumInputs,
1536 ArrayRef<StringRef> Constraints,
1537 ArrayRef<StringRef> Clobbers,
1538 ArrayRef<Expr*> Exprs,
1539 SourceLocation EndLoc) {
1540 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1541 NumOutputs, NumInputs,
1542 Constraints, Clobbers, Exprs, EndLoc);
1543 }
1544
1545 /// Build a new co_return statement.
1546 ///
1547 /// By default, performs semantic analysis to build the new statement.
1548 /// Subclasses may override this routine to provide different behavior.
1549 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1550 bool IsImplicit) {
1551 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1552 }
1553
1554 /// Build a new co_await expression.
1555 ///
1556 /// By default, performs semantic analysis to build the new expression.
1557 /// Subclasses may override this routine to provide different behavior.
1558 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1559 UnresolvedLookupExpr *OpCoawaitLookup,
1560 bool IsImplicit) {
1561 // This function rebuilds a coawait-expr given its operator.
1562 // For an explicit coawait-expr, the rebuild involves the full set
1563 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1564 // including calling await_transform().
1565 // For an implicit coawait-expr, we need to rebuild the "operator
1566 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1567 // This mirrors how the implicit CoawaitExpr is originally created
1568 // in Sema::ActOnCoroutineBodyStart().
1569 if (IsImplicit) {
1570 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1571 CoawaitLoc, Operand, OpCoawaitLookup);
1572 if (Suspend.isInvalid())
1573 return ExprError();
1574 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1575 Suspend.get(), true);
1576 }
1577
1578 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1579 OpCoawaitLookup);
1580 }
1581
1582 /// Build a new co_await expression.
1583 ///
1584 /// By default, performs semantic analysis to build the new expression.
1585 /// Subclasses may override this routine to provide different behavior.
1586 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1587 Expr *Result,
1588 UnresolvedLookupExpr *Lookup) {
1589 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1590 }
1591
1592 /// Build a new co_yield expression.
1593 ///
1594 /// By default, performs semantic analysis to build the new expression.
1595 /// Subclasses may override this routine to provide different behavior.
1596 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1597 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1598 }
1599
1600 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1601 return getSema().BuildCoroutineBodyStmt(Args);
1602 }
1603
1604 /// Build a new Objective-C \@try statement.
1605 ///
1606 /// By default, performs semantic analysis to build the new statement.
1607 /// Subclasses may override this routine to provide different behavior.
1608 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1609 Stmt *TryBody,
1610 MultiStmtArg CatchStmts,
1611 Stmt *Finally) {
1612 return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1613 Finally);
1614 }
1615
1616 /// Rebuild an Objective-C exception declaration.
1617 ///
1618 /// By default, performs semantic analysis to build the new declaration.
1619 /// Subclasses may override this routine to provide different behavior.
1620 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1621 TypeSourceInfo *TInfo, QualType T) {
1622 return getSema().BuildObjCExceptionDecl(TInfo, T,
1623 ExceptionDecl->getInnerLocStart(),
1624 ExceptionDecl->getLocation(),
1625 ExceptionDecl->getIdentifier());
1626 }
1627
1628 /// Build a new Objective-C \@catch statement.
1629 ///
1630 /// By default, performs semantic analysis to build the new statement.
1631 /// Subclasses may override this routine to provide different behavior.
1632 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1633 SourceLocation RParenLoc,
1634 VarDecl *Var,
1635 Stmt *Body) {
1636 return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1637 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().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().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().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().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().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().ActOnObjCForCollectionStmt(ForLoc,
2526 Element,
2527 Collection,
2528 RParenLoc);
2529 if (ForEachStmt.isInvalid())
2530 return StmtError();
2531
2532 return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
2533 }
2534
2535 /// Build a new C++ exception declaration.
2536 ///
2537 /// By default, performs semantic analysis to build the new decaration.
2538 /// Subclasses may override this routine to provide different behavior.
2539 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2540 TypeSourceInfo *Declarator,
2541 SourceLocation StartLoc,
2542 SourceLocation IdLoc,
2543 IdentifierInfo *Id) {
2544 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2545 StartLoc, IdLoc, Id);
2546 if (Var)
2547 getSema().CurContext->addDecl(Var);
2548 return Var;
2549 }
2550
2551 /// Build a new C++ catch statement.
2552 ///
2553 /// By default, performs semantic analysis to build the new statement.
2554 /// Subclasses may override this routine to provide different behavior.
2555 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2556 VarDecl *ExceptionDecl,
2557 Stmt *Handler) {
2558 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2559 Handler));
2560 }
2561
2562 /// Build a new C++ try statement.
2563 ///
2564 /// By default, performs semantic analysis to build the new statement.
2565 /// Subclasses may override this routine to provide different behavior.
2566 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2567 ArrayRef<Stmt *> Handlers) {
2568 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2569 }
2570
2571 /// Build a new C++0x range-based for statement.
2572 ///
2573 /// By default, performs semantic analysis to build the new statement.
2574 /// Subclasses may override this routine to provide different behavior.
2575 StmtResult RebuildCXXForRangeStmt(
2576 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2577 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2578 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2579 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2580 // If we've just learned that the range is actually an Objective-C
2581 // collection, treat this as an Objective-C fast enumeration loop.
2582 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2583 if (RangeStmt->isSingleDecl()) {
2584 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2585 if (RangeVar->isInvalidDecl())
2586 return StmtError();
2587
2588 Expr *RangeExpr = RangeVar->getInit();
2589 if (!RangeExpr->isTypeDependent() &&
2590 RangeExpr->getType()->isObjCObjectPointerType()) {
2591 // FIXME: Support init-statements in Objective-C++20 ranged for
2592 // statement.
2593 if (Init) {
2594 return SemaRef.Diag(Init->getBeginLoc(),
2595 diag::err_objc_for_range_init_stmt)
2596 << Init->getSourceRange();
2597 }
2598 return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar,
2599 RangeExpr, RParenLoc);
2600 }
2601 }
2602 }
2603 }
2604
2605 return getSema().BuildCXXForRangeStmt(
2606 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2607 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2608 }
2609
2610 /// Build a new C++0x range-based for statement.
2611 ///
2612 /// By default, performs semantic analysis to build the new statement.
2613 /// Subclasses may override this routine to provide different behavior.
2614 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2615 bool IsIfExists,
2616 NestedNameSpecifierLoc QualifierLoc,
2617 DeclarationNameInfo NameInfo,
2618 Stmt *Nested) {
2619 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2620 QualifierLoc, NameInfo, Nested);
2621 }
2622
2623 /// Attach body to a C++0x range-based for statement.
2624 ///
2625 /// By default, performs semantic analysis to finish the new statement.
2626 /// Subclasses may override this routine to provide different behavior.
2627 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2628 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2629 }
2630
2631 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2632 Stmt *TryBlock, Stmt *Handler) {
2633 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2634 }
2635
2636 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2637 Stmt *Block) {
2638 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2639 }
2640
2641 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2642 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2643 }
2644
2645 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2646 SourceLocation LParen,
2647 SourceLocation RParen,
2648 TypeSourceInfo *TSI) {
2649 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2650 TSI);
2651 }
2652
2653 /// Build a new predefined expression.
2654 ///
2655 /// By default, performs semantic analysis to build the new expression.
2656 /// Subclasses may override this routine to provide different behavior.
2657 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2658 return getSema().BuildPredefinedExpr(Loc, IK);
2659 }
2660
2661 /// Build a new expression that references a declaration.
2662 ///
2663 /// By default, performs semantic analysis to build the new expression.
2664 /// Subclasses may override this routine to provide different behavior.
2665 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2666 LookupResult &R,
2667 bool RequiresADL) {
2668 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2669 }
2670
2671
2672 /// Build a new expression that references a declaration.
2673 ///
2674 /// By default, performs semantic analysis to build the new expression.
2675 /// Subclasses may override this routine to provide different behavior.
2676 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2677 ValueDecl *VD,
2678 const DeclarationNameInfo &NameInfo,
2679 NamedDecl *Found,
2680 TemplateArgumentListInfo *TemplateArgs) {
2681 CXXScopeSpec SS;
2682 SS.Adopt(Other: QualifierLoc);
2683 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2684 TemplateArgs);
2685 }
2686
2687 /// Build a new expression in parentheses.
2688 ///
2689 /// By default, performs semantic analysis to build the new expression.
2690 /// Subclasses may override this routine to provide different behavior.
2691 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2692 SourceLocation RParen) {
2693 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2694 }
2695
2696 /// Build a new pseudo-destructor expression.
2697 ///
2698 /// By default, performs semantic analysis to build the new expression.
2699 /// Subclasses may override this routine to provide different behavior.
2700 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2701 SourceLocation OperatorLoc,
2702 bool isArrow,
2703 CXXScopeSpec &SS,
2704 TypeSourceInfo *ScopeType,
2705 SourceLocation CCLoc,
2706 SourceLocation TildeLoc,
2707 PseudoDestructorTypeStorage Destroyed);
2708
2709 /// Build a new unary operator expression.
2710 ///
2711 /// By default, performs semantic analysis to build the new expression.
2712 /// Subclasses may override this routine to provide different behavior.
2713 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2714 UnaryOperatorKind Opc,
2715 Expr *SubExpr) {
2716 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2717 }
2718
2719 /// Build a new builtin offsetof expression.
2720 ///
2721 /// By default, performs semantic analysis to build the new expression.
2722 /// Subclasses may override this routine to provide different behavior.
2723 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2724 TypeSourceInfo *Type,
2725 ArrayRef<Sema::OffsetOfComponent> Components,
2726 SourceLocation RParenLoc) {
2727 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2728 RParenLoc);
2729 }
2730
2731 /// Build a new sizeof, alignof or vec_step expression with a
2732 /// type argument.
2733 ///
2734 /// By default, performs semantic analysis to build the new expression.
2735 /// Subclasses may override this routine to provide different behavior.
2736 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2737 SourceLocation OpLoc,
2738 UnaryExprOrTypeTrait ExprKind,
2739 SourceRange R) {
2740 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2741 }
2742
2743 /// Build a new sizeof, alignof or vec step expression with an
2744 /// expression argument.
2745 ///
2746 /// By default, performs semantic analysis to build the new expression.
2747 /// Subclasses may override this routine to provide different behavior.
2748 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2749 UnaryExprOrTypeTrait ExprKind,
2750 SourceRange R) {
2751 ExprResult Result
2752 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2753 if (Result.isInvalid())
2754 return ExprError();
2755
2756 return Result;
2757 }
2758
2759 /// Build a new array subscript expression.
2760 ///
2761 /// By default, performs semantic analysis to build the new expression.
2762 /// Subclasses may override this routine to provide different behavior.
2763 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2764 SourceLocation LBracketLoc,
2765 Expr *RHS,
2766 SourceLocation RBracketLoc) {
2767 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2768 LBracketLoc, RHS,
2769 RBracketLoc);
2770 }
2771
2772 /// Build a new matrix subscript expression.
2773 ///
2774 /// By default, performs semantic analysis to build the new expression.
2775 /// Subclasses may override this routine to provide different behavior.
2776 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2777 Expr *ColumnIdx,
2778 SourceLocation RBracketLoc) {
2779 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2780 RBracketLoc);
2781 }
2782
2783 /// Build a new array section expression.
2784 ///
2785 /// By default, performs semantic analysis to build the new expression.
2786 /// Subclasses may override this routine to provide different behavior.
2787 ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,
2788 Expr *LowerBound,
2789 SourceLocation ColonLocFirst,
2790 SourceLocation ColonLocSecond,
2791 Expr *Length, Expr *Stride,
2792 SourceLocation RBracketLoc) {
2793 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2794 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2795 Stride, RBracketLoc);
2796 }
2797
2798 /// Build a new array shaping expression.
2799 ///
2800 /// By default, performs semantic analysis to build the new expression.
2801 /// Subclasses may override this routine to provide different behavior.
2802 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2803 SourceLocation RParenLoc,
2804 ArrayRef<Expr *> Dims,
2805 ArrayRef<SourceRange> BracketsRanges) {
2806 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2807 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2808 }
2809
2810 /// Build a new iterator expression.
2811 ///
2812 /// By default, performs semantic analysis to build the new expression.
2813 /// Subclasses may override this routine to provide different behavior.
2814 ExprResult
2815 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2816 SourceLocation RLoc,
2817 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2818 return getSema().OpenMP().ActOnOMPIteratorExpr(
2819 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2820 }
2821
2822 /// Build a new call expression.
2823 ///
2824 /// By default, performs semantic analysis to build the new expression.
2825 /// Subclasses may override this routine to provide different behavior.
2826 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2827 MultiExprArg Args,
2828 SourceLocation RParenLoc,
2829 Expr *ExecConfig = nullptr) {
2830 return getSema().ActOnCallExpr(
2831 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2832 }
2833
2834 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2835 MultiExprArg Args,
2836 SourceLocation RParenLoc) {
2837 return getSema().ActOnArraySubscriptExpr(
2838 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2839 }
2840
2841 /// Build a new member access expression.
2842 ///
2843 /// By default, performs semantic analysis to build the new expression.
2844 /// Subclasses may override this routine to provide different behavior.
2845 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2846 bool isArrow,
2847 NestedNameSpecifierLoc QualifierLoc,
2848 SourceLocation TemplateKWLoc,
2849 const DeclarationNameInfo &MemberNameInfo,
2850 ValueDecl *Member,
2851 NamedDecl *FoundDecl,
2852 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2853 NamedDecl *FirstQualifierInScope) {
2854 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2855 isArrow);
2856 if (!Member->getDeclName()) {
2857 // We have a reference to an unnamed field. This is always the
2858 // base of an anonymous struct/union member access, i.e. the
2859 // field is always of record type.
2860 assert(Member->getType()->isRecordType() &&
2861 "unnamed member not of record type?");
2862
2863 BaseResult =
2864 getSema().PerformObjectMemberConversion(BaseResult.get(),
2865 QualifierLoc.getNestedNameSpecifier(),
2866 FoundDecl, Member);
2867 if (BaseResult.isInvalid())
2868 return ExprError();
2869 Base = BaseResult.get();
2870
2871 CXXScopeSpec EmptySS;
2872 return getSema().BuildFieldReferenceExpr(
2873 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2874 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()), MemberNameInfo);
2875 }
2876
2877 CXXScopeSpec SS;
2878 SS.Adopt(Other: QualifierLoc);
2879
2880 Base = BaseResult.get();
2881 QualType BaseType = Base->getType();
2882
2883 if (isArrow && !BaseType->isPointerType())
2884 return ExprError();
2885
2886 // FIXME: this involves duplicating earlier analysis in a lot of
2887 // cases; we should avoid this when possible.
2888 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2889 R.addDecl(D: FoundDecl);
2890 R.resolveKind();
2891
2892 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2893 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2894 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2895 ->getType()
2896 ->getPointeeType()
2897 ->getAsCXXRecordDecl()) {
2898 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2899 // In unevaluated contexts, an expression supposed to be a member access
2900 // might reference a member in an unrelated class.
2901 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2902 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2903 VK_LValue, Member->getLocation());
2904 }
2905 }
2906
2907 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2908 SS, TemplateKWLoc,
2909 FirstQualifierInScope,
2910 R, ExplicitTemplateArgs,
2911 /*S*/nullptr);
2912 }
2913
2914 /// Build a new binary operator expression.
2915 ///
2916 /// By default, performs semantic analysis to build the new expression.
2917 /// Subclasses may override this routine to provide different behavior.
2918 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2919 BinaryOperatorKind Opc,
2920 Expr *LHS, Expr *RHS) {
2921 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2922 }
2923
2924 /// Build a new rewritten operator expression.
2925 ///
2926 /// By default, performs semantic analysis to build the new expression.
2927 /// Subclasses may override this routine to provide different behavior.
2928 ExprResult RebuildCXXRewrittenBinaryOperator(
2929 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2930 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2931 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2932 RHS, /*RequiresADL*/false);
2933 }
2934
2935 /// Build a new conditional 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 RebuildConditionalOperator(Expr *Cond,
2940 SourceLocation QuestionLoc,
2941 Expr *LHS,
2942 SourceLocation ColonLoc,
2943 Expr *RHS) {
2944 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2945 LHS, RHS);
2946 }
2947
2948 /// Build a new C-style cast expression.
2949 ///
2950 /// By default, performs semantic analysis to build the new expression.
2951 /// Subclasses may override this routine to provide different behavior.
2952 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2953 TypeSourceInfo *TInfo,
2954 SourceLocation RParenLoc,
2955 Expr *SubExpr) {
2956 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2957 SubExpr);
2958 }
2959
2960 /// Build a new compound literal expression.
2961 ///
2962 /// By default, performs semantic analysis to build the new expression.
2963 /// Subclasses may override this routine to provide different behavior.
2964 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2965 TypeSourceInfo *TInfo,
2966 SourceLocation RParenLoc,
2967 Expr *Init) {
2968 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2969 Init);
2970 }
2971
2972 /// Build a new extended vector element access expression.
2973 ///
2974 /// By default, performs semantic analysis to build the new expression.
2975 /// Subclasses may override this routine to provide different behavior.
2976 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2977 bool IsArrow,
2978 SourceLocation AccessorLoc,
2979 IdentifierInfo &Accessor) {
2980
2981 CXXScopeSpec SS;
2982 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
2983 return getSema().BuildMemberReferenceExpr(
2984 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
2985 /*FirstQualifierInScope*/ nullptr, NameInfo,
2986 /* TemplateArgs */ nullptr,
2987 /*S*/ nullptr);
2988 }
2989
2990 /// Build a new initializer list expression.
2991 ///
2992 /// By default, performs semantic analysis to build the new expression.
2993 /// Subclasses may override this routine to provide different behavior.
2994 ExprResult RebuildInitList(SourceLocation LBraceLoc,
2995 MultiExprArg Inits,
2996 SourceLocation RBraceLoc) {
2997 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
2998 }
2999
3000 /// Build a new designated initializer expression.
3001 ///
3002 /// By default, performs semantic analysis to build the new expression.
3003 /// Subclasses may override this routine to provide different behavior.
3004 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3005 MultiExprArg ArrayExprs,
3006 SourceLocation EqualOrColonLoc,
3007 bool GNUSyntax,
3008 Expr *Init) {
3009 ExprResult Result
3010 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3011 Init);
3012 if (Result.isInvalid())
3013 return ExprError();
3014
3015 return Result;
3016 }
3017
3018 /// Build a new value-initialized expression.
3019 ///
3020 /// By default, builds the implicit value initialization without performing
3021 /// any semantic analysis. Subclasses may override this routine to provide
3022 /// different behavior.
3023 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3024 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3025 }
3026
3027 /// Build a new \c va_arg expression.
3028 ///
3029 /// By default, performs semantic analysis to build the new expression.
3030 /// Subclasses may override this routine to provide different behavior.
3031 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3032 Expr *SubExpr, TypeSourceInfo *TInfo,
3033 SourceLocation RParenLoc) {
3034 return getSema().BuildVAArgExpr(BuiltinLoc,
3035 SubExpr, TInfo,
3036 RParenLoc);
3037 }
3038
3039 /// Build a new expression list in parentheses.
3040 ///
3041 /// By default, performs semantic analysis to build the new expression.
3042 /// Subclasses may override this routine to provide different behavior.
3043 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3044 MultiExprArg SubExprs,
3045 SourceLocation RParenLoc) {
3046 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3047 }
3048
3049 /// Build a new address-of-label expression.
3050 ///
3051 /// By default, performs semantic analysis, using the name of the label
3052 /// rather than attempting to map the label statement itself.
3053 /// Subclasses may override this routine to provide different behavior.
3054 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3055 SourceLocation LabelLoc, LabelDecl *Label) {
3056 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3057 }
3058
3059 /// Build a new GNU statement expression.
3060 ///
3061 /// By default, performs semantic analysis to build the new expression.
3062 /// Subclasses may override this routine to provide different behavior.
3063 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3064 SourceLocation RParenLoc, unsigned TemplateDepth) {
3065 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3066 TemplateDepth);
3067 }
3068
3069 /// Build a new __builtin_choose_expr expression.
3070 ///
3071 /// By default, performs semantic analysis to build the new expression.
3072 /// Subclasses may override this routine to provide different behavior.
3073 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3074 Expr *Cond, Expr *LHS, Expr *RHS,
3075 SourceLocation RParenLoc) {
3076 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3077 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3078 RPLoc: RParenLoc);
3079 }
3080
3081 /// Build a new generic selection expression with an expression predicate.
3082 ///
3083 /// By default, performs semantic analysis to build the new expression.
3084 /// Subclasses may override this routine to provide different behavior.
3085 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3086 SourceLocation DefaultLoc,
3087 SourceLocation RParenLoc,
3088 Expr *ControllingExpr,
3089 ArrayRef<TypeSourceInfo *> Types,
3090 ArrayRef<Expr *> Exprs) {
3091 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3092 /*PredicateIsExpr=*/true,
3093 ControllingExpr, Types, Exprs);
3094 }
3095
3096 /// Build a new generic selection expression with a type predicate.
3097 ///
3098 /// By default, performs semantic analysis to build the new expression.
3099 /// Subclasses may override this routine to provide different behavior.
3100 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3101 SourceLocation DefaultLoc,
3102 SourceLocation RParenLoc,
3103 TypeSourceInfo *ControllingType,
3104 ArrayRef<TypeSourceInfo *> Types,
3105 ArrayRef<Expr *> Exprs) {
3106 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3107 /*PredicateIsExpr=*/false,
3108 ControllingType, Types, Exprs);
3109 }
3110
3111 /// Build a new overloaded operator call expression.
3112 ///
3113 /// By default, performs semantic analysis to build the new expression.
3114 /// The semantic analysis provides the behavior of template instantiation,
3115 /// copying with transformations that turn what looks like an overloaded
3116 /// operator call into a use of a builtin operator, performing
3117 /// argument-dependent lookup, etc. Subclasses may override this routine to
3118 /// provide different behavior.
3119 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3120 SourceLocation OpLoc,
3121 SourceLocation CalleeLoc,
3122 bool RequiresADL,
3123 const UnresolvedSetImpl &Functions,
3124 Expr *First, Expr *Second);
3125
3126 /// Build a new C++ "named" cast expression, such as static_cast or
3127 /// reinterpret_cast.
3128 ///
3129 /// By default, this routine dispatches to one of the more-specific routines
3130 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3131 /// Subclasses may override this routine to provide different behavior.
3132 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3133 Stmt::StmtClass Class,
3134 SourceLocation LAngleLoc,
3135 TypeSourceInfo *TInfo,
3136 SourceLocation RAngleLoc,
3137 SourceLocation LParenLoc,
3138 Expr *SubExpr,
3139 SourceLocation RParenLoc) {
3140 switch (Class) {
3141 case Stmt::CXXStaticCastExprClass:
3142 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3143 RAngleLoc, LParenLoc,
3144 SubExpr, RParenLoc);
3145
3146 case Stmt::CXXDynamicCastExprClass:
3147 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3148 RAngleLoc, LParenLoc,
3149 SubExpr, RParenLoc);
3150
3151 case Stmt::CXXReinterpretCastExprClass:
3152 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3153 RAngleLoc, LParenLoc,
3154 SubExpr,
3155 RParenLoc);
3156
3157 case Stmt::CXXConstCastExprClass:
3158 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3159 RAngleLoc, LParenLoc,
3160 SubExpr, RParenLoc);
3161
3162 case Stmt::CXXAddrspaceCastExprClass:
3163 return getDerived().RebuildCXXAddrspaceCastExpr(
3164 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3165
3166 default:
3167 llvm_unreachable("Invalid C++ named cast");
3168 }
3169 }
3170
3171 /// Build a new C++ static_cast expression.
3172 ///
3173 /// By default, performs semantic analysis to build the new expression.
3174 /// Subclasses may override this routine to provide different behavior.
3175 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3176 SourceLocation LAngleLoc,
3177 TypeSourceInfo *TInfo,
3178 SourceLocation RAngleLoc,
3179 SourceLocation LParenLoc,
3180 Expr *SubExpr,
3181 SourceLocation RParenLoc) {
3182 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3183 TInfo, SubExpr,
3184 SourceRange(LAngleLoc, RAngleLoc),
3185 SourceRange(LParenLoc, RParenLoc));
3186 }
3187
3188 /// Build a new C++ dynamic_cast expression.
3189 ///
3190 /// By default, performs semantic analysis to build the new expression.
3191 /// Subclasses may override this routine to provide different behavior.
3192 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3193 SourceLocation LAngleLoc,
3194 TypeSourceInfo *TInfo,
3195 SourceLocation RAngleLoc,
3196 SourceLocation LParenLoc,
3197 Expr *SubExpr,
3198 SourceLocation RParenLoc) {
3199 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3200 TInfo, SubExpr,
3201 SourceRange(LAngleLoc, RAngleLoc),
3202 SourceRange(LParenLoc, RParenLoc));
3203 }
3204
3205 /// Build a new C++ reinterpret_cast expression.
3206 ///
3207 /// By default, performs semantic analysis to build the new expression.
3208 /// Subclasses may override this routine to provide different behavior.
3209 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3210 SourceLocation LAngleLoc,
3211 TypeSourceInfo *TInfo,
3212 SourceLocation RAngleLoc,
3213 SourceLocation LParenLoc,
3214 Expr *SubExpr,
3215 SourceLocation RParenLoc) {
3216 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3217 TInfo, SubExpr,
3218 SourceRange(LAngleLoc, RAngleLoc),
3219 SourceRange(LParenLoc, RParenLoc));
3220 }
3221
3222 /// Build a new C++ const_cast expression.
3223 ///
3224 /// By default, performs semantic analysis to build the new expression.
3225 /// Subclasses may override this routine to provide different behavior.
3226 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3227 SourceLocation LAngleLoc,
3228 TypeSourceInfo *TInfo,
3229 SourceLocation RAngleLoc,
3230 SourceLocation LParenLoc,
3231 Expr *SubExpr,
3232 SourceLocation RParenLoc) {
3233 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3234 TInfo, SubExpr,
3235 SourceRange(LAngleLoc, RAngleLoc),
3236 SourceRange(LParenLoc, RParenLoc));
3237 }
3238
3239 ExprResult
3240 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3241 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3242 SourceLocation LParenLoc, Expr *SubExpr,
3243 SourceLocation RParenLoc) {
3244 return getSema().BuildCXXNamedCast(
3245 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3246 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3247 }
3248
3249 /// Build a new C++ functional-style cast expression.
3250 ///
3251 /// By default, performs semantic analysis to build the new expression.
3252 /// Subclasses may override this routine to provide different behavior.
3253 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3254 SourceLocation LParenLoc,
3255 Expr *Sub,
3256 SourceLocation RParenLoc,
3257 bool ListInitialization) {
3258 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3259 // CXXParenListInitExpr. Pass its expanded arguments so that the
3260 // CXXParenListInitExpr can be rebuilt.
3261 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3262 return getSema().BuildCXXTypeConstructExpr(
3263 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3264 RParenLoc, ListInitialization);
3265 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3266 MultiExprArg(&Sub, 1), RParenLoc,
3267 ListInitialization);
3268 }
3269
3270 /// Build a new C++ __builtin_bit_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 RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3275 TypeSourceInfo *TSI, Expr *Sub,
3276 SourceLocation RParenLoc) {
3277 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3278 }
3279
3280 /// Build a new C++ typeid(type) expression.
3281 ///
3282 /// By default, performs semantic analysis to build the new expression.
3283 /// Subclasses may override this routine to provide different behavior.
3284 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3285 SourceLocation TypeidLoc,
3286 TypeSourceInfo *Operand,
3287 SourceLocation RParenLoc) {
3288 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3289 RParenLoc);
3290 }
3291
3292
3293 /// Build a new C++ typeid(expr) expression.
3294 ///
3295 /// By default, performs semantic analysis to build the new expression.
3296 /// Subclasses may override this routine to provide different behavior.
3297 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3298 SourceLocation TypeidLoc,
3299 Expr *Operand,
3300 SourceLocation RParenLoc) {
3301 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3302 RParenLoc);
3303 }
3304
3305 /// Build a new C++ __uuidof(type) expression.
3306 ///
3307 /// By default, performs semantic analysis to build the new expression.
3308 /// Subclasses may override this routine to provide different behavior.
3309 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3310 TypeSourceInfo *Operand,
3311 SourceLocation RParenLoc) {
3312 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3313 }
3314
3315 /// Build a new C++ __uuidof(expr) expression.
3316 ///
3317 /// By default, performs semantic analysis to build the new expression.
3318 /// Subclasses may override this routine to provide different behavior.
3319 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3320 Expr *Operand, SourceLocation RParenLoc) {
3321 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3322 }
3323
3324 /// Build a new C++ "this" expression.
3325 ///
3326 /// By default, performs semantic analysis to build a new "this" expression.
3327 /// Subclasses may override this routine to provide different behavior.
3328 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3329 QualType ThisType,
3330 bool isImplicit) {
3331 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3332 return ExprError();
3333 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3334 }
3335
3336 /// Build a new C++ throw 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 RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3341 bool IsThrownVariableInScope) {
3342 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3343 }
3344
3345 /// Build a new C++ default-argument expression.
3346 ///
3347 /// By default, builds a new default-argument expression, which does not
3348 /// require any semantic analysis. Subclasses may override this routine to
3349 /// provide different behavior.
3350 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3351 Expr *RewrittenExpr) {
3352 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3353 RewrittenExpr, UsedContext: getSema().CurContext);
3354 }
3355
3356 /// Build a new C++11 default-initialization expression.
3357 ///
3358 /// By default, builds a new default field initialization expression, which
3359 /// does not require any semantic analysis. Subclasses may override this
3360 /// routine to provide different behavior.
3361 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3362 FieldDecl *Field) {
3363 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3364 }
3365
3366 /// Build a new C++ zero-initialization expression.
3367 ///
3368 /// By default, performs semantic analysis to build the new expression.
3369 /// Subclasses may override this routine to provide different behavior.
3370 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3371 SourceLocation LParenLoc,
3372 SourceLocation RParenLoc) {
3373 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3374 RParenLoc,
3375 /*ListInitialization=*/false);
3376 }
3377
3378 /// Build a new C++ "new" expression.
3379 ///
3380 /// By default, performs semantic analysis to build the new expression.
3381 /// Subclasses may override this routine to provide different behavior.
3382 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3383 SourceLocation PlacementLParen,
3384 MultiExprArg PlacementArgs,
3385 SourceLocation PlacementRParen,
3386 SourceRange TypeIdParens, QualType AllocatedType,
3387 TypeSourceInfo *AllocatedTypeInfo,
3388 std::optional<Expr *> ArraySize,
3389 SourceRange DirectInitRange, Expr *Initializer) {
3390 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3391 PlacementLParen,
3392 PlacementArgs,
3393 PlacementRParen,
3394 TypeIdParens,
3395 AllocatedType,
3396 AllocatedTypeInfo,
3397 ArraySize,
3398 DirectInitRange,
3399 Initializer);
3400 }
3401
3402 /// Build a new C++ "delete" expression.
3403 ///
3404 /// By default, performs semantic analysis to build the new expression.
3405 /// Subclasses may override this routine to provide different behavior.
3406 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3407 bool IsGlobalDelete,
3408 bool IsArrayForm,
3409 Expr *Operand) {
3410 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3411 Operand);
3412 }
3413
3414 /// Build a new type trait expression.
3415 ///
3416 /// By default, performs semantic analysis to build the new expression.
3417 /// Subclasses may override this routine to provide different behavior.
3418 ExprResult RebuildTypeTrait(TypeTrait Trait,
3419 SourceLocation StartLoc,
3420 ArrayRef<TypeSourceInfo *> Args,
3421 SourceLocation RParenLoc) {
3422 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3423 }
3424
3425 /// Build a new array type trait expression.
3426 ///
3427 /// By default, performs semantic analysis to build the new expression.
3428 /// Subclasses may override this routine to provide different behavior.
3429 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3430 SourceLocation StartLoc,
3431 TypeSourceInfo *TSInfo,
3432 Expr *DimExpr,
3433 SourceLocation RParenLoc) {
3434 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3435 }
3436
3437 /// Build a new expression trait expression.
3438 ///
3439 /// By default, performs semantic analysis to build the new expression.
3440 /// Subclasses may override this routine to provide different behavior.
3441 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3442 SourceLocation StartLoc,
3443 Expr *Queried,
3444 SourceLocation RParenLoc) {
3445 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3446 }
3447
3448 /// Build a new (previously unresolved) declaration reference
3449 /// expression.
3450 ///
3451 /// By default, performs semantic analysis to build the new expression.
3452 /// Subclasses may override this routine to provide different behavior.
3453 ExprResult RebuildDependentScopeDeclRefExpr(
3454 NestedNameSpecifierLoc QualifierLoc,
3455 SourceLocation TemplateKWLoc,
3456 const DeclarationNameInfo &NameInfo,
3457 const TemplateArgumentListInfo *TemplateArgs,
3458 bool IsAddressOfOperand,
3459 TypeSourceInfo **RecoveryTSI) {
3460 CXXScopeSpec SS;
3461 SS.Adopt(Other: QualifierLoc);
3462
3463 if (TemplateArgs || TemplateKWLoc.isValid())
3464 return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
3465 TemplateArgs);
3466
3467 return getSema().BuildQualifiedDeclarationNameExpr(
3468 SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI);
3469 }
3470
3471 /// Build a new template-id expression.
3472 ///
3473 /// By default, performs semantic analysis to build the new expression.
3474 /// Subclasses may override this routine to provide different behavior.
3475 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3476 SourceLocation TemplateKWLoc,
3477 LookupResult &R,
3478 bool RequiresADL,
3479 const TemplateArgumentListInfo *TemplateArgs) {
3480 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3481 TemplateArgs);
3482 }
3483
3484 /// Build a new object-construction expression.
3485 ///
3486 /// By default, performs semantic analysis to build the new expression.
3487 /// Subclasses may override this routine to provide different behavior.
3488 ExprResult RebuildCXXConstructExpr(
3489 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3490 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3491 bool ListInitialization, bool StdInitListInitialization,
3492 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3493 SourceRange ParenRange) {
3494 // Reconstruct the constructor we originally found, which might be
3495 // different if this is a call to an inherited constructor.
3496 CXXConstructorDecl *FoundCtor = Constructor;
3497 if (Constructor->isInheritingConstructor())
3498 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3499
3500 SmallVector<Expr *, 8> ConvertedArgs;
3501 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3502 ConvertedArgs))
3503 return ExprError();
3504
3505 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3506 IsElidable,
3507 ConvertedArgs,
3508 HadMultipleCandidates,
3509 ListInitialization,
3510 StdInitListInitialization,
3511 RequiresZeroInit, ConstructKind,
3512 ParenRange);
3513 }
3514
3515 /// Build a new implicit construction via inherited constructor
3516 /// expression.
3517 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3518 CXXConstructorDecl *Constructor,
3519 bool ConstructsVBase,
3520 bool InheritedFromVBase) {
3521 return new (getSema().Context) CXXInheritedCtorInitExpr(
3522 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3523 }
3524
3525 /// Build a new object-construction expression.
3526 ///
3527 /// By default, performs semantic analysis to build the new expression.
3528 /// Subclasses may override this routine to provide different behavior.
3529 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3530 SourceLocation LParenOrBraceLoc,
3531 MultiExprArg Args,
3532 SourceLocation RParenOrBraceLoc,
3533 bool ListInitialization) {
3534 return getSema().BuildCXXTypeConstructExpr(
3535 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3536 }
3537
3538 /// Build a new object-construction expression.
3539 ///
3540 /// By default, performs semantic analysis to build the new expression.
3541 /// Subclasses may override this routine to provide different behavior.
3542 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3543 SourceLocation LParenLoc,
3544 MultiExprArg Args,
3545 SourceLocation RParenLoc,
3546 bool ListInitialization) {
3547 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3548 RParenLoc, ListInitialization);
3549 }
3550
3551 /// Build a new member reference expression.
3552 ///
3553 /// By default, performs semantic analysis to build the new expression.
3554 /// Subclasses may override this routine to provide different behavior.
3555 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3556 QualType BaseType,
3557 bool IsArrow,
3558 SourceLocation OperatorLoc,
3559 NestedNameSpecifierLoc QualifierLoc,
3560 SourceLocation TemplateKWLoc,
3561 NamedDecl *FirstQualifierInScope,
3562 const DeclarationNameInfo &MemberNameInfo,
3563 const TemplateArgumentListInfo *TemplateArgs) {
3564 CXXScopeSpec SS;
3565 SS.Adopt(Other: QualifierLoc);
3566
3567 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3568 OpLoc: OperatorLoc, IsArrow,
3569 SS, TemplateKWLoc,
3570 FirstQualifierInScope,
3571 NameInfo: MemberNameInfo,
3572 TemplateArgs, /*S*/S: nullptr);
3573 }
3574
3575 /// Build a new member reference expression.
3576 ///
3577 /// By default, performs semantic analysis to build the new expression.
3578 /// Subclasses may override this routine to provide different behavior.
3579 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3580 SourceLocation OperatorLoc,
3581 bool IsArrow,
3582 NestedNameSpecifierLoc QualifierLoc,
3583 SourceLocation TemplateKWLoc,
3584 NamedDecl *FirstQualifierInScope,
3585 LookupResult &R,
3586 const TemplateArgumentListInfo *TemplateArgs) {
3587 CXXScopeSpec SS;
3588 SS.Adopt(Other: QualifierLoc);
3589
3590 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3591 OpLoc: OperatorLoc, IsArrow,
3592 SS, TemplateKWLoc,
3593 FirstQualifierInScope,
3594 R, TemplateArgs, /*S*/S: nullptr);
3595 }
3596
3597 /// Build a new noexcept expression.
3598 ///
3599 /// By default, performs semantic analysis to build the new expression.
3600 /// Subclasses may override this routine to provide different behavior.
3601 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3602 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3603 }
3604
3605 /// Build a new expression to compute the length of a parameter pack.
3606 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3607 SourceLocation PackLoc,
3608 SourceLocation RParenLoc,
3609 std::optional<unsigned> Length,
3610 ArrayRef<TemplateArgument> PartialArgs) {
3611 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3612 RParenLoc, Length, PartialArgs);
3613 }
3614
3615 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3616 SourceLocation RSquareLoc,
3617 Expr *PackIdExpression, Expr *IndexExpr,
3618 ArrayRef<Expr *> ExpandedExprs,
3619 bool EmptyPack = false) {
3620 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3621 IndexExpr, RSquareLoc, ExpandedExprs,
3622 EmptyPack);
3623 }
3624
3625 /// Build a new expression representing a call to a source location
3626 /// builtin.
3627 ///
3628 /// By default, performs semantic analysis to build the new expression.
3629 /// Subclasses may override this routine to provide different behavior.
3630 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3631 SourceLocation BuiltinLoc,
3632 SourceLocation RPLoc,
3633 DeclContext *ParentContext) {
3634 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3635 ParentContext);
3636 }
3637
3638 /// Build a new Objective-C boxed expression.
3639 ///
3640 /// By default, performs semantic analysis to build the new expression.
3641 /// Subclasses may override this routine to provide different behavior.
3642 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3643 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3644 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3645 TemplateArgumentListInfo *TALI) {
3646 CXXScopeSpec SS;
3647 SS.Adopt(Other: NNS);
3648 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3649 ConceptNameInfo,
3650 FoundDecl,
3651 NamedConcept, TALI);
3652 if (Result.isInvalid())
3653 return ExprError();
3654 return Result;
3655 }
3656
3657 /// \brief Build a new requires expression.
3658 ///
3659 /// By default, performs semantic analysis to build the new expression.
3660 /// Subclasses may override this routine to provide different behavior.
3661 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3662 RequiresExprBodyDecl *Body,
3663 SourceLocation LParenLoc,
3664 ArrayRef<ParmVarDecl *> LocalParameters,
3665 SourceLocation RParenLoc,
3666 ArrayRef<concepts::Requirement *> Requirements,
3667 SourceLocation ClosingBraceLoc) {
3668 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3669 LocalParameters, RParenLoc, Requirements,
3670 ClosingBraceLoc);
3671 }
3672
3673 concepts::TypeRequirement *
3674 RebuildTypeRequirement(
3675 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3676 return SemaRef.BuildTypeRequirement(SubstDiag);
3677 }
3678
3679 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3680 return SemaRef.BuildTypeRequirement(Type: T);
3681 }
3682
3683 concepts::ExprRequirement *
3684 RebuildExprRequirement(
3685 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3686 SourceLocation NoexceptLoc,
3687 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3688 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3689 std::move(Ret));
3690 }
3691
3692 concepts::ExprRequirement *
3693 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3694 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3695 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3696 std::move(Ret));
3697 }
3698
3699 concepts::NestedRequirement *
3700 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3701 const ASTConstraintSatisfaction &Satisfaction) {
3702 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3703 Satisfaction);
3704 }
3705
3706 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3707 return SemaRef.BuildNestedRequirement(E: Constraint);
3708 }
3709
3710 /// \brief Build a new Objective-C boxed expression.
3711 ///
3712 /// By default, performs semantic analysis to build the new expression.
3713 /// Subclasses may override this routine to provide different behavior.
3714 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3715 return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
3716 }
3717
3718 /// Build a new Objective-C array literal.
3719 ///
3720 /// By default, performs semantic analysis to build the new expression.
3721 /// Subclasses may override this routine to provide different behavior.
3722 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3723 Expr **Elements, unsigned NumElements) {
3724 return getSema().BuildObjCArrayLiteral(Range,
3725 MultiExprArg(Elements, NumElements));
3726 }
3727
3728 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3729 Expr *Base, Expr *Key,
3730 ObjCMethodDecl *getterMethod,
3731 ObjCMethodDecl *setterMethod) {
3732 return getSema().BuildObjCSubscriptExpression(RB, Base, Key,
3733 getterMethod, setterMethod);
3734 }
3735
3736 /// Build a new Objective-C dictionary literal.
3737 ///
3738 /// By default, performs semantic analysis to build the new expression.
3739 /// Subclasses may override this routine to provide different behavior.
3740 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3741 MutableArrayRef<ObjCDictionaryElement> Elements) {
3742 return getSema().BuildObjCDictionaryLiteral(Range, Elements);
3743 }
3744
3745 /// Build a new Objective-C \@encode expression.
3746 ///
3747 /// By default, performs semantic analysis to build the new expression.
3748 /// Subclasses may override this routine to provide different behavior.
3749 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3750 TypeSourceInfo *EncodeTypeInfo,
3751 SourceLocation RParenLoc) {
3752 return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo, RParenLoc);
3753 }
3754
3755 /// Build a new Objective-C class message.
3756 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3757 Selector Sel,
3758 ArrayRef<SourceLocation> SelectorLocs,
3759 ObjCMethodDecl *Method,
3760 SourceLocation LBracLoc,
3761 MultiExprArg Args,
3762 SourceLocation RBracLoc) {
3763 return SemaRef.BuildClassMessage(ReceiverTypeInfo,
3764 ReceiverType: ReceiverTypeInfo->getType(),
3765 /*SuperLoc=*/SuperLoc: SourceLocation(),
3766 Sel, Method, LBracLoc, SelectorLocs,
3767 RBracLoc, Args);
3768 }
3769
3770 /// Build a new Objective-C instance message.
3771 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3772 Selector Sel,
3773 ArrayRef<SourceLocation> SelectorLocs,
3774 ObjCMethodDecl *Method,
3775 SourceLocation LBracLoc,
3776 MultiExprArg Args,
3777 SourceLocation RBracLoc) {
3778 return SemaRef.BuildInstanceMessage(Receiver,
3779 ReceiverType: Receiver->getType(),
3780 /*SuperLoc=*/SuperLoc: SourceLocation(),
3781 Sel, Method, LBracLoc, SelectorLocs,
3782 RBracLoc, Args);
3783 }
3784
3785 /// Build a new Objective-C instance/class message to 'super'.
3786 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3787 Selector Sel,
3788 ArrayRef<SourceLocation> SelectorLocs,
3789 QualType SuperType,
3790 ObjCMethodDecl *Method,
3791 SourceLocation LBracLoc,
3792 MultiExprArg Args,
3793 SourceLocation RBracLoc) {
3794 return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(Receiver: nullptr,
3795 ReceiverType: SuperType,
3796 SuperLoc,
3797 Sel, Method, LBracLoc, SelectorLocs,
3798 RBracLoc, Args)
3799 : SemaRef.BuildClassMessage(ReceiverTypeInfo: nullptr,
3800 ReceiverType: SuperType,
3801 SuperLoc,
3802 Sel, Method, LBracLoc, SelectorLocs,
3803 RBracLoc, Args);
3804
3805
3806 }
3807
3808 /// Build a new Objective-C ivar reference expression.
3809 ///
3810 /// By default, performs semantic analysis to build the new expression.
3811 /// Subclasses may override this routine to provide different behavior.
3812 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3813 SourceLocation IvarLoc,
3814 bool IsArrow, bool IsFreeIvar) {
3815 CXXScopeSpec SS;
3816 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3817 ExprResult Result = getSema().BuildMemberReferenceExpr(
3818 BaseArg, BaseArg->getType(),
3819 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3820 /*FirstQualifierInScope=*/nullptr, NameInfo,
3821 /*TemplateArgs=*/nullptr,
3822 /*S=*/nullptr);
3823 if (IsFreeIvar && Result.isUsable())
3824 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3825 return Result;
3826 }
3827
3828 /// Build a new Objective-C property reference expression.
3829 ///
3830 /// By default, performs semantic analysis to build the new expression.
3831 /// Subclasses may override this routine to provide different behavior.
3832 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3833 ObjCPropertyDecl *Property,
3834 SourceLocation PropertyLoc) {
3835 CXXScopeSpec SS;
3836 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3837 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3838 /*FIXME:*/PropertyLoc,
3839 /*IsArrow=*/false,
3840 SS, SourceLocation(),
3841 /*FirstQualifierInScope=*/nullptr,
3842 NameInfo,
3843 /*TemplateArgs=*/nullptr,
3844 /*S=*/nullptr);
3845 }
3846
3847 /// Build a new Objective-C property reference expression.
3848 ///
3849 /// By default, performs semantic analysis to build the new expression.
3850 /// Subclasses may override this routine to provide different behavior.
3851 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3852 ObjCMethodDecl *Getter,
3853 ObjCMethodDecl *Setter,
3854 SourceLocation PropertyLoc) {
3855 // Since these expressions can only be value-dependent, we do not
3856 // need to perform semantic analysis again.
3857 return Owned(
3858 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3859 VK_LValue, OK_ObjCProperty,
3860 PropertyLoc, Base));
3861 }
3862
3863 /// Build a new Objective-C "isa" expression.
3864 ///
3865 /// By default, performs semantic analysis to build the new expression.
3866 /// Subclasses may override this routine to provide different behavior.
3867 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3868 SourceLocation OpLoc, bool IsArrow) {
3869 CXXScopeSpec SS;
3870 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3871 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3872 OpLoc, IsArrow,
3873 SS, SourceLocation(),
3874 /*FirstQualifierInScope=*/nullptr,
3875 NameInfo,
3876 /*TemplateArgs=*/nullptr,
3877 /*S=*/nullptr);
3878 }
3879
3880 /// Build a new shuffle vector expression.
3881 ///
3882 /// By default, performs semantic analysis to build the new expression.
3883 /// Subclasses may override this routine to provide different behavior.
3884 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3885 MultiExprArg SubExprs,
3886 SourceLocation RParenLoc) {
3887 // Find the declaration for __builtin_shufflevector
3888 const IdentifierInfo &Name
3889 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
3890 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3891 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3892 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3893
3894 // Build a reference to the __builtin_shufflevector builtin
3895 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3896 Expr *Callee = new (SemaRef.Context)
3897 DeclRefExpr(SemaRef.Context, Builtin, false,
3898 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3899 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3900 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
3901 CK: CK_BuiltinFnToFnPtr).get();
3902
3903 // Build the CallExpr
3904 ExprResult TheCall = CallExpr::Create(
3905 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
3906 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
3907 FPFeatures: FPOptionsOverride());
3908
3909 // Type-check the __builtin_shufflevector expression.
3910 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(TheCall.get()));
3911 }
3912
3913 /// Build a new convert vector expression.
3914 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3915 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3916 SourceLocation RParenLoc) {
3917 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
3918 }
3919
3920 /// Build a new template argument pack expansion.
3921 ///
3922 /// By default, performs semantic analysis to build a new pack expansion
3923 /// for a template argument. Subclasses may override this routine to provide
3924 /// different behavior.
3925 TemplateArgumentLoc
3926 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3927 std::optional<unsigned> NumExpansions) {
3928 switch (Pattern.getArgument().getKind()) {
3929 case TemplateArgument::Expression: {
3930 ExprResult Result
3931 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3932 EllipsisLoc, NumExpansions);
3933 if (Result.isInvalid())
3934 return TemplateArgumentLoc();
3935
3936 return TemplateArgumentLoc(Result.get(), Result.get());
3937 }
3938
3939 case TemplateArgument::Template:
3940 return TemplateArgumentLoc(
3941 SemaRef.Context,
3942 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3943 NumExpansions),
3944 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3945 EllipsisLoc);
3946
3947 case TemplateArgument::Null:
3948 case TemplateArgument::Integral:
3949 case TemplateArgument::Declaration:
3950 case TemplateArgument::StructuralValue:
3951 case TemplateArgument::Pack:
3952 case TemplateArgument::TemplateExpansion:
3953 case TemplateArgument::NullPtr:
3954 llvm_unreachable("Pack expansion pattern has no parameter packs");
3955
3956 case TemplateArgument::Type:
3957 if (TypeSourceInfo *Expansion
3958 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3959 EllipsisLoc,
3960 NumExpansions))
3961 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3962 Expansion);
3963 break;
3964 }
3965
3966 return TemplateArgumentLoc();
3967 }
3968
3969 /// Build a new expression pack expansion.
3970 ///
3971 /// By default, performs semantic analysis to build a new pack expansion
3972 /// for an expression. Subclasses may override this routine to provide
3973 /// different behavior.
3974 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3975 std::optional<unsigned> NumExpansions) {
3976 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3977 }
3978
3979 /// Build a new C++1z fold-expression.
3980 ///
3981 /// By default, performs semantic analysis in order to build a new fold
3982 /// expression.
3983 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3984 SourceLocation LParenLoc, Expr *LHS,
3985 BinaryOperatorKind Operator,
3986 SourceLocation EllipsisLoc, Expr *RHS,
3987 SourceLocation RParenLoc,
3988 std::optional<unsigned> NumExpansions) {
3989 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
3990 EllipsisLoc, RHS, RParenLoc,
3991 NumExpansions);
3992 }
3993
3994 /// Build an empty C++1z fold-expression with the given operator.
3995 ///
3996 /// By default, produces the fallback value for the fold-expression, or
3997 /// produce an error if there is no fallback value.
3998 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
3999 BinaryOperatorKind Operator) {
4000 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4001 }
4002
4003 /// Build a new atomic operation expression.
4004 ///
4005 /// By default, performs semantic analysis to build the new expression.
4006 /// Subclasses may override this routine to provide different behavior.
4007 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4008 AtomicExpr::AtomicOp Op,
4009 SourceLocation RParenLoc) {
4010 // Use this for all of the locations, since we don't know the difference
4011 // between the call and the expr at this point.
4012 SourceRange Range{BuiltinLoc, RParenLoc};
4013 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4014 Sema::AtomicArgumentOrder::AST);
4015 }
4016
4017 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4018 ArrayRef<Expr *> SubExprs, QualType Type) {
4019 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4020 }
4021
4022 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4023 SourceLocation BeginLoc,
4024 SourceLocation EndLoc,
4025 ArrayRef<OpenACCClause *> Clauses,
4026 StmtResult StrBlock) {
4027 return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, EndLoc,
4028 Clauses, StrBlock);
4029 }
4030
4031private:
4032 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4033 QualType ObjectType,
4034 NamedDecl *FirstQualifierInScope,
4035 CXXScopeSpec &SS);
4036
4037 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4038 QualType ObjectType,
4039 NamedDecl *FirstQualifierInScope,
4040 CXXScopeSpec &SS);
4041
4042 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4043 NamedDecl *FirstQualifierInScope,
4044 CXXScopeSpec &SS);
4045
4046 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4047 DependentNameTypeLoc TL,
4048 bool DeducibleTSTContext);
4049
4050 llvm::SmallVector<OpenACCClause *>
4051 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4052 ArrayRef<const OpenACCClause *> OldClauses);
4053
4054 OpenACCClause *
4055 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4056 OpenACCDirectiveKind DirKind,
4057 const OpenACCClause *OldClause);
4058};
4059
4060template <typename Derived>
4061StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4062 if (!S)
4063 return S;
4064
4065 switch (S->getStmtClass()) {
4066 case Stmt::NoStmtClass: break;
4067
4068 // Transform individual statement nodes
4069 // Pass SDK into statements that can produce a value
4070#define STMT(Node, Parent) \
4071 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4072#define VALUESTMT(Node, Parent) \
4073 case Stmt::Node##Class: \
4074 return getDerived().Transform##Node(cast<Node>(S), SDK);
4075#define ABSTRACT_STMT(Node)
4076#define EXPR(Node, Parent)
4077#include "clang/AST/StmtNodes.inc"
4078
4079 // Transform expressions by calling TransformExpr.
4080#define STMT(Node, Parent)
4081#define ABSTRACT_STMT(Stmt)
4082#define EXPR(Node, Parent) case Stmt::Node##Class:
4083#include "clang/AST/StmtNodes.inc"
4084 {
4085 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4086
4087 if (SDK == SDK_StmtExprResult)
4088 E = getSema().ActOnStmtExprResult(E);
4089 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4090 }
4091 }
4092
4093 return S;
4094}
4095
4096template<typename Derived>
4097OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4098 if (!S)
4099 return S;
4100
4101 switch (S->getClauseKind()) {
4102 default: break;
4103 // Transform individual clause nodes
4104#define GEN_CLANG_CLAUSE_CLASS
4105#define CLAUSE_CLASS(Enum, Str, Class) \
4106 case Enum: \
4107 return getDerived().Transform##Class(cast<Class>(S));
4108#include "llvm/Frontend/OpenMP/OMP.inc"
4109 }
4110
4111 return S;
4112}
4113
4114
4115template<typename Derived>
4116ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4117 if (!E)
4118 return E;
4119
4120 switch (E->getStmtClass()) {
4121 case Stmt::NoStmtClass: break;
4122#define STMT(Node, Parent) case Stmt::Node##Class: break;
4123#define ABSTRACT_STMT(Stmt)
4124#define EXPR(Node, Parent) \
4125 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4126#include "clang/AST/StmtNodes.inc"
4127 }
4128
4129 return E;
4130}
4131
4132template<typename Derived>
4133ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4134 bool NotCopyInit) {
4135 // Initializers are instantiated like expressions, except that various outer
4136 // layers are stripped.
4137 if (!Init)
4138 return Init;
4139
4140 if (auto *FE = dyn_cast<FullExpr>(Init))
4141 Init = FE->getSubExpr();
4142
4143 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4144 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4145 Init = OVE->getSourceExpr();
4146 }
4147
4148 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4149 Init = MTE->getSubExpr();
4150
4151 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4152 Init = Binder->getSubExpr();
4153
4154 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4155 Init = ICE->getSubExprAsWritten();
4156
4157 if (CXXStdInitializerListExpr *ILE =
4158 dyn_cast<CXXStdInitializerListExpr>(Init))
4159 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4160
4161 // If this is copy-initialization, we only need to reconstruct
4162 // InitListExprs. Other forms of copy-initialization will be a no-op if
4163 // the initializer is already the right type.
4164 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4165 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4166 return getDerived().TransformExpr(Init);
4167
4168 // Revert value-initialization back to empty parens.
4169 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4170 SourceRange Parens = VIE->getSourceRange();
4171 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4172 Parens.getEnd());
4173 }
4174
4175 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4176 if (isa<ImplicitValueInitExpr>(Init))
4177 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4178 SourceLocation());
4179
4180 // Revert initialization by constructor back to a parenthesized or braced list
4181 // of expressions. Any other form of initializer can just be reused directly.
4182 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4183 return getDerived().TransformExpr(Init);
4184
4185 // If the initialization implicitly converted an initializer list to a
4186 // std::initializer_list object, unwrap the std::initializer_list too.
4187 if (Construct && Construct->isStdInitListInitialization())
4188 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4189
4190 // Enter a list-init context if this was list initialization.
4191 EnterExpressionEvaluationContext Context(
4192 getSema(), EnterExpressionEvaluationContext::InitList,
4193 Construct->isListInitialization());
4194
4195 getSema().keepInLifetimeExtendingContext();
4196 SmallVector<Expr*, 8> NewArgs;
4197 bool ArgChanged = false;
4198 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4199 /*IsCall*/true, NewArgs, &ArgChanged))
4200 return ExprError();
4201
4202 // If this was list initialization, revert to syntactic list form.
4203 if (Construct->isListInitialization())
4204 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4205 Construct->getEndLoc());
4206
4207 // Build a ParenListExpr to represent anything else.
4208 SourceRange Parens = Construct->getParenOrBraceRange();
4209 if (Parens.isInvalid()) {
4210 // This was a variable declaration's initialization for which no initializer
4211 // was specified.
4212 assert(NewArgs.empty() &&
4213 "no parens or braces but have direct init with arguments?");
4214 return ExprEmpty();
4215 }
4216 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4217 Parens.getEnd());
4218}
4219
4220template<typename Derived>
4221bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4222 unsigned NumInputs,
4223 bool IsCall,
4224 SmallVectorImpl<Expr *> &Outputs,
4225 bool *ArgChanged) {
4226 for (unsigned I = 0; I != NumInputs; ++I) {
4227 // If requested, drop call arguments that need to be dropped.
4228 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4229 if (ArgChanged)
4230 *ArgChanged = true;
4231
4232 break;
4233 }
4234
4235 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4236 Expr *Pattern = Expansion->getPattern();
4237
4238 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4239 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4240 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4241
4242 // Determine whether the set of unexpanded parameter packs can and should
4243 // be expanded.
4244 bool Expand = true;
4245 bool RetainExpansion = false;
4246 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4247 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4248 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4249 Pattern->getSourceRange(),
4250 Unexpanded,
4251 Expand, RetainExpansion,
4252 NumExpansions))
4253 return true;
4254
4255 if (!Expand) {
4256 // The transform has determined that we should perform a simple
4257 // transformation on the pack expansion, producing another pack
4258 // expansion.
4259 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4260 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4261 if (OutPattern.isInvalid())
4262 return true;
4263
4264 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4265 Expansion->getEllipsisLoc(),
4266 NumExpansions);
4267 if (Out.isInvalid())
4268 return true;
4269
4270 if (ArgChanged)
4271 *ArgChanged = true;
4272 Outputs.push_back(Elt: Out.get());
4273 continue;
4274 }
4275
4276 // Record right away that the argument was changed. This needs
4277 // to happen even if the array expands to nothing.
4278 if (ArgChanged) *ArgChanged = true;
4279
4280 // The transform has determined that we should perform an elementwise
4281 // expansion of the pattern. Do so.
4282 for (unsigned I = 0; I != *NumExpansions; ++I) {
4283 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4284 ExprResult Out = getDerived().TransformExpr(Pattern);
4285 if (Out.isInvalid())
4286 return true;
4287
4288 if (Out.get()->containsUnexpandedParameterPack()) {
4289 Out = getDerived().RebuildPackExpansion(
4290 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4291 if (Out.isInvalid())
4292 return true;
4293 }
4294
4295 Outputs.push_back(Elt: Out.get());
4296 }
4297
4298 // If we're supposed to retain a pack expansion, do so by temporarily
4299 // forgetting the partially-substituted parameter pack.
4300 if (RetainExpansion) {
4301 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4302
4303 ExprResult Out = getDerived().TransformExpr(Pattern);
4304 if (Out.isInvalid())
4305 return true;
4306
4307 Out = getDerived().RebuildPackExpansion(
4308 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4309 if (Out.isInvalid())
4310 return true;
4311
4312 Outputs.push_back(Elt: Out.get());
4313 }
4314
4315 continue;
4316 }
4317
4318 ExprResult Result =
4319 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4320 : getDerived().TransformExpr(Inputs[I]);
4321 if (Result.isInvalid())
4322 return true;
4323
4324 if (Result.get() != Inputs[I] && ArgChanged)
4325 *ArgChanged = true;
4326
4327 Outputs.push_back(Elt: Result.get());
4328 }
4329
4330 return false;
4331}
4332
4333template <typename Derived>
4334Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4335 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4336 if (Var) {
4337 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4338 getDerived().TransformDefinition(Var->getLocation(), Var));
4339
4340 if (!ConditionVar)
4341 return Sema::ConditionError();
4342
4343 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4344 }
4345
4346 if (Expr) {
4347 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4348
4349 if (CondExpr.isInvalid())
4350 return Sema::ConditionError();
4351
4352 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4353 /*MissingOK=*/true);
4354 }
4355
4356 return Sema::ConditionResult();
4357}
4358
4359template <typename Derived>
4360NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4361 NestedNameSpecifierLoc NNS, QualType ObjectType,
4362 NamedDecl *FirstQualifierInScope) {
4363 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4364
4365 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4366 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4367 Qualifier = Qualifier.getPrefix())
4368 Qualifiers.push_back(Qualifier);
4369 };
4370 insertNNS(NNS);
4371
4372 CXXScopeSpec SS;
4373 while (!Qualifiers.empty()) {
4374 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4375 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4376
4377 switch (QNNS->getKind()) {
4378 case NestedNameSpecifier::Identifier: {
4379 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4380 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4381 ObjectType);
4382 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo, EnteringContext: false,
4383 SS, ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4384 return NestedNameSpecifierLoc();
4385 break;
4386 }
4387
4388 case NestedNameSpecifier::Namespace: {
4389 NamespaceDecl *NS =
4390 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4391 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4392 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4393 break;
4394 }
4395
4396 case NestedNameSpecifier::NamespaceAlias: {
4397 NamespaceAliasDecl *Alias =
4398 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4399 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4400 SS.Extend(Context&: SemaRef.Context, Alias, AliasLoc: Q.getLocalBeginLoc(),
4401 ColonColonLoc: Q.getLocalEndLoc());
4402 break;
4403 }
4404
4405 case NestedNameSpecifier::Global:
4406 // There is no meaningful transformation that one could perform on the
4407 // global scope.
4408 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4409 break;
4410
4411 case NestedNameSpecifier::Super: {
4412 CXXRecordDecl *RD =
4413 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4414 SourceLocation(), QNNS->getAsRecordDecl()));
4415 SS.MakeSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(), ColonColonLoc: Q.getEndLoc());
4416 break;
4417 }
4418
4419 case NestedNameSpecifier::TypeSpecWithTemplate:
4420 case NestedNameSpecifier::TypeSpec: {
4421 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4422 FirstQualifierInScope, SS);
4423
4424 if (!TL)
4425 return NestedNameSpecifierLoc();
4426
4427 QualType T = TL.getType();
4428 if (T->isDependentType() || T->isRecordType() ||
4429 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4430 if (T->isEnumeralType())
4431 SemaRef.Diag(TL.getBeginLoc(),
4432 diag::warn_cxx98_compat_enum_nested_name_spec);
4433
4434 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4435 SS.Adopt(Other: ETL.getQualifierLoc());
4436 TL = ETL.getNamedTypeLoc();
4437 }
4438
4439 SS.Extend(Context&: SemaRef.Context, TemplateKWLoc: TL.getTemplateKeywordLoc(), TL,
4440 ColonColonLoc: Q.getLocalEndLoc());
4441 break;
4442 }
4443 // If the nested-name-specifier is an invalid type def, don't emit an
4444 // error because a previous error should have already been emitted.
4445 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4446 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4447 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4448 << T << SS.getRange();
4449 }
4450 return NestedNameSpecifierLoc();
4451 }
4452 }
4453
4454 // The qualifier-in-scope and object type only apply to the leftmost entity.
4455 FirstQualifierInScope = nullptr;
4456 ObjectType = QualType();
4457 }
4458
4459 // Don't rebuild the nested-name-specifier if we don't have to.
4460 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4461 !getDerived().AlwaysRebuild())
4462 return NNS;
4463
4464 // If we can re-use the source-location data from the original
4465 // nested-name-specifier, do so.
4466 if (SS.location_size() == NNS.getDataLength() &&
4467 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4468 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4469
4470 // Allocate new nested-name-specifier location information.
4471 return SS.getWithLocInContext(Context&: SemaRef.Context);
4472}
4473
4474template<typename Derived>
4475DeclarationNameInfo
4476TreeTransform<Derived>
4477::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4478 DeclarationName Name = NameInfo.getName();
4479 if (!Name)
4480 return DeclarationNameInfo();
4481
4482 switch (Name.getNameKind()) {
4483 case DeclarationName::Identifier:
4484 case DeclarationName::ObjCZeroArgSelector:
4485 case DeclarationName::ObjCOneArgSelector:
4486 case DeclarationName::ObjCMultiArgSelector:
4487 case DeclarationName::CXXOperatorName:
4488 case DeclarationName::CXXLiteralOperatorName:
4489 case DeclarationName::CXXUsingDirective:
4490 return NameInfo;
4491
4492 case DeclarationName::CXXDeductionGuideName: {
4493 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4494 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4495 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4496 if (!NewTemplate)
4497 return DeclarationNameInfo();
4498
4499 DeclarationNameInfo NewNameInfo(NameInfo);
4500 NewNameInfo.setName(
4501 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4502 return NewNameInfo;
4503 }
4504
4505 case DeclarationName::CXXConstructorName:
4506 case DeclarationName::CXXDestructorName:
4507 case DeclarationName::CXXConversionFunctionName: {
4508 TypeSourceInfo *NewTInfo;
4509 CanQualType NewCanTy;
4510 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4511 NewTInfo = getDerived().TransformType(OldTInfo);
4512 if (!NewTInfo)
4513 return DeclarationNameInfo();
4514 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4515 }
4516 else {
4517 NewTInfo = nullptr;
4518 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4519 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4520 if (NewT.isNull())
4521 return DeclarationNameInfo();
4522 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4523 }
4524
4525 DeclarationName NewName
4526 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4527 Ty: NewCanTy);
4528 DeclarationNameInfo NewNameInfo(NameInfo);
4529 NewNameInfo.setName(NewName);
4530 NewNameInfo.setNamedTypeInfo(NewTInfo);
4531 return NewNameInfo;
4532 }
4533 }
4534
4535 llvm_unreachable("Unknown name kind.");
4536}
4537
4538template<typename Derived>
4539TemplateName
4540TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4541 TemplateName Name,
4542 SourceLocation NameLoc,
4543 QualType ObjectType,
4544 NamedDecl *FirstQualifierInScope,
4545 bool AllowInjectedClassName) {
4546 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4547 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4548 assert(Template && "qualified template name must refer to a template");
4549
4550 TemplateDecl *TransTemplate
4551 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4552 Template));
4553 if (!TransTemplate)
4554 return TemplateName();
4555
4556 if (!getDerived().AlwaysRebuild() &&
4557 SS.getScopeRep() == QTN->getQualifier() &&
4558 TransTemplate == Template)
4559 return Name;
4560
4561 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4562 TransTemplate);
4563 }
4564
4565 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4566 if (SS.getScopeRep()) {
4567 // These apply to the scope specifier, not the template.
4568 ObjectType = QualType();
4569 FirstQualifierInScope = nullptr;
4570 }
4571
4572 if (!getDerived().AlwaysRebuild() &&
4573 SS.getScopeRep() == DTN->getQualifier() &&
4574 ObjectType.isNull())
4575 return Name;
4576
4577 // FIXME: Preserve the location of the "template" keyword.
4578 SourceLocation TemplateKWLoc = NameLoc;
4579
4580 if (DTN->isIdentifier()) {
4581 return getDerived().RebuildTemplateName(SS,
4582 TemplateKWLoc,
4583 *DTN->getIdentifier(),
4584 NameLoc,
4585 ObjectType,
4586 FirstQualifierInScope,
4587 AllowInjectedClassName);
4588 }
4589
4590 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4591 DTN->getOperator(), NameLoc,
4592 ObjectType, AllowInjectedClassName);
4593 }
4594
4595 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4596 TemplateDecl *TransTemplate
4597 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4598 Template));
4599 if (!TransTemplate)
4600 return TemplateName();
4601
4602 if (!getDerived().AlwaysRebuild() &&
4603 TransTemplate == Template)
4604 return Name;
4605
4606 return TemplateName(TransTemplate);
4607 }
4608
4609 if (SubstTemplateTemplateParmPackStorage *SubstPack
4610 = Name.getAsSubstTemplateTemplateParmPack()) {
4611 return getDerived().RebuildTemplateName(
4612 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4613 SubstPack->getIndex(), SubstPack->getFinal());
4614 }
4615
4616 // These should be getting filtered out before they reach the AST.
4617 llvm_unreachable("overloaded function decl survived to here");
4618}
4619
4620template<typename Derived>
4621void TreeTransform<Derived>::InventTemplateArgumentLoc(
4622 const TemplateArgument &Arg,
4623 TemplateArgumentLoc &Output) {
4624 Output = getSema().getTrivialTemplateArgumentLoc(
4625 Arg, QualType(), getDerived().getBaseLocation());
4626}
4627
4628template <typename Derived>
4629bool TreeTransform<Derived>::TransformTemplateArgument(
4630 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4631 bool Uneval) {
4632 const TemplateArgument &Arg = Input.getArgument();
4633 switch (Arg.getKind()) {
4634 case TemplateArgument::Null:
4635 case TemplateArgument::Pack:
4636 llvm_unreachable("Unexpected TemplateArgument");
4637
4638 case TemplateArgument::Integral:
4639 case TemplateArgument::NullPtr:
4640 case TemplateArgument::Declaration:
4641 case TemplateArgument::StructuralValue: {
4642 // Transform a resolved template argument straight to a resolved template
4643 // argument. We get here when substituting into an already-substituted
4644 // template type argument during concept satisfaction checking.
4645 QualType T = Arg.getNonTypeTemplateArgumentType();
4646 QualType NewT = getDerived().TransformType(T);
4647 if (NewT.isNull())
4648 return true;
4649
4650 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4651 ? Arg.getAsDecl()
4652 : nullptr;
4653 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4654 getDerived().getBaseLocation(), D))
4655 : nullptr;
4656 if (D && !NewD)
4657 return true;
4658
4659 if (NewT == T && D == NewD)
4660 Output = Input;
4661 else if (Arg.getKind() == TemplateArgument::Integral)
4662 Output = TemplateArgumentLoc(
4663 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4664 TemplateArgumentLocInfo());
4665 else if (Arg.getKind() == TemplateArgument::NullPtr)
4666 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4667 TemplateArgumentLocInfo());
4668 else if (Arg.getKind() == TemplateArgument::Declaration)
4669 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4670 TemplateArgumentLocInfo());
4671 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4672 Output = TemplateArgumentLoc(
4673 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4674 TemplateArgumentLocInfo());
4675 else
4676 llvm_unreachable("unexpected template argument kind");
4677
4678 return false;
4679 }
4680
4681 case TemplateArgument::Type: {
4682 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4683 if (!DI)
4684 DI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
4685
4686 DI = getDerived().TransformType(DI);
4687 if (!DI)
4688 return true;
4689
4690 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4691 return false;
4692 }
4693
4694 case TemplateArgument::Template: {
4695 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4696 if (QualifierLoc) {
4697 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4698 if (!QualifierLoc)
4699 return true;
4700 }
4701
4702 CXXScopeSpec SS;
4703 SS.Adopt(Other: QualifierLoc);
4704 TemplateName Template = getDerived().TransformTemplateName(
4705 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4706 if (Template.isNull())
4707 return true;
4708
4709 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4710 QualifierLoc, Input.getTemplateNameLoc());
4711 return false;
4712 }
4713
4714 case TemplateArgument::TemplateExpansion:
4715 llvm_unreachable("Caller should expand pack expansions");
4716
4717 case TemplateArgument::Expression: {
4718 // Template argument expressions are constant expressions.
4719 EnterExpressionEvaluationContext Unevaluated(
4720 getSema(),
4721 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4722 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4723 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4724 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4725
4726 Expr *InputExpr = Input.getSourceExpression();
4727 if (!InputExpr)
4728 InputExpr = Input.getArgument().getAsExpr();
4729
4730 ExprResult E = getDerived().TransformExpr(InputExpr);
4731 E = SemaRef.ActOnConstantExpression(Res: E);
4732 if (E.isInvalid())
4733 return true;
4734 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4735 return false;
4736 }
4737 }
4738
4739 // Work around bogus GCC warning
4740 return true;
4741}
4742
4743/// Iterator adaptor that invents template argument location information
4744/// for each of the template arguments in its underlying iterator.
4745template<typename Derived, typename InputIterator>
4746class TemplateArgumentLocInventIterator {
4747 TreeTransform<Derived> &Self;
4748 InputIterator Iter;
4749
4750public:
4751 typedef TemplateArgumentLoc value_type;
4752 typedef TemplateArgumentLoc reference;
4753 typedef typename std::iterator_traits<InputIterator>::difference_type
4754 difference_type;
4755 typedef std::input_iterator_tag iterator_category;
4756
4757 class pointer {
4758 TemplateArgumentLoc Arg;
4759
4760 public:
4761 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4762
4763 const TemplateArgumentLoc *operator->() const { return &Arg; }
4764 };
4765
4766 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4767 InputIterator Iter)
4768 : Self(Self), Iter(Iter) { }
4769
4770 TemplateArgumentLocInventIterator &operator++() {
4771 ++Iter;
4772 return *this;
4773 }
4774
4775 TemplateArgumentLocInventIterator operator++(int) {
4776 TemplateArgumentLocInventIterator Old(*this);
4777 ++(*this);
4778 return Old;
4779 }
4780
4781 reference operator*() const {
4782 TemplateArgumentLoc Result;
4783 Self.InventTemplateArgumentLoc(*Iter, Result);
4784 return Result;
4785 }
4786
4787 pointer operator->() const { return pointer(**this); }
4788
4789 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4790 const TemplateArgumentLocInventIterator &Y) {
4791 return X.Iter == Y.Iter;
4792 }
4793
4794 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4795 const TemplateArgumentLocInventIterator &Y) {
4796 return X.Iter != Y.Iter;
4797 }
4798};
4799
4800template<typename Derived>
4801template<typename InputIterator>
4802bool TreeTransform<Derived>::TransformTemplateArguments(
4803 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4804 bool Uneval) {
4805 for (; First != Last; ++First) {
4806 TemplateArgumentLoc Out;
4807 TemplateArgumentLoc In = *First;
4808
4809 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4810 // When building the deduction guides, we rewrite the argument packs
4811 // instead of unpacking.
4812 if (getSema().CodeSynthesisContexts.back().Kind ==
4813 Sema::CodeSynthesisContext::BuildingDeductionGuides) {
4814 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4815 return true;
4816 continue;
4817 }
4818 // Unpack argument packs, which we translate them into separate
4819 // arguments.
4820 // FIXME: We could do much better if we could guarantee that the
4821 // TemplateArgumentLocInfo for the pack expansion would be usable for
4822 // all of the template arguments in the argument pack.
4823 typedef TemplateArgumentLocInventIterator<Derived,
4824 TemplateArgument::pack_iterator>
4825 PackLocIterator;
4826 if (TransformTemplateArguments(PackLocIterator(*this,
4827 In.getArgument().pack_begin()),
4828 PackLocIterator(*this,
4829 In.getArgument().pack_end()),
4830 Outputs, Uneval))
4831 return true;
4832
4833 continue;
4834 }
4835
4836 if (In.getArgument().isPackExpansion()) {
4837 // We have a pack expansion, for which we will be substituting into
4838 // the pattern.
4839 SourceLocation Ellipsis;
4840 std::optional<unsigned> OrigNumExpansions;
4841 TemplateArgumentLoc Pattern
4842 = getSema().getTemplateArgumentPackExpansionPattern(
4843 In, Ellipsis, OrigNumExpansions);
4844
4845 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4846 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4847 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4848
4849 // Determine whether the set of unexpanded parameter packs can and should
4850 // be expanded.
4851 bool Expand = true;
4852 bool RetainExpansion = false;
4853 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4854 if (getDerived().TryExpandParameterPacks(Ellipsis,
4855 Pattern.getSourceRange(),
4856 Unexpanded,
4857 Expand,
4858 RetainExpansion,
4859 NumExpansions))
4860 return true;
4861
4862 if (!Expand) {
4863 // The transform has determined that we should perform a simple
4864 // transformation on the pack expansion, producing another pack
4865 // expansion.
4866 TemplateArgumentLoc OutPattern;
4867 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4868 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4869 return true;
4870
4871 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4872 NumExpansions);
4873 if (Out.getArgument().isNull())
4874 return true;
4875
4876 Outputs.addArgument(Loc: Out);
4877 continue;
4878 }
4879
4880 // The transform has determined that we should perform an elementwise
4881 // expansion of the pattern. Do so.
4882 for (unsigned I = 0; I != *NumExpansions; ++I) {
4883 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4884
4885 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4886 return true;
4887
4888 if (Out.getArgument().containsUnexpandedParameterPack()) {
4889 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4890 OrigNumExpansions);
4891 if (Out.getArgument().isNull())
4892 return true;
4893 }
4894
4895 Outputs.addArgument(Loc: Out);
4896 }
4897
4898 // If we're supposed to retain a pack expansion, do so by temporarily
4899 // forgetting the partially-substituted parameter pack.
4900 if (RetainExpansion) {
4901 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4902
4903 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4904 return true;
4905
4906 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4907 OrigNumExpansions);
4908 if (Out.getArgument().isNull())
4909 return true;
4910
4911 Outputs.addArgument(Loc: Out);
4912 }
4913
4914 continue;
4915 }
4916
4917 // The simple case:
4918 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4919 return true;
4920
4921 Outputs.addArgument(Loc: Out);
4922 }
4923
4924 return false;
4925
4926}
4927
4928//===----------------------------------------------------------------------===//
4929// Type transformation
4930//===----------------------------------------------------------------------===//
4931
4932template<typename Derived>
4933QualType TreeTransform<Derived>::TransformType(QualType T) {
4934 if (getDerived().AlreadyTransformed(T))
4935 return T;
4936
4937 // Temporary workaround. All of these transformations should
4938 // eventually turn into transformations on TypeLocs.
4939 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4940 getDerived().getBaseLocation());
4941
4942 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4943
4944 if (!NewDI)
4945 return QualType();
4946
4947 return NewDI->getType();
4948}
4949
4950template<typename Derived>
4951TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4952 // Refine the base location to the type's location.
4953 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4954 getDerived().getBaseEntity());
4955 if (getDerived().AlreadyTransformed(DI->getType()))
4956 return DI;
4957
4958 TypeLocBuilder TLB;
4959
4960 TypeLoc TL = DI->getTypeLoc();
4961 TLB.reserve(Requested: TL.getFullDataSize());
4962
4963 QualType Result = getDerived().TransformType(TLB, TL);
4964 if (Result.isNull())
4965 return nullptr;
4966
4967 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
4968}
4969
4970template<typename Derived>
4971QualType
4972TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4973 switch (T.getTypeLocClass()) {
4974#define ABSTRACT_TYPELOC(CLASS, PARENT)
4975#define TYPELOC(CLASS, PARENT) \
4976 case TypeLoc::CLASS: \
4977 return getDerived().Transform##CLASS##Type(TLB, \
4978 T.castAs<CLASS##TypeLoc>());
4979#include "clang/AST/TypeLocNodes.def"
4980 }
4981
4982 llvm_unreachable("unhandled type loc!");
4983}
4984
4985template<typename Derived>
4986QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
4987 if (!isa<DependentNameType>(T))
4988 return TransformType(T);
4989
4990 if (getDerived().AlreadyTransformed(T))
4991 return T;
4992 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4993 getDerived().getBaseLocation());
4994 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4995 return NewDI ? NewDI->getType() : QualType();
4996}
4997
4998template<typename Derived>
4999TypeSourceInfo *
5000TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5001 if (!isa<DependentNameType>(DI->getType()))
5002 return TransformType(DI);
5003
5004 // Refine the base location to the type's location.
5005 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5006 getDerived().getBaseEntity());
5007 if (getDerived().AlreadyTransformed(DI->getType()))
5008 return DI;
5009
5010 TypeLocBuilder TLB;
5011
5012 TypeLoc TL = DI->getTypeLoc();
5013 TLB.reserve(Requested: TL.getFullDataSize());
5014
5015 auto QTL = TL.getAs<QualifiedTypeLoc>();
5016 if (QTL)
5017 TL = QTL.getUnqualifiedLoc();
5018
5019 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5020
5021 QualType Result = getDerived().TransformDependentNameType(
5022 TLB, DNTL, /*DeducedTSTContext*/true);
5023 if (Result.isNull())
5024 return nullptr;
5025
5026 if (QTL) {
5027 Result = getDerived().RebuildQualifiedType(Result, QTL);
5028 if (Result.isNull())
5029 return nullptr;
5030 TLB.TypeWasModifiedSafely(T: Result);
5031 }
5032
5033 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5034}
5035
5036template<typename Derived>
5037QualType
5038TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5039 QualifiedTypeLoc T) {
5040 QualType Result;
5041 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5042 auto SuppressObjCLifetime =
5043 T.getType().getLocalQualifiers().hasObjCLifetime();
5044 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5045 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5046 SuppressObjCLifetime);
5047 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5048 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5049 TLB, STTP, SuppressObjCLifetime);
5050 } else {
5051 Result = getDerived().TransformType(TLB, UnqualTL);
5052 }
5053
5054 if (Result.isNull())
5055 return QualType();
5056
5057 Result = getDerived().RebuildQualifiedType(Result, T);
5058
5059 if (Result.isNull())
5060 return QualType();
5061
5062 // RebuildQualifiedType might have updated the type, but not in a way
5063 // that invalidates the TypeLoc. (There's no location information for
5064 // qualifiers.)
5065 TLB.TypeWasModifiedSafely(T: Result);
5066
5067 return Result;
5068}
5069
5070template <typename Derived>
5071QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5072 QualifiedTypeLoc TL) {
5073
5074 SourceLocation Loc = TL.getBeginLoc();
5075 Qualifiers Quals = TL.getType().getLocalQualifiers();
5076
5077 if ((T.getAddressSpace() != LangAS::Default &&
5078 Quals.getAddressSpace() != LangAS::Default) &&
5079 T.getAddressSpace() != Quals.getAddressSpace()) {
5080 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5081 << TL.getType() << T;
5082 return QualType();
5083 }
5084
5085 // C++ [dcl.fct]p7:
5086 // [When] adding cv-qualifications on top of the function type [...] the
5087 // cv-qualifiers are ignored.
5088 if (T->isFunctionType()) {
5089 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5090 AddressSpace: Quals.getAddressSpace());
5091 return T;
5092 }
5093
5094 // C++ [dcl.ref]p1:
5095 // when the cv-qualifiers are introduced through the use of a typedef-name
5096 // or decltype-specifier [...] the cv-qualifiers are ignored.
5097 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5098 // applied to a reference type.
5099 if (T->isReferenceType()) {
5100 // The only qualifier that applies to a reference type is restrict.
5101 if (!Quals.hasRestrict())
5102 return T;
5103 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5104 }
5105
5106 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5107 // resulting type.
5108 if (Quals.hasObjCLifetime()) {
5109 if (!T->isObjCLifetimeType() && !T->isDependentType())
5110 Quals.removeObjCLifetime();
5111 else if (T.getObjCLifetime()) {
5112 // Objective-C ARC:
5113 // A lifetime qualifier applied to a substituted template parameter
5114 // overrides the lifetime qualifier from the template argument.
5115 const AutoType *AutoTy;
5116 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5117 // 'auto' types behave the same way as template parameters.
5118 QualType Deduced = AutoTy->getDeducedType();
5119 Qualifiers Qs = Deduced.getQualifiers();
5120 Qs.removeObjCLifetime();
5121 Deduced =
5122 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5123 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5124 IsDependent: AutoTy->isDependentType(),
5125 /*isPack=*/IsPack: false,
5126 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5127 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5128 } else {
5129 // Otherwise, complain about the addition of a qualifier to an
5130 // already-qualified type.
5131 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5132 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5133 Quals.removeObjCLifetime();
5134 }
5135 }
5136 }
5137
5138 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5139}
5140
5141template<typename Derived>
5142TypeLoc
5143TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5144 QualType ObjectType,
5145 NamedDecl *UnqualLookup,
5146 CXXScopeSpec &SS) {
5147 if (getDerived().AlreadyTransformed(TL.getType()))
5148 return TL;
5149
5150 TypeSourceInfo *TSI =
5151 TransformTSIInObjectScope(TL, ObjectType, FirstQualifierInScope: UnqualLookup, SS);
5152 if (TSI)
5153 return TSI->getTypeLoc();
5154 return TypeLoc();
5155}
5156
5157template<typename Derived>
5158TypeSourceInfo *
5159TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5160 QualType ObjectType,
5161 NamedDecl *UnqualLookup,
5162 CXXScopeSpec &SS) {
5163 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5164 return TSInfo;
5165
5166 return TransformTSIInObjectScope(TL: TSInfo->getTypeLoc(), ObjectType,
5167 FirstQualifierInScope: UnqualLookup, SS);
5168}
5169
5170template <typename Derived>
5171TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5172 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5173 CXXScopeSpec &SS) {
5174 QualType T = TL.getType();
5175 assert(!getDerived().AlreadyTransformed(T));
5176
5177 TypeLocBuilder TLB;
5178 QualType Result;
5179
5180 if (isa<TemplateSpecializationType>(T)) {
5181 TemplateSpecializationTypeLoc SpecTL =
5182 TL.castAs<TemplateSpecializationTypeLoc>();
5183
5184 TemplateName Template = getDerived().TransformTemplateName(
5185 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5186 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5187 if (Template.isNull())
5188 return nullptr;
5189
5190 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5191 Template);
5192 } else if (isa<DependentTemplateSpecializationType>(T)) {
5193 DependentTemplateSpecializationTypeLoc SpecTL =
5194 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5195
5196 TemplateName Template
5197 = getDerived().RebuildTemplateName(SS,
5198 SpecTL.getTemplateKeywordLoc(),
5199 *SpecTL.getTypePtr()->getIdentifier(),
5200 SpecTL.getTemplateNameLoc(),
5201 ObjectType, UnqualLookup,
5202 /*AllowInjectedClassName*/true);
5203 if (Template.isNull())
5204 return nullptr;
5205
5206 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5207 SpecTL,
5208 Template,
5209 SS);
5210 } else {
5211 // Nothing special needs to be done for these.
5212 Result = getDerived().TransformType(TLB, TL);
5213 }
5214
5215 if (Result.isNull())
5216 return nullptr;
5217
5218 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5219}
5220
5221template <class TyLoc> static inline
5222QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5223 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5224 NewT.setNameLoc(T.getNameLoc());
5225 return T.getType();
5226}
5227
5228template<typename Derived>
5229QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5230 BuiltinTypeLoc T) {
5231 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5232 NewT.setBuiltinLoc(T.getBuiltinLoc());
5233 if (T.needsExtraLocalData())
5234 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5235 return T.getType();
5236}
5237
5238template<typename Derived>
5239QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5240 ComplexTypeLoc T) {
5241 // FIXME: recurse?
5242 return TransformTypeSpecType(TLB, T);
5243}
5244
5245template <typename Derived>
5246QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5247 AdjustedTypeLoc TL) {
5248 // Adjustments applied during transformation are handled elsewhere.
5249 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5250}
5251
5252template<typename Derived>
5253QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5254 DecayedTypeLoc TL) {
5255 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5256 if (OriginalType.isNull())
5257 return QualType();
5258
5259 QualType Result = TL.getType();
5260 if (getDerived().AlwaysRebuild() ||
5261 OriginalType != TL.getOriginalLoc().getType())
5262 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5263 TLB.push<DecayedTypeLoc>(Result);
5264 // Nothing to set for DecayedTypeLoc.
5265 return Result;
5266}
5267
5268template <typename Derived>
5269QualType
5270TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5271 ArrayParameterTypeLoc TL) {
5272 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5273 if (OriginalType.isNull())
5274 return QualType();
5275
5276 QualType Result = TL.getType();
5277 if (getDerived().AlwaysRebuild() ||
5278 OriginalType != TL.getElementLoc().getType())
5279 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5280 TLB.push<ArrayParameterTypeLoc>(Result);
5281 // Nothing to set for ArrayParameterTypeLoc.
5282 return Result;
5283}
5284
5285template<typename Derived>
5286QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5287 PointerTypeLoc TL) {
5288 QualType PointeeType
5289 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5290 if (PointeeType.isNull())
5291 return QualType();
5292
5293 QualType Result = TL.getType();
5294 if (PointeeType->getAs<ObjCObjectType>()) {
5295 // A dependent pointer type 'T *' has is being transformed such
5296 // that an Objective-C class type is being replaced for 'T'. The
5297 // resulting pointer type is an ObjCObjectPointerType, not a
5298 // PointerType.
5299 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5300
5301 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5302 NewT.setStarLoc(TL.getStarLoc());
5303 return Result;
5304 }
5305
5306 if (getDerived().AlwaysRebuild() ||
5307 PointeeType != TL.getPointeeLoc().getType()) {
5308 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5309 if (Result.isNull())
5310 return QualType();
5311 }
5312
5313 // Objective-C ARC can add lifetime qualifiers to the type that we're
5314 // pointing to.
5315 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5316
5317 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5318 NewT.setSigilLoc(TL.getSigilLoc());
5319 return Result;
5320}
5321
5322template<typename Derived>
5323QualType
5324TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5325 BlockPointerTypeLoc TL) {
5326 QualType PointeeType
5327 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5328 if (PointeeType.isNull())
5329 return QualType();
5330
5331 QualType Result = TL.getType();
5332 if (getDerived().AlwaysRebuild() ||
5333 PointeeType != TL.getPointeeLoc().getType()) {
5334 Result = getDerived().RebuildBlockPointerType(PointeeType,
5335 TL.getSigilLoc());
5336 if (Result.isNull())
5337 return QualType();
5338 }
5339
5340 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5341 NewT.setSigilLoc(TL.getSigilLoc());
5342 return Result;
5343}
5344
5345/// Transforms a reference type. Note that somewhat paradoxically we
5346/// don't care whether the type itself is an l-value type or an r-value
5347/// type; we only care if the type was *written* as an l-value type
5348/// or an r-value type.
5349template<typename Derived>
5350QualType
5351TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5352 ReferenceTypeLoc TL) {
5353 const ReferenceType *T = TL.getTypePtr();
5354
5355 // Note that this works with the pointee-as-written.
5356 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5357 if (PointeeType.isNull())
5358 return QualType();
5359
5360 QualType Result = TL.getType();
5361 if (getDerived().AlwaysRebuild() ||
5362 PointeeType != T->getPointeeTypeAsWritten()) {
5363 Result = getDerived().RebuildReferenceType(PointeeType,
5364 T->isSpelledAsLValue(),
5365 TL.getSigilLoc());
5366 if (Result.isNull())
5367 return QualType();
5368 }
5369
5370 // Objective-C ARC can add lifetime qualifiers to the type that we're
5371 // referring to.
5372 TLB.TypeWasModifiedSafely(
5373 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5374
5375 // r-value references can be rebuilt as l-value references.
5376 ReferenceTypeLoc NewTL;
5377 if (isa<LValueReferenceType>(Result))
5378 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5379 else
5380 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5381 NewTL.setSigilLoc(TL.getSigilLoc());
5382
5383 return Result;
5384}
5385
5386template<typename Derived>
5387QualType
5388TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5389 LValueReferenceTypeLoc TL) {
5390 return TransformReferenceType(TLB, TL);
5391}
5392
5393template<typename Derived>
5394QualType
5395TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5396 RValueReferenceTypeLoc TL) {
5397 return TransformReferenceType(TLB, TL);
5398}
5399
5400template<typename Derived>
5401QualType
5402TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5403 MemberPointerTypeLoc TL) {
5404 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5405 if (PointeeType.isNull())
5406 return QualType();
5407
5408 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5409 TypeSourceInfo *NewClsTInfo = nullptr;
5410 if (OldClsTInfo) {
5411 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5412 if (!NewClsTInfo)
5413 return QualType();
5414 }
5415
5416 const MemberPointerType *T = TL.getTypePtr();
5417 QualType OldClsType = QualType(T->getClass(), 0);
5418 QualType NewClsType;
5419 if (NewClsTInfo)
5420 NewClsType = NewClsTInfo->getType();
5421 else {
5422 NewClsType = getDerived().TransformType(OldClsType);
5423 if (NewClsType.isNull())
5424 return QualType();
5425 }
5426
5427 QualType Result = TL.getType();
5428 if (getDerived().AlwaysRebuild() ||
5429 PointeeType != T->getPointeeType() ||
5430 NewClsType != OldClsType) {
5431 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5432 TL.getStarLoc());
5433 if (Result.isNull())
5434 return QualType();
5435 }
5436
5437 // If we had to adjust the pointee type when building a member pointer, make
5438 // sure to push TypeLoc info for it.
5439 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5440 if (MPT && PointeeType != MPT->getPointeeType()) {
5441 assert(isa<AdjustedType>(MPT->getPointeeType()));
5442 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5443 }
5444
5445 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5446 NewTL.setSigilLoc(TL.getSigilLoc());
5447 NewTL.setClassTInfo(NewClsTInfo);
5448
5449 return Result;
5450}
5451
5452template<typename Derived>
5453QualType
5454TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5455 ConstantArrayTypeLoc TL) {
5456 const ConstantArrayType *T = TL.getTypePtr();
5457 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5458 if (ElementType.isNull())
5459 return QualType();
5460
5461 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5462 Expr *OldSize = TL.getSizeExpr();
5463 if (!OldSize)
5464 OldSize = const_cast<Expr*>(T->getSizeExpr());
5465 Expr *NewSize = nullptr;
5466 if (OldSize) {
5467 EnterExpressionEvaluationContext Unevaluated(
5468 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5469 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5470 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5471 }
5472
5473 QualType Result = TL.getType();
5474 if (getDerived().AlwaysRebuild() ||
5475 ElementType != T->getElementType() ||
5476 (T->getSizeExpr() && NewSize != OldSize)) {
5477 Result = getDerived().RebuildConstantArrayType(ElementType,
5478 T->getSizeModifier(),
5479 T->getSize(), NewSize,
5480 T->getIndexTypeCVRQualifiers(),
5481 TL.getBracketsRange());
5482 if (Result.isNull())
5483 return QualType();
5484 }
5485
5486 // We might have either a ConstantArrayType or a VariableArrayType now:
5487 // a ConstantArrayType is allowed to have an element type which is a
5488 // VariableArrayType if the type is dependent. Fortunately, all array
5489 // types have the same location layout.
5490 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5491 NewTL.setLBracketLoc(TL.getLBracketLoc());
5492 NewTL.setRBracketLoc(TL.getRBracketLoc());
5493 NewTL.setSizeExpr(NewSize);
5494
5495 return Result;
5496}
5497
5498template<typename Derived>
5499QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5500 TypeLocBuilder &TLB,
5501 IncompleteArrayTypeLoc TL) {
5502 const IncompleteArrayType *T = TL.getTypePtr();
5503 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5504 if (ElementType.isNull())
5505 return QualType();
5506
5507 QualType Result = TL.getType();
5508 if (getDerived().AlwaysRebuild() ||
5509 ElementType != T->getElementType()) {
5510 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5511 T->getSizeModifier(),
5512 T->getIndexTypeCVRQualifiers(),
5513 TL.getBracketsRange());
5514 if (Result.isNull())
5515 return QualType();
5516 }
5517
5518 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5519 NewTL.setLBracketLoc(TL.getLBracketLoc());
5520 NewTL.setRBracketLoc(TL.getRBracketLoc());
5521 NewTL.setSizeExpr(nullptr);
5522
5523 return Result;
5524}
5525
5526template<typename Derived>
5527QualType
5528TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5529 VariableArrayTypeLoc TL) {
5530 const VariableArrayType *T = TL.getTypePtr();
5531 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5532 if (ElementType.isNull())
5533 return QualType();
5534
5535 ExprResult SizeResult;
5536 {
5537 EnterExpressionEvaluationContext Context(
5538 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5539 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5540 }
5541 if (SizeResult.isInvalid())
5542 return QualType();
5543 SizeResult =
5544 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5545 if (SizeResult.isInvalid())
5546 return QualType();
5547
5548 Expr *Size = SizeResult.get();
5549
5550 QualType Result = TL.getType();
5551 if (getDerived().AlwaysRebuild() ||
5552 ElementType != T->getElementType() ||
5553 Size != T->getSizeExpr()) {
5554 Result = getDerived().RebuildVariableArrayType(ElementType,
5555 T->getSizeModifier(),
5556 Size,
5557 T->getIndexTypeCVRQualifiers(),
5558 TL.getBracketsRange());
5559 if (Result.isNull())
5560 return QualType();
5561 }
5562
5563 // We might have constant size array now, but fortunately it has the same
5564 // location layout.
5565 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5566 NewTL.setLBracketLoc(TL.getLBracketLoc());
5567 NewTL.setRBracketLoc(TL.getRBracketLoc());
5568 NewTL.setSizeExpr(Size);
5569
5570 return Result;
5571}
5572
5573template<typename Derived>
5574QualType
5575TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5576 DependentSizedArrayTypeLoc TL) {
5577 const DependentSizedArrayType *T = TL.getTypePtr();
5578 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5579 if (ElementType.isNull())
5580 return QualType();
5581
5582 // Array bounds are constant expressions.
5583 EnterExpressionEvaluationContext Unevaluated(
5584 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5585
5586 // If we have a VLA then it won't be a constant.
5587 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5588
5589 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5590 Expr *origSize = TL.getSizeExpr();
5591 if (!origSize) origSize = T->getSizeExpr();
5592
5593 ExprResult sizeResult
5594 = getDerived().TransformExpr(origSize);
5595 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
5596 if (sizeResult.isInvalid())
5597 return QualType();
5598
5599 Expr *size = sizeResult.get();
5600
5601 QualType Result = TL.getType();
5602 if (getDerived().AlwaysRebuild() ||
5603 ElementType != T->getElementType() ||
5604 size != origSize) {
5605 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5606 T->getSizeModifier(),
5607 size,
5608 T->getIndexTypeCVRQualifiers(),
5609 TL.getBracketsRange());
5610 if (Result.isNull())
5611 return QualType();
5612 }
5613
5614 // We might have any sort of array type now, but fortunately they
5615 // all have the same location layout.
5616 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5617 NewTL.setLBracketLoc(TL.getLBracketLoc());
5618 NewTL.setRBracketLoc(TL.getRBracketLoc());
5619 NewTL.setSizeExpr(size);
5620
5621 return Result;
5622}
5623
5624template <typename Derived>
5625QualType TreeTransform<Derived>::TransformDependentVectorType(
5626 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5627 const DependentVectorType *T = TL.getTypePtr();
5628 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5629 if (ElementType.isNull())
5630 return QualType();
5631
5632 EnterExpressionEvaluationContext Unevaluated(
5633 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5634
5635 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5636 Size = SemaRef.ActOnConstantExpression(Res: Size);
5637 if (Size.isInvalid())
5638 return QualType();
5639
5640 QualType Result = TL.getType();
5641 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5642 Size.get() != T->getSizeExpr()) {
5643 Result = getDerived().RebuildDependentVectorType(
5644 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5645 if (Result.isNull())
5646 return QualType();
5647 }
5648
5649 // Result might be dependent or not.
5650 if (isa<DependentVectorType>(Result)) {
5651 DependentVectorTypeLoc NewTL =
5652 TLB.push<DependentVectorTypeLoc>(Result);
5653 NewTL.setNameLoc(TL.getNameLoc());
5654 } else {
5655 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5656 NewTL.setNameLoc(TL.getNameLoc());
5657 }
5658
5659 return Result;
5660}
5661
5662template<typename Derived>
5663QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5664 TypeLocBuilder &TLB,
5665 DependentSizedExtVectorTypeLoc TL) {
5666 const DependentSizedExtVectorType *T = TL.getTypePtr();
5667
5668 // FIXME: ext vector locs should be nested
5669 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5670 if (ElementType.isNull())
5671 return QualType();
5672
5673 // Vector sizes are constant expressions.
5674 EnterExpressionEvaluationContext Unevaluated(
5675 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5676
5677 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5678 Size = SemaRef.ActOnConstantExpression(Res: Size);
5679 if (Size.isInvalid())
5680 return QualType();
5681
5682 QualType Result = TL.getType();
5683 if (getDerived().AlwaysRebuild() ||
5684 ElementType != T->getElementType() ||
5685 Size.get() != T->getSizeExpr()) {
5686 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5687 Size.get(),
5688 T->getAttributeLoc());
5689 if (Result.isNull())
5690 return QualType();
5691 }
5692
5693 // Result might be dependent or not.
5694 if (isa<DependentSizedExtVectorType>(Result)) {
5695 DependentSizedExtVectorTypeLoc NewTL
5696 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5697 NewTL.setNameLoc(TL.getNameLoc());
5698 } else {
5699 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5700 NewTL.setNameLoc(TL.getNameLoc());
5701 }
5702
5703 return Result;
5704}
5705
5706template <typename Derived>
5707QualType
5708TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5709 ConstantMatrixTypeLoc TL) {
5710 const ConstantMatrixType *T = TL.getTypePtr();
5711 QualType ElementType = getDerived().TransformType(T->getElementType());
5712 if (ElementType.isNull())
5713 return QualType();
5714
5715 QualType Result = TL.getType();
5716 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5717 Result = getDerived().RebuildConstantMatrixType(
5718 ElementType, T->getNumRows(), T->getNumColumns());
5719 if (Result.isNull())
5720 return QualType();
5721 }
5722
5723 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5724 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5725 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5726 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5727 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5728
5729 return Result;
5730}
5731
5732template <typename Derived>
5733QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5734 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5735 const DependentSizedMatrixType *T = TL.getTypePtr();
5736
5737 QualType ElementType = getDerived().TransformType(T->getElementType());
5738 if (ElementType.isNull()) {
5739 return QualType();
5740 }
5741
5742 // Matrix dimensions are constant expressions.
5743 EnterExpressionEvaluationContext Unevaluated(
5744 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5745
5746 Expr *origRows = TL.getAttrRowOperand();
5747 if (!origRows)
5748 origRows = T->getRowExpr();
5749 Expr *origColumns = TL.getAttrColumnOperand();
5750 if (!origColumns)
5751 origColumns = T->getColumnExpr();
5752
5753 ExprResult rowResult = getDerived().TransformExpr(origRows);
5754 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
5755 if (rowResult.isInvalid())
5756 return QualType();
5757
5758 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5759 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
5760 if (columnResult.isInvalid())
5761 return QualType();
5762
5763 Expr *rows = rowResult.get();
5764 Expr *columns = columnResult.get();
5765
5766 QualType Result = TL.getType();
5767 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5768 rows != origRows || columns != origColumns) {
5769 Result = getDerived().RebuildDependentSizedMatrixType(
5770 ElementType, rows, columns, T->getAttributeLoc());
5771
5772 if (Result.isNull())
5773 return QualType();
5774 }
5775
5776 // We might have any sort of matrix type now, but fortunately they
5777 // all have the same location layout.
5778 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5779 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5780 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5781 NewTL.setAttrRowOperand(rows);
5782 NewTL.setAttrColumnOperand(columns);
5783 return Result;
5784}
5785
5786template <typename Derived>
5787QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5788 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5789 const DependentAddressSpaceType *T = TL.getTypePtr();
5790
5791 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5792
5793 if (pointeeType.isNull())
5794 return QualType();
5795
5796 // Address spaces are constant expressions.
5797 EnterExpressionEvaluationContext Unevaluated(
5798 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5799
5800 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5801 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
5802 if (AddrSpace.isInvalid())
5803 return QualType();
5804
5805 QualType Result = TL.getType();
5806 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5807 AddrSpace.get() != T->getAddrSpaceExpr()) {
5808 Result = getDerived().RebuildDependentAddressSpaceType(
5809 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5810 if (Result.isNull())
5811 return QualType();
5812 }
5813
5814 // Result might be dependent or not.
5815 if (isa<DependentAddressSpaceType>(Result)) {
5816 DependentAddressSpaceTypeLoc NewTL =
5817 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5818
5819 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5820 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5821 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5822
5823 } else {
5824 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5825 Result, getDerived().getBaseLocation());
5826 TransformType(TLB, DI->getTypeLoc());
5827 }
5828
5829 return Result;
5830}
5831
5832template <typename Derived>
5833QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5834 VectorTypeLoc TL) {
5835 const VectorType *T = TL.getTypePtr();
5836 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5837 if (ElementType.isNull())
5838 return QualType();
5839
5840 QualType Result = TL.getType();
5841 if (getDerived().AlwaysRebuild() ||
5842 ElementType != T->getElementType()) {
5843 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5844 T->getVectorKind());
5845 if (Result.isNull())
5846 return QualType();
5847 }
5848
5849 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5850 NewTL.setNameLoc(TL.getNameLoc());
5851
5852 return Result;
5853}
5854
5855template<typename Derived>
5856QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5857 ExtVectorTypeLoc TL) {
5858 const VectorType *T = TL.getTypePtr();
5859 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5860 if (ElementType.isNull())
5861 return QualType();
5862
5863 QualType Result = TL.getType();
5864 if (getDerived().AlwaysRebuild() ||
5865 ElementType != T->getElementType()) {
5866 Result = getDerived().RebuildExtVectorType(ElementType,
5867 T->getNumElements(),
5868 /*FIXME*/ SourceLocation());
5869 if (Result.isNull())
5870 return QualType();
5871 }
5872
5873 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5874 NewTL.setNameLoc(TL.getNameLoc());
5875
5876 return Result;
5877}
5878
5879template <typename Derived>
5880ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5881 ParmVarDecl *OldParm, int indexAdjustment,
5882 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5883 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5884 TypeSourceInfo *NewDI = nullptr;
5885
5886 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5887 // If we're substituting into a pack expansion type and we know the
5888 // length we want to expand to, just substitute for the pattern.
5889 TypeLoc OldTL = OldDI->getTypeLoc();
5890 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5891
5892 TypeLocBuilder TLB;
5893 TypeLoc NewTL = OldDI->getTypeLoc();
5894 TLB.reserve(Requested: NewTL.getFullDataSize());
5895
5896 QualType Result = getDerived().TransformType(TLB,
5897 OldExpansionTL.getPatternLoc());
5898 if (Result.isNull())
5899 return nullptr;
5900
5901 Result = RebuildPackExpansionType(Pattern: Result,
5902 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
5903 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
5904 NumExpansions);
5905 if (Result.isNull())
5906 return nullptr;
5907
5908 PackExpansionTypeLoc NewExpansionTL
5909 = TLB.push<PackExpansionTypeLoc>(Result);
5910 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5911 NewDI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5912 } else
5913 NewDI = getDerived().TransformType(OldDI);
5914 if (!NewDI)
5915 return nullptr;
5916
5917 if (NewDI == OldDI && indexAdjustment == 0)
5918 return OldParm;
5919
5920 ParmVarDecl *newParm = ParmVarDecl::Create(C&: SemaRef.Context,
5921 DC: OldParm->getDeclContext(),
5922 StartLoc: OldParm->getInnerLocStart(),
5923 IdLoc: OldParm->getLocation(),
5924 Id: OldParm->getIdentifier(),
5925 T: NewDI->getType(),
5926 TInfo: NewDI,
5927 S: OldParm->getStorageClass(),
5928 /* DefArg */ DefArg: nullptr);
5929 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
5930 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
5931 transformedLocalDecl(Old: OldParm, New: {newParm});
5932 return newParm;
5933}
5934
5935template <typename Derived>
5936bool TreeTransform<Derived>::TransformFunctionTypeParams(
5937 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5938 const QualType *ParamTypes,
5939 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5940 SmallVectorImpl<QualType> &OutParamTypes,
5941 SmallVectorImpl<ParmVarDecl *> *PVars,
5942 Sema::ExtParameterInfoBuilder &PInfos,
5943 unsigned *LastParamTransformed) {
5944 int indexAdjustment = 0;
5945
5946 unsigned NumParams = Params.size();
5947 for (unsigned i = 0; i != NumParams; ++i) {
5948 if (LastParamTransformed)
5949 *LastParamTransformed = i;
5950 if (ParmVarDecl *OldParm = Params[i]) {
5951 assert(OldParm->getFunctionScopeIndex() == i);
5952
5953 std::optional<unsigned> NumExpansions;
5954 ParmVarDecl *NewParm = nullptr;
5955 if (OldParm->isParameterPack()) {
5956 // We have a function parameter pack that may need to be expanded.
5957 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5958
5959 // Find the parameter packs that could be expanded.
5960 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5961 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5962 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5963 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5964
5965 // Determine whether we should expand the parameter packs.
5966 bool ShouldExpand = false;
5967 bool RetainExpansion = false;
5968 std::optional<unsigned> OrigNumExpansions;
5969 if (Unexpanded.size() > 0) {
5970 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5971 NumExpansions = OrigNumExpansions;
5972 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5973 Pattern.getSourceRange(),
5974 Unexpanded,
5975 ShouldExpand,
5976 RetainExpansion,
5977 NumExpansions)) {
5978 return true;
5979 }
5980 } else {
5981#ifndef NDEBUG
5982 const AutoType *AT =
5983 Pattern.getType().getTypePtr()->getContainedAutoType();
5984 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5985 "Could not find parameter packs or undeduced auto type!");
5986#endif
5987 }
5988
5989 if (ShouldExpand) {
5990 // Expand the function parameter pack into multiple, separate
5991 // parameters.
5992 getDerived().ExpandingFunctionParameterPack(OldParm);
5993 for (unsigned I = 0; I != *NumExpansions; ++I) {
5994 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5995 ParmVarDecl *NewParm
5996 = getDerived().TransformFunctionTypeParam(OldParm,
5997 indexAdjustment++,
5998 OrigNumExpansions,
5999 /*ExpectParameterPack=*/false);
6000 if (!NewParm)
6001 return true;
6002
6003 if (ParamInfos)
6004 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6005 OutParamTypes.push_back(Elt: NewParm->getType());
6006 if (PVars)
6007 PVars->push_back(NewParm);
6008 }
6009
6010 // If we're supposed to retain a pack expansion, do so by temporarily
6011 // forgetting the partially-substituted parameter pack.
6012 if (RetainExpansion) {
6013 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6014 ParmVarDecl *NewParm
6015 = getDerived().TransformFunctionTypeParam(OldParm,
6016 indexAdjustment++,
6017 OrigNumExpansions,
6018 /*ExpectParameterPack=*/false);
6019 if (!NewParm)
6020 return true;
6021
6022 if (ParamInfos)
6023 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6024 OutParamTypes.push_back(Elt: NewParm->getType());
6025 if (PVars)
6026 PVars->push_back(NewParm);
6027 }
6028
6029 // The next parameter should have the same adjustment as the
6030 // last thing we pushed, but we post-incremented indexAdjustment
6031 // on every push. Also, if we push nothing, the adjustment should
6032 // go down by one.
6033 indexAdjustment--;
6034
6035 // We're done with the pack expansion.
6036 continue;
6037 }
6038
6039 // We'll substitute the parameter now without expanding the pack
6040 // expansion.
6041 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6042 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6043 indexAdjustment,
6044 NumExpansions,
6045 /*ExpectParameterPack=*/true);
6046 assert(NewParm->isParameterPack() &&
6047 "Parameter pack no longer a parameter pack after "
6048 "transformation.");
6049 } else {
6050 NewParm = getDerived().TransformFunctionTypeParam(
6051 OldParm, indexAdjustment, std::nullopt,
6052 /*ExpectParameterPack=*/false);
6053 }
6054
6055 if (!NewParm)
6056 return true;
6057
6058 if (ParamInfos)
6059 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6060 OutParamTypes.push_back(Elt: NewParm->getType());
6061 if (PVars)
6062 PVars->push_back(NewParm);
6063 continue;
6064 }
6065
6066 // Deal with the possibility that we don't have a parameter
6067 // declaration for this parameter.
6068 assert(ParamTypes);
6069 QualType OldType = ParamTypes[i];
6070 bool IsPackExpansion = false;
6071 std::optional<unsigned> NumExpansions;
6072 QualType NewType;
6073 if (const PackExpansionType *Expansion
6074 = dyn_cast<PackExpansionType>(OldType)) {
6075 // We have a function parameter pack that may need to be expanded.
6076 QualType Pattern = Expansion->getPattern();
6077 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6078 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6079
6080 // Determine whether we should expand the parameter packs.
6081 bool ShouldExpand = false;
6082 bool RetainExpansion = false;
6083 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6084 Unexpanded,
6085 ShouldExpand,
6086 RetainExpansion,
6087 NumExpansions)) {
6088 return true;
6089 }
6090
6091 if (ShouldExpand) {
6092 // Expand the function parameter pack into multiple, separate
6093 // parameters.
6094 for (unsigned I = 0; I != *NumExpansions; ++I) {
6095 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6096 QualType NewType = getDerived().TransformType(Pattern);
6097 if (NewType.isNull())
6098 return true;
6099
6100 if (NewType->containsUnexpandedParameterPack()) {
6101 NewType = getSema().getASTContext().getPackExpansionType(
6102 NewType, std::nullopt);
6103
6104 if (NewType.isNull())
6105 return true;
6106 }
6107
6108 if (ParamInfos)
6109 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6110 OutParamTypes.push_back(Elt: NewType);
6111 if (PVars)
6112 PVars->push_back(nullptr);
6113 }
6114
6115 // We're done with the pack expansion.
6116 continue;
6117 }
6118
6119 // If we're supposed to retain a pack expansion, do so by temporarily
6120 // forgetting the partially-substituted parameter pack.
6121 if (RetainExpansion) {
6122 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6123 QualType NewType = getDerived().TransformType(Pattern);
6124 if (NewType.isNull())
6125 return true;
6126
6127 if (ParamInfos)
6128 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6129 OutParamTypes.push_back(Elt: NewType);
6130 if (PVars)
6131 PVars->push_back(nullptr);
6132 }
6133
6134 // We'll substitute the parameter now without expanding the pack
6135 // expansion.
6136 OldType = Expansion->getPattern();
6137 IsPackExpansion = true;
6138 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6139 NewType = getDerived().TransformType(OldType);
6140 } else {
6141 NewType = getDerived().TransformType(OldType);
6142 }
6143
6144 if (NewType.isNull())
6145 return true;
6146
6147 if (IsPackExpansion)
6148 NewType = getSema().Context.getPackExpansionType(NewType,
6149 NumExpansions);
6150
6151 if (ParamInfos)
6152 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6153 OutParamTypes.push_back(Elt: NewType);
6154 if (PVars)
6155 PVars->push_back(nullptr);
6156 }
6157
6158#ifndef NDEBUG
6159 if (PVars) {
6160 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6161 if (ParmVarDecl *parm = (*PVars)[i])
6162 assert(parm->getFunctionScopeIndex() == i);
6163 }
6164#endif
6165
6166 return false;
6167}
6168
6169template<typename Derived>
6170QualType
6171TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6172 FunctionProtoTypeLoc TL) {
6173 SmallVector<QualType, 4> ExceptionStorage;
6174 return getDerived().TransformFunctionProtoType(
6175 TLB, TL, nullptr, Qualifiers(),
6176 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6177 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6178 ExceptionStorage, Changed);
6179 });
6180}
6181
6182template<typename Derived> template<typename Fn>
6183QualType TreeTransform<Derived>::TransformFunctionProtoType(
6184 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6185 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6186
6187 // Transform the parameters and return type.
6188 //
6189 // We are required to instantiate the params and return type in source order.
6190 // When the function has a trailing return type, we instantiate the
6191 // parameters before the return type, since the return type can then refer
6192 // to the parameters themselves (via decltype, sizeof, etc.).
6193 //
6194 SmallVector<QualType, 4> ParamTypes;
6195 SmallVector<ParmVarDecl*, 4> ParamDecls;
6196 Sema::ExtParameterInfoBuilder ExtParamInfos;
6197 const FunctionProtoType *T = TL.getTypePtr();
6198
6199 QualType ResultType;
6200
6201 if (T->hasTrailingReturn()) {
6202 if (getDerived().TransformFunctionTypeParams(
6203 TL.getBeginLoc(), TL.getParams(),
6204 TL.getTypePtr()->param_type_begin(),
6205 T->getExtParameterInfosOrNull(),
6206 ParamTypes, &ParamDecls, ExtParamInfos))
6207 return QualType();
6208
6209 {
6210 // C++11 [expr.prim.general]p3:
6211 // If a declaration declares a member function or member function
6212 // template of a class X, the expression this is a prvalue of type
6213 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6214 // and the end of the function-definition, member-declarator, or
6215 // declarator.
6216 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6217 Sema::CXXThisScopeRAII ThisScope(
6218 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6219
6220 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6221 if (ResultType.isNull())
6222 return QualType();
6223 }
6224 }
6225 else {
6226 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6227 if (ResultType.isNull())
6228 return QualType();
6229
6230 if (getDerived().TransformFunctionTypeParams(
6231 TL.getBeginLoc(), TL.getParams(),
6232 TL.getTypePtr()->param_type_begin(),
6233 T->getExtParameterInfosOrNull(),
6234 ParamTypes, &ParamDecls, ExtParamInfos))
6235 return QualType();
6236 }
6237
6238 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6239
6240 bool EPIChanged = false;
6241 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6242 return QualType();
6243
6244 // Handle extended parameter information.
6245 if (auto NewExtParamInfos =
6246 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6247 if (!EPI.ExtParameterInfos ||
6248 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6249 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6250 EPIChanged = true;
6251 }
6252 EPI.ExtParameterInfos = NewExtParamInfos;
6253 } else if (EPI.ExtParameterInfos) {
6254 EPIChanged = true;
6255 EPI.ExtParameterInfos = nullptr;
6256 }
6257
6258 QualType Result = TL.getType();
6259 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6260 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6261 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6262 if (Result.isNull())
6263 return QualType();
6264 }
6265
6266 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6267 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6268 NewTL.setLParenLoc(TL.getLParenLoc());
6269 NewTL.setRParenLoc(TL.getRParenLoc());
6270 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6271 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6272 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6273 NewTL.setParam(i, ParamDecls[i]);
6274
6275 return Result;
6276}
6277
6278template<typename Derived>
6279bool TreeTransform<Derived>::TransformExceptionSpec(
6280 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6281 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6282 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6283
6284 // Instantiate a dynamic noexcept expression, if any.
6285 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6286 // Update this scrope because ContextDecl in Sema will be used in
6287 // TransformExpr.
6288 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6289 Sema::CXXThisScopeRAII ThisScope(
6290 SemaRef, Method ? Method->getParent() : nullptr,
6291 Method ? Method->getMethodQualifiers() : Qualifiers{},
6292 Method != nullptr);
6293 EnterExpressionEvaluationContext Unevaluated(
6294 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6295 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6296 if (NoexceptExpr.isInvalid())
6297 return true;
6298
6299 ExceptionSpecificationType EST = ESI.Type;
6300 NoexceptExpr =
6301 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6302 if (NoexceptExpr.isInvalid())
6303 return true;
6304
6305 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6306 Changed = true;
6307 ESI.NoexceptExpr = NoexceptExpr.get();
6308 ESI.Type = EST;
6309 }
6310
6311 if (ESI.Type != EST_Dynamic)
6312 return false;
6313
6314 // Instantiate a dynamic exception specification's type.
6315 for (QualType T : ESI.Exceptions) {
6316 if (const PackExpansionType *PackExpansion =
6317 T->getAs<PackExpansionType>()) {
6318 Changed = true;
6319
6320 // We have a pack expansion. Instantiate it.
6321 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6322 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6323 Unexpanded);
6324 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6325
6326 // Determine whether the set of unexpanded parameter packs can and
6327 // should
6328 // be expanded.
6329 bool Expand = false;
6330 bool RetainExpansion = false;
6331 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6332 // FIXME: Track the location of the ellipsis (and track source location
6333 // information for the types in the exception specification in general).
6334 if (getDerived().TryExpandParameterPacks(
6335 Loc, SourceRange(), Unexpanded, Expand,
6336 RetainExpansion, NumExpansions))
6337 return true;
6338
6339 if (!Expand) {
6340 // We can't expand this pack expansion into separate arguments yet;
6341 // just substitute into the pattern and create a new pack expansion
6342 // type.
6343 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6344 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6345 if (U.isNull())
6346 return true;
6347
6348 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6349 Exceptions.push_back(U);
6350 continue;
6351 }
6352
6353 // Substitute into the pack expansion pattern for each slice of the
6354 // pack.
6355 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6356 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6357
6358 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6359 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6360 return true;
6361
6362 Exceptions.push_back(U);
6363 }
6364 } else {
6365 QualType U = getDerived().TransformType(T);
6366 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6367 return true;
6368 if (T != U)
6369 Changed = true;
6370
6371 Exceptions.push_back(U);
6372 }
6373 }
6374
6375 ESI.Exceptions = Exceptions;
6376 if (ESI.Exceptions.empty())
6377 ESI.Type = EST_DynamicNone;
6378 return false;
6379}
6380
6381template<typename Derived>
6382QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6383 TypeLocBuilder &TLB,
6384 FunctionNoProtoTypeLoc TL) {
6385 const FunctionNoProtoType *T = TL.getTypePtr();
6386 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6387 if (ResultType.isNull())
6388 return QualType();
6389
6390 QualType Result = TL.getType();
6391 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6392 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6393
6394 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6395 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6396 NewTL.setLParenLoc(TL.getLParenLoc());
6397 NewTL.setRParenLoc(TL.getRParenLoc());
6398 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6399
6400 return Result;
6401}
6402
6403template <typename Derived>
6404QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6405 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6406 const UnresolvedUsingType *T = TL.getTypePtr();
6407 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6408 if (!D)
6409 return QualType();
6410
6411 QualType Result = TL.getType();
6412 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6413 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6414 if (Result.isNull())
6415 return QualType();
6416 }
6417
6418 // We might get an arbitrary type spec type back. We should at
6419 // least always get a type spec type, though.
6420 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(T: Result);
6421 NewTL.setNameLoc(TL.getNameLoc());
6422
6423 return Result;
6424}
6425
6426template <typename Derived>
6427QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6428 UsingTypeLoc TL) {
6429 const UsingType *T = TL.getTypePtr();
6430
6431 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6432 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6433 if (!Found)
6434 return QualType();
6435
6436 QualType Underlying = getDerived().TransformType(T->desugar());
6437 if (Underlying.isNull())
6438 return QualType();
6439
6440 QualType Result = TL.getType();
6441 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6442 Underlying != T->getUnderlyingType()) {
6443 Result = getDerived().RebuildUsingType(Found, Underlying);
6444 if (Result.isNull())
6445 return QualType();
6446 }
6447
6448 TLB.pushTypeSpec(T: Result).setNameLoc(TL.getNameLoc());
6449 return Result;
6450}
6451
6452template<typename Derived>
6453QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6454 TypedefTypeLoc TL) {
6455 const TypedefType *T = TL.getTypePtr();
6456 TypedefNameDecl *Typedef
6457 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6458 T->getDecl()));
6459 if (!Typedef)
6460 return QualType();
6461
6462 QualType Result = TL.getType();
6463 if (getDerived().AlwaysRebuild() ||
6464 Typedef != T->getDecl()) {
6465 Result = getDerived().RebuildTypedefType(Typedef);
6466 if (Result.isNull())
6467 return QualType();
6468 }
6469
6470 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6471 NewTL.setNameLoc(TL.getNameLoc());
6472
6473 return Result;
6474}
6475
6476template<typename Derived>
6477QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6478 TypeOfExprTypeLoc TL) {
6479 // typeof expressions are not potentially evaluated contexts
6480 EnterExpressionEvaluationContext Unevaluated(
6481 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6482 Sema::ReuseLambdaContextDecl);
6483
6484 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6485 if (E.isInvalid())
6486 return QualType();
6487
6488 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
6489 if (E.isInvalid())
6490 return QualType();
6491
6492 QualType Result = TL.getType();
6493 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6494 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6495 Result =
6496 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6497 if (Result.isNull())
6498 return QualType();
6499 }
6500
6501 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6502 NewTL.setTypeofLoc(TL.getTypeofLoc());
6503 NewTL.setLParenLoc(TL.getLParenLoc());
6504 NewTL.setRParenLoc(TL.getRParenLoc());
6505
6506 return Result;
6507}
6508
6509template<typename Derived>
6510QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6511 TypeOfTypeLoc TL) {
6512 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6513 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6514 if (!New_Under_TI)
6515 return QualType();
6516
6517 QualType Result = TL.getType();
6518 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6519 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6520 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6521 if (Result.isNull())
6522 return QualType();
6523 }
6524
6525 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6526 NewTL.setTypeofLoc(TL.getTypeofLoc());
6527 NewTL.setLParenLoc(TL.getLParenLoc());
6528 NewTL.setRParenLoc(TL.getRParenLoc());
6529 NewTL.setUnmodifiedTInfo(New_Under_TI);
6530
6531 return Result;
6532}
6533
6534template<typename Derived>
6535QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6536 DecltypeTypeLoc TL) {
6537 const DecltypeType *T = TL.getTypePtr();
6538
6539 // decltype expressions are not potentially evaluated contexts
6540 EnterExpressionEvaluationContext Unevaluated(
6541 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6542 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6543
6544 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6545 if (E.isInvalid())
6546 return QualType();
6547
6548 E = getSema().ActOnDecltypeExpression(E.get());
6549 if (E.isInvalid())
6550 return QualType();
6551
6552 QualType Result = TL.getType();
6553 if (getDerived().AlwaysRebuild() ||
6554 E.get() != T->getUnderlyingExpr()) {
6555 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6556 if (Result.isNull())
6557 return QualType();
6558 }
6559 else E.get();
6560
6561 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6562 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6563 NewTL.setRParenLoc(TL.getRParenLoc());
6564 return Result;
6565}
6566
6567template <typename Derived>
6568QualType
6569TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6570 PackIndexingTypeLoc TL) {
6571 // Transform the index
6572 ExprResult IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6573 if (IndexExpr.isInvalid())
6574 return QualType();
6575 QualType Pattern = TL.getPattern();
6576
6577 const PackIndexingType *PIT = TL.getTypePtr();
6578 SmallVector<QualType, 5> SubtitutedTypes;
6579 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6580
6581 bool NotYetExpanded = Types.empty();
6582 bool FullySubstituted = true;
6583
6584 if (Types.empty())
6585 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6586
6587 for (const QualType &T : Types) {
6588 if (!T->containsUnexpandedParameterPack()) {
6589 QualType Transformed = getDerived().TransformType(T);
6590 if (Transformed.isNull())
6591 return QualType();
6592 SubtitutedTypes.push_back(Transformed);
6593 continue;
6594 }
6595
6596 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6597 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6598 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6599 // Determine whether the set of unexpanded parameter packs can and should
6600 // be expanded.
6601 bool ShouldExpand = true;
6602 bool RetainExpansion = false;
6603 std::optional<unsigned> OrigNumExpansions;
6604 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6605 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6606 Unexpanded, ShouldExpand,
6607 RetainExpansion, NumExpansions))
6608 return QualType();
6609 if (!ShouldExpand) {
6610 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6611 // FIXME: should we keep TypeLoc for individual expansions in
6612 // PackIndexingTypeLoc?
6613 TypeSourceInfo *TI =
6614 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6615 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6616 if (Pack.isNull())
6617 return QualType();
6618 if (NotYetExpanded) {
6619 FullySubstituted = false;
6620 QualType Out = getDerived().RebuildPackIndexingType(
6621 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6622 FullySubstituted);
6623 if (Out.isNull())
6624 return QualType();
6625
6626 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6627 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6628 return Out;
6629 }
6630 SubtitutedTypes.push_back(Pack);
6631 continue;
6632 }
6633 for (unsigned I = 0; I != *NumExpansions; ++I) {
6634 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6635 QualType Out = getDerived().TransformType(T);
6636 if (Out.isNull())
6637 return QualType();
6638 SubtitutedTypes.push_back(Out);
6639 }
6640 // If we're supposed to retain a pack expansion, do so by temporarily
6641 // forgetting the partially-substituted parameter pack.
6642 if (RetainExpansion) {
6643 FullySubstituted = false;
6644 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6645 QualType Out = getDerived().TransformType(T);
6646 if (Out.isNull())
6647 return QualType();
6648 SubtitutedTypes.push_back(Out);
6649 }
6650 }
6651
6652 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6653
6654 QualType Out = getDerived().RebuildPackIndexingType(
6655 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6656 FullySubstituted, SubtitutedTypes);
6657 if (Out.isNull())
6658 return Out;
6659
6660 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6661 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6662 return Out;
6663}
6664
6665template<typename Derived>
6666QualType TreeTransform<Derived>::TransformUnaryTransformType(
6667 TypeLocBuilder &TLB,
6668 UnaryTransformTypeLoc TL) {
6669 QualType Result = TL.getType();
6670 if (Result->isDependentType()) {
6671 const UnaryTransformType *T = TL.getTypePtr();
6672 QualType NewBase =
6673 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6674 Result = getDerived().RebuildUnaryTransformType(NewBase,
6675 T->getUTTKind(),
6676 TL.getKWLoc());
6677 if (Result.isNull())
6678 return QualType();
6679 }
6680
6681 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6682 NewTL.setKWLoc(TL.getKWLoc());
6683 NewTL.setParensRange(TL.getParensRange());
6684 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6685 return Result;
6686}
6687
6688template<typename Derived>
6689QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6690 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6691 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6692
6693 CXXScopeSpec SS;
6694 TemplateName TemplateName = getDerived().TransformTemplateName(
6695 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6696 if (TemplateName.isNull())
6697 return QualType();
6698
6699 QualType OldDeduced = T->getDeducedType();
6700 QualType NewDeduced;
6701 if (!OldDeduced.isNull()) {
6702 NewDeduced = getDerived().TransformType(OldDeduced);
6703 if (NewDeduced.isNull())
6704 return QualType();
6705 }
6706
6707 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6708 TemplateName, NewDeduced);
6709 if (Result.isNull())
6710 return QualType();
6711
6712 DeducedTemplateSpecializationTypeLoc NewTL =
6713 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6714 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6715
6716 return Result;
6717}
6718
6719template<typename Derived>
6720QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6721 RecordTypeLoc TL) {
6722 const RecordType *T = TL.getTypePtr();
6723 RecordDecl *Record
6724 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6725 T->getDecl()));
6726 if (!Record)
6727 return QualType();
6728
6729 QualType Result = TL.getType();
6730 if (getDerived().AlwaysRebuild() ||
6731 Record != T->getDecl()) {
6732 Result = getDerived().RebuildRecordType(Record);
6733 if (Result.isNull())
6734 return QualType();
6735 }
6736
6737 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6738 NewTL.setNameLoc(TL.getNameLoc());
6739
6740 return Result;
6741}
6742
6743template<typename Derived>
6744QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6745 EnumTypeLoc TL) {
6746 const EnumType *T = TL.getTypePtr();
6747 EnumDecl *Enum
6748 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6749 T->getDecl()));
6750 if (!Enum)
6751 return QualType();
6752
6753 QualType Result = TL.getType();
6754 if (getDerived().AlwaysRebuild() ||
6755 Enum != T->getDecl()) {
6756 Result = getDerived().RebuildEnumType(Enum);
6757 if (Result.isNull())
6758 return QualType();
6759 }
6760
6761 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6762 NewTL.setNameLoc(TL.getNameLoc());
6763
6764 return Result;
6765}
6766
6767template<typename Derived>
6768QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6769 TypeLocBuilder &TLB,
6770 InjectedClassNameTypeLoc TL) {
6771 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6772 TL.getTypePtr()->getDecl());
6773 if (!D) return QualType();
6774
6775 QualType T = SemaRef.Context.getTypeDeclType(Decl: cast<TypeDecl>(D));
6776 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6777 return T;
6778}
6779
6780template<typename Derived>
6781QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6782 TypeLocBuilder &TLB,
6783 TemplateTypeParmTypeLoc TL) {
6784 return getDerived().TransformTemplateTypeParmType(
6785 TLB, TL,
6786 /*SuppressObjCLifetime=*/false);
6787}
6788
6789template <typename Derived>
6790QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6791 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6792 return TransformTypeSpecType(TLB, TL);
6793}
6794
6795template<typename Derived>
6796QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6797 TypeLocBuilder &TLB,
6798 SubstTemplateTypeParmTypeLoc TL) {
6799 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6800
6801 Decl *NewReplaced =
6802 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6803
6804 // Substitute into the replacement type, which itself might involve something
6805 // that needs to be transformed. This only tends to occur with default
6806 // template arguments of template template parameters.
6807 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6808 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6809 if (Replacement.isNull())
6810 return QualType();
6811
6812 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6813 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex());
6814
6815 // Propagate type-source information.
6816 SubstTemplateTypeParmTypeLoc NewTL
6817 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6818 NewTL.setNameLoc(TL.getNameLoc());
6819 return Result;
6820
6821}
6822
6823template<typename Derived>
6824QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6825 TypeLocBuilder &TLB,
6826 SubstTemplateTypeParmPackTypeLoc TL) {
6827 return getDerived().TransformSubstTemplateTypeParmPackType(
6828 TLB, TL, /*SuppressObjCLifetime=*/false);
6829}
6830
6831template <typename Derived>
6832QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6833 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6834 return TransformTypeSpecType(TLB, TL);
6835}
6836
6837template<typename Derived>
6838QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6839 TypeLocBuilder &TLB,
6840 TemplateSpecializationTypeLoc TL) {
6841 const TemplateSpecializationType *T = TL.getTypePtr();
6842
6843 // The nested-name-specifier never matters in a TemplateSpecializationType,
6844 // because we can't have a dependent nested-name-specifier anyway.
6845 CXXScopeSpec SS;
6846 TemplateName Template
6847 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6848 TL.getTemplateNameLoc());
6849 if (Template.isNull())
6850 return QualType();
6851
6852 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6853}
6854
6855template<typename Derived>
6856QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6857 AtomicTypeLoc TL) {
6858 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6859 if (ValueType.isNull())
6860 return QualType();
6861
6862 QualType Result = TL.getType();
6863 if (getDerived().AlwaysRebuild() ||
6864 ValueType != TL.getValueLoc().getType()) {
6865 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6866 if (Result.isNull())
6867 return QualType();
6868 }
6869
6870 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6871 NewTL.setKWLoc(TL.getKWLoc());
6872 NewTL.setLParenLoc(TL.getLParenLoc());
6873 NewTL.setRParenLoc(TL.getRParenLoc());
6874
6875 return Result;
6876}
6877
6878template <typename Derived>
6879QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6880 PipeTypeLoc TL) {
6881 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6882 if (ValueType.isNull())
6883 return QualType();
6884
6885 QualType Result = TL.getType();
6886 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6887 const PipeType *PT = Result->castAs<PipeType>();
6888 bool isReadPipe = PT->isReadOnly();
6889 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6890 if (Result.isNull())
6891 return QualType();
6892 }
6893
6894 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6895 NewTL.setKWLoc(TL.getKWLoc());
6896
6897 return Result;
6898}
6899
6900template <typename Derived>
6901QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6902 BitIntTypeLoc TL) {
6903 const BitIntType *EIT = TL.getTypePtr();
6904 QualType Result = TL.getType();
6905
6906 if (getDerived().AlwaysRebuild()) {
6907 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6908 EIT->getNumBits(), TL.getNameLoc());
6909 if (Result.isNull())
6910 return QualType();
6911 }
6912
6913 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6914 NewTL.setNameLoc(TL.getNameLoc());
6915 return Result;
6916}
6917
6918template <typename Derived>
6919QualType TreeTransform<Derived>::TransformDependentBitIntType(
6920 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6921 const DependentBitIntType *EIT = TL.getTypePtr();
6922
6923 EnterExpressionEvaluationContext Unevaluated(
6924 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6925 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6926 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
6927
6928 if (BitsExpr.isInvalid())
6929 return QualType();
6930
6931 QualType Result = TL.getType();
6932
6933 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6934 Result = getDerived().RebuildDependentBitIntType(
6935 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6936
6937 if (Result.isNull())
6938 return QualType();
6939 }
6940
6941 if (isa<DependentBitIntType>(Result)) {
6942 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6943 NewTL.setNameLoc(TL.getNameLoc());
6944 } else {
6945 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6946 NewTL.setNameLoc(TL.getNameLoc());
6947 }
6948 return Result;
6949}
6950
6951 /// Simple iterator that traverses the template arguments in a
6952 /// container that provides a \c getArgLoc() member function.
6953 ///
6954 /// This iterator is intended to be used with the iterator form of
6955 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6956 template<typename ArgLocContainer>
6957 class TemplateArgumentLocContainerIterator {
6958 ArgLocContainer *Container;
6959 unsigned Index;
6960
6961 public:
6962 typedef TemplateArgumentLoc value_type;
6963 typedef TemplateArgumentLoc reference;
6964 typedef int difference_type;
6965 typedef std::input_iterator_tag iterator_category;
6966
6967 class pointer {
6968 TemplateArgumentLoc Arg;
6969
6970 public:
6971 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6972
6973 const TemplateArgumentLoc *operator->() const {
6974 return &Arg;
6975 }
6976 };
6977
6978
6979 TemplateArgumentLocContainerIterator() {}
6980
6981 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6982 unsigned Index)
6983 : Container(&Container), Index(Index) { }
6984
6985 TemplateArgumentLocContainerIterator &operator++() {
6986 ++Index;
6987 return *this;
6988 }
6989
6990 TemplateArgumentLocContainerIterator operator++(int) {
6991 TemplateArgumentLocContainerIterator Old(*this);
6992 ++(*this);
6993 return Old;
6994 }
6995
6996 TemplateArgumentLoc operator*() const {
6997 return Container->getArgLoc(Index);
6998 }
6999
7000 pointer operator->() const {
7001 return pointer(Container->getArgLoc(Index));
7002 }
7003
7004 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7005 const TemplateArgumentLocContainerIterator &Y) {
7006 return X.Container == Y.Container && X.Index == Y.Index;
7007 }
7008
7009 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7010 const TemplateArgumentLocContainerIterator &Y) {
7011 return !(X == Y);
7012 }
7013 };
7014
7015template<typename Derived>
7016QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7017 AutoTypeLoc TL) {
7018 const AutoType *T = TL.getTypePtr();
7019 QualType OldDeduced = T->getDeducedType();
7020 QualType NewDeduced;
7021 if (!OldDeduced.isNull()) {
7022 NewDeduced = getDerived().TransformType(OldDeduced);
7023 if (NewDeduced.isNull())
7024 return QualType();
7025 }
7026
7027 ConceptDecl *NewCD = nullptr;
7028 TemplateArgumentListInfo NewTemplateArgs;
7029 NestedNameSpecifierLoc NewNestedNameSpec;
7030 if (T->isConstrained()) {
7031 assert(TL.getConceptReference());
7032 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7033 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7034
7035 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7036 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7037 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7038 if (getDerived().TransformTemplateArguments(
7039 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7040 NewTemplateArgs))
7041 return QualType();
7042
7043 if (TL.getNestedNameSpecifierLoc()) {
7044 NewNestedNameSpec
7045 = getDerived().TransformNestedNameSpecifierLoc(
7046 TL.getNestedNameSpecifierLoc());
7047 if (!NewNestedNameSpec)
7048 return QualType();
7049 }
7050 }
7051
7052 QualType Result = TL.getType();
7053 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7054 T->isDependentType() || T->isConstrained()) {
7055 // FIXME: Maybe don't rebuild if all template arguments are the same.
7056 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7057 NewArgList.reserve(N: NewTemplateArgs.size());
7058 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7059 NewArgList.push_back(Elt: ArgLoc.getArgument());
7060 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7061 NewArgList);
7062 if (Result.isNull())
7063 return QualType();
7064 }
7065
7066 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7067 NewTL.setNameLoc(TL.getNameLoc());
7068 NewTL.setRParenLoc(TL.getRParenLoc());
7069 NewTL.setConceptReference(nullptr);
7070
7071 if (T->isConstrained()) {
7072 DeclarationNameInfo DNI = DeclarationNameInfo(
7073 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7074 TL.getConceptNameLoc(),
7075 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7076 auto *CR = ConceptReference::Create(
7077 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7078 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7079 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7080 NewTL.setConceptReference(CR);
7081 }
7082
7083 return Result;
7084}
7085
7086template <typename Derived>
7087QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7088 TypeLocBuilder &TLB,
7089 TemplateSpecializationTypeLoc TL,
7090 TemplateName Template) {
7091 TemplateArgumentListInfo NewTemplateArgs;
7092 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7093 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7094 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7095 ArgIterator;
7096 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7097 ArgIterator(TL, TL.getNumArgs()),
7098 NewTemplateArgs))
7099 return QualType();
7100
7101 // FIXME: maybe don't rebuild if all the template arguments are the same.
7102
7103 QualType Result =
7104 getDerived().RebuildTemplateSpecializationType(Template,
7105 TL.getTemplateNameLoc(),
7106 NewTemplateArgs);
7107
7108 if (!Result.isNull()) {
7109 // Specializations of template template parameters are represented as
7110 // TemplateSpecializationTypes, and substitution of type alias templates
7111 // within a dependent context can transform them into
7112 // DependentTemplateSpecializationTypes.
7113 if (isa<DependentTemplateSpecializationType>(Result)) {
7114 DependentTemplateSpecializationTypeLoc NewTL
7115 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7116 NewTL.setElaboratedKeywordLoc(SourceLocation());
7117 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7118 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7119 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7120 NewTL.setLAngleLoc(TL.getLAngleLoc());
7121 NewTL.setRAngleLoc(TL.getRAngleLoc());
7122 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7123 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7124 return Result;
7125 }
7126
7127 TemplateSpecializationTypeLoc NewTL
7128 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7129 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7130 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7131 NewTL.setLAngleLoc(TL.getLAngleLoc());
7132 NewTL.setRAngleLoc(TL.getRAngleLoc());
7133 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7134 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7135 }
7136
7137 return Result;
7138}
7139
7140template <typename Derived>
7141QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7142 TypeLocBuilder &TLB,
7143 DependentTemplateSpecializationTypeLoc TL,
7144 TemplateName Template,
7145 CXXScopeSpec &SS) {
7146 TemplateArgumentListInfo NewTemplateArgs;
7147 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7148 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7149 typedef TemplateArgumentLocContainerIterator<
7150 DependentTemplateSpecializationTypeLoc> ArgIterator;
7151 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7152 ArgIterator(TL, TL.getNumArgs()),
7153 NewTemplateArgs))
7154 return QualType();
7155
7156 // FIXME: maybe don't rebuild if all the template arguments are the same.
7157
7158 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7159 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7160 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7161 DTN->getIdentifier(), NewTemplateArgs.arguments());
7162
7163 DependentTemplateSpecializationTypeLoc NewTL
7164 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7165 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7166 NewTL.setQualifierLoc(SS.getWithLocInContext(Context&: SemaRef.Context));
7167 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7168 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7169 NewTL.setLAngleLoc(TL.getLAngleLoc());
7170 NewTL.setRAngleLoc(TL.getRAngleLoc());
7171 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7172 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7173 return Result;
7174 }
7175
7176 QualType Result
7177 = getDerived().RebuildTemplateSpecializationType(Template,
7178 TL.getTemplateNameLoc(),
7179 NewTemplateArgs);
7180
7181 if (!Result.isNull()) {
7182 /// FIXME: Wrap this in an elaborated-type-specifier?
7183 TemplateSpecializationTypeLoc NewTL
7184 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7185 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7186 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7187 NewTL.setLAngleLoc(TL.getLAngleLoc());
7188 NewTL.setRAngleLoc(TL.getRAngleLoc());
7189 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7190 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7191 }
7192
7193 return Result;
7194}
7195
7196template<typename Derived>
7197QualType
7198TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7199 ElaboratedTypeLoc TL) {
7200 const ElaboratedType *T = TL.getTypePtr();
7201
7202 NestedNameSpecifierLoc QualifierLoc;
7203 // NOTE: the qualifier in an ElaboratedType is optional.
7204 if (TL.getQualifierLoc()) {
7205 QualifierLoc
7206 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7207 if (!QualifierLoc)
7208 return QualType();
7209 }
7210
7211 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7212 if (NamedT.isNull())
7213 return QualType();
7214
7215 // C++0x [dcl.type.elab]p2:
7216 // If the identifier resolves to a typedef-name or the simple-template-id
7217 // resolves to an alias template specialization, the
7218 // elaborated-type-specifier is ill-formed.
7219 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7220 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7221 if (const TemplateSpecializationType *TST =
7222 NamedT->getAs<TemplateSpecializationType>()) {
7223 TemplateName Template = TST->getTemplateName();
7224 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7225 Template.getAsTemplateDecl())) {
7226 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7227 diag::err_tag_reference_non_tag)
7228 << TAT << Sema::NTK_TypeAliasTemplate
7229 << llvm::to_underlying(
7230 ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()));
7231 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7232 }
7233 }
7234 }
7235
7236 QualType Result = TL.getType();
7237 if (getDerived().AlwaysRebuild() ||
7238 QualifierLoc != TL.getQualifierLoc() ||
7239 NamedT != T->getNamedType()) {
7240 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7241 T->getKeyword(),
7242 QualifierLoc, NamedT);
7243 if (Result.isNull())
7244 return QualType();
7245 }
7246
7247 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7248 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7249 NewTL.setQualifierLoc(QualifierLoc);
7250 return Result;
7251}
7252
7253template <typename Derived>
7254template <typename Fn>
7255QualType TreeTransform<Derived>::TransformAttributedType(
7256 TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
7257 const AttributedType *oldType = TL.getTypePtr();
7258 QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc());
7259 if (modifiedType.isNull())
7260 return QualType();
7261
7262 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7263 const Attr *oldAttr = TL.getAttr();
7264 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7265 if (oldAttr && !newAttr)
7266 return QualType();
7267
7268 QualType result = TL.getType();
7269
7270 // FIXME: dependent operand expressions?
7271 if (getDerived().AlwaysRebuild() ||
7272 modifiedType != oldType->getModifiedType()) {
7273 TypeLocBuilder AuxiliaryTLB;
7274 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7275 QualType equivalentType =
7276 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7277 if (equivalentType.isNull())
7278 return QualType();
7279
7280 // Check whether we can add nullability; it is only represented as
7281 // type sugar, and therefore cannot be diagnosed in any other way.
7282 if (auto nullability = oldType->getImmediateNullability()) {
7283 if (!modifiedType->canHaveNullability()) {
7284 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7285 : TL.getModifiedLoc().getBeginLoc()),
7286 diag::err_nullability_nonpointer)
7287 << DiagNullabilityKind(*nullability, false) << modifiedType;
7288 return QualType();
7289 }
7290 }
7291
7292 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7293 modifiedType,
7294 equivalentType);
7295 }
7296
7297 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7298 newTL.setAttr(newAttr);
7299 return result;
7300}
7301
7302template <typename Derived>
7303QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7304 AttributedTypeLoc TL) {
7305 return getDerived().TransformAttributedType(
7306 TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7307 return getDerived().TransformType(TLB, ModifiedLoc);
7308 });
7309}
7310
7311template <typename Derived>
7312QualType TreeTransform<Derived>::TransformCountAttributedType(
7313 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7314 const CountAttributedType *OldTy = TL.getTypePtr();
7315 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7316 if (InnerTy.isNull())
7317 return QualType();
7318
7319 Expr *OldCount = TL.getCountExpr();
7320 Expr *NewCount = nullptr;
7321 if (OldCount) {
7322 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7323 if (CountResult.isInvalid())
7324 return QualType();
7325 NewCount = CountResult.get();
7326 }
7327
7328 QualType Result = TL.getType();
7329 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7330 OldCount != NewCount) {
7331 // Currently, CountAttributedType can only wrap incomplete array types.
7332 Result = SemaRef.BuildCountAttributedArrayType(WrappedTy: InnerTy, CountExpr: NewCount);
7333 }
7334
7335 TLB.push<CountAttributedTypeLoc>(Result);
7336 return Result;
7337}
7338
7339template <typename Derived>
7340QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7341 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7342 // The BTFTagAttributedType is available for C only.
7343 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7344}
7345
7346template<typename Derived>
7347QualType
7348TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7349 ParenTypeLoc TL) {
7350 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7351 if (Inner.isNull())
7352 return QualType();
7353
7354 QualType Result = TL.getType();
7355 if (getDerived().AlwaysRebuild() ||
7356 Inner != TL.getInnerLoc().getType()) {
7357 Result = getDerived().RebuildParenType(Inner);
7358 if (Result.isNull())
7359 return QualType();
7360 }
7361
7362 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7363 NewTL.setLParenLoc(TL.getLParenLoc());
7364 NewTL.setRParenLoc(TL.getRParenLoc());
7365 return Result;
7366}
7367
7368template <typename Derived>
7369QualType
7370TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7371 MacroQualifiedTypeLoc TL) {
7372 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7373 if (Inner.isNull())
7374 return QualType();
7375
7376 QualType Result = TL.getType();
7377 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7378 Result =
7379 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7380 if (Result.isNull())
7381 return QualType();
7382 }
7383
7384 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7385 NewTL.setExpansionLoc(TL.getExpansionLoc());
7386 return Result;
7387}
7388
7389template<typename Derived>
7390QualType TreeTransform<Derived>::TransformDependentNameType(
7391 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7392 return TransformDependentNameType(TLB, TL, DeducibleTSTContext: false);
7393}
7394
7395template<typename Derived>
7396QualType TreeTransform<Derived>::TransformDependentNameType(
7397 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7398 const DependentNameType *T = TL.getTypePtr();
7399
7400 NestedNameSpecifierLoc QualifierLoc
7401 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7402 if (!QualifierLoc)
7403 return QualType();
7404
7405 QualType Result
7406 = getDerived().RebuildDependentNameType(T->getKeyword(),
7407 TL.getElaboratedKeywordLoc(),
7408 QualifierLoc,
7409 T->getIdentifier(),
7410 TL.getNameLoc(),
7411 DeducedTSTContext);
7412 if (Result.isNull())
7413 return QualType();
7414
7415 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7416 QualType NamedT = ElabT->getNamedType();
7417 TLB.pushTypeSpec(T: NamedT).setNameLoc(TL.getNameLoc());
7418
7419 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7420 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7421 NewTL.setQualifierLoc(QualifierLoc);
7422 } else {
7423 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7424 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7425 NewTL.setQualifierLoc(QualifierLoc);
7426 NewTL.setNameLoc(TL.getNameLoc());
7427 }
7428 return Result;
7429}
7430
7431template<typename Derived>
7432QualType TreeTransform<Derived>::
7433 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7434 DependentTemplateSpecializationTypeLoc TL) {
7435 NestedNameSpecifierLoc QualifierLoc;
7436 if (TL.getQualifierLoc()) {
7437 QualifierLoc
7438 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7439 if (!QualifierLoc)
7440 return QualType();
7441 }
7442
7443 return getDerived()
7444 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7445}
7446
7447template<typename Derived>
7448QualType TreeTransform<Derived>::
7449TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7450 DependentTemplateSpecializationTypeLoc TL,
7451 NestedNameSpecifierLoc QualifierLoc) {
7452 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7453
7454 TemplateArgumentListInfo NewTemplateArgs;
7455 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7456 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7457
7458 typedef TemplateArgumentLocContainerIterator<
7459 DependentTemplateSpecializationTypeLoc> ArgIterator;
7460 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7461 ArgIterator(TL, TL.getNumArgs()),
7462 NewTemplateArgs))
7463 return QualType();
7464
7465 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7466 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7467 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7468 /*AllowInjectedClassName*/ false);
7469 if (Result.isNull())
7470 return QualType();
7471
7472 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7473 QualType NamedT = ElabT->getNamedType();
7474
7475 // Copy information relevant to the template specialization.
7476 TemplateSpecializationTypeLoc NamedTL
7477 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7478 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7479 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7480 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7481 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7482 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7483 NamedTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7484
7485 // Copy information relevant to the elaborated type.
7486 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7487 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7488 NewTL.setQualifierLoc(QualifierLoc);
7489 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7490 DependentTemplateSpecializationTypeLoc SpecTL
7491 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7492 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7493 SpecTL.setQualifierLoc(QualifierLoc);
7494 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7495 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7496 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7497 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7498 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7499 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7500 } else {
7501 TemplateSpecializationTypeLoc SpecTL
7502 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7503 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7504 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7505 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7506 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7507 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7508 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7509 }
7510 return Result;
7511}
7512
7513template<typename Derived>
7514QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7515 PackExpansionTypeLoc TL) {
7516 QualType Pattern
7517 = getDerived().TransformType(TLB, TL.getPatternLoc());
7518 if (Pattern.isNull())
7519 return QualType();
7520
7521 QualType Result = TL.getType();
7522 if (getDerived().AlwaysRebuild() ||
7523 Pattern != TL.getPatternLoc().getType()) {
7524 Result = getDerived().RebuildPackExpansionType(Pattern,
7525 TL.getPatternLoc().getSourceRange(),
7526 TL.getEllipsisLoc(),
7527 TL.getTypePtr()->getNumExpansions());
7528 if (Result.isNull())
7529 return QualType();
7530 }
7531
7532 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7533 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7534 return Result;
7535}
7536
7537template<typename Derived>
7538QualType
7539TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7540 ObjCInterfaceTypeLoc TL) {
7541 // ObjCInterfaceType is never dependent.
7542 TLB.pushFullCopy(TL);
7543 return TL.getType();
7544}
7545
7546template<typename Derived>
7547QualType
7548TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7549 ObjCTypeParamTypeLoc TL) {
7550 const ObjCTypeParamType *T = TL.getTypePtr();
7551 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7552 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7553 if (!OTP)
7554 return QualType();
7555
7556 QualType Result = TL.getType();
7557 if (getDerived().AlwaysRebuild() ||
7558 OTP != T->getDecl()) {
7559 Result = getDerived().RebuildObjCTypeParamType(
7560 OTP, TL.getProtocolLAngleLoc(),
7561 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7562 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7563 if (Result.isNull())
7564 return QualType();
7565 }
7566
7567 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7568 if (TL.getNumProtocols()) {
7569 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7570 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7571 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7572 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7573 }
7574 return Result;
7575}
7576
7577template<typename Derived>
7578QualType
7579TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7580 ObjCObjectTypeLoc TL) {
7581 // Transform base type.
7582 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7583 if (BaseType.isNull())
7584 return QualType();
7585
7586 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7587
7588 // Transform type arguments.
7589 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7590 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7591 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7592 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7593 QualType TypeArg = TypeArgInfo->getType();
7594 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7595 AnyChanged = true;
7596
7597 // We have a pack expansion. Instantiate it.
7598 const auto *PackExpansion = PackExpansionLoc.getType()
7599 ->castAs<PackExpansionType>();
7600 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7601 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7602 Unexpanded);
7603 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7604
7605 // Determine whether the set of unexpanded parameter packs can
7606 // and should be expanded.
7607 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7608 bool Expand = false;
7609 bool RetainExpansion = false;
7610 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7611 if (getDerived().TryExpandParameterPacks(
7612 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7613 Unexpanded, Expand, RetainExpansion, NumExpansions))
7614 return QualType();
7615
7616 if (!Expand) {
7617 // We can't expand this pack expansion into separate arguments yet;
7618 // just substitute into the pattern and create a new pack expansion
7619 // type.
7620 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7621
7622 TypeLocBuilder TypeArgBuilder;
7623 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7624 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7625 PatternLoc);
7626 if (NewPatternType.isNull())
7627 return QualType();
7628
7629 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7630 Pattern: NewPatternType, NumExpansions);
7631 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7632 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7633 NewTypeArgInfos.push_back(
7634 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
7635 continue;
7636 }
7637
7638 // Substitute into the pack expansion pattern for each slice of the
7639 // pack.
7640 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7641 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7642
7643 TypeLocBuilder TypeArgBuilder;
7644 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7645
7646 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7647 PatternLoc);
7648 if (NewTypeArg.isNull())
7649 return QualType();
7650
7651 NewTypeArgInfos.push_back(
7652 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
7653 }
7654
7655 continue;
7656 }
7657
7658 TypeLocBuilder TypeArgBuilder;
7659 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
7660 QualType NewTypeArg =
7661 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7662 if (NewTypeArg.isNull())
7663 return QualType();
7664
7665 // If nothing changed, just keep the old TypeSourceInfo.
7666 if (NewTypeArg == TypeArg) {
7667 NewTypeArgInfos.push_back(TypeArgInfo);
7668 continue;
7669 }
7670
7671 NewTypeArgInfos.push_back(
7672 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
7673 AnyChanged = true;
7674 }
7675
7676 QualType Result = TL.getType();
7677 if (getDerived().AlwaysRebuild() || AnyChanged) {
7678 // Rebuild the type.
7679 Result = getDerived().RebuildObjCObjectType(
7680 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7681 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7682 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7683 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7684
7685 if (Result.isNull())
7686 return QualType();
7687 }
7688
7689 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7690 NewT.setHasBaseTypeAsWritten(true);
7691 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7692 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7693 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
7694 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7695 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7696 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7697 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7698 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7699 return Result;
7700}
7701
7702template<typename Derived>
7703QualType
7704TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7705 ObjCObjectPointerTypeLoc TL) {
7706 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7707 if (PointeeType.isNull())
7708 return QualType();
7709
7710 QualType Result = TL.getType();
7711 if (getDerived().AlwaysRebuild() ||
7712 PointeeType != TL.getPointeeLoc().getType()) {
7713 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7714 TL.getStarLoc());
7715 if (Result.isNull())
7716 return QualType();
7717 }
7718
7719 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7720 NewT.setStarLoc(TL.getStarLoc());
7721 return Result;
7722}
7723
7724//===----------------------------------------------------------------------===//
7725// Statement transformation
7726//===----------------------------------------------------------------------===//
7727template<typename Derived>
7728StmtResult
7729TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7730 return S;
7731}
7732
7733template<typename Derived>
7734StmtResult
7735TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7736 return getDerived().TransformCompoundStmt(S, false);
7737}
7738
7739template<typename Derived>
7740StmtResult
7741TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7742 bool IsStmtExpr) {
7743 Sema::CompoundScopeRAII CompoundScope(getSema());
7744 Sema::FPFeaturesStateRAII FPSave(getSema());
7745 if (S->hasStoredFPFeatures())
7746 getSema().resetFPOptions(
7747 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7748
7749 const Stmt *ExprResult = S->getStmtExprResult();
7750 bool SubStmtInvalid = false;
7751 bool SubStmtChanged = false;
7752 SmallVector<Stmt*, 8> Statements;
7753 for (auto *B : S->body()) {
7754 StmtResult Result = getDerived().TransformStmt(
7755 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7756
7757 if (Result.isInvalid()) {
7758 // Immediately fail if this was a DeclStmt, since it's very
7759 // likely that this will cause problems for future statements.
7760 if (isa<DeclStmt>(B))
7761 return StmtError();
7762
7763 // Otherwise, just keep processing substatements and fail later.
7764 SubStmtInvalid = true;
7765 continue;
7766 }
7767
7768 SubStmtChanged = SubStmtChanged || Result.get() != B;
7769 Statements.push_back(Result.getAs<Stmt>());
7770 }
7771
7772 if (SubStmtInvalid)
7773 return StmtError();
7774
7775 if (!getDerived().AlwaysRebuild() &&
7776 !SubStmtChanged)
7777 return S;
7778
7779 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7780 Statements,
7781 S->getRBracLoc(),
7782 IsStmtExpr);
7783}
7784
7785template<typename Derived>
7786StmtResult
7787TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7788 ExprResult LHS, RHS;
7789 {
7790 EnterExpressionEvaluationContext Unevaluated(
7791 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7792
7793 // Transform the left-hand case value.
7794 LHS = getDerived().TransformExpr(S->getLHS());
7795 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
7796 if (LHS.isInvalid())
7797 return StmtError();
7798
7799 // Transform the right-hand case value (for the GNU case-range extension).
7800 RHS = getDerived().TransformExpr(S->getRHS());
7801 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
7802 if (RHS.isInvalid())
7803 return StmtError();
7804 }
7805
7806 // Build the case statement.
7807 // Case statements are always rebuilt so that they will attached to their
7808 // transformed switch statement.
7809 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7810 LHS.get(),
7811 S->getEllipsisLoc(),
7812 RHS.get(),
7813 S->getColonLoc());
7814 if (Case.isInvalid())
7815 return StmtError();
7816
7817 // Transform the statement following the case
7818 StmtResult SubStmt =
7819 getDerived().TransformStmt(S->getSubStmt());
7820 if (SubStmt.isInvalid())
7821 return StmtError();
7822
7823 // Attach the body to the case statement
7824 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7825}
7826
7827template <typename Derived>
7828StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7829 // Transform the statement following the default case
7830 StmtResult SubStmt =
7831 getDerived().TransformStmt(S->getSubStmt());
7832 if (SubStmt.isInvalid())
7833 return StmtError();
7834
7835 // Default statements are always rebuilt
7836 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7837 SubStmt.get());
7838}
7839
7840template<typename Derived>
7841StmtResult
7842TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7843 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7844 if (SubStmt.isInvalid())
7845 return StmtError();
7846
7847 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7848 S->getDecl());
7849 if (!LD)
7850 return StmtError();
7851
7852 // If we're transforming "in-place" (we're not creating new local
7853 // declarations), assume we're replacing the old label statement
7854 // and clear out the reference to it.
7855 if (LD == S->getDecl())
7856 S->getDecl()->setStmt(nullptr);
7857
7858 // FIXME: Pass the real colon location in.
7859 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7860 cast<LabelDecl>(LD), SourceLocation(),
7861 SubStmt.get());
7862}
7863
7864template <typename Derived>
7865const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7866 if (!R)
7867 return R;
7868
7869 switch (R->getKind()) {
7870// Transform attributes by calling TransformXXXAttr.
7871#define ATTR(X) \
7872 case attr::X: \
7873 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7874#include "clang/Basic/AttrList.inc"
7875 }
7876 return R;
7877}
7878
7879template <typename Derived>
7880const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
7881 const Stmt *InstS,
7882 const Attr *R) {
7883 if (!R)
7884 return R;
7885
7886 switch (R->getKind()) {
7887// Transform attributes by calling TransformStmtXXXAttr.
7888#define ATTR(X) \
7889 case attr::X: \
7890 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7891#include "clang/Basic/AttrList.inc"
7892 }
7893 return TransformAttr(R);
7894}
7895
7896template <typename Derived>
7897StmtResult
7898TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7899 StmtDiscardKind SDK) {
7900 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7901 if (SubStmt.isInvalid())
7902 return StmtError();
7903
7904 bool AttrsChanged = false;
7905 SmallVector<const Attr *, 1> Attrs;
7906
7907 // Visit attributes and keep track if any are transformed.
7908 for (const auto *I : S->getAttrs()) {
7909 const Attr *R =
7910 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7911 AttrsChanged |= (I != R);
7912 if (R)
7913 Attrs.push_back(R);
7914 }
7915
7916 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7917 return S;
7918
7919 // If transforming the attributes failed for all of the attributes in the
7920 // statement, don't make an AttributedStmt without attributes.
7921 if (Attrs.empty())
7922 return SubStmt;
7923
7924 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7925 SubStmt.get());
7926}
7927
7928template<typename Derived>
7929StmtResult
7930TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7931 // Transform the initialization statement
7932 StmtResult Init = getDerived().TransformStmt(S->getInit());
7933 if (Init.isInvalid())
7934 return StmtError();
7935
7936 Sema::ConditionResult Cond;
7937 if (!S->isConsteval()) {
7938 // Transform the condition
7939 Cond = getDerived().TransformCondition(
7940 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7941 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7942 : Sema::ConditionKind::Boolean);
7943 if (Cond.isInvalid())
7944 return StmtError();
7945 }
7946
7947 // If this is a constexpr if, determine which arm we should instantiate.
7948 std::optional<bool> ConstexprConditionValue;
7949 if (S->isConstexpr())
7950 ConstexprConditionValue = Cond.getKnownValue();
7951
7952 // Transform the "then" branch.
7953 StmtResult Then;
7954 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7955 Then = getDerived().TransformStmt(S->getThen());
7956 if (Then.isInvalid())
7957 return StmtError();
7958 } else {
7959 // Discarded branch is replaced with empty CompoundStmt so we can keep
7960 // proper source location for start and end of original branch, so
7961 // subsequent transformations like CoverageMapping work properly
7962 Then = new (getSema().Context)
7963 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
7964 }
7965
7966 // Transform the "else" branch.
7967 StmtResult Else;
7968 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7969 Else = getDerived().TransformStmt(S->getElse());
7970 if (Else.isInvalid())
7971 return StmtError();
7972 } else if (S->getElse() && ConstexprConditionValue &&
7973 *ConstexprConditionValue) {
7974 // Same thing here as with <then> branch, we are discarding it, we can't
7975 // replace it with NULL nor NullStmt as we need to keep for source location
7976 // range, for CoverageMapping
7977 Else = new (getSema().Context)
7978 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
7979 }
7980
7981 if (!getDerived().AlwaysRebuild() &&
7982 Init.get() == S->getInit() &&
7983 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7984 Then.get() == S->getThen() &&
7985 Else.get() == S->getElse())
7986 return S;
7987
7988 return getDerived().RebuildIfStmt(
7989 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
7990 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
7991}
7992
7993template<typename Derived>
7994StmtResult
7995TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
7996 // Transform the initialization statement
7997 StmtResult Init = getDerived().TransformStmt(S->getInit());
7998 if (Init.isInvalid())
7999 return StmtError();
8000
8001 // Transform the condition.
8002 Sema::ConditionResult Cond = getDerived().TransformCondition(
8003 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8004 Sema::ConditionKind::Switch);
8005 if (Cond.isInvalid())
8006 return StmtError();
8007
8008 // Rebuild the switch statement.
8009 StmtResult Switch =
8010 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8011 Init.get(), Cond, S->getRParenLoc());
8012 if (Switch.isInvalid())
8013 return StmtError();
8014
8015 // Transform the body of the switch statement.
8016 StmtResult Body = getDerived().TransformStmt(S->getBody());
8017 if (Body.isInvalid())
8018 return StmtError();
8019
8020 // Complete the switch statement.
8021 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8022 Body.get());
8023}
8024
8025template<typename Derived>
8026StmtResult
8027TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8028 // Transform the condition
8029 Sema::ConditionResult Cond = getDerived().TransformCondition(
8030 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8031 Sema::ConditionKind::Boolean);
8032 if (Cond.isInvalid())
8033 return StmtError();
8034
8035 // Transform the body
8036 StmtResult Body = getDerived().TransformStmt(S->getBody());
8037 if (Body.isInvalid())
8038 return StmtError();
8039
8040 if (!getDerived().AlwaysRebuild() &&
8041 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8042 Body.get() == S->getBody())
8043 return Owned(S);
8044
8045 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8046 Cond, S->getRParenLoc(), Body.get());
8047}
8048
8049template<typename Derived>
8050StmtResult
8051TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8052 // Transform the body
8053 StmtResult Body = getDerived().TransformStmt(S->getBody());
8054 if (Body.isInvalid())
8055 return StmtError();
8056
8057 // Transform the condition
8058 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8059 if (Cond.isInvalid())
8060 return StmtError();
8061
8062 if (!getDerived().AlwaysRebuild() &&
8063 Cond.get() == S->getCond() &&
8064 Body.get() == S->getBody())
8065 return S;
8066
8067 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8068 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8069 S->getRParenLoc());
8070}
8071
8072template<typename Derived>
8073StmtResult
8074TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8075 if (getSema().getLangOpts().OpenMP)
8076 getSema().OpenMP().startOpenMPLoop();
8077
8078 // Transform the initialization statement
8079 StmtResult Init = getDerived().TransformStmt(S->getInit());
8080 if (Init.isInvalid())
8081 return StmtError();
8082
8083 // In OpenMP loop region loop control variable must be captured and be
8084 // private. Perform analysis of first part (if any).
8085 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8086 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8087 Init.get());
8088
8089 // Transform the condition
8090 Sema::ConditionResult Cond = getDerived().TransformCondition(
8091 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8092 Sema::ConditionKind::Boolean);
8093 if (Cond.isInvalid())
8094 return StmtError();
8095
8096 // Transform the increment
8097 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8098 if (Inc.isInvalid())
8099 return StmtError();
8100
8101 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8102 if (S->getInc() && !FullInc.get())
8103 return StmtError();
8104
8105 // Transform the body
8106 StmtResult Body = getDerived().TransformStmt(S->getBody());
8107 if (Body.isInvalid())
8108 return StmtError();
8109
8110 if (!getDerived().AlwaysRebuild() &&
8111 Init.get() == S->getInit() &&
8112 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8113 Inc.get() == S->getInc() &&
8114 Body.get() == S->getBody())
8115 return S;
8116
8117 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8118 Init.get(), Cond, FullInc,
8119 S->getRParenLoc(), Body.get());
8120}
8121
8122template<typename Derived>
8123StmtResult
8124TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8125 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8126 S->getLabel());
8127 if (!LD)
8128 return StmtError();
8129
8130 // Goto statements must always be rebuilt, to resolve the label.
8131 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8132 cast<LabelDecl>(LD));
8133}
8134
8135template<typename Derived>
8136StmtResult
8137TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8138 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8139 if (Target.isInvalid())
8140 return StmtError();
8141 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8142
8143 if (!getDerived().AlwaysRebuild() &&
8144 Target.get() == S->getTarget())
8145 return S;
8146
8147 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8148 Target.get());
8149}
8150
8151template<typename Derived>
8152StmtResult
8153TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8154 return S;
8155}
8156
8157template<typename Derived>
8158StmtResult
8159TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8160 return S;
8161}
8162
8163template<typename Derived>
8164StmtResult
8165TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8166 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8167 /*NotCopyInit*/false);
8168 if (Result.isInvalid())
8169 return StmtError();
8170
8171 // FIXME: We always rebuild the return statement because there is no way
8172 // to tell whether the return type of the function has changed.
8173 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8174}
8175
8176template<typename Derived>
8177StmtResult
8178TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8179 bool DeclChanged = false;
8180 SmallVector<Decl *, 4> Decls;
8181 for (auto *D : S->decls()) {
8182 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8183 if (!Transformed)
8184 return StmtError();
8185
8186 if (Transformed != D)
8187 DeclChanged = true;
8188
8189 Decls.push_back(Transformed);
8190 }
8191
8192 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8193 return S;
8194
8195 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8196}
8197
8198template<typename Derived>
8199StmtResult
8200TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8201
8202 SmallVector<Expr*, 8> Constraints;
8203 SmallVector<Expr*, 8> Exprs;
8204 SmallVector<IdentifierInfo *, 4> Names;
8205
8206 ExprResult AsmString;
8207 SmallVector<Expr*, 8> Clobbers;
8208
8209 bool ExprsChanged = false;
8210
8211 // Go through the outputs.
8212 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8213 Names.push_back(S->getOutputIdentifier(i: I));
8214
8215 // No need to transform the constraint literal.
8216 Constraints.push_back(S->getOutputConstraintLiteral(i: I));
8217
8218 // Transform the output expr.
8219 Expr *OutputExpr = S->getOutputExpr(i: I);
8220 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8221 if (Result.isInvalid())
8222 return StmtError();
8223
8224 ExprsChanged |= Result.get() != OutputExpr;
8225
8226 Exprs.push_back(Result.get());
8227 }
8228
8229 // Go through the inputs.
8230 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8231 Names.push_back(S->getInputIdentifier(i: I));
8232
8233 // No need to transform the constraint literal.
8234 Constraints.push_back(S->getInputConstraintLiteral(i: I));
8235
8236 // Transform the input expr.
8237 Expr *InputExpr = S->getInputExpr(i: I);
8238 ExprResult Result = getDerived().TransformExpr(InputExpr);
8239 if (Result.isInvalid())
8240 return StmtError();
8241
8242 ExprsChanged |= Result.get() != InputExpr;
8243
8244 Exprs.push_back(Result.get());
8245 }
8246
8247 // Go through the Labels.
8248 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8249 Names.push_back(S->getLabelIdentifier(i: I));
8250
8251 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8252 if (Result.isInvalid())
8253 return StmtError();
8254 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8255 Exprs.push_back(Result.get());
8256 }
8257 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8258 return S;
8259
8260 // Go through the clobbers.
8261 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8262 Clobbers.push_back(S->getClobberStringLiteral(i: I));
8263
8264 // No need to transform the asm string literal.
8265 AsmString = S->getAsmString();
8266 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8267 S->isVolatile(), S->getNumOutputs(),
8268 S->getNumInputs(), Names.data(),
8269 Constraints, Exprs, AsmString.get(),
8270 Clobbers, S->getNumLabels(),
8271 S->getRParenLoc());
8272}
8273
8274template<typename Derived>
8275StmtResult
8276TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8277 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8278
8279 bool HadError = false, HadChange = false;
8280
8281 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8282 SmallVector<Expr*, 8> TransformedExprs;
8283 TransformedExprs.reserve(SrcExprs.size());
8284 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8285 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8286 if (!Result.isUsable()) {
8287 HadError = true;
8288 } else {
8289 HadChange |= (Result.get() != SrcExprs[i]);
8290 TransformedExprs.push_back(Result.get());
8291 }
8292 }
8293
8294 if (HadError) return StmtError();
8295 if (!HadChange && !getDerived().AlwaysRebuild())
8296 return Owned(S);
8297
8298 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8299 AsmToks, S->getAsmString(),
8300 S->getNumOutputs(), S->getNumInputs(),
8301 S->getAllConstraints(), S->getClobbers(),
8302 TransformedExprs, S->getEndLoc());
8303}
8304
8305// C++ Coroutines
8306template<typename Derived>
8307StmtResult
8308TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8309 auto *ScopeInfo = SemaRef.getCurFunction();
8310 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8311 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8312 ScopeInfo->NeedsCoroutineSuspends &&
8313 ScopeInfo->CoroutineSuspends.first == nullptr &&
8314 ScopeInfo->CoroutineSuspends.second == nullptr &&
8315 "expected clean scope info");
8316
8317 // Set that we have (possibly-invalid) suspend points before we do anything
8318 // that may fail.
8319 ScopeInfo->setNeedsCoroutineSuspends(false);
8320
8321 // We re-build the coroutine promise object (and the coroutine parameters its
8322 // type and constructor depend on) based on the types used in our current
8323 // function. We must do so, and set it on the current FunctionScopeInfo,
8324 // before attempting to transform the other parts of the coroutine body
8325 // statement, such as the implicit suspend statements (because those
8326 // statements reference the FunctionScopeInfo::CoroutinePromise).
8327 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8328 return StmtError();
8329 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8330 if (!Promise)
8331 return StmtError();
8332 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8333 ScopeInfo->CoroutinePromise = Promise;
8334
8335 // Transform the implicit coroutine statements constructed using dependent
8336 // types during the previous parse: initial and final suspensions, the return
8337 // object, and others. We also transform the coroutine function's body.
8338 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8339 if (InitSuspend.isInvalid())
8340 return StmtError();
8341 StmtResult FinalSuspend =
8342 getDerived().TransformStmt(S->getFinalSuspendStmt());
8343 if (FinalSuspend.isInvalid() ||
8344 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8345 return StmtError();
8346 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8347 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8348
8349 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8350 if (BodyRes.isInvalid())
8351 return StmtError();
8352
8353 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8354 if (Builder.isInvalid())
8355 return StmtError();
8356
8357 Expr *ReturnObject = S->getReturnValueInit();
8358 assert(ReturnObject && "the return object is expected to be valid");
8359 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8360 /*NoCopyInit*/ false);
8361 if (Res.isInvalid())
8362 return StmtError();
8363 Builder.ReturnValue = Res.get();
8364
8365 // If during the previous parse the coroutine still had a dependent promise
8366 // statement, we may need to build some implicit coroutine statements
8367 // (such as exception and fallthrough handlers) for the first time.
8368 if (S->hasDependentPromiseType()) {
8369 // We can only build these statements, however, if the current promise type
8370 // is not dependent.
8371 if (!Promise->getType()->isDependentType()) {
8372 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8373 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8374 "these nodes should not have been built yet");
8375 if (!Builder.buildDependentStatements())
8376 return StmtError();
8377 }
8378 } else {
8379 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8380 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8381 if (Res.isInvalid())
8382 return StmtError();
8383 Builder.OnFallthrough = Res.get();
8384 }
8385
8386 if (auto *OnException = S->getExceptionHandler()) {
8387 StmtResult Res = getDerived().TransformStmt(OnException);
8388 if (Res.isInvalid())
8389 return StmtError();
8390 Builder.OnException = Res.get();
8391 }
8392
8393 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8394 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8395 if (Res.isInvalid())
8396 return StmtError();
8397 Builder.ReturnStmtOnAllocFailure = Res.get();
8398 }
8399
8400 // Transform any additional statements we may have already built
8401 assert(S->getAllocate() && S->getDeallocate() &&
8402 "allocation and deallocation calls must already be built");
8403 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8404 if (AllocRes.isInvalid())
8405 return StmtError();
8406 Builder.Allocate = AllocRes.get();
8407
8408 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8409 if (DeallocRes.isInvalid())
8410 return StmtError();
8411 Builder.Deallocate = DeallocRes.get();
8412
8413 if (auto *ResultDecl = S->getResultDecl()) {
8414 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8415 if (Res.isInvalid())
8416 return StmtError();
8417 Builder.ResultDecl = Res.get();
8418 }
8419
8420 if (auto *ReturnStmt = S->getReturnStmt()) {
8421 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8422 if (Res.isInvalid())
8423 return StmtError();
8424 Builder.ReturnStmt = Res.get();
8425 }
8426 }
8427
8428 return getDerived().RebuildCoroutineBodyStmt(Builder);
8429}
8430
8431template<typename Derived>
8432StmtResult
8433TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8434 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8435 /*NotCopyInit*/false);
8436 if (Result.isInvalid())
8437 return StmtError();
8438
8439 // Always rebuild; we don't know if this needs to be injected into a new
8440 // context or if the promise type has changed.
8441 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8442 S->isImplicit());
8443}
8444
8445template <typename Derived>
8446ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8447 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8448 /*NotCopyInit*/ false);
8449 if (Operand.isInvalid())
8450 return ExprError();
8451
8452 // Rebuild the common-expr from the operand rather than transforming it
8453 // separately.
8454
8455 // FIXME: getCurScope() should not be used during template instantiation.
8456 // We should pick up the set of unqualified lookup results for operator
8457 // co_await during the initial parse.
8458 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8459 getSema().getCurScope(), E->getKeywordLoc());
8460
8461 // Always rebuild; we don't know if this needs to be injected into a new
8462 // context or if the promise type has changed.
8463 return getDerived().RebuildCoawaitExpr(
8464 E->getKeywordLoc(), Operand.get(),
8465 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8466}
8467
8468template <typename Derived>
8469ExprResult
8470TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8471 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8472 /*NotCopyInit*/ false);
8473 if (OperandResult.isInvalid())
8474 return ExprError();
8475
8476 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8477 E->getOperatorCoawaitLookup());
8478
8479 if (LookupResult.isInvalid())
8480 return ExprError();
8481
8482 // Always rebuild; we don't know if this needs to be injected into a new
8483 // context or if the promise type has changed.
8484 return getDerived().RebuildDependentCoawaitExpr(
8485 E->getKeywordLoc(), OperandResult.get(),
8486 cast<UnresolvedLookupExpr>(LookupResult.get()));
8487}
8488
8489template<typename Derived>
8490ExprResult
8491TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8492 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8493 /*NotCopyInit*/false);
8494 if (Result.isInvalid())
8495 return ExprError();
8496
8497 // Always rebuild; we don't know if this needs to be injected into a new
8498 // context or if the promise type has changed.
8499 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8500}
8501
8502// Objective-C Statements.
8503
8504template<typename Derived>
8505StmtResult
8506TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8507 // Transform the body of the @try.
8508 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8509 if (TryBody.isInvalid())
8510 return StmtError();
8511
8512 // Transform the @catch statements (if present).
8513 bool AnyCatchChanged = false;
8514 SmallVector<Stmt*, 8> CatchStmts;
8515 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8516 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8517 if (Catch.isInvalid())
8518 return StmtError();
8519 if (Catch.get() != S->getCatchStmt(I))
8520 AnyCatchChanged = true;
8521 CatchStmts.push_back(Catch.get());
8522 }
8523
8524 // Transform the @finally statement (if present).
8525 StmtResult Finally;
8526 if (S->getFinallyStmt()) {
8527 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8528 if (Finally.isInvalid())
8529 return StmtError();
8530 }
8531
8532 // If nothing changed, just retain this statement.
8533 if (!getDerived().AlwaysRebuild() &&
8534 TryBody.get() == S->getTryBody() &&
8535 !AnyCatchChanged &&
8536 Finally.get() == S->getFinallyStmt())
8537 return S;
8538
8539 // Build a new statement.
8540 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8541 CatchStmts, Finally.get());
8542}
8543
8544template<typename Derived>
8545StmtResult
8546TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8547 // Transform the @catch parameter, if there is one.
8548 VarDecl *Var = nullptr;
8549 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8550 TypeSourceInfo *TSInfo = nullptr;
8551 if (FromVar->getTypeSourceInfo()) {
8552 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8553 if (!TSInfo)
8554 return StmtError();
8555 }
8556
8557 QualType T;
8558 if (TSInfo)
8559 T = TSInfo->getType();
8560 else {
8561 T = getDerived().TransformType(FromVar->getType());
8562 if (T.isNull())
8563 return StmtError();
8564 }
8565
8566 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8567 if (!Var)
8568 return StmtError();
8569 }
8570
8571 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8572 if (Body.isInvalid())
8573 return StmtError();
8574
8575 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8576 S->getRParenLoc(),
8577 Var, Body.get());
8578}
8579
8580template<typename Derived>
8581StmtResult
8582TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8583 // Transform the body.
8584 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8585 if (Body.isInvalid())
8586 return StmtError();
8587
8588 // If nothing changed, just retain this statement.
8589 if (!getDerived().AlwaysRebuild() &&
8590 Body.get() == S->getFinallyBody())
8591 return S;
8592
8593 // Build a new statement.
8594 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8595 Body.get());
8596}
8597
8598template<typename Derived>
8599StmtResult
8600TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8601 ExprResult Operand;
8602 if (S->getThrowExpr()) {
8603 Operand = getDerived().TransformExpr(S->getThrowExpr());
8604 if (Operand.isInvalid())
8605 return StmtError();
8606 }
8607
8608 if (!getDerived().AlwaysRebuild() &&
8609 Operand.get() == S->getThrowExpr())
8610 return S;
8611
8612 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8613}
8614
8615template<typename Derived>
8616StmtResult
8617TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8618 ObjCAtSynchronizedStmt *S) {
8619 // Transform the object we are locking.
8620 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8621 if (Object.isInvalid())
8622 return StmtError();
8623 Object =
8624 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8625 Object.get());
8626 if (Object.isInvalid())
8627 return StmtError();
8628
8629 // Transform the body.
8630 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8631 if (Body.isInvalid())
8632 return StmtError();
8633
8634 // If nothing change, just retain the current statement.
8635 if (!getDerived().AlwaysRebuild() &&
8636 Object.get() == S->getSynchExpr() &&
8637 Body.get() == S->getSynchBody())
8638 return S;
8639
8640 // Build a new statement.
8641 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8642 Object.get(), Body.get());
8643}
8644
8645template<typename Derived>
8646StmtResult
8647TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8648 ObjCAutoreleasePoolStmt *S) {
8649 // Transform the body.
8650 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8651 if (Body.isInvalid())
8652 return StmtError();
8653
8654 // If nothing changed, just retain this statement.
8655 if (!getDerived().AlwaysRebuild() &&
8656 Body.get() == S->getSubStmt())
8657 return S;
8658
8659 // Build a new statement.
8660 return getDerived().RebuildObjCAutoreleasePoolStmt(
8661 S->getAtLoc(), Body.get());
8662}
8663
8664template<typename Derived>
8665StmtResult
8666TreeTransform<Derived>::TransformObjCForCollectionStmt(
8667 ObjCForCollectionStmt *S) {
8668 // Transform the element statement.
8669 StmtResult Element =
8670 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8671 if (Element.isInvalid())
8672 return StmtError();
8673
8674 // Transform the collection expression.
8675 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8676 if (Collection.isInvalid())
8677 return StmtError();
8678
8679 // Transform the body.
8680 StmtResult Body = getDerived().TransformStmt(S->getBody());
8681 if (Body.isInvalid())
8682 return StmtError();
8683
8684 // If nothing changed, just retain this statement.
8685 if (!getDerived().AlwaysRebuild() &&
8686 Element.get() == S->getElement() &&
8687 Collection.get() == S->getCollection() &&
8688 Body.get() == S->getBody())
8689 return S;
8690
8691 // Build a new statement.
8692 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8693 Element.get(),
8694 Collection.get(),
8695 S->getRParenLoc(),
8696 Body.get());
8697}
8698
8699template <typename Derived>
8700StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8701 // Transform the exception declaration, if any.
8702 VarDecl *Var = nullptr;
8703 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8704 TypeSourceInfo *T =
8705 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8706 if (!T)
8707 return StmtError();
8708
8709 Var = getDerived().RebuildExceptionDecl(
8710 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8711 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8712 if (!Var || Var->isInvalidDecl())
8713 return StmtError();
8714 }
8715
8716 // Transform the actual exception handler.
8717 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8718 if (Handler.isInvalid())
8719 return StmtError();
8720
8721 if (!getDerived().AlwaysRebuild() && !Var &&
8722 Handler.get() == S->getHandlerBlock())
8723 return S;
8724
8725 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8726}
8727
8728template <typename Derived>
8729StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8730 // Transform the try block itself.
8731 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8732 if (TryBlock.isInvalid())
8733 return StmtError();
8734
8735 // Transform the handlers.
8736 bool HandlerChanged = false;
8737 SmallVector<Stmt *, 8> Handlers;
8738 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8739 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
8740 if (Handler.isInvalid())
8741 return StmtError();
8742
8743 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
8744 Handlers.push_back(Handler.getAs<Stmt>());
8745 }
8746
8747 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8748 !HandlerChanged)
8749 return S;
8750
8751 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8752 Handlers);
8753}
8754
8755template<typename Derived>
8756StmtResult
8757TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8758 EnterExpressionEvaluationContext ForRangeInitContext(
8759 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
8760 /*LambdaContextDecl=*/nullptr,
8761 Sema::ExpressionEvaluationContextRecord::EK_Other,
8762 getSema().getLangOpts().CPlusPlus23);
8763
8764 // P2718R0 - Lifetime extension in range-based for loops.
8765 if (getSema().getLangOpts().CPlusPlus23) {
8766 auto &LastRecord = getSema().ExprEvalContexts.back();
8767 LastRecord.InLifetimeExtendingContext = true;
8768 }
8769 StmtResult Init =
8770 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8771 if (Init.isInvalid())
8772 return StmtError();
8773
8774 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8775 if (Range.isInvalid())
8776 return StmtError();
8777
8778 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
8779 assert(getSema().getLangOpts().CPlusPlus23 ||
8780 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
8781 auto ForRangeLifetimeExtendTemps =
8782 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
8783
8784 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8785 if (Begin.isInvalid())
8786 return StmtError();
8787 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8788 if (End.isInvalid())
8789 return StmtError();
8790
8791 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8792 if (Cond.isInvalid())
8793 return StmtError();
8794 if (Cond.get())
8795 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
8796 if (Cond.isInvalid())
8797 return StmtError();
8798 if (Cond.get())
8799 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
8800
8801 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8802 if (Inc.isInvalid())
8803 return StmtError();
8804 if (Inc.get())
8805 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
8806
8807 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8808 if (LoopVar.isInvalid())
8809 return StmtError();
8810
8811 StmtResult NewStmt = S;
8812 if (getDerived().AlwaysRebuild() ||
8813 Init.get() != S->getInit() ||
8814 Range.get() != S->getRangeStmt() ||
8815 Begin.get() != S->getBeginStmt() ||
8816 End.get() != S->getEndStmt() ||
8817 Cond.get() != S->getCond() ||
8818 Inc.get() != S->getInc() ||
8819 LoopVar.get() != S->getLoopVarStmt()) {
8820 NewStmt = getDerived().RebuildCXXForRangeStmt(
8821 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8822 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8823 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8824 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8825 // Might not have attached any initializer to the loop variable.
8826 getSema().ActOnInitializerError(
8827 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8828 return StmtError();
8829 }
8830 }
8831
8832 StmtResult Body = getDerived().TransformStmt(S->getBody());
8833 if (Body.isInvalid())
8834 return StmtError();
8835
8836 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8837 // it now so we have a new statement to attach the body to.
8838 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8839 NewStmt = getDerived().RebuildCXXForRangeStmt(
8840 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8841 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8842 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8843 if (NewStmt.isInvalid())
8844 return StmtError();
8845 }
8846
8847 if (NewStmt.get() == S)
8848 return S;
8849
8850 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
8851}
8852
8853template<typename Derived>
8854StmtResult
8855TreeTransform<Derived>::TransformMSDependentExistsStmt(
8856 MSDependentExistsStmt *S) {
8857 // Transform the nested-name-specifier, if any.
8858 NestedNameSpecifierLoc QualifierLoc;
8859 if (S->getQualifierLoc()) {
8860 QualifierLoc
8861 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8862 if (!QualifierLoc)
8863 return StmtError();
8864 }
8865
8866 // Transform the declaration name.
8867 DeclarationNameInfo NameInfo = S->getNameInfo();
8868 if (NameInfo.getName()) {
8869 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8870 if (!NameInfo.getName())
8871 return StmtError();
8872 }
8873
8874 // Check whether anything changed.
8875 if (!getDerived().AlwaysRebuild() &&
8876 QualifierLoc == S->getQualifierLoc() &&
8877 NameInfo.getName() == S->getNameInfo().getName())
8878 return S;
8879
8880 // Determine whether this name exists, if we can.
8881 CXXScopeSpec SS;
8882 SS.Adopt(Other: QualifierLoc);
8883 bool Dependent = false;
8884 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8885 case Sema::IER_Exists:
8886 if (S->isIfExists())
8887 break;
8888
8889 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8890
8891 case Sema::IER_DoesNotExist:
8892 if (S->isIfNotExists())
8893 break;
8894
8895 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8896
8897 case Sema::IER_Dependent:
8898 Dependent = true;
8899 break;
8900
8901 case Sema::IER_Error:
8902 return StmtError();
8903 }
8904
8905 // We need to continue with the instantiation, so do so now.
8906 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8907 if (SubStmt.isInvalid())
8908 return StmtError();
8909
8910 // If we have resolved the name, just transform to the substatement.
8911 if (!Dependent)
8912 return SubStmt;
8913
8914 // The name is still dependent, so build a dependent expression again.
8915 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8916 S->isIfExists(),
8917 QualifierLoc,
8918 NameInfo,
8919 SubStmt.get());
8920}
8921
8922template<typename Derived>
8923ExprResult
8924TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8925 NestedNameSpecifierLoc QualifierLoc;
8926 if (E->getQualifierLoc()) {
8927 QualifierLoc
8928 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8929 if (!QualifierLoc)
8930 return ExprError();
8931 }
8932
8933 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8934 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8935 if (!PD)
8936 return ExprError();
8937
8938 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8939 if (Base.isInvalid())
8940 return ExprError();
8941
8942 return new (SemaRef.getASTContext())
8943 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8944 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
8945 QualifierLoc, E->getMemberLoc());
8946}
8947
8948template <typename Derived>
8949ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8950 MSPropertySubscriptExpr *E) {
8951 auto BaseRes = getDerived().TransformExpr(E->getBase());
8952 if (BaseRes.isInvalid())
8953 return ExprError();
8954 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8955 if (IdxRes.isInvalid())
8956 return ExprError();
8957
8958 if (!getDerived().AlwaysRebuild() &&
8959 BaseRes.get() == E->getBase() &&
8960 IdxRes.get() == E->getIdx())
8961 return E;
8962
8963 return getDerived().RebuildArraySubscriptExpr(
8964 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8965}
8966
8967template <typename Derived>
8968StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8969 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8970 if (TryBlock.isInvalid())
8971 return StmtError();
8972
8973 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8974 if (Handler.isInvalid())
8975 return StmtError();
8976
8977 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8978 Handler.get() == S->getHandler())
8979 return S;
8980
8981 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8982 TryBlock.get(), Handler.get());
8983}
8984
8985template <typename Derived>
8986StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
8987 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8988 if (Block.isInvalid())
8989 return StmtError();
8990
8991 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
8992}
8993
8994template <typename Derived>
8995StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
8996 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
8997 if (FilterExpr.isInvalid())
8998 return StmtError();
8999
9000 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9001 if (Block.isInvalid())
9002 return StmtError();
9003
9004 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9005 Block.get());
9006}
9007
9008template <typename Derived>
9009StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9010 if (isa<SEHFinallyStmt>(Handler))
9011 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9012 else
9013 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9014}
9015
9016template<typename Derived>
9017StmtResult
9018TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9019 return S;
9020}
9021
9022//===----------------------------------------------------------------------===//
9023// OpenMP directive transformation
9024//===----------------------------------------------------------------------===//
9025
9026template <typename Derived>
9027StmtResult
9028TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9029 // OMPCanonicalLoops are eliminated during transformation, since they will be
9030 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9031 // after transformation.
9032 return getDerived().TransformStmt(L->getLoopStmt());
9033}
9034
9035template <typename Derived>
9036StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9037 OMPExecutableDirective *D) {
9038
9039 // Transform the clauses
9040 llvm::SmallVector<OMPClause *, 16> TClauses;
9041 ArrayRef<OMPClause *> Clauses = D->clauses();
9042 TClauses.reserve(Clauses.size());
9043 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9044 I != E; ++I) {
9045 if (*I) {
9046 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9047 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9048 getDerived().getSema().OpenMP().EndOpenMPClause();
9049 if (Clause)
9050 TClauses.push_back(Clause);
9051 } else {
9052 TClauses.push_back(nullptr);
9053 }
9054 }
9055 StmtResult AssociatedStmt;
9056 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9057 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9058 D->getDirectiveKind(),
9059 /*CurScope=*/nullptr);
9060 StmtResult Body;
9061 {
9062 Sema::CompoundScopeRAII CompoundScope(getSema());
9063 Stmt *CS;
9064 if (D->getDirectiveKind() == OMPD_atomic ||
9065 D->getDirectiveKind() == OMPD_critical ||
9066 D->getDirectiveKind() == OMPD_section ||
9067 D->getDirectiveKind() == OMPD_master)
9068 CS = D->getAssociatedStmt();
9069 else
9070 CS = D->getRawStmt();
9071 Body = getDerived().TransformStmt(CS);
9072 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9073 getSema().getLangOpts().OpenMPIRBuilder)
9074 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9075 }
9076 AssociatedStmt =
9077 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9078 if (AssociatedStmt.isInvalid()) {
9079 return StmtError();
9080 }
9081 }
9082 if (TClauses.size() != Clauses.size()) {
9083 return StmtError();
9084 }
9085
9086 // Transform directive name for 'omp critical' directive.
9087 DeclarationNameInfo DirName;
9088 if (D->getDirectiveKind() == OMPD_critical) {
9089 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9090 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9091 }
9092 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9093 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9094 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9095 } else if (D->getDirectiveKind() == OMPD_cancel) {
9096 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9097 }
9098
9099 return getDerived().RebuildOMPExecutableDirective(
9100 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9101 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
9102 D->getMappedDirective());
9103}
9104
9105template <typename Derived>
9106StmtResult
9107TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9108 // TODO: Fix This
9109 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9110 << getOpenMPDirectiveName(D->getDirectiveKind());
9111 return StmtError();
9112}
9113
9114template <typename Derived>
9115StmtResult
9116TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9117 DeclarationNameInfo DirName;
9118 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9119 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9120 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9121 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9122 return Res;
9123}
9124
9125template <typename Derived>
9126StmtResult
9127TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9128 DeclarationNameInfo DirName;
9129 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9130 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9131 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9132 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9133 return Res;
9134}
9135
9136template <typename Derived>
9137StmtResult
9138TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9139 DeclarationNameInfo DirName;
9140 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9141 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9142 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9143 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9144 return Res;
9145}
9146
9147template <typename Derived>
9148StmtResult
9149TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9150 DeclarationNameInfo DirName;
9151 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9152 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9153 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9154 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9155 return Res;
9156}
9157
9158template <typename Derived>
9159StmtResult
9160TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9161 DeclarationNameInfo DirName;
9162 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9163 OMPD_for, DirName, nullptr, D->getBeginLoc());
9164 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9165 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9166 return Res;
9167}
9168
9169template <typename Derived>
9170StmtResult
9171TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9172 DeclarationNameInfo DirName;
9173 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9174 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9175 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9176 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9177 return Res;
9178}
9179
9180template <typename Derived>
9181StmtResult
9182TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9183 DeclarationNameInfo DirName;
9184 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9185 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9186 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9187 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9188 return Res;
9189}
9190
9191template <typename Derived>
9192StmtResult
9193TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9194 DeclarationNameInfo DirName;
9195 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9196 OMPD_section, DirName, nullptr, D->getBeginLoc());
9197 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9198 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9199 return Res;
9200}
9201
9202template <typename Derived>
9203StmtResult
9204TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9205 DeclarationNameInfo DirName;
9206 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9207 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9208 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9209 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9210 return Res;
9211}
9212
9213template <typename Derived>
9214StmtResult
9215TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9216 DeclarationNameInfo DirName;
9217 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9218 OMPD_single, DirName, nullptr, D->getBeginLoc());
9219 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9220 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9221 return Res;
9222}
9223
9224template <typename Derived>
9225StmtResult
9226TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9227 DeclarationNameInfo DirName;
9228 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9229 OMPD_master, DirName, nullptr, D->getBeginLoc());
9230 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9231 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9232 return Res;
9233}
9234
9235template <typename Derived>
9236StmtResult
9237TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9238 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9239 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9240 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9241 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9242 return Res;
9243}
9244
9245template <typename Derived>
9246StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9247 OMPParallelForDirective *D) {
9248 DeclarationNameInfo DirName;
9249 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9250 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9251 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9252 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9253 return Res;
9254}
9255
9256template <typename Derived>
9257StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9258 OMPParallelForSimdDirective *D) {
9259 DeclarationNameInfo DirName;
9260 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9261 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9262 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9263 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9264 return Res;
9265}
9266
9267template <typename Derived>
9268StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9269 OMPParallelMasterDirective *D) {
9270 DeclarationNameInfo DirName;
9271 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9272 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9273 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9274 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9275 return Res;
9276}
9277
9278template <typename Derived>
9279StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9280 OMPParallelMaskedDirective *D) {
9281 DeclarationNameInfo DirName;
9282 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9283 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9284 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9285 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9286 return Res;
9287}
9288
9289template <typename Derived>
9290StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9291 OMPParallelSectionsDirective *D) {
9292 DeclarationNameInfo DirName;
9293 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9294 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9295 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9296 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9297 return Res;
9298}
9299
9300template <typename Derived>
9301StmtResult
9302TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9303 DeclarationNameInfo DirName;
9304 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9305 OMPD_task, DirName, nullptr, D->getBeginLoc());
9306 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9307 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9308 return Res;
9309}
9310
9311template <typename Derived>
9312StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9313 OMPTaskyieldDirective *D) {
9314 DeclarationNameInfo DirName;
9315 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9316 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9317 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9318 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9319 return Res;
9320}
9321
9322template <typename Derived>
9323StmtResult
9324TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9325 DeclarationNameInfo DirName;
9326 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9327 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9328 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9329 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9330 return Res;
9331}
9332
9333template <typename Derived>
9334StmtResult
9335TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9336 DeclarationNameInfo DirName;
9337 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9338 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9339 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9340 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9341 return Res;
9342}
9343
9344template <typename Derived>
9345StmtResult
9346TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9347 DeclarationNameInfo DirName;
9348 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9349 OMPD_error, DirName, nullptr, D->getBeginLoc());
9350 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9351 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9352 return Res;
9353}
9354
9355template <typename Derived>
9356StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9357 OMPTaskgroupDirective *D) {
9358 DeclarationNameInfo DirName;
9359 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9360 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9361 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9362 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9363 return Res;
9364}
9365
9366template <typename Derived>
9367StmtResult
9368TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9369 DeclarationNameInfo DirName;
9370 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9371 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9372 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9373 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9374 return Res;
9375}
9376
9377template <typename Derived>
9378StmtResult
9379TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9380 DeclarationNameInfo DirName;
9381 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9382 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9383 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9384 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9385 return Res;
9386}
9387
9388template <typename Derived>
9389StmtResult
9390TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9391 DeclarationNameInfo DirName;
9392 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9393 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9394 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9395 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9396 return Res;
9397}
9398
9399template <typename Derived>
9400StmtResult
9401TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9402 DeclarationNameInfo DirName;
9403 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9404 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9405 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9406 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9407 return Res;
9408}
9409
9410template <typename Derived>
9411StmtResult
9412TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9413 DeclarationNameInfo DirName;
9414 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9415 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9416 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9417 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9418 return Res;
9419}
9420
9421template <typename Derived>
9422StmtResult
9423TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9424 DeclarationNameInfo DirName;
9425 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9426 OMPD_target, DirName, nullptr, D->getBeginLoc());
9427 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9428 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9429 return Res;
9430}
9431
9432template <typename Derived>
9433StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9434 OMPTargetDataDirective *D) {
9435 DeclarationNameInfo DirName;
9436 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9437 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9438 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9439 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9440 return Res;
9441}
9442
9443template <typename Derived>
9444StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9445 OMPTargetEnterDataDirective *D) {
9446 DeclarationNameInfo DirName;
9447 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9448 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9449 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9450 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9451 return Res;
9452}
9453
9454template <typename Derived>
9455StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9456 OMPTargetExitDataDirective *D) {
9457 DeclarationNameInfo DirName;
9458 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9459 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9460 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9461 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9462 return Res;
9463}
9464
9465template <typename Derived>
9466StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9467 OMPTargetParallelDirective *D) {
9468 DeclarationNameInfo DirName;
9469 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9470 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9471 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9472 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9473 return Res;
9474}
9475
9476template <typename Derived>
9477StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9478 OMPTargetParallelForDirective *D) {
9479 DeclarationNameInfo DirName;
9480 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9481 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9482 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9483 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9484 return Res;
9485}
9486
9487template <typename Derived>
9488StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9489 OMPTargetUpdateDirective *D) {
9490 DeclarationNameInfo DirName;
9491 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9492 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
9493 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9494 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9495 return Res;
9496}
9497
9498template <typename Derived>
9499StmtResult
9500TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9501 DeclarationNameInfo DirName;
9502 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9503 OMPD_teams, DirName, nullptr, D->getBeginLoc());
9504 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9505 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9506 return Res;
9507}
9508
9509template <typename Derived>
9510StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9511 OMPCancellationPointDirective *D) {
9512 DeclarationNameInfo DirName;
9513 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9514 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
9515 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9516 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9517 return Res;
9518}
9519
9520template <typename Derived>
9521StmtResult
9522TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9523 DeclarationNameInfo DirName;
9524 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9525 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
9526 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9527 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9528 return Res;
9529}
9530
9531template <typename Derived>
9532StmtResult
9533TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9534 DeclarationNameInfo DirName;
9535 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9536 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
9537 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9538 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9539 return Res;
9540}
9541
9542template <typename Derived>
9543StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9544 OMPTaskLoopSimdDirective *D) {
9545 DeclarationNameInfo DirName;
9546 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9547 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9548 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9549 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9550 return Res;
9551}
9552
9553template <typename Derived>
9554StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9555 OMPMasterTaskLoopDirective *D) {
9556 DeclarationNameInfo DirName;
9557 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9558 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
9559 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9560 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9561 return Res;
9562}
9563
9564template <typename Derived>
9565StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9566 OMPMaskedTaskLoopDirective *D) {
9567 DeclarationNameInfo DirName;
9568 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9569 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9570 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9571 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9572 return Res;
9573}
9574
9575template <typename Derived>
9576StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9577 OMPMasterTaskLoopSimdDirective *D) {
9578 DeclarationNameInfo DirName;
9579 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9580 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9581 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9582 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9583 return Res;
9584}
9585
9586template <typename Derived>
9587StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9588 OMPMaskedTaskLoopSimdDirective *D) {
9589 DeclarationNameInfo DirName;
9590 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9591 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9592 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9593 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9594 return Res;
9595}
9596
9597template <typename Derived>
9598StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9599 OMPParallelMasterTaskLoopDirective *D) {
9600 DeclarationNameInfo DirName;
9601 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9602 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9603 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9604 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9605 return Res;
9606}
9607
9608template <typename Derived>
9609StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9610 OMPParallelMaskedTaskLoopDirective *D) {
9611 DeclarationNameInfo DirName;
9612 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9613 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9614 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9615 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9616 return Res;
9617}
9618
9619template <typename Derived>
9620StmtResult
9621TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9622 OMPParallelMasterTaskLoopSimdDirective *D) {
9623 DeclarationNameInfo DirName;
9624 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9625 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9626 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9627 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9628 return Res;
9629}
9630
9631template <typename Derived>
9632StmtResult
9633TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9634 OMPParallelMaskedTaskLoopSimdDirective *D) {
9635 DeclarationNameInfo DirName;
9636 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9637 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9638 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9639 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9640 return Res;
9641}
9642
9643template <typename Derived>
9644StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9645 OMPDistributeDirective *D) {
9646 DeclarationNameInfo DirName;
9647 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9648 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
9649 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9650 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9651 return Res;
9652}
9653
9654template <typename Derived>
9655StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9656 OMPDistributeParallelForDirective *D) {
9657 DeclarationNameInfo DirName;
9658 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9659 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9660 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9661 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9662 return Res;
9663}
9664
9665template <typename Derived>
9666StmtResult
9667TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9668 OMPDistributeParallelForSimdDirective *D) {
9669 DeclarationNameInfo DirName;
9670 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9671 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9672 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9673 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9674 return Res;
9675}
9676
9677template <typename Derived>
9678StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9679 OMPDistributeSimdDirective *D) {
9680 DeclarationNameInfo DirName;
9681 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9682 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
9683 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9684 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9685 return Res;
9686}
9687
9688template <typename Derived>
9689StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9690 OMPTargetParallelForSimdDirective *D) {
9691 DeclarationNameInfo DirName;
9692 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9693 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9694 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9695 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9696 return Res;
9697}
9698
9699template <typename Derived>
9700StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9701 OMPTargetSimdDirective *D) {
9702 DeclarationNameInfo DirName;
9703 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9704 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
9705 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9706 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9707 return Res;
9708}
9709
9710template <typename Derived>
9711StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9712 OMPTeamsDistributeDirective *D) {
9713 DeclarationNameInfo DirName;
9714 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9715 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
9716 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9717 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9718 return Res;
9719}
9720
9721template <typename Derived>
9722StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9723 OMPTeamsDistributeSimdDirective *D) {
9724 DeclarationNameInfo DirName;
9725 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9726 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9727 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9728 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9729 return Res;
9730}
9731
9732template <typename Derived>
9733StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9734 OMPTeamsDistributeParallelForSimdDirective *D) {
9735 DeclarationNameInfo DirName;
9736 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9737 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9738 D->getBeginLoc());
9739 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9740 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9741 return Res;
9742}
9743
9744template <typename Derived>
9745StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9746 OMPTeamsDistributeParallelForDirective *D) {
9747 DeclarationNameInfo DirName;
9748 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9749 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9750 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9751 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9752 return Res;
9753}
9754
9755template <typename Derived>
9756StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9757 OMPTargetTeamsDirective *D) {
9758 DeclarationNameInfo DirName;
9759 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9760 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
9761 auto Res = getDerived().TransformOMPExecutableDirective(D);
9762 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9763 return Res;
9764}
9765
9766template <typename Derived>
9767StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9768 OMPTargetTeamsDistributeDirective *D) {
9769 DeclarationNameInfo DirName;
9770 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9771 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9772 auto Res = getDerived().TransformOMPExecutableDirective(D);
9773 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9774 return Res;
9775}
9776
9777template <typename Derived>
9778StmtResult
9779TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9780 OMPTargetTeamsDistributeParallelForDirective *D) {
9781 DeclarationNameInfo DirName;
9782 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9783 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9784 D->getBeginLoc());
9785 auto Res = getDerived().TransformOMPExecutableDirective(D);
9786 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9787 return Res;
9788}
9789
9790template <typename Derived>
9791StmtResult TreeTransform<Derived>::
9792 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9793 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9794 DeclarationNameInfo DirName;
9795 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9796 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9797 D->getBeginLoc());
9798 auto Res = getDerived().TransformOMPExecutableDirective(D);
9799 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9800 return Res;
9801}
9802
9803template <typename Derived>
9804StmtResult
9805TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9806 OMPTargetTeamsDistributeSimdDirective *D) {
9807 DeclarationNameInfo DirName;
9808 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9809 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9810 auto Res = getDerived().TransformOMPExecutableDirective(D);
9811 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9812 return Res;
9813}
9814
9815template <typename Derived>
9816StmtResult
9817TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9818 DeclarationNameInfo DirName;
9819 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9820 OMPD_interop, DirName, nullptr, D->getBeginLoc());
9821 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9822 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9823 return Res;
9824}
9825
9826template <typename Derived>
9827StmtResult
9828TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9829 DeclarationNameInfo DirName;
9830 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9831 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
9832 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9833 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9834 return Res;
9835}
9836
9837template <typename Derived>
9838StmtResult
9839TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9840 DeclarationNameInfo DirName;
9841 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9842 OMPD_masked, DirName, nullptr, D->getBeginLoc());
9843 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9844 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9845 return Res;
9846}
9847
9848template <typename Derived>
9849StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9850 OMPGenericLoopDirective *D) {
9851 DeclarationNameInfo DirName;
9852 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9853 OMPD_loop, DirName, nullptr, D->getBeginLoc());
9854 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9855 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9856 return Res;
9857}
9858
9859template <typename Derived>
9860StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9861 OMPTeamsGenericLoopDirective *D) {
9862 DeclarationNameInfo DirName;
9863 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9864 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
9865 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9866 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9867 return Res;
9868}
9869
9870template <typename Derived>
9871StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9872 OMPTargetTeamsGenericLoopDirective *D) {
9873 DeclarationNameInfo DirName;
9874 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9875 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
9876 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9877 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9878 return Res;
9879}
9880
9881template <typename Derived>
9882StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9883 OMPParallelGenericLoopDirective *D) {
9884 DeclarationNameInfo DirName;
9885 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9886 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
9887 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9888 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9889 return Res;
9890}
9891
9892template <typename Derived>
9893StmtResult
9894TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9895 OMPTargetParallelGenericLoopDirective *D) {
9896 DeclarationNameInfo DirName;
9897 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9898 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
9899 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9900 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9901 return Res;
9902}
9903
9904//===----------------------------------------------------------------------===//
9905// OpenMP clause transformation
9906//===----------------------------------------------------------------------===//
9907template <typename Derived>
9908OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9909 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9910 if (Cond.isInvalid())
9911 return nullptr;
9912 return getDerived().RebuildOMPIfClause(
9913 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9914 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9915}
9916
9917template <typename Derived>
9918OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9919 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9920 if (Cond.isInvalid())
9921 return nullptr;
9922 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9923 C->getLParenLoc(), C->getEndLoc());
9924}
9925
9926template <typename Derived>
9927OMPClause *
9928TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9929 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9930 if (NumThreads.isInvalid())
9931 return nullptr;
9932 return getDerived().RebuildOMPNumThreadsClause(
9933 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9934}
9935
9936template <typename Derived>
9937OMPClause *
9938TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9939 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9940 if (E.isInvalid())
9941 return nullptr;
9942 return getDerived().RebuildOMPSafelenClause(
9943 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9944}
9945
9946template <typename Derived>
9947OMPClause *
9948TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9949 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9950 if (E.isInvalid())
9951 return nullptr;
9952 return getDerived().RebuildOMPAllocatorClause(
9953 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9954}
9955
9956template <typename Derived>
9957OMPClause *
9958TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9959 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9960 if (E.isInvalid())
9961 return nullptr;
9962 return getDerived().RebuildOMPSimdlenClause(
9963 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9964}
9965
9966template <typename Derived>
9967OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9968 SmallVector<Expr *, 4> TransformedSizes;
9969 TransformedSizes.reserve(N: C->getNumSizes());
9970 bool Changed = false;
9971 for (Expr *E : C->getSizesRefs()) {
9972 if (!E) {
9973 TransformedSizes.push_back(Elt: nullptr);
9974 continue;
9975 }
9976
9977 ExprResult T = getDerived().TransformExpr(E);
9978 if (T.isInvalid())
9979 return nullptr;
9980 if (E != T.get())
9981 Changed = true;
9982 TransformedSizes.push_back(Elt: T.get());
9983 }
9984
9985 if (!Changed && !getDerived().AlwaysRebuild())
9986 return C;
9987 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
9988 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
9989}
9990
9991template <typename Derived>
9992OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
9993 if (!getDerived().AlwaysRebuild())
9994 return C;
9995 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
9996}
9997
9998template <typename Derived>
9999OMPClause *
10000TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10001 ExprResult T = getDerived().TransformExpr(C->getFactor());
10002 if (T.isInvalid())
10003 return nullptr;
10004 Expr *Factor = T.get();
10005 bool Changed = Factor != C->getFactor();
10006
10007 if (!Changed && !getDerived().AlwaysRebuild())
10008 return C;
10009 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10010 EndLoc: C->getEndLoc());
10011}
10012
10013template <typename Derived>
10014OMPClause *
10015TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10016 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10017 if (E.isInvalid())
10018 return nullptr;
10019 return getDerived().RebuildOMPCollapseClause(
10020 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10021}
10022
10023template <typename Derived>
10024OMPClause *
10025TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10026 return getDerived().RebuildOMPDefaultClause(
10027 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10028 C->getLParenLoc(), C->getEndLoc());
10029}
10030
10031template <typename Derived>
10032OMPClause *
10033TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10034 return getDerived().RebuildOMPProcBindClause(
10035 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10036 C->getLParenLoc(), C->getEndLoc());
10037}
10038
10039template <typename Derived>
10040OMPClause *
10041TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10042 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10043 if (E.isInvalid())
10044 return nullptr;
10045 return getDerived().RebuildOMPScheduleClause(
10046 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10047 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10048 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10049 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10050}
10051
10052template <typename Derived>
10053OMPClause *
10054TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10055 ExprResult E;
10056 if (auto *Num = C->getNumForLoops()) {
10057 E = getDerived().TransformExpr(Num);
10058 if (E.isInvalid())
10059 return nullptr;
10060 }
10061 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10062 C->getLParenLoc(), E.get());
10063}
10064
10065template <typename Derived>
10066OMPClause *
10067TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10068 ExprResult E;
10069 if (Expr *Evt = C->getEventHandler()) {
10070 E = getDerived().TransformExpr(Evt);
10071 if (E.isInvalid())
10072 return nullptr;
10073 }
10074 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10075 C->getLParenLoc(), C->getEndLoc());
10076}
10077
10078template <typename Derived>
10079OMPClause *
10080TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10081 // No need to rebuild this clause, no template-dependent parameters.
10082 return C;
10083}
10084
10085template <typename Derived>
10086OMPClause *
10087TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10088 // No need to rebuild this clause, no template-dependent parameters.
10089 return C;
10090}
10091
10092template <typename Derived>
10093OMPClause *
10094TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10095 // No need to rebuild this clause, no template-dependent parameters.
10096 return C;
10097}
10098
10099template <typename Derived>
10100OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10101 // No need to rebuild this clause, no template-dependent parameters.
10102 return C;
10103}
10104
10105template <typename Derived>
10106OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10107 // No need to rebuild this clause, no template-dependent parameters.
10108 return C;
10109}
10110
10111template <typename Derived>
10112OMPClause *
10113TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10114 // No need to rebuild this clause, no template-dependent parameters.
10115 return C;
10116}
10117
10118template <typename Derived>
10119OMPClause *
10120TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10121 // No need to rebuild this clause, no template-dependent parameters.
10122 return C;
10123}
10124
10125template <typename Derived>
10126OMPClause *
10127TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10128 // No need to rebuild this clause, no template-dependent parameters.
10129 return C;
10130}
10131
10132template <typename Derived>
10133OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10134 // No need to rebuild this clause, no template-dependent parameters.
10135 return C;
10136}
10137
10138template <typename Derived>
10139OMPClause *
10140TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10141 // No need to rebuild this clause, no template-dependent parameters.
10142 return C;
10143}
10144
10145template <typename Derived>
10146OMPClause *
10147TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10148 // No need to rebuild this clause, no template-dependent parameters.
10149 return C;
10150}
10151
10152template <typename Derived>
10153OMPClause *
10154TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10155 // No need to rebuild this clause, no template-dependent parameters.
10156 return C;
10157}
10158
10159template <typename Derived>
10160OMPClause *
10161TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10162 // No need to rebuild this clause, no template-dependent parameters.
10163 return C;
10164}
10165
10166template <typename Derived>
10167OMPClause *
10168TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10169 // No need to rebuild this clause, no template-dependent parameters.
10170 return C;
10171}
10172
10173template <typename Derived>
10174OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10175 // No need to rebuild this clause, no template-dependent parameters.
10176 return C;
10177}
10178
10179template <typename Derived>
10180OMPClause *
10181TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10182 // No need to rebuild this clause, no template-dependent parameters.
10183 return C;
10184}
10185
10186template <typename Derived>
10187OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10188 // No need to rebuild this clause, no template-dependent parameters.
10189 return C;
10190}
10191
10192template <typename Derived>
10193OMPClause *
10194TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10195 // No need to rebuild this clause, no template-dependent parameters.
10196 return C;
10197}
10198
10199template <typename Derived>
10200OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10201 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10202 if (IVR.isInvalid())
10203 return nullptr;
10204
10205 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10206 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10207 for (Expr *E : llvm::drop_begin(C->varlists())) {
10208 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10209 if (ER.isInvalid())
10210 return nullptr;
10211 InteropInfo.PreferTypes.push_back(ER.get());
10212 }
10213 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10214 C->getBeginLoc(), C->getLParenLoc(),
10215 C->getVarLoc(), C->getEndLoc());
10216}
10217
10218template <typename Derived>
10219OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10220 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10221 if (ER.isInvalid())
10222 return nullptr;
10223 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10224 C->getLParenLoc(), C->getVarLoc(),
10225 C->getEndLoc());
10226}
10227
10228template <typename Derived>
10229OMPClause *
10230TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10231 ExprResult ER;
10232 if (Expr *IV = C->getInteropVar()) {
10233 ER = getDerived().TransformExpr(IV);
10234 if (ER.isInvalid())
10235 return nullptr;
10236 }
10237 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10238 C->getLParenLoc(), C->getVarLoc(),
10239 C->getEndLoc());
10240}
10241
10242template <typename Derived>
10243OMPClause *
10244TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10245 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10246 if (Cond.isInvalid())
10247 return nullptr;
10248 return getDerived().RebuildOMPNovariantsClause(
10249 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10250}
10251
10252template <typename Derived>
10253OMPClause *
10254TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10255 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10256 if (Cond.isInvalid())
10257 return nullptr;
10258 return getDerived().RebuildOMPNocontextClause(
10259 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10260}
10261
10262template <typename Derived>
10263OMPClause *
10264TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10265 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10266 if (ThreadID.isInvalid())
10267 return nullptr;
10268 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10269 C->getLParenLoc(), C->getEndLoc());
10270}
10271
10272template <typename Derived>
10273OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10274 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10275 if (E.isInvalid())
10276 return nullptr;
10277 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10278 C->getLParenLoc(), C->getEndLoc());
10279}
10280
10281template <typename Derived>
10282OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10283 OMPUnifiedAddressClause *C) {
10284 llvm_unreachable("unified_address clause cannot appear in dependent context");
10285}
10286
10287template <typename Derived>
10288OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10289 OMPUnifiedSharedMemoryClause *C) {
10290 llvm_unreachable(
10291 "unified_shared_memory clause cannot appear in dependent context");
10292}
10293
10294template <typename Derived>
10295OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10296 OMPReverseOffloadClause *C) {
10297 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10298}
10299
10300template <typename Derived>
10301OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10302 OMPDynamicAllocatorsClause *C) {
10303 llvm_unreachable(
10304 "dynamic_allocators clause cannot appear in dependent context");
10305}
10306
10307template <typename Derived>
10308OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10309 OMPAtomicDefaultMemOrderClause *C) {
10310 llvm_unreachable(
10311 "atomic_default_mem_order clause cannot appear in dependent context");
10312}
10313
10314template <typename Derived>
10315OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10316 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10317 C->getBeginLoc(), C->getLParenLoc(),
10318 C->getEndLoc());
10319}
10320
10321template <typename Derived>
10322OMPClause *
10323TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10324 return getDerived().RebuildOMPSeverityClause(
10325 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10326 C->getLParenLoc(), C->getEndLoc());
10327}
10328
10329template <typename Derived>
10330OMPClause *
10331TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10332 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10333 if (E.isInvalid())
10334 return nullptr;
10335 return getDerived().RebuildOMPMessageClause(
10336 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10337 C->getEndLoc());
10338}
10339
10340template <typename Derived>
10341OMPClause *
10342TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10343 llvm::SmallVector<Expr *, 16> Vars;
10344 Vars.reserve(C->varlist_size());
10345 for (auto *VE : C->varlists()) {
10346 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10347 if (EVar.isInvalid())
10348 return nullptr;
10349 Vars.push_back(EVar.get());
10350 }
10351 return getDerived().RebuildOMPPrivateClause(
10352 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10353}
10354
10355template <typename Derived>
10356OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10357 OMPFirstprivateClause *C) {
10358 llvm::SmallVector<Expr *, 16> Vars;
10359 Vars.reserve(C->varlist_size());
10360 for (auto *VE : C->varlists()) {
10361 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10362 if (EVar.isInvalid())
10363 return nullptr;
10364 Vars.push_back(EVar.get());
10365 }
10366 return getDerived().RebuildOMPFirstprivateClause(
10367 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10368}
10369
10370template <typename Derived>
10371OMPClause *
10372TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10373 llvm::SmallVector<Expr *, 16> Vars;
10374 Vars.reserve(C->varlist_size());
10375 for (auto *VE : C->varlists()) {
10376 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10377 if (EVar.isInvalid())
10378 return nullptr;
10379 Vars.push_back(EVar.get());
10380 }
10381 return getDerived().RebuildOMPLastprivateClause(
10382 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10383 C->getLParenLoc(), C->getEndLoc());
10384}
10385
10386template <typename Derived>
10387OMPClause *
10388TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10389 llvm::SmallVector<Expr *, 16> Vars;
10390 Vars.reserve(C->varlist_size());
10391 for (auto *VE : C->varlists()) {
10392 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10393 if (EVar.isInvalid())
10394 return nullptr;
10395 Vars.push_back(EVar.get());
10396 }
10397 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10398 C->getLParenLoc(), C->getEndLoc());
10399}
10400
10401template <typename Derived>
10402OMPClause *
10403TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10404 llvm::SmallVector<Expr *, 16> Vars;
10405 Vars.reserve(C->varlist_size());
10406 for (auto *VE : C->varlists()) {
10407 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10408 if (EVar.isInvalid())
10409 return nullptr;
10410 Vars.push_back(EVar.get());
10411 }
10412 CXXScopeSpec ReductionIdScopeSpec;
10413 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10414
10415 DeclarationNameInfo NameInfo = C->getNameInfo();
10416 if (NameInfo.getName()) {
10417 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10418 if (!NameInfo.getName())
10419 return nullptr;
10420 }
10421 // Build a list of all UDR decls with the same names ranged by the Scopes.
10422 // The Scope boundary is a duplication of the previous decl.
10423 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10424 for (auto *E : C->reduction_ops()) {
10425 // Transform all the decls.
10426 if (E) {
10427 auto *ULE = cast<UnresolvedLookupExpr>(E);
10428 UnresolvedSet<8> Decls;
10429 for (auto *D : ULE->decls()) {
10430 NamedDecl *InstD =
10431 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10432 Decls.addDecl(InstD, InstD->getAccess());
10433 }
10434 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10435 SemaRef.Context, /*NamingClass=*/nullptr,
10436 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10437 /*ADL=*/true, Decls.begin(), Decls.end(),
10438 /*KnownDependent=*/false));
10439 } else
10440 UnresolvedReductions.push_back(nullptr);
10441 }
10442 return getDerived().RebuildOMPReductionClause(
10443 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10444 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10445 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10446}
10447
10448template <typename Derived>
10449OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10450 OMPTaskReductionClause *C) {
10451 llvm::SmallVector<Expr *, 16> Vars;
10452 Vars.reserve(C->varlist_size());
10453 for (auto *VE : C->varlists()) {
10454 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10455 if (EVar.isInvalid())
10456 return nullptr;
10457 Vars.push_back(EVar.get());
10458 }
10459 CXXScopeSpec ReductionIdScopeSpec;
10460 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10461
10462 DeclarationNameInfo NameInfo = C->getNameInfo();
10463 if (NameInfo.getName()) {
10464 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10465 if (!NameInfo.getName())
10466 return nullptr;
10467 }
10468 // Build a list of all UDR decls with the same names ranged by the Scopes.
10469 // The Scope boundary is a duplication of the previous decl.
10470 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10471 for (auto *E : C->reduction_ops()) {
10472 // Transform all the decls.
10473 if (E) {
10474 auto *ULE = cast<UnresolvedLookupExpr>(E);
10475 UnresolvedSet<8> Decls;
10476 for (auto *D : ULE->decls()) {
10477 NamedDecl *InstD =
10478 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10479 Decls.addDecl(InstD, InstD->getAccess());
10480 }
10481 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10482 SemaRef.Context, /*NamingClass=*/nullptr,
10483 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10484 /*ADL=*/true, Decls.begin(), Decls.end(),
10485 /*KnownDependent=*/false));
10486 } else
10487 UnresolvedReductions.push_back(nullptr);
10488 }
10489 return getDerived().RebuildOMPTaskReductionClause(
10490 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10491 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10492}
10493
10494template <typename Derived>
10495OMPClause *
10496TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10497 llvm::SmallVector<Expr *, 16> Vars;
10498 Vars.reserve(C->varlist_size());
10499 for (auto *VE : C->varlists()) {
10500 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10501 if (EVar.isInvalid())
10502 return nullptr;
10503 Vars.push_back(EVar.get());
10504 }
10505 CXXScopeSpec ReductionIdScopeSpec;
10506 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10507
10508 DeclarationNameInfo NameInfo = C->getNameInfo();
10509 if (NameInfo.getName()) {
10510 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10511 if (!NameInfo.getName())
10512 return nullptr;
10513 }
10514 // Build a list of all UDR decls with the same names ranged by the Scopes.
10515 // The Scope boundary is a duplication of the previous decl.
10516 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10517 for (auto *E : C->reduction_ops()) {
10518 // Transform all the decls.
10519 if (E) {
10520 auto *ULE = cast<UnresolvedLookupExpr>(E);
10521 UnresolvedSet<8> Decls;
10522 for (auto *D : ULE->decls()) {
10523 NamedDecl *InstD =
10524 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10525 Decls.addDecl(InstD, InstD->getAccess());
10526 }
10527 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10528 SemaRef.Context, /*NamingClass=*/nullptr,
10529 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10530 /*ADL=*/true, Decls.begin(), Decls.end(),
10531 /*KnownDependent=*/false));
10532 } else
10533 UnresolvedReductions.push_back(nullptr);
10534 }
10535 return getDerived().RebuildOMPInReductionClause(
10536 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10537 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10538}
10539
10540template <typename Derived>
10541OMPClause *
10542TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10543 llvm::SmallVector<Expr *, 16> Vars;
10544 Vars.reserve(C->varlist_size());
10545 for (auto *VE : C->varlists()) {
10546 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10547 if (EVar.isInvalid())
10548 return nullptr;
10549 Vars.push_back(EVar.get());
10550 }
10551 ExprResult Step = getDerived().TransformExpr(C->getStep());
10552 if (Step.isInvalid())
10553 return nullptr;
10554 return getDerived().RebuildOMPLinearClause(
10555 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10556 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10557 C->getEndLoc());
10558}
10559
10560template <typename Derived>
10561OMPClause *
10562TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10563 llvm::SmallVector<Expr *, 16> Vars;
10564 Vars.reserve(C->varlist_size());
10565 for (auto *VE : C->varlists()) {
10566 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10567 if (EVar.isInvalid())
10568 return nullptr;
10569 Vars.push_back(EVar.get());
10570 }
10571 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10572 if (Alignment.isInvalid())
10573 return nullptr;
10574 return getDerived().RebuildOMPAlignedClause(
10575 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10576 C->getColonLoc(), C->getEndLoc());
10577}
10578
10579template <typename Derived>
10580OMPClause *
10581TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10582 llvm::SmallVector<Expr *, 16> Vars;
10583 Vars.reserve(C->varlist_size());
10584 for (auto *VE : C->varlists()) {
10585 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10586 if (EVar.isInvalid())
10587 return nullptr;
10588 Vars.push_back(EVar.get());
10589 }
10590 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10591 C->getLParenLoc(), C->getEndLoc());
10592}
10593
10594template <typename Derived>
10595OMPClause *
10596TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10597 llvm::SmallVector<Expr *, 16> Vars;
10598 Vars.reserve(C->varlist_size());
10599 for (auto *VE : C->varlists()) {
10600 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10601 if (EVar.isInvalid())
10602 return nullptr;
10603 Vars.push_back(EVar.get());
10604 }
10605 return getDerived().RebuildOMPCopyprivateClause(
10606 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10607}
10608
10609template <typename Derived>
10610OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10611 llvm::SmallVector<Expr *, 16> Vars;
10612 Vars.reserve(C->varlist_size());
10613 for (auto *VE : C->varlists()) {
10614 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10615 if (EVar.isInvalid())
10616 return nullptr;
10617 Vars.push_back(EVar.get());
10618 }
10619 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10620 C->getLParenLoc(), C->getEndLoc());
10621}
10622
10623template <typename Derived>
10624OMPClause *
10625TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10626 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10627 if (E.isInvalid())
10628 return nullptr;
10629 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10630 C->getLParenLoc(), C->getEndLoc());
10631}
10632
10633template <typename Derived>
10634OMPClause *
10635TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10636 llvm::SmallVector<Expr *, 16> Vars;
10637 Expr *DepModifier = C->getModifier();
10638 if (DepModifier) {
10639 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10640 if (DepModRes.isInvalid())
10641 return nullptr;
10642 DepModifier = DepModRes.get();
10643 }
10644 Vars.reserve(C->varlist_size());
10645 for (auto *VE : C->varlists()) {
10646 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10647 if (EVar.isInvalid())
10648 return nullptr;
10649 Vars.push_back(EVar.get());
10650 }
10651 return getDerived().RebuildOMPDependClause(
10652 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10653 C->getOmpAllMemoryLoc()},
10654 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10655}
10656
10657template <typename Derived>
10658OMPClause *
10659TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10660 ExprResult E = getDerived().TransformExpr(C->getDevice());
10661 if (E.isInvalid())
10662 return nullptr;
10663 return getDerived().RebuildOMPDeviceClause(
10664 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10665 C->getModifierLoc(), C->getEndLoc());
10666}
10667
10668template <typename Derived, class T>
10669bool transformOMPMappableExprListClause(
10670 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10671 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10672 DeclarationNameInfo &MapperIdInfo,
10673 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10674 // Transform expressions in the list.
10675 Vars.reserve(N: C->varlist_size());
10676 for (auto *VE : C->varlists()) {
10677 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10678 if (EVar.isInvalid())
10679 return true;
10680 Vars.push_back(Elt: EVar.get());
10681 }
10682 // Transform mapper scope specifier and identifier.
10683 NestedNameSpecifierLoc QualifierLoc;
10684 if (C->getMapperQualifierLoc()) {
10685 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10686 C->getMapperQualifierLoc());
10687 if (!QualifierLoc)
10688 return true;
10689 }
10690 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
10691 MapperIdInfo = C->getMapperIdInfo();
10692 if (MapperIdInfo.getName()) {
10693 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10694 if (!MapperIdInfo.getName())
10695 return true;
10696 }
10697 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10698 // the previous user-defined mapper lookup in dependent environment.
10699 for (auto *E : C->mapperlists()) {
10700 // Transform all the decls.
10701 if (E) {
10702 auto *ULE = cast<UnresolvedLookupExpr>(E);
10703 UnresolvedSet<8> Decls;
10704 for (auto *D : ULE->decls()) {
10705 NamedDecl *InstD =
10706 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10707 Decls.addDecl(InstD, InstD->getAccess());
10708 }
10709 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
10710 TT.getSema().Context, /*NamingClass=*/nullptr,
10711 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
10712 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
10713 /*KnownDependent=*/false));
10714 } else {
10715 UnresolvedMappers.push_back(Elt: nullptr);
10716 }
10717 }
10718 return false;
10719}
10720
10721template <typename Derived>
10722OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10723 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10724 llvm::SmallVector<Expr *, 16> Vars;
10725 Expr *IteratorModifier = C->getIteratorModifier();
10726 if (IteratorModifier) {
10727 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10728 if (MapModRes.isInvalid())
10729 return nullptr;
10730 IteratorModifier = MapModRes.get();
10731 }
10732 CXXScopeSpec MapperIdScopeSpec;
10733 DeclarationNameInfo MapperIdInfo;
10734 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10735 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10736 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10737 return nullptr;
10738 return getDerived().RebuildOMPMapClause(
10739 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10740 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10741 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10742}
10743
10744template <typename Derived>
10745OMPClause *
10746TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10747 Expr *Allocator = C->getAllocator();
10748 if (Allocator) {
10749 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10750 if (AllocatorRes.isInvalid())
10751 return nullptr;
10752 Allocator = AllocatorRes.get();
10753 }
10754 llvm::SmallVector<Expr *, 16> Vars;
10755 Vars.reserve(C->varlist_size());
10756 for (auto *VE : C->varlists()) {
10757 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10758 if (EVar.isInvalid())
10759 return nullptr;
10760 Vars.push_back(EVar.get());
10761 }
10762 return getDerived().RebuildOMPAllocateClause(
10763 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10764 C->getEndLoc());
10765}
10766
10767template <typename Derived>
10768OMPClause *
10769TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10770 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10771 if (E.isInvalid())
10772 return nullptr;
10773 return getDerived().RebuildOMPNumTeamsClause(
10774 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10775}
10776
10777template <typename Derived>
10778OMPClause *
10779TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10780 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10781 if (E.isInvalid())
10782 return nullptr;
10783 return getDerived().RebuildOMPThreadLimitClause(
10784 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10785}
10786
10787template <typename Derived>
10788OMPClause *
10789TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10790 ExprResult E = getDerived().TransformExpr(C->getPriority());
10791 if (E.isInvalid())
10792 return nullptr;
10793 return getDerived().RebuildOMPPriorityClause(
10794 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10795}
10796
10797template <typename Derived>
10798OMPClause *
10799TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10800 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10801 if (E.isInvalid())
10802 return nullptr;
10803 return getDerived().RebuildOMPGrainsizeClause(
10804 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10805 C->getModifierLoc(), C->getEndLoc());
10806}
10807
10808template <typename Derived>
10809OMPClause *
10810TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10811 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10812 if (E.isInvalid())
10813 return nullptr;
10814 return getDerived().RebuildOMPNumTasksClause(
10815 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10816 C->getModifierLoc(), C->getEndLoc());
10817}
10818
10819template <typename Derived>
10820OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10821 ExprResult E = getDerived().TransformExpr(C->getHint());
10822 if (E.isInvalid())
10823 return nullptr;
10824 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10825 C->getLParenLoc(), C->getEndLoc());
10826}
10827
10828template <typename Derived>
10829OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10830 OMPDistScheduleClause *C) {
10831 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10832 if (E.isInvalid())
10833 return nullptr;
10834 return getDerived().RebuildOMPDistScheduleClause(
10835 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10836 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10837}
10838
10839template <typename Derived>
10840OMPClause *
10841TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10842 // Rebuild Defaultmap Clause since we need to invoke the checking of
10843 // defaultmap(none:variable-category) after template initialization.
10844 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10845 C->getDefaultmapKind(),
10846 C->getBeginLoc(),
10847 C->getLParenLoc(),
10848 C->getDefaultmapModifierLoc(),
10849 C->getDefaultmapKindLoc(),
10850 C->getEndLoc());
10851}
10852
10853template <typename Derived>
10854OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10855 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10856 llvm::SmallVector<Expr *, 16> Vars;
10857 CXXScopeSpec MapperIdScopeSpec;
10858 DeclarationNameInfo MapperIdInfo;
10859 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10860 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10861 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10862 return nullptr;
10863 return getDerived().RebuildOMPToClause(
10864 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10865 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10866}
10867
10868template <typename Derived>
10869OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10870 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10871 llvm::SmallVector<Expr *, 16> Vars;
10872 CXXScopeSpec MapperIdScopeSpec;
10873 DeclarationNameInfo MapperIdInfo;
10874 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10875 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10876 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10877 return nullptr;
10878 return getDerived().RebuildOMPFromClause(
10879 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10880 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10881}
10882
10883template <typename Derived>
10884OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10885 OMPUseDevicePtrClause *C) {
10886 llvm::SmallVector<Expr *, 16> Vars;
10887 Vars.reserve(C->varlist_size());
10888 for (auto *VE : C->varlists()) {
10889 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10890 if (EVar.isInvalid())
10891 return nullptr;
10892 Vars.push_back(EVar.get());
10893 }
10894 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10895 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10896}
10897
10898template <typename Derived>
10899OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10900 OMPUseDeviceAddrClause *C) {
10901 llvm::SmallVector<Expr *, 16> Vars;
10902 Vars.reserve(C->varlist_size());
10903 for (auto *VE : C->varlists()) {
10904 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10905 if (EVar.isInvalid())
10906 return nullptr;
10907 Vars.push_back(EVar.get());
10908 }
10909 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10910 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10911}
10912
10913template <typename Derived>
10914OMPClause *
10915TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10916 llvm::SmallVector<Expr *, 16> Vars;
10917 Vars.reserve(C->varlist_size());
10918 for (auto *VE : C->varlists()) {
10919 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10920 if (EVar.isInvalid())
10921 return nullptr;
10922 Vars.push_back(EVar.get());
10923 }
10924 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10925 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10926}
10927
10928template <typename Derived>
10929OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10930 OMPHasDeviceAddrClause *C) {
10931 llvm::SmallVector<Expr *, 16> Vars;
10932 Vars.reserve(C->varlist_size());
10933 for (auto *VE : C->varlists()) {
10934 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10935 if (EVar.isInvalid())
10936 return nullptr;
10937 Vars.push_back(EVar.get());
10938 }
10939 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10940 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10941}
10942
10943template <typename Derived>
10944OMPClause *
10945TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10946 llvm::SmallVector<Expr *, 16> Vars;
10947 Vars.reserve(C->varlist_size());
10948 for (auto *VE : C->varlists()) {
10949 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10950 if (EVar.isInvalid())
10951 return nullptr;
10952 Vars.push_back(EVar.get());
10953 }
10954 return getDerived().RebuildOMPNontemporalClause(
10955 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10956}
10957
10958template <typename Derived>
10959OMPClause *
10960TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10961 llvm::SmallVector<Expr *, 16> Vars;
10962 Vars.reserve(C->varlist_size());
10963 for (auto *VE : C->varlists()) {
10964 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10965 if (EVar.isInvalid())
10966 return nullptr;
10967 Vars.push_back(EVar.get());
10968 }
10969 return getDerived().RebuildOMPInclusiveClause(
10970 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10971}
10972
10973template <typename Derived>
10974OMPClause *
10975TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10976 llvm::SmallVector<Expr *, 16> Vars;
10977 Vars.reserve(C->varlist_size());
10978 for (auto *VE : C->varlists()) {
10979 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10980 if (EVar.isInvalid())
10981 return nullptr;
10982 Vars.push_back(EVar.get());
10983 }
10984 return getDerived().RebuildOMPExclusiveClause(
10985 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10986}
10987
10988template <typename Derived>
10989OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
10990 OMPUsesAllocatorsClause *C) {
10991 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
10992 Data.reserve(C->getNumberOfAllocators());
10993 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
10994 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
10995 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
10996 if (Allocator.isInvalid())
10997 continue;
10998 ExprResult AllocatorTraits;
10999 if (Expr *AT = D.AllocatorTraits) {
11000 AllocatorTraits = getDerived().TransformExpr(AT);
11001 if (AllocatorTraits.isInvalid())
11002 continue;
11003 }
11004 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11005 NewD.Allocator = Allocator.get();
11006 NewD.AllocatorTraits = AllocatorTraits.get();
11007 NewD.LParenLoc = D.LParenLoc;
11008 NewD.RParenLoc = D.RParenLoc;
11009 }
11010 return getDerived().RebuildOMPUsesAllocatorsClause(
11011 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11012}
11013
11014template <typename Derived>
11015OMPClause *
11016TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11017 SmallVector<Expr *, 4> Locators;
11018 Locators.reserve(N: C->varlist_size());
11019 ExprResult ModifierRes;
11020 if (Expr *Modifier = C->getModifier()) {
11021 ModifierRes = getDerived().TransformExpr(Modifier);
11022 if (ModifierRes.isInvalid())
11023 return nullptr;
11024 }
11025 for (Expr *E : C->varlists()) {
11026 ExprResult Locator = getDerived().TransformExpr(E);
11027 if (Locator.isInvalid())
11028 continue;
11029 Locators.push_back(Locator.get());
11030 }
11031 return getDerived().RebuildOMPAffinityClause(
11032 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11033 ModifierRes.get(), Locators);
11034}
11035
11036template <typename Derived>
11037OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11038 return getDerived().RebuildOMPOrderClause(
11039 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11040 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11041}
11042
11043template <typename Derived>
11044OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11045 return getDerived().RebuildOMPBindClause(
11046 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11047 C->getLParenLoc(), C->getEndLoc());
11048}
11049
11050template <typename Derived>
11051OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11052 OMPXDynCGroupMemClause *C) {
11053 ExprResult Size = getDerived().TransformExpr(C->getSize());
11054 if (Size.isInvalid())
11055 return nullptr;
11056 return getDerived().RebuildOMPXDynCGroupMemClause(
11057 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11058}
11059
11060template <typename Derived>
11061OMPClause *
11062TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11063 llvm::SmallVector<Expr *, 16> Vars;
11064 Vars.reserve(C->varlist_size());
11065 for (auto *VE : C->varlists()) {
11066 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11067 if (EVar.isInvalid())
11068 return nullptr;
11069 Vars.push_back(EVar.get());
11070 }
11071 return getDerived().RebuildOMPDoacrossClause(
11072 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11073 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11074}
11075
11076template <typename Derived>
11077OMPClause *
11078TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11079 SmallVector<const Attr *> NewAttrs;
11080 for (auto *A : C->getAttrs())
11081 NewAttrs.push_back(getDerived().TransformAttr(A));
11082 return getDerived().RebuildOMPXAttributeClause(
11083 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11084}
11085
11086template <typename Derived>
11087OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11088 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11089}
11090
11091//===----------------------------------------------------------------------===//
11092// OpenACC transformation
11093//===----------------------------------------------------------------------===//
11094namespace {
11095template <typename Derived>
11096class OpenACCClauseTransform final
11097 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11098 TreeTransform<Derived> &Self;
11099 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11100 OpenACCClause *NewClause = nullptr;
11101
11102public:
11103 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11104 SemaOpenACC::OpenACCParsedClause &PC)
11105 : Self(Self), ParsedClause(PC) {}
11106
11107 OpenACCClause *CreatedClause() const { return NewClause; }
11108
11109#define VISIT_CLAUSE(CLAUSE_NAME) \
11110 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11111#include "clang/Basic/OpenACCClauses.def"
11112};
11113
11114template <typename Derived>
11115void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11116 const OpenACCDefaultClause &C) {
11117 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11118
11119 NewClause = OpenACCDefaultClause::Create(
11120 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11121 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11122 EndLoc: ParsedClause.getEndLoc());
11123}
11124
11125template <typename Derived>
11126void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11127 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11128 assert(Cond && "If constructed with invalid Condition");
11129 Sema::ConditionResult Res = Self.TransformCondition(
11130 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11131
11132 if (Res.isInvalid() || !Res.get().second)
11133 return;
11134
11135 ParsedClause.setConditionDetails(Res.get().second);
11136
11137 NewClause = OpenACCIfClause::Create(
11138 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11139 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11140 EndLoc: ParsedClause.getEndLoc());
11141}
11142
11143template <typename Derived>
11144void OpenACCClauseTransform<Derived>::VisitSelfClause(
11145 const OpenACCSelfClause &C) {
11146
11147 if (C.hasConditionExpr()) {
11148 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11149 Sema::ConditionResult Res =
11150 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11151 Sema::ConditionKind::Boolean);
11152
11153 if (Res.isInvalid() || !Res.get().second)
11154 return;
11155
11156 ParsedClause.setConditionDetails(Res.get().second);
11157 }
11158
11159 NewClause = OpenACCSelfClause::Create(
11160 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11161 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11162 EndLoc: ParsedClause.getEndLoc());
11163}
11164
11165template <typename Derived>
11166void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11167 const OpenACCNumGangsClause &C) {
11168 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11169
11170 for (Expr *CurIntExpr : C.getIntExprs()) {
11171 ExprResult Res = Self.TransformExpr(CurIntExpr);
11172
11173 if (!Res.isUsable())
11174 return;
11175
11176 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11177 C.getClauseKind(),
11178 C.getBeginLoc(), Res.get());
11179 if (!Res.isUsable())
11180 return;
11181
11182 InstantiatedIntExprs.push_back(Res.get());
11183 }
11184
11185 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11186 NewClause = OpenACCNumGangsClause::Create(
11187 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11188 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
11189 EndLoc: ParsedClause.getEndLoc());
11190}
11191template <typename Derived>
11192void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11193 const OpenACCNumWorkersClause &C) {
11194 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11195 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11196
11197 ExprResult Res = Self.TransformExpr(IntExpr);
11198 if (!Res.isUsable())
11199 return;
11200
11201 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11202 C.getClauseKind(),
11203 C.getBeginLoc(), Res.get());
11204 if (!Res.isUsable())
11205 return;
11206
11207 ParsedClause.setIntExprDetails(Res.get());
11208 NewClause = OpenACCNumWorkersClause::Create(
11209 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11210 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
11211 EndLoc: ParsedClause.getEndLoc());
11212}
11213
11214template <typename Derived>
11215void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
11216 const OpenACCVectorLengthClause &C) {
11217 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11218 assert(IntExpr && "vector_length clause constructed with invalid int expr");
11219
11220 ExprResult Res = Self.TransformExpr(IntExpr);
11221 if (!Res.isUsable())
11222 return;
11223
11224 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11225 C.getClauseKind(),
11226 C.getBeginLoc(), Res.get());
11227 if (!Res.isUsable())
11228 return;
11229
11230 ParsedClause.setIntExprDetails(Res.get());
11231 NewClause = OpenACCVectorLengthClause::Create(
11232 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11233 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
11234 EndLoc: ParsedClause.getEndLoc());
11235}
11236} // namespace
11237template <typename Derived>
11238OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
11239 ArrayRef<const OpenACCClause *> ExistingClauses,
11240 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
11241
11242 SemaOpenACC::OpenACCParsedClause ParsedClause(
11243 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
11244 ParsedClause.setEndLoc(OldClause->getEndLoc());
11245
11246 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
11247 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
11248
11249 OpenACCClauseTransform<Derived> Transform{*this, ParsedClause};
11250 Transform.Visit(OldClause);
11251
11252 return Transform.CreatedClause();
11253}
11254
11255template <typename Derived>
11256llvm::SmallVector<OpenACCClause *>
11257TreeTransform<Derived>::TransformOpenACCClauseList(
11258 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
11259 llvm::SmallVector<OpenACCClause *> TransformedClauses;
11260 for (const auto *Clause : OldClauses) {
11261 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
11262 TransformedClauses, DirKind, Clause))
11263 TransformedClauses.push_back(TransformedClause);
11264 }
11265 return TransformedClauses;
11266}
11267
11268template <typename Derived>
11269StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
11270 OpenACCComputeConstruct *C) {
11271 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
11272 // FIXME: When implementing this for constructs that can take arguments, we
11273 // should do Sema for them here.
11274
11275 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
11276 C->getBeginLoc()))
11277 return StmtError();
11278
11279 llvm::SmallVector<OpenACCClause *> TransformedClauses =
11280 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
11281 C->clauses());
11282
11283 // Transform Structured Block.
11284 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
11285 StrBlock =
11286 getSema().OpenACC().ActOnAssociatedStmt(C->getDirectiveKind(), StrBlock);
11287
11288 return getDerived().RebuildOpenACCComputeConstruct(
11289 C->getDirectiveKind(), C->getBeginLoc(), C->getEndLoc(),
11290 TransformedClauses, StrBlock);
11291}
11292
11293//===----------------------------------------------------------------------===//
11294// Expression transformation
11295//===----------------------------------------------------------------------===//
11296template<typename Derived>
11297ExprResult
11298TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
11299 return TransformExpr(E: E->getSubExpr());
11300}
11301
11302template <typename Derived>
11303ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
11304 SYCLUniqueStableNameExpr *E) {
11305 if (!E->isTypeDependent())
11306 return E;
11307
11308 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
11309
11310 if (!NewT)
11311 return ExprError();
11312
11313 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
11314 return E;
11315
11316 return getDerived().RebuildSYCLUniqueStableNameExpr(
11317 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
11318}
11319
11320template<typename Derived>
11321ExprResult
11322TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
11323 if (!E->isTypeDependent())
11324 return E;
11325
11326 return getDerived().RebuildPredefinedExpr(E->getLocation(),
11327 E->getIdentKind());
11328}
11329
11330template<typename Derived>
11331ExprResult
11332TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
11333 NestedNameSpecifierLoc QualifierLoc;
11334 if (E->getQualifierLoc()) {
11335 QualifierLoc
11336 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11337 if (!QualifierLoc)
11338 return ExprError();
11339 }
11340
11341 ValueDecl *ND
11342 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
11343 E->getDecl()));
11344 if (!ND)
11345 return ExprError();
11346
11347 NamedDecl *Found = ND;
11348 if (E->getFoundDecl() != E->getDecl()) {
11349 Found = cast_or_null<NamedDecl>(
11350 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
11351 if (!Found)
11352 return ExprError();
11353 }
11354
11355 DeclarationNameInfo NameInfo = E->getNameInfo();
11356 if (NameInfo.getName()) {
11357 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11358 if (!NameInfo.getName())
11359 return ExprError();
11360 }
11361
11362 if (!getDerived().AlwaysRebuild() &&
11363 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
11364 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
11365 Found == E->getFoundDecl() &&
11366 NameInfo.getName() == E->getDecl()->getDeclName() &&
11367 !E->hasExplicitTemplateArgs()) {
11368
11369 // Mark it referenced in the new context regardless.
11370 // FIXME: this is a bit instantiation-specific.
11371 SemaRef.MarkDeclRefReferenced(E);
11372
11373 return E;
11374 }
11375
11376 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
11377 if (E->hasExplicitTemplateArgs()) {
11378 TemplateArgs = &TransArgs;
11379 TransArgs.setLAngleLoc(E->getLAngleLoc());
11380 TransArgs.setRAngleLoc(E->getRAngleLoc());
11381 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11382 E->getNumTemplateArgs(),
11383 TransArgs))
11384 return ExprError();
11385 }
11386
11387 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
11388 Found, TemplateArgs);
11389}
11390
11391template<typename Derived>
11392ExprResult
11393TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
11394 return E;
11395}
11396
11397template <typename Derived>
11398ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
11399 FixedPointLiteral *E) {
11400 return E;
11401}
11402
11403template<typename Derived>
11404ExprResult
11405TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
11406 return E;
11407}
11408
11409template<typename Derived>
11410ExprResult
11411TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
11412 return E;
11413}
11414
11415template<typename Derived>
11416ExprResult
11417TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
11418 return E;
11419}
11420
11421template<typename Derived>
11422ExprResult
11423TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
11424 return E;
11425}
11426
11427template<typename Derived>
11428ExprResult
11429TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
11430 return getDerived().TransformCallExpr(E);
11431}
11432
11433template<typename Derived>
11434ExprResult
11435TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
11436 ExprResult ControllingExpr;
11437 TypeSourceInfo *ControllingType = nullptr;
11438 if (E->isExprPredicate())
11439 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
11440 else
11441 ControllingType = getDerived().TransformType(E->getControllingType());
11442
11443 if (ControllingExpr.isInvalid() && !ControllingType)
11444 return ExprError();
11445
11446 SmallVector<Expr *, 4> AssocExprs;
11447 SmallVector<TypeSourceInfo *, 4> AssocTypes;
11448 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
11449 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
11450 if (TSI) {
11451 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
11452 if (!AssocType)
11453 return ExprError();
11454 AssocTypes.push_back(AssocType);
11455 } else {
11456 AssocTypes.push_back(nullptr);
11457 }
11458
11459 ExprResult AssocExpr =
11460 getDerived().TransformExpr(Assoc.getAssociationExpr());
11461 if (AssocExpr.isInvalid())
11462 return ExprError();
11463 AssocExprs.push_back(AssocExpr.get());
11464 }
11465
11466 if (!ControllingType)
11467 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
11468 E->getDefaultLoc(),
11469 E->getRParenLoc(),
11470 ControllingExpr.get(),
11471 AssocTypes,
11472 AssocExprs);
11473 return getDerived().RebuildGenericSelectionExpr(
11474 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11475 ControllingType, AssocTypes, AssocExprs);
11476}
11477
11478template<typename Derived>
11479ExprResult
11480TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11481 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11482 if (SubExpr.isInvalid())
11483 return ExprError();
11484
11485 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11486 return E;
11487
11488 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11489 E->getRParen());
11490}
11491
11492/// The operand of a unary address-of operator has special rules: it's
11493/// allowed to refer to a non-static member of a class even if there's no 'this'
11494/// object available.
11495template<typename Derived>
11496ExprResult
11497TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
11498 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
11499 return getDerived().TransformDependentScopeDeclRefExpr(
11500 DRE, /*IsAddressOfOperand=*/true, nullptr);
11501 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
11502 return getDerived().TransformUnresolvedLookupExpr(
11503 ULE, /*IsAddressOfOperand=*/true);
11504 else
11505 return getDerived().TransformExpr(E);
11506}
11507
11508template<typename Derived>
11509ExprResult
11510TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
11511 ExprResult SubExpr;
11512 if (E->getOpcode() == UO_AddrOf)
11513 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
11514 else
11515 SubExpr = TransformExpr(E: E->getSubExpr());
11516 if (SubExpr.isInvalid())
11517 return ExprError();
11518
11519 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11520 return E;
11521
11522 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11523 E->getOpcode(),
11524 SubExpr.get());
11525}
11526
11527template<typename Derived>
11528ExprResult
11529TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11530 // Transform the type.
11531 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11532 if (!Type)
11533 return ExprError();
11534
11535 // Transform all of the components into components similar to what the
11536 // parser uses.
11537 // FIXME: It would be slightly more efficient in the non-dependent case to
11538 // just map FieldDecls, rather than requiring the rebuilder to look for
11539 // the fields again. However, __builtin_offsetof is rare enough in
11540 // template code that we don't care.
11541 bool ExprChanged = false;
11542 typedef Sema::OffsetOfComponent Component;
11543 SmallVector<Component, 4> Components;
11544 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11545 const OffsetOfNode &ON = E->getComponent(Idx: I);
11546 Component Comp;
11547 Comp.isBrackets = true;
11548 Comp.LocStart = ON.getSourceRange().getBegin();
11549 Comp.LocEnd = ON.getSourceRange().getEnd();
11550 switch (ON.getKind()) {
11551 case OffsetOfNode::Array: {
11552 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
11553 ExprResult Index = getDerived().TransformExpr(FromIndex);
11554 if (Index.isInvalid())
11555 return ExprError();
11556
11557 ExprChanged = ExprChanged || Index.get() != FromIndex;
11558 Comp.isBrackets = true;
11559 Comp.U.E = Index.get();
11560 break;
11561 }
11562
11563 case OffsetOfNode::Field:
11564 case OffsetOfNode::Identifier:
11565 Comp.isBrackets = false;
11566 Comp.U.IdentInfo = ON.getFieldName();
11567 if (!Comp.U.IdentInfo)
11568 continue;
11569
11570 break;
11571
11572 case OffsetOfNode::Base:
11573 // Will be recomputed during the rebuild.
11574 continue;
11575 }
11576
11577 Components.push_back(Comp);
11578 }
11579
11580 // If nothing changed, retain the existing expression.
11581 if (!getDerived().AlwaysRebuild() &&
11582 Type == E->getTypeSourceInfo() &&
11583 !ExprChanged)
11584 return E;
11585
11586 // Build a new offsetof expression.
11587 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11588 Components, E->getRParenLoc());
11589}
11590
11591template<typename Derived>
11592ExprResult
11593TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
11594 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
11595 "opaque value expression requires transformation");
11596 return E;
11597}
11598
11599template<typename Derived>
11600ExprResult
11601TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
11602 return E;
11603}
11604
11605template <typename Derived>
11606ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
11607 llvm::SmallVector<Expr *, 8> Children;
11608 bool Changed = false;
11609 for (Expr *C : E->subExpressions()) {
11610 ExprResult NewC = getDerived().TransformExpr(C);
11611 if (NewC.isInvalid())
11612 return ExprError();
11613 Children.push_back(NewC.get());
11614
11615 Changed |= NewC.get() != C;
11616 }
11617 if (!getDerived().AlwaysRebuild() && !Changed)
11618 return E;
11619 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
11620 Children, E->getType());
11621}
11622
11623template<typename Derived>
11624ExprResult
11625TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
11626 // Rebuild the syntactic form. The original syntactic form has
11627 // opaque-value expressions in it, so strip those away and rebuild
11628 // the result. This is a really awful way of doing this, but the
11629 // better solution (rebuilding the semantic expressions and
11630 // rebinding OVEs as necessary) doesn't work; we'd need
11631 // TreeTransform to not strip away implicit conversions.
11632 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
11633 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
11634 if (result.isInvalid()) return ExprError();
11635
11636 // If that gives us a pseudo-object result back, the pseudo-object
11637 // expression must have been an lvalue-to-rvalue conversion which we
11638 // should reapply.
11639 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
11640 result = SemaRef.checkPseudoObjectRValue(E: result.get());
11641
11642 return result;
11643}
11644
11645template<typename Derived>
11646ExprResult
11647TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11648 UnaryExprOrTypeTraitExpr *E) {
11649 if (E->isArgumentType()) {
11650 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11651
11652 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11653 if (!NewT)
11654 return ExprError();
11655
11656 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11657 return E;
11658
11659 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11660 E->getKind(),
11661 E->getSourceRange());
11662 }
11663
11664 // C++0x [expr.sizeof]p1:
11665 // The operand is either an expression, which is an unevaluated operand
11666 // [...]
11667 EnterExpressionEvaluationContext Unevaluated(
11668 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
11669 Sema::ReuseLambdaContextDecl);
11670
11671 // Try to recover if we have something like sizeof(T::X) where X is a type.
11672 // Notably, there must be *exactly* one set of parens if X is a type.
11673 TypeSourceInfo *RecoveryTSI = nullptr;
11674 ExprResult SubExpr;
11675 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11676 if (auto *DRE =
11677 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11678 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11679 PE, DRE, false, &RecoveryTSI);
11680 else
11681 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11682
11683 if (RecoveryTSI) {
11684 return getDerived().RebuildUnaryExprOrTypeTrait(
11685 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11686 } else if (SubExpr.isInvalid())
11687 return ExprError();
11688
11689 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11690 return E;
11691
11692 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11693 E->getOperatorLoc(),
11694 E->getKind(),
11695 E->getSourceRange());
11696}
11697
11698template<typename Derived>
11699ExprResult
11700TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11701 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11702 if (LHS.isInvalid())
11703 return ExprError();
11704
11705 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11706 if (RHS.isInvalid())
11707 return ExprError();
11708
11709
11710 if (!getDerived().AlwaysRebuild() &&
11711 LHS.get() == E->getLHS() &&
11712 RHS.get() == E->getRHS())
11713 return E;
11714
11715 return getDerived().RebuildArraySubscriptExpr(
11716 LHS.get(),
11717 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11718}
11719
11720template <typename Derived>
11721ExprResult
11722TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11723 ExprResult Base = getDerived().TransformExpr(E->getBase());
11724 if (Base.isInvalid())
11725 return ExprError();
11726
11727 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11728 if (RowIdx.isInvalid())
11729 return ExprError();
11730
11731 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11732 if (ColumnIdx.isInvalid())
11733 return ExprError();
11734
11735 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11736 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11737 return E;
11738
11739 return getDerived().RebuildMatrixSubscriptExpr(
11740 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11741}
11742
11743template <typename Derived>
11744ExprResult
11745TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
11746 ExprResult Base = getDerived().TransformExpr(E->getBase());
11747 if (Base.isInvalid())
11748 return ExprError();
11749
11750 ExprResult LowerBound;
11751 if (E->getLowerBound()) {
11752 LowerBound = getDerived().TransformExpr(E->getLowerBound());
11753 if (LowerBound.isInvalid())
11754 return ExprError();
11755 }
11756
11757 ExprResult Length;
11758 if (E->getLength()) {
11759 Length = getDerived().TransformExpr(E->getLength());
11760 if (Length.isInvalid())
11761 return ExprError();
11762 }
11763
11764 ExprResult Stride;
11765 if (Expr *Str = E->getStride()) {
11766 Stride = getDerived().TransformExpr(Str);
11767 if (Stride.isInvalid())
11768 return ExprError();
11769 }
11770
11771 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11772 LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())
11773 return E;
11774
11775 return getDerived().RebuildOMPArraySectionExpr(
11776 Base.get(), E->getBase()->getEndLoc(), LowerBound.get(),
11777 E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(),
11778 E->getRBracketLoc());
11779}
11780
11781template <typename Derived>
11782ExprResult
11783TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
11784 ExprResult Base = getDerived().TransformExpr(E->getBase());
11785 if (Base.isInvalid())
11786 return ExprError();
11787
11788 SmallVector<Expr *, 4> Dims;
11789 bool ErrorFound = false;
11790 for (Expr *Dim : E->getDimensions()) {
11791 ExprResult DimRes = getDerived().TransformExpr(Dim);
11792 if (DimRes.isInvalid()) {
11793 ErrorFound = true;
11794 continue;
11795 }
11796 Dims.push_back(Elt: DimRes.get());
11797 }
11798
11799 if (ErrorFound)
11800 return ExprError();
11801 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
11802 E->getRParenLoc(), Dims,
11803 E->getBracketsRanges());
11804}
11805
11806template <typename Derived>
11807ExprResult
11808TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
11809 unsigned NumIterators = E->numOfIterators();
11810 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
11811
11812 bool ErrorFound = false;
11813 bool NeedToRebuild = getDerived().AlwaysRebuild();
11814 for (unsigned I = 0; I < NumIterators; ++I) {
11815 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
11816 Data[I].DeclIdent = D->getIdentifier();
11817 Data[I].DeclIdentLoc = D->getLocation();
11818 if (D->getLocation() == D->getBeginLoc()) {
11819 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
11820 "Implicit type must be int.");
11821 } else {
11822 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
11823 QualType DeclTy = getDerived().TransformType(D->getType());
11824 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
11825 }
11826 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
11827 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
11828 ExprResult End = getDerived().TransformExpr(Range.End);
11829 ExprResult Step = getDerived().TransformExpr(Range.Step);
11830 ErrorFound = ErrorFound ||
11831 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
11832 !Data[I].Type.get().isNull())) ||
11833 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
11834 if (ErrorFound)
11835 continue;
11836 Data[I].Range.Begin = Begin.get();
11837 Data[I].Range.End = End.get();
11838 Data[I].Range.Step = Step.get();
11839 Data[I].AssignLoc = E->getAssignLoc(I);
11840 Data[I].ColonLoc = E->getColonLoc(I);
11841 Data[I].SecColonLoc = E->getSecondColonLoc(I);
11842 NeedToRebuild =
11843 NeedToRebuild ||
11844 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
11845 D->getType().getTypePtrOrNull()) ||
11846 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
11847 Range.Step != Data[I].Range.Step;
11848 }
11849 if (ErrorFound)
11850 return ExprError();
11851 if (!NeedToRebuild)
11852 return E;
11853
11854 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
11855 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
11856 if (!Res.isUsable())
11857 return Res;
11858 auto *IE = cast<OMPIteratorExpr>(Res.get());
11859 for (unsigned I = 0; I < NumIterators; ++I)
11860 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
11861 IE->getIteratorDecl(I));
11862 return Res;
11863}
11864
11865template<typename Derived>
11866ExprResult
11867TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
11868 // Transform the callee.
11869 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11870 if (Callee.isInvalid())
11871 return ExprError();
11872
11873 // Transform arguments.
11874 bool ArgChanged = false;
11875 SmallVector<Expr*, 8> Args;
11876 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11877 &ArgChanged))
11878 return ExprError();
11879
11880 if (!getDerived().AlwaysRebuild() &&
11881 Callee.get() == E->getCallee() &&
11882 !ArgChanged)
11883 return SemaRef.MaybeBindToTemporary(E);
11884
11885 // FIXME: Wrong source location information for the '('.
11886 SourceLocation FakeLParenLoc
11887 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11888
11889 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11890 if (E->hasStoredFPFeatures()) {
11891 FPOptionsOverride NewOverrides = E->getFPFeatures();
11892 getSema().CurFPFeatures =
11893 NewOverrides.applyOverrides(getSema().getLangOpts());
11894 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11895 }
11896
11897 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11898 Args,
11899 E->getRParenLoc());
11900}
11901
11902template<typename Derived>
11903ExprResult
11904TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
11905 ExprResult Base = getDerived().TransformExpr(E->getBase());
11906 if (Base.isInvalid())
11907 return ExprError();
11908
11909 NestedNameSpecifierLoc QualifierLoc;
11910 if (E->hasQualifier()) {
11911 QualifierLoc
11912 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11913
11914 if (!QualifierLoc)
11915 return ExprError();
11916 }
11917 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
11918
11919 ValueDecl *Member
11920 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
11921 E->getMemberDecl()));
11922 if (!Member)
11923 return ExprError();
11924
11925 NamedDecl *FoundDecl = E->getFoundDecl();
11926 if (FoundDecl == E->getMemberDecl()) {
11927 FoundDecl = Member;
11928 } else {
11929 FoundDecl = cast_or_null<NamedDecl>(
11930 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
11931 if (!FoundDecl)
11932 return ExprError();
11933 }
11934
11935 if (!getDerived().AlwaysRebuild() &&
11936 Base.get() == E->getBase() &&
11937 QualifierLoc == E->getQualifierLoc() &&
11938 Member == E->getMemberDecl() &&
11939 FoundDecl == E->getFoundDecl() &&
11940 !E->hasExplicitTemplateArgs()) {
11941
11942 // Skip for member expression of (this->f), rebuilt thisi->f is needed
11943 // for Openmp where the field need to be privatizized in the case.
11944 if (!(isa<CXXThisExpr>(E->getBase()) &&
11945 getSema().OpenMP().isOpenMPRebuildMemberExpr(
11946 cast<ValueDecl>(Member)))) {
11947 // Mark it referenced in the new context regardless.
11948 // FIXME: this is a bit instantiation-specific.
11949 SemaRef.MarkMemberReferenced(E);
11950 return E;
11951 }
11952 }
11953
11954 TemplateArgumentListInfo TransArgs;
11955 if (E->hasExplicitTemplateArgs()) {
11956 TransArgs.setLAngleLoc(E->getLAngleLoc());
11957 TransArgs.setRAngleLoc(E->getRAngleLoc());
11958 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11959 E->getNumTemplateArgs(),
11960 TransArgs))
11961 return ExprError();
11962 }
11963
11964 // FIXME: Bogus source location for the operator
11965 SourceLocation FakeOperatorLoc =
11966 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
11967
11968 // FIXME: to do this check properly, we will need to preserve the
11969 // first-qualifier-in-scope here, just in case we had a dependent
11970 // base (and therefore couldn't do the check) and a
11971 // nested-name-qualifier (and therefore could do the lookup).
11972 NamedDecl *FirstQualifierInScope = nullptr;
11973 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
11974 if (MemberNameInfo.getName()) {
11975 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
11976 if (!MemberNameInfo.getName())
11977 return ExprError();
11978 }
11979
11980 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
11981 E->isArrow(),
11982 QualifierLoc,
11983 TemplateKWLoc,
11984 MemberNameInfo,
11985 Member,
11986 FoundDecl,
11987 (E->hasExplicitTemplateArgs()
11988 ? &TransArgs : nullptr),
11989 FirstQualifierInScope);
11990}
11991
11992template<typename Derived>
11993ExprResult
11994TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
11995 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11996 if (LHS.isInvalid())
11997 return ExprError();
11998
11999 ExprResult RHS =
12000 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
12001 if (RHS.isInvalid())
12002 return ExprError();
12003
12004 if (!getDerived().AlwaysRebuild() &&
12005 LHS.get() == E->getLHS() &&
12006 RHS.get() == E->getRHS())
12007 return E;
12008
12009 if (E->isCompoundAssignmentOp())
12010 // FPFeatures has already been established from trailing storage
12011 return getDerived().RebuildBinaryOperator(
12012 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
12013 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12014 FPOptionsOverride NewOverrides(E->getFPFeatures());
12015 getSema().CurFPFeatures =
12016 NewOverrides.applyOverrides(getSema().getLangOpts());
12017 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12018 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
12019 LHS.get(), RHS.get());
12020}
12021
12022template <typename Derived>
12023ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
12024 CXXRewrittenBinaryOperator *E) {
12025 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
12026
12027 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
12028 if (LHS.isInvalid())
12029 return ExprError();
12030
12031 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
12032 if (RHS.isInvalid())
12033 return ExprError();
12034
12035 // Extract the already-resolved callee declarations so that we can restrict
12036 // ourselves to using them as the unqualified lookup results when rebuilding.
12037 UnresolvedSet<2> UnqualLookups;
12038 bool ChangedAnyLookups = false;
12039 Expr *PossibleBinOps[] = {E->getSemanticForm(),
12040 const_cast<Expr *>(Decomp.InnerBinOp)};
12041 for (Expr *PossibleBinOp : PossibleBinOps) {
12042 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
12043 if (!Op)
12044 continue;
12045 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
12046 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
12047 continue;
12048
12049 // Transform the callee in case we built a call to a local extern
12050 // declaration.
12051 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
12052 E->getOperatorLoc(), Callee->getFoundDecl()));
12053 if (!Found)
12054 return ExprError();
12055 if (Found != Callee->getFoundDecl())
12056 ChangedAnyLookups = true;
12057 UnqualLookups.addDecl(Found);
12058 }
12059
12060 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
12061 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
12062 // Mark all functions used in the rewrite as referenced. Note that when
12063 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
12064 // function calls, and/or there might be a user-defined conversion sequence
12065 // applied to the operands of the <.
12066 // FIXME: this is a bit instantiation-specific.
12067 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
12068 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
12069 return E;
12070 }
12071
12072 return getDerived().RebuildCXXRewrittenBinaryOperator(
12073 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
12074}
12075
12076template<typename Derived>
12077ExprResult
12078TreeTransform<Derived>::TransformCompoundAssignOperator(
12079 CompoundAssignOperator *E) {
12080 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12081 FPOptionsOverride NewOverrides(E->getFPFeatures());
12082 getSema().CurFPFeatures =
12083 NewOverrides.applyOverrides(getSema().getLangOpts());
12084 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12085 return getDerived().TransformBinaryOperator(E);
12086}
12087
12088template<typename Derived>
12089ExprResult TreeTransform<Derived>::
12090TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
12091 // Just rebuild the common and RHS expressions and see whether we
12092 // get any changes.
12093
12094 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
12095 if (commonExpr.isInvalid())
12096 return ExprError();
12097
12098 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
12099 if (rhs.isInvalid())
12100 return ExprError();
12101
12102 if (!getDerived().AlwaysRebuild() &&
12103 commonExpr.get() == e->getCommon() &&
12104 rhs.get() == e->getFalseExpr())
12105 return e;
12106
12107 return getDerived().RebuildConditionalOperator(commonExpr.get(),
12108 e->getQuestionLoc(),
12109 nullptr,
12110 e->getColonLoc(),
12111 rhs.get());
12112}
12113
12114template<typename Derived>
12115ExprResult
12116TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
12117 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12118 if (Cond.isInvalid())
12119 return ExprError();
12120
12121 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12122 if (LHS.isInvalid())
12123 return ExprError();
12124
12125 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12126 if (RHS.isInvalid())
12127 return ExprError();
12128
12129 if (!getDerived().AlwaysRebuild() &&
12130 Cond.get() == E->getCond() &&
12131 LHS.get() == E->getLHS() &&
12132 RHS.get() == E->getRHS())
12133 return E;
12134
12135 return getDerived().RebuildConditionalOperator(Cond.get(),
12136 E->getQuestionLoc(),
12137 LHS.get(),
12138 E->getColonLoc(),
12139 RHS.get());
12140}
12141
12142template<typename Derived>
12143ExprResult
12144TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
12145 // Implicit casts are eliminated during transformation, since they
12146 // will be recomputed by semantic analysis after transformation.
12147 return getDerived().TransformExpr(E->getSubExprAsWritten());
12148}
12149
12150template<typename Derived>
12151ExprResult
12152TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
12153 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12154 if (!Type)
12155 return ExprError();
12156
12157 ExprResult SubExpr
12158 = getDerived().TransformExpr(E->getSubExprAsWritten());
12159 if (SubExpr.isInvalid())
12160 return ExprError();
12161
12162 if (!getDerived().AlwaysRebuild() &&
12163 Type == E->getTypeInfoAsWritten() &&
12164 SubExpr.get() == E->getSubExpr())
12165 return E;
12166
12167 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
12168 Type,
12169 E->getRParenLoc(),
12170 SubExpr.get());
12171}
12172
12173template<typename Derived>
12174ExprResult
12175TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
12176 TypeSourceInfo *OldT = E->getTypeSourceInfo();
12177 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12178 if (!NewT)
12179 return ExprError();
12180
12181 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
12182 if (Init.isInvalid())
12183 return ExprError();
12184
12185 if (!getDerived().AlwaysRebuild() &&
12186 OldT == NewT &&
12187 Init.get() == E->getInitializer())
12188 return SemaRef.MaybeBindToTemporary(E);
12189
12190 // Note: the expression type doesn't necessarily match the
12191 // type-as-written, but that's okay, because it should always be
12192 // derivable from the initializer.
12193
12194 return getDerived().RebuildCompoundLiteralExpr(
12195 E->getLParenLoc(), NewT,
12196 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
12197}
12198
12199template<typename Derived>
12200ExprResult
12201TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
12202 ExprResult Base = getDerived().TransformExpr(E->getBase());
12203 if (Base.isInvalid())
12204 return ExprError();
12205
12206 if (!getDerived().AlwaysRebuild() &&
12207 Base.get() == E->getBase())
12208 return E;
12209
12210 // FIXME: Bad source location
12211 SourceLocation FakeOperatorLoc =
12212 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
12213 return getDerived().RebuildExtVectorElementExpr(
12214 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
12215 E->getAccessor());
12216}
12217
12218template<typename Derived>
12219ExprResult
12220TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
12221 if (InitListExpr *Syntactic = E->getSyntacticForm())
12222 E = Syntactic;
12223
12224 bool InitChanged = false;
12225
12226 EnterExpressionEvaluationContext Context(
12227 getSema(), EnterExpressionEvaluationContext::InitList);
12228
12229 SmallVector<Expr*, 4> Inits;
12230 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
12231 Inits, &InitChanged))
12232 return ExprError();
12233
12234 if (!getDerived().AlwaysRebuild() && !InitChanged) {
12235 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
12236 // in some cases. We can't reuse it in general, because the syntactic and
12237 // semantic forms are linked, and we can't know that semantic form will
12238 // match even if the syntactic form does.
12239 }
12240
12241 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
12242 E->getRBraceLoc());
12243}
12244
12245template<typename Derived>
12246ExprResult
12247TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
12248 Designation Desig;
12249
12250 // transform the initializer value
12251 ExprResult Init = getDerived().TransformExpr(E->getInit());
12252 if (Init.isInvalid())
12253 return ExprError();
12254
12255 // transform the designators.
12256 SmallVector<Expr*, 4> ArrayExprs;
12257 bool ExprChanged = false;
12258 for (const DesignatedInitExpr::Designator &D : E->designators()) {
12259 if (D.isFieldDesignator()) {
12260 if (D.getFieldDecl()) {
12261 FieldDecl *Field = cast_or_null<FieldDecl>(
12262 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
12263 if (Field != D.getFieldDecl())
12264 // Rebuild the expression when the transformed FieldDecl is
12265 // different to the already assigned FieldDecl.
12266 ExprChanged = true;
12267 if (Field->isAnonymousStructOrUnion())
12268 continue;
12269 } else {
12270 // Ensure that the designator expression is rebuilt when there isn't
12271 // a resolved FieldDecl in the designator as we don't want to assign
12272 // a FieldDecl to a pattern designator that will be instantiated again.
12273 ExprChanged = true;
12274 }
12275 Desig.AddDesignator(Designator::CreateFieldDesignator(
12276 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
12277 continue;
12278 }
12279
12280 if (D.isArrayDesignator()) {
12281 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
12282 if (Index.isInvalid())
12283 return ExprError();
12284
12285 Desig.AddDesignator(
12286 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
12287
12288 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
12289 ArrayExprs.push_back(Index.get());
12290 continue;
12291 }
12292
12293 assert(D.isArrayRangeDesignator() && "New kind of designator?");
12294 ExprResult Start
12295 = getDerived().TransformExpr(E->getArrayRangeStart(D));
12296 if (Start.isInvalid())
12297 return ExprError();
12298
12299 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
12300 if (End.isInvalid())
12301 return ExprError();
12302
12303 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
12304 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
12305
12306 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
12307 End.get() != E->getArrayRangeEnd(D);
12308
12309 ArrayExprs.push_back(Start.get());
12310 ArrayExprs.push_back(End.get());
12311 }
12312
12313 if (!getDerived().AlwaysRebuild() &&
12314 Init.get() == E->getInit() &&
12315 !ExprChanged)
12316 return E;
12317
12318 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
12319 E->getEqualOrColonLoc(),
12320 E->usesGNUSyntax(), Init.get());
12321}
12322
12323// Seems that if TransformInitListExpr() only works on the syntactic form of an
12324// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
12325template<typename Derived>
12326ExprResult
12327TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
12328 DesignatedInitUpdateExpr *E) {
12329 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
12330 "initializer");
12331 return ExprError();
12332}
12333
12334template<typename Derived>
12335ExprResult
12336TreeTransform<Derived>::TransformNoInitExpr(
12337 NoInitExpr *E) {
12338 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
12339 return ExprError();
12340}
12341
12342template<typename Derived>
12343ExprResult
12344TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
12345 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
12346 return ExprError();
12347}
12348
12349template<typename Derived>
12350ExprResult
12351TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
12352 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
12353 return ExprError();
12354}
12355
12356template<typename Derived>
12357ExprResult
12358TreeTransform<Derived>::TransformImplicitValueInitExpr(
12359 ImplicitValueInitExpr *E) {
12360 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
12361
12362 // FIXME: Will we ever have proper type location here? Will we actually
12363 // need to transform the type?
12364 QualType T = getDerived().TransformType(E->getType());
12365 if (T.isNull())
12366 return ExprError();
12367
12368 if (!getDerived().AlwaysRebuild() &&
12369 T == E->getType())
12370 return E;
12371
12372 return getDerived().RebuildImplicitValueInitExpr(T);
12373}
12374
12375template<typename Derived>
12376ExprResult
12377TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
12378 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
12379 if (!TInfo)
12380 return ExprError();
12381
12382 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12383 if (SubExpr.isInvalid())
12384 return ExprError();
12385
12386 if (!getDerived().AlwaysRebuild() &&
12387 TInfo == E->getWrittenTypeInfo() &&
12388 SubExpr.get() == E->getSubExpr())
12389 return E;
12390
12391 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
12392 TInfo, E->getRParenLoc());
12393}
12394
12395template<typename Derived>
12396ExprResult
12397TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
12398 bool ArgumentChanged = false;
12399 SmallVector<Expr*, 4> Inits;
12400 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
12401 ArgChanged: &ArgumentChanged))
12402 return ExprError();
12403
12404 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
12405 Inits,
12406 E->getRParenLoc());
12407}
12408
12409/// Transform an address-of-label expression.
12410///
12411/// By default, the transformation of an address-of-label expression always
12412/// rebuilds the expression, so that the label identifier can be resolved to
12413/// the corresponding label statement by semantic analysis.
12414template<typename Derived>
12415ExprResult
12416TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
12417 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
12418 E->getLabel());
12419 if (!LD)
12420 return ExprError();
12421
12422 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
12423 cast<LabelDecl>(LD));
12424}
12425
12426template<typename Derived>
12427ExprResult
12428TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
12429 SemaRef.ActOnStartStmtExpr();
12430 StmtResult SubStmt
12431 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
12432 if (SubStmt.isInvalid()) {
12433 SemaRef.ActOnStmtExprError();
12434 return ExprError();
12435 }
12436
12437 unsigned OldDepth = E->getTemplateDepth();
12438 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
12439
12440 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
12441 SubStmt.get() == E->getSubStmt()) {
12442 // Calling this an 'error' is unintuitive, but it does the right thing.
12443 SemaRef.ActOnStmtExprError();
12444 return SemaRef.MaybeBindToTemporary(E);
12445 }
12446
12447 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
12448 E->getRParenLoc(), NewDepth);
12449}
12450
12451template<typename Derived>
12452ExprResult
12453TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
12454 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12455 if (Cond.isInvalid())
12456 return ExprError();
12457
12458 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12459 if (LHS.isInvalid())
12460 return ExprError();
12461
12462 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12463 if (RHS.isInvalid())
12464 return ExprError();
12465
12466 if (!getDerived().AlwaysRebuild() &&
12467 Cond.get() == E->getCond() &&
12468 LHS.get() == E->getLHS() &&
12469 RHS.get() == E->getRHS())
12470 return E;
12471
12472 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
12473 Cond.get(), LHS.get(), RHS.get(),
12474 E->getRParenLoc());
12475}
12476
12477template<typename Derived>
12478ExprResult
12479TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12480 return E;
12481}
12482
12483template<typename Derived>
12484ExprResult
12485TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12486 switch (E->getOperator()) {
12487 case OO_New:
12488 case OO_Delete:
12489 case OO_Array_New:
12490 case OO_Array_Delete:
12491 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12492
12493 case OO_Subscript:
12494 case OO_Call: {
12495 // This is a call to an object's operator().
12496 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12497
12498 // Transform the object itself.
12499 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
12500 if (Object.isInvalid())
12501 return ExprError();
12502
12503 // FIXME: Poor location information
12504 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12505 Loc: static_cast<Expr *>(Object.get())->getEndLoc());
12506
12507 // Transform the call arguments.
12508 SmallVector<Expr*, 8> Args;
12509 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12510 Args))
12511 return ExprError();
12512
12513 if (E->getOperator() == OO_Subscript)
12514 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12515 Args, E->getEndLoc());
12516
12517 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12518 E->getEndLoc());
12519 }
12520
12521#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12522 case OO_##Name: \
12523 break;
12524
12525#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12526#include "clang/Basic/OperatorKinds.def"
12527
12528 case OO_Conditional:
12529 llvm_unreachable("conditional operator is not actually overloadable");
12530
12531 case OO_None:
12532 case NUM_OVERLOADED_OPERATORS:
12533 llvm_unreachable("not an overloaded operator?");
12534 }
12535
12536 ExprResult First;
12537 if (E->getOperator() == OO_Amp)
12538 First = getDerived().TransformAddressOfOperand(E->getArg(0));
12539 else
12540 First = getDerived().TransformExpr(E->getArg(0));
12541 if (First.isInvalid())
12542 return ExprError();
12543
12544 ExprResult Second;
12545 if (E->getNumArgs() == 2) {
12546 Second =
12547 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
12548 if (Second.isInvalid())
12549 return ExprError();
12550 }
12551
12552 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12553 FPOptionsOverride NewOverrides(E->getFPFeatures());
12554 getSema().CurFPFeatures =
12555 NewOverrides.applyOverrides(getSema().getLangOpts());
12556 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12557
12558 Expr *Callee = E->getCallee();
12559 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
12560 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12561 Sema::LookupOrdinaryName);
12562 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12563 return ExprError();
12564
12565 return getDerived().RebuildCXXOperatorCallExpr(
12566 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12567 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12568 }
12569
12570 UnresolvedSet<1> Functions;
12571 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
12572 Callee = ICE->getSubExprAsWritten();
12573 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
12574 ValueDecl *VD = cast_or_null<ValueDecl>(
12575 getDerived().TransformDecl(DR->getLocation(), DR));
12576 if (!VD)
12577 return ExprError();
12578
12579 if (!isa<CXXMethodDecl>(VD))
12580 Functions.addDecl(VD);
12581
12582 return getDerived().RebuildCXXOperatorCallExpr(
12583 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12584 /*RequiresADL=*/false, Functions, First.get(), Second.get());
12585}
12586
12587template<typename Derived>
12588ExprResult
12589TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
12590 return getDerived().TransformCallExpr(E);
12591}
12592
12593template <typename Derived>
12594ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
12595 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
12596 getSema().CurContext != E->getParentContext();
12597
12598 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
12599 return E;
12600
12601 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
12602 E->getBeginLoc(), E->getEndLoc(),
12603 getSema().CurContext);
12604}
12605
12606template<typename Derived>
12607ExprResult
12608TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
12609 // Transform the callee.
12610 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12611 if (Callee.isInvalid())
12612 return ExprError();
12613
12614 // Transform exec config.
12615 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
12616 if (EC.isInvalid())
12617 return ExprError();
12618
12619 // Transform arguments.
12620 bool ArgChanged = false;
12621 SmallVector<Expr*, 8> Args;
12622 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12623 &ArgChanged))
12624 return ExprError();
12625
12626 if (!getDerived().AlwaysRebuild() &&
12627 Callee.get() == E->getCallee() &&
12628 !ArgChanged)
12629 return SemaRef.MaybeBindToTemporary(E);
12630
12631 // FIXME: Wrong source location information for the '('.
12632 SourceLocation FakeLParenLoc
12633 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12634 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12635 Args,
12636 E->getRParenLoc(), EC.get());
12637}
12638
12639template<typename Derived>
12640ExprResult
12641TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
12642 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12643 if (!Type)
12644 return ExprError();
12645
12646 ExprResult SubExpr
12647 = getDerived().TransformExpr(E->getSubExprAsWritten());
12648 if (SubExpr.isInvalid())
12649 return ExprError();
12650
12651 if (!getDerived().AlwaysRebuild() &&
12652 Type == E->getTypeInfoAsWritten() &&
12653 SubExpr.get() == E->getSubExpr())
12654 return E;
12655 return getDerived().RebuildCXXNamedCastExpr(
12656 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
12657 Type, E->getAngleBrackets().getEnd(),
12658 // FIXME. this should be '(' location
12659 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
12660}
12661
12662template<typename Derived>
12663ExprResult
12664TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
12665 TypeSourceInfo *TSI =
12666 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12667 if (!TSI)
12668 return ExprError();
12669
12670 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12671 if (Sub.isInvalid())
12672 return ExprError();
12673
12674 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12675 Sub.get(), BCE->getEndLoc());
12676}
12677
12678template<typename Derived>
12679ExprResult
12680TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12681 return getDerived().TransformCXXNamedCastExpr(E);
12682}
12683
12684template<typename Derived>
12685ExprResult
12686TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12687 return getDerived().TransformCXXNamedCastExpr(E);
12688}
12689
12690template<typename Derived>
12691ExprResult
12692TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12693 CXXReinterpretCastExpr *E) {
12694 return getDerived().TransformCXXNamedCastExpr(E);
12695}
12696
12697template<typename Derived>
12698ExprResult
12699TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12700 return getDerived().TransformCXXNamedCastExpr(E);
12701}
12702
12703template<typename Derived>
12704ExprResult
12705TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12706 return getDerived().TransformCXXNamedCastExpr(E);
12707}
12708
12709template<typename Derived>
12710ExprResult
12711TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12712 CXXFunctionalCastExpr *E) {
12713 TypeSourceInfo *Type =
12714 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12715 if (!Type)
12716 return ExprError();
12717
12718 ExprResult SubExpr
12719 = getDerived().TransformExpr(E->getSubExprAsWritten());
12720 if (SubExpr.isInvalid())
12721 return ExprError();
12722
12723 if (!getDerived().AlwaysRebuild() &&
12724 Type == E->getTypeInfoAsWritten() &&
12725 SubExpr.get() == E->getSubExpr())
12726 return E;
12727
12728 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12729 E->getLParenLoc(),
12730 SubExpr.get(),
12731 E->getRParenLoc(),
12732 E->isListInitialization());
12733}
12734
12735template<typename Derived>
12736ExprResult
12737TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12738 if (E->isTypeOperand()) {
12739 TypeSourceInfo *TInfo
12740 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12741 if (!TInfo)
12742 return ExprError();
12743
12744 if (!getDerived().AlwaysRebuild() &&
12745 TInfo == E->getTypeOperandSourceInfo())
12746 return E;
12747
12748 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12749 TInfo, E->getEndLoc());
12750 }
12751
12752 // Typeid's operand is an unevaluated context, unless it's a polymorphic
12753 // type. We must not unilaterally enter unevaluated context here, as then
12754 // semantic processing can re-transform an already transformed operand.
12755 Expr *Op = E->getExprOperand();
12756 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
12757 if (E->isGLValue())
12758 if (auto *RecordT = Op->getType()->getAs<RecordType>())
12759 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
12760 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
12761
12762 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
12763 Sema::ReuseLambdaContextDecl);
12764
12765 ExprResult SubExpr = getDerived().TransformExpr(Op);
12766 if (SubExpr.isInvalid())
12767 return ExprError();
12768
12769 if (!getDerived().AlwaysRebuild() &&
12770 SubExpr.get() == E->getExprOperand())
12771 return E;
12772
12773 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12774 SubExpr.get(), E->getEndLoc());
12775}
12776
12777template<typename Derived>
12778ExprResult
12779TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
12780 if (E->isTypeOperand()) {
12781 TypeSourceInfo *TInfo
12782 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12783 if (!TInfo)
12784 return ExprError();
12785
12786 if (!getDerived().AlwaysRebuild() &&
12787 TInfo == E->getTypeOperandSourceInfo())
12788 return E;
12789
12790 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12791 TInfo, E->getEndLoc());
12792 }
12793
12794 EnterExpressionEvaluationContext Unevaluated(
12795 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12796
12797 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
12798 if (SubExpr.isInvalid())
12799 return ExprError();
12800
12801 if (!getDerived().AlwaysRebuild() &&
12802 SubExpr.get() == E->getExprOperand())
12803 return E;
12804
12805 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12806 SubExpr.get(), E->getEndLoc());
12807}
12808
12809template<typename Derived>
12810ExprResult
12811TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
12812 return E;
12813}
12814
12815template<typename Derived>
12816ExprResult
12817TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
12818 CXXNullPtrLiteralExpr *E) {
12819 return E;
12820}
12821
12822template<typename Derived>
12823ExprResult
12824TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
12825
12826 // In lambdas, the qualifiers of the type depends of where in
12827 // the call operator `this` appear, and we do not have a good way to
12828 // rebuild this information, so we transform the type.
12829 //
12830 // In other contexts, the type of `this` may be overrided
12831 // for type deduction, so we need to recompute it.
12832 //
12833 // Always recompute the type if we're in the body of a lambda, and
12834 // 'this' is dependent on a lambda's explicit object parameter.
12835 QualType T = [&]() {
12836 auto &S = getSema();
12837 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
12838 return S.getCurrentThisType();
12839 if (S.getCurLambda())
12840 return getDerived().TransformType(E->getType());
12841 return S.getCurrentThisType();
12842 }();
12843
12844 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
12845 // Mark it referenced in the new context regardless.
12846 // FIXME: this is a bit instantiation-specific.
12847 getSema().MarkThisReferenced(E);
12848 return E;
12849 }
12850
12851 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
12852}
12853
12854template<typename Derived>
12855ExprResult
12856TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
12857 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12858 if (SubExpr.isInvalid())
12859 return ExprError();
12860
12861 if (!getDerived().AlwaysRebuild() &&
12862 SubExpr.get() == E->getSubExpr())
12863 return E;
12864
12865 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
12866 E->isThrownVariableInScope());
12867}
12868
12869template<typename Derived>
12870ExprResult
12871TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
12872 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
12873 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
12874 if (!Param)
12875 return ExprError();
12876
12877 ExprResult InitRes;
12878 if (E->hasRewrittenInit()) {
12879 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
12880 if (InitRes.isInvalid())
12881 return ExprError();
12882 }
12883
12884 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
12885 E->getUsedContext() == SemaRef.CurContext &&
12886 InitRes.get() == E->getRewrittenExpr())
12887 return E;
12888
12889 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
12890 InitRes.get());
12891}
12892
12893template<typename Derived>
12894ExprResult
12895TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
12896 FieldDecl *Field = cast_or_null<FieldDecl>(
12897 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
12898 if (!Field)
12899 return ExprError();
12900
12901 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
12902 E->getUsedContext() == SemaRef.CurContext)
12903 return E;
12904
12905 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
12906}
12907
12908template<typename Derived>
12909ExprResult
12910TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
12911 CXXScalarValueInitExpr *E) {
12912 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
12913 if (!T)
12914 return ExprError();
12915
12916 if (!getDerived().AlwaysRebuild() &&
12917 T == E->getTypeSourceInfo())
12918 return E;
12919
12920 return getDerived().RebuildCXXScalarValueInitExpr(T,
12921 /*FIXME:*/T->getTypeLoc().getEndLoc(),
12922 E->getRParenLoc());
12923}
12924
12925template<typename Derived>
12926ExprResult
12927TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
12928 // Transform the type that we're allocating
12929 TypeSourceInfo *AllocTypeInfo =
12930 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
12931 if (!AllocTypeInfo)
12932 return ExprError();
12933
12934 // Transform the size of the array we're allocating (if any).
12935 std::optional<Expr *> ArraySize;
12936 if (E->isArray()) {
12937 ExprResult NewArraySize;
12938 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
12939 NewArraySize = getDerived().TransformExpr(*OldArraySize);
12940 if (NewArraySize.isInvalid())
12941 return ExprError();
12942 }
12943 ArraySize = NewArraySize.get();
12944 }
12945
12946 // Transform the placement arguments (if any).
12947 bool ArgumentChanged = false;
12948 SmallVector<Expr*, 8> PlacementArgs;
12949 if (getDerived().TransformExprs(E->getPlacementArgs(),
12950 E->getNumPlacementArgs(), true,
12951 PlacementArgs, &ArgumentChanged))
12952 return ExprError();
12953
12954 // Transform the initializer (if any).
12955 Expr *OldInit = E->getInitializer();
12956 ExprResult NewInit;
12957 if (OldInit)
12958 NewInit = getDerived().TransformInitializer(OldInit, true);
12959 if (NewInit.isInvalid())
12960 return ExprError();
12961
12962 // Transform new operator and delete operator.
12963 FunctionDecl *OperatorNew = nullptr;
12964 if (E->getOperatorNew()) {
12965 OperatorNew = cast_or_null<FunctionDecl>(
12966 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
12967 if (!OperatorNew)
12968 return ExprError();
12969 }
12970
12971 FunctionDecl *OperatorDelete = nullptr;
12972 if (E->getOperatorDelete()) {
12973 OperatorDelete = cast_or_null<FunctionDecl>(
12974 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12975 if (!OperatorDelete)
12976 return ExprError();
12977 }
12978
12979 if (!getDerived().AlwaysRebuild() &&
12980 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
12981 ArraySize == E->getArraySize() &&
12982 NewInit.get() == OldInit &&
12983 OperatorNew == E->getOperatorNew() &&
12984 OperatorDelete == E->getOperatorDelete() &&
12985 !ArgumentChanged) {
12986 // Mark any declarations we need as referenced.
12987 // FIXME: instantiation-specific.
12988 if (OperatorNew)
12989 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
12990 if (OperatorDelete)
12991 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
12992
12993 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
12994 QualType ElementType
12995 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
12996 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
12997 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
12998 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record)) {
12999 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
13000 }
13001 }
13002 }
13003
13004 return E;
13005 }
13006
13007 QualType AllocType = AllocTypeInfo->getType();
13008 if (!ArraySize) {
13009 // If no array size was specified, but the new expression was
13010 // instantiated with an array type (e.g., "new T" where T is
13011 // instantiated with "int[4]"), extract the outer bound from the
13012 // array type as our array size. We do this with constant and
13013 // dependently-sized array types.
13014 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
13015 if (!ArrayT) {
13016 // Do nothing
13017 } else if (const ConstantArrayType *ConsArrayT
13018 = dyn_cast<ConstantArrayType>(ArrayT)) {
13019 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
13020 type: SemaRef.Context.getSizeType(),
13021 /*FIXME:*/ l: E->getBeginLoc());
13022 AllocType = ConsArrayT->getElementType();
13023 } else if (const DependentSizedArrayType *DepArrayT
13024 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
13025 if (DepArrayT->getSizeExpr()) {
13026 ArraySize = DepArrayT->getSizeExpr();
13027 AllocType = DepArrayT->getElementType();
13028 }
13029 }
13030 }
13031
13032 return getDerived().RebuildCXXNewExpr(
13033 E->getBeginLoc(), E->isGlobalNew(),
13034 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
13035 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
13036 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
13037}
13038
13039template<typename Derived>
13040ExprResult
13041TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
13042 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
13043 if (Operand.isInvalid())
13044 return ExprError();
13045
13046 // Transform the delete operator, if known.
13047 FunctionDecl *OperatorDelete = nullptr;
13048 if (E->getOperatorDelete()) {
13049 OperatorDelete = cast_or_null<FunctionDecl>(
13050 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13051 if (!OperatorDelete)
13052 return ExprError();
13053 }
13054
13055 if (!getDerived().AlwaysRebuild() &&
13056 Operand.get() == E->getArgument() &&
13057 OperatorDelete == E->getOperatorDelete()) {
13058 // Mark any declarations we need as referenced.
13059 // FIXME: instantiation-specific.
13060 if (OperatorDelete)
13061 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
13062
13063 if (!E->getArgument()->isTypeDependent()) {
13064 QualType Destroyed = SemaRef.Context.getBaseElementType(
13065 QT: E->getDestroyedType());
13066 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
13067 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
13068 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13069 SemaRef.LookupDestructor(Class: Record));
13070 }
13071 }
13072
13073 return E;
13074 }
13075
13076 return getDerived().RebuildCXXDeleteExpr(
13077 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
13078}
13079
13080template<typename Derived>
13081ExprResult
13082TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
13083 CXXPseudoDestructorExpr *E) {
13084 ExprResult Base = getDerived().TransformExpr(E->getBase());
13085 if (Base.isInvalid())
13086 return ExprError();
13087
13088 ParsedType ObjectTypePtr;
13089 bool MayBePseudoDestructor = false;
13090 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
13091 OpLoc: E->getOperatorLoc(),
13092 OpKind: E->isArrow()? tok::arrow : tok::period,
13093 ObjectType&: ObjectTypePtr,
13094 MayBePseudoDestructor);
13095 if (Base.isInvalid())
13096 return ExprError();
13097
13098 QualType ObjectType = ObjectTypePtr.get();
13099 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
13100 if (QualifierLoc) {
13101 QualifierLoc
13102 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
13103 if (!QualifierLoc)
13104 return ExprError();
13105 }
13106 CXXScopeSpec SS;
13107 SS.Adopt(Other: QualifierLoc);
13108
13109 PseudoDestructorTypeStorage Destroyed;
13110 if (E->getDestroyedTypeInfo()) {
13111 TypeSourceInfo *DestroyedTypeInfo
13112 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
13113 ObjectType, nullptr, SS);
13114 if (!DestroyedTypeInfo)
13115 return ExprError();
13116 Destroyed = DestroyedTypeInfo;
13117 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
13118 // We aren't likely to be able to resolve the identifier down to a type
13119 // now anyway, so just retain the identifier.
13120 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
13121 E->getDestroyedTypeLoc());
13122 } else {
13123 // Look for a destructor known with the given name.
13124 ParsedType T = SemaRef.getDestructorName(
13125 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
13126 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
13127 if (!T)
13128 return ExprError();
13129
13130 Destroyed
13131 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
13132 Loc: E->getDestroyedTypeLoc());
13133 }
13134
13135 TypeSourceInfo *ScopeTypeInfo = nullptr;
13136 if (E->getScopeTypeInfo()) {
13137 CXXScopeSpec EmptySS;
13138 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
13139 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
13140 if (!ScopeTypeInfo)
13141 return ExprError();
13142 }
13143
13144 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
13145 E->getOperatorLoc(),
13146 E->isArrow(),
13147 SS,
13148 ScopeTypeInfo,
13149 E->getColonColonLoc(),
13150 E->getTildeLoc(),
13151 Destroyed);
13152}
13153
13154template <typename Derived>
13155bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
13156 bool RequiresADL,
13157 LookupResult &R) {
13158 // Transform all the decls.
13159 bool AllEmptyPacks = true;
13160 for (auto *OldD : Old->decls()) {
13161 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
13162 if (!InstD) {
13163 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
13164 // This can happen because of dependent hiding.
13165 if (isa<UsingShadowDecl>(OldD))
13166 continue;
13167 else {
13168 R.clear();
13169 return true;
13170 }
13171 }
13172
13173 // Expand using pack declarations.
13174 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
13175 ArrayRef<NamedDecl*> Decls = SingleDecl;
13176 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
13177 Decls = UPD->expansions();
13178
13179 // Expand using declarations.
13180 for (auto *D : Decls) {
13181 if (auto *UD = dyn_cast<UsingDecl>(D)) {
13182 for (auto *SD : UD->shadows())
13183 R.addDecl(SD);
13184 } else {
13185 R.addDecl(D);
13186 }
13187 }
13188
13189 AllEmptyPacks &= Decls.empty();
13190 };
13191
13192 // C++ [temp.res]/8.4.2:
13193 // The program is ill-formed, no diagnostic required, if [...] lookup for
13194 // a name in the template definition found a using-declaration, but the
13195 // lookup in the corresponding scope in the instantiation odoes not find
13196 // any declarations because the using-declaration was a pack expansion and
13197 // the corresponding pack is empty
13198 if (AllEmptyPacks && !RequiresADL) {
13199 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
13200 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
13201 return true;
13202 }
13203
13204 // Resolve a kind, but don't do any further analysis. If it's
13205 // ambiguous, the callee needs to deal with it.
13206 R.resolveKind();
13207 return false;
13208}
13209
13210template <typename Derived>
13211ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
13212 UnresolvedLookupExpr *Old) {
13213 return TransformUnresolvedLookupExpr(E: Old, /*IsAddressOfOperand=*/IsAddressOfOperand: false);
13214}
13215
13216template <typename Derived>
13217ExprResult
13218TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
13219 bool IsAddressOfOperand) {
13220 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
13221 Sema::LookupOrdinaryName);
13222
13223 // Transform the declaration set.
13224 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
13225 return ExprError();
13226
13227 // Rebuild the nested-name qualifier, if present.
13228 CXXScopeSpec SS;
13229 if (Old->getQualifierLoc()) {
13230 NestedNameSpecifierLoc QualifierLoc
13231 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13232 if (!QualifierLoc)
13233 return ExprError();
13234
13235 SS.Adopt(Other: QualifierLoc);
13236 }
13237
13238 if (Old->getNamingClass()) {
13239 CXXRecordDecl *NamingClass
13240 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
13241 Old->getNameLoc(),
13242 Old->getNamingClass()));
13243 if (!NamingClass) {
13244 R.clear();
13245 return ExprError();
13246 }
13247
13248 R.setNamingClass(NamingClass);
13249 }
13250
13251 // Rebuild the template arguments, if any.
13252 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13253 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
13254 if (Old->hasExplicitTemplateArgs() &&
13255 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13256 Old->getNumTemplateArgs(),
13257 TransArgs)) {
13258 R.clear();
13259 return ExprError();
13260 }
13261
13262 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
13263 // a non-static data member is named in an unevaluated operand, or when
13264 // a member is named in a dependent class scope function template explicit
13265 // specialization that is neither declared static nor with an explicit object
13266 // parameter.
13267 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
13268 return SemaRef.BuildPossibleImplicitMemberExpr(
13269 SS, TemplateKWLoc, R,
13270 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
13271 /*S=*/S: nullptr);
13272
13273 // If we have neither explicit template arguments, nor the template keyword,
13274 // it's a normal declaration name or member reference.
13275 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
13276 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
13277
13278 // If we have template arguments, then rebuild the template-id expression.
13279 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
13280 Old->requiresADL(), &TransArgs);
13281}
13282
13283template<typename Derived>
13284ExprResult
13285TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
13286 bool ArgChanged = false;
13287 SmallVector<TypeSourceInfo *, 4> Args;
13288 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
13289 TypeSourceInfo *From = E->getArg(I);
13290 TypeLoc FromTL = From->getTypeLoc();
13291 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
13292 TypeLocBuilder TLB;
13293 TLB.reserve(Requested: FromTL.getFullDataSize());
13294 QualType To = getDerived().TransformType(TLB, FromTL);
13295 if (To.isNull())
13296 return ExprError();
13297
13298 if (To == From->getType())
13299 Args.push_back(From);
13300 else {
13301 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13302 ArgChanged = true;
13303 }
13304 continue;
13305 }
13306
13307 ArgChanged = true;
13308
13309 // We have a pack expansion. Instantiate it.
13310 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
13311 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
13312 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13313 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
13314
13315 // Determine whether the set of unexpanded parameter packs can and should
13316 // be expanded.
13317 bool Expand = true;
13318 bool RetainExpansion = false;
13319 std::optional<unsigned> OrigNumExpansions =
13320 ExpansionTL.getTypePtr()->getNumExpansions();
13321 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13322 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
13323 PatternTL.getSourceRange(),
13324 Unexpanded,
13325 Expand, RetainExpansion,
13326 NumExpansions))
13327 return ExprError();
13328
13329 if (!Expand) {
13330 // The transform has determined that we should perform a simple
13331 // transformation on the pack expansion, producing another pack
13332 // expansion.
13333 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13334
13335 TypeLocBuilder TLB;
13336 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
13337
13338 QualType To = getDerived().TransformType(TLB, PatternTL);
13339 if (To.isNull())
13340 return ExprError();
13341
13342 To = getDerived().RebuildPackExpansionType(To,
13343 PatternTL.getSourceRange(),
13344 ExpansionTL.getEllipsisLoc(),
13345 NumExpansions);
13346 if (To.isNull())
13347 return ExprError();
13348
13349 PackExpansionTypeLoc ToExpansionTL
13350 = TLB.push<PackExpansionTypeLoc>(To);
13351 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13352 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13353 continue;
13354 }
13355
13356 // Expand the pack expansion by substituting for each argument in the
13357 // pack(s).
13358 for (unsigned I = 0; I != *NumExpansions; ++I) {
13359 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
13360 TypeLocBuilder TLB;
13361 TLB.reserve(Requested: PatternTL.getFullDataSize());
13362 QualType To = getDerived().TransformType(TLB, PatternTL);
13363 if (To.isNull())
13364 return ExprError();
13365
13366 if (To->containsUnexpandedParameterPack()) {
13367 To = getDerived().RebuildPackExpansionType(To,
13368 PatternTL.getSourceRange(),
13369 ExpansionTL.getEllipsisLoc(),
13370 NumExpansions);
13371 if (To.isNull())
13372 return ExprError();
13373
13374 PackExpansionTypeLoc ToExpansionTL
13375 = TLB.push<PackExpansionTypeLoc>(To);
13376 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13377 }
13378
13379 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13380 }
13381
13382 if (!RetainExpansion)
13383 continue;
13384
13385 // If we're supposed to retain a pack expansion, do so by temporarily
13386 // forgetting the partially-substituted parameter pack.
13387 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13388
13389 TypeLocBuilder TLB;
13390 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
13391
13392 QualType To = getDerived().TransformType(TLB, PatternTL);
13393 if (To.isNull())
13394 return ExprError();
13395
13396 To = getDerived().RebuildPackExpansionType(To,
13397 PatternTL.getSourceRange(),
13398 ExpansionTL.getEllipsisLoc(),
13399 NumExpansions);
13400 if (To.isNull())
13401 return ExprError();
13402
13403 PackExpansionTypeLoc ToExpansionTL
13404 = TLB.push<PackExpansionTypeLoc>(To);
13405 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13406 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13407 }
13408
13409 if (!getDerived().AlwaysRebuild() && !ArgChanged)
13410 return E;
13411
13412 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
13413 E->getEndLoc());
13414}
13415
13416template<typename Derived>
13417ExprResult
13418TreeTransform<Derived>::TransformConceptSpecializationExpr(
13419 ConceptSpecializationExpr *E) {
13420 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
13421 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
13422 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13423 Old->NumTemplateArgs, TransArgs))
13424 return ExprError();
13425
13426 return getDerived().RebuildConceptSpecializationExpr(
13427 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
13428 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
13429 &TransArgs);
13430}
13431
13432template<typename Derived>
13433ExprResult
13434TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
13435 SmallVector<ParmVarDecl*, 4> TransParams;
13436 SmallVector<QualType, 4> TransParamTypes;
13437 Sema::ExtParameterInfoBuilder ExtParamInfos;
13438
13439 // C++2a [expr.prim.req]p2
13440 // Expressions appearing within a requirement-body are unevaluated operands.
13441 EnterExpressionEvaluationContext Ctx(
13442 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13443 Sema::ReuseLambdaContextDecl);
13444
13445 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
13446 C&: getSema().Context, DC: getSema().CurContext,
13447 StartLoc: E->getBody()->getBeginLoc());
13448
13449 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
13450
13451 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
13452 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
13453 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
13454
13455 for (ParmVarDecl *Param : TransParams)
13456 if (Param)
13457 Param->setDeclContext(Body);
13458
13459 // On failure to transform, TransformRequiresTypeParams returns an expression
13460 // in the event that the transformation of the type params failed in some way.
13461 // It is expected that this will result in a 'not satisfied' Requires clause
13462 // when instantiating.
13463 if (!TypeParamResult.isUnset())
13464 return TypeParamResult;
13465
13466 SmallVector<concepts::Requirement *, 4> TransReqs;
13467 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
13468 TransReqs))
13469 return ExprError();
13470
13471 for (concepts::Requirement *Req : TransReqs) {
13472 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
13473 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
13474 ER->getReturnTypeRequirement()
13475 .getTypeConstraintTemplateParameterList()->getParam(0)
13476 ->setDeclContext(Body);
13477 }
13478 }
13479 }
13480
13481 return getDerived().RebuildRequiresExpr(
13482 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
13483 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
13484}
13485
13486template<typename Derived>
13487bool TreeTransform<Derived>::TransformRequiresExprRequirements(
13488 ArrayRef<concepts::Requirement *> Reqs,
13489 SmallVectorImpl<concepts::Requirement *> &Transformed) {
13490 for (concepts::Requirement *Req : Reqs) {
13491 concepts::Requirement *TransReq = nullptr;
13492 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
13493 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13494 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
13495 TransReq = getDerived().TransformExprRequirement(ExprReq);
13496 else
13497 TransReq = getDerived().TransformNestedRequirement(
13498 cast<concepts::NestedRequirement>(Req));
13499 if (!TransReq)
13500 return true;
13501 Transformed.push_back(TransReq);
13502 }
13503 return false;
13504}
13505
13506template<typename Derived>
13507concepts::TypeRequirement *
13508TreeTransform<Derived>::TransformTypeRequirement(
13509 concepts::TypeRequirement *Req) {
13510 if (Req->isSubstitutionFailure()) {
13511 if (getDerived().AlwaysRebuild())
13512 return getDerived().RebuildTypeRequirement(
13513 Req->getSubstitutionDiagnostic());
13514 return Req;
13515 }
13516 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13517 if (!TransType)
13518 return nullptr;
13519 return getDerived().RebuildTypeRequirement(TransType);
13520}
13521
13522template<typename Derived>
13523concepts::ExprRequirement *
13524TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
13525 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13526 if (Req->isExprSubstitutionFailure())
13527 TransExpr = Req->getExprSubstitutionDiagnostic();
13528 else {
13529 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13530 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13531 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
13532 if (TransExprRes.isInvalid())
13533 return nullptr;
13534 TransExpr = TransExprRes.get();
13535 }
13536
13537 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13538 const auto &RetReq = Req->getReturnTypeRequirement();
13539 if (RetReq.isEmpty())
13540 TransRetReq.emplace();
13541 else if (RetReq.isSubstitutionFailure())
13542 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
13543 else if (RetReq.isTypeConstraint()) {
13544 TemplateParameterList *OrigTPL =
13545 RetReq.getTypeConstraintTemplateParameterList();
13546 TemplateParameterList *TPL =
13547 getDerived().TransformTemplateParameterList(OrigTPL);
13548 if (!TPL)
13549 return nullptr;
13550 TransRetReq.emplace(TPL);
13551 }
13552 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13553 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13554 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13555 Req->getNoexceptLoc(),
13556 std::move(*TransRetReq));
13557 return getDerived().RebuildExprRequirement(
13558 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
13559 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
13560}
13561
13562template<typename Derived>
13563concepts::NestedRequirement *
13564TreeTransform<Derived>::TransformNestedRequirement(
13565 concepts::NestedRequirement *Req) {
13566 if (Req->hasInvalidConstraint()) {
13567 if (getDerived().AlwaysRebuild())
13568 return getDerived().RebuildNestedRequirement(
13569 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
13570 return Req;
13571 }
13572 ExprResult TransConstraint =
13573 getDerived().TransformExpr(Req->getConstraintExpr());
13574 if (TransConstraint.isInvalid())
13575 return nullptr;
13576 return getDerived().RebuildNestedRequirement(TransConstraint.get());
13577}
13578
13579template<typename Derived>
13580ExprResult
13581TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
13582 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
13583 if (!T)
13584 return ExprError();
13585
13586 if (!getDerived().AlwaysRebuild() &&
13587 T == E->getQueriedTypeSourceInfo())
13588 return E;
13589
13590 ExprResult SubExpr;
13591 {
13592 EnterExpressionEvaluationContext Unevaluated(
13593 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13594 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
13595 if (SubExpr.isInvalid())
13596 return ExprError();
13597
13598 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
13599 return E;
13600 }
13601
13602 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
13603 SubExpr.get(), E->getEndLoc());
13604}
13605
13606template<typename Derived>
13607ExprResult
13608TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
13609 ExprResult SubExpr;
13610 {
13611 EnterExpressionEvaluationContext Unevaluated(
13612 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13613 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
13614 if (SubExpr.isInvalid())
13615 return ExprError();
13616
13617 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
13618 return E;
13619 }
13620
13621 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
13622 SubExpr.get(), E->getEndLoc());
13623}
13624
13625template <typename Derived>
13626ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
13627 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
13628 TypeSourceInfo **RecoveryTSI) {
13629 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
13630 DRE, AddrTaken, RecoveryTSI);
13631
13632 // Propagate both errors and recovered types, which return ExprEmpty.
13633 if (!NewDRE.isUsable())
13634 return NewDRE;
13635
13636 // We got an expr, wrap it up in parens.
13637 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
13638 return PE;
13639 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
13640 PE->getRParen());
13641}
13642
13643template <typename Derived>
13644ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13645 DependentScopeDeclRefExpr *E) {
13646 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/IsAddressOfOperand: false,
13647 RecoveryTSI: nullptr);
13648}
13649
13650template <typename Derived>
13651ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13652 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
13653 TypeSourceInfo **RecoveryTSI) {
13654 assert(E->getQualifierLoc());
13655 NestedNameSpecifierLoc QualifierLoc =
13656 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13657 if (!QualifierLoc)
13658 return ExprError();
13659 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13660
13661 // TODO: If this is a conversion-function-id, verify that the
13662 // destination type name (if present) resolves the same way after
13663 // instantiation as it did in the local scope.
13664
13665 DeclarationNameInfo NameInfo =
13666 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
13667 if (!NameInfo.getName())
13668 return ExprError();
13669
13670 if (!E->hasExplicitTemplateArgs()) {
13671 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
13672 // Note: it is sufficient to compare the Name component of NameInfo:
13673 // if name has not changed, DNLoc has not changed either.
13674 NameInfo.getName() == E->getDeclName())
13675 return E;
13676
13677 return getDerived().RebuildDependentScopeDeclRefExpr(
13678 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
13679 IsAddressOfOperand, RecoveryTSI);
13680 }
13681
13682 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13683 if (getDerived().TransformTemplateArguments(
13684 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13685 return ExprError();
13686
13687 return getDerived().RebuildDependentScopeDeclRefExpr(
13688 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13689 RecoveryTSI);
13690}
13691
13692template<typename Derived>
13693ExprResult
13694TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13695 // CXXConstructExprs other than for list-initialization and
13696 // CXXTemporaryObjectExpr are always implicit, so when we have
13697 // a 1-argument construction we just transform that argument.
13698 if (getDerived().AllowSkippingCXXConstructExpr() &&
13699 ((E->getNumArgs() == 1 ||
13700 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
13701 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
13702 !E->isListInitialization()))
13703 return getDerived().TransformInitializer(E->getArg(Arg: 0),
13704 /*DirectInit*/ false);
13705
13706 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13707
13708 QualType T = getDerived().TransformType(E->getType());
13709 if (T.isNull())
13710 return ExprError();
13711
13712 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13713 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13714 if (!Constructor)
13715 return ExprError();
13716
13717 bool ArgumentChanged = false;
13718 SmallVector<Expr*, 8> Args;
13719 {
13720 EnterExpressionEvaluationContext Context(
13721 getSema(), EnterExpressionEvaluationContext::InitList,
13722 E->isListInitialization());
13723 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13724 &ArgumentChanged))
13725 return ExprError();
13726 }
13727
13728 if (!getDerived().AlwaysRebuild() &&
13729 T == E->getType() &&
13730 Constructor == E->getConstructor() &&
13731 !ArgumentChanged) {
13732 // Mark the constructor as referenced.
13733 // FIXME: Instantiation-specific
13734 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13735 return E;
13736 }
13737
13738 return getDerived().RebuildCXXConstructExpr(
13739 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
13740 E->hadMultipleCandidates(), E->isListInitialization(),
13741 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
13742 E->getConstructionKind(), E->getParenOrBraceRange());
13743}
13744
13745template<typename Derived>
13746ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
13747 CXXInheritedCtorInitExpr *E) {
13748 QualType T = getDerived().TransformType(E->getType());
13749 if (T.isNull())
13750 return ExprError();
13751
13752 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13753 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13754 if (!Constructor)
13755 return ExprError();
13756
13757 if (!getDerived().AlwaysRebuild() &&
13758 T == E->getType() &&
13759 Constructor == E->getConstructor()) {
13760 // Mark the constructor as referenced.
13761 // FIXME: Instantiation-specific
13762 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13763 return E;
13764 }
13765
13766 return getDerived().RebuildCXXInheritedCtorInitExpr(
13767 T, E->getLocation(), Constructor,
13768 E->constructsVBase(), E->inheritedFromVBase());
13769}
13770
13771/// Transform a C++ temporary-binding expression.
13772///
13773/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
13774/// transform the subexpression and return that.
13775template<typename Derived>
13776ExprResult
13777TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
13778 if (auto *Dtor = E->getTemporary()->getDestructor())
13779 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13780 const_cast<CXXDestructorDecl *>(Dtor));
13781 return getDerived().TransformExpr(E->getSubExpr());
13782}
13783
13784/// Transform a C++ expression that contains cleanups that should
13785/// be run after the expression is evaluated.
13786///
13787/// Since ExprWithCleanups nodes are implicitly generated, we
13788/// just transform the subexpression and return that.
13789template<typename Derived>
13790ExprResult
13791TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
13792 return getDerived().TransformExpr(E->getSubExpr());
13793}
13794
13795template<typename Derived>
13796ExprResult
13797TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
13798 CXXTemporaryObjectExpr *E) {
13799 TypeSourceInfo *T =
13800 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13801 if (!T)
13802 return ExprError();
13803
13804 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13805 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13806 if (!Constructor)
13807 return ExprError();
13808
13809 bool ArgumentChanged = false;
13810 SmallVector<Expr*, 8> Args;
13811 Args.reserve(E->getNumArgs());
13812 {
13813 EnterExpressionEvaluationContext Context(
13814 getSema(), EnterExpressionEvaluationContext::InitList,
13815 E->isListInitialization());
13816 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
13817 ArgChanged: &ArgumentChanged))
13818 return ExprError();
13819 }
13820
13821 if (!getDerived().AlwaysRebuild() &&
13822 T == E->getTypeSourceInfo() &&
13823 Constructor == E->getConstructor() &&
13824 !ArgumentChanged) {
13825 // FIXME: Instantiation-specific
13826 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13827 return SemaRef.MaybeBindToTemporary(E);
13828 }
13829
13830 // FIXME: We should just pass E->isListInitialization(), but we're not
13831 // prepared to handle list-initialization without a child InitListExpr.
13832 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
13833 return getDerived().RebuildCXXTemporaryObjectExpr(
13834 T, LParenLoc, Args, E->getEndLoc(),
13835 /*ListInitialization=*/LParenLoc.isInvalid());
13836}
13837
13838template<typename Derived>
13839ExprResult
13840TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
13841 // Transform any init-capture expressions before entering the scope of the
13842 // lambda body, because they are not semantically within that scope.
13843 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
13844 struct TransformedInitCapture {
13845 // The location of the ... if the result is retaining a pack expansion.
13846 SourceLocation EllipsisLoc;
13847 // Zero or more expansions of the init-capture.
13848 SmallVector<InitCaptureInfoTy, 4> Expansions;
13849 };
13850 SmallVector<TransformedInitCapture, 4> InitCaptures;
13851 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
13852 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13853 CEnd = E->capture_end();
13854 C != CEnd; ++C) {
13855 if (!E->isInitCapture(Capture: C))
13856 continue;
13857
13858 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
13859 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13860
13861 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
13862 std::optional<unsigned> NumExpansions) {
13863 ExprResult NewExprInitResult = getDerived().TransformInitializer(
13864 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
13865
13866 if (NewExprInitResult.isInvalid()) {
13867 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
13868 return;
13869 }
13870 Expr *NewExprInit = NewExprInitResult.get();
13871
13872 QualType NewInitCaptureType =
13873 getSema().buildLambdaInitCaptureInitialization(
13874 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
13875 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
13876 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
13877 VarDecl::CInit,
13878 NewExprInit);
13879 Result.Expansions.push_back(
13880 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
13881 };
13882
13883 // If this is an init-capture pack, consider expanding the pack now.
13884 if (OldVD->isParameterPack()) {
13885 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
13886 ->getTypeLoc()
13887 .castAs<PackExpansionTypeLoc>();
13888 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13889 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
13890
13891 // Determine whether the set of unexpanded parameter packs can and should
13892 // be expanded.
13893 bool Expand = true;
13894 bool RetainExpansion = false;
13895 std::optional<unsigned> OrigNumExpansions =
13896 ExpansionTL.getTypePtr()->getNumExpansions();
13897 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13898 if (getDerived().TryExpandParameterPacks(
13899 ExpansionTL.getEllipsisLoc(),
13900 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
13901 RetainExpansion, NumExpansions))
13902 return ExprError();
13903 if (Expand) {
13904 for (unsigned I = 0; I != *NumExpansions; ++I) {
13905 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13906 SubstInitCapture(SourceLocation(), std::nullopt);
13907 }
13908 }
13909 if (!Expand || RetainExpansion) {
13910 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13911 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
13912 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
13913 }
13914 } else {
13915 SubstInitCapture(SourceLocation(), std::nullopt);
13916 }
13917 }
13918
13919 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
13920 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
13921
13922 // Create the local class that will describe the lambda.
13923
13924 // FIXME: DependencyKind below is wrong when substituting inside a templated
13925 // context that isn't a DeclContext (such as a variable template), or when
13926 // substituting an unevaluated lambda inside of a function's parameter's type
13927 // - as parameter types are not instantiated from within a function's DC. We
13928 // use evaluation contexts to distinguish the function parameter case.
13929 CXXRecordDecl::LambdaDependencyKind DependencyKind =
13930 CXXRecordDecl::LDK_Unknown;
13931 DeclContext *DC = getSema().CurContext;
13932 // A RequiresExprBodyDecl is not interesting for dependencies.
13933 // For the following case,
13934 //
13935 // template <typename>
13936 // concept C = requires { [] {}; };
13937 //
13938 // template <class F>
13939 // struct Widget;
13940 //
13941 // template <C F>
13942 // struct Widget<F> {};
13943 //
13944 // While we are substituting Widget<F>, the parent of DC would be
13945 // the template specialization itself. Thus, the lambda expression
13946 // will be deemed as dependent even if there are no dependent template
13947 // arguments.
13948 // (A ClassTemplateSpecializationDecl is always a dependent context.)
13949 while (DC->getDeclKind() == Decl::Kind::RequiresExprBody)
13950 DC = DC->getParent();
13951 if ((getSema().isUnevaluatedContext() ||
13952 getSema().isConstantEvaluatedContext()) &&
13953 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
13954 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
13955
13956 CXXRecordDecl *OldClass = E->getLambdaClass();
13957 CXXRecordDecl *Class = getSema().createLambdaClosureType(
13958 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
13959 E->getCaptureDefault());
13960 getDerived().transformedLocalDecl(OldClass, {Class});
13961
13962 CXXMethodDecl *NewCallOperator =
13963 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
13964 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
13965
13966 // Enter the scope of the lambda.
13967 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
13968 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
13969 E->hasExplicitParameters(), E->isMutable());
13970
13971 // Introduce the context of the call operator.
13972 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
13973 /*NewThisContext*/false);
13974
13975 bool Invalid = false;
13976
13977 // Transform captures.
13978 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13979 CEnd = E->capture_end();
13980 C != CEnd; ++C) {
13981 // When we hit the first implicit capture, tell Sema that we've finished
13982 // the list of explicit captures.
13983 if (C->isImplicit())
13984 break;
13985
13986 // Capturing 'this' is trivial.
13987 if (C->capturesThis()) {
13988 // If this is a lambda that is part of a default member initialiser
13989 // and which we're instantiating outside the class that 'this' is
13990 // supposed to refer to, adjust the type of 'this' accordingly.
13991 //
13992 // Otherwise, leave the type of 'this' as-is.
13993 Sema::CXXThisScopeRAII ThisScope(
13994 getSema(),
13995 dyn_cast_if_present<CXXRecordDecl>(
13996 getSema().getFunctionLevelDeclContext()),
13997 Qualifiers());
13998 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13999 /*BuildAndDiagnose*/ true, nullptr,
14000 C->getCaptureKind() == LCK_StarThis);
14001 continue;
14002 }
14003 // Captured expression will be recaptured during captured variables
14004 // rebuilding.
14005 if (C->capturesVLAType())
14006 continue;
14007
14008 // Rebuild init-captures, including the implied field declaration.
14009 if (E->isInitCapture(Capture: C)) {
14010 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
14011
14012 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14013 llvm::SmallVector<Decl*, 4> NewVDs;
14014
14015 for (InitCaptureInfoTy &Info : NewC.Expansions) {
14016 ExprResult Init = Info.first;
14017 QualType InitQualType = Info.second;
14018 if (Init.isInvalid() || InitQualType.isNull()) {
14019 Invalid = true;
14020 break;
14021 }
14022 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
14023 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
14024 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
14025 getSema().CurContext);
14026 if (!NewVD) {
14027 Invalid = true;
14028 break;
14029 }
14030 NewVDs.push_back(NewVD);
14031 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
14032 }
14033
14034 if (Invalid)
14035 break;
14036
14037 getDerived().transformedLocalDecl(OldVD, NewVDs);
14038 continue;
14039 }
14040
14041 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14042
14043 // Determine the capture kind for Sema.
14044 Sema::TryCaptureKind Kind
14045 = C->isImplicit()? Sema::TryCapture_Implicit
14046 : C->getCaptureKind() == LCK_ByCopy
14047 ? Sema::TryCapture_ExplicitByVal
14048 : Sema::TryCapture_ExplicitByRef;
14049 SourceLocation EllipsisLoc;
14050 if (C->isPackExpansion()) {
14051 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
14052 bool ShouldExpand = false;
14053 bool RetainExpansion = false;
14054 std::optional<unsigned> NumExpansions;
14055 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
14056 C->getLocation(),
14057 Unexpanded,
14058 ShouldExpand, RetainExpansion,
14059 NumExpansions)) {
14060 Invalid = true;
14061 continue;
14062 }
14063
14064 if (ShouldExpand) {
14065 // The transform has determined that we should perform an expansion;
14066 // transform and capture each of the arguments.
14067 // expansion of the pattern. Do so.
14068 auto *Pack = cast<VarDecl>(C->getCapturedVar());
14069 for (unsigned I = 0; I != *NumExpansions; ++I) {
14070 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14071 VarDecl *CapturedVar
14072 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
14073 Pack));
14074 if (!CapturedVar) {
14075 Invalid = true;
14076 continue;
14077 }
14078
14079 // Capture the transformed variable.
14080 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
14081 }
14082
14083 // FIXME: Retain a pack expansion if RetainExpansion is true.
14084
14085 continue;
14086 }
14087
14088 EllipsisLoc = C->getEllipsisLoc();
14089 }
14090
14091 // Transform the captured variable.
14092 auto *CapturedVar = cast_or_null<ValueDecl>(
14093 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14094 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
14095 Invalid = true;
14096 continue;
14097 }
14098
14099 // Capture the transformed variable.
14100 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
14101 EllipsisLoc);
14102 }
14103 getSema().finishLambdaExplicitCaptures(LSI);
14104
14105 // Transform the template parameters, and add them to the current
14106 // instantiation scope. The null case is handled correctly.
14107 auto TPL = getDerived().TransformTemplateParameterList(
14108 E->getTemplateParameterList());
14109 LSI->GLTemplateParameterList = TPL;
14110 if (TPL)
14111 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
14112 TPL);
14113
14114 // Transform the type of the original lambda's call operator.
14115 // The transformation MUST be done in the CurrentInstantiationScope since
14116 // it introduces a mapping of the original to the newly created
14117 // transformed parameters.
14118 TypeSourceInfo *NewCallOpTSI = nullptr;
14119 {
14120 auto OldCallOpTypeLoc =
14121 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
14122
14123 auto TransformFunctionProtoTypeLoc =
14124 [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
14125 SmallVector<QualType, 4> ExceptionStorage;
14126 return this->TransformFunctionProtoType(
14127 TLB, FPTL, nullptr, Qualifiers(),
14128 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
14129 return TransformExceptionSpec(Loc: FPTL.getBeginLoc(), ESI,
14130 Exceptions&: ExceptionStorage, Changed);
14131 });
14132 };
14133
14134 QualType NewCallOpType;
14135 TypeLocBuilder NewCallOpTLBuilder;
14136
14137 if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
14138 NewCallOpType = this->TransformAttributedType(
14139 NewCallOpTLBuilder, ATL,
14140 [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
14141 return TransformFunctionProtoTypeLoc(
14142 TLB, TL.castAs<FunctionProtoTypeLoc>());
14143 });
14144 } else {
14145 auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
14146 NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
14147 }
14148
14149 if (NewCallOpType.isNull())
14150 return ExprError();
14151 NewCallOpTSI =
14152 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
14153 }
14154
14155 ArrayRef<ParmVarDecl *> Params;
14156 if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
14157 Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
14158 } else {
14159 auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
14160 Params = FPTL.getParams();
14161 }
14162
14163 getSema().CompleteLambdaCallOperator(
14164 NewCallOperator, E->getCallOperator()->getLocation(),
14165 E->getCallOperator()->getInnerLocStart(),
14166 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
14167 E->getCallOperator()->getConstexprKind(),
14168 E->getCallOperator()->getStorageClass(), Params,
14169 E->hasExplicitResultType());
14170
14171 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
14172 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
14173
14174 {
14175 // Number the lambda for linkage purposes if necessary.
14176 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
14177
14178 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
14179 if (getDerived().ReplacingOriginal()) {
14180 Numbering = OldClass->getLambdaNumbering();
14181 }
14182
14183 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
14184 }
14185
14186 // FIXME: Sema's lambda-building mechanism expects us to push an expression
14187 // evaluation context even if we're not transforming the function body.
14188 getSema().PushExpressionEvaluationContext(
14189 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
14190
14191 Sema::CodeSynthesisContext C;
14192 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
14193 C.PointOfInstantiation = E->getBody()->getBeginLoc();
14194 getSema().pushCodeSynthesisContext(C);
14195
14196 // Instantiate the body of the lambda expression.
14197 StmtResult Body =
14198 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
14199
14200 getSema().popCodeSynthesisContext();
14201
14202 // ActOnLambda* will pop the function scope for us.
14203 FuncScopeCleanup.disable();
14204
14205 if (Body.isInvalid()) {
14206 SavedContext.pop();
14207 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
14208 /*IsInstantiation=*/true);
14209 return ExprError();
14210 }
14211
14212 // Copy the LSI before ActOnFinishFunctionBody removes it.
14213 // FIXME: This is dumb. Store the lambda information somewhere that outlives
14214 // the call operator.
14215 auto LSICopy = *LSI;
14216 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
14217 /*IsInstantiation*/ true);
14218 SavedContext.pop();
14219
14220 // Recompute the dependency of the lambda so that we can defer the lambda call
14221 // construction until after we have all the necessary template arguments. For
14222 // example, given
14223 //
14224 // template <class> struct S {
14225 // template <class U>
14226 // using Type = decltype([](U){}(42.0));
14227 // };
14228 // void foo() {
14229 // using T = S<int>::Type<float>;
14230 // ^~~~~~
14231 // }
14232 //
14233 // We would end up here from instantiating S<int> when ensuring its
14234 // completeness. That would transform the lambda call expression regardless of
14235 // the absence of the corresponding argument for U.
14236 //
14237 // Going ahead with unsubstituted type U makes things worse: we would soon
14238 // compare the argument type (which is float) against the parameter U
14239 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
14240 // error suggesting unmatched types 'U' and 'float'!
14241 //
14242 // That said, everything will be fine if we defer that semantic checking.
14243 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
14244 // dependent. Since the CallExpr's dependency boils down to the lambda's
14245 // dependency in this case, we can harness that by recomputing the dependency
14246 // from the instantiation arguments.
14247 //
14248 // FIXME: Creating the type of a lambda requires us to have a dependency
14249 // value, which happens before its substitution. We update its dependency
14250 // *after* the substitution in case we can't decide the dependency
14251 // so early, e.g. because we want to see if any of the *substituted*
14252 // parameters are dependent.
14253 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
14254 Class->setLambdaDependencyKind(DependencyKind);
14255 // Clean up the type cache created previously. Then, we re-create a type for
14256 // such Decl with the new DependencyKind.
14257 Class->setTypeForDecl(nullptr);
14258 getSema().Context.getTypeDeclType(Class);
14259
14260 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
14261 &LSICopy);
14262}
14263
14264template<typename Derived>
14265StmtResult
14266TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
14267 return TransformStmt(S);
14268}
14269
14270template<typename Derived>
14271StmtResult
14272TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
14273 // Transform captures.
14274 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14275 CEnd = E->capture_end();
14276 C != CEnd; ++C) {
14277 // When we hit the first implicit capture, tell Sema that we've finished
14278 // the list of explicit captures.
14279 if (!C->isImplicit())
14280 continue;
14281
14282 // Capturing 'this' is trivial.
14283 if (C->capturesThis()) {
14284 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14285 /*BuildAndDiagnose*/ true, nullptr,
14286 C->getCaptureKind() == LCK_StarThis);
14287 continue;
14288 }
14289 // Captured expression will be recaptured during captured variables
14290 // rebuilding.
14291 if (C->capturesVLAType())
14292 continue;
14293
14294 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14295 assert(!E->isInitCapture(C) && "implicit init-capture?");
14296
14297 // Transform the captured variable.
14298 VarDecl *CapturedVar = cast_or_null<VarDecl>(
14299 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14300 if (!CapturedVar || CapturedVar->isInvalidDecl())
14301 return StmtError();
14302
14303 // Capture the transformed variable.
14304 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
14305 }
14306
14307 return S;
14308}
14309
14310template<typename Derived>
14311ExprResult
14312TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
14313 CXXUnresolvedConstructExpr *E) {
14314 TypeSourceInfo *T =
14315 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14316 if (!T)
14317 return ExprError();
14318
14319 bool ArgumentChanged = false;
14320 SmallVector<Expr*, 8> Args;
14321 Args.reserve(E->getNumArgs());
14322 {
14323 EnterExpressionEvaluationContext Context(
14324 getSema(), EnterExpressionEvaluationContext::InitList,
14325 E->isListInitialization());
14326 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
14327 &ArgumentChanged))
14328 return ExprError();
14329 }
14330
14331 if (!getDerived().AlwaysRebuild() &&
14332 T == E->getTypeSourceInfo() &&
14333 !ArgumentChanged)
14334 return E;
14335
14336 // FIXME: we're faking the locations of the commas
14337 return getDerived().RebuildCXXUnresolvedConstructExpr(
14338 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
14339}
14340
14341template<typename Derived>
14342ExprResult
14343TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
14344 CXXDependentScopeMemberExpr *E) {
14345 // Transform the base of the expression.
14346 ExprResult Base((Expr*) nullptr);
14347 Expr *OldBase;
14348 QualType BaseType;
14349 QualType ObjectType;
14350 if (!E->isImplicitAccess()) {
14351 OldBase = E->getBase();
14352 Base = getDerived().TransformExpr(OldBase);
14353 if (Base.isInvalid())
14354 return ExprError();
14355
14356 // Start the member reference and compute the object's type.
14357 ParsedType ObjectTy;
14358 bool MayBePseudoDestructor = false;
14359 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14360 OpLoc: E->getOperatorLoc(),
14361 OpKind: E->isArrow()? tok::arrow : tok::period,
14362 ObjectType&: ObjectTy,
14363 MayBePseudoDestructor);
14364 if (Base.isInvalid())
14365 return ExprError();
14366
14367 ObjectType = ObjectTy.get();
14368 BaseType = ((Expr*) Base.get())->getType();
14369 } else {
14370 OldBase = nullptr;
14371 BaseType = getDerived().TransformType(E->getBaseType());
14372 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
14373 }
14374
14375 // Transform the first part of the nested-name-specifier that qualifies
14376 // the member name.
14377 NamedDecl *FirstQualifierInScope
14378 = getDerived().TransformFirstQualifierInScope(
14379 E->getFirstQualifierFoundInScope(),
14380 E->getQualifierLoc().getBeginLoc());
14381
14382 NestedNameSpecifierLoc QualifierLoc;
14383 if (E->getQualifier()) {
14384 QualifierLoc
14385 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
14386 ObjectType,
14387 FirstQualifierInScope);
14388 if (!QualifierLoc)
14389 return ExprError();
14390 }
14391
14392 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14393
14394 // TODO: If this is a conversion-function-id, verify that the
14395 // destination type name (if present) resolves the same way after
14396 // instantiation as it did in the local scope.
14397
14398 DeclarationNameInfo NameInfo
14399 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
14400 if (!NameInfo.getName())
14401 return ExprError();
14402
14403 if (!E->hasExplicitTemplateArgs()) {
14404 // This is a reference to a member without an explicitly-specified
14405 // template argument list. Optimize for this common case.
14406 if (!getDerived().AlwaysRebuild() &&
14407 Base.get() == OldBase &&
14408 BaseType == E->getBaseType() &&
14409 QualifierLoc == E->getQualifierLoc() &&
14410 NameInfo.getName() == E->getMember() &&
14411 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
14412 return E;
14413
14414 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14415 BaseType,
14416 E->isArrow(),
14417 E->getOperatorLoc(),
14418 QualifierLoc,
14419 TemplateKWLoc,
14420 FirstQualifierInScope,
14421 NameInfo,
14422 /*TemplateArgs*/nullptr);
14423 }
14424
14425 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14426 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14427 E->getNumTemplateArgs(),
14428 TransArgs))
14429 return ExprError();
14430
14431 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14432 BaseType,
14433 E->isArrow(),
14434 E->getOperatorLoc(),
14435 QualifierLoc,
14436 TemplateKWLoc,
14437 FirstQualifierInScope,
14438 NameInfo,
14439 &TransArgs);
14440}
14441
14442template <typename Derived>
14443ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
14444 UnresolvedMemberExpr *Old) {
14445 // Transform the base of the expression.
14446 ExprResult Base((Expr *)nullptr);
14447 QualType BaseType;
14448 if (!Old->isImplicitAccess()) {
14449 Base = getDerived().TransformExpr(Old->getBase());
14450 if (Base.isInvalid())
14451 return ExprError();
14452 Base =
14453 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
14454 if (Base.isInvalid())
14455 return ExprError();
14456 BaseType = Base.get()->getType();
14457 } else {
14458 BaseType = getDerived().TransformType(Old->getBaseType());
14459 }
14460
14461 NestedNameSpecifierLoc QualifierLoc;
14462 if (Old->getQualifierLoc()) {
14463 QualifierLoc =
14464 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14465 if (!QualifierLoc)
14466 return ExprError();
14467 }
14468
14469 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14470
14471 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
14472
14473 // Transform the declaration set.
14474 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
14475 return ExprError();
14476
14477 // Determine the naming class.
14478 if (Old->getNamingClass()) {
14479 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
14480 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
14481 if (!NamingClass)
14482 return ExprError();
14483
14484 R.setNamingClass(NamingClass);
14485 }
14486
14487 TemplateArgumentListInfo TransArgs;
14488 if (Old->hasExplicitTemplateArgs()) {
14489 TransArgs.setLAngleLoc(Old->getLAngleLoc());
14490 TransArgs.setRAngleLoc(Old->getRAngleLoc());
14491 if (getDerived().TransformTemplateArguments(
14492 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
14493 return ExprError();
14494 }
14495
14496 // FIXME: to do this check properly, we will need to preserve the
14497 // first-qualifier-in-scope here, just in case we had a dependent
14498 // base (and therefore couldn't do the check) and a
14499 // nested-name-qualifier (and therefore could do the lookup).
14500 NamedDecl *FirstQualifierInScope = nullptr;
14501
14502 return getDerived().RebuildUnresolvedMemberExpr(
14503 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
14504 TemplateKWLoc, FirstQualifierInScope, R,
14505 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
14506}
14507
14508template<typename Derived>
14509ExprResult
14510TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
14511 EnterExpressionEvaluationContext Unevaluated(
14512 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14513 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
14514 if (SubExpr.isInvalid())
14515 return ExprError();
14516
14517 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
14518 return E;
14519
14520 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
14521}
14522
14523template<typename Derived>
14524ExprResult
14525TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
14526 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
14527 if (Pattern.isInvalid())
14528 return ExprError();
14529
14530 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
14531 return E;
14532
14533 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
14534 E->getNumExpansions());
14535}
14536
14537template<typename Derived>
14538ExprResult
14539TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
14540 // If E is not value-dependent, then nothing will change when we transform it.
14541 // Note: This is an instantiation-centric view.
14542 if (!E->isValueDependent())
14543 return E;
14544
14545 EnterExpressionEvaluationContext Unevaluated(
14546 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
14547
14548 ArrayRef<TemplateArgument> PackArgs;
14549 TemplateArgument ArgStorage;
14550
14551 // Find the argument list to transform.
14552 if (E->isPartiallySubstituted()) {
14553 PackArgs = E->getPartialArguments();
14554 } else if (E->isValueDependent()) {
14555 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
14556 bool ShouldExpand = false;
14557 bool RetainExpansion = false;
14558 std::optional<unsigned> NumExpansions;
14559 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
14560 Unexpanded,
14561 ShouldExpand, RetainExpansion,
14562 NumExpansions))
14563 return ExprError();
14564
14565 // If we need to expand the pack, build a template argument from it and
14566 // expand that.
14567 if (ShouldExpand) {
14568 auto *Pack = E->getPack();
14569 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
14570 ArgStorage = getSema().Context.getPackExpansionType(
14571 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
14572 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
14573 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
14574 } else {
14575 auto *VD = cast<ValueDecl>(Pack);
14576 ExprResult DRE = getSema().BuildDeclRefExpr(
14577 VD, VD->getType().getNonLValueExprType(getSema().Context),
14578 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
14579 E->getPackLoc());
14580 if (DRE.isInvalid())
14581 return ExprError();
14582 ArgStorage = new (getSema().Context)
14583 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
14584 E->getPackLoc(), std::nullopt);
14585 }
14586 PackArgs = ArgStorage;
14587 }
14588 }
14589
14590 // If we're not expanding the pack, just transform the decl.
14591 if (!PackArgs.size()) {
14592 auto *Pack = cast_or_null<NamedDecl>(
14593 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
14594 if (!Pack)
14595 return ExprError();
14596 return getDerived().RebuildSizeOfPackExpr(
14597 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
14598 std::nullopt, std::nullopt);
14599 }
14600
14601 // Try to compute the result without performing a partial substitution.
14602 std::optional<unsigned> Result = 0;
14603 for (const TemplateArgument &Arg : PackArgs) {
14604 if (!Arg.isPackExpansion()) {
14605 Result = *Result + 1;
14606 continue;
14607 }
14608
14609 TemplateArgumentLoc ArgLoc;
14610 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
14611
14612 // Find the pattern of the pack expansion.
14613 SourceLocation Ellipsis;
14614 std::optional<unsigned> OrigNumExpansions;
14615 TemplateArgumentLoc Pattern =
14616 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
14617 OrigNumExpansions);
14618
14619 // Substitute under the pack expansion. Do not expand the pack (yet).
14620 TemplateArgumentLoc OutPattern;
14621 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14622 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
14623 /*Uneval*/ true))
14624 return true;
14625
14626 // See if we can determine the number of arguments from the result.
14627 std::optional<unsigned> NumExpansions =
14628 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
14629 if (!NumExpansions) {
14630 // No: we must be in an alias template expansion, and we're going to need
14631 // to actually expand the packs.
14632 Result = std::nullopt;
14633 break;
14634 }
14635
14636 Result = *Result + *NumExpansions;
14637 }
14638
14639 // Common case: we could determine the number of expansions without
14640 // substituting.
14641 if (Result)
14642 return getDerived().RebuildSizeOfPackExpr(
14643 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14644 *Result, std::nullopt);
14645
14646 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
14647 E->getPackLoc());
14648 {
14649 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
14650 typedef TemplateArgumentLocInventIterator<
14651 Derived, const TemplateArgument*> PackLocIterator;
14652 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
14653 PackLocIterator(*this, PackArgs.end()),
14654 TransformedPackArgs, /*Uneval*/true))
14655 return ExprError();
14656 }
14657
14658 // Check whether we managed to fully-expand the pack.
14659 // FIXME: Is it possible for us to do so and not hit the early exit path?
14660 SmallVector<TemplateArgument, 8> Args;
14661 bool PartialSubstitution = false;
14662 for (auto &Loc : TransformedPackArgs.arguments()) {
14663 Args.push_back(Loc.getArgument());
14664 if (Loc.getArgument().isPackExpansion())
14665 PartialSubstitution = true;
14666 }
14667
14668 if (PartialSubstitution)
14669 return getDerived().RebuildSizeOfPackExpr(
14670 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14671 std::nullopt, Args);
14672
14673 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
14674 E->getPackLoc(), E->getRParenLoc(),
14675 Args.size(), std::nullopt);
14676}
14677
14678template <typename Derived>
14679ExprResult
14680TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
14681 if (!E->isValueDependent())
14682 return E;
14683
14684 // Transform the index
14685 ExprResult IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
14686 if (IndexExpr.isInvalid())
14687 return ExprError();
14688
14689 SmallVector<Expr *, 5> ExpandedExprs;
14690 if (E->getExpressions().empty()) {
14691 Expr *Pattern = E->getPackIdExpression();
14692 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14693 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
14694 Unexpanded);
14695 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14696
14697 // Determine whether the set of unexpanded parameter packs can and should
14698 // be expanded.
14699 bool ShouldExpand = true;
14700 bool RetainExpansion = false;
14701 std::optional<unsigned> OrigNumExpansions;
14702 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14703 if (getDerived().TryExpandParameterPacks(
14704 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
14705 ShouldExpand, RetainExpansion, NumExpansions))
14706 return true;
14707 if (!ShouldExpand) {
14708 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14709 ExprResult Pack = getDerived().TransformExpr(Pattern);
14710 if (Pack.isInvalid())
14711 return ExprError();
14712 return getDerived().RebuildPackIndexingExpr(
14713 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
14714 std::nullopt);
14715 }
14716 for (unsigned I = 0; I != *NumExpansions; ++I) {
14717 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14718 ExprResult Out = getDerived().TransformExpr(Pattern);
14719 if (Out.isInvalid())
14720 return true;
14721 if (Out.get()->containsUnexpandedParameterPack()) {
14722 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
14723 OrigNumExpansions);
14724 if (Out.isInvalid())
14725 return true;
14726 }
14727 ExpandedExprs.push_back(Out.get());
14728 }
14729 // If we're supposed to retain a pack expansion, do so by temporarily
14730 // forgetting the partially-substituted parameter pack.
14731 if (RetainExpansion) {
14732 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14733
14734 ExprResult Out = getDerived().TransformExpr(Pattern);
14735 if (Out.isInvalid())
14736 return true;
14737
14738 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
14739 OrigNumExpansions);
14740 if (Out.isInvalid())
14741 return true;
14742 ExpandedExprs.push_back(Out.get());
14743 }
14744 }
14745
14746 else {
14747 if (getDerived().TransformExprs(E->getExpressions().data(),
14748 E->getExpressions().size(), false,
14749 ExpandedExprs))
14750 return ExprError();
14751 }
14752
14753 return getDerived().RebuildPackIndexingExpr(
14754 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
14755 IndexExpr.get(), ExpandedExprs,
14756 /*EmptyPack=*/ExpandedExprs.size() == 0);
14757}
14758
14759template<typename Derived>
14760ExprResult
14761TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
14762 SubstNonTypeTemplateParmPackExpr *E) {
14763 // Default behavior is to do nothing with this transformation.
14764 return E;
14765}
14766
14767template<typename Derived>
14768ExprResult
14769TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
14770 SubstNonTypeTemplateParmExpr *E) {
14771 // Default behavior is to do nothing with this transformation.
14772 return E;
14773}
14774
14775template<typename Derived>
14776ExprResult
14777TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
14778 // Default behavior is to do nothing with this transformation.
14779 return E;
14780}
14781
14782template<typename Derived>
14783ExprResult
14784TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
14785 MaterializeTemporaryExpr *E) {
14786 return getDerived().TransformExpr(E->getSubExpr());
14787}
14788
14789template<typename Derived>
14790ExprResult
14791TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
14792 UnresolvedLookupExpr *Callee = nullptr;
14793 if (Expr *OldCallee = E->getCallee()) {
14794 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
14795 if (CalleeResult.isInvalid())
14796 return ExprError();
14797 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
14798 }
14799
14800 Expr *Pattern = E->getPattern();
14801
14802 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14803 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
14804 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14805
14806 // Determine whether the set of unexpanded parameter packs can and should
14807 // be expanded.
14808 bool Expand = true;
14809 bool RetainExpansion = false;
14810 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
14811 NumExpansions = OrigNumExpansions;
14812 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
14813 Pattern->getSourceRange(),
14814 Unexpanded,
14815 Expand, RetainExpansion,
14816 NumExpansions))
14817 return true;
14818
14819 if (!Expand) {
14820 // Do not expand any packs here, just transform and rebuild a fold
14821 // expression.
14822 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14823
14824 ExprResult LHS =
14825 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
14826 if (LHS.isInvalid())
14827 return true;
14828
14829 ExprResult RHS =
14830 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
14831 if (RHS.isInvalid())
14832 return true;
14833
14834 if (!getDerived().AlwaysRebuild() &&
14835 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
14836 return E;
14837
14838 return getDerived().RebuildCXXFoldExpr(
14839 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
14840 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
14841 }
14842
14843 // Formally a fold expression expands to nested parenthesized expressions.
14844 // Enforce this limit to avoid creating trees so deep we can't safely traverse
14845 // them.
14846 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
14847 SemaRef.Diag(E->getEllipsisLoc(),
14848 clang::diag::err_fold_expression_limit_exceeded)
14849 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
14850 << E->getSourceRange();
14851 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
14852 return ExprError();
14853 }
14854
14855 // The transform has determined that we should perform an elementwise
14856 // expansion of the pattern. Do so.
14857 ExprResult Result = getDerived().TransformExpr(E->getInit());
14858 if (Result.isInvalid())
14859 return true;
14860 bool LeftFold = E->isLeftFold();
14861
14862 // If we're retaining an expansion for a right fold, it is the innermost
14863 // component and takes the init (if any).
14864 if (!LeftFold && RetainExpansion) {
14865 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14866
14867 ExprResult Out = getDerived().TransformExpr(Pattern);
14868 if (Out.isInvalid())
14869 return true;
14870
14871 Result = getDerived().RebuildCXXFoldExpr(
14872 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
14873 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
14874 if (Result.isInvalid())
14875 return true;
14876 }
14877
14878 for (unsigned I = 0; I != *NumExpansions; ++I) {
14879 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
14880 getSema(), LeftFold ? I : *NumExpansions - I - 1);
14881 ExprResult Out = getDerived().TransformExpr(Pattern);
14882 if (Out.isInvalid())
14883 return true;
14884
14885 if (Out.get()->containsUnexpandedParameterPack()) {
14886 // We still have a pack; retain a pack expansion for this slice.
14887 Result = getDerived().RebuildCXXFoldExpr(
14888 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
14889 E->getOperator(), E->getEllipsisLoc(),
14890 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
14891 OrigNumExpansions);
14892 } else if (Result.isUsable()) {
14893 // We've got down to a single element; build a binary operator.
14894 Expr *LHS = LeftFold ? Result.get() : Out.get();
14895 Expr *RHS = LeftFold ? Out.get() : Result.get();
14896 if (Callee) {
14897 UnresolvedSet<16> Functions;
14898 Functions.append(Callee->decls_begin(), Callee->decls_end());
14899 Result = getDerived().RebuildCXXOperatorCallExpr(
14900 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
14901 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
14902 Functions, LHS, RHS);
14903 } else {
14904 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
14905 E->getOperator(), LHS, RHS);
14906 }
14907 } else
14908 Result = Out;
14909
14910 if (Result.isInvalid())
14911 return true;
14912 }
14913
14914 // If we're retaining an expansion for a left fold, it is the outermost
14915 // component and takes the complete expansion so far as its init (if any).
14916 if (LeftFold && RetainExpansion) {
14917 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14918
14919 ExprResult Out = getDerived().TransformExpr(Pattern);
14920 if (Out.isInvalid())
14921 return true;
14922
14923 Result = getDerived().RebuildCXXFoldExpr(
14924 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
14925 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
14926 if (Result.isInvalid())
14927 return true;
14928 }
14929
14930 // If we had no init and an empty pack, and we're not retaining an expansion,
14931 // then produce a fallback value or error.
14932 if (Result.isUnset())
14933 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
14934 E->getOperator());
14935
14936 return Result;
14937}
14938
14939template <typename Derived>
14940ExprResult
14941TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
14942 SmallVector<Expr *, 4> TransformedInits;
14943 ArrayRef<Expr *> InitExprs = E->getInitExprs();
14944 if (TransformExprs(Inputs: InitExprs.data(), NumInputs: InitExprs.size(), IsCall: true,
14945 Outputs&: TransformedInits))
14946 return ExprError();
14947
14948 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
14949 E->getEndLoc());
14950}
14951
14952template<typename Derived>
14953ExprResult
14954TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
14955 CXXStdInitializerListExpr *E) {
14956 return getDerived().TransformExpr(E->getSubExpr());
14957}
14958
14959template<typename Derived>
14960ExprResult
14961TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
14962 return SemaRef.MaybeBindToTemporary(E);
14963}
14964
14965template<typename Derived>
14966ExprResult
14967TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
14968 return E;
14969}
14970
14971template<typename Derived>
14972ExprResult
14973TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
14974 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14975 if (SubExpr.isInvalid())
14976 return ExprError();
14977
14978 if (!getDerived().AlwaysRebuild() &&
14979 SubExpr.get() == E->getSubExpr())
14980 return E;
14981
14982 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
14983}
14984
14985template<typename Derived>
14986ExprResult
14987TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
14988 // Transform each of the elements.
14989 SmallVector<Expr *, 8> Elements;
14990 bool ArgChanged = false;
14991 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
14992 /*IsCall=*/false, Elements, &ArgChanged))
14993 return ExprError();
14994
14995 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14996 return SemaRef.MaybeBindToTemporary(E);
14997
14998 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
14999 Elements.data(),
15000 Elements.size());
15001}
15002
15003template<typename Derived>
15004ExprResult
15005TreeTransform<Derived>::TransformObjCDictionaryLiteral(
15006 ObjCDictionaryLiteral *E) {
15007 // Transform each of the elements.
15008 SmallVector<ObjCDictionaryElement, 8> Elements;
15009 bool ArgChanged = false;
15010 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
15011 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
15012
15013 if (OrigElement.isPackExpansion()) {
15014 // This key/value element is a pack expansion.
15015 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15016 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
15017 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
15018 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15019
15020 // Determine whether the set of unexpanded parameter packs can
15021 // and should be expanded.
15022 bool Expand = true;
15023 bool RetainExpansion = false;
15024 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
15025 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15026 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
15027 OrigElement.Value->getEndLoc());
15028 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
15029 PatternRange, Unexpanded, Expand,
15030 RetainExpansion, NumExpansions))
15031 return ExprError();
15032
15033 if (!Expand) {
15034 // The transform has determined that we should perform a simple
15035 // transformation on the pack expansion, producing another pack
15036 // expansion.
15037 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15038 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15039 if (Key.isInvalid())
15040 return ExprError();
15041
15042 if (Key.get() != OrigElement.Key)
15043 ArgChanged = true;
15044
15045 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15046 if (Value.isInvalid())
15047 return ExprError();
15048
15049 if (Value.get() != OrigElement.Value)
15050 ArgChanged = true;
15051
15052 ObjCDictionaryElement Expansion = {
15053 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
15054 };
15055 Elements.push_back(Expansion);
15056 continue;
15057 }
15058
15059 // Record right away that the argument was changed. This needs
15060 // to happen even if the array expands to nothing.
15061 ArgChanged = true;
15062
15063 // The transform has determined that we should perform an elementwise
15064 // expansion of the pattern. Do so.
15065 for (unsigned I = 0; I != *NumExpansions; ++I) {
15066 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15067 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15068 if (Key.isInvalid())
15069 return ExprError();
15070
15071 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15072 if (Value.isInvalid())
15073 return ExprError();
15074
15075 ObjCDictionaryElement Element = {
15076 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
15077 };
15078
15079 // If any unexpanded parameter packs remain, we still have a
15080 // pack expansion.
15081 // FIXME: Can this really happen?
15082 if (Key.get()->containsUnexpandedParameterPack() ||
15083 Value.get()->containsUnexpandedParameterPack())
15084 Element.EllipsisLoc = OrigElement.EllipsisLoc;
15085
15086 Elements.push_back(Element);
15087 }
15088
15089 // FIXME: Retain a pack expansion if RetainExpansion is true.
15090
15091 // We've finished with this pack expansion.
15092 continue;
15093 }
15094
15095 // Transform and check key.
15096 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15097 if (Key.isInvalid())
15098 return ExprError();
15099
15100 if (Key.get() != OrigElement.Key)
15101 ArgChanged = true;
15102
15103 // Transform and check value.
15104 ExprResult Value
15105 = getDerived().TransformExpr(OrigElement.Value);
15106 if (Value.isInvalid())
15107 return ExprError();
15108
15109 if (Value.get() != OrigElement.Value)
15110 ArgChanged = true;
15111
15112 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
15113 .NumExpansions: std::nullopt};
15114 Elements.push_back(Element);
15115 }
15116
15117 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15118 return SemaRef.MaybeBindToTemporary(E);
15119
15120 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
15121 Elements);
15122}
15123
15124template<typename Derived>
15125ExprResult
15126TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
15127 TypeSourceInfo *EncodedTypeInfo
15128 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
15129 if (!EncodedTypeInfo)
15130 return ExprError();
15131
15132 if (!getDerived().AlwaysRebuild() &&
15133 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
15134 return E;
15135
15136 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
15137 EncodedTypeInfo,
15138 E->getRParenLoc());
15139}
15140
15141template<typename Derived>
15142ExprResult TreeTransform<Derived>::
15143TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
15144 // This is a kind of implicit conversion, and it needs to get dropped
15145 // and recomputed for the same general reasons that ImplicitCastExprs
15146 // do, as well a more specific one: this expression is only valid when
15147 // it appears *immediately* as an argument expression.
15148 return getDerived().TransformExpr(E->getSubExpr());
15149}
15150
15151template<typename Derived>
15152ExprResult TreeTransform<Derived>::
15153TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
15154 TypeSourceInfo *TSInfo
15155 = getDerived().TransformType(E->getTypeInfoAsWritten());
15156 if (!TSInfo)
15157 return ExprError();
15158
15159 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
15160 if (Result.isInvalid())
15161 return ExprError();
15162
15163 if (!getDerived().AlwaysRebuild() &&
15164 TSInfo == E->getTypeInfoAsWritten() &&
15165 Result.get() == E->getSubExpr())
15166 return E;
15167
15168 return SemaRef.BuildObjCBridgedCast(LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(),
15169 BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
15170 SubExpr: Result.get());
15171}
15172
15173template <typename Derived>
15174ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
15175 ObjCAvailabilityCheckExpr *E) {
15176 return E;
15177}
15178
15179template<typename Derived>
15180ExprResult
15181TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
15182 // Transform arguments.
15183 bool ArgChanged = false;
15184 SmallVector<Expr*, 8> Args;
15185 Args.reserve(E->getNumArgs());
15186 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
15187 &ArgChanged))
15188 return ExprError();
15189
15190 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
15191 // Class message: transform the receiver type.
15192 TypeSourceInfo *ReceiverTypeInfo
15193 = getDerived().TransformType(E->getClassReceiverTypeInfo());
15194 if (!ReceiverTypeInfo)
15195 return ExprError();
15196
15197 // If nothing changed, just retain the existing message send.
15198 if (!getDerived().AlwaysRebuild() &&
15199 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
15200 return SemaRef.MaybeBindToTemporary(E);
15201
15202 // Build a new class message send.
15203 SmallVector<SourceLocation, 16> SelLocs;
15204 E->getSelectorLocs(SelLocs&: SelLocs);
15205 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
15206 E->getSelector(),
15207 SelLocs,
15208 E->getMethodDecl(),
15209 E->getLeftLoc(),
15210 Args,
15211 E->getRightLoc());
15212 }
15213 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
15214 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
15215 if (!E->getMethodDecl())
15216 return ExprError();
15217
15218 // Build a new class message send to 'super'.
15219 SmallVector<SourceLocation, 16> SelLocs;
15220 E->getSelectorLocs(SelLocs&: SelLocs);
15221 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
15222 E->getSelector(),
15223 SelLocs,
15224 E->getReceiverType(),
15225 E->getMethodDecl(),
15226 E->getLeftLoc(),
15227 Args,
15228 E->getRightLoc());
15229 }
15230
15231 // Instance message: transform the receiver
15232 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
15233 "Only class and instance messages may be instantiated");
15234 ExprResult Receiver
15235 = getDerived().TransformExpr(E->getInstanceReceiver());
15236 if (Receiver.isInvalid())
15237 return ExprError();
15238
15239 // If nothing changed, just retain the existing message send.
15240 if (!getDerived().AlwaysRebuild() &&
15241 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
15242 return SemaRef.MaybeBindToTemporary(E);
15243
15244 // Build a new instance message send.
15245 SmallVector<SourceLocation, 16> SelLocs;
15246 E->getSelectorLocs(SelLocs&: SelLocs);
15247 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
15248 E->getSelector(),
15249 SelLocs,
15250 E->getMethodDecl(),
15251 E->getLeftLoc(),
15252 Args,
15253 E->getRightLoc());
15254}
15255
15256template<typename Derived>
15257ExprResult
15258TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
15259 return E;
15260}
15261
15262template<typename Derived>
15263ExprResult
15264TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
15265 return E;
15266}
15267
15268template<typename Derived>
15269ExprResult
15270TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
15271 // Transform the base expression.
15272 ExprResult Base = getDerived().TransformExpr(E->getBase());
15273 if (Base.isInvalid())
15274 return ExprError();
15275
15276 // We don't need to transform the ivar; it will never change.
15277
15278 // If nothing changed, just retain the existing expression.
15279 if (!getDerived().AlwaysRebuild() &&
15280 Base.get() == E->getBase())
15281 return E;
15282
15283 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
15284 E->getLocation(),
15285 E->isArrow(), E->isFreeIvar());
15286}
15287
15288template<typename Derived>
15289ExprResult
15290TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
15291 // 'super' and types never change. Property never changes. Just
15292 // retain the existing expression.
15293 if (!E->isObjectReceiver())
15294 return E;
15295
15296 // Transform the base expression.
15297 ExprResult Base = getDerived().TransformExpr(E->getBase());
15298 if (Base.isInvalid())
15299 return ExprError();
15300
15301 // We don't need to transform the property; it will never change.
15302
15303 // If nothing changed, just retain the existing expression.
15304 if (!getDerived().AlwaysRebuild() &&
15305 Base.get() == E->getBase())
15306 return E;
15307
15308 if (E->isExplicitProperty())
15309 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15310 E->getExplicitProperty(),
15311 E->getLocation());
15312
15313 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15314 SemaRef.Context.PseudoObjectTy,
15315 E->getImplicitPropertyGetter(),
15316 E->getImplicitPropertySetter(),
15317 E->getLocation());
15318}
15319
15320template<typename Derived>
15321ExprResult
15322TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
15323 // Transform the base expression.
15324 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
15325 if (Base.isInvalid())
15326 return ExprError();
15327
15328 // Transform the key expression.
15329 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
15330 if (Key.isInvalid())
15331 return ExprError();
15332
15333 // If nothing changed, just retain the existing expression.
15334 if (!getDerived().AlwaysRebuild() &&
15335 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
15336 return E;
15337
15338 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
15339 Base.get(), Key.get(),
15340 E->getAtIndexMethodDecl(),
15341 E->setAtIndexMethodDecl());
15342}
15343
15344template<typename Derived>
15345ExprResult
15346TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
15347 // Transform the base expression.
15348 ExprResult Base = getDerived().TransformExpr(E->getBase());
15349 if (Base.isInvalid())
15350 return ExprError();
15351
15352 // If nothing changed, just retain the existing expression.
15353 if (!getDerived().AlwaysRebuild() &&
15354 Base.get() == E->getBase())
15355 return E;
15356
15357 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
15358 E->getOpLoc(),
15359 E->isArrow());
15360}
15361
15362template<typename Derived>
15363ExprResult
15364TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
15365 bool ArgumentChanged = false;
15366 SmallVector<Expr*, 8> SubExprs;
15367 SubExprs.reserve(E->getNumSubExprs());
15368 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15369 SubExprs, &ArgumentChanged))
15370 return ExprError();
15371
15372 if (!getDerived().AlwaysRebuild() &&
15373 !ArgumentChanged)
15374 return E;
15375
15376 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
15377 SubExprs,
15378 E->getRParenLoc());
15379}
15380
15381template<typename Derived>
15382ExprResult
15383TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
15384 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15385 if (SrcExpr.isInvalid())
15386 return ExprError();
15387
15388 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
15389 if (!Type)
15390 return ExprError();
15391
15392 if (!getDerived().AlwaysRebuild() &&
15393 Type == E->getTypeSourceInfo() &&
15394 SrcExpr.get() == E->getSrcExpr())
15395 return E;
15396
15397 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
15398 SrcExpr.get(), Type,
15399 E->getRParenLoc());
15400}
15401
15402template<typename Derived>
15403ExprResult
15404TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
15405 BlockDecl *oldBlock = E->getBlockDecl();
15406
15407 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
15408 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
15409
15410 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
15411 blockScope->TheDecl->setBlockMissingReturnType(
15412 oldBlock->blockMissingReturnType());
15413
15414 SmallVector<ParmVarDecl*, 4> params;
15415 SmallVector<QualType, 4> paramTypes;
15416
15417 const FunctionProtoType *exprFunctionType = E->getFunctionType();
15418
15419 // Parameter substitution.
15420 Sema::ExtParameterInfoBuilder extParamInfos;
15421 if (getDerived().TransformFunctionTypeParams(
15422 E->getCaretLocation(), oldBlock->parameters(), nullptr,
15423 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
15424 extParamInfos)) {
15425 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15426 return ExprError();
15427 }
15428
15429 QualType exprResultType =
15430 getDerived().TransformType(exprFunctionType->getReturnType());
15431
15432 auto epi = exprFunctionType->getExtProtoInfo();
15433 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
15434
15435 QualType functionType =
15436 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
15437 blockScope->FunctionType = functionType;
15438
15439 // Set the parameters on the block decl.
15440 if (!params.empty())
15441 blockScope->TheDecl->setParams(params);
15442
15443 if (!oldBlock->blockMissingReturnType()) {
15444 blockScope->HasImplicitReturnType = false;
15445 blockScope->ReturnType = exprResultType;
15446 }
15447
15448 // Transform the body
15449 StmtResult body = getDerived().TransformStmt(E->getBody());
15450 if (body.isInvalid()) {
15451 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15452 return ExprError();
15453 }
15454
15455#ifndef NDEBUG
15456 // In builds with assertions, make sure that we captured everything we
15457 // captured before.
15458 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
15459 for (const auto &I : oldBlock->captures()) {
15460 VarDecl *oldCapture = I.getVariable();
15461
15462 // Ignore parameter packs.
15463 if (oldCapture->isParameterPack())
15464 continue;
15465
15466 VarDecl *newCapture =
15467 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
15468 oldCapture));
15469 assert(blockScope->CaptureMap.count(newCapture));
15470 }
15471
15472 // The this pointer may not be captured by the instantiated block, even when
15473 // it's captured by the original block, if the expression causing the
15474 // capture is in the discarded branch of a constexpr if statement.
15475 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
15476 "this pointer isn't captured in the old block");
15477 }
15478#endif
15479
15480 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
15481 /*Scope=*/CurScope: nullptr);
15482}
15483
15484template<typename Derived>
15485ExprResult
15486TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
15487 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15488 if (SrcExpr.isInvalid())
15489 return ExprError();
15490
15491 QualType Type = getDerived().TransformType(E->getType());
15492
15493 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
15494 RParenLoc: E->getRParenLoc());
15495}
15496
15497template<typename Derived>
15498ExprResult
15499TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
15500 bool ArgumentChanged = false;
15501 SmallVector<Expr*, 8> SubExprs;
15502 SubExprs.reserve(E->getNumSubExprs());
15503 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15504 SubExprs, &ArgumentChanged))
15505 return ExprError();
15506
15507 if (!getDerived().AlwaysRebuild() &&
15508 !ArgumentChanged)
15509 return E;
15510
15511 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
15512 E->getOp(), E->getRParenLoc());
15513}
15514
15515//===----------------------------------------------------------------------===//
15516// Type reconstruction
15517//===----------------------------------------------------------------------===//
15518
15519template<typename Derived>
15520QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
15521 SourceLocation Star) {
15522 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
15523 Entity: getDerived().getBaseEntity());
15524}
15525
15526template<typename Derived>
15527QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
15528 SourceLocation Star) {
15529 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
15530 Entity: getDerived().getBaseEntity());
15531}
15532
15533template<typename Derived>
15534QualType
15535TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
15536 bool WrittenAsLValue,
15537 SourceLocation Sigil) {
15538 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
15539 Loc: Sigil, Entity: getDerived().getBaseEntity());
15540}
15541
15542template<typename Derived>
15543QualType
15544TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
15545 QualType ClassType,
15546 SourceLocation Sigil) {
15547 return SemaRef.BuildMemberPointerType(T: PointeeType, Class: ClassType, Loc: Sigil,
15548 Entity: getDerived().getBaseEntity());
15549}
15550
15551template<typename Derived>
15552QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
15553 const ObjCTypeParamDecl *Decl,
15554 SourceLocation ProtocolLAngleLoc,
15555 ArrayRef<ObjCProtocolDecl *> Protocols,
15556 ArrayRef<SourceLocation> ProtocolLocs,
15557 SourceLocation ProtocolRAngleLoc) {
15558 return SemaRef.BuildObjCTypeParamType(Decl,
15559 ProtocolLAngleLoc, Protocols: Protocols,
15560 ProtocolLocs, ProtocolRAngleLoc,
15561 /*FailOnError=*/FailOnError: true);
15562}
15563
15564template<typename Derived>
15565QualType TreeTransform<Derived>::RebuildObjCObjectType(
15566 QualType BaseType,
15567 SourceLocation Loc,
15568 SourceLocation TypeArgsLAngleLoc,
15569 ArrayRef<TypeSourceInfo *> TypeArgs,
15570 SourceLocation TypeArgsRAngleLoc,
15571 SourceLocation ProtocolLAngleLoc,
15572 ArrayRef<ObjCProtocolDecl *> Protocols,
15573 ArrayRef<SourceLocation> ProtocolLocs,
15574 SourceLocation ProtocolRAngleLoc) {
15575 return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs: TypeArgs,
15576 TypeArgsRAngleLoc, ProtocolLAngleLoc,
15577 Protocols: Protocols, ProtocolLocs, ProtocolRAngleLoc,
15578 /*FailOnError=*/FailOnError: true,
15579 /*Rebuilding=*/Rebuilding: true);
15580}
15581
15582template<typename Derived>
15583QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
15584 QualType PointeeType,
15585 SourceLocation Star) {
15586 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
15587}
15588
15589template <typename Derived>
15590QualType TreeTransform<Derived>::RebuildArrayType(
15591 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
15592 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
15593 if (SizeExpr || !Size)
15594 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
15595 Quals: IndexTypeQuals, Brackets: BracketsRange,
15596 Entity: getDerived().getBaseEntity());
15597
15598 QualType Types[] = {
15599 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
15600 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
15601 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
15602 };
15603 QualType SizeType;
15604 for (const auto &T : Types)
15605 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
15606 SizeType = T;
15607 break;
15608 }
15609
15610 // Note that we can return a VariableArrayType here in the case where
15611 // the element type was a dependent VariableArrayType.
15612 IntegerLiteral *ArraySize
15613 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
15614 /*FIXME*/l: BracketsRange.getBegin());
15615 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
15616 Quals: IndexTypeQuals, Brackets: BracketsRange,
15617 Entity: getDerived().getBaseEntity());
15618}
15619
15620template <typename Derived>
15621QualType TreeTransform<Derived>::RebuildConstantArrayType(
15622 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
15623 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
15624 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
15625 IndexTypeQuals, BracketsRange);
15626}
15627
15628template <typename Derived>
15629QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
15630 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
15631 SourceRange BracketsRange) {
15632 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
15633 IndexTypeQuals, BracketsRange);
15634}
15635
15636template <typename Derived>
15637QualType TreeTransform<Derived>::RebuildVariableArrayType(
15638 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
15639 unsigned IndexTypeQuals, SourceRange BracketsRange) {
15640 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
15641 SizeExpr,
15642 IndexTypeQuals, BracketsRange);
15643}
15644
15645template <typename Derived>
15646QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
15647 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
15648 unsigned IndexTypeQuals, SourceRange BracketsRange) {
15649 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
15650 SizeExpr,
15651 IndexTypeQuals, BracketsRange);
15652}
15653
15654template <typename Derived>
15655QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
15656 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
15657 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
15658 AttrLoc: AttributeLoc);
15659}
15660
15661template <typename Derived>
15662QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
15663 unsigned NumElements,
15664 VectorKind VecKind) {
15665 // FIXME: semantic checking!
15666 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
15667}
15668
15669template <typename Derived>
15670QualType TreeTransform<Derived>::RebuildDependentVectorType(
15671 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
15672 VectorKind VecKind) {
15673 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
15674}
15675
15676template<typename Derived>
15677QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
15678 unsigned NumElements,
15679 SourceLocation AttributeLoc) {
15680 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
15681 NumElements, true);
15682 IntegerLiteral *VectorSize
15683 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
15684 AttributeLoc);
15685 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
15686}
15687
15688template<typename Derived>
15689QualType
15690TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
15691 Expr *SizeExpr,
15692 SourceLocation AttributeLoc) {
15693 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
15694}
15695
15696template <typename Derived>
15697QualType TreeTransform<Derived>::RebuildConstantMatrixType(
15698 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
15699 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
15700 NumColumns);
15701}
15702
15703template <typename Derived>
15704QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
15705 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
15706 SourceLocation AttributeLoc) {
15707 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
15708 AttrLoc: AttributeLoc);
15709}
15710
15711template<typename Derived>
15712QualType TreeTransform<Derived>::RebuildFunctionProtoType(
15713 QualType T,
15714 MutableArrayRef<QualType> ParamTypes,
15715 const FunctionProtoType::ExtProtoInfo &EPI) {
15716 return SemaRef.BuildFunctionType(T, ParamTypes: ParamTypes,
15717 Loc: getDerived().getBaseLocation(),
15718 Entity: getDerived().getBaseEntity(),
15719 EPI);
15720}
15721
15722template<typename Derived>
15723QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
15724 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
15725}
15726
15727template<typename Derived>
15728QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
15729 Decl *D) {
15730 assert(D && "no decl found");
15731 if (D->isInvalidDecl()) return QualType();
15732
15733 // FIXME: Doesn't account for ObjCInterfaceDecl!
15734 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
15735 // A valid resolved using typename pack expansion decl can have multiple
15736 // UsingDecls, but they must each have exactly one type, and it must be
15737 // the same type in every case. But we must have at least one expansion!
15738 if (UPD->expansions().empty()) {
15739 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
15740 << UPD->isCXXClassMember() << UPD;
15741 return QualType();
15742 }
15743
15744 // We might still have some unresolved types. Try to pick a resolved type
15745 // if we can. The final instantiation will check that the remaining
15746 // unresolved types instantiate to the type we pick.
15747 QualType FallbackT;
15748 QualType T;
15749 for (auto *E : UPD->expansions()) {
15750 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
15751 if (ThisT.isNull())
15752 continue;
15753 else if (ThisT->getAs<UnresolvedUsingType>())
15754 FallbackT = ThisT;
15755 else if (T.isNull())
15756 T = ThisT;
15757 else
15758 assert(getSema().Context.hasSameType(ThisT, T) &&
15759 "mismatched resolved types in using pack expansion");
15760 }
15761 return T.isNull() ? FallbackT : T;
15762 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
15763 assert(Using->hasTypename() &&
15764 "UnresolvedUsingTypenameDecl transformed to non-typename using");
15765
15766 // A valid resolved using typename decl points to exactly one type decl.
15767 assert(++Using->shadow_begin() == Using->shadow_end());
15768
15769 UsingShadowDecl *Shadow = *Using->shadow_begin();
15770 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: Loc))
15771 return QualType();
15772 return SemaRef.Context.getUsingType(
15773 Found: Shadow, Underlying: SemaRef.Context.getTypeDeclType(
15774 Decl: cast<TypeDecl>(Shadow->getTargetDecl())));
15775 } else {
15776 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
15777 "UnresolvedUsingTypenameDecl transformed to non-using decl");
15778 return SemaRef.Context.getTypeDeclType(
15779 Decl: cast<UnresolvedUsingTypenameDecl>(D));
15780 }
15781}
15782
15783template <typename Derived>
15784QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
15785 TypeOfKind Kind) {
15786 return SemaRef.BuildTypeofExprType(E, Kind);
15787}
15788
15789template<typename Derived>
15790QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
15791 TypeOfKind Kind) {
15792 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
15793}
15794
15795template <typename Derived>
15796QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
15797 return SemaRef.BuildDecltypeType(E);
15798}
15799
15800template <typename Derived>
15801QualType TreeTransform<Derived>::RebuildPackIndexingType(
15802 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
15803 SourceLocation EllipsisLoc, bool FullySubstituted,
15804 ArrayRef<QualType> Expansions) {
15805 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
15806 FullySubstituted, Expansions);
15807}
15808
15809template<typename Derived>
15810QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
15811 UnaryTransformType::UTTKind UKind,
15812 SourceLocation Loc) {
15813 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
15814}
15815
15816template<typename Derived>
15817QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
15818 TemplateName Template,
15819 SourceLocation TemplateNameLoc,
15820 TemplateArgumentListInfo &TemplateArgs) {
15821 return SemaRef.CheckTemplateIdType(Template, TemplateLoc: TemplateNameLoc, TemplateArgs);
15822}
15823
15824template<typename Derived>
15825QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
15826 SourceLocation KWLoc) {
15827 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
15828}
15829
15830template<typename Derived>
15831QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
15832 SourceLocation KWLoc,
15833 bool isReadPipe) {
15834 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
15835 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
15836}
15837
15838template <typename Derived>
15839QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
15840 unsigned NumBits,
15841 SourceLocation Loc) {
15842 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
15843 NumBits, true);
15844 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
15845 SemaRef.Context.IntTy, Loc);
15846 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
15847}
15848
15849template <typename Derived>
15850QualType TreeTransform<Derived>::RebuildDependentBitIntType(
15851 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
15852 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
15853}
15854
15855template<typename Derived>
15856TemplateName
15857TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15858 bool TemplateKW,
15859 TemplateDecl *Template) {
15860 return SemaRef.Context.getQualifiedTemplateName(NNS: SS.getScopeRep(), TemplateKeyword: TemplateKW,
15861 Template: TemplateName(Template));
15862}
15863
15864template<typename Derived>
15865TemplateName
15866TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15867 SourceLocation TemplateKWLoc,
15868 const IdentifierInfo &Name,
15869 SourceLocation NameLoc,
15870 QualType ObjectType,
15871 NamedDecl *FirstQualifierInScope,
15872 bool AllowInjectedClassName) {
15873 UnqualifiedId TemplateName;
15874 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
15875 Sema::TemplateTy Template;
15876 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
15877 TemplateName, ParsedType::make(P: ObjectType),
15878 /*EnteringContext=*/false, Template,
15879 AllowInjectedClassName);
15880 return Template.get();
15881}
15882
15883template<typename Derived>
15884TemplateName
15885TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15886 SourceLocation TemplateKWLoc,
15887 OverloadedOperatorKind Operator,
15888 SourceLocation NameLoc,
15889 QualType ObjectType,
15890 bool AllowInjectedClassName) {
15891 UnqualifiedId Name;
15892 // FIXME: Bogus location information.
15893 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
15894 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
15895 Sema::TemplateTy Template;
15896 getSema().ActOnTemplateName(
15897 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
15898 /*EnteringContext=*/false, Template, AllowInjectedClassName);
15899 return Template.get();
15900}
15901
15902template <typename Derived>
15903ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
15904 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
15905 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
15906 Expr *Second) {
15907 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
15908
15909 if (First->getObjectKind() == OK_ObjCProperty) {
15910 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
15911 if (BinaryOperator::isAssignmentOp(Opc))
15912 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/S: nullptr, OpLoc, Opcode: Opc,
15913 LHS: First, RHS: Second);
15914 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
15915 if (Result.isInvalid())
15916 return ExprError();
15917 First = Result.get();
15918 }
15919
15920 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
15921 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
15922 if (Result.isInvalid())
15923 return ExprError();
15924 Second = Result.get();
15925 }
15926
15927 // Determine whether this should be a builtin operation.
15928 if (Op == OO_Subscript) {
15929 if (!First->getType()->isOverloadableType() &&
15930 !Second->getType()->isOverloadableType())
15931 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
15932 OpLoc);
15933 } else if (Op == OO_Arrow) {
15934 // It is possible that the type refers to a RecoveryExpr created earlier
15935 // in the tree transformation.
15936 if (First->getType()->isDependentType())
15937 return ExprError();
15938 // -> is never a builtin operation.
15939 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
15940 } else if (Second == nullptr || isPostIncDec) {
15941 if (!First->getType()->isOverloadableType() ||
15942 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
15943 // The argument is not of overloadable type, or this is an expression
15944 // of the form &Class::member, so try to create a built-in unary
15945 // operation.
15946 UnaryOperatorKind Opc
15947 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
15948
15949 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
15950 }
15951 } else {
15952 if (!First->getType()->isOverloadableType() &&
15953 !Second->getType()->isOverloadableType()) {
15954 // Neither of the arguments is an overloadable type, so try to
15955 // create a built-in binary operation.
15956 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
15957 ExprResult Result
15958 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
15959 if (Result.isInvalid())
15960 return ExprError();
15961
15962 return Result;
15963 }
15964 }
15965
15966 // Add any functions found via argument-dependent lookup.
15967 Expr *Args[2] = { First, Second };
15968 unsigned NumArgs = 1 + (Second != nullptr);
15969
15970 // Create the overloaded operator invocation for unary operators.
15971 if (NumArgs == 1 || isPostIncDec) {
15972 UnaryOperatorKind Opc
15973 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
15974 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
15975 RequiresADL);
15976 }
15977
15978 // Create the overloaded operator invocation for binary operators.
15979 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
15980 ExprResult Result = SemaRef.CreateOverloadedBinOp(
15981 OpLoc, Opc, Fns: Functions, LHS: Args[0], RHS: Args[1], RequiresADL);
15982 if (Result.isInvalid())
15983 return ExprError();
15984
15985 return Result;
15986}
15987
15988template<typename Derived>
15989ExprResult
15990TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
15991 SourceLocation OperatorLoc,
15992 bool isArrow,
15993 CXXScopeSpec &SS,
15994 TypeSourceInfo *ScopeType,
15995 SourceLocation CCLoc,
15996 SourceLocation TildeLoc,
15997 PseudoDestructorTypeStorage Destroyed) {
15998 QualType BaseType = Base->getType();
15999 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
16000 (!isArrow && !BaseType->getAs<RecordType>()) ||
16001 (isArrow && BaseType->getAs<PointerType>() &&
16002 !BaseType->castAs<PointerType>()->getPointeeType()
16003 ->template getAs<RecordType>())){
16004 // This pseudo-destructor expression is still a pseudo-destructor.
16005 return SemaRef.BuildPseudoDestructorExpr(
16006 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
16007 CCLoc, TildeLoc, DestroyedType: Destroyed);
16008 }
16009
16010 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
16011 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
16012 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
16013 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
16014 NameInfo.setNamedTypeInfo(DestroyedType);
16015
16016 // The scope type is now known to be a valid nested name specifier
16017 // component. Tack it on to the end of the nested name specifier.
16018 if (ScopeType) {
16019 if (!ScopeType->getType()->getAs<TagType>()) {
16020 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
16021 diag::err_expected_class_or_namespace)
16022 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
16023 return ExprError();
16024 }
16025 SS.Extend(Context&: SemaRef.Context, TemplateKWLoc: SourceLocation(), TL: ScopeType->getTypeLoc(),
16026 ColonColonLoc: CCLoc);
16027 }
16028
16029 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
16030 return getSema().BuildMemberReferenceExpr(Base, BaseType,
16031 OperatorLoc, isArrow,
16032 SS, TemplateKWLoc,
16033 /*FIXME: FirstQualifier*/ nullptr,
16034 NameInfo,
16035 /*TemplateArgs*/ nullptr,
16036 /*S*/nullptr);
16037}
16038
16039template<typename Derived>
16040StmtResult
16041TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
16042 SourceLocation Loc = S->getBeginLoc();
16043 CapturedDecl *CD = S->getCapturedDecl();
16044 unsigned NumParams = CD->getNumParams();
16045 unsigned ContextParamPos = CD->getContextParamPosition();
16046 SmallVector<Sema::CapturedParamNameType, 4> Params;
16047 for (unsigned I = 0; I < NumParams; ++I) {
16048 if (I != ContextParamPos) {
16049 Params.push_back(
16050 std::make_pair(
16051 CD->getParam(i: I)->getName(),
16052 getDerived().TransformType(CD->getParam(i: I)->getType())));
16053 } else {
16054 Params.push_back(std::make_pair(StringRef(), QualType()));
16055 }
16056 }
16057 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
16058 S->getCapturedRegionKind(), Params);
16059 StmtResult Body;
16060 {
16061 Sema::CompoundScopeRAII CompoundScope(getSema());
16062 Body = getDerived().TransformStmt(S->getCapturedStmt());
16063 }
16064
16065 if (Body.isInvalid()) {
16066 getSema().ActOnCapturedRegionError();
16067 return StmtError();
16068 }
16069
16070 return getSema().ActOnCapturedRegionEnd(Body.get());
16071}
16072
16073} // end namespace clang
16074
16075#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
16076

source code of clang/lib/Sema/TreeTransform.h