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 "llvm/ADT/ArrayRef.h"
43#include "llvm/Support/ErrorHandling.h"
44#include <algorithm>
45#include <optional>
46
47using namespace llvm::omp;
48
49namespace clang {
50using namespace sema;
51
52/// A semantic tree transformation that allows one to transform one
53/// abstract syntax tree into another.
54///
55/// A new tree transformation is defined by creating a new subclass \c X of
56/// \c TreeTransform<X> and then overriding certain operations to provide
57/// behavior specific to that transformation. For example, template
58/// instantiation is implemented as a tree transformation where the
59/// transformation of TemplateTypeParmType nodes involves substituting the
60/// template arguments for their corresponding template parameters; a similar
61/// transformation is performed for non-type template parameters and
62/// template template parameters.
63///
64/// This tree-transformation template uses static polymorphism to allow
65/// subclasses to customize any of its operations. Thus, a subclass can
66/// override any of the transformation or rebuild operators by providing an
67/// operation with the same signature as the default implementation. The
68/// overriding function should not be virtual.
69///
70/// Semantic tree transformations are split into two stages, either of which
71/// can be replaced by a subclass. The "transform" step transforms an AST node
72/// or the parts of an AST node using the various transformation functions,
73/// then passes the pieces on to the "rebuild" step, which constructs a new AST
74/// node of the appropriate kind from the pieces. The default transformation
75/// routines recursively transform the operands to composite AST nodes (e.g.,
76/// the pointee type of a PointerType node) and, if any of those operand nodes
77/// were changed by the transformation, invokes the rebuild operation to create
78/// a new AST node.
79///
80/// Subclasses can customize the transformation at various levels. The
81/// most coarse-grained transformations involve replacing TransformType(),
82/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
83/// TransformTemplateName(), or TransformTemplateArgument() with entirely
84/// new implementations.
85///
86/// For more fine-grained transformations, subclasses can replace any of the
87/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
88/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
89/// replacing TransformTemplateTypeParmType() allows template instantiation
90/// to substitute template arguments for their corresponding template
91/// parameters. Additionally, subclasses can override the \c RebuildXXX
92/// functions to control how AST nodes are rebuilt when their operands change.
93/// By default, \c TreeTransform will invoke semantic analysis to rebuild
94/// AST nodes. However, certain other tree transformations (e.g, cloning) may
95/// be able to use more efficient rebuild steps.
96///
97/// There are a handful of other functions that can be overridden, allowing one
98/// to avoid traversing nodes that don't need any transformation
99/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
100/// operands have not changed (\c AlwaysRebuild()), and customize the
101/// default locations and entity names used for type-checking
102/// (\c getBaseLocation(), \c getBaseEntity()).
103template<typename Derived>
104class TreeTransform {
105 /// Private RAII object that helps us forget and then re-remember
106 /// the template argument corresponding to a partially-substituted parameter
107 /// pack.
108 class ForgetPartiallySubstitutedPackRAII {
109 Derived &Self;
110 TemplateArgument Old;
111
112 public:
113 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
114 Old = Self.ForgetPartiallySubstitutedPack();
115 }
116
117 ~ForgetPartiallySubstitutedPackRAII() {
118 Self.RememberPartiallySubstitutedPack(Old);
119 }
120 };
121
122protected:
123 Sema &SemaRef;
124
125 /// The set of local declarations that have been transformed, for
126 /// cases where we are forced to build new declarations within the transformer
127 /// rather than in the subclass (e.g., lambda closure types).
128 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
129
130public:
131 /// Initializes a new tree transformer.
132 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
133
134 /// Retrieves a reference to the derived class.
135 Derived &getDerived() { return static_cast<Derived&>(*this); }
136
137 /// Retrieves a reference to the derived class.
138 const Derived &getDerived() const {
139 return static_cast<const Derived&>(*this);
140 }
141
142 static inline ExprResult Owned(Expr *E) { return E; }
143 static inline StmtResult Owned(Stmt *S) { return S; }
144
145 /// Retrieves a reference to the semantic analysis object used for
146 /// this tree transform.
147 Sema &getSema() const { return SemaRef; }
148
149 /// Whether the transformation should always rebuild AST nodes, even
150 /// if none of the children have changed.
151 ///
152 /// Subclasses may override this function to specify when the transformation
153 /// should rebuild all AST nodes.
154 ///
155 /// We must always rebuild all AST nodes when performing variadic template
156 /// pack expansion, in order to avoid violating the AST invariant that each
157 /// statement node appears at most once in its containing declaration.
158 bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
159
160 /// Whether the transformation is forming an expression or statement that
161 /// replaces the original. In this case, we'll reuse mangling numbers from
162 /// existing lambdas.
163 bool ReplacingOriginal() { return false; }
164
165 /// Wether CXXConstructExpr can be skipped when they are implicit.
166 /// They will be reconstructed when used if needed.
167 /// This is useful when the user that cause rebuilding of the
168 /// CXXConstructExpr is outside of the expression at which the TreeTransform
169 /// started.
170 bool AllowSkippingCXXConstructExpr() { return true; }
171
172 /// Returns the location of the entity being transformed, if that
173 /// information was not available elsewhere in the AST.
174 ///
175 /// By default, returns no source-location information. Subclasses can
176 /// provide an alternative implementation that provides better location
177 /// information.
178 SourceLocation getBaseLocation() { return SourceLocation(); }
179
180 /// Returns the name of the entity being transformed, if that
181 /// information was not available elsewhere in the AST.
182 ///
183 /// By default, returns an empty name. Subclasses can provide an alternative
184 /// implementation with a more precise name.
185 DeclarationName getBaseEntity() { return DeclarationName(); }
186
187 /// Sets the "base" location and entity when that
188 /// information is known based on another transformation.
189 ///
190 /// By default, the source location and entity are ignored. Subclasses can
191 /// override this function to provide a customized implementation.
192 void setBase(SourceLocation Loc, DeclarationName Entity) { }
193
194 /// RAII object that temporarily sets the base location and entity
195 /// used for reporting diagnostics in types.
196 class TemporaryBase {
197 TreeTransform &Self;
198 SourceLocation OldLocation;
199 DeclarationName OldEntity;
200
201 public:
202 TemporaryBase(TreeTransform &Self, SourceLocation Location,
203 DeclarationName Entity) : Self(Self) {
204 OldLocation = Self.getDerived().getBaseLocation();
205 OldEntity = Self.getDerived().getBaseEntity();
206
207 if (Location.isValid())
208 Self.getDerived().setBase(Location, Entity);
209 }
210
211 ~TemporaryBase() {
212 Self.getDerived().setBase(OldLocation, OldEntity);
213 }
214 };
215
216 /// Determine whether the given type \p T has already been
217 /// transformed.
218 ///
219 /// Subclasses can provide an alternative implementation of this routine
220 /// to short-circuit evaluation when it is known that a given type will
221 /// not change. For example, template instantiation need not traverse
222 /// non-dependent types.
223 bool AlreadyTransformed(QualType T) {
224 return T.isNull();
225 }
226
227 /// Transform a template parameter depth level.
228 ///
229 /// During a transformation that transforms template parameters, this maps
230 /// an old template parameter depth to a new depth.
231 unsigned TransformTemplateDepth(unsigned Depth) {
232 return Depth;
233 }
234
235 /// Determine whether the given call argument should be dropped, e.g.,
236 /// because it is a default argument.
237 ///
238 /// Subclasses can provide an alternative implementation of this routine to
239 /// determine which kinds of call arguments get dropped. By default,
240 /// CXXDefaultArgument nodes are dropped (prior to transformation).
241 bool DropCallArgument(Expr *E) {
242 return E->isDefaultArgument();
243 }
244
245 /// Determine whether we should expand a pack expansion with the
246 /// given set of parameter packs into separate arguments by repeatedly
247 /// transforming the pattern.
248 ///
249 /// By default, the transformer never tries to expand pack expansions.
250 /// Subclasses can override this routine to provide different behavior.
251 ///
252 /// \param EllipsisLoc The location of the ellipsis that identifies the
253 /// pack expansion.
254 ///
255 /// \param PatternRange The source range that covers the entire pattern of
256 /// the pack expansion.
257 ///
258 /// \param Unexpanded The set of unexpanded parameter packs within the
259 /// pattern.
260 ///
261 /// \param ShouldExpand Will be set to \c true if the transformer should
262 /// expand the corresponding pack expansions into separate arguments. When
263 /// set, \c NumExpansions must also be set.
264 ///
265 /// \param RetainExpansion Whether the caller should add an unexpanded
266 /// pack expansion after all of the expanded arguments. This is used
267 /// when extending explicitly-specified template argument packs per
268 /// C++0x [temp.arg.explicit]p9.
269 ///
270 /// \param NumExpansions The number of separate arguments that will be in
271 /// the expanded form of the corresponding pack expansion. This is both an
272 /// input and an output parameter, which can be set by the caller if the
273 /// number of expansions is known a priori (e.g., due to a prior substitution)
274 /// and will be set by the callee when the number of expansions is known.
275 /// The callee must set this value when \c ShouldExpand is \c true; it may
276 /// set this value in other cases.
277 ///
278 /// \returns true if an error occurred (e.g., because the parameter packs
279 /// are to be instantiated with arguments of different lengths), false
280 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
281 /// must be set.
282 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
283 SourceRange PatternRange,
284 ArrayRef<UnexpandedParameterPack> Unexpanded,
285 bool &ShouldExpand, bool &RetainExpansion,
286 std::optional<unsigned> &NumExpansions) {
287 ShouldExpand = false;
288 return false;
289 }
290
291 /// "Forget" about the partially-substituted pack template argument,
292 /// when performing an instantiation that must preserve the parameter pack
293 /// use.
294 ///
295 /// This routine is meant to be overridden by the template instantiator.
296 TemplateArgument ForgetPartiallySubstitutedPack() {
297 return TemplateArgument();
298 }
299
300 /// "Remember" the partially-substituted pack template argument
301 /// after performing an instantiation that must preserve the parameter pack
302 /// use.
303 ///
304 /// This routine is meant to be overridden by the template instantiator.
305 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
306
307 /// Note to the derived class when a function parameter pack is
308 /// being expanded.
309 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
310
311 /// Transforms the given type into another type.
312 ///
313 /// By default, this routine transforms a type by creating a
314 /// TypeSourceInfo for it and delegating to the appropriate
315 /// function. This is expensive, but we don't mind, because
316 /// this method is deprecated anyway; all users should be
317 /// switched to storing TypeSourceInfos.
318 ///
319 /// \returns the transformed type.
320 QualType TransformType(QualType T);
321
322 /// Transforms the given type-with-location into a new
323 /// type-with-location.
324 ///
325 /// By default, this routine transforms a type by delegating to the
326 /// appropriate TransformXXXType to build a new type. Subclasses
327 /// may override this function (to take over all type
328 /// transformations) or some set of the TransformXXXType functions
329 /// to alter the transformation.
330 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
331
332 /// Transform the given type-with-location into a new
333 /// type, collecting location information in the given builder
334 /// as necessary.
335 ///
336 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
337
338 /// Transform a type that is permitted to produce a
339 /// DeducedTemplateSpecializationType.
340 ///
341 /// This is used in the (relatively rare) contexts where it is acceptable
342 /// for transformation to produce a class template type with deduced
343 /// template arguments.
344 /// @{
345 QualType TransformTypeWithDeducedTST(QualType T);
346 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
347 /// @}
348
349 /// The reason why the value of a statement is not discarded, if any.
350 enum StmtDiscardKind {
351 SDK_Discarded,
352 SDK_NotDiscarded,
353 SDK_StmtExprResult,
354 };
355
356 /// Transform the given statement.
357 ///
358 /// By default, this routine transforms a statement by delegating to the
359 /// appropriate TransformXXXStmt function to transform a specific kind of
360 /// statement or the TransformExpr() function to transform an expression.
361 /// Subclasses may override this function to transform statements using some
362 /// other mechanism.
363 ///
364 /// \returns the transformed statement.
365 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
366
367 /// Transform the given statement.
368 ///
369 /// By default, this routine transforms a statement by delegating to the
370 /// appropriate TransformOMPXXXClause function to transform a specific kind
371 /// of clause. Subclasses may override this function to transform statements
372 /// using some other mechanism.
373 ///
374 /// \returns the transformed OpenMP clause.
375 OMPClause *TransformOMPClause(OMPClause *S);
376
377 /// Transform the given attribute.
378 ///
379 /// By default, this routine transforms a statement by delegating to the
380 /// appropriate TransformXXXAttr function to transform a specific kind
381 /// of attribute. Subclasses may override this function to transform
382 /// attributed statements/types using some other mechanism.
383 ///
384 /// \returns the transformed attribute
385 const Attr *TransformAttr(const Attr *S);
386
387 // Transform the given statement attribute.
388 //
389 // Delegates to the appropriate TransformXXXAttr function to transform a
390 // specific kind of statement attribute. Unlike the non-statement taking
391 // version of this, this implements all attributes, not just pragmas.
392 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
393 const Attr *A);
394
395 // Transform the specified attribute.
396 //
397 // Subclasses should override the transformation of attributes with a pragma
398 // spelling to transform expressions stored within the attribute.
399 //
400 // \returns the transformed attribute.
401#define ATTR(X) \
402 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
403#include "clang/Basic/AttrList.inc"
404
405 // Transform the specified attribute.
406 //
407 // Subclasses should override the transformation of attributes to do
408 // transformation and checking of statement attributes. By default, this
409 // delegates to the non-statement taking version.
410 //
411 // \returns the transformed attribute.
412#define ATTR(X) \
413 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
414 const X##Attr *A) { \
415 return getDerived().Transform##X##Attr(A); \
416 }
417#include "clang/Basic/AttrList.inc"
418
419 /// Transform the given expression.
420 ///
421 /// By default, this routine transforms an expression by delegating to the
422 /// appropriate TransformXXXExpr function to build a new expression.
423 /// Subclasses may override this function to transform expressions using some
424 /// other mechanism.
425 ///
426 /// \returns the transformed expression.
427 ExprResult TransformExpr(Expr *E);
428
429 /// Transform the given initializer.
430 ///
431 /// By default, this routine transforms an initializer by stripping off the
432 /// semantic nodes added by initialization, then passing the result to
433 /// TransformExpr or TransformExprs.
434 ///
435 /// \returns the transformed initializer.
436 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
437
438 /// Transform the given list of expressions.
439 ///
440 /// This routine transforms a list of expressions by invoking
441 /// \c TransformExpr() for each subexpression. However, it also provides
442 /// support for variadic templates by expanding any pack expansions (if the
443 /// derived class permits such expansion) along the way. When pack expansions
444 /// are present, the number of outputs may not equal the number of inputs.
445 ///
446 /// \param Inputs The set of expressions to be transformed.
447 ///
448 /// \param NumInputs The number of expressions in \c Inputs.
449 ///
450 /// \param IsCall If \c true, then this transform is being performed on
451 /// function-call arguments, and any arguments that should be dropped, will
452 /// be.
453 ///
454 /// \param Outputs The transformed input expressions will be added to this
455 /// vector.
456 ///
457 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
458 /// due to transformation.
459 ///
460 /// \returns true if an error occurred, false otherwise.
461 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
462 SmallVectorImpl<Expr *> &Outputs,
463 bool *ArgChanged = nullptr);
464
465 /// Transform the given declaration, which is referenced from a type
466 /// or expression.
467 ///
468 /// By default, acts as the identity function on declarations, unless the
469 /// transformer has had to transform the declaration itself. Subclasses
470 /// may override this function to provide alternate behavior.
471 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
472 llvm::DenseMap<Decl *, Decl *>::iterator Known
473 = TransformedLocalDecls.find(D);
474 if (Known != TransformedLocalDecls.end())
475 return Known->second;
476
477 return D;
478 }
479
480 /// Transform the specified condition.
481 ///
482 /// By default, this transforms the variable and expression and rebuilds
483 /// the condition.
484 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
485 Expr *Expr,
486 Sema::ConditionKind Kind);
487
488 /// Transform the attributes associated with the given declaration and
489 /// place them on the new declaration.
490 ///
491 /// By default, this operation does nothing. Subclasses may override this
492 /// behavior to transform attributes.
493 void transformAttrs(Decl *Old, Decl *New) { }
494
495 /// Note that a local declaration has been transformed by this
496 /// transformer.
497 ///
498 /// Local declarations are typically transformed via a call to
499 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
500 /// the transformer itself has to transform the declarations. This routine
501 /// can be overridden by a subclass that keeps track of such mappings.
502 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
503 assert(New.size() == 1 &&
504 "must override transformedLocalDecl if performing pack expansion");
505 TransformedLocalDecls[Old] = New.front();
506 }
507
508 /// Transform the definition of the given declaration.
509 ///
510 /// By default, invokes TransformDecl() to transform the declaration.
511 /// Subclasses may override this function to provide alternate behavior.
512 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
513 return getDerived().TransformDecl(Loc, D);
514 }
515
516 /// Transform the given declaration, which was the first part of a
517 /// nested-name-specifier in a member access expression.
518 ///
519 /// This specific declaration transformation only applies to the first
520 /// identifier in a nested-name-specifier of a member access expression, e.g.,
521 /// the \c T in \c x->T::member
522 ///
523 /// By default, invokes TransformDecl() to transform the declaration.
524 /// Subclasses may override this function to provide alternate behavior.
525 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
526 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
527 }
528
529 /// Transform the set of declarations in an OverloadExpr.
530 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
531 LookupResult &R);
532
533 /// Transform the given nested-name-specifier with source-location
534 /// information.
535 ///
536 /// By default, transforms all of the types and declarations within the
537 /// nested-name-specifier. Subclasses may override this function to provide
538 /// alternate behavior.
539 NestedNameSpecifierLoc
540 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
541 QualType ObjectType = QualType(),
542 NamedDecl *FirstQualifierInScope = nullptr);
543
544 /// Transform the given declaration name.
545 ///
546 /// By default, transforms the types of conversion function, constructor,
547 /// and destructor names and then (if needed) rebuilds the declaration name.
548 /// Identifiers and selectors are returned unmodified. Subclasses may
549 /// override this function to provide alternate behavior.
550 DeclarationNameInfo
551 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
552
553 bool TransformRequiresExprRequirements(
554 ArrayRef<concepts::Requirement *> Reqs,
555 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
556 concepts::TypeRequirement *
557 TransformTypeRequirement(concepts::TypeRequirement *Req);
558 concepts::ExprRequirement *
559 TransformExprRequirement(concepts::ExprRequirement *Req);
560 concepts::NestedRequirement *
561 TransformNestedRequirement(concepts::NestedRequirement *Req);
562
563 /// Transform the given template name.
564 ///
565 /// \param SS The nested-name-specifier that qualifies the template
566 /// name. This nested-name-specifier must already have been transformed.
567 ///
568 /// \param Name The template name to transform.
569 ///
570 /// \param NameLoc The source location of the template name.
571 ///
572 /// \param ObjectType If we're translating a template name within a member
573 /// access expression, this is the type of the object whose member template
574 /// is being referenced.
575 ///
576 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
577 /// also refers to a name within the current (lexical) scope, this is the
578 /// declaration it refers to.
579 ///
580 /// By default, transforms the template name by transforming the declarations
581 /// and nested-name-specifiers that occur within the template name.
582 /// Subclasses may override this function to provide alternate behavior.
583 TemplateName
584 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
585 SourceLocation NameLoc,
586 QualType ObjectType = QualType(),
587 NamedDecl *FirstQualifierInScope = nullptr,
588 bool AllowInjectedClassName = false);
589
590 /// Transform the given template argument.
591 ///
592 /// By default, this operation transforms the type, expression, or
593 /// declaration stored within the template argument and constructs a
594 /// new template argument from the transformed result. Subclasses may
595 /// override this function to provide alternate behavior.
596 ///
597 /// Returns true if there was an error.
598 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
599 TemplateArgumentLoc &Output,
600 bool Uneval = false);
601
602 /// Transform the given set of template arguments.
603 ///
604 /// By default, this operation transforms all of the template arguments
605 /// in the input set using \c TransformTemplateArgument(), and appends
606 /// the transformed arguments to the output list.
607 ///
608 /// Note that this overload of \c TransformTemplateArguments() is merely
609 /// a convenience function. Subclasses that wish to override this behavior
610 /// should override the iterator-based member template version.
611 ///
612 /// \param Inputs The set of template arguments to be transformed.
613 ///
614 /// \param NumInputs The number of template arguments in \p Inputs.
615 ///
616 /// \param Outputs The set of transformed template arguments output by this
617 /// routine.
618 ///
619 /// Returns true if an error occurred.
620 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
621 unsigned NumInputs,
622 TemplateArgumentListInfo &Outputs,
623 bool Uneval = false) {
624 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
625 Uneval);
626 }
627
628 /// Transform the given set of template arguments.
629 ///
630 /// By default, this operation transforms all of the template arguments
631 /// in the input set using \c TransformTemplateArgument(), and appends
632 /// the transformed arguments to the output list.
633 ///
634 /// \param First An iterator to the first template argument.
635 ///
636 /// \param Last An iterator one step past the last template argument.
637 ///
638 /// \param Outputs The set of transformed template arguments output by this
639 /// routine.
640 ///
641 /// Returns true if an error occurred.
642 template<typename InputIterator>
643 bool TransformTemplateArguments(InputIterator First,
644 InputIterator Last,
645 TemplateArgumentListInfo &Outputs,
646 bool Uneval = false);
647
648 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
649 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
650 TemplateArgumentLoc &ArgLoc);
651
652 /// Fakes up a TypeSourceInfo for a type.
653 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
654 return SemaRef.Context.getTrivialTypeSourceInfo(T,
655 Loc: getDerived().getBaseLocation());
656 }
657
658#define ABSTRACT_TYPELOC(CLASS, PARENT)
659#define TYPELOC(CLASS, PARENT) \
660 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
661#include "clang/AST/TypeLocNodes.def"
662
663 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
664 TemplateTypeParmTypeLoc TL,
665 bool SuppressObjCLifetime);
666 QualType
667 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
668 SubstTemplateTypeParmPackTypeLoc TL,
669 bool SuppressObjCLifetime);
670
671 template<typename Fn>
672 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
673 FunctionProtoTypeLoc TL,
674 CXXRecordDecl *ThisContext,
675 Qualifiers ThisTypeQuals,
676 Fn TransformExceptionSpec);
677
678 template <typename Fn>
679 QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL,
680 Fn TransformModifiedType);
681
682 bool TransformExceptionSpec(SourceLocation Loc,
683 FunctionProtoType::ExceptionSpecInfo &ESI,
684 SmallVectorImpl<QualType> &Exceptions,
685 bool &Changed);
686
687 StmtResult TransformSEHHandler(Stmt *Handler);
688
689 QualType
690 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
691 TemplateSpecializationTypeLoc TL,
692 TemplateName Template);
693
694 QualType
695 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
696 DependentTemplateSpecializationTypeLoc TL,
697 TemplateName Template,
698 CXXScopeSpec &SS);
699
700 QualType TransformDependentTemplateSpecializationType(
701 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
702 NestedNameSpecifierLoc QualifierLoc);
703
704 /// Transforms the parameters of a function type into the
705 /// given vectors.
706 ///
707 /// The result vectors should be kept in sync; null entries in the
708 /// variables vector are acceptable.
709 ///
710 /// LastParamTransformed, if non-null, will be set to the index of the last
711 /// parameter on which transfromation was started. In the event of an error,
712 /// this will contain the parameter which failed to instantiate.
713 ///
714 /// Return true on error.
715 bool TransformFunctionTypeParams(
716 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
717 const QualType *ParamTypes,
718 const FunctionProtoType::ExtParameterInfo *ParamInfos,
719 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
720 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
721
722 bool TransformFunctionTypeParams(
723 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
724 const QualType *ParamTypes,
725 const FunctionProtoType::ExtParameterInfo *ParamInfos,
726 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
727 Sema::ExtParameterInfoBuilder &PInfos) {
728 return getDerived().TransformFunctionTypeParams(
729 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
730 }
731
732 /// Transforms the parameters of a requires expresison into the given vectors.
733 ///
734 /// The result vectors should be kept in sync; null entries in the
735 /// variables vector are acceptable.
736 ///
737 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
738 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
739 /// which are cases where transformation shouldn't continue.
740 ExprResult TransformRequiresTypeParams(
741 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
742 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
743 SmallVectorImpl<QualType> &PTypes,
744 SmallVectorImpl<ParmVarDecl *> &TransParams,
745 Sema::ExtParameterInfoBuilder &PInfos) {
746 if (getDerived().TransformFunctionTypeParams(
747 KWLoc, Params, /*ParamTypes=*/nullptr,
748 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
749 return ExprError();
750
751 return ExprResult{};
752 }
753
754 /// Transforms a single function-type parameter. Return null
755 /// on error.
756 ///
757 /// \param indexAdjustment - A number to add to the parameter's
758 /// scope index; can be negative
759 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
760 int indexAdjustment,
761 std::optional<unsigned> NumExpansions,
762 bool ExpectParameterPack);
763
764 /// Transform the body of a lambda-expression.
765 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
766 /// Alternative implementation of TransformLambdaBody that skips transforming
767 /// the body.
768 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
769
770 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
771
772 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
773 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
774
775 TemplateParameterList *TransformTemplateParameterList(
776 TemplateParameterList *TPL) {
777 return TPL;
778 }
779
780 ExprResult TransformAddressOfOperand(Expr *E);
781
782 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
783 bool IsAddressOfOperand,
784 TypeSourceInfo **RecoveryTSI);
785
786 ExprResult TransformParenDependentScopeDeclRefExpr(
787 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
788 TypeSourceInfo **RecoveryTSI);
789
790 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
791
792// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
793// amount of stack usage with clang.
794#define STMT(Node, Parent) \
795 LLVM_ATTRIBUTE_NOINLINE \
796 StmtResult Transform##Node(Node *S);
797#define VALUESTMT(Node, Parent) \
798 LLVM_ATTRIBUTE_NOINLINE \
799 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
800#define EXPR(Node, Parent) \
801 LLVM_ATTRIBUTE_NOINLINE \
802 ExprResult Transform##Node(Node *E);
803#define ABSTRACT_STMT(Stmt)
804#include "clang/AST/StmtNodes.inc"
805
806#define GEN_CLANG_CLAUSE_CLASS
807#define CLAUSE_CLASS(Enum, Str, Class) \
808 LLVM_ATTRIBUTE_NOINLINE \
809 OMPClause *Transform##Class(Class *S);
810#include "llvm/Frontend/OpenMP/OMP.inc"
811
812 /// Build a new qualified type given its unqualified type and type location.
813 ///
814 /// By default, this routine adds type qualifiers only to types that can
815 /// have qualifiers, and silently suppresses those qualifiers that are not
816 /// permitted. Subclasses may override this routine to provide different
817 /// behavior.
818 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
819
820 /// Build a new pointer type given its pointee type.
821 ///
822 /// By default, performs semantic analysis when building the pointer type.
823 /// Subclasses may override this routine to provide different behavior.
824 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
825
826 /// Build a new block pointer type given its pointee type.
827 ///
828 /// By default, performs semantic analysis when building the block pointer
829 /// type. Subclasses may override this routine to provide different behavior.
830 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
831
832 /// Build a new reference type given the type it references.
833 ///
834 /// By default, performs semantic analysis when building the
835 /// reference type. Subclasses may override this routine to provide
836 /// different behavior.
837 ///
838 /// \param LValue whether the type was written with an lvalue sigil
839 /// or an rvalue sigil.
840 QualType RebuildReferenceType(QualType ReferentType,
841 bool LValue,
842 SourceLocation Sigil);
843
844 /// Build a new member pointer type given the pointee type and the
845 /// class type it refers into.
846 ///
847 /// By default, performs semantic analysis when building the member pointer
848 /// type. Subclasses may override this routine to provide different behavior.
849 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
850 SourceLocation Sigil);
851
852 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
853 SourceLocation ProtocolLAngleLoc,
854 ArrayRef<ObjCProtocolDecl *> Protocols,
855 ArrayRef<SourceLocation> ProtocolLocs,
856 SourceLocation ProtocolRAngleLoc);
857
858 /// Build an Objective-C object type.
859 ///
860 /// By default, performs semantic analysis when building the object type.
861 /// Subclasses may override this routine to provide different behavior.
862 QualType RebuildObjCObjectType(QualType BaseType,
863 SourceLocation Loc,
864 SourceLocation TypeArgsLAngleLoc,
865 ArrayRef<TypeSourceInfo *> TypeArgs,
866 SourceLocation TypeArgsRAngleLoc,
867 SourceLocation ProtocolLAngleLoc,
868 ArrayRef<ObjCProtocolDecl *> Protocols,
869 ArrayRef<SourceLocation> ProtocolLocs,
870 SourceLocation ProtocolRAngleLoc);
871
872 /// Build a new Objective-C object pointer type given the pointee type.
873 ///
874 /// By default, directly builds the pointer type, with no additional semantic
875 /// analysis.
876 QualType RebuildObjCObjectPointerType(QualType PointeeType,
877 SourceLocation Star);
878
879 /// Build a new array type given the element type, size
880 /// modifier, size of the array (if known), size expression, and index type
881 /// qualifiers.
882 ///
883 /// By default, performs semantic analysis when building the array type.
884 /// Subclasses may override this routine to provide different behavior.
885 /// Also by default, all of the other Rebuild*Array
886 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
887 const llvm::APInt *Size, Expr *SizeExpr,
888 unsigned IndexTypeQuals, SourceRange BracketsRange);
889
890 /// Build a new constant array type given the element type, size
891 /// modifier, (known) size of the array, and index type qualifiers.
892 ///
893 /// By default, performs semantic analysis when building the array type.
894 /// Subclasses may override this routine to provide different behavior.
895 QualType RebuildConstantArrayType(QualType ElementType,
896 ArraySizeModifier SizeMod,
897 const llvm::APInt &Size, Expr *SizeExpr,
898 unsigned IndexTypeQuals,
899 SourceRange BracketsRange);
900
901 /// Build a new incomplete array type given the element type, size
902 /// modifier, and index type qualifiers.
903 ///
904 /// By default, performs semantic analysis when building the array type.
905 /// Subclasses may override this routine to provide different behavior.
906 QualType RebuildIncompleteArrayType(QualType ElementType,
907 ArraySizeModifier SizeMod,
908 unsigned IndexTypeQuals,
909 SourceRange BracketsRange);
910
911 /// Build a new variable-length array type given the element type,
912 /// size modifier, size expression, and index type qualifiers.
913 ///
914 /// By default, performs semantic analysis when building the array type.
915 /// Subclasses may override this routine to provide different behavior.
916 QualType RebuildVariableArrayType(QualType ElementType,
917 ArraySizeModifier SizeMod, Expr *SizeExpr,
918 unsigned IndexTypeQuals,
919 SourceRange BracketsRange);
920
921 /// Build a new dependent-sized array type given the element type,
922 /// size modifier, size expression, and index type qualifiers.
923 ///
924 /// By default, performs semantic analysis when building the array type.
925 /// Subclasses may override this routine to provide different behavior.
926 QualType RebuildDependentSizedArrayType(QualType ElementType,
927 ArraySizeModifier SizeMod,
928 Expr *SizeExpr,
929 unsigned IndexTypeQuals,
930 SourceRange BracketsRange);
931
932 /// Build a new vector type given the element type and
933 /// number of elements.
934 ///
935 /// By default, performs semantic analysis when building the vector type.
936 /// Subclasses may override this routine to provide different behavior.
937 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
938 VectorKind VecKind);
939
940 /// Build a new potentially dependently-sized extended vector type
941 /// given the element type and number of elements.
942 ///
943 /// By default, performs semantic analysis when building the vector type.
944 /// Subclasses may override this routine to provide different behavior.
945 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
946 SourceLocation AttributeLoc, VectorKind);
947
948 /// Build a new extended vector type given the element type and
949 /// number of elements.
950 ///
951 /// By default, performs semantic analysis when building the vector type.
952 /// Subclasses may override this routine to provide different behavior.
953 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
954 SourceLocation AttributeLoc);
955
956 /// Build a new potentially dependently-sized extended vector type
957 /// given the element type and number of elements.
958 ///
959 /// By default, performs semantic analysis when building the vector type.
960 /// Subclasses may override this routine to provide different behavior.
961 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
962 Expr *SizeExpr,
963 SourceLocation AttributeLoc);
964
965 /// Build a new matrix type given the element type and dimensions.
966 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
967 unsigned NumColumns);
968
969 /// Build a new matrix type given the type and dependently-defined
970 /// dimensions.
971 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
972 Expr *ColumnExpr,
973 SourceLocation AttributeLoc);
974
975 /// Build a new DependentAddressSpaceType or return the pointee
976 /// type variable with the correct address space (retrieved from
977 /// AddrSpaceExpr) applied to it. The former will be returned in cases
978 /// where the address space remains dependent.
979 ///
980 /// By default, performs semantic analysis when building the type with address
981 /// space applied. Subclasses may override this routine to provide different
982 /// behavior.
983 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
984 Expr *AddrSpaceExpr,
985 SourceLocation AttributeLoc);
986
987 /// Build a new function type.
988 ///
989 /// By default, performs semantic analysis when building the function type.
990 /// Subclasses may override this routine to provide different behavior.
991 QualType RebuildFunctionProtoType(QualType T,
992 MutableArrayRef<QualType> ParamTypes,
993 const FunctionProtoType::ExtProtoInfo &EPI);
994
995 /// Build a new unprototyped function type.
996 QualType RebuildFunctionNoProtoType(QualType ResultType);
997
998 /// Rebuild an unresolved typename type, given the decl that
999 /// the UnresolvedUsingTypenameDecl was transformed to.
1000 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1001
1002 /// Build a new type found via an alias.
1003 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1004 return SemaRef.Context.getUsingType(Found, Underlying);
1005 }
1006
1007 /// Build a new typedef type.
1008 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1009 return SemaRef.Context.getTypeDeclType(Typedef);
1010 }
1011
1012 /// Build a new MacroDefined type.
1013 QualType RebuildMacroQualifiedType(QualType T,
1014 const IdentifierInfo *MacroII) {
1015 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1016 }
1017
1018 /// Build a new class/struct/union type.
1019 QualType RebuildRecordType(RecordDecl *Record) {
1020 return SemaRef.Context.getTypeDeclType(Record);
1021 }
1022
1023 /// Build a new Enum type.
1024 QualType RebuildEnumType(EnumDecl *Enum) {
1025 return SemaRef.Context.getTypeDeclType(Enum);
1026 }
1027
1028 /// Build a new typeof(expr) type.
1029 ///
1030 /// By default, performs semantic analysis when building the typeof type.
1031 /// Subclasses may override this routine to provide different behavior.
1032 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1033 TypeOfKind Kind);
1034
1035 /// Build a new typeof(type) type.
1036 ///
1037 /// By default, builds a new TypeOfType with the given underlying type.
1038 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1039
1040 /// Build a new unary transform type.
1041 QualType RebuildUnaryTransformType(QualType BaseType,
1042 UnaryTransformType::UTTKind UKind,
1043 SourceLocation Loc);
1044
1045 /// Build a new C++11 decltype type.
1046 ///
1047 /// By default, performs semantic analysis when building the decltype type.
1048 /// Subclasses may override this routine to provide different behavior.
1049 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1050
1051 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1052 SourceLocation Loc,
1053 SourceLocation EllipsisLoc,
1054 bool FullySubstituted,
1055 ArrayRef<QualType> Expansions = {});
1056
1057 /// Build a new C++11 auto type.
1058 ///
1059 /// By default, builds a new AutoType with the given deduced type.
1060 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1061 ConceptDecl *TypeConstraintConcept,
1062 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1063 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1064 // which has been deduced to a dependent type into an undeduced 'auto', so
1065 // that we'll retry deduction after the transformation.
1066 return SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword,
1067 /*IsDependent*/ IsDependent: false, /*IsPack=*/IsPack: false,
1068 TypeConstraintConcept,
1069 TypeConstraintArgs);
1070 }
1071
1072 /// By default, builds a new DeducedTemplateSpecializationType with the given
1073 /// deduced type.
1074 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1075 QualType Deduced) {
1076 return SemaRef.Context.getDeducedTemplateSpecializationType(
1077 Template, DeducedType: Deduced, /*IsDependent*/ IsDependent: false);
1078 }
1079
1080 /// Build a new template specialization type.
1081 ///
1082 /// By default, performs semantic analysis when building the template
1083 /// specialization type. Subclasses may override this routine to provide
1084 /// different behavior.
1085 QualType RebuildTemplateSpecializationType(TemplateName Template,
1086 SourceLocation TemplateLoc,
1087 TemplateArgumentListInfo &Args);
1088
1089 /// Build a new parenthesized type.
1090 ///
1091 /// By default, builds a new ParenType type from the inner type.
1092 /// Subclasses may override this routine to provide different behavior.
1093 QualType RebuildParenType(QualType InnerType) {
1094 return SemaRef.BuildParenType(T: InnerType);
1095 }
1096
1097 /// Build a new qualified name type.
1098 ///
1099 /// By default, builds a new ElaboratedType type from the keyword,
1100 /// the nested-name-specifier and the named type.
1101 /// Subclasses may override this routine to provide different behavior.
1102 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1103 ElaboratedTypeKeyword Keyword,
1104 NestedNameSpecifierLoc QualifierLoc,
1105 QualType Named) {
1106 return SemaRef.Context.getElaboratedType(Keyword,
1107 NNS: QualifierLoc.getNestedNameSpecifier(),
1108 NamedType: Named);
1109 }
1110
1111 /// Build a new typename type that refers to a template-id.
1112 ///
1113 /// By default, builds a new DependentNameType type from the
1114 /// nested-name-specifier and the given type. Subclasses may override
1115 /// this routine to provide different behavior.
1116 QualType RebuildDependentTemplateSpecializationType(
1117 ElaboratedTypeKeyword Keyword,
1118 NestedNameSpecifierLoc QualifierLoc,
1119 SourceLocation TemplateKWLoc,
1120 const IdentifierInfo *Name,
1121 SourceLocation NameLoc,
1122 TemplateArgumentListInfo &Args,
1123 bool AllowInjectedClassName) {
1124 // Rebuild the template name.
1125 // TODO: avoid TemplateName abstraction
1126 CXXScopeSpec SS;
1127 SS.Adopt(Other: QualifierLoc);
1128 TemplateName InstName = getDerived().RebuildTemplateName(
1129 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1130 AllowInjectedClassName);
1131
1132 if (InstName.isNull())
1133 return QualType();
1134
1135 // If it's still dependent, make a dependent specialization.
1136 if (InstName.getAsDependentTemplateName())
1137 return SemaRef.Context.getDependentTemplateSpecializationType(
1138 Keyword, NNS: QualifierLoc.getNestedNameSpecifier(), Name,
1139 Args: Args.arguments());
1140
1141 // Otherwise, make an elaborated type wrapping a non-dependent
1142 // specialization.
1143 QualType T =
1144 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1145 if (T.isNull())
1146 return QualType();
1147 return SemaRef.Context.getElaboratedType(
1148 Keyword, NNS: QualifierLoc.getNestedNameSpecifier(), NamedType: T);
1149 }
1150
1151 /// Build a new typename type that refers to an identifier.
1152 ///
1153 /// By default, performs semantic analysis when building the typename type
1154 /// (or elaborated type). Subclasses may override this routine to provide
1155 /// different behavior.
1156 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1157 SourceLocation KeywordLoc,
1158 NestedNameSpecifierLoc QualifierLoc,
1159 const IdentifierInfo *Id,
1160 SourceLocation IdLoc,
1161 bool DeducedTSTContext) {
1162 CXXScopeSpec SS;
1163 SS.Adopt(Other: QualifierLoc);
1164
1165 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1166 // If the name is still dependent, just build a new dependent name type.
1167 if (!SemaRef.computeDeclContext(SS))
1168 return SemaRef.Context.getDependentNameType(Keyword,
1169 NNS: QualifierLoc.getNestedNameSpecifier(),
1170 Name: Id);
1171 }
1172
1173 if (Keyword == ElaboratedTypeKeyword::None ||
1174 Keyword == ElaboratedTypeKeyword::Typename) {
1175 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1176 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1177 }
1178
1179 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1180
1181 // We had a dependent elaborated-type-specifier that has been transformed
1182 // into a non-dependent elaborated-type-specifier. Find the tag we're
1183 // referring to.
1184 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1185 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1186 if (!DC)
1187 return QualType();
1188
1189 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1190 return QualType();
1191
1192 TagDecl *Tag = nullptr;
1193 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1194 switch (Result.getResultKind()) {
1195 case LookupResult::NotFound:
1196 case LookupResult::NotFoundInCurrentInstantiation:
1197 break;
1198
1199 case LookupResult::Found:
1200 Tag = Result.getAsSingle<TagDecl>();
1201 break;
1202
1203 case LookupResult::FoundOverloaded:
1204 case LookupResult::FoundUnresolvedValue:
1205 llvm_unreachable("Tag lookup cannot find non-tags");
1206
1207 case LookupResult::Ambiguous:
1208 // Let the LookupResult structure handle ambiguities.
1209 return QualType();
1210 }
1211
1212 if (!Tag) {
1213 // Check where the name exists but isn't a tag type and use that to emit
1214 // better diagnostics.
1215 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1216 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1217 switch (Result.getResultKind()) {
1218 case LookupResult::Found:
1219 case LookupResult::FoundOverloaded:
1220 case LookupResult::FoundUnresolvedValue: {
1221 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1222 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1223 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1224 << SomeDecl << NTK << llvm::to_underlying(Kind);
1225 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1226 break;
1227 }
1228 default:
1229 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1230 << llvm::to_underlying(Kind) << Id << DC
1231 << QualifierLoc.getSourceRange();
1232 break;
1233 }
1234 return QualType();
1235 }
1236
1237 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1238 NewTagLoc: IdLoc, Name: Id)) {
1239 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1240 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1241 return QualType();
1242 }
1243
1244 // Build the elaborated-type-specifier type.
1245 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1246 return SemaRef.Context.getElaboratedType(Keyword,
1247 NNS: QualifierLoc.getNestedNameSpecifier(),
1248 NamedType: T);
1249 }
1250
1251 /// Build a new pack expansion type.
1252 ///
1253 /// By default, builds a new PackExpansionType type from the given pattern.
1254 /// Subclasses may override this routine to provide different behavior.
1255 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1256 SourceLocation EllipsisLoc,
1257 std::optional<unsigned> NumExpansions) {
1258 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1259 NumExpansions);
1260 }
1261
1262 /// Build a new atomic type given its value type.
1263 ///
1264 /// By default, performs semantic analysis when building the atomic type.
1265 /// Subclasses may override this routine to provide different behavior.
1266 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1267
1268 /// Build a new pipe type given its value type.
1269 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1270 bool isReadPipe);
1271
1272 /// Build a bit-precise int given its value type.
1273 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1274 SourceLocation Loc);
1275
1276 /// Build a dependent bit-precise int given its value type.
1277 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1278 SourceLocation Loc);
1279
1280 /// Build a new template name given a nested name specifier, a flag
1281 /// indicating whether the "template" keyword was provided, and the template
1282 /// that the template name refers to.
1283 ///
1284 /// By default, builds the new template name directly. Subclasses may override
1285 /// this routine to provide different behavior.
1286 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1287 bool TemplateKW,
1288 TemplateDecl *Template);
1289
1290 /// Build a new template name given a nested name specifier and the
1291 /// name that is referred to as a template.
1292 ///
1293 /// By default, performs semantic analysis to determine whether the name can
1294 /// be resolved to a specific template, then builds the appropriate kind of
1295 /// template name. Subclasses may override this routine to provide different
1296 /// behavior.
1297 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1298 SourceLocation TemplateKWLoc,
1299 const IdentifierInfo &Name,
1300 SourceLocation NameLoc, QualType ObjectType,
1301 NamedDecl *FirstQualifierInScope,
1302 bool AllowInjectedClassName);
1303
1304 /// Build a new template name given a nested name specifier and the
1305 /// overloaded operator name that is referred to as a template.
1306 ///
1307 /// By default, performs semantic analysis to determine whether the name can
1308 /// be resolved to a specific template, then builds the appropriate kind of
1309 /// template name. Subclasses may override this routine to provide different
1310 /// behavior.
1311 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1312 SourceLocation TemplateKWLoc,
1313 OverloadedOperatorKind Operator,
1314 SourceLocation NameLoc, QualType ObjectType,
1315 bool AllowInjectedClassName);
1316
1317 /// Build a new template name given a template template parameter pack
1318 /// and the
1319 ///
1320 /// By default, performs semantic analysis to determine whether the name can
1321 /// be resolved to a specific template, then builds the appropriate kind of
1322 /// template name. Subclasses may override this routine to provide different
1323 /// behavior.
1324 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1325 Decl *AssociatedDecl, unsigned Index,
1326 bool Final) {
1327 return getSema().Context.getSubstTemplateTemplateParmPack(
1328 ArgPack, AssociatedDecl, Index, Final);
1329 }
1330
1331 /// Build a new compound statement.
1332 ///
1333 /// By default, performs semantic analysis to build the new statement.
1334 /// Subclasses may override this routine to provide different behavior.
1335 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1336 MultiStmtArg Statements,
1337 SourceLocation RBraceLoc,
1338 bool IsStmtExpr) {
1339 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1340 IsStmtExpr);
1341 }
1342
1343 /// Build a new case 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 RebuildCaseStmt(SourceLocation CaseLoc,
1348 Expr *LHS,
1349 SourceLocation EllipsisLoc,
1350 Expr *RHS,
1351 SourceLocation ColonLoc) {
1352 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1353 ColonLoc);
1354 }
1355
1356 /// Attach the body to a new case statement.
1357 ///
1358 /// By default, performs semantic analysis to build the new statement.
1359 /// Subclasses may override this routine to provide different behavior.
1360 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1361 getSema().ActOnCaseStmtBody(S, Body);
1362 return S;
1363 }
1364
1365 /// Build a new default statement.
1366 ///
1367 /// By default, performs semantic analysis to build the new statement.
1368 /// Subclasses may override this routine to provide different behavior.
1369 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1370 SourceLocation ColonLoc,
1371 Stmt *SubStmt) {
1372 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1373 /*CurScope=*/nullptr);
1374 }
1375
1376 /// Build a new label statement.
1377 ///
1378 /// By default, performs semantic analysis to build the new statement.
1379 /// Subclasses may override this routine to provide different behavior.
1380 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1381 SourceLocation ColonLoc, Stmt *SubStmt) {
1382 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1383 }
1384
1385 /// Build a new attributed statement.
1386 ///
1387 /// By default, performs semantic analysis to build the new statement.
1388 /// Subclasses may override this routine to provide different behavior.
1389 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1390 ArrayRef<const Attr *> Attrs,
1391 Stmt *SubStmt) {
1392 if (SemaRef.CheckRebuiltStmtAttributes(Attrs: Attrs))
1393 return StmtError();
1394 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs: Attrs, SubStmt);
1395 }
1396
1397 /// Build a new "if" 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 RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1402 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1403 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1404 SourceLocation ElseLoc, Stmt *Else) {
1405 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1406 Then, ElseLoc, Else);
1407 }
1408
1409 /// Start building a new switch 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 RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1414 SourceLocation LParenLoc, Stmt *Init,
1415 Sema::ConditionResult Cond,
1416 SourceLocation RParenLoc) {
1417 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1418 RParenLoc);
1419 }
1420
1421 /// Attach the body to the 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 RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1426 Stmt *Switch, Stmt *Body) {
1427 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1428 }
1429
1430 /// Build a new while statement.
1431 ///
1432 /// By default, performs semantic analysis to build the new statement.
1433 /// Subclasses may override this routine to provide different behavior.
1434 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1435 Sema::ConditionResult Cond,
1436 SourceLocation RParenLoc, Stmt *Body) {
1437 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1438 }
1439
1440 /// Build a new do-while statement.
1441 ///
1442 /// By default, performs semantic analysis to build the new statement.
1443 /// Subclasses may override this routine to provide different behavior.
1444 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1445 SourceLocation WhileLoc, SourceLocation LParenLoc,
1446 Expr *Cond, SourceLocation RParenLoc) {
1447 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1448 Cond, RParenLoc);
1449 }
1450
1451 /// Build a new for statement.
1452 ///
1453 /// By default, performs semantic analysis to build the new statement.
1454 /// Subclasses may override this routine to provide different behavior.
1455 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1456 Stmt *Init, Sema::ConditionResult Cond,
1457 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1458 Stmt *Body) {
1459 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1460 Inc, RParenLoc, Body);
1461 }
1462
1463 /// Build a new goto 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 RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1468 LabelDecl *Label) {
1469 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1470 }
1471
1472 /// Build a new indirect goto statement.
1473 ///
1474 /// By default, performs semantic analysis to build the new statement.
1475 /// Subclasses may override this routine to provide different behavior.
1476 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1477 SourceLocation StarLoc,
1478 Expr *Target) {
1479 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1480 }
1481
1482 /// Build a new return statement.
1483 ///
1484 /// By default, performs semantic analysis to build the new statement.
1485 /// Subclasses may override this routine to provide different behavior.
1486 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1487 return getSema().BuildReturnStmt(ReturnLoc, Result);
1488 }
1489
1490 /// Build a new declaration statement.
1491 ///
1492 /// By default, performs semantic analysis to build the new statement.
1493 /// Subclasses may override this routine to provide different behavior.
1494 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1495 SourceLocation StartLoc, SourceLocation EndLoc) {
1496 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1497 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1498 }
1499
1500 /// Build a new inline asm statement.
1501 ///
1502 /// By default, performs semantic analysis to build the new statement.
1503 /// Subclasses may override this routine to provide different behavior.
1504 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1505 bool IsVolatile, unsigned NumOutputs,
1506 unsigned NumInputs, IdentifierInfo **Names,
1507 MultiExprArg Constraints, MultiExprArg Exprs,
1508 Expr *AsmString, MultiExprArg Clobbers,
1509 unsigned NumLabels,
1510 SourceLocation RParenLoc) {
1511 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1512 NumInputs, Names, Constraints, Exprs,
1513 AsmString, Clobbers, NumLabels, RParenLoc);
1514 }
1515
1516 /// Build a new MS style inline asm statement.
1517 ///
1518 /// By default, performs semantic analysis to build the new statement.
1519 /// Subclasses may override this routine to provide different behavior.
1520 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1521 ArrayRef<Token> AsmToks,
1522 StringRef AsmString,
1523 unsigned NumOutputs, unsigned NumInputs,
1524 ArrayRef<StringRef> Constraints,
1525 ArrayRef<StringRef> Clobbers,
1526 ArrayRef<Expr*> Exprs,
1527 SourceLocation EndLoc) {
1528 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1529 NumOutputs, NumInputs,
1530 Constraints, Clobbers, Exprs, EndLoc);
1531 }
1532
1533 /// Build a new co_return statement.
1534 ///
1535 /// By default, performs semantic analysis to build the new statement.
1536 /// Subclasses may override this routine to provide different behavior.
1537 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1538 bool IsImplicit) {
1539 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1540 }
1541
1542 /// Build a new co_await expression.
1543 ///
1544 /// By default, performs semantic analysis to build the new expression.
1545 /// Subclasses may override this routine to provide different behavior.
1546 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1547 UnresolvedLookupExpr *OpCoawaitLookup,
1548 bool IsImplicit) {
1549 // This function rebuilds a coawait-expr given its operator.
1550 // For an explicit coawait-expr, the rebuild involves the full set
1551 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1552 // including calling await_transform().
1553 // For an implicit coawait-expr, we need to rebuild the "operator
1554 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1555 // This mirrors how the implicit CoawaitExpr is originally created
1556 // in Sema::ActOnCoroutineBodyStart().
1557 if (IsImplicit) {
1558 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1559 CoawaitLoc, Operand, OpCoawaitLookup);
1560 if (Suspend.isInvalid())
1561 return ExprError();
1562 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1563 Suspend.get(), true);
1564 }
1565
1566 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1567 OpCoawaitLookup);
1568 }
1569
1570 /// Build a new co_await expression.
1571 ///
1572 /// By default, performs semantic analysis to build the new expression.
1573 /// Subclasses may override this routine to provide different behavior.
1574 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1575 Expr *Result,
1576 UnresolvedLookupExpr *Lookup) {
1577 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1578 }
1579
1580 /// Build a new co_yield expression.
1581 ///
1582 /// By default, performs semantic analysis to build the new expression.
1583 /// Subclasses may override this routine to provide different behavior.
1584 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1585 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1586 }
1587
1588 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1589 return getSema().BuildCoroutineBodyStmt(Args);
1590 }
1591
1592 /// Build a new Objective-C \@try statement.
1593 ///
1594 /// By default, performs semantic analysis to build the new statement.
1595 /// Subclasses may override this routine to provide different behavior.
1596 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1597 Stmt *TryBody,
1598 MultiStmtArg CatchStmts,
1599 Stmt *Finally) {
1600 return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1601 Finally);
1602 }
1603
1604 /// Rebuild an Objective-C exception declaration.
1605 ///
1606 /// By default, performs semantic analysis to build the new declaration.
1607 /// Subclasses may override this routine to provide different behavior.
1608 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1609 TypeSourceInfo *TInfo, QualType T) {
1610 return getSema().BuildObjCExceptionDecl(TInfo, T,
1611 ExceptionDecl->getInnerLocStart(),
1612 ExceptionDecl->getLocation(),
1613 ExceptionDecl->getIdentifier());
1614 }
1615
1616 /// Build a new Objective-C \@catch statement.
1617 ///
1618 /// By default, performs semantic analysis to build the new statement.
1619 /// Subclasses may override this routine to provide different behavior.
1620 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1621 SourceLocation RParenLoc,
1622 VarDecl *Var,
1623 Stmt *Body) {
1624 return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1625 Var, Body);
1626 }
1627
1628 /// Build a new Objective-C \@finally 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 RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1633 Stmt *Body) {
1634 return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
1635 }
1636
1637 /// Build a new Objective-C \@throw statement.
1638 ///
1639 /// By default, performs semantic analysis to build the new statement.
1640 /// Subclasses may override this routine to provide different behavior.
1641 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1642 Expr *Operand) {
1643 return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
1644 }
1645
1646 /// Build a new OpenMP Canonical loop.
1647 ///
1648 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1649 /// OMPCanonicalLoop.
1650 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1651 return getSema().ActOnOpenMPCanonicalLoop(LoopStmt);
1652 }
1653
1654 /// Build a new OpenMP executable directive.
1655 ///
1656 /// By default, performs semantic analysis to build the new statement.
1657 /// Subclasses may override this routine to provide different behavior.
1658 StmtResult RebuildOMPExecutableDirective(
1659 OpenMPDirectiveKind Kind, DeclarationNameInfo DirName,
1660 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1661 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
1662 OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) {
1663
1664 return getSema().ActOnOpenMPExecutableDirective(
1665 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc,
1666 PrevMappedDirective);
1667 }
1668
1669 /// Build a new OpenMP 'if' clause.
1670 ///
1671 /// By default, performs semantic analysis to build the new OpenMP clause.
1672 /// Subclasses may override this routine to provide different behavior.
1673 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1674 Expr *Condition, SourceLocation StartLoc,
1675 SourceLocation LParenLoc,
1676 SourceLocation NameModifierLoc,
1677 SourceLocation ColonLoc,
1678 SourceLocation EndLoc) {
1679 return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
1680 LParenLoc, NameModifierLoc, ColonLoc,
1681 EndLoc);
1682 }
1683
1684 /// Build a new OpenMP 'final' clause.
1685 ///
1686 /// By default, performs semantic analysis to build the new OpenMP clause.
1687 /// Subclasses may override this routine to provide different behavior.
1688 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1689 SourceLocation LParenLoc,
1690 SourceLocation EndLoc) {
1691 return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc,
1692 EndLoc);
1693 }
1694
1695 /// Build a new OpenMP 'num_threads' clause.
1696 ///
1697 /// By default, performs semantic analysis to build the new OpenMP clause.
1698 /// Subclasses may override this routine to provide different behavior.
1699 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1700 SourceLocation StartLoc,
1701 SourceLocation LParenLoc,
1702 SourceLocation EndLoc) {
1703 return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1704 LParenLoc, EndLoc);
1705 }
1706
1707 /// Build a new OpenMP 'safelen' 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 *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1712 SourceLocation LParenLoc,
1713 SourceLocation EndLoc) {
1714 return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc);
1715 }
1716
1717 /// Build a new OpenMP 'simdlen' clause.
1718 ///
1719 /// By default, performs semantic analysis to build the new OpenMP clause.
1720 /// Subclasses may override this routine to provide different behavior.
1721 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1722 SourceLocation LParenLoc,
1723 SourceLocation EndLoc) {
1724 return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
1725 }
1726
1727 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1728 SourceLocation StartLoc,
1729 SourceLocation LParenLoc,
1730 SourceLocation EndLoc) {
1731 return getSema().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc, EndLoc);
1732 }
1733
1734 /// Build a new OpenMP 'full' clause.
1735 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1736 SourceLocation EndLoc) {
1737 return getSema().ActOnOpenMPFullClause(StartLoc, EndLoc);
1738 }
1739
1740 /// Build a new OpenMP 'partial' clause.
1741 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1742 SourceLocation LParenLoc,
1743 SourceLocation EndLoc) {
1744 return getSema().ActOnOpenMPPartialClause(Factor, StartLoc, LParenLoc,
1745 EndLoc);
1746 }
1747
1748 /// Build a new OpenMP 'allocator' clause.
1749 ///
1750 /// By default, performs semantic analysis to build the new OpenMP clause.
1751 /// Subclasses may override this routine to provide different behavior.
1752 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1753 SourceLocation LParenLoc,
1754 SourceLocation EndLoc) {
1755 return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
1756 }
1757
1758 /// Build a new OpenMP 'collapse' clause.
1759 ///
1760 /// By default, performs semantic analysis to build the new OpenMP clause.
1761 /// Subclasses may override this routine to provide different behavior.
1762 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1763 SourceLocation LParenLoc,
1764 SourceLocation EndLoc) {
1765 return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc,
1766 EndLoc);
1767 }
1768
1769 /// Build a new OpenMP 'default' clause.
1770 ///
1771 /// By default, performs semantic analysis to build the new OpenMP clause.
1772 /// Subclasses may override this routine to provide different behavior.
1773 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1774 SourceLocation StartLoc,
1775 SourceLocation LParenLoc,
1776 SourceLocation EndLoc) {
1777 return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc,
1778 StartLoc, LParenLoc, EndLoc);
1779 }
1780
1781 /// Build a new OpenMP 'proc_bind' clause.
1782 ///
1783 /// By default, performs semantic analysis to build the new OpenMP clause.
1784 /// Subclasses may override this routine to provide different behavior.
1785 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1786 SourceLocation KindKwLoc,
1787 SourceLocation StartLoc,
1788 SourceLocation LParenLoc,
1789 SourceLocation EndLoc) {
1790 return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
1791 StartLoc, LParenLoc, EndLoc);
1792 }
1793
1794 /// Build a new OpenMP 'schedule' clause.
1795 ///
1796 /// By default, performs semantic analysis to build the new OpenMP clause.
1797 /// Subclasses may override this routine to provide different behavior.
1798 OMPClause *RebuildOMPScheduleClause(
1799 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1800 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1801 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1802 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1803 return getSema().ActOnOpenMPScheduleClause(
1804 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1805 CommaLoc, EndLoc);
1806 }
1807
1808 /// Build a new OpenMP 'ordered' clause.
1809 ///
1810 /// By default, performs semantic analysis to build the new OpenMP clause.
1811 /// Subclasses may override this routine to provide different behavior.
1812 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1813 SourceLocation EndLoc,
1814 SourceLocation LParenLoc, Expr *Num) {
1815 return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num);
1816 }
1817
1818 /// Build a new OpenMP 'private' clause.
1819 ///
1820 /// By default, performs semantic analysis to build the new OpenMP clause.
1821 /// Subclasses may override this routine to provide different behavior.
1822 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1823 SourceLocation StartLoc,
1824 SourceLocation LParenLoc,
1825 SourceLocation EndLoc) {
1826 return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc,
1827 EndLoc);
1828 }
1829
1830 /// Build a new OpenMP 'firstprivate' clause.
1831 ///
1832 /// By default, performs semantic analysis to build the new OpenMP clause.
1833 /// Subclasses may override this routine to provide different behavior.
1834 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1835 SourceLocation StartLoc,
1836 SourceLocation LParenLoc,
1837 SourceLocation EndLoc) {
1838 return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc,
1839 EndLoc);
1840 }
1841
1842 /// Build a new OpenMP 'lastprivate' clause.
1843 ///
1844 /// By default, performs semantic analysis to build the new OpenMP clause.
1845 /// Subclasses may override this routine to provide different behavior.
1846 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1847 OpenMPLastprivateModifier LPKind,
1848 SourceLocation LPKindLoc,
1849 SourceLocation ColonLoc,
1850 SourceLocation StartLoc,
1851 SourceLocation LParenLoc,
1852 SourceLocation EndLoc) {
1853 return getSema().ActOnOpenMPLastprivateClause(
1854 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1855 }
1856
1857 /// Build a new OpenMP 'shared' clause.
1858 ///
1859 /// By default, performs semantic analysis to build the new OpenMP clause.
1860 /// Subclasses may override this routine to provide different behavior.
1861 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1862 SourceLocation StartLoc,
1863 SourceLocation LParenLoc,
1864 SourceLocation EndLoc) {
1865 return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
1866 EndLoc);
1867 }
1868
1869 /// Build a new OpenMP 'reduction' clause.
1870 ///
1871 /// By default, performs semantic analysis to build the new statement.
1872 /// Subclasses may override this routine to provide different behavior.
1873 OMPClause *RebuildOMPReductionClause(
1874 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1875 SourceLocation StartLoc, SourceLocation LParenLoc,
1876 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1877 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1878 const DeclarationNameInfo &ReductionId,
1879 ArrayRef<Expr *> UnresolvedReductions) {
1880 return getSema().ActOnOpenMPReductionClause(
1881 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1882 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1883 }
1884
1885 /// Build a new OpenMP 'task_reduction' clause.
1886 ///
1887 /// By default, performs semantic analysis to build the new statement.
1888 /// Subclasses may override this routine to provide different behavior.
1889 OMPClause *RebuildOMPTaskReductionClause(
1890 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1891 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1892 CXXScopeSpec &ReductionIdScopeSpec,
1893 const DeclarationNameInfo &ReductionId,
1894 ArrayRef<Expr *> UnresolvedReductions) {
1895 return getSema().ActOnOpenMPTaskReductionClause(
1896 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1897 ReductionId, UnresolvedReductions);
1898 }
1899
1900 /// Build a new OpenMP 'in_reduction' clause.
1901 ///
1902 /// By default, performs semantic analysis to build the new statement.
1903 /// Subclasses may override this routine to provide different behavior.
1904 OMPClause *
1905 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1906 SourceLocation LParenLoc, SourceLocation ColonLoc,
1907 SourceLocation EndLoc,
1908 CXXScopeSpec &ReductionIdScopeSpec,
1909 const DeclarationNameInfo &ReductionId,
1910 ArrayRef<Expr *> UnresolvedReductions) {
1911 return getSema().ActOnOpenMPInReductionClause(
1912 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1913 ReductionId, UnresolvedReductions);
1914 }
1915
1916 /// Build a new OpenMP 'linear' clause.
1917 ///
1918 /// By default, performs semantic analysis to build the new OpenMP clause.
1919 /// Subclasses may override this routine to provide different behavior.
1920 OMPClause *RebuildOMPLinearClause(
1921 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1922 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1923 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1924 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1925 return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
1926 Modifier, ModifierLoc, ColonLoc,
1927 StepModifierLoc, EndLoc);
1928 }
1929
1930 /// Build a new OpenMP 'aligned' clause.
1931 ///
1932 /// By default, performs semantic analysis to build the new OpenMP clause.
1933 /// Subclasses may override this routine to provide different behavior.
1934 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1935 SourceLocation StartLoc,
1936 SourceLocation LParenLoc,
1937 SourceLocation ColonLoc,
1938 SourceLocation EndLoc) {
1939 return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
1940 LParenLoc, ColonLoc, EndLoc);
1941 }
1942
1943 /// Build a new OpenMP 'copyin' clause.
1944 ///
1945 /// By default, performs semantic analysis to build the new OpenMP clause.
1946 /// Subclasses may override this routine to provide different behavior.
1947 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1948 SourceLocation StartLoc,
1949 SourceLocation LParenLoc,
1950 SourceLocation EndLoc) {
1951 return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
1952 EndLoc);
1953 }
1954
1955 /// Build a new OpenMP 'copyprivate' clause.
1956 ///
1957 /// By default, performs semantic analysis to build the new OpenMP clause.
1958 /// Subclasses may override this routine to provide different behavior.
1959 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1960 SourceLocation StartLoc,
1961 SourceLocation LParenLoc,
1962 SourceLocation EndLoc) {
1963 return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
1964 EndLoc);
1965 }
1966
1967 /// Build a new OpenMP 'flush' pseudo clause.
1968 ///
1969 /// By default, performs semantic analysis to build the new OpenMP clause.
1970 /// Subclasses may override this routine to provide different behavior.
1971 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
1972 SourceLocation StartLoc,
1973 SourceLocation LParenLoc,
1974 SourceLocation EndLoc) {
1975 return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
1976 EndLoc);
1977 }
1978
1979 /// Build a new OpenMP 'depobj' pseudo clause.
1980 ///
1981 /// By default, performs semantic analysis to build the new OpenMP clause.
1982 /// Subclasses may override this routine to provide different behavior.
1983 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
1984 SourceLocation LParenLoc,
1985 SourceLocation EndLoc) {
1986 return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc,
1987 EndLoc);
1988 }
1989
1990 /// Build a new OpenMP 'depend' pseudo clause.
1991 ///
1992 /// By default, performs semantic analysis to build the new OpenMP clause.
1993 /// Subclasses may override this routine to provide different behavior.
1994 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
1995 Expr *DepModifier, ArrayRef<Expr *> VarList,
1996 SourceLocation StartLoc,
1997 SourceLocation LParenLoc,
1998 SourceLocation EndLoc) {
1999 return getSema().ActOnOpenMPDependClause(Data, DepModifier, VarList,
2000 StartLoc, LParenLoc, EndLoc);
2001 }
2002
2003 /// Build a new OpenMP 'device' clause.
2004 ///
2005 /// By default, performs semantic analysis to build the new statement.
2006 /// Subclasses may override this routine to provide different behavior.
2007 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2008 Expr *Device, SourceLocation StartLoc,
2009 SourceLocation LParenLoc,
2010 SourceLocation ModifierLoc,
2011 SourceLocation EndLoc) {
2012 return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc,
2013 LParenLoc, ModifierLoc, EndLoc);
2014 }
2015
2016 /// Build a new OpenMP 'map' clause.
2017 ///
2018 /// By default, performs semantic analysis to build the new OpenMP clause.
2019 /// Subclasses may override this routine to provide different behavior.
2020 OMPClause *RebuildOMPMapClause(
2021 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2022 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2023 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2024 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2025 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2026 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2027 return getSema().ActOnOpenMPMapClause(
2028 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2029 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2030 ColonLoc, VarList, Locs,
2031 /*NoDiagnose=*/false, UnresolvedMappers);
2032 }
2033
2034 /// Build a new OpenMP 'allocate' clause.
2035 ///
2036 /// By default, performs semantic analysis to build the new OpenMP clause.
2037 /// Subclasses may override this routine to provide different behavior.
2038 OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2039 SourceLocation StartLoc,
2040 SourceLocation LParenLoc,
2041 SourceLocation ColonLoc,
2042 SourceLocation EndLoc) {
2043 return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
2044 LParenLoc, ColonLoc, EndLoc);
2045 }
2046
2047 /// Build a new OpenMP 'num_teams' clause.
2048 ///
2049 /// By default, performs semantic analysis to build the new statement.
2050 /// Subclasses may override this routine to provide different behavior.
2051 OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
2052 SourceLocation LParenLoc,
2053 SourceLocation EndLoc) {
2054 return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc,
2055 EndLoc);
2056 }
2057
2058 /// Build a new OpenMP 'thread_limit' clause.
2059 ///
2060 /// By default, performs semantic analysis to build the new statement.
2061 /// Subclasses may override this routine to provide different behavior.
2062 OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit,
2063 SourceLocation StartLoc,
2064 SourceLocation LParenLoc,
2065 SourceLocation EndLoc) {
2066 return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc,
2067 LParenLoc, EndLoc);
2068 }
2069
2070 /// Build a new OpenMP 'priority' clause.
2071 ///
2072 /// By default, performs semantic analysis to build the new statement.
2073 /// Subclasses may override this routine to provide different behavior.
2074 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2075 SourceLocation LParenLoc,
2076 SourceLocation EndLoc) {
2077 return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc,
2078 EndLoc);
2079 }
2080
2081 /// Build a new OpenMP 'grainsize' clause.
2082 ///
2083 /// By default, performs semantic analysis to build the new statement.
2084 /// Subclasses may override this routine to provide different behavior.
2085 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2086 Expr *Device, SourceLocation StartLoc,
2087 SourceLocation LParenLoc,
2088 SourceLocation ModifierLoc,
2089 SourceLocation EndLoc) {
2090 return getSema().ActOnOpenMPGrainsizeClause(Modifier, Device, StartLoc,
2091 LParenLoc, ModifierLoc, EndLoc);
2092 }
2093
2094 /// Build a new OpenMP 'num_tasks' clause.
2095 ///
2096 /// By default, performs semantic analysis to build the new statement.
2097 /// Subclasses may override this routine to provide different behavior.
2098 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2099 Expr *NumTasks, SourceLocation StartLoc,
2100 SourceLocation LParenLoc,
2101 SourceLocation ModifierLoc,
2102 SourceLocation EndLoc) {
2103 return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc,
2104 LParenLoc, ModifierLoc, EndLoc);
2105 }
2106
2107 /// Build a new OpenMP 'hint' clause.
2108 ///
2109 /// By default, performs semantic analysis to build the new statement.
2110 /// Subclasses may override this routine to provide different behavior.
2111 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2112 SourceLocation LParenLoc,
2113 SourceLocation EndLoc) {
2114 return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);
2115 }
2116
2117 /// Build a new OpenMP 'detach' clause.
2118 ///
2119 /// By default, performs semantic analysis to build the new statement.
2120 /// Subclasses may override this routine to provide different behavior.
2121 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2122 SourceLocation LParenLoc,
2123 SourceLocation EndLoc) {
2124 return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
2125 }
2126
2127 /// Build a new OpenMP 'dist_schedule' clause.
2128 ///
2129 /// By default, performs semantic analysis to build the new OpenMP clause.
2130 /// Subclasses may override this routine to provide different behavior.
2131 OMPClause *
2132 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2133 Expr *ChunkSize, SourceLocation StartLoc,
2134 SourceLocation LParenLoc, SourceLocation KindLoc,
2135 SourceLocation CommaLoc, SourceLocation EndLoc) {
2136 return getSema().ActOnOpenMPDistScheduleClause(
2137 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2138 }
2139
2140 /// Build a new OpenMP 'to' clause.
2141 ///
2142 /// By default, performs semantic analysis to build the new statement.
2143 /// Subclasses may override this routine to provide different behavior.
2144 OMPClause *
2145 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2146 ArrayRef<SourceLocation> MotionModifiersLoc,
2147 CXXScopeSpec &MapperIdScopeSpec,
2148 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2149 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2150 ArrayRef<Expr *> UnresolvedMappers) {
2151 return getSema().ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
2152 MapperIdScopeSpec, MapperId, ColonLoc,
2153 VarList, Locs, UnresolvedMappers);
2154 }
2155
2156 /// Build a new OpenMP 'from' clause.
2157 ///
2158 /// By default, performs semantic analysis to build the new statement.
2159 /// Subclasses may override this routine to provide different behavior.
2160 OMPClause *
2161 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2162 ArrayRef<SourceLocation> MotionModifiersLoc,
2163 CXXScopeSpec &MapperIdScopeSpec,
2164 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2165 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2166 ArrayRef<Expr *> UnresolvedMappers) {
2167 return getSema().ActOnOpenMPFromClause(
2168 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2169 ColonLoc, VarList, Locs, UnresolvedMappers);
2170 }
2171
2172 /// Build a new OpenMP 'use_device_ptr' clause.
2173 ///
2174 /// By default, performs semantic analysis to build the new OpenMP clause.
2175 /// Subclasses may override this routine to provide different behavior.
2176 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2177 const OMPVarListLocTy &Locs) {
2178 return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2179 }
2180
2181 /// Build a new OpenMP 'use_device_addr' clause.
2182 ///
2183 /// By default, performs semantic analysis to build the new OpenMP clause.
2184 /// Subclasses may override this routine to provide different behavior.
2185 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2186 const OMPVarListLocTy &Locs) {
2187 return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2188 }
2189
2190 /// Build a new OpenMP 'is_device_ptr' clause.
2191 ///
2192 /// By default, performs semantic analysis to build the new OpenMP clause.
2193 /// Subclasses may override this routine to provide different behavior.
2194 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2195 const OMPVarListLocTy &Locs) {
2196 return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2197 }
2198
2199 /// Build a new OpenMP 'has_device_addr' clause.
2200 ///
2201 /// By default, performs semantic analysis to build the new OpenMP clause.
2202 /// Subclasses may override this routine to provide different behavior.
2203 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2204 const OMPVarListLocTy &Locs) {
2205 return getSema().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2206 }
2207
2208 /// Build a new OpenMP 'defaultmap' clause.
2209 ///
2210 /// By default, performs semantic analysis to build the new OpenMP clause.
2211 /// Subclasses may override this routine to provide different behavior.
2212 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2213 OpenMPDefaultmapClauseKind Kind,
2214 SourceLocation StartLoc,
2215 SourceLocation LParenLoc,
2216 SourceLocation MLoc,
2217 SourceLocation KindLoc,
2218 SourceLocation EndLoc) {
2219 return getSema().ActOnOpenMPDefaultmapClause(M, Kind, StartLoc, LParenLoc,
2220 MLoc, KindLoc, EndLoc);
2221 }
2222
2223 /// Build a new OpenMP 'nontemporal' clause.
2224 ///
2225 /// By default, performs semantic analysis to build the new OpenMP clause.
2226 /// Subclasses may override this routine to provide different behavior.
2227 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2228 SourceLocation StartLoc,
2229 SourceLocation LParenLoc,
2230 SourceLocation EndLoc) {
2231 return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc,
2232 EndLoc);
2233 }
2234
2235 /// Build a new OpenMP 'inclusive' clause.
2236 ///
2237 /// By default, performs semantic analysis to build the new OpenMP clause.
2238 /// Subclasses may override this routine to provide different behavior.
2239 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2240 SourceLocation StartLoc,
2241 SourceLocation LParenLoc,
2242 SourceLocation EndLoc) {
2243 return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc,
2244 EndLoc);
2245 }
2246
2247 /// Build a new OpenMP 'exclusive' clause.
2248 ///
2249 /// By default, performs semantic analysis to build the new OpenMP clause.
2250 /// Subclasses may override this routine to provide different behavior.
2251 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2252 SourceLocation StartLoc,
2253 SourceLocation LParenLoc,
2254 SourceLocation EndLoc) {
2255 return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc,
2256 EndLoc);
2257 }
2258
2259 /// Build a new OpenMP 'uses_allocators' clause.
2260 ///
2261 /// By default, performs semantic analysis to build the new OpenMP clause.
2262 /// Subclasses may override this routine to provide different behavior.
2263 OMPClause *RebuildOMPUsesAllocatorsClause(
2264 ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc,
2265 SourceLocation LParenLoc, SourceLocation EndLoc) {
2266 return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc,
2267 Data);
2268 }
2269
2270 /// Build a new OpenMP 'affinity' clause.
2271 ///
2272 /// By default, performs semantic analysis to build the new OpenMP clause.
2273 /// Subclasses may override this routine to provide different behavior.
2274 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2275 SourceLocation LParenLoc,
2276 SourceLocation ColonLoc,
2277 SourceLocation EndLoc, Expr *Modifier,
2278 ArrayRef<Expr *> Locators) {
2279 return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc,
2280 EndLoc, Modifier, Locators);
2281 }
2282
2283 /// Build a new OpenMP 'order' clause.
2284 ///
2285 /// By default, performs semantic analysis to build the new OpenMP clause.
2286 /// Subclasses may override this routine to provide different behavior.
2287 OMPClause *RebuildOMPOrderClause(
2288 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2289 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2290 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2291 return getSema().ActOnOpenMPOrderClause(Modifier, Kind, StartLoc, LParenLoc,
2292 ModifierKwLoc, KindKwLoc, EndLoc);
2293 }
2294
2295 /// Build a new OpenMP 'init' clause.
2296 ///
2297 /// By default, performs semantic analysis to build the new OpenMP clause.
2298 /// Subclasses may override this routine to provide different behavior.
2299 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2300 SourceLocation StartLoc,
2301 SourceLocation LParenLoc,
2302 SourceLocation VarLoc,
2303 SourceLocation EndLoc) {
2304 return getSema().ActOnOpenMPInitClause(InteropVar, InteropInfo, StartLoc,
2305 LParenLoc, VarLoc, EndLoc);
2306 }
2307
2308 /// Build a new OpenMP 'use' clause.
2309 ///
2310 /// By default, performs semantic analysis to build the new OpenMP clause.
2311 /// Subclasses may override this routine to provide different behavior.
2312 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2313 SourceLocation LParenLoc,
2314 SourceLocation VarLoc, SourceLocation EndLoc) {
2315 return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc,
2316 VarLoc, EndLoc);
2317 }
2318
2319 /// Build a new OpenMP 'destroy' clause.
2320 ///
2321 /// By default, performs semantic analysis to build the new OpenMP clause.
2322 /// Subclasses may override this routine to provide different behavior.
2323 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2324 SourceLocation LParenLoc,
2325 SourceLocation VarLoc,
2326 SourceLocation EndLoc) {
2327 return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc,
2328 VarLoc, EndLoc);
2329 }
2330
2331 /// Build a new OpenMP 'novariants' clause.
2332 ///
2333 /// By default, performs semantic analysis to build the new OpenMP clause.
2334 /// Subclasses may override this routine to provide different behavior.
2335 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2336 SourceLocation StartLoc,
2337 SourceLocation LParenLoc,
2338 SourceLocation EndLoc) {
2339 return getSema().ActOnOpenMPNovariantsClause(Condition, StartLoc, LParenLoc,
2340 EndLoc);
2341 }
2342
2343 /// Build a new OpenMP 'nocontext' clause.
2344 ///
2345 /// By default, performs semantic analysis to build the new OpenMP clause.
2346 /// Subclasses may override this routine to provide different behavior.
2347 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2348 SourceLocation LParenLoc,
2349 SourceLocation EndLoc) {
2350 return getSema().ActOnOpenMPNocontextClause(Condition, StartLoc, LParenLoc,
2351 EndLoc);
2352 }
2353
2354 /// Build a new OpenMP 'filter' clause.
2355 ///
2356 /// By default, performs semantic analysis to build the new OpenMP clause.
2357 /// Subclasses may override this routine to provide different behavior.
2358 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2359 SourceLocation LParenLoc,
2360 SourceLocation EndLoc) {
2361 return getSema().ActOnOpenMPFilterClause(ThreadID, StartLoc, LParenLoc,
2362 EndLoc);
2363 }
2364
2365 /// Build a new OpenMP 'bind' clause.
2366 ///
2367 /// By default, performs semantic analysis to build the new OpenMP clause.
2368 /// Subclasses may override this routine to provide different behavior.
2369 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2370 SourceLocation KindLoc,
2371 SourceLocation StartLoc,
2372 SourceLocation LParenLoc,
2373 SourceLocation EndLoc) {
2374 return getSema().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc, LParenLoc,
2375 EndLoc);
2376 }
2377
2378 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2379 ///
2380 /// By default, performs semantic analysis to build the new OpenMP clause.
2381 /// Subclasses may override this routine to provide different behavior.
2382 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2383 SourceLocation LParenLoc,
2384 SourceLocation EndLoc) {
2385 return getSema().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc, LParenLoc,
2386 EndLoc);
2387 }
2388
2389 /// Build a new OpenMP 'ompx_attribute' clause.
2390 ///
2391 /// By default, performs semantic analysis to build the new OpenMP clause.
2392 /// Subclasses may override this routine to provide different behavior.
2393 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2394 SourceLocation StartLoc,
2395 SourceLocation LParenLoc,
2396 SourceLocation EndLoc) {
2397 return getSema().ActOnOpenMPXAttributeClause(Attrs, StartLoc, LParenLoc,
2398 EndLoc);
2399 }
2400
2401 /// Build a new OpenMP 'ompx_bare' clause.
2402 ///
2403 /// By default, performs semantic analysis to build the new OpenMP clause.
2404 /// Subclasses may override this routine to provide different behavior.
2405 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2406 SourceLocation EndLoc) {
2407 return getSema().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2408 }
2409
2410 /// Build a new OpenMP 'align' clause.
2411 ///
2412 /// By default, performs semantic analysis to build the new OpenMP clause.
2413 /// Subclasses may override this routine to provide different behavior.
2414 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2415 SourceLocation LParenLoc,
2416 SourceLocation EndLoc) {
2417 return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
2418 }
2419
2420 /// Build a new OpenMP 'at' 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 *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2425 SourceLocation StartLoc,
2426 SourceLocation LParenLoc,
2427 SourceLocation EndLoc) {
2428 return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
2429 EndLoc);
2430 }
2431
2432 /// Build a new OpenMP 'severity' clause.
2433 ///
2434 /// By default, performs semantic analysis to build the new OpenMP clause.
2435 /// Subclasses may override this routine to provide different behavior.
2436 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2437 SourceLocation KwLoc,
2438 SourceLocation StartLoc,
2439 SourceLocation LParenLoc,
2440 SourceLocation EndLoc) {
2441 return getSema().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc, LParenLoc,
2442 EndLoc);
2443 }
2444
2445 /// Build a new OpenMP 'message' clause.
2446 ///
2447 /// By default, performs semantic analysis to build the new OpenMP clause.
2448 /// Subclasses may override this routine to provide different behavior.
2449 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2450 SourceLocation LParenLoc,
2451 SourceLocation EndLoc) {
2452 return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
2453 }
2454
2455 /// Build a new OpenMP 'doacross' clause.
2456 ///
2457 /// By default, performs semantic analysis to build the new OpenMP clause.
2458 /// Subclasses may override this routine to provide different behavior.
2459 OMPClause *
2460 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2461 SourceLocation DepLoc, SourceLocation ColonLoc,
2462 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2463 SourceLocation LParenLoc, SourceLocation EndLoc) {
2464 return getSema().ActOnOpenMPDoacrossClause(
2465 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2466 }
2467
2468 /// Rebuild the operand to an Objective-C \@synchronized statement.
2469 ///
2470 /// By default, performs semantic analysis to build the new statement.
2471 /// Subclasses may override this routine to provide different behavior.
2472 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2473 Expr *object) {
2474 return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object);
2475 }
2476
2477 /// Build a new Objective-C \@synchronized statement.
2478 ///
2479 /// By default, performs semantic analysis to build the new statement.
2480 /// Subclasses may override this routine to provide different behavior.
2481 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2482 Expr *Object, Stmt *Body) {
2483 return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2484 }
2485
2486 /// Build a new Objective-C \@autoreleasepool statement.
2487 ///
2488 /// By default, performs semantic analysis to build the new statement.
2489 /// Subclasses may override this routine to provide different behavior.
2490 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2491 Stmt *Body) {
2492 return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2493 }
2494
2495 /// Build a new Objective-C fast enumeration statement.
2496 ///
2497 /// By default, performs semantic analysis to build the new statement.
2498 /// Subclasses may override this routine to provide different behavior.
2499 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2500 Stmt *Element,
2501 Expr *Collection,
2502 SourceLocation RParenLoc,
2503 Stmt *Body) {
2504 StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
2505 Element,
2506 Collection,
2507 RParenLoc);
2508 if (ForEachStmt.isInvalid())
2509 return StmtError();
2510
2511 return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
2512 }
2513
2514 /// Build a new C++ exception declaration.
2515 ///
2516 /// By default, performs semantic analysis to build the new decaration.
2517 /// Subclasses may override this routine to provide different behavior.
2518 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2519 TypeSourceInfo *Declarator,
2520 SourceLocation StartLoc,
2521 SourceLocation IdLoc,
2522 IdentifierInfo *Id) {
2523 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2524 StartLoc, IdLoc, Id);
2525 if (Var)
2526 getSema().CurContext->addDecl(Var);
2527 return Var;
2528 }
2529
2530 /// Build a new C++ catch statement.
2531 ///
2532 /// By default, performs semantic analysis to build the new statement.
2533 /// Subclasses may override this routine to provide different behavior.
2534 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2535 VarDecl *ExceptionDecl,
2536 Stmt *Handler) {
2537 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2538 Handler));
2539 }
2540
2541 /// Build a new C++ try statement.
2542 ///
2543 /// By default, performs semantic analysis to build the new statement.
2544 /// Subclasses may override this routine to provide different behavior.
2545 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2546 ArrayRef<Stmt *> Handlers) {
2547 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2548 }
2549
2550 /// Build a new C++0x range-based for statement.
2551 ///
2552 /// By default, performs semantic analysis to build the new statement.
2553 /// Subclasses may override this routine to provide different behavior.
2554 StmtResult RebuildCXXForRangeStmt(
2555 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2556 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2557 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2558 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2559 // If we've just learned that the range is actually an Objective-C
2560 // collection, treat this as an Objective-C fast enumeration loop.
2561 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2562 if (RangeStmt->isSingleDecl()) {
2563 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2564 if (RangeVar->isInvalidDecl())
2565 return StmtError();
2566
2567 Expr *RangeExpr = RangeVar->getInit();
2568 if (!RangeExpr->isTypeDependent() &&
2569 RangeExpr->getType()->isObjCObjectPointerType()) {
2570 // FIXME: Support init-statements in Objective-C++20 ranged for
2571 // statement.
2572 if (Init) {
2573 return SemaRef.Diag(Init->getBeginLoc(),
2574 diag::err_objc_for_range_init_stmt)
2575 << Init->getSourceRange();
2576 }
2577 return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar,
2578 RangeExpr, RParenLoc);
2579 }
2580 }
2581 }
2582 }
2583
2584 return getSema().BuildCXXForRangeStmt(
2585 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2586 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2587 }
2588
2589 /// Build a new C++0x range-based for statement.
2590 ///
2591 /// By default, performs semantic analysis to build the new statement.
2592 /// Subclasses may override this routine to provide different behavior.
2593 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2594 bool IsIfExists,
2595 NestedNameSpecifierLoc QualifierLoc,
2596 DeclarationNameInfo NameInfo,
2597 Stmt *Nested) {
2598 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2599 QualifierLoc, NameInfo, Nested);
2600 }
2601
2602 /// Attach body to a C++0x range-based for statement.
2603 ///
2604 /// By default, performs semantic analysis to finish the new statement.
2605 /// Subclasses may override this routine to provide different behavior.
2606 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2607 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2608 }
2609
2610 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2611 Stmt *TryBlock, Stmt *Handler) {
2612 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2613 }
2614
2615 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2616 Stmt *Block) {
2617 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2618 }
2619
2620 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2621 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2622 }
2623
2624 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2625 SourceLocation LParen,
2626 SourceLocation RParen,
2627 TypeSourceInfo *TSI) {
2628 return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
2629 }
2630
2631 /// Build a new predefined expression.
2632 ///
2633 /// By default, performs semantic analysis to build the new expression.
2634 /// Subclasses may override this routine to provide different behavior.
2635 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2636 return getSema().BuildPredefinedExpr(Loc, IK);
2637 }
2638
2639 /// Build a new expression that references a declaration.
2640 ///
2641 /// By default, performs semantic analysis to build the new expression.
2642 /// Subclasses may override this routine to provide different behavior.
2643 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2644 LookupResult &R,
2645 bool RequiresADL) {
2646 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2647 }
2648
2649
2650 /// Build a new expression that references a declaration.
2651 ///
2652 /// By default, performs semantic analysis to build the new expression.
2653 /// Subclasses may override this routine to provide different behavior.
2654 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2655 ValueDecl *VD,
2656 const DeclarationNameInfo &NameInfo,
2657 NamedDecl *Found,
2658 TemplateArgumentListInfo *TemplateArgs) {
2659 CXXScopeSpec SS;
2660 SS.Adopt(Other: QualifierLoc);
2661 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2662 TemplateArgs);
2663 }
2664
2665 /// Build a new expression in parentheses.
2666 ///
2667 /// By default, performs semantic analysis to build the new expression.
2668 /// Subclasses may override this routine to provide different behavior.
2669 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2670 SourceLocation RParen) {
2671 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2672 }
2673
2674 /// Build a new pseudo-destructor expression.
2675 ///
2676 /// By default, performs semantic analysis to build the new expression.
2677 /// Subclasses may override this routine to provide different behavior.
2678 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2679 SourceLocation OperatorLoc,
2680 bool isArrow,
2681 CXXScopeSpec &SS,
2682 TypeSourceInfo *ScopeType,
2683 SourceLocation CCLoc,
2684 SourceLocation TildeLoc,
2685 PseudoDestructorTypeStorage Destroyed);
2686
2687 /// Build a new unary operator expression.
2688 ///
2689 /// By default, performs semantic analysis to build the new expression.
2690 /// Subclasses may override this routine to provide different behavior.
2691 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2692 UnaryOperatorKind Opc,
2693 Expr *SubExpr) {
2694 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2695 }
2696
2697 /// Build a new builtin offsetof expression.
2698 ///
2699 /// By default, performs semantic analysis to build the new expression.
2700 /// Subclasses may override this routine to provide different behavior.
2701 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2702 TypeSourceInfo *Type,
2703 ArrayRef<Sema::OffsetOfComponent> Components,
2704 SourceLocation RParenLoc) {
2705 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2706 RParenLoc);
2707 }
2708
2709 /// Build a new sizeof, alignof or vec_step expression with a
2710 /// type argument.
2711 ///
2712 /// By default, performs semantic analysis to build the new expression.
2713 /// Subclasses may override this routine to provide different behavior.
2714 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2715 SourceLocation OpLoc,
2716 UnaryExprOrTypeTrait ExprKind,
2717 SourceRange R) {
2718 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2719 }
2720
2721 /// Build a new sizeof, alignof or vec step expression with an
2722 /// expression argument.
2723 ///
2724 /// By default, performs semantic analysis to build the new expression.
2725 /// Subclasses may override this routine to provide different behavior.
2726 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2727 UnaryExprOrTypeTrait ExprKind,
2728 SourceRange R) {
2729 ExprResult Result
2730 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2731 if (Result.isInvalid())
2732 return ExprError();
2733
2734 return Result;
2735 }
2736
2737 /// Build a new array subscript expression.
2738 ///
2739 /// By default, performs semantic analysis to build the new expression.
2740 /// Subclasses may override this routine to provide different behavior.
2741 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2742 SourceLocation LBracketLoc,
2743 Expr *RHS,
2744 SourceLocation RBracketLoc) {
2745 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2746 LBracketLoc, RHS,
2747 RBracketLoc);
2748 }
2749
2750 /// Build a new matrix subscript expression.
2751 ///
2752 /// By default, performs semantic analysis to build the new expression.
2753 /// Subclasses may override this routine to provide different behavior.
2754 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2755 Expr *ColumnIdx,
2756 SourceLocation RBracketLoc) {
2757 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2758 RBracketLoc);
2759 }
2760
2761 /// Build a new array section expression.
2762 ///
2763 /// By default, performs semantic analysis to build the new expression.
2764 /// Subclasses may override this routine to provide different behavior.
2765 ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,
2766 Expr *LowerBound,
2767 SourceLocation ColonLocFirst,
2768 SourceLocation ColonLocSecond,
2769 Expr *Length, Expr *Stride,
2770 SourceLocation RBracketLoc) {
2771 return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound,
2772 ColonLocFirst, ColonLocSecond,
2773 Length, Stride, RBracketLoc);
2774 }
2775
2776 /// Build a new array shaping expression.
2777 ///
2778 /// By default, performs semantic analysis to build the new expression.
2779 /// Subclasses may override this routine to provide different behavior.
2780 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2781 SourceLocation RParenLoc,
2782 ArrayRef<Expr *> Dims,
2783 ArrayRef<SourceRange> BracketsRanges) {
2784 return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims,
2785 BracketsRanges);
2786 }
2787
2788 /// Build a new iterator expression.
2789 ///
2790 /// By default, performs semantic analysis to build the new expression.
2791 /// Subclasses may override this routine to provide different behavior.
2792 ExprResult RebuildOMPIteratorExpr(
2793 SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc,
2794 ArrayRef<Sema::OMPIteratorData> Data) {
2795 return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc,
2796 LLoc, RLoc, Data);
2797 }
2798
2799 /// Build a new call expression.
2800 ///
2801 /// By default, performs semantic analysis to build the new expression.
2802 /// Subclasses may override this routine to provide different behavior.
2803 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2804 MultiExprArg Args,
2805 SourceLocation RParenLoc,
2806 Expr *ExecConfig = nullptr) {
2807 return getSema().ActOnCallExpr(
2808 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2809 }
2810
2811 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2812 MultiExprArg Args,
2813 SourceLocation RParenLoc) {
2814 return getSema().ActOnArraySubscriptExpr(
2815 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2816 }
2817
2818 /// Build a new member access expression.
2819 ///
2820 /// By default, performs semantic analysis to build the new expression.
2821 /// Subclasses may override this routine to provide different behavior.
2822 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2823 bool isArrow,
2824 NestedNameSpecifierLoc QualifierLoc,
2825 SourceLocation TemplateKWLoc,
2826 const DeclarationNameInfo &MemberNameInfo,
2827 ValueDecl *Member,
2828 NamedDecl *FoundDecl,
2829 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2830 NamedDecl *FirstQualifierInScope) {
2831 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2832 isArrow);
2833 if (!Member->getDeclName()) {
2834 // We have a reference to an unnamed field. This is always the
2835 // base of an anonymous struct/union member access, i.e. the
2836 // field is always of record type.
2837 assert(Member->getType()->isRecordType() &&
2838 "unnamed member not of record type?");
2839
2840 BaseResult =
2841 getSema().PerformObjectMemberConversion(BaseResult.get(),
2842 QualifierLoc.getNestedNameSpecifier(),
2843 FoundDecl, Member);
2844 if (BaseResult.isInvalid())
2845 return ExprError();
2846 Base = BaseResult.get();
2847
2848 CXXScopeSpec EmptySS;
2849 return getSema().BuildFieldReferenceExpr(
2850 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2851 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()), MemberNameInfo);
2852 }
2853
2854 CXXScopeSpec SS;
2855 SS.Adopt(Other: QualifierLoc);
2856
2857 Base = BaseResult.get();
2858 QualType BaseType = Base->getType();
2859
2860 if (isArrow && !BaseType->isPointerType())
2861 return ExprError();
2862
2863 // FIXME: this involves duplicating earlier analysis in a lot of
2864 // cases; we should avoid this when possible.
2865 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2866 R.addDecl(D: FoundDecl);
2867 R.resolveKind();
2868
2869 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2870 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2871 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2872 ->getType()
2873 ->getPointeeType()
2874 ->getAsCXXRecordDecl()) {
2875 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2876 // In unevaluated contexts, an expression supposed to be a member access
2877 // might reference a member in an unrelated class.
2878 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2879 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2880 VK_LValue, Member->getLocation());
2881 }
2882 }
2883
2884 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2885 SS, TemplateKWLoc,
2886 FirstQualifierInScope,
2887 R, ExplicitTemplateArgs,
2888 /*S*/nullptr);
2889 }
2890
2891 /// Build a new binary operator expression.
2892 ///
2893 /// By default, performs semantic analysis to build the new expression.
2894 /// Subclasses may override this routine to provide different behavior.
2895 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2896 BinaryOperatorKind Opc,
2897 Expr *LHS, Expr *RHS) {
2898 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2899 }
2900
2901 /// Build a new rewritten operator expression.
2902 ///
2903 /// By default, performs semantic analysis to build the new expression.
2904 /// Subclasses may override this routine to provide different behavior.
2905 ExprResult RebuildCXXRewrittenBinaryOperator(
2906 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2907 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2908 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2909 RHS, /*RequiresADL*/false);
2910 }
2911
2912 /// Build a new conditional operator expression.
2913 ///
2914 /// By default, performs semantic analysis to build the new expression.
2915 /// Subclasses may override this routine to provide different behavior.
2916 ExprResult RebuildConditionalOperator(Expr *Cond,
2917 SourceLocation QuestionLoc,
2918 Expr *LHS,
2919 SourceLocation ColonLoc,
2920 Expr *RHS) {
2921 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2922 LHS, RHS);
2923 }
2924
2925 /// Build a new C-style cast expression.
2926 ///
2927 /// By default, performs semantic analysis to build the new expression.
2928 /// Subclasses may override this routine to provide different behavior.
2929 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2930 TypeSourceInfo *TInfo,
2931 SourceLocation RParenLoc,
2932 Expr *SubExpr) {
2933 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2934 SubExpr);
2935 }
2936
2937 /// Build a new compound literal expression.
2938 ///
2939 /// By default, performs semantic analysis to build the new expression.
2940 /// Subclasses may override this routine to provide different behavior.
2941 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2942 TypeSourceInfo *TInfo,
2943 SourceLocation RParenLoc,
2944 Expr *Init) {
2945 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2946 Init);
2947 }
2948
2949 /// Build a new extended vector element access expression.
2950 ///
2951 /// By default, performs semantic analysis to build the new expression.
2952 /// Subclasses may override this routine to provide different behavior.
2953 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2954 bool IsArrow,
2955 SourceLocation AccessorLoc,
2956 IdentifierInfo &Accessor) {
2957
2958 CXXScopeSpec SS;
2959 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
2960 return getSema().BuildMemberReferenceExpr(
2961 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
2962 /*FirstQualifierInScope*/ nullptr, NameInfo,
2963 /* TemplateArgs */ nullptr,
2964 /*S*/ nullptr);
2965 }
2966
2967 /// Build a new initializer list expression.
2968 ///
2969 /// By default, performs semantic analysis to build the new expression.
2970 /// Subclasses may override this routine to provide different behavior.
2971 ExprResult RebuildInitList(SourceLocation LBraceLoc,
2972 MultiExprArg Inits,
2973 SourceLocation RBraceLoc) {
2974 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
2975 }
2976
2977 /// Build a new designated initializer expression.
2978 ///
2979 /// By default, performs semantic analysis to build the new expression.
2980 /// Subclasses may override this routine to provide different behavior.
2981 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
2982 MultiExprArg ArrayExprs,
2983 SourceLocation EqualOrColonLoc,
2984 bool GNUSyntax,
2985 Expr *Init) {
2986 ExprResult Result
2987 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
2988 Init);
2989 if (Result.isInvalid())
2990 return ExprError();
2991
2992 return Result;
2993 }
2994
2995 /// Build a new value-initialized expression.
2996 ///
2997 /// By default, builds the implicit value initialization without performing
2998 /// any semantic analysis. Subclasses may override this routine to provide
2999 /// different behavior.
3000 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3001 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3002 }
3003
3004 /// Build a new \c va_arg expression.
3005 ///
3006 /// By default, performs semantic analysis to build the new expression.
3007 /// Subclasses may override this routine to provide different behavior.
3008 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3009 Expr *SubExpr, TypeSourceInfo *TInfo,
3010 SourceLocation RParenLoc) {
3011 return getSema().BuildVAArgExpr(BuiltinLoc,
3012 SubExpr, TInfo,
3013 RParenLoc);
3014 }
3015
3016 /// Build a new expression list in parentheses.
3017 ///
3018 /// By default, performs semantic analysis to build the new expression.
3019 /// Subclasses may override this routine to provide different behavior.
3020 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3021 MultiExprArg SubExprs,
3022 SourceLocation RParenLoc) {
3023 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3024 }
3025
3026 /// Build a new address-of-label expression.
3027 ///
3028 /// By default, performs semantic analysis, using the name of the label
3029 /// rather than attempting to map the label statement itself.
3030 /// Subclasses may override this routine to provide different behavior.
3031 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3032 SourceLocation LabelLoc, LabelDecl *Label) {
3033 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3034 }
3035
3036 /// Build a new GNU statement expression.
3037 ///
3038 /// By default, performs semantic analysis to build the new expression.
3039 /// Subclasses may override this routine to provide different behavior.
3040 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3041 SourceLocation RParenLoc, unsigned TemplateDepth) {
3042 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3043 TemplateDepth);
3044 }
3045
3046 /// Build a new __builtin_choose_expr expression.
3047 ///
3048 /// By default, performs semantic analysis to build the new expression.
3049 /// Subclasses may override this routine to provide different behavior.
3050 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3051 Expr *Cond, Expr *LHS, Expr *RHS,
3052 SourceLocation RParenLoc) {
3053 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3054 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3055 RPLoc: RParenLoc);
3056 }
3057
3058 /// Build a new generic selection expression with an expression predicate.
3059 ///
3060 /// By default, performs semantic analysis to build the new expression.
3061 /// Subclasses may override this routine to provide different behavior.
3062 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3063 SourceLocation DefaultLoc,
3064 SourceLocation RParenLoc,
3065 Expr *ControllingExpr,
3066 ArrayRef<TypeSourceInfo *> Types,
3067 ArrayRef<Expr *> Exprs) {
3068 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3069 /*PredicateIsExpr=*/true,
3070 ControllingExpr, Types, Exprs);
3071 }
3072
3073 /// Build a new generic selection expression with a type predicate.
3074 ///
3075 /// By default, performs semantic analysis to build the new expression.
3076 /// Subclasses may override this routine to provide different behavior.
3077 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3078 SourceLocation DefaultLoc,
3079 SourceLocation RParenLoc,
3080 TypeSourceInfo *ControllingType,
3081 ArrayRef<TypeSourceInfo *> Types,
3082 ArrayRef<Expr *> Exprs) {
3083 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3084 /*PredicateIsExpr=*/false,
3085 ControllingType, Types, Exprs);
3086 }
3087
3088 /// Build a new overloaded operator call expression.
3089 ///
3090 /// By default, performs semantic analysis to build the new expression.
3091 /// The semantic analysis provides the behavior of template instantiation,
3092 /// copying with transformations that turn what looks like an overloaded
3093 /// operator call into a use of a builtin operator, performing
3094 /// argument-dependent lookup, etc. Subclasses may override this routine to
3095 /// provide different behavior.
3096 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3097 SourceLocation OpLoc,
3098 SourceLocation CalleeLoc,
3099 bool RequiresADL,
3100 const UnresolvedSetImpl &Functions,
3101 Expr *First, Expr *Second);
3102
3103 /// Build a new C++ "named" cast expression, such as static_cast or
3104 /// reinterpret_cast.
3105 ///
3106 /// By default, this routine dispatches to one of the more-specific routines
3107 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3108 /// Subclasses may override this routine to provide different behavior.
3109 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3110 Stmt::StmtClass Class,
3111 SourceLocation LAngleLoc,
3112 TypeSourceInfo *TInfo,
3113 SourceLocation RAngleLoc,
3114 SourceLocation LParenLoc,
3115 Expr *SubExpr,
3116 SourceLocation RParenLoc) {
3117 switch (Class) {
3118 case Stmt::CXXStaticCastExprClass:
3119 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3120 RAngleLoc, LParenLoc,
3121 SubExpr, RParenLoc);
3122
3123 case Stmt::CXXDynamicCastExprClass:
3124 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3125 RAngleLoc, LParenLoc,
3126 SubExpr, RParenLoc);
3127
3128 case Stmt::CXXReinterpretCastExprClass:
3129 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3130 RAngleLoc, LParenLoc,
3131 SubExpr,
3132 RParenLoc);
3133
3134 case Stmt::CXXConstCastExprClass:
3135 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3136 RAngleLoc, LParenLoc,
3137 SubExpr, RParenLoc);
3138
3139 case Stmt::CXXAddrspaceCastExprClass:
3140 return getDerived().RebuildCXXAddrspaceCastExpr(
3141 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3142
3143 default:
3144 llvm_unreachable("Invalid C++ named cast");
3145 }
3146 }
3147
3148 /// Build a new C++ static_cast expression.
3149 ///
3150 /// By default, performs semantic analysis to build the new expression.
3151 /// Subclasses may override this routine to provide different behavior.
3152 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3153 SourceLocation LAngleLoc,
3154 TypeSourceInfo *TInfo,
3155 SourceLocation RAngleLoc,
3156 SourceLocation LParenLoc,
3157 Expr *SubExpr,
3158 SourceLocation RParenLoc) {
3159 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3160 TInfo, SubExpr,
3161 SourceRange(LAngleLoc, RAngleLoc),
3162 SourceRange(LParenLoc, RParenLoc));
3163 }
3164
3165 /// Build a new C++ dynamic_cast expression.
3166 ///
3167 /// By default, performs semantic analysis to build the new expression.
3168 /// Subclasses may override this routine to provide different behavior.
3169 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3170 SourceLocation LAngleLoc,
3171 TypeSourceInfo *TInfo,
3172 SourceLocation RAngleLoc,
3173 SourceLocation LParenLoc,
3174 Expr *SubExpr,
3175 SourceLocation RParenLoc) {
3176 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3177 TInfo, SubExpr,
3178 SourceRange(LAngleLoc, RAngleLoc),
3179 SourceRange(LParenLoc, RParenLoc));
3180 }
3181
3182 /// Build a new C++ reinterpret_cast expression.
3183 ///
3184 /// By default, performs semantic analysis to build the new expression.
3185 /// Subclasses may override this routine to provide different behavior.
3186 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3187 SourceLocation LAngleLoc,
3188 TypeSourceInfo *TInfo,
3189 SourceLocation RAngleLoc,
3190 SourceLocation LParenLoc,
3191 Expr *SubExpr,
3192 SourceLocation RParenLoc) {
3193 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3194 TInfo, SubExpr,
3195 SourceRange(LAngleLoc, RAngleLoc),
3196 SourceRange(LParenLoc, RParenLoc));
3197 }
3198
3199 /// Build a new C++ const_cast expression.
3200 ///
3201 /// By default, performs semantic analysis to build the new expression.
3202 /// Subclasses may override this routine to provide different behavior.
3203 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3204 SourceLocation LAngleLoc,
3205 TypeSourceInfo *TInfo,
3206 SourceLocation RAngleLoc,
3207 SourceLocation LParenLoc,
3208 Expr *SubExpr,
3209 SourceLocation RParenLoc) {
3210 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3211 TInfo, SubExpr,
3212 SourceRange(LAngleLoc, RAngleLoc),
3213 SourceRange(LParenLoc, RParenLoc));
3214 }
3215
3216 ExprResult
3217 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3218 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3219 SourceLocation LParenLoc, Expr *SubExpr,
3220 SourceLocation RParenLoc) {
3221 return getSema().BuildCXXNamedCast(
3222 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3223 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3224 }
3225
3226 /// Build a new C++ functional-style cast expression.
3227 ///
3228 /// By default, performs semantic analysis to build the new expression.
3229 /// Subclasses may override this routine to provide different behavior.
3230 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3231 SourceLocation LParenLoc,
3232 Expr *Sub,
3233 SourceLocation RParenLoc,
3234 bool ListInitialization) {
3235 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3236 // CXXParenListInitExpr. Pass its expanded arguments so that the
3237 // CXXParenListInitExpr can be rebuilt.
3238 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3239 return getSema().BuildCXXTypeConstructExpr(
3240 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3241 RParenLoc, ListInitialization);
3242 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3243 MultiExprArg(&Sub, 1), RParenLoc,
3244 ListInitialization);
3245 }
3246
3247 /// Build a new C++ __builtin_bit_cast expression.
3248 ///
3249 /// By default, performs semantic analysis to build the new expression.
3250 /// Subclasses may override this routine to provide different behavior.
3251 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3252 TypeSourceInfo *TSI, Expr *Sub,
3253 SourceLocation RParenLoc) {
3254 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3255 }
3256
3257 /// Build a new C++ typeid(type) expression.
3258 ///
3259 /// By default, performs semantic analysis to build the new expression.
3260 /// Subclasses may override this routine to provide different behavior.
3261 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3262 SourceLocation TypeidLoc,
3263 TypeSourceInfo *Operand,
3264 SourceLocation RParenLoc) {
3265 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3266 RParenLoc);
3267 }
3268
3269
3270 /// Build a new C++ typeid(expr) 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 RebuildCXXTypeidExpr(QualType TypeInfoType,
3275 SourceLocation TypeidLoc,
3276 Expr *Operand,
3277 SourceLocation RParenLoc) {
3278 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3279 RParenLoc);
3280 }
3281
3282 /// Build a new C++ __uuidof(type) expression.
3283 ///
3284 /// By default, performs semantic analysis to build the new expression.
3285 /// Subclasses may override this routine to provide different behavior.
3286 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3287 TypeSourceInfo *Operand,
3288 SourceLocation RParenLoc) {
3289 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3290 }
3291
3292 /// Build a new C++ __uuidof(expr) expression.
3293 ///
3294 /// By default, performs semantic analysis to build the new expression.
3295 /// Subclasses may override this routine to provide different behavior.
3296 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3297 Expr *Operand, SourceLocation RParenLoc) {
3298 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3299 }
3300
3301 /// Build a new C++ "this" expression.
3302 ///
3303 /// By default, builds a new "this" expression without performing any
3304 /// semantic analysis. Subclasses may override this routine to provide
3305 /// different behavior.
3306 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3307 QualType ThisType,
3308 bool isImplicit) {
3309 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3310 }
3311
3312 /// Build a new C++ throw expression.
3313 ///
3314 /// By default, performs semantic analysis to build the new expression.
3315 /// Subclasses may override this routine to provide different behavior.
3316 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3317 bool IsThrownVariableInScope) {
3318 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3319 }
3320
3321 /// Build a new C++ default-argument expression.
3322 ///
3323 /// By default, builds a new default-argument expression, which does not
3324 /// require any semantic analysis. Subclasses may override this routine to
3325 /// provide different behavior.
3326 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3327 Expr *RewrittenExpr) {
3328 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3329 RewrittenExpr, UsedContext: getSema().CurContext);
3330 }
3331
3332 /// Build a new C++11 default-initialization expression.
3333 ///
3334 /// By default, builds a new default field initialization expression, which
3335 /// does not require any semantic analysis. Subclasses may override this
3336 /// routine to provide different behavior.
3337 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3338 FieldDecl *Field) {
3339 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3340 }
3341
3342 /// Build a new C++ zero-initialization expression.
3343 ///
3344 /// By default, performs semantic analysis to build the new expression.
3345 /// Subclasses may override this routine to provide different behavior.
3346 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3347 SourceLocation LParenLoc,
3348 SourceLocation RParenLoc) {
3349 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3350 RParenLoc,
3351 /*ListInitialization=*/false);
3352 }
3353
3354 /// Build a new C++ "new" expression.
3355 ///
3356 /// By default, performs semantic analysis to build the new expression.
3357 /// Subclasses may override this routine to provide different behavior.
3358 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3359 SourceLocation PlacementLParen,
3360 MultiExprArg PlacementArgs,
3361 SourceLocation PlacementRParen,
3362 SourceRange TypeIdParens, QualType AllocatedType,
3363 TypeSourceInfo *AllocatedTypeInfo,
3364 std::optional<Expr *> ArraySize,
3365 SourceRange DirectInitRange, Expr *Initializer) {
3366 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3367 PlacementLParen,
3368 PlacementArgs,
3369 PlacementRParen,
3370 TypeIdParens,
3371 AllocatedType,
3372 AllocatedTypeInfo,
3373 ArraySize,
3374 DirectInitRange,
3375 Initializer);
3376 }
3377
3378 /// Build a new C++ "delete" 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 RebuildCXXDeleteExpr(SourceLocation StartLoc,
3383 bool IsGlobalDelete,
3384 bool IsArrayForm,
3385 Expr *Operand) {
3386 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3387 Operand);
3388 }
3389
3390 /// Build a new type trait expression.
3391 ///
3392 /// By default, performs semantic analysis to build the new expression.
3393 /// Subclasses may override this routine to provide different behavior.
3394 ExprResult RebuildTypeTrait(TypeTrait Trait,
3395 SourceLocation StartLoc,
3396 ArrayRef<TypeSourceInfo *> Args,
3397 SourceLocation RParenLoc) {
3398 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3399 }
3400
3401 /// Build a new array type trait expression.
3402 ///
3403 /// By default, performs semantic analysis to build the new expression.
3404 /// Subclasses may override this routine to provide different behavior.
3405 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3406 SourceLocation StartLoc,
3407 TypeSourceInfo *TSInfo,
3408 Expr *DimExpr,
3409 SourceLocation RParenLoc) {
3410 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3411 }
3412
3413 /// Build a new expression trait expression.
3414 ///
3415 /// By default, performs semantic analysis to build the new expression.
3416 /// Subclasses may override this routine to provide different behavior.
3417 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3418 SourceLocation StartLoc,
3419 Expr *Queried,
3420 SourceLocation RParenLoc) {
3421 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3422 }
3423
3424 /// Build a new (previously unresolved) declaration reference
3425 /// 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 RebuildDependentScopeDeclRefExpr(
3430 NestedNameSpecifierLoc QualifierLoc,
3431 SourceLocation TemplateKWLoc,
3432 const DeclarationNameInfo &NameInfo,
3433 const TemplateArgumentListInfo *TemplateArgs,
3434 bool IsAddressOfOperand,
3435 TypeSourceInfo **RecoveryTSI) {
3436 CXXScopeSpec SS;
3437 SS.Adopt(Other: QualifierLoc);
3438
3439 if (TemplateArgs || TemplateKWLoc.isValid())
3440 return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
3441 TemplateArgs);
3442
3443 return getSema().BuildQualifiedDeclarationNameExpr(
3444 SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI);
3445 }
3446
3447 /// Build a new template-id expression.
3448 ///
3449 /// By default, performs semantic analysis to build the new expression.
3450 /// Subclasses may override this routine to provide different behavior.
3451 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3452 SourceLocation TemplateKWLoc,
3453 LookupResult &R,
3454 bool RequiresADL,
3455 const TemplateArgumentListInfo *TemplateArgs) {
3456 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3457 TemplateArgs);
3458 }
3459
3460 /// Build a new object-construction expression.
3461 ///
3462 /// By default, performs semantic analysis to build the new expression.
3463 /// Subclasses may override this routine to provide different behavior.
3464 ExprResult RebuildCXXConstructExpr(
3465 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3466 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3467 bool ListInitialization, bool StdInitListInitialization,
3468 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3469 SourceRange ParenRange) {
3470 // Reconstruct the constructor we originally found, which might be
3471 // different if this is a call to an inherited constructor.
3472 CXXConstructorDecl *FoundCtor = Constructor;
3473 if (Constructor->isInheritingConstructor())
3474 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3475
3476 SmallVector<Expr *, 8> ConvertedArgs;
3477 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3478 ConvertedArgs))
3479 return ExprError();
3480
3481 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3482 IsElidable,
3483 ConvertedArgs,
3484 HadMultipleCandidates,
3485 ListInitialization,
3486 StdInitListInitialization,
3487 RequiresZeroInit, ConstructKind,
3488 ParenRange);
3489 }
3490
3491 /// Build a new implicit construction via inherited constructor
3492 /// expression.
3493 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3494 CXXConstructorDecl *Constructor,
3495 bool ConstructsVBase,
3496 bool InheritedFromVBase) {
3497 return new (getSema().Context) CXXInheritedCtorInitExpr(
3498 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3499 }
3500
3501 /// Build a new object-construction expression.
3502 ///
3503 /// By default, performs semantic analysis to build the new expression.
3504 /// Subclasses may override this routine to provide different behavior.
3505 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3506 SourceLocation LParenOrBraceLoc,
3507 MultiExprArg Args,
3508 SourceLocation RParenOrBraceLoc,
3509 bool ListInitialization) {
3510 return getSema().BuildCXXTypeConstructExpr(
3511 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3512 }
3513
3514 /// Build a new object-construction expression.
3515 ///
3516 /// By default, performs semantic analysis to build the new expression.
3517 /// Subclasses may override this routine to provide different behavior.
3518 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3519 SourceLocation LParenLoc,
3520 MultiExprArg Args,
3521 SourceLocation RParenLoc,
3522 bool ListInitialization) {
3523 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3524 RParenLoc, ListInitialization);
3525 }
3526
3527 /// Build a new member reference expression.
3528 ///
3529 /// By default, performs semantic analysis to build the new expression.
3530 /// Subclasses may override this routine to provide different behavior.
3531 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3532 QualType BaseType,
3533 bool IsArrow,
3534 SourceLocation OperatorLoc,
3535 NestedNameSpecifierLoc QualifierLoc,
3536 SourceLocation TemplateKWLoc,
3537 NamedDecl *FirstQualifierInScope,
3538 const DeclarationNameInfo &MemberNameInfo,
3539 const TemplateArgumentListInfo *TemplateArgs) {
3540 CXXScopeSpec SS;
3541 SS.Adopt(Other: QualifierLoc);
3542
3543 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3544 OpLoc: OperatorLoc, IsArrow,
3545 SS, TemplateKWLoc,
3546 FirstQualifierInScope,
3547 NameInfo: MemberNameInfo,
3548 TemplateArgs, /*S*/S: nullptr);
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 RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3556 SourceLocation OperatorLoc,
3557 bool IsArrow,
3558 NestedNameSpecifierLoc QualifierLoc,
3559 SourceLocation TemplateKWLoc,
3560 NamedDecl *FirstQualifierInScope,
3561 LookupResult &R,
3562 const TemplateArgumentListInfo *TemplateArgs) {
3563 CXXScopeSpec SS;
3564 SS.Adopt(Other: QualifierLoc);
3565
3566 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3567 OpLoc: OperatorLoc, IsArrow,
3568 SS, TemplateKWLoc,
3569 FirstQualifierInScope,
3570 R, TemplateArgs, /*S*/S: nullptr);
3571 }
3572
3573 /// Build a new noexcept expression.
3574 ///
3575 /// By default, performs semantic analysis to build the new expression.
3576 /// Subclasses may override this routine to provide different behavior.
3577 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3578 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3579 }
3580
3581 /// Build a new expression to compute the length of a parameter pack.
3582 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3583 SourceLocation PackLoc,
3584 SourceLocation RParenLoc,
3585 std::optional<unsigned> Length,
3586 ArrayRef<TemplateArgument> PartialArgs) {
3587 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3588 RParenLoc, Length, PartialArgs);
3589 }
3590
3591 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3592 SourceLocation RSquareLoc,
3593 Expr *PackIdExpression, Expr *IndexExpr,
3594 ArrayRef<Expr *> ExpandedExprs,
3595 bool EmptyPack = false) {
3596 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3597 IndexExpr, RSquareLoc, ExpandedExprs,
3598 EmptyPack);
3599 }
3600
3601 /// Build a new expression representing a call to a source location
3602 /// builtin.
3603 ///
3604 /// By default, performs semantic analysis to build the new expression.
3605 /// Subclasses may override this routine to provide different behavior.
3606 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3607 SourceLocation BuiltinLoc,
3608 SourceLocation RPLoc,
3609 DeclContext *ParentContext) {
3610 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3611 ParentContext);
3612 }
3613
3614 /// Build a new Objective-C boxed expression.
3615 ///
3616 /// By default, performs semantic analysis to build the new expression.
3617 /// Subclasses may override this routine to provide different behavior.
3618 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3619 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3620 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3621 TemplateArgumentListInfo *TALI) {
3622 CXXScopeSpec SS;
3623 SS.Adopt(Other: NNS);
3624 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3625 ConceptNameInfo,
3626 FoundDecl,
3627 NamedConcept, TALI);
3628 if (Result.isInvalid())
3629 return ExprError();
3630 return Result;
3631 }
3632
3633 /// \brief Build a new requires expression.
3634 ///
3635 /// By default, performs semantic analysis to build the new expression.
3636 /// Subclasses may override this routine to provide different behavior.
3637 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3638 RequiresExprBodyDecl *Body,
3639 SourceLocation LParenLoc,
3640 ArrayRef<ParmVarDecl *> LocalParameters,
3641 SourceLocation RParenLoc,
3642 ArrayRef<concepts::Requirement *> Requirements,
3643 SourceLocation ClosingBraceLoc) {
3644 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3645 LocalParameters, RParenLoc, Requirements,
3646 ClosingBraceLoc);
3647 }
3648
3649 concepts::TypeRequirement *
3650 RebuildTypeRequirement(
3651 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3652 return SemaRef.BuildTypeRequirement(SubstDiag);
3653 }
3654
3655 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3656 return SemaRef.BuildTypeRequirement(Type: T);
3657 }
3658
3659 concepts::ExprRequirement *
3660 RebuildExprRequirement(
3661 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3662 SourceLocation NoexceptLoc,
3663 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3664 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3665 std::move(Ret));
3666 }
3667
3668 concepts::ExprRequirement *
3669 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3670 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3671 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3672 std::move(Ret));
3673 }
3674
3675 concepts::NestedRequirement *
3676 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3677 const ASTConstraintSatisfaction &Satisfaction) {
3678 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3679 Satisfaction);
3680 }
3681
3682 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3683 return SemaRef.BuildNestedRequirement(E: Constraint);
3684 }
3685
3686 /// \brief Build a new Objective-C boxed expression.
3687 ///
3688 /// By default, performs semantic analysis to build the new expression.
3689 /// Subclasses may override this routine to provide different behavior.
3690 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3691 return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
3692 }
3693
3694 /// Build a new Objective-C array literal.
3695 ///
3696 /// By default, performs semantic analysis to build the new expression.
3697 /// Subclasses may override this routine to provide different behavior.
3698 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3699 Expr **Elements, unsigned NumElements) {
3700 return getSema().BuildObjCArrayLiteral(Range,
3701 MultiExprArg(Elements, NumElements));
3702 }
3703
3704 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3705 Expr *Base, Expr *Key,
3706 ObjCMethodDecl *getterMethod,
3707 ObjCMethodDecl *setterMethod) {
3708 return getSema().BuildObjCSubscriptExpression(RB, Base, Key,
3709 getterMethod, setterMethod);
3710 }
3711
3712 /// Build a new Objective-C dictionary literal.
3713 ///
3714 /// By default, performs semantic analysis to build the new expression.
3715 /// Subclasses may override this routine to provide different behavior.
3716 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3717 MutableArrayRef<ObjCDictionaryElement> Elements) {
3718 return getSema().BuildObjCDictionaryLiteral(Range, Elements);
3719 }
3720
3721 /// Build a new Objective-C \@encode expression.
3722 ///
3723 /// By default, performs semantic analysis to build the new expression.
3724 /// Subclasses may override this routine to provide different behavior.
3725 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3726 TypeSourceInfo *EncodeTypeInfo,
3727 SourceLocation RParenLoc) {
3728 return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo, RParenLoc);
3729 }
3730
3731 /// Build a new Objective-C class message.
3732 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3733 Selector Sel,
3734 ArrayRef<SourceLocation> SelectorLocs,
3735 ObjCMethodDecl *Method,
3736 SourceLocation LBracLoc,
3737 MultiExprArg Args,
3738 SourceLocation RBracLoc) {
3739 return SemaRef.BuildClassMessage(ReceiverTypeInfo,
3740 ReceiverType: ReceiverTypeInfo->getType(),
3741 /*SuperLoc=*/SuperLoc: SourceLocation(),
3742 Sel, Method, LBracLoc, SelectorLocs,
3743 RBracLoc, Args);
3744 }
3745
3746 /// Build a new Objective-C instance message.
3747 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3748 Selector Sel,
3749 ArrayRef<SourceLocation> SelectorLocs,
3750 ObjCMethodDecl *Method,
3751 SourceLocation LBracLoc,
3752 MultiExprArg Args,
3753 SourceLocation RBracLoc) {
3754 return SemaRef.BuildInstanceMessage(Receiver,
3755 ReceiverType: Receiver->getType(),
3756 /*SuperLoc=*/SuperLoc: SourceLocation(),
3757 Sel, Method, LBracLoc, SelectorLocs,
3758 RBracLoc, Args);
3759 }
3760
3761 /// Build a new Objective-C instance/class message to 'super'.
3762 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3763 Selector Sel,
3764 ArrayRef<SourceLocation> SelectorLocs,
3765 QualType SuperType,
3766 ObjCMethodDecl *Method,
3767 SourceLocation LBracLoc,
3768 MultiExprArg Args,
3769 SourceLocation RBracLoc) {
3770 return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(Receiver: nullptr,
3771 ReceiverType: SuperType,
3772 SuperLoc,
3773 Sel, Method, LBracLoc, SelectorLocs,
3774 RBracLoc, Args)
3775 : SemaRef.BuildClassMessage(ReceiverTypeInfo: nullptr,
3776 ReceiverType: SuperType,
3777 SuperLoc,
3778 Sel, Method, LBracLoc, SelectorLocs,
3779 RBracLoc, Args);
3780
3781
3782 }
3783
3784 /// Build a new Objective-C ivar reference expression.
3785 ///
3786 /// By default, performs semantic analysis to build the new expression.
3787 /// Subclasses may override this routine to provide different behavior.
3788 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3789 SourceLocation IvarLoc,
3790 bool IsArrow, bool IsFreeIvar) {
3791 CXXScopeSpec SS;
3792 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3793 ExprResult Result = getSema().BuildMemberReferenceExpr(
3794 BaseArg, BaseArg->getType(),
3795 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3796 /*FirstQualifierInScope=*/nullptr, NameInfo,
3797 /*TemplateArgs=*/nullptr,
3798 /*S=*/nullptr);
3799 if (IsFreeIvar && Result.isUsable())
3800 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3801 return Result;
3802 }
3803
3804 /// Build a new Objective-C property reference expression.
3805 ///
3806 /// By default, performs semantic analysis to build the new expression.
3807 /// Subclasses may override this routine to provide different behavior.
3808 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3809 ObjCPropertyDecl *Property,
3810 SourceLocation PropertyLoc) {
3811 CXXScopeSpec SS;
3812 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3813 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3814 /*FIXME:*/PropertyLoc,
3815 /*IsArrow=*/false,
3816 SS, SourceLocation(),
3817 /*FirstQualifierInScope=*/nullptr,
3818 NameInfo,
3819 /*TemplateArgs=*/nullptr,
3820 /*S=*/nullptr);
3821 }
3822
3823 /// Build a new Objective-C property reference expression.
3824 ///
3825 /// By default, performs semantic analysis to build the new expression.
3826 /// Subclasses may override this routine to provide different behavior.
3827 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3828 ObjCMethodDecl *Getter,
3829 ObjCMethodDecl *Setter,
3830 SourceLocation PropertyLoc) {
3831 // Since these expressions can only be value-dependent, we do not
3832 // need to perform semantic analysis again.
3833 return Owned(
3834 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3835 VK_LValue, OK_ObjCProperty,
3836 PropertyLoc, Base));
3837 }
3838
3839 /// Build a new Objective-C "isa" expression.
3840 ///
3841 /// By default, performs semantic analysis to build the new expression.
3842 /// Subclasses may override this routine to provide different behavior.
3843 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3844 SourceLocation OpLoc, bool IsArrow) {
3845 CXXScopeSpec SS;
3846 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3847 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3848 OpLoc, IsArrow,
3849 SS, SourceLocation(),
3850 /*FirstQualifierInScope=*/nullptr,
3851 NameInfo,
3852 /*TemplateArgs=*/nullptr,
3853 /*S=*/nullptr);
3854 }
3855
3856 /// Build a new shuffle vector expression.
3857 ///
3858 /// By default, performs semantic analysis to build the new expression.
3859 /// Subclasses may override this routine to provide different behavior.
3860 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3861 MultiExprArg SubExprs,
3862 SourceLocation RParenLoc) {
3863 // Find the declaration for __builtin_shufflevector
3864 const IdentifierInfo &Name
3865 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
3866 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3867 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3868 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3869
3870 // Build a reference to the __builtin_shufflevector builtin
3871 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3872 Expr *Callee = new (SemaRef.Context)
3873 DeclRefExpr(SemaRef.Context, Builtin, false,
3874 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3875 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3876 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
3877 CK: CK_BuiltinFnToFnPtr).get();
3878
3879 // Build the CallExpr
3880 ExprResult TheCall = CallExpr::Create(
3881 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
3882 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
3883 FPFeatures: FPOptionsOverride());
3884
3885 // Type-check the __builtin_shufflevector expression.
3886 return SemaRef.SemaBuiltinShuffleVector(TheCall: cast<CallExpr>(TheCall.get()));
3887 }
3888
3889 /// Build a new convert vector expression.
3890 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3891 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3892 SourceLocation RParenLoc) {
3893 return SemaRef.SemaConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo,
3894 BuiltinLoc, RParenLoc);
3895 }
3896
3897 /// Build a new template argument pack expansion.
3898 ///
3899 /// By default, performs semantic analysis to build a new pack expansion
3900 /// for a template argument. Subclasses may override this routine to provide
3901 /// different behavior.
3902 TemplateArgumentLoc
3903 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3904 std::optional<unsigned> NumExpansions) {
3905 switch (Pattern.getArgument().getKind()) {
3906 case TemplateArgument::Expression: {
3907 ExprResult Result
3908 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3909 EllipsisLoc, NumExpansions);
3910 if (Result.isInvalid())
3911 return TemplateArgumentLoc();
3912
3913 return TemplateArgumentLoc(Result.get(), Result.get());
3914 }
3915
3916 case TemplateArgument::Template:
3917 return TemplateArgumentLoc(
3918 SemaRef.Context,
3919 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3920 NumExpansions),
3921 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3922 EllipsisLoc);
3923
3924 case TemplateArgument::Null:
3925 case TemplateArgument::Integral:
3926 case TemplateArgument::Declaration:
3927 case TemplateArgument::StructuralValue:
3928 case TemplateArgument::Pack:
3929 case TemplateArgument::TemplateExpansion:
3930 case TemplateArgument::NullPtr:
3931 llvm_unreachable("Pack expansion pattern has no parameter packs");
3932
3933 case TemplateArgument::Type:
3934 if (TypeSourceInfo *Expansion
3935 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3936 EllipsisLoc,
3937 NumExpansions))
3938 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3939 Expansion);
3940 break;
3941 }
3942
3943 return TemplateArgumentLoc();
3944 }
3945
3946 /// Build a new expression pack expansion.
3947 ///
3948 /// By default, performs semantic analysis to build a new pack expansion
3949 /// for an expression. Subclasses may override this routine to provide
3950 /// different behavior.
3951 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3952 std::optional<unsigned> NumExpansions) {
3953 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3954 }
3955
3956 /// Build a new C++1z fold-expression.
3957 ///
3958 /// By default, performs semantic analysis in order to build a new fold
3959 /// expression.
3960 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3961 SourceLocation LParenLoc, Expr *LHS,
3962 BinaryOperatorKind Operator,
3963 SourceLocation EllipsisLoc, Expr *RHS,
3964 SourceLocation RParenLoc,
3965 std::optional<unsigned> NumExpansions) {
3966 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
3967 EllipsisLoc, RHS, RParenLoc,
3968 NumExpansions);
3969 }
3970
3971 /// Build an empty C++1z fold-expression with the given operator.
3972 ///
3973 /// By default, produces the fallback value for the fold-expression, or
3974 /// produce an error if there is no fallback value.
3975 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
3976 BinaryOperatorKind Operator) {
3977 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
3978 }
3979
3980 /// Build a new atomic operation expression.
3981 ///
3982 /// By default, performs semantic analysis to build the new expression.
3983 /// Subclasses may override this routine to provide different behavior.
3984 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
3985 AtomicExpr::AtomicOp Op,
3986 SourceLocation RParenLoc) {
3987 // Use this for all of the locations, since we don't know the difference
3988 // between the call and the expr at this point.
3989 SourceRange Range{BuiltinLoc, RParenLoc};
3990 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
3991 Sema::AtomicArgumentOrder::AST);
3992 }
3993
3994 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
3995 ArrayRef<Expr *> SubExprs, QualType Type) {
3996 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
3997 }
3998
3999 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4000 SourceLocation BeginLoc,
4001 SourceLocation EndLoc,
4002 StmtResult StrBlock) {
4003 llvm_unreachable("Not yet implemented!");
4004 }
4005
4006private:
4007 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4008 QualType ObjectType,
4009 NamedDecl *FirstQualifierInScope,
4010 CXXScopeSpec &SS);
4011
4012 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4013 QualType ObjectType,
4014 NamedDecl *FirstQualifierInScope,
4015 CXXScopeSpec &SS);
4016
4017 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4018 NamedDecl *FirstQualifierInScope,
4019 CXXScopeSpec &SS);
4020
4021 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4022 DependentNameTypeLoc TL,
4023 bool DeducibleTSTContext);
4024};
4025
4026template <typename Derived>
4027StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4028 if (!S)
4029 return S;
4030
4031 switch (S->getStmtClass()) {
4032 case Stmt::NoStmtClass: break;
4033
4034 // Transform individual statement nodes
4035 // Pass SDK into statements that can produce a value
4036#define STMT(Node, Parent) \
4037 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4038#define VALUESTMT(Node, Parent) \
4039 case Stmt::Node##Class: \
4040 return getDerived().Transform##Node(cast<Node>(S), SDK);
4041#define ABSTRACT_STMT(Node)
4042#define EXPR(Node, Parent)
4043#include "clang/AST/StmtNodes.inc"
4044
4045 // Transform expressions by calling TransformExpr.
4046#define STMT(Node, Parent)
4047#define ABSTRACT_STMT(Stmt)
4048#define EXPR(Node, Parent) case Stmt::Node##Class:
4049#include "clang/AST/StmtNodes.inc"
4050 {
4051 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4052
4053 if (SDK == SDK_StmtExprResult)
4054 E = getSema().ActOnStmtExprResult(E);
4055 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4056 }
4057 }
4058
4059 return S;
4060}
4061
4062template<typename Derived>
4063OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4064 if (!S)
4065 return S;
4066
4067 switch (S->getClauseKind()) {
4068 default: break;
4069 // Transform individual clause nodes
4070#define GEN_CLANG_CLAUSE_CLASS
4071#define CLAUSE_CLASS(Enum, Str, Class) \
4072 case Enum: \
4073 return getDerived().Transform##Class(cast<Class>(S));
4074#include "llvm/Frontend/OpenMP/OMP.inc"
4075 }
4076
4077 return S;
4078}
4079
4080
4081template<typename Derived>
4082ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4083 if (!E)
4084 return E;
4085
4086 switch (E->getStmtClass()) {
4087 case Stmt::NoStmtClass: break;
4088#define STMT(Node, Parent) case Stmt::Node##Class: break;
4089#define ABSTRACT_STMT(Stmt)
4090#define EXPR(Node, Parent) \
4091 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4092#include "clang/AST/StmtNodes.inc"
4093 }
4094
4095 return E;
4096}
4097
4098template<typename Derived>
4099ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4100 bool NotCopyInit) {
4101 // Initializers are instantiated like expressions, except that various outer
4102 // layers are stripped.
4103 if (!Init)
4104 return Init;
4105
4106 if (auto *FE = dyn_cast<FullExpr>(Init))
4107 Init = FE->getSubExpr();
4108
4109 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4110 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4111 Init = OVE->getSourceExpr();
4112 }
4113
4114 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4115 Init = MTE->getSubExpr();
4116
4117 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4118 Init = Binder->getSubExpr();
4119
4120 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4121 Init = ICE->getSubExprAsWritten();
4122
4123 if (CXXStdInitializerListExpr *ILE =
4124 dyn_cast<CXXStdInitializerListExpr>(Init))
4125 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4126
4127 // If this is copy-initialization, we only need to reconstruct
4128 // InitListExprs. Other forms of copy-initialization will be a no-op if
4129 // the initializer is already the right type.
4130 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4131 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4132 return getDerived().TransformExpr(Init);
4133
4134 // Revert value-initialization back to empty parens.
4135 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4136 SourceRange Parens = VIE->getSourceRange();
4137 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4138 Parens.getEnd());
4139 }
4140
4141 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4142 if (isa<ImplicitValueInitExpr>(Init))
4143 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4144 SourceLocation());
4145
4146 // Revert initialization by constructor back to a parenthesized or braced list
4147 // of expressions. Any other form of initializer can just be reused directly.
4148 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4149 return getDerived().TransformExpr(Init);
4150
4151 // If the initialization implicitly converted an initializer list to a
4152 // std::initializer_list object, unwrap the std::initializer_list too.
4153 if (Construct && Construct->isStdInitListInitialization())
4154 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4155
4156 // Enter a list-init context if this was list initialization.
4157 EnterExpressionEvaluationContext Context(
4158 getSema(), EnterExpressionEvaluationContext::InitList,
4159 Construct->isListInitialization());
4160
4161 getSema().keepInLifetimeExtendingContext();
4162 getSema().keepInLifetimeExtendingContext();
4163 SmallVector<Expr*, 8> NewArgs;
4164 bool ArgChanged = false;
4165 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4166 /*IsCall*/true, NewArgs, &ArgChanged))
4167 return ExprError();
4168
4169 // If this was list initialization, revert to syntactic list form.
4170 if (Construct->isListInitialization())
4171 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4172 Construct->getEndLoc());
4173
4174 // Build a ParenListExpr to represent anything else.
4175 SourceRange Parens = Construct->getParenOrBraceRange();
4176 if (Parens.isInvalid()) {
4177 // This was a variable declaration's initialization for which no initializer
4178 // was specified.
4179 assert(NewArgs.empty() &&
4180 "no parens or braces but have direct init with arguments?");
4181 return ExprEmpty();
4182 }
4183 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4184 Parens.getEnd());
4185}
4186
4187template<typename Derived>
4188bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4189 unsigned NumInputs,
4190 bool IsCall,
4191 SmallVectorImpl<Expr *> &Outputs,
4192 bool *ArgChanged) {
4193 for (unsigned I = 0; I != NumInputs; ++I) {
4194 // If requested, drop call arguments that need to be dropped.
4195 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4196 if (ArgChanged)
4197 *ArgChanged = true;
4198
4199 break;
4200 }
4201
4202 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4203 Expr *Pattern = Expansion->getPattern();
4204
4205 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4206 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4207 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4208
4209 // Determine whether the set of unexpanded parameter packs can and should
4210 // be expanded.
4211 bool Expand = true;
4212 bool RetainExpansion = false;
4213 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4214 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4215 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4216 Pattern->getSourceRange(),
4217 Unexpanded,
4218 Expand, RetainExpansion,
4219 NumExpansions))
4220 return true;
4221
4222 if (!Expand) {
4223 // The transform has determined that we should perform a simple
4224 // transformation on the pack expansion, producing another pack
4225 // expansion.
4226 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4227 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4228 if (OutPattern.isInvalid())
4229 return true;
4230
4231 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4232 Expansion->getEllipsisLoc(),
4233 NumExpansions);
4234 if (Out.isInvalid())
4235 return true;
4236
4237 if (ArgChanged)
4238 *ArgChanged = true;
4239 Outputs.push_back(Elt: Out.get());
4240 continue;
4241 }
4242
4243 // Record right away that the argument was changed. This needs
4244 // to happen even if the array expands to nothing.
4245 if (ArgChanged) *ArgChanged = true;
4246
4247 // The transform has determined that we should perform an elementwise
4248 // expansion of the pattern. Do so.
4249 for (unsigned I = 0; I != *NumExpansions; ++I) {
4250 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4251 ExprResult Out = getDerived().TransformExpr(Pattern);
4252 if (Out.isInvalid())
4253 return true;
4254
4255 if (Out.get()->containsUnexpandedParameterPack()) {
4256 Out = getDerived().RebuildPackExpansion(
4257 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4258 if (Out.isInvalid())
4259 return true;
4260 }
4261
4262 Outputs.push_back(Elt: Out.get());
4263 }
4264
4265 // If we're supposed to retain a pack expansion, do so by temporarily
4266 // forgetting the partially-substituted parameter pack.
4267 if (RetainExpansion) {
4268 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4269
4270 ExprResult Out = getDerived().TransformExpr(Pattern);
4271 if (Out.isInvalid())
4272 return true;
4273
4274 Out = getDerived().RebuildPackExpansion(
4275 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4276 if (Out.isInvalid())
4277 return true;
4278
4279 Outputs.push_back(Elt: Out.get());
4280 }
4281
4282 continue;
4283 }
4284
4285 ExprResult Result =
4286 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4287 : getDerived().TransformExpr(Inputs[I]);
4288 if (Result.isInvalid())
4289 return true;
4290
4291 if (Result.get() != Inputs[I] && ArgChanged)
4292 *ArgChanged = true;
4293
4294 Outputs.push_back(Elt: Result.get());
4295 }
4296
4297 return false;
4298}
4299
4300template <typename Derived>
4301Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4302 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4303 if (Var) {
4304 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4305 getDerived().TransformDefinition(Var->getLocation(), Var));
4306
4307 if (!ConditionVar)
4308 return Sema::ConditionError();
4309
4310 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4311 }
4312
4313 if (Expr) {
4314 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4315
4316 if (CondExpr.isInvalid())
4317 return Sema::ConditionError();
4318
4319 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4320 /*MissingOK=*/true);
4321 }
4322
4323 return Sema::ConditionResult();
4324}
4325
4326template <typename Derived>
4327NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4328 NestedNameSpecifierLoc NNS, QualType ObjectType,
4329 NamedDecl *FirstQualifierInScope) {
4330 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4331
4332 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4333 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4334 Qualifier = Qualifier.getPrefix())
4335 Qualifiers.push_back(Qualifier);
4336 };
4337 insertNNS(NNS);
4338
4339 CXXScopeSpec SS;
4340 while (!Qualifiers.empty()) {
4341 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4342 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4343
4344 switch (QNNS->getKind()) {
4345 case NestedNameSpecifier::Identifier: {
4346 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4347 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4348 ObjectType);
4349 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo, EnteringContext: false,
4350 SS, ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4351 return NestedNameSpecifierLoc();
4352 break;
4353 }
4354
4355 case NestedNameSpecifier::Namespace: {
4356 NamespaceDecl *NS =
4357 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4358 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4359 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4360 break;
4361 }
4362
4363 case NestedNameSpecifier::NamespaceAlias: {
4364 NamespaceAliasDecl *Alias =
4365 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4366 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4367 SS.Extend(Context&: SemaRef.Context, Alias, AliasLoc: Q.getLocalBeginLoc(),
4368 ColonColonLoc: Q.getLocalEndLoc());
4369 break;
4370 }
4371
4372 case NestedNameSpecifier::Global:
4373 // There is no meaningful transformation that one could perform on the
4374 // global scope.
4375 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4376 break;
4377
4378 case NestedNameSpecifier::Super: {
4379 CXXRecordDecl *RD =
4380 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4381 SourceLocation(), QNNS->getAsRecordDecl()));
4382 SS.MakeSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(), ColonColonLoc: Q.getEndLoc());
4383 break;
4384 }
4385
4386 case NestedNameSpecifier::TypeSpecWithTemplate:
4387 case NestedNameSpecifier::TypeSpec: {
4388 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4389 FirstQualifierInScope, SS);
4390
4391 if (!TL)
4392 return NestedNameSpecifierLoc();
4393
4394 QualType T = TL.getType();
4395 if (T->isDependentType() || T->isRecordType() ||
4396 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4397 if (T->isEnumeralType())
4398 SemaRef.Diag(TL.getBeginLoc(),
4399 diag::warn_cxx98_compat_enum_nested_name_spec);
4400
4401 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4402 SS.Adopt(Other: ETL.getQualifierLoc());
4403 TL = ETL.getNamedTypeLoc();
4404 }
4405
4406 SS.Extend(Context&: SemaRef.Context, TemplateKWLoc: TL.getTemplateKeywordLoc(), TL,
4407 ColonColonLoc: Q.getLocalEndLoc());
4408 break;
4409 }
4410 // If the nested-name-specifier is an invalid type def, don't emit an
4411 // error because a previous error should have already been emitted.
4412 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4413 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4414 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4415 << T << SS.getRange();
4416 }
4417 return NestedNameSpecifierLoc();
4418 }
4419 }
4420
4421 // The qualifier-in-scope and object type only apply to the leftmost entity.
4422 FirstQualifierInScope = nullptr;
4423 ObjectType = QualType();
4424 }
4425
4426 // Don't rebuild the nested-name-specifier if we don't have to.
4427 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4428 !getDerived().AlwaysRebuild())
4429 return NNS;
4430
4431 // If we can re-use the source-location data from the original
4432 // nested-name-specifier, do so.
4433 if (SS.location_size() == NNS.getDataLength() &&
4434 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4435 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4436
4437 // Allocate new nested-name-specifier location information.
4438 return SS.getWithLocInContext(Context&: SemaRef.Context);
4439}
4440
4441template<typename Derived>
4442DeclarationNameInfo
4443TreeTransform<Derived>
4444::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4445 DeclarationName Name = NameInfo.getName();
4446 if (!Name)
4447 return DeclarationNameInfo();
4448
4449 switch (Name.getNameKind()) {
4450 case DeclarationName::Identifier:
4451 case DeclarationName::ObjCZeroArgSelector:
4452 case DeclarationName::ObjCOneArgSelector:
4453 case DeclarationName::ObjCMultiArgSelector:
4454 case DeclarationName::CXXOperatorName:
4455 case DeclarationName::CXXLiteralOperatorName:
4456 case DeclarationName::CXXUsingDirective:
4457 return NameInfo;
4458
4459 case DeclarationName::CXXDeductionGuideName: {
4460 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4461 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4462 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4463 if (!NewTemplate)
4464 return DeclarationNameInfo();
4465
4466 DeclarationNameInfo NewNameInfo(NameInfo);
4467 NewNameInfo.setName(
4468 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4469 return NewNameInfo;
4470 }
4471
4472 case DeclarationName::CXXConstructorName:
4473 case DeclarationName::CXXDestructorName:
4474 case DeclarationName::CXXConversionFunctionName: {
4475 TypeSourceInfo *NewTInfo;
4476 CanQualType NewCanTy;
4477 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4478 NewTInfo = getDerived().TransformType(OldTInfo);
4479 if (!NewTInfo)
4480 return DeclarationNameInfo();
4481 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4482 }
4483 else {
4484 NewTInfo = nullptr;
4485 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4486 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4487 if (NewT.isNull())
4488 return DeclarationNameInfo();
4489 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4490 }
4491
4492 DeclarationName NewName
4493 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4494 Ty: NewCanTy);
4495 DeclarationNameInfo NewNameInfo(NameInfo);
4496 NewNameInfo.setName(NewName);
4497 NewNameInfo.setNamedTypeInfo(NewTInfo);
4498 return NewNameInfo;
4499 }
4500 }
4501
4502 llvm_unreachable("Unknown name kind.");
4503}
4504
4505template<typename Derived>
4506TemplateName
4507TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4508 TemplateName Name,
4509 SourceLocation NameLoc,
4510 QualType ObjectType,
4511 NamedDecl *FirstQualifierInScope,
4512 bool AllowInjectedClassName) {
4513 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4514 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4515 assert(Template && "qualified template name must refer to a template");
4516
4517 TemplateDecl *TransTemplate
4518 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4519 Template));
4520 if (!TransTemplate)
4521 return TemplateName();
4522
4523 if (!getDerived().AlwaysRebuild() &&
4524 SS.getScopeRep() == QTN->getQualifier() &&
4525 TransTemplate == Template)
4526 return Name;
4527
4528 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4529 TransTemplate);
4530 }
4531
4532 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4533 if (SS.getScopeRep()) {
4534 // These apply to the scope specifier, not the template.
4535 ObjectType = QualType();
4536 FirstQualifierInScope = nullptr;
4537 }
4538
4539 if (!getDerived().AlwaysRebuild() &&
4540 SS.getScopeRep() == DTN->getQualifier() &&
4541 ObjectType.isNull())
4542 return Name;
4543
4544 // FIXME: Preserve the location of the "template" keyword.
4545 SourceLocation TemplateKWLoc = NameLoc;
4546
4547 if (DTN->isIdentifier()) {
4548 return getDerived().RebuildTemplateName(SS,
4549 TemplateKWLoc,
4550 *DTN->getIdentifier(),
4551 NameLoc,
4552 ObjectType,
4553 FirstQualifierInScope,
4554 AllowInjectedClassName);
4555 }
4556
4557 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4558 DTN->getOperator(), NameLoc,
4559 ObjectType, AllowInjectedClassName);
4560 }
4561
4562 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4563 TemplateDecl *TransTemplate
4564 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4565 Template));
4566 if (!TransTemplate)
4567 return TemplateName();
4568
4569 if (!getDerived().AlwaysRebuild() &&
4570 TransTemplate == Template)
4571 return Name;
4572
4573 return TemplateName(TransTemplate);
4574 }
4575
4576 if (SubstTemplateTemplateParmPackStorage *SubstPack
4577 = Name.getAsSubstTemplateTemplateParmPack()) {
4578 return getDerived().RebuildTemplateName(
4579 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4580 SubstPack->getIndex(), SubstPack->getFinal());
4581 }
4582
4583 // These should be getting filtered out before they reach the AST.
4584 llvm_unreachable("overloaded function decl survived to here");
4585}
4586
4587template<typename Derived>
4588void TreeTransform<Derived>::InventTemplateArgumentLoc(
4589 const TemplateArgument &Arg,
4590 TemplateArgumentLoc &Output) {
4591 Output = getSema().getTrivialTemplateArgumentLoc(
4592 Arg, QualType(), getDerived().getBaseLocation());
4593}
4594
4595template <typename Derived>
4596bool TreeTransform<Derived>::TransformTemplateArgument(
4597 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4598 bool Uneval) {
4599 const TemplateArgument &Arg = Input.getArgument();
4600 switch (Arg.getKind()) {
4601 case TemplateArgument::Null:
4602 case TemplateArgument::Pack:
4603 llvm_unreachable("Unexpected TemplateArgument");
4604
4605 case TemplateArgument::Integral:
4606 case TemplateArgument::NullPtr:
4607 case TemplateArgument::Declaration:
4608 case TemplateArgument::StructuralValue: {
4609 // Transform a resolved template argument straight to a resolved template
4610 // argument. We get here when substituting into an already-substituted
4611 // template type argument during concept satisfaction checking.
4612 QualType T = Arg.getNonTypeTemplateArgumentType();
4613 QualType NewT = getDerived().TransformType(T);
4614 if (NewT.isNull())
4615 return true;
4616
4617 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4618 ? Arg.getAsDecl()
4619 : nullptr;
4620 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4621 getDerived().getBaseLocation(), D))
4622 : nullptr;
4623 if (D && !NewD)
4624 return true;
4625
4626 if (NewT == T && D == NewD)
4627 Output = Input;
4628 else if (Arg.getKind() == TemplateArgument::Integral)
4629 Output = TemplateArgumentLoc(
4630 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4631 TemplateArgumentLocInfo());
4632 else if (Arg.getKind() == TemplateArgument::NullPtr)
4633 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4634 TemplateArgumentLocInfo());
4635 else if (Arg.getKind() == TemplateArgument::Declaration)
4636 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4637 TemplateArgumentLocInfo());
4638 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4639 Output = TemplateArgumentLoc(
4640 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4641 TemplateArgumentLocInfo());
4642 else
4643 llvm_unreachable("unexpected template argument kind");
4644
4645 return false;
4646 }
4647
4648 case TemplateArgument::Type: {
4649 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4650 if (!DI)
4651 DI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
4652
4653 DI = getDerived().TransformType(DI);
4654 if (!DI)
4655 return true;
4656
4657 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4658 return false;
4659 }
4660
4661 case TemplateArgument::Template: {
4662 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4663 if (QualifierLoc) {
4664 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4665 if (!QualifierLoc)
4666 return true;
4667 }
4668
4669 CXXScopeSpec SS;
4670 SS.Adopt(Other: QualifierLoc);
4671 TemplateName Template = getDerived().TransformTemplateName(
4672 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4673 if (Template.isNull())
4674 return true;
4675
4676 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4677 QualifierLoc, Input.getTemplateNameLoc());
4678 return false;
4679 }
4680
4681 case TemplateArgument::TemplateExpansion:
4682 llvm_unreachable("Caller should expand pack expansions");
4683
4684 case TemplateArgument::Expression: {
4685 // Template argument expressions are constant expressions.
4686 EnterExpressionEvaluationContext Unevaluated(
4687 getSema(),
4688 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4689 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4690 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4691 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4692
4693 Expr *InputExpr = Input.getSourceExpression();
4694 if (!InputExpr)
4695 InputExpr = Input.getArgument().getAsExpr();
4696
4697 ExprResult E = getDerived().TransformExpr(InputExpr);
4698 E = SemaRef.ActOnConstantExpression(Res: E);
4699 if (E.isInvalid())
4700 return true;
4701 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4702 return false;
4703 }
4704 }
4705
4706 // Work around bogus GCC warning
4707 return true;
4708}
4709
4710/// Iterator adaptor that invents template argument location information
4711/// for each of the template arguments in its underlying iterator.
4712template<typename Derived, typename InputIterator>
4713class TemplateArgumentLocInventIterator {
4714 TreeTransform<Derived> &Self;
4715 InputIterator Iter;
4716
4717public:
4718 typedef TemplateArgumentLoc value_type;
4719 typedef TemplateArgumentLoc reference;
4720 typedef typename std::iterator_traits<InputIterator>::difference_type
4721 difference_type;
4722 typedef std::input_iterator_tag iterator_category;
4723
4724 class pointer {
4725 TemplateArgumentLoc Arg;
4726
4727 public:
4728 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4729
4730 const TemplateArgumentLoc *operator->() const { return &Arg; }
4731 };
4732
4733 TemplateArgumentLocInventIterator() { }
4734
4735 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4736 InputIterator Iter)
4737 : Self(Self), Iter(Iter) { }
4738
4739 TemplateArgumentLocInventIterator &operator++() {
4740 ++Iter;
4741 return *this;
4742 }
4743
4744 TemplateArgumentLocInventIterator operator++(int) {
4745 TemplateArgumentLocInventIterator Old(*this);
4746 ++(*this);
4747 return Old;
4748 }
4749
4750 reference operator*() const {
4751 TemplateArgumentLoc Result;
4752 Self.InventTemplateArgumentLoc(*Iter, Result);
4753 return Result;
4754 }
4755
4756 pointer operator->() const { return pointer(**this); }
4757
4758 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4759 const TemplateArgumentLocInventIterator &Y) {
4760 return X.Iter == Y.Iter;
4761 }
4762
4763 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4764 const TemplateArgumentLocInventIterator &Y) {
4765 return X.Iter != Y.Iter;
4766 }
4767};
4768
4769template<typename Derived>
4770template<typename InputIterator>
4771bool TreeTransform<Derived>::TransformTemplateArguments(
4772 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4773 bool Uneval) {
4774 for (; First != Last; ++First) {
4775 TemplateArgumentLoc Out;
4776 TemplateArgumentLoc In = *First;
4777
4778 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4779 // Unpack argument packs, which we translate them into separate
4780 // arguments.
4781 // FIXME: We could do much better if we could guarantee that the
4782 // TemplateArgumentLocInfo for the pack expansion would be usable for
4783 // all of the template arguments in the argument pack.
4784 typedef TemplateArgumentLocInventIterator<Derived,
4785 TemplateArgument::pack_iterator>
4786 PackLocIterator;
4787 if (TransformTemplateArguments(PackLocIterator(*this,
4788 In.getArgument().pack_begin()),
4789 PackLocIterator(*this,
4790 In.getArgument().pack_end()),
4791 Outputs, Uneval))
4792 return true;
4793
4794 continue;
4795 }
4796
4797 if (In.getArgument().isPackExpansion()) {
4798 // We have a pack expansion, for which we will be substituting into
4799 // the pattern.
4800 SourceLocation Ellipsis;
4801 std::optional<unsigned> OrigNumExpansions;
4802 TemplateArgumentLoc Pattern
4803 = getSema().getTemplateArgumentPackExpansionPattern(
4804 In, Ellipsis, OrigNumExpansions);
4805
4806 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4807 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4808 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4809
4810 // Determine whether the set of unexpanded parameter packs can and should
4811 // be expanded.
4812 bool Expand = true;
4813 bool RetainExpansion = false;
4814 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4815 if (getDerived().TryExpandParameterPacks(Ellipsis,
4816 Pattern.getSourceRange(),
4817 Unexpanded,
4818 Expand,
4819 RetainExpansion,
4820 NumExpansions))
4821 return true;
4822
4823 if (!Expand) {
4824 // The transform has determined that we should perform a simple
4825 // transformation on the pack expansion, producing another pack
4826 // expansion.
4827 TemplateArgumentLoc OutPattern;
4828 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4829 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4830 return true;
4831
4832 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4833 NumExpansions);
4834 if (Out.getArgument().isNull())
4835 return true;
4836
4837 Outputs.addArgument(Loc: Out);
4838 continue;
4839 }
4840
4841 // The transform has determined that we should perform an elementwise
4842 // expansion of the pattern. Do so.
4843 for (unsigned I = 0; I != *NumExpansions; ++I) {
4844 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4845
4846 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4847 return true;
4848
4849 if (Out.getArgument().containsUnexpandedParameterPack()) {
4850 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4851 OrigNumExpansions);
4852 if (Out.getArgument().isNull())
4853 return true;
4854 }
4855
4856 Outputs.addArgument(Loc: Out);
4857 }
4858
4859 // If we're supposed to retain a pack expansion, do so by temporarily
4860 // forgetting the partially-substituted parameter pack.
4861 if (RetainExpansion) {
4862 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4863
4864 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4865 return true;
4866
4867 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4868 OrigNumExpansions);
4869 if (Out.getArgument().isNull())
4870 return true;
4871
4872 Outputs.addArgument(Loc: Out);
4873 }
4874
4875 continue;
4876 }
4877
4878 // The simple case:
4879 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4880 return true;
4881
4882 Outputs.addArgument(Loc: Out);
4883 }
4884
4885 return false;
4886
4887}
4888
4889//===----------------------------------------------------------------------===//
4890// Type transformation
4891//===----------------------------------------------------------------------===//
4892
4893template<typename Derived>
4894QualType TreeTransform<Derived>::TransformType(QualType T) {
4895 if (getDerived().AlreadyTransformed(T))
4896 return T;
4897
4898 // Temporary workaround. All of these transformations should
4899 // eventually turn into transformations on TypeLocs.
4900 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4901 getDerived().getBaseLocation());
4902
4903 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4904
4905 if (!NewDI)
4906 return QualType();
4907
4908 return NewDI->getType();
4909}
4910
4911template<typename Derived>
4912TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4913 // Refine the base location to the type's location.
4914 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4915 getDerived().getBaseEntity());
4916 if (getDerived().AlreadyTransformed(DI->getType()))
4917 return DI;
4918
4919 TypeLocBuilder TLB;
4920
4921 TypeLoc TL = DI->getTypeLoc();
4922 TLB.reserve(Requested: TL.getFullDataSize());
4923
4924 QualType Result = getDerived().TransformType(TLB, TL);
4925 if (Result.isNull())
4926 return nullptr;
4927
4928 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
4929}
4930
4931template<typename Derived>
4932QualType
4933TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4934 switch (T.getTypeLocClass()) {
4935#define ABSTRACT_TYPELOC(CLASS, PARENT)
4936#define TYPELOC(CLASS, PARENT) \
4937 case TypeLoc::CLASS: \
4938 return getDerived().Transform##CLASS##Type(TLB, \
4939 T.castAs<CLASS##TypeLoc>());
4940#include "clang/AST/TypeLocNodes.def"
4941 }
4942
4943 llvm_unreachable("unhandled type loc!");
4944}
4945
4946template<typename Derived>
4947QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
4948 if (!isa<DependentNameType>(T))
4949 return TransformType(T);
4950
4951 if (getDerived().AlreadyTransformed(T))
4952 return T;
4953 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4954 getDerived().getBaseLocation());
4955 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4956 return NewDI ? NewDI->getType() : QualType();
4957}
4958
4959template<typename Derived>
4960TypeSourceInfo *
4961TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
4962 if (!isa<DependentNameType>(DI->getType()))
4963 return TransformType(DI);
4964
4965 // Refine the base location to the type's location.
4966 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4967 getDerived().getBaseEntity());
4968 if (getDerived().AlreadyTransformed(DI->getType()))
4969 return DI;
4970
4971 TypeLocBuilder TLB;
4972
4973 TypeLoc TL = DI->getTypeLoc();
4974 TLB.reserve(Requested: TL.getFullDataSize());
4975
4976 auto QTL = TL.getAs<QualifiedTypeLoc>();
4977 if (QTL)
4978 TL = QTL.getUnqualifiedLoc();
4979
4980 auto DNTL = TL.castAs<DependentNameTypeLoc>();
4981
4982 QualType Result = getDerived().TransformDependentNameType(
4983 TLB, DNTL, /*DeducedTSTContext*/true);
4984 if (Result.isNull())
4985 return nullptr;
4986
4987 if (QTL) {
4988 Result = getDerived().RebuildQualifiedType(Result, QTL);
4989 if (Result.isNull())
4990 return nullptr;
4991 TLB.TypeWasModifiedSafely(T: Result);
4992 }
4993
4994 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
4995}
4996
4997template<typename Derived>
4998QualType
4999TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5000 QualifiedTypeLoc T) {
5001 QualType Result;
5002 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5003 auto SuppressObjCLifetime =
5004 T.getType().getLocalQualifiers().hasObjCLifetime();
5005 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5006 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5007 SuppressObjCLifetime);
5008 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5009 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5010 TLB, STTP, SuppressObjCLifetime);
5011 } else {
5012 Result = getDerived().TransformType(TLB, UnqualTL);
5013 }
5014
5015 if (Result.isNull())
5016 return QualType();
5017
5018 Result = getDerived().RebuildQualifiedType(Result, T);
5019
5020 if (Result.isNull())
5021 return QualType();
5022
5023 // RebuildQualifiedType might have updated the type, but not in a way
5024 // that invalidates the TypeLoc. (There's no location information for
5025 // qualifiers.)
5026 TLB.TypeWasModifiedSafely(T: Result);
5027
5028 return Result;
5029}
5030
5031template <typename Derived>
5032QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5033 QualifiedTypeLoc TL) {
5034
5035 SourceLocation Loc = TL.getBeginLoc();
5036 Qualifiers Quals = TL.getType().getLocalQualifiers();
5037
5038 if ((T.getAddressSpace() != LangAS::Default &&
5039 Quals.getAddressSpace() != LangAS::Default) &&
5040 T.getAddressSpace() != Quals.getAddressSpace()) {
5041 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5042 << TL.getType() << T;
5043 return QualType();
5044 }
5045
5046 // C++ [dcl.fct]p7:
5047 // [When] adding cv-qualifications on top of the function type [...] the
5048 // cv-qualifiers are ignored.
5049 if (T->isFunctionType()) {
5050 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5051 AddressSpace: Quals.getAddressSpace());
5052 return T;
5053 }
5054
5055 // C++ [dcl.ref]p1:
5056 // when the cv-qualifiers are introduced through the use of a typedef-name
5057 // or decltype-specifier [...] the cv-qualifiers are ignored.
5058 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5059 // applied to a reference type.
5060 if (T->isReferenceType()) {
5061 // The only qualifier that applies to a reference type is restrict.
5062 if (!Quals.hasRestrict())
5063 return T;
5064 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5065 }
5066
5067 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5068 // resulting type.
5069 if (Quals.hasObjCLifetime()) {
5070 if (!T->isObjCLifetimeType() && !T->isDependentType())
5071 Quals.removeObjCLifetime();
5072 else if (T.getObjCLifetime()) {
5073 // Objective-C ARC:
5074 // A lifetime qualifier applied to a substituted template parameter
5075 // overrides the lifetime qualifier from the template argument.
5076 const AutoType *AutoTy;
5077 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5078 // 'auto' types behave the same way as template parameters.
5079 QualType Deduced = AutoTy->getDeducedType();
5080 Qualifiers Qs = Deduced.getQualifiers();
5081 Qs.removeObjCLifetime();
5082 Deduced =
5083 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5084 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5085 IsDependent: AutoTy->isDependentType(),
5086 /*isPack=*/IsPack: false,
5087 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5088 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5089 } else {
5090 // Otherwise, complain about the addition of a qualifier to an
5091 // already-qualified type.
5092 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5093 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5094 Quals.removeObjCLifetime();
5095 }
5096 }
5097 }
5098
5099 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5100}
5101
5102template<typename Derived>
5103TypeLoc
5104TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5105 QualType ObjectType,
5106 NamedDecl *UnqualLookup,
5107 CXXScopeSpec &SS) {
5108 if (getDerived().AlreadyTransformed(TL.getType()))
5109 return TL;
5110
5111 TypeSourceInfo *TSI =
5112 TransformTSIInObjectScope(TL, ObjectType, FirstQualifierInScope: UnqualLookup, SS);
5113 if (TSI)
5114 return TSI->getTypeLoc();
5115 return TypeLoc();
5116}
5117
5118template<typename Derived>
5119TypeSourceInfo *
5120TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5121 QualType ObjectType,
5122 NamedDecl *UnqualLookup,
5123 CXXScopeSpec &SS) {
5124 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5125 return TSInfo;
5126
5127 return TransformTSIInObjectScope(TL: TSInfo->getTypeLoc(), ObjectType,
5128 FirstQualifierInScope: UnqualLookup, SS);
5129}
5130
5131template <typename Derived>
5132TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5133 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5134 CXXScopeSpec &SS) {
5135 QualType T = TL.getType();
5136 assert(!getDerived().AlreadyTransformed(T));
5137
5138 TypeLocBuilder TLB;
5139 QualType Result;
5140
5141 if (isa<TemplateSpecializationType>(T)) {
5142 TemplateSpecializationTypeLoc SpecTL =
5143 TL.castAs<TemplateSpecializationTypeLoc>();
5144
5145 TemplateName Template = getDerived().TransformTemplateName(
5146 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5147 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5148 if (Template.isNull())
5149 return nullptr;
5150
5151 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5152 Template);
5153 } else if (isa<DependentTemplateSpecializationType>(T)) {
5154 DependentTemplateSpecializationTypeLoc SpecTL =
5155 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5156
5157 TemplateName Template
5158 = getDerived().RebuildTemplateName(SS,
5159 SpecTL.getTemplateKeywordLoc(),
5160 *SpecTL.getTypePtr()->getIdentifier(),
5161 SpecTL.getTemplateNameLoc(),
5162 ObjectType, UnqualLookup,
5163 /*AllowInjectedClassName*/true);
5164 if (Template.isNull())
5165 return nullptr;
5166
5167 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5168 SpecTL,
5169 Template,
5170 SS);
5171 } else {
5172 // Nothing special needs to be done for these.
5173 Result = getDerived().TransformType(TLB, TL);
5174 }
5175
5176 if (Result.isNull())
5177 return nullptr;
5178
5179 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5180}
5181
5182template <class TyLoc> static inline
5183QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5184 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5185 NewT.setNameLoc(T.getNameLoc());
5186 return T.getType();
5187}
5188
5189template<typename Derived>
5190QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5191 BuiltinTypeLoc T) {
5192 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5193 NewT.setBuiltinLoc(T.getBuiltinLoc());
5194 if (T.needsExtraLocalData())
5195 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5196 return T.getType();
5197}
5198
5199template<typename Derived>
5200QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5201 ComplexTypeLoc T) {
5202 // FIXME: recurse?
5203 return TransformTypeSpecType(TLB, T);
5204}
5205
5206template <typename Derived>
5207QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5208 AdjustedTypeLoc TL) {
5209 // Adjustments applied during transformation are handled elsewhere.
5210 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5211}
5212
5213template<typename Derived>
5214QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5215 DecayedTypeLoc TL) {
5216 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5217 if (OriginalType.isNull())
5218 return QualType();
5219
5220 QualType Result = TL.getType();
5221 if (getDerived().AlwaysRebuild() ||
5222 OriginalType != TL.getOriginalLoc().getType())
5223 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5224 TLB.push<DecayedTypeLoc>(Result);
5225 // Nothing to set for DecayedTypeLoc.
5226 return Result;
5227}
5228
5229template<typename Derived>
5230QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5231 PointerTypeLoc TL) {
5232 QualType PointeeType
5233 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5234 if (PointeeType.isNull())
5235 return QualType();
5236
5237 QualType Result = TL.getType();
5238 if (PointeeType->getAs<ObjCObjectType>()) {
5239 // A dependent pointer type 'T *' has is being transformed such
5240 // that an Objective-C class type is being replaced for 'T'. The
5241 // resulting pointer type is an ObjCObjectPointerType, not a
5242 // PointerType.
5243 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5244
5245 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5246 NewT.setStarLoc(TL.getStarLoc());
5247 return Result;
5248 }
5249
5250 if (getDerived().AlwaysRebuild() ||
5251 PointeeType != TL.getPointeeLoc().getType()) {
5252 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5253 if (Result.isNull())
5254 return QualType();
5255 }
5256
5257 // Objective-C ARC can add lifetime qualifiers to the type that we're
5258 // pointing to.
5259 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5260
5261 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5262 NewT.setSigilLoc(TL.getSigilLoc());
5263 return Result;
5264}
5265
5266template<typename Derived>
5267QualType
5268TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5269 BlockPointerTypeLoc TL) {
5270 QualType PointeeType
5271 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5272 if (PointeeType.isNull())
5273 return QualType();
5274
5275 QualType Result = TL.getType();
5276 if (getDerived().AlwaysRebuild() ||
5277 PointeeType != TL.getPointeeLoc().getType()) {
5278 Result = getDerived().RebuildBlockPointerType(PointeeType,
5279 TL.getSigilLoc());
5280 if (Result.isNull())
5281 return QualType();
5282 }
5283
5284 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5285 NewT.setSigilLoc(TL.getSigilLoc());
5286 return Result;
5287}
5288
5289/// Transforms a reference type. Note that somewhat paradoxically we
5290/// don't care whether the type itself is an l-value type or an r-value
5291/// type; we only care if the type was *written* as an l-value type
5292/// or an r-value type.
5293template<typename Derived>
5294QualType
5295TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5296 ReferenceTypeLoc TL) {
5297 const ReferenceType *T = TL.getTypePtr();
5298
5299 // Note that this works with the pointee-as-written.
5300 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5301 if (PointeeType.isNull())
5302 return QualType();
5303
5304 QualType Result = TL.getType();
5305 if (getDerived().AlwaysRebuild() ||
5306 PointeeType != T->getPointeeTypeAsWritten()) {
5307 Result = getDerived().RebuildReferenceType(PointeeType,
5308 T->isSpelledAsLValue(),
5309 TL.getSigilLoc());
5310 if (Result.isNull())
5311 return QualType();
5312 }
5313
5314 // Objective-C ARC can add lifetime qualifiers to the type that we're
5315 // referring to.
5316 TLB.TypeWasModifiedSafely(
5317 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5318
5319 // r-value references can be rebuilt as l-value references.
5320 ReferenceTypeLoc NewTL;
5321 if (isa<LValueReferenceType>(Result))
5322 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5323 else
5324 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5325 NewTL.setSigilLoc(TL.getSigilLoc());
5326
5327 return Result;
5328}
5329
5330template<typename Derived>
5331QualType
5332TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5333 LValueReferenceTypeLoc TL) {
5334 return TransformReferenceType(TLB, TL);
5335}
5336
5337template<typename Derived>
5338QualType
5339TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5340 RValueReferenceTypeLoc TL) {
5341 return TransformReferenceType(TLB, TL);
5342}
5343
5344template<typename Derived>
5345QualType
5346TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5347 MemberPointerTypeLoc TL) {
5348 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5349 if (PointeeType.isNull())
5350 return QualType();
5351
5352 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5353 TypeSourceInfo *NewClsTInfo = nullptr;
5354 if (OldClsTInfo) {
5355 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5356 if (!NewClsTInfo)
5357 return QualType();
5358 }
5359
5360 const MemberPointerType *T = TL.getTypePtr();
5361 QualType OldClsType = QualType(T->getClass(), 0);
5362 QualType NewClsType;
5363 if (NewClsTInfo)
5364 NewClsType = NewClsTInfo->getType();
5365 else {
5366 NewClsType = getDerived().TransformType(OldClsType);
5367 if (NewClsType.isNull())
5368 return QualType();
5369 }
5370
5371 QualType Result = TL.getType();
5372 if (getDerived().AlwaysRebuild() ||
5373 PointeeType != T->getPointeeType() ||
5374 NewClsType != OldClsType) {
5375 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5376 TL.getStarLoc());
5377 if (Result.isNull())
5378 return QualType();
5379 }
5380
5381 // If we had to adjust the pointee type when building a member pointer, make
5382 // sure to push TypeLoc info for it.
5383 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5384 if (MPT && PointeeType != MPT->getPointeeType()) {
5385 assert(isa<AdjustedType>(MPT->getPointeeType()));
5386 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5387 }
5388
5389 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5390 NewTL.setSigilLoc(TL.getSigilLoc());
5391 NewTL.setClassTInfo(NewClsTInfo);
5392
5393 return Result;
5394}
5395
5396template<typename Derived>
5397QualType
5398TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5399 ConstantArrayTypeLoc TL) {
5400 const ConstantArrayType *T = TL.getTypePtr();
5401 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5402 if (ElementType.isNull())
5403 return QualType();
5404
5405 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5406 Expr *OldSize = TL.getSizeExpr();
5407 if (!OldSize)
5408 OldSize = const_cast<Expr*>(T->getSizeExpr());
5409 Expr *NewSize = nullptr;
5410 if (OldSize) {
5411 EnterExpressionEvaluationContext Unevaluated(
5412 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5413 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5414 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5415 }
5416
5417 QualType Result = TL.getType();
5418 if (getDerived().AlwaysRebuild() ||
5419 ElementType != T->getElementType() ||
5420 (T->getSizeExpr() && NewSize != OldSize)) {
5421 Result = getDerived().RebuildConstantArrayType(ElementType,
5422 T->getSizeModifier(),
5423 T->getSize(), NewSize,
5424 T->getIndexTypeCVRQualifiers(),
5425 TL.getBracketsRange());
5426 if (Result.isNull())
5427 return QualType();
5428 }
5429
5430 // We might have either a ConstantArrayType or a VariableArrayType now:
5431 // a ConstantArrayType is allowed to have an element type which is a
5432 // VariableArrayType if the type is dependent. Fortunately, all array
5433 // types have the same location layout.
5434 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5435 NewTL.setLBracketLoc(TL.getLBracketLoc());
5436 NewTL.setRBracketLoc(TL.getRBracketLoc());
5437 NewTL.setSizeExpr(NewSize);
5438
5439 return Result;
5440}
5441
5442template<typename Derived>
5443QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5444 TypeLocBuilder &TLB,
5445 IncompleteArrayTypeLoc TL) {
5446 const IncompleteArrayType *T = TL.getTypePtr();
5447 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5448 if (ElementType.isNull())
5449 return QualType();
5450
5451 QualType Result = TL.getType();
5452 if (getDerived().AlwaysRebuild() ||
5453 ElementType != T->getElementType()) {
5454 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5455 T->getSizeModifier(),
5456 T->getIndexTypeCVRQualifiers(),
5457 TL.getBracketsRange());
5458 if (Result.isNull())
5459 return QualType();
5460 }
5461
5462 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5463 NewTL.setLBracketLoc(TL.getLBracketLoc());
5464 NewTL.setRBracketLoc(TL.getRBracketLoc());
5465 NewTL.setSizeExpr(nullptr);
5466
5467 return Result;
5468}
5469
5470template<typename Derived>
5471QualType
5472TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5473 VariableArrayTypeLoc TL) {
5474 const VariableArrayType *T = TL.getTypePtr();
5475 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5476 if (ElementType.isNull())
5477 return QualType();
5478
5479 ExprResult SizeResult;
5480 {
5481 EnterExpressionEvaluationContext Context(
5482 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5483 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5484 }
5485 if (SizeResult.isInvalid())
5486 return QualType();
5487 SizeResult =
5488 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5489 if (SizeResult.isInvalid())
5490 return QualType();
5491
5492 Expr *Size = SizeResult.get();
5493
5494 QualType Result = TL.getType();
5495 if (getDerived().AlwaysRebuild() ||
5496 ElementType != T->getElementType() ||
5497 Size != T->getSizeExpr()) {
5498 Result = getDerived().RebuildVariableArrayType(ElementType,
5499 T->getSizeModifier(),
5500 Size,
5501 T->getIndexTypeCVRQualifiers(),
5502 TL.getBracketsRange());
5503 if (Result.isNull())
5504 return QualType();
5505 }
5506
5507 // We might have constant size array now, but fortunately it has the same
5508 // location layout.
5509 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5510 NewTL.setLBracketLoc(TL.getLBracketLoc());
5511 NewTL.setRBracketLoc(TL.getRBracketLoc());
5512 NewTL.setSizeExpr(Size);
5513
5514 return Result;
5515}
5516
5517template<typename Derived>
5518QualType
5519TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5520 DependentSizedArrayTypeLoc TL) {
5521 const DependentSizedArrayType *T = TL.getTypePtr();
5522 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5523 if (ElementType.isNull())
5524 return QualType();
5525
5526 // Array bounds are constant expressions.
5527 EnterExpressionEvaluationContext Unevaluated(
5528 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5529
5530 // If we have a VLA then it won't be a constant.
5531 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5532
5533 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5534 Expr *origSize = TL.getSizeExpr();
5535 if (!origSize) origSize = T->getSizeExpr();
5536
5537 ExprResult sizeResult
5538 = getDerived().TransformExpr(origSize);
5539 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
5540 if (sizeResult.isInvalid())
5541 return QualType();
5542
5543 Expr *size = sizeResult.get();
5544
5545 QualType Result = TL.getType();
5546 if (getDerived().AlwaysRebuild() ||
5547 ElementType != T->getElementType() ||
5548 size != origSize) {
5549 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5550 T->getSizeModifier(),
5551 size,
5552 T->getIndexTypeCVRQualifiers(),
5553 TL.getBracketsRange());
5554 if (Result.isNull())
5555 return QualType();
5556 }
5557
5558 // We might have any sort of array type now, but fortunately they
5559 // all have the same location layout.
5560 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5561 NewTL.setLBracketLoc(TL.getLBracketLoc());
5562 NewTL.setRBracketLoc(TL.getRBracketLoc());
5563 NewTL.setSizeExpr(size);
5564
5565 return Result;
5566}
5567
5568template <typename Derived>
5569QualType TreeTransform<Derived>::TransformDependentVectorType(
5570 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5571 const DependentVectorType *T = TL.getTypePtr();
5572 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5573 if (ElementType.isNull())
5574 return QualType();
5575
5576 EnterExpressionEvaluationContext Unevaluated(
5577 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5578
5579 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5580 Size = SemaRef.ActOnConstantExpression(Res: Size);
5581 if (Size.isInvalid())
5582 return QualType();
5583
5584 QualType Result = TL.getType();
5585 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5586 Size.get() != T->getSizeExpr()) {
5587 Result = getDerived().RebuildDependentVectorType(
5588 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5589 if (Result.isNull())
5590 return QualType();
5591 }
5592
5593 // Result might be dependent or not.
5594 if (isa<DependentVectorType>(Result)) {
5595 DependentVectorTypeLoc NewTL =
5596 TLB.push<DependentVectorTypeLoc>(Result);
5597 NewTL.setNameLoc(TL.getNameLoc());
5598 } else {
5599 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5600 NewTL.setNameLoc(TL.getNameLoc());
5601 }
5602
5603 return Result;
5604}
5605
5606template<typename Derived>
5607QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5608 TypeLocBuilder &TLB,
5609 DependentSizedExtVectorTypeLoc TL) {
5610 const DependentSizedExtVectorType *T = TL.getTypePtr();
5611
5612 // FIXME: ext vector locs should be nested
5613 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5614 if (ElementType.isNull())
5615 return QualType();
5616
5617 // Vector sizes are constant expressions.
5618 EnterExpressionEvaluationContext Unevaluated(
5619 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5620
5621 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5622 Size = SemaRef.ActOnConstantExpression(Res: Size);
5623 if (Size.isInvalid())
5624 return QualType();
5625
5626 QualType Result = TL.getType();
5627 if (getDerived().AlwaysRebuild() ||
5628 ElementType != T->getElementType() ||
5629 Size.get() != T->getSizeExpr()) {
5630 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5631 Size.get(),
5632 T->getAttributeLoc());
5633 if (Result.isNull())
5634 return QualType();
5635 }
5636
5637 // Result might be dependent or not.
5638 if (isa<DependentSizedExtVectorType>(Result)) {
5639 DependentSizedExtVectorTypeLoc NewTL
5640 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5641 NewTL.setNameLoc(TL.getNameLoc());
5642 } else {
5643 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5644 NewTL.setNameLoc(TL.getNameLoc());
5645 }
5646
5647 return Result;
5648}
5649
5650template <typename Derived>
5651QualType
5652TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5653 ConstantMatrixTypeLoc TL) {
5654 const ConstantMatrixType *T = TL.getTypePtr();
5655 QualType ElementType = getDerived().TransformType(T->getElementType());
5656 if (ElementType.isNull())
5657 return QualType();
5658
5659 QualType Result = TL.getType();
5660 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5661 Result = getDerived().RebuildConstantMatrixType(
5662 ElementType, T->getNumRows(), T->getNumColumns());
5663 if (Result.isNull())
5664 return QualType();
5665 }
5666
5667 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5668 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5669 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5670 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5671 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5672
5673 return Result;
5674}
5675
5676template <typename Derived>
5677QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5678 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5679 const DependentSizedMatrixType *T = TL.getTypePtr();
5680
5681 QualType ElementType = getDerived().TransformType(T->getElementType());
5682 if (ElementType.isNull()) {
5683 return QualType();
5684 }
5685
5686 // Matrix dimensions are constant expressions.
5687 EnterExpressionEvaluationContext Unevaluated(
5688 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5689
5690 Expr *origRows = TL.getAttrRowOperand();
5691 if (!origRows)
5692 origRows = T->getRowExpr();
5693 Expr *origColumns = TL.getAttrColumnOperand();
5694 if (!origColumns)
5695 origColumns = T->getColumnExpr();
5696
5697 ExprResult rowResult = getDerived().TransformExpr(origRows);
5698 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
5699 if (rowResult.isInvalid())
5700 return QualType();
5701
5702 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5703 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
5704 if (columnResult.isInvalid())
5705 return QualType();
5706
5707 Expr *rows = rowResult.get();
5708 Expr *columns = columnResult.get();
5709
5710 QualType Result = TL.getType();
5711 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5712 rows != origRows || columns != origColumns) {
5713 Result = getDerived().RebuildDependentSizedMatrixType(
5714 ElementType, rows, columns, T->getAttributeLoc());
5715
5716 if (Result.isNull())
5717 return QualType();
5718 }
5719
5720 // We might have any sort of matrix type now, but fortunately they
5721 // all have the same location layout.
5722 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5723 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5724 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5725 NewTL.setAttrRowOperand(rows);
5726 NewTL.setAttrColumnOperand(columns);
5727 return Result;
5728}
5729
5730template <typename Derived>
5731QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5732 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5733 const DependentAddressSpaceType *T = TL.getTypePtr();
5734
5735 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5736
5737 if (pointeeType.isNull())
5738 return QualType();
5739
5740 // Address spaces are constant expressions.
5741 EnterExpressionEvaluationContext Unevaluated(
5742 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5743
5744 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5745 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
5746 if (AddrSpace.isInvalid())
5747 return QualType();
5748
5749 QualType Result = TL.getType();
5750 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5751 AddrSpace.get() != T->getAddrSpaceExpr()) {
5752 Result = getDerived().RebuildDependentAddressSpaceType(
5753 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5754 if (Result.isNull())
5755 return QualType();
5756 }
5757
5758 // Result might be dependent or not.
5759 if (isa<DependentAddressSpaceType>(Result)) {
5760 DependentAddressSpaceTypeLoc NewTL =
5761 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5762
5763 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5764 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5765 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5766
5767 } else {
5768 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5769 Result, getDerived().getBaseLocation());
5770 TransformType(TLB, DI->getTypeLoc());
5771 }
5772
5773 return Result;
5774}
5775
5776template <typename Derived>
5777QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5778 VectorTypeLoc TL) {
5779 const VectorType *T = TL.getTypePtr();
5780 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5781 if (ElementType.isNull())
5782 return QualType();
5783
5784 QualType Result = TL.getType();
5785 if (getDerived().AlwaysRebuild() ||
5786 ElementType != T->getElementType()) {
5787 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5788 T->getVectorKind());
5789 if (Result.isNull())
5790 return QualType();
5791 }
5792
5793 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5794 NewTL.setNameLoc(TL.getNameLoc());
5795
5796 return Result;
5797}
5798
5799template<typename Derived>
5800QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5801 ExtVectorTypeLoc TL) {
5802 const VectorType *T = TL.getTypePtr();
5803 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5804 if (ElementType.isNull())
5805 return QualType();
5806
5807 QualType Result = TL.getType();
5808 if (getDerived().AlwaysRebuild() ||
5809 ElementType != T->getElementType()) {
5810 Result = getDerived().RebuildExtVectorType(ElementType,
5811 T->getNumElements(),
5812 /*FIXME*/ SourceLocation());
5813 if (Result.isNull())
5814 return QualType();
5815 }
5816
5817 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5818 NewTL.setNameLoc(TL.getNameLoc());
5819
5820 return Result;
5821}
5822
5823template <typename Derived>
5824ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5825 ParmVarDecl *OldParm, int indexAdjustment,
5826 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5827 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5828 TypeSourceInfo *NewDI = nullptr;
5829
5830 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5831 // If we're substituting into a pack expansion type and we know the
5832 // length we want to expand to, just substitute for the pattern.
5833 TypeLoc OldTL = OldDI->getTypeLoc();
5834 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5835
5836 TypeLocBuilder TLB;
5837 TypeLoc NewTL = OldDI->getTypeLoc();
5838 TLB.reserve(Requested: NewTL.getFullDataSize());
5839
5840 QualType Result = getDerived().TransformType(TLB,
5841 OldExpansionTL.getPatternLoc());
5842 if (Result.isNull())
5843 return nullptr;
5844
5845 Result = RebuildPackExpansionType(Pattern: Result,
5846 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
5847 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
5848 NumExpansions);
5849 if (Result.isNull())
5850 return nullptr;
5851
5852 PackExpansionTypeLoc NewExpansionTL
5853 = TLB.push<PackExpansionTypeLoc>(Result);
5854 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5855 NewDI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5856 } else
5857 NewDI = getDerived().TransformType(OldDI);
5858 if (!NewDI)
5859 return nullptr;
5860
5861 if (NewDI == OldDI && indexAdjustment == 0)
5862 return OldParm;
5863
5864 ParmVarDecl *newParm = ParmVarDecl::Create(C&: SemaRef.Context,
5865 DC: OldParm->getDeclContext(),
5866 StartLoc: OldParm->getInnerLocStart(),
5867 IdLoc: OldParm->getLocation(),
5868 Id: OldParm->getIdentifier(),
5869 T: NewDI->getType(),
5870 TInfo: NewDI,
5871 S: OldParm->getStorageClass(),
5872 /* DefArg */ DefArg: nullptr);
5873 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
5874 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
5875 transformedLocalDecl(Old: OldParm, New: {newParm});
5876 return newParm;
5877}
5878
5879template <typename Derived>
5880bool TreeTransform<Derived>::TransformFunctionTypeParams(
5881 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5882 const QualType *ParamTypes,
5883 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5884 SmallVectorImpl<QualType> &OutParamTypes,
5885 SmallVectorImpl<ParmVarDecl *> *PVars,
5886 Sema::ExtParameterInfoBuilder &PInfos,
5887 unsigned *LastParamTransformed) {
5888 int indexAdjustment = 0;
5889
5890 unsigned NumParams = Params.size();
5891 for (unsigned i = 0; i != NumParams; ++i) {
5892 if (LastParamTransformed)
5893 *LastParamTransformed = i;
5894 if (ParmVarDecl *OldParm = Params[i]) {
5895 assert(OldParm->getFunctionScopeIndex() == i);
5896
5897 std::optional<unsigned> NumExpansions;
5898 ParmVarDecl *NewParm = nullptr;
5899 if (OldParm->isParameterPack()) {
5900 // We have a function parameter pack that may need to be expanded.
5901 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5902
5903 // Find the parameter packs that could be expanded.
5904 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5905 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5906 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5907 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5908
5909 // Determine whether we should expand the parameter packs.
5910 bool ShouldExpand = false;
5911 bool RetainExpansion = false;
5912 std::optional<unsigned> OrigNumExpansions;
5913 if (Unexpanded.size() > 0) {
5914 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5915 NumExpansions = OrigNumExpansions;
5916 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5917 Pattern.getSourceRange(),
5918 Unexpanded,
5919 ShouldExpand,
5920 RetainExpansion,
5921 NumExpansions)) {
5922 return true;
5923 }
5924 } else {
5925#ifndef NDEBUG
5926 const AutoType *AT =
5927 Pattern.getType().getTypePtr()->getContainedAutoType();
5928 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5929 "Could not find parameter packs or undeduced auto type!");
5930#endif
5931 }
5932
5933 if (ShouldExpand) {
5934 // Expand the function parameter pack into multiple, separate
5935 // parameters.
5936 getDerived().ExpandingFunctionParameterPack(OldParm);
5937 for (unsigned I = 0; I != *NumExpansions; ++I) {
5938 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5939 ParmVarDecl *NewParm
5940 = getDerived().TransformFunctionTypeParam(OldParm,
5941 indexAdjustment++,
5942 OrigNumExpansions,
5943 /*ExpectParameterPack=*/false);
5944 if (!NewParm)
5945 return true;
5946
5947 if (ParamInfos)
5948 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
5949 OutParamTypes.push_back(Elt: NewParm->getType());
5950 if (PVars)
5951 PVars->push_back(NewParm);
5952 }
5953
5954 // If we're supposed to retain a pack expansion, do so by temporarily
5955 // forgetting the partially-substituted parameter pack.
5956 if (RetainExpansion) {
5957 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5958 ParmVarDecl *NewParm
5959 = getDerived().TransformFunctionTypeParam(OldParm,
5960 indexAdjustment++,
5961 OrigNumExpansions,
5962 /*ExpectParameterPack=*/false);
5963 if (!NewParm)
5964 return true;
5965
5966 if (ParamInfos)
5967 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
5968 OutParamTypes.push_back(Elt: NewParm->getType());
5969 if (PVars)
5970 PVars->push_back(NewParm);
5971 }
5972
5973 // The next parameter should have the same adjustment as the
5974 // last thing we pushed, but we post-incremented indexAdjustment
5975 // on every push. Also, if we push nothing, the adjustment should
5976 // go down by one.
5977 indexAdjustment--;
5978
5979 // We're done with the pack expansion.
5980 continue;
5981 }
5982
5983 // We'll substitute the parameter now without expanding the pack
5984 // expansion.
5985 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5986 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
5987 indexAdjustment,
5988 NumExpansions,
5989 /*ExpectParameterPack=*/true);
5990 assert(NewParm->isParameterPack() &&
5991 "Parameter pack no longer a parameter pack after "
5992 "transformation.");
5993 } else {
5994 NewParm = getDerived().TransformFunctionTypeParam(
5995 OldParm, indexAdjustment, std::nullopt,
5996 /*ExpectParameterPack=*/false);
5997 }
5998
5999 if (!NewParm)
6000 return true;
6001
6002 if (ParamInfos)
6003 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6004 OutParamTypes.push_back(Elt: NewParm->getType());
6005 if (PVars)
6006 PVars->push_back(NewParm);
6007 continue;
6008 }
6009
6010 // Deal with the possibility that we don't have a parameter
6011 // declaration for this parameter.
6012 assert(ParamTypes);
6013 QualType OldType = ParamTypes[i];
6014 bool IsPackExpansion = false;
6015 std::optional<unsigned> NumExpansions;
6016 QualType NewType;
6017 if (const PackExpansionType *Expansion
6018 = dyn_cast<PackExpansionType>(OldType)) {
6019 // We have a function parameter pack that may need to be expanded.
6020 QualType Pattern = Expansion->getPattern();
6021 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6022 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6023
6024 // Determine whether we should expand the parameter packs.
6025 bool ShouldExpand = false;
6026 bool RetainExpansion = false;
6027 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6028 Unexpanded,
6029 ShouldExpand,
6030 RetainExpansion,
6031 NumExpansions)) {
6032 return true;
6033 }
6034
6035 if (ShouldExpand) {
6036 // Expand the function parameter pack into multiple, separate
6037 // parameters.
6038 for (unsigned I = 0; I != *NumExpansions; ++I) {
6039 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6040 QualType NewType = getDerived().TransformType(Pattern);
6041 if (NewType.isNull())
6042 return true;
6043
6044 if (NewType->containsUnexpandedParameterPack()) {
6045 NewType = getSema().getASTContext().getPackExpansionType(
6046 NewType, std::nullopt);
6047
6048 if (NewType.isNull())
6049 return true;
6050 }
6051
6052 if (ParamInfos)
6053 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6054 OutParamTypes.push_back(Elt: NewType);
6055 if (PVars)
6056 PVars->push_back(nullptr);
6057 }
6058
6059 // We're done with the pack expansion.
6060 continue;
6061 }
6062
6063 // If we're supposed to retain a pack expansion, do so by temporarily
6064 // forgetting the partially-substituted parameter pack.
6065 if (RetainExpansion) {
6066 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6067 QualType NewType = getDerived().TransformType(Pattern);
6068 if (NewType.isNull())
6069 return true;
6070
6071 if (ParamInfos)
6072 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6073 OutParamTypes.push_back(Elt: NewType);
6074 if (PVars)
6075 PVars->push_back(nullptr);
6076 }
6077
6078 // We'll substitute the parameter now without expanding the pack
6079 // expansion.
6080 OldType = Expansion->getPattern();
6081 IsPackExpansion = true;
6082 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6083 NewType = getDerived().TransformType(OldType);
6084 } else {
6085 NewType = getDerived().TransformType(OldType);
6086 }
6087
6088 if (NewType.isNull())
6089 return true;
6090
6091 if (IsPackExpansion)
6092 NewType = getSema().Context.getPackExpansionType(NewType,
6093 NumExpansions);
6094
6095 if (ParamInfos)
6096 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6097 OutParamTypes.push_back(Elt: NewType);
6098 if (PVars)
6099 PVars->push_back(nullptr);
6100 }
6101
6102#ifndef NDEBUG
6103 if (PVars) {
6104 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6105 if (ParmVarDecl *parm = (*PVars)[i])
6106 assert(parm->getFunctionScopeIndex() == i);
6107 }
6108#endif
6109
6110 return false;
6111}
6112
6113template<typename Derived>
6114QualType
6115TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6116 FunctionProtoTypeLoc TL) {
6117 SmallVector<QualType, 4> ExceptionStorage;
6118 return getDerived().TransformFunctionProtoType(
6119 TLB, TL, nullptr, Qualifiers(),
6120 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6121 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6122 ExceptionStorage, Changed);
6123 });
6124}
6125
6126template<typename Derived> template<typename Fn>
6127QualType TreeTransform<Derived>::TransformFunctionProtoType(
6128 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6129 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6130
6131 // Transform the parameters and return type.
6132 //
6133 // We are required to instantiate the params and return type in source order.
6134 // When the function has a trailing return type, we instantiate the
6135 // parameters before the return type, since the return type can then refer
6136 // to the parameters themselves (via decltype, sizeof, etc.).
6137 //
6138 SmallVector<QualType, 4> ParamTypes;
6139 SmallVector<ParmVarDecl*, 4> ParamDecls;
6140 Sema::ExtParameterInfoBuilder ExtParamInfos;
6141 const FunctionProtoType *T = TL.getTypePtr();
6142
6143 QualType ResultType;
6144
6145 if (T->hasTrailingReturn()) {
6146 if (getDerived().TransformFunctionTypeParams(
6147 TL.getBeginLoc(), TL.getParams(),
6148 TL.getTypePtr()->param_type_begin(),
6149 T->getExtParameterInfosOrNull(),
6150 ParamTypes, &ParamDecls, ExtParamInfos))
6151 return QualType();
6152
6153 {
6154 // C++11 [expr.prim.general]p3:
6155 // If a declaration declares a member function or member function
6156 // template of a class X, the expression this is a prvalue of type
6157 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6158 // and the end of the function-definition, member-declarator, or
6159 // declarator.
6160 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6161 Sema::CXXThisScopeRAII ThisScope(
6162 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6163
6164 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6165 if (ResultType.isNull())
6166 return QualType();
6167 }
6168 }
6169 else {
6170 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6171 if (ResultType.isNull())
6172 return QualType();
6173
6174 if (getDerived().TransformFunctionTypeParams(
6175 TL.getBeginLoc(), TL.getParams(),
6176 TL.getTypePtr()->param_type_begin(),
6177 T->getExtParameterInfosOrNull(),
6178 ParamTypes, &ParamDecls, ExtParamInfos))
6179 return QualType();
6180 }
6181
6182 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6183
6184 bool EPIChanged = false;
6185 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6186 return QualType();
6187
6188 // Handle extended parameter information.
6189 if (auto NewExtParamInfos =
6190 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6191 if (!EPI.ExtParameterInfos ||
6192 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6193 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6194 EPIChanged = true;
6195 }
6196 EPI.ExtParameterInfos = NewExtParamInfos;
6197 } else if (EPI.ExtParameterInfos) {
6198 EPIChanged = true;
6199 EPI.ExtParameterInfos = nullptr;
6200 }
6201
6202 QualType Result = TL.getType();
6203 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6204 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6205 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6206 if (Result.isNull())
6207 return QualType();
6208 }
6209
6210 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6211 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6212 NewTL.setLParenLoc(TL.getLParenLoc());
6213 NewTL.setRParenLoc(TL.getRParenLoc());
6214 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6215 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6216 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6217 NewTL.setParam(i, ParamDecls[i]);
6218
6219 return Result;
6220}
6221
6222template<typename Derived>
6223bool TreeTransform<Derived>::TransformExceptionSpec(
6224 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6225 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6226 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6227
6228 // Instantiate a dynamic noexcept expression, if any.
6229 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6230 // Update this scrope because ContextDecl in Sema will be used in
6231 // TransformExpr.
6232 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6233 Sema::CXXThisScopeRAII ThisScope(
6234 SemaRef, Method ? Method->getParent() : nullptr,
6235 Method ? Method->getMethodQualifiers() : Qualifiers{},
6236 Method != nullptr);
6237 EnterExpressionEvaluationContext Unevaluated(
6238 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6239 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6240 if (NoexceptExpr.isInvalid())
6241 return true;
6242
6243 ExceptionSpecificationType EST = ESI.Type;
6244 NoexceptExpr =
6245 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6246 if (NoexceptExpr.isInvalid())
6247 return true;
6248
6249 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6250 Changed = true;
6251 ESI.NoexceptExpr = NoexceptExpr.get();
6252 ESI.Type = EST;
6253 }
6254
6255 if (ESI.Type != EST_Dynamic)
6256 return false;
6257
6258 // Instantiate a dynamic exception specification's type.
6259 for (QualType T : ESI.Exceptions) {
6260 if (const PackExpansionType *PackExpansion =
6261 T->getAs<PackExpansionType>()) {
6262 Changed = true;
6263
6264 // We have a pack expansion. Instantiate it.
6265 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6266 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6267 Unexpanded);
6268 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6269
6270 // Determine whether the set of unexpanded parameter packs can and
6271 // should
6272 // be expanded.
6273 bool Expand = false;
6274 bool RetainExpansion = false;
6275 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6276 // FIXME: Track the location of the ellipsis (and track source location
6277 // information for the types in the exception specification in general).
6278 if (getDerived().TryExpandParameterPacks(
6279 Loc, SourceRange(), Unexpanded, Expand,
6280 RetainExpansion, NumExpansions))
6281 return true;
6282
6283 if (!Expand) {
6284 // We can't expand this pack expansion into separate arguments yet;
6285 // just substitute into the pattern and create a new pack expansion
6286 // type.
6287 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6288 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6289 if (U.isNull())
6290 return true;
6291
6292 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6293 Exceptions.push_back(U);
6294 continue;
6295 }
6296
6297 // Substitute into the pack expansion pattern for each slice of the
6298 // pack.
6299 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6300 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6301
6302 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6303 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6304 return true;
6305
6306 Exceptions.push_back(U);
6307 }
6308 } else {
6309 QualType U = getDerived().TransformType(T);
6310 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6311 return true;
6312 if (T != U)
6313 Changed = true;
6314
6315 Exceptions.push_back(U);
6316 }
6317 }
6318
6319 ESI.Exceptions = Exceptions;
6320 if (ESI.Exceptions.empty())
6321 ESI.Type = EST_DynamicNone;
6322 return false;
6323}
6324
6325template<typename Derived>
6326QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6327 TypeLocBuilder &TLB,
6328 FunctionNoProtoTypeLoc TL) {
6329 const FunctionNoProtoType *T = TL.getTypePtr();
6330 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6331 if (ResultType.isNull())
6332 return QualType();
6333
6334 QualType Result = TL.getType();
6335 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6336 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6337
6338 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6339 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6340 NewTL.setLParenLoc(TL.getLParenLoc());
6341 NewTL.setRParenLoc(TL.getRParenLoc());
6342 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6343
6344 return Result;
6345}
6346
6347template <typename Derived>
6348QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6349 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6350 const UnresolvedUsingType *T = TL.getTypePtr();
6351 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6352 if (!D)
6353 return QualType();
6354
6355 QualType Result = TL.getType();
6356 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6357 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6358 if (Result.isNull())
6359 return QualType();
6360 }
6361
6362 // We might get an arbitrary type spec type back. We should at
6363 // least always get a type spec type, though.
6364 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(T: Result);
6365 NewTL.setNameLoc(TL.getNameLoc());
6366
6367 return Result;
6368}
6369
6370template <typename Derived>
6371QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6372 UsingTypeLoc TL) {
6373 const UsingType *T = TL.getTypePtr();
6374
6375 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6376 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6377 if (!Found)
6378 return QualType();
6379
6380 QualType Underlying = getDerived().TransformType(T->desugar());
6381 if (Underlying.isNull())
6382 return QualType();
6383
6384 QualType Result = TL.getType();
6385 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6386 Underlying != T->getUnderlyingType()) {
6387 Result = getDerived().RebuildUsingType(Found, Underlying);
6388 if (Result.isNull())
6389 return QualType();
6390 }
6391
6392 TLB.pushTypeSpec(T: Result).setNameLoc(TL.getNameLoc());
6393 return Result;
6394}
6395
6396template<typename Derived>
6397QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6398 TypedefTypeLoc TL) {
6399 const TypedefType *T = TL.getTypePtr();
6400 TypedefNameDecl *Typedef
6401 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6402 T->getDecl()));
6403 if (!Typedef)
6404 return QualType();
6405
6406 QualType Result = TL.getType();
6407 if (getDerived().AlwaysRebuild() ||
6408 Typedef != T->getDecl()) {
6409 Result = getDerived().RebuildTypedefType(Typedef);
6410 if (Result.isNull())
6411 return QualType();
6412 }
6413
6414 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6415 NewTL.setNameLoc(TL.getNameLoc());
6416
6417 return Result;
6418}
6419
6420template<typename Derived>
6421QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6422 TypeOfExprTypeLoc TL) {
6423 // typeof expressions are not potentially evaluated contexts
6424 EnterExpressionEvaluationContext Unevaluated(
6425 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6426 Sema::ReuseLambdaContextDecl);
6427
6428 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6429 if (E.isInvalid())
6430 return QualType();
6431
6432 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
6433 if (E.isInvalid())
6434 return QualType();
6435
6436 QualType Result = TL.getType();
6437 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6438 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6439 Result =
6440 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6441 if (Result.isNull())
6442 return QualType();
6443 }
6444
6445 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6446 NewTL.setTypeofLoc(TL.getTypeofLoc());
6447 NewTL.setLParenLoc(TL.getLParenLoc());
6448 NewTL.setRParenLoc(TL.getRParenLoc());
6449
6450 return Result;
6451}
6452
6453template<typename Derived>
6454QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6455 TypeOfTypeLoc TL) {
6456 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6457 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6458 if (!New_Under_TI)
6459 return QualType();
6460
6461 QualType Result = TL.getType();
6462 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6463 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6464 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6465 if (Result.isNull())
6466 return QualType();
6467 }
6468
6469 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6470 NewTL.setTypeofLoc(TL.getTypeofLoc());
6471 NewTL.setLParenLoc(TL.getLParenLoc());
6472 NewTL.setRParenLoc(TL.getRParenLoc());
6473 NewTL.setUnmodifiedTInfo(New_Under_TI);
6474
6475 return Result;
6476}
6477
6478template<typename Derived>
6479QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6480 DecltypeTypeLoc TL) {
6481 const DecltypeType *T = TL.getTypePtr();
6482
6483 // decltype expressions are not potentially evaluated contexts
6484 EnterExpressionEvaluationContext Unevaluated(
6485 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6486 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6487
6488 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6489 if (E.isInvalid())
6490 return QualType();
6491
6492 E = getSema().ActOnDecltypeExpression(E.get());
6493 if (E.isInvalid())
6494 return QualType();
6495
6496 QualType Result = TL.getType();
6497 if (getDerived().AlwaysRebuild() ||
6498 E.get() != T->getUnderlyingExpr()) {
6499 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6500 if (Result.isNull())
6501 return QualType();
6502 }
6503 else E.get();
6504
6505 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6506 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6507 NewTL.setRParenLoc(TL.getRParenLoc());
6508 return Result;
6509}
6510
6511template <typename Derived>
6512QualType
6513TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6514 PackIndexingTypeLoc TL) {
6515 // Transform the index
6516 ExprResult IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6517 if (IndexExpr.isInvalid())
6518 return QualType();
6519 QualType Pattern = TL.getPattern();
6520
6521 const PackIndexingType *PIT = TL.getTypePtr();
6522 SmallVector<QualType, 5> SubtitutedTypes;
6523 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6524
6525 bool NotYetExpanded = Types.empty();
6526 bool FullySubstituted = true;
6527
6528 if (Types.empty())
6529 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6530
6531 for (const QualType &T : Types) {
6532 if (!T->containsUnexpandedParameterPack()) {
6533 QualType Transformed = getDerived().TransformType(T);
6534 if (Transformed.isNull())
6535 return QualType();
6536 SubtitutedTypes.push_back(Transformed);
6537 continue;
6538 }
6539
6540 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6541 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6542 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6543 // Determine whether the set of unexpanded parameter packs can and should
6544 // be expanded.
6545 bool ShouldExpand = true;
6546 bool RetainExpansion = false;
6547 std::optional<unsigned> OrigNumExpansions;
6548 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6549 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6550 Unexpanded, ShouldExpand,
6551 RetainExpansion, NumExpansions))
6552 return QualType();
6553 if (!ShouldExpand) {
6554 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6555 QualType Pack = getDerived().TransformType(T);
6556 if (Pack.isNull())
6557 return QualType();
6558 if (NotYetExpanded) {
6559 FullySubstituted = false;
6560 QualType Out = getDerived().RebuildPackIndexingType(
6561 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6562 FullySubstituted);
6563 if (Out.isNull())
6564 return QualType();
6565
6566 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6567 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6568 return Out;
6569 }
6570 SubtitutedTypes.push_back(Pack);
6571 continue;
6572 }
6573 for (unsigned I = 0; I != *NumExpansions; ++I) {
6574 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6575 QualType Out = getDerived().TransformType(T);
6576 if (Out.isNull())
6577 return QualType();
6578 SubtitutedTypes.push_back(Out);
6579 }
6580 // If we're supposed to retain a pack expansion, do so by temporarily
6581 // forgetting the partially-substituted parameter pack.
6582 if (RetainExpansion) {
6583 FullySubstituted = false;
6584 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6585 QualType Out = getDerived().TransformType(T);
6586 if (Out.isNull())
6587 return QualType();
6588 SubtitutedTypes.push_back(Out);
6589 }
6590 }
6591
6592 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6593
6594 QualType Out = getDerived().RebuildPackIndexingType(
6595 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6596 FullySubstituted, SubtitutedTypes);
6597 if (Out.isNull())
6598 return Out;
6599
6600 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6601 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6602 return Out;
6603}
6604
6605template<typename Derived>
6606QualType TreeTransform<Derived>::TransformUnaryTransformType(
6607 TypeLocBuilder &TLB,
6608 UnaryTransformTypeLoc TL) {
6609 QualType Result = TL.getType();
6610 if (Result->isDependentType()) {
6611 const UnaryTransformType *T = TL.getTypePtr();
6612 QualType NewBase =
6613 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6614 Result = getDerived().RebuildUnaryTransformType(NewBase,
6615 T->getUTTKind(),
6616 TL.getKWLoc());
6617 if (Result.isNull())
6618 return QualType();
6619 }
6620
6621 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6622 NewTL.setKWLoc(TL.getKWLoc());
6623 NewTL.setParensRange(TL.getParensRange());
6624 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6625 return Result;
6626}
6627
6628template<typename Derived>
6629QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6630 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6631 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6632
6633 CXXScopeSpec SS;
6634 TemplateName TemplateName = getDerived().TransformTemplateName(
6635 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6636 if (TemplateName.isNull())
6637 return QualType();
6638
6639 QualType OldDeduced = T->getDeducedType();
6640 QualType NewDeduced;
6641 if (!OldDeduced.isNull()) {
6642 NewDeduced = getDerived().TransformType(OldDeduced);
6643 if (NewDeduced.isNull())
6644 return QualType();
6645 }
6646
6647 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6648 TemplateName, NewDeduced);
6649 if (Result.isNull())
6650 return QualType();
6651
6652 DeducedTemplateSpecializationTypeLoc NewTL =
6653 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6654 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6655
6656 return Result;
6657}
6658
6659template<typename Derived>
6660QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6661 RecordTypeLoc TL) {
6662 const RecordType *T = TL.getTypePtr();
6663 RecordDecl *Record
6664 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6665 T->getDecl()));
6666 if (!Record)
6667 return QualType();
6668
6669 QualType Result = TL.getType();
6670 if (getDerived().AlwaysRebuild() ||
6671 Record != T->getDecl()) {
6672 Result = getDerived().RebuildRecordType(Record);
6673 if (Result.isNull())
6674 return QualType();
6675 }
6676
6677 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6678 NewTL.setNameLoc(TL.getNameLoc());
6679
6680 return Result;
6681}
6682
6683template<typename Derived>
6684QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6685 EnumTypeLoc TL) {
6686 const EnumType *T = TL.getTypePtr();
6687 EnumDecl *Enum
6688 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6689 T->getDecl()));
6690 if (!Enum)
6691 return QualType();
6692
6693 QualType Result = TL.getType();
6694 if (getDerived().AlwaysRebuild() ||
6695 Enum != T->getDecl()) {
6696 Result = getDerived().RebuildEnumType(Enum);
6697 if (Result.isNull())
6698 return QualType();
6699 }
6700
6701 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6702 NewTL.setNameLoc(TL.getNameLoc());
6703
6704 return Result;
6705}
6706
6707template<typename Derived>
6708QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6709 TypeLocBuilder &TLB,
6710 InjectedClassNameTypeLoc TL) {
6711 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6712 TL.getTypePtr()->getDecl());
6713 if (!D) return QualType();
6714
6715 QualType T = SemaRef.Context.getTypeDeclType(Decl: cast<TypeDecl>(D));
6716 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6717 return T;
6718}
6719
6720template<typename Derived>
6721QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6722 TypeLocBuilder &TLB,
6723 TemplateTypeParmTypeLoc TL) {
6724 return getDerived().TransformTemplateTypeParmType(
6725 TLB, TL,
6726 /*SuppressObjCLifetime=*/false);
6727}
6728
6729template <typename Derived>
6730QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6731 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6732 return TransformTypeSpecType(TLB, TL);
6733}
6734
6735template<typename Derived>
6736QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6737 TypeLocBuilder &TLB,
6738 SubstTemplateTypeParmTypeLoc TL) {
6739 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6740
6741 Decl *NewReplaced =
6742 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6743
6744 // Substitute into the replacement type, which itself might involve something
6745 // that needs to be transformed. This only tends to occur with default
6746 // template arguments of template template parameters.
6747 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6748 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6749 if (Replacement.isNull())
6750 return QualType();
6751
6752 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6753 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex());
6754
6755 // Propagate type-source information.
6756 SubstTemplateTypeParmTypeLoc NewTL
6757 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6758 NewTL.setNameLoc(TL.getNameLoc());
6759 return Result;
6760
6761}
6762
6763template<typename Derived>
6764QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6765 TypeLocBuilder &TLB,
6766 SubstTemplateTypeParmPackTypeLoc TL) {
6767 return getDerived().TransformSubstTemplateTypeParmPackType(
6768 TLB, TL, /*SuppressObjCLifetime=*/false);
6769}
6770
6771template <typename Derived>
6772QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6773 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6774 return TransformTypeSpecType(TLB, TL);
6775}
6776
6777template<typename Derived>
6778QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6779 TypeLocBuilder &TLB,
6780 TemplateSpecializationTypeLoc TL) {
6781 const TemplateSpecializationType *T = TL.getTypePtr();
6782
6783 // The nested-name-specifier never matters in a TemplateSpecializationType,
6784 // because we can't have a dependent nested-name-specifier anyway.
6785 CXXScopeSpec SS;
6786 TemplateName Template
6787 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6788 TL.getTemplateNameLoc());
6789 if (Template.isNull())
6790 return QualType();
6791
6792 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6793}
6794
6795template<typename Derived>
6796QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6797 AtomicTypeLoc TL) {
6798 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6799 if (ValueType.isNull())
6800 return QualType();
6801
6802 QualType Result = TL.getType();
6803 if (getDerived().AlwaysRebuild() ||
6804 ValueType != TL.getValueLoc().getType()) {
6805 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6806 if (Result.isNull())
6807 return QualType();
6808 }
6809
6810 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6811 NewTL.setKWLoc(TL.getKWLoc());
6812 NewTL.setLParenLoc(TL.getLParenLoc());
6813 NewTL.setRParenLoc(TL.getRParenLoc());
6814
6815 return Result;
6816}
6817
6818template <typename Derived>
6819QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6820 PipeTypeLoc TL) {
6821 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6822 if (ValueType.isNull())
6823 return QualType();
6824
6825 QualType Result = TL.getType();
6826 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6827 const PipeType *PT = Result->castAs<PipeType>();
6828 bool isReadPipe = PT->isReadOnly();
6829 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6830 if (Result.isNull())
6831 return QualType();
6832 }
6833
6834 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6835 NewTL.setKWLoc(TL.getKWLoc());
6836
6837 return Result;
6838}
6839
6840template <typename Derived>
6841QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6842 BitIntTypeLoc TL) {
6843 const BitIntType *EIT = TL.getTypePtr();
6844 QualType Result = TL.getType();
6845
6846 if (getDerived().AlwaysRebuild()) {
6847 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6848 EIT->getNumBits(), TL.getNameLoc());
6849 if (Result.isNull())
6850 return QualType();
6851 }
6852
6853 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6854 NewTL.setNameLoc(TL.getNameLoc());
6855 return Result;
6856}
6857
6858template <typename Derived>
6859QualType TreeTransform<Derived>::TransformDependentBitIntType(
6860 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6861 const DependentBitIntType *EIT = TL.getTypePtr();
6862
6863 EnterExpressionEvaluationContext Unevaluated(
6864 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6865 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6866 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
6867
6868 if (BitsExpr.isInvalid())
6869 return QualType();
6870
6871 QualType Result = TL.getType();
6872
6873 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6874 Result = getDerived().RebuildDependentBitIntType(
6875 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6876
6877 if (Result.isNull())
6878 return QualType();
6879 }
6880
6881 if (isa<DependentBitIntType>(Result)) {
6882 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6883 NewTL.setNameLoc(TL.getNameLoc());
6884 } else {
6885 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6886 NewTL.setNameLoc(TL.getNameLoc());
6887 }
6888 return Result;
6889}
6890
6891 /// Simple iterator that traverses the template arguments in a
6892 /// container that provides a \c getArgLoc() member function.
6893 ///
6894 /// This iterator is intended to be used with the iterator form of
6895 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6896 template<typename ArgLocContainer>
6897 class TemplateArgumentLocContainerIterator {
6898 ArgLocContainer *Container;
6899 unsigned Index;
6900
6901 public:
6902 typedef TemplateArgumentLoc value_type;
6903 typedef TemplateArgumentLoc reference;
6904 typedef int difference_type;
6905 typedef std::input_iterator_tag iterator_category;
6906
6907 class pointer {
6908 TemplateArgumentLoc Arg;
6909
6910 public:
6911 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6912
6913 const TemplateArgumentLoc *operator->() const {
6914 return &Arg;
6915 }
6916 };
6917
6918
6919 TemplateArgumentLocContainerIterator() {}
6920
6921 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6922 unsigned Index)
6923 : Container(&Container), Index(Index) { }
6924
6925 TemplateArgumentLocContainerIterator &operator++() {
6926 ++Index;
6927 return *this;
6928 }
6929
6930 TemplateArgumentLocContainerIterator operator++(int) {
6931 TemplateArgumentLocContainerIterator Old(*this);
6932 ++(*this);
6933 return Old;
6934 }
6935
6936 TemplateArgumentLoc operator*() const {
6937 return Container->getArgLoc(Index);
6938 }
6939
6940 pointer operator->() const {
6941 return pointer(Container->getArgLoc(Index));
6942 }
6943
6944 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
6945 const TemplateArgumentLocContainerIterator &Y) {
6946 return X.Container == Y.Container && X.Index == Y.Index;
6947 }
6948
6949 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
6950 const TemplateArgumentLocContainerIterator &Y) {
6951 return !(X == Y);
6952 }
6953 };
6954
6955template<typename Derived>
6956QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
6957 AutoTypeLoc TL) {
6958 const AutoType *T = TL.getTypePtr();
6959 QualType OldDeduced = T->getDeducedType();
6960 QualType NewDeduced;
6961 if (!OldDeduced.isNull()) {
6962 NewDeduced = getDerived().TransformType(OldDeduced);
6963 if (NewDeduced.isNull())
6964 return QualType();
6965 }
6966
6967 ConceptDecl *NewCD = nullptr;
6968 TemplateArgumentListInfo NewTemplateArgs;
6969 NestedNameSpecifierLoc NewNestedNameSpec;
6970 if (T->isConstrained()) {
6971 assert(TL.getConceptReference());
6972 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
6973 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
6974
6975 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6976 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6977 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
6978 if (getDerived().TransformTemplateArguments(
6979 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
6980 NewTemplateArgs))
6981 return QualType();
6982
6983 if (TL.getNestedNameSpecifierLoc()) {
6984 NewNestedNameSpec
6985 = getDerived().TransformNestedNameSpecifierLoc(
6986 TL.getNestedNameSpecifierLoc());
6987 if (!NewNestedNameSpec)
6988 return QualType();
6989 }
6990 }
6991
6992 QualType Result = TL.getType();
6993 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
6994 T->isDependentType() || T->isConstrained()) {
6995 // FIXME: Maybe don't rebuild if all template arguments are the same.
6996 llvm::SmallVector<TemplateArgument, 4> NewArgList;
6997 NewArgList.reserve(N: NewTemplateArgs.size());
6998 for (const auto &ArgLoc : NewTemplateArgs.arguments())
6999 NewArgList.push_back(Elt: ArgLoc.getArgument());
7000 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7001 NewArgList);
7002 if (Result.isNull())
7003 return QualType();
7004 }
7005
7006 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7007 NewTL.setNameLoc(TL.getNameLoc());
7008 NewTL.setRParenLoc(TL.getRParenLoc());
7009 NewTL.setConceptReference(nullptr);
7010
7011 if (T->isConstrained()) {
7012 DeclarationNameInfo DNI = DeclarationNameInfo(
7013 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7014 TL.getConceptNameLoc(),
7015 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7016 auto *CR = ConceptReference::Create(
7017 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7018 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7019 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7020 NewTL.setConceptReference(CR);
7021 }
7022
7023 return Result;
7024}
7025
7026template <typename Derived>
7027QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7028 TypeLocBuilder &TLB,
7029 TemplateSpecializationTypeLoc TL,
7030 TemplateName Template) {
7031 TemplateArgumentListInfo NewTemplateArgs;
7032 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7033 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7034 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7035 ArgIterator;
7036 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7037 ArgIterator(TL, TL.getNumArgs()),
7038 NewTemplateArgs))
7039 return QualType();
7040
7041 // FIXME: maybe don't rebuild if all the template arguments are the same.
7042
7043 QualType Result =
7044 getDerived().RebuildTemplateSpecializationType(Template,
7045 TL.getTemplateNameLoc(),
7046 NewTemplateArgs);
7047
7048 if (!Result.isNull()) {
7049 // Specializations of template template parameters are represented as
7050 // TemplateSpecializationTypes, and substitution of type alias templates
7051 // within a dependent context can transform them into
7052 // DependentTemplateSpecializationTypes.
7053 if (isa<DependentTemplateSpecializationType>(Result)) {
7054 DependentTemplateSpecializationTypeLoc NewTL
7055 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7056 NewTL.setElaboratedKeywordLoc(SourceLocation());
7057 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7058 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7059 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7060 NewTL.setLAngleLoc(TL.getLAngleLoc());
7061 NewTL.setRAngleLoc(TL.getRAngleLoc());
7062 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7063 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7064 return Result;
7065 }
7066
7067 TemplateSpecializationTypeLoc NewTL
7068 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7069 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7070 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7071 NewTL.setLAngleLoc(TL.getLAngleLoc());
7072 NewTL.setRAngleLoc(TL.getRAngleLoc());
7073 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7074 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7075 }
7076
7077 return Result;
7078}
7079
7080template <typename Derived>
7081QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7082 TypeLocBuilder &TLB,
7083 DependentTemplateSpecializationTypeLoc TL,
7084 TemplateName Template,
7085 CXXScopeSpec &SS) {
7086 TemplateArgumentListInfo NewTemplateArgs;
7087 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7088 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7089 typedef TemplateArgumentLocContainerIterator<
7090 DependentTemplateSpecializationTypeLoc> ArgIterator;
7091 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7092 ArgIterator(TL, TL.getNumArgs()),
7093 NewTemplateArgs))
7094 return QualType();
7095
7096 // FIXME: maybe don't rebuild if all the template arguments are the same.
7097
7098 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7099 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7100 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7101 DTN->getIdentifier(), NewTemplateArgs.arguments());
7102
7103 DependentTemplateSpecializationTypeLoc NewTL
7104 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7105 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7106 NewTL.setQualifierLoc(SS.getWithLocInContext(Context&: SemaRef.Context));
7107 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7108 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7109 NewTL.setLAngleLoc(TL.getLAngleLoc());
7110 NewTL.setRAngleLoc(TL.getRAngleLoc());
7111 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7112 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7113 return Result;
7114 }
7115
7116 QualType Result
7117 = getDerived().RebuildTemplateSpecializationType(Template,
7118 TL.getTemplateNameLoc(),
7119 NewTemplateArgs);
7120
7121 if (!Result.isNull()) {
7122 /// FIXME: Wrap this in an elaborated-type-specifier?
7123 TemplateSpecializationTypeLoc NewTL
7124 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7125 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7126 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7127 NewTL.setLAngleLoc(TL.getLAngleLoc());
7128 NewTL.setRAngleLoc(TL.getRAngleLoc());
7129 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7130 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7131 }
7132
7133 return Result;
7134}
7135
7136template<typename Derived>
7137QualType
7138TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7139 ElaboratedTypeLoc TL) {
7140 const ElaboratedType *T = TL.getTypePtr();
7141
7142 NestedNameSpecifierLoc QualifierLoc;
7143 // NOTE: the qualifier in an ElaboratedType is optional.
7144 if (TL.getQualifierLoc()) {
7145 QualifierLoc
7146 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7147 if (!QualifierLoc)
7148 return QualType();
7149 }
7150
7151 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7152 if (NamedT.isNull())
7153 return QualType();
7154
7155 // C++0x [dcl.type.elab]p2:
7156 // If the identifier resolves to a typedef-name or the simple-template-id
7157 // resolves to an alias template specialization, the
7158 // elaborated-type-specifier is ill-formed.
7159 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7160 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7161 if (const TemplateSpecializationType *TST =
7162 NamedT->getAs<TemplateSpecializationType>()) {
7163 TemplateName Template = TST->getTemplateName();
7164 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7165 Template.getAsTemplateDecl())) {
7166 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7167 diag::err_tag_reference_non_tag)
7168 << TAT << Sema::NTK_TypeAliasTemplate
7169 << llvm::to_underlying(
7170 ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()));
7171 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7172 }
7173 }
7174 }
7175
7176 QualType Result = TL.getType();
7177 if (getDerived().AlwaysRebuild() ||
7178 QualifierLoc != TL.getQualifierLoc() ||
7179 NamedT != T->getNamedType()) {
7180 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7181 T->getKeyword(),
7182 QualifierLoc, NamedT);
7183 if (Result.isNull())
7184 return QualType();
7185 }
7186
7187 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7188 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7189 NewTL.setQualifierLoc(QualifierLoc);
7190 return Result;
7191}
7192
7193template <typename Derived>
7194template <typename Fn>
7195QualType TreeTransform<Derived>::TransformAttributedType(
7196 TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
7197 const AttributedType *oldType = TL.getTypePtr();
7198 QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc());
7199 if (modifiedType.isNull())
7200 return QualType();
7201
7202 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7203 const Attr *oldAttr = TL.getAttr();
7204 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7205 if (oldAttr && !newAttr)
7206 return QualType();
7207
7208 QualType result = TL.getType();
7209
7210 // FIXME: dependent operand expressions?
7211 if (getDerived().AlwaysRebuild() ||
7212 modifiedType != oldType->getModifiedType()) {
7213 TypeLocBuilder AuxiliaryTLB;
7214 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7215 QualType equivalentType =
7216 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7217 if (equivalentType.isNull())
7218 return QualType();
7219
7220 // Check whether we can add nullability; it is only represented as
7221 // type sugar, and therefore cannot be diagnosed in any other way.
7222 if (auto nullability = oldType->getImmediateNullability()) {
7223 if (!modifiedType->canHaveNullability()) {
7224 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7225 : TL.getModifiedLoc().getBeginLoc()),
7226 diag::err_nullability_nonpointer)
7227 << DiagNullabilityKind(*nullability, false) << modifiedType;
7228 return QualType();
7229 }
7230 }
7231
7232 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7233 modifiedType,
7234 equivalentType);
7235 }
7236
7237 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7238 newTL.setAttr(newAttr);
7239 return result;
7240}
7241
7242template <typename Derived>
7243QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7244 AttributedTypeLoc TL) {
7245 return getDerived().TransformAttributedType(
7246 TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7247 return getDerived().TransformType(TLB, ModifiedLoc);
7248 });
7249}
7250
7251template <typename Derived>
7252QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7253 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7254 // The BTFTagAttributedType is available for C only.
7255 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7256}
7257
7258template<typename Derived>
7259QualType
7260TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7261 ParenTypeLoc TL) {
7262 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7263 if (Inner.isNull())
7264 return QualType();
7265
7266 QualType Result = TL.getType();
7267 if (getDerived().AlwaysRebuild() ||
7268 Inner != TL.getInnerLoc().getType()) {
7269 Result = getDerived().RebuildParenType(Inner);
7270 if (Result.isNull())
7271 return QualType();
7272 }
7273
7274 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7275 NewTL.setLParenLoc(TL.getLParenLoc());
7276 NewTL.setRParenLoc(TL.getRParenLoc());
7277 return Result;
7278}
7279
7280template <typename Derived>
7281QualType
7282TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7283 MacroQualifiedTypeLoc TL) {
7284 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7285 if (Inner.isNull())
7286 return QualType();
7287
7288 QualType Result = TL.getType();
7289 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7290 Result =
7291 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7292 if (Result.isNull())
7293 return QualType();
7294 }
7295
7296 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7297 NewTL.setExpansionLoc(TL.getExpansionLoc());
7298 return Result;
7299}
7300
7301template<typename Derived>
7302QualType TreeTransform<Derived>::TransformDependentNameType(
7303 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7304 return TransformDependentNameType(TLB, TL, DeducibleTSTContext: false);
7305}
7306
7307template<typename Derived>
7308QualType TreeTransform<Derived>::TransformDependentNameType(
7309 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7310 const DependentNameType *T = TL.getTypePtr();
7311
7312 NestedNameSpecifierLoc QualifierLoc
7313 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7314 if (!QualifierLoc)
7315 return QualType();
7316
7317 QualType Result
7318 = getDerived().RebuildDependentNameType(T->getKeyword(),
7319 TL.getElaboratedKeywordLoc(),
7320 QualifierLoc,
7321 T->getIdentifier(),
7322 TL.getNameLoc(),
7323 DeducedTSTContext);
7324 if (Result.isNull())
7325 return QualType();
7326
7327 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7328 QualType NamedT = ElabT->getNamedType();
7329 TLB.pushTypeSpec(T: NamedT).setNameLoc(TL.getNameLoc());
7330
7331 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7332 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7333 NewTL.setQualifierLoc(QualifierLoc);
7334 } else {
7335 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7336 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7337 NewTL.setQualifierLoc(QualifierLoc);
7338 NewTL.setNameLoc(TL.getNameLoc());
7339 }
7340 return Result;
7341}
7342
7343template<typename Derived>
7344QualType TreeTransform<Derived>::
7345 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7346 DependentTemplateSpecializationTypeLoc TL) {
7347 NestedNameSpecifierLoc QualifierLoc;
7348 if (TL.getQualifierLoc()) {
7349 QualifierLoc
7350 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7351 if (!QualifierLoc)
7352 return QualType();
7353 }
7354
7355 return getDerived()
7356 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7357}
7358
7359template<typename Derived>
7360QualType TreeTransform<Derived>::
7361TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7362 DependentTemplateSpecializationTypeLoc TL,
7363 NestedNameSpecifierLoc QualifierLoc) {
7364 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7365
7366 TemplateArgumentListInfo NewTemplateArgs;
7367 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7368 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7369
7370 typedef TemplateArgumentLocContainerIterator<
7371 DependentTemplateSpecializationTypeLoc> ArgIterator;
7372 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7373 ArgIterator(TL, TL.getNumArgs()),
7374 NewTemplateArgs))
7375 return QualType();
7376
7377 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7378 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7379 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7380 /*AllowInjectedClassName*/ false);
7381 if (Result.isNull())
7382 return QualType();
7383
7384 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7385 QualType NamedT = ElabT->getNamedType();
7386
7387 // Copy information relevant to the template specialization.
7388 TemplateSpecializationTypeLoc NamedTL
7389 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7390 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7391 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7392 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7393 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7394 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7395 NamedTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7396
7397 // Copy information relevant to the elaborated type.
7398 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7399 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7400 NewTL.setQualifierLoc(QualifierLoc);
7401 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7402 DependentTemplateSpecializationTypeLoc SpecTL
7403 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7404 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7405 SpecTL.setQualifierLoc(QualifierLoc);
7406 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7407 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7408 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7409 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7410 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7411 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7412 } else {
7413 TemplateSpecializationTypeLoc SpecTL
7414 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7415 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7416 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7417 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7418 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7419 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7420 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7421 }
7422 return Result;
7423}
7424
7425template<typename Derived>
7426QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7427 PackExpansionTypeLoc TL) {
7428 QualType Pattern
7429 = getDerived().TransformType(TLB, TL.getPatternLoc());
7430 if (Pattern.isNull())
7431 return QualType();
7432
7433 QualType Result = TL.getType();
7434 if (getDerived().AlwaysRebuild() ||
7435 Pattern != TL.getPatternLoc().getType()) {
7436 Result = getDerived().RebuildPackExpansionType(Pattern,
7437 TL.getPatternLoc().getSourceRange(),
7438 TL.getEllipsisLoc(),
7439 TL.getTypePtr()->getNumExpansions());
7440 if (Result.isNull())
7441 return QualType();
7442 }
7443
7444 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7445 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7446 return Result;
7447}
7448
7449template<typename Derived>
7450QualType
7451TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7452 ObjCInterfaceTypeLoc TL) {
7453 // ObjCInterfaceType is never dependent.
7454 TLB.pushFullCopy(TL);
7455 return TL.getType();
7456}
7457
7458template<typename Derived>
7459QualType
7460TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7461 ObjCTypeParamTypeLoc TL) {
7462 const ObjCTypeParamType *T = TL.getTypePtr();
7463 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7464 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7465 if (!OTP)
7466 return QualType();
7467
7468 QualType Result = TL.getType();
7469 if (getDerived().AlwaysRebuild() ||
7470 OTP != T->getDecl()) {
7471 Result = getDerived().RebuildObjCTypeParamType(
7472 OTP, TL.getProtocolLAngleLoc(),
7473 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7474 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7475 if (Result.isNull())
7476 return QualType();
7477 }
7478
7479 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7480 if (TL.getNumProtocols()) {
7481 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7482 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7483 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7484 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7485 }
7486 return Result;
7487}
7488
7489template<typename Derived>
7490QualType
7491TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7492 ObjCObjectTypeLoc TL) {
7493 // Transform base type.
7494 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7495 if (BaseType.isNull())
7496 return QualType();
7497
7498 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7499
7500 // Transform type arguments.
7501 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7502 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7503 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7504 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7505 QualType TypeArg = TypeArgInfo->getType();
7506 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7507 AnyChanged = true;
7508
7509 // We have a pack expansion. Instantiate it.
7510 const auto *PackExpansion = PackExpansionLoc.getType()
7511 ->castAs<PackExpansionType>();
7512 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7513 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7514 Unexpanded);
7515 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7516
7517 // Determine whether the set of unexpanded parameter packs can
7518 // and should be expanded.
7519 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7520 bool Expand = false;
7521 bool RetainExpansion = false;
7522 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7523 if (getDerived().TryExpandParameterPacks(
7524 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7525 Unexpanded, Expand, RetainExpansion, NumExpansions))
7526 return QualType();
7527
7528 if (!Expand) {
7529 // We can't expand this pack expansion into separate arguments yet;
7530 // just substitute into the pattern and create a new pack expansion
7531 // type.
7532 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7533
7534 TypeLocBuilder TypeArgBuilder;
7535 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7536 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7537 PatternLoc);
7538 if (NewPatternType.isNull())
7539 return QualType();
7540
7541 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7542 Pattern: NewPatternType, NumExpansions);
7543 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7544 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7545 NewTypeArgInfos.push_back(
7546 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
7547 continue;
7548 }
7549
7550 // Substitute into the pack expansion pattern for each slice of the
7551 // pack.
7552 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7553 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7554
7555 TypeLocBuilder TypeArgBuilder;
7556 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7557
7558 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7559 PatternLoc);
7560 if (NewTypeArg.isNull())
7561 return QualType();
7562
7563 NewTypeArgInfos.push_back(
7564 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
7565 }
7566
7567 continue;
7568 }
7569
7570 TypeLocBuilder TypeArgBuilder;
7571 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
7572 QualType NewTypeArg =
7573 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7574 if (NewTypeArg.isNull())
7575 return QualType();
7576
7577 // If nothing changed, just keep the old TypeSourceInfo.
7578 if (NewTypeArg == TypeArg) {
7579 NewTypeArgInfos.push_back(TypeArgInfo);
7580 continue;
7581 }
7582
7583 NewTypeArgInfos.push_back(
7584 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
7585 AnyChanged = true;
7586 }
7587
7588 QualType Result = TL.getType();
7589 if (getDerived().AlwaysRebuild() || AnyChanged) {
7590 // Rebuild the type.
7591 Result = getDerived().RebuildObjCObjectType(
7592 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7593 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7594 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7595 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7596
7597 if (Result.isNull())
7598 return QualType();
7599 }
7600
7601 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7602 NewT.setHasBaseTypeAsWritten(true);
7603 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7604 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7605 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
7606 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7607 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7608 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7609 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7610 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7611 return Result;
7612}
7613
7614template<typename Derived>
7615QualType
7616TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7617 ObjCObjectPointerTypeLoc TL) {
7618 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7619 if (PointeeType.isNull())
7620 return QualType();
7621
7622 QualType Result = TL.getType();
7623 if (getDerived().AlwaysRebuild() ||
7624 PointeeType != TL.getPointeeLoc().getType()) {
7625 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7626 TL.getStarLoc());
7627 if (Result.isNull())
7628 return QualType();
7629 }
7630
7631 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7632 NewT.setStarLoc(TL.getStarLoc());
7633 return Result;
7634}
7635
7636//===----------------------------------------------------------------------===//
7637// Statement transformation
7638//===----------------------------------------------------------------------===//
7639template<typename Derived>
7640StmtResult
7641TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7642 return S;
7643}
7644
7645template<typename Derived>
7646StmtResult
7647TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7648 return getDerived().TransformCompoundStmt(S, false);
7649}
7650
7651template<typename Derived>
7652StmtResult
7653TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7654 bool IsStmtExpr) {
7655 Sema::CompoundScopeRAII CompoundScope(getSema());
7656 Sema::FPFeaturesStateRAII FPSave(getSema());
7657 if (S->hasStoredFPFeatures())
7658 getSema().resetFPOptions(
7659 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7660
7661 const Stmt *ExprResult = S->getStmtExprResult();
7662 bool SubStmtInvalid = false;
7663 bool SubStmtChanged = false;
7664 SmallVector<Stmt*, 8> Statements;
7665 for (auto *B : S->body()) {
7666 StmtResult Result = getDerived().TransformStmt(
7667 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7668
7669 if (Result.isInvalid()) {
7670 // Immediately fail if this was a DeclStmt, since it's very
7671 // likely that this will cause problems for future statements.
7672 if (isa<DeclStmt>(B))
7673 return StmtError();
7674
7675 // Otherwise, just keep processing substatements and fail later.
7676 SubStmtInvalid = true;
7677 continue;
7678 }
7679
7680 SubStmtChanged = SubStmtChanged || Result.get() != B;
7681 Statements.push_back(Result.getAs<Stmt>());
7682 }
7683
7684 if (SubStmtInvalid)
7685 return StmtError();
7686
7687 if (!getDerived().AlwaysRebuild() &&
7688 !SubStmtChanged)
7689 return S;
7690
7691 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7692 Statements,
7693 S->getRBracLoc(),
7694 IsStmtExpr);
7695}
7696
7697template<typename Derived>
7698StmtResult
7699TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7700 ExprResult LHS, RHS;
7701 {
7702 EnterExpressionEvaluationContext Unevaluated(
7703 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7704
7705 // Transform the left-hand case value.
7706 LHS = getDerived().TransformExpr(S->getLHS());
7707 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
7708 if (LHS.isInvalid())
7709 return StmtError();
7710
7711 // Transform the right-hand case value (for the GNU case-range extension).
7712 RHS = getDerived().TransformExpr(S->getRHS());
7713 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
7714 if (RHS.isInvalid())
7715 return StmtError();
7716 }
7717
7718 // Build the case statement.
7719 // Case statements are always rebuilt so that they will attached to their
7720 // transformed switch statement.
7721 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7722 LHS.get(),
7723 S->getEllipsisLoc(),
7724 RHS.get(),
7725 S->getColonLoc());
7726 if (Case.isInvalid())
7727 return StmtError();
7728
7729 // Transform the statement following the case
7730 StmtResult SubStmt =
7731 getDerived().TransformStmt(S->getSubStmt());
7732 if (SubStmt.isInvalid())
7733 return StmtError();
7734
7735 // Attach the body to the case statement
7736 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7737}
7738
7739template <typename Derived>
7740StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7741 // Transform the statement following the default case
7742 StmtResult SubStmt =
7743 getDerived().TransformStmt(S->getSubStmt());
7744 if (SubStmt.isInvalid())
7745 return StmtError();
7746
7747 // Default statements are always rebuilt
7748 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7749 SubStmt.get());
7750}
7751
7752template<typename Derived>
7753StmtResult
7754TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7755 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7756 if (SubStmt.isInvalid())
7757 return StmtError();
7758
7759 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7760 S->getDecl());
7761 if (!LD)
7762 return StmtError();
7763
7764 // If we're transforming "in-place" (we're not creating new local
7765 // declarations), assume we're replacing the old label statement
7766 // and clear out the reference to it.
7767 if (LD == S->getDecl())
7768 S->getDecl()->setStmt(nullptr);
7769
7770 // FIXME: Pass the real colon location in.
7771 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7772 cast<LabelDecl>(LD), SourceLocation(),
7773 SubStmt.get());
7774}
7775
7776template <typename Derived>
7777const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7778 if (!R)
7779 return R;
7780
7781 switch (R->getKind()) {
7782// Transform attributes by calling TransformXXXAttr.
7783#define ATTR(X) \
7784 case attr::X: \
7785 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7786#include "clang/Basic/AttrList.inc"
7787 }
7788 return R;
7789}
7790
7791template <typename Derived>
7792const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
7793 const Stmt *InstS,
7794 const Attr *R) {
7795 if (!R)
7796 return R;
7797
7798 switch (R->getKind()) {
7799// Transform attributes by calling TransformStmtXXXAttr.
7800#define ATTR(X) \
7801 case attr::X: \
7802 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7803#include "clang/Basic/AttrList.inc"
7804 }
7805 return TransformAttr(R);
7806}
7807
7808template <typename Derived>
7809StmtResult
7810TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7811 StmtDiscardKind SDK) {
7812 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7813 if (SubStmt.isInvalid())
7814 return StmtError();
7815
7816 bool AttrsChanged = false;
7817 SmallVector<const Attr *, 1> Attrs;
7818
7819 // Visit attributes and keep track if any are transformed.
7820 for (const auto *I : S->getAttrs()) {
7821 const Attr *R =
7822 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7823 AttrsChanged |= (I != R);
7824 if (R)
7825 Attrs.push_back(R);
7826 }
7827
7828 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7829 return S;
7830
7831 // If transforming the attributes failed for all of the attributes in the
7832 // statement, don't make an AttributedStmt without attributes.
7833 if (Attrs.empty())
7834 return SubStmt;
7835
7836 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7837 SubStmt.get());
7838}
7839
7840template<typename Derived>
7841StmtResult
7842TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7843 // Transform the initialization statement
7844 StmtResult Init = getDerived().TransformStmt(S->getInit());
7845 if (Init.isInvalid())
7846 return StmtError();
7847
7848 Sema::ConditionResult Cond;
7849 if (!S->isConsteval()) {
7850 // Transform the condition
7851 Cond = getDerived().TransformCondition(
7852 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7853 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7854 : Sema::ConditionKind::Boolean);
7855 if (Cond.isInvalid())
7856 return StmtError();
7857 }
7858
7859 // If this is a constexpr if, determine which arm we should instantiate.
7860 std::optional<bool> ConstexprConditionValue;
7861 if (S->isConstexpr())
7862 ConstexprConditionValue = Cond.getKnownValue();
7863
7864 // Transform the "then" branch.
7865 StmtResult Then;
7866 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7867 Then = getDerived().TransformStmt(S->getThen());
7868 if (Then.isInvalid())
7869 return StmtError();
7870 } else {
7871 // Discarded branch is replaced with empty CompoundStmt so we can keep
7872 // proper source location for start and end of original branch, so
7873 // subsequent transformations like CoverageMapping work properly
7874 Then = new (getSema().Context)
7875 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
7876 }
7877
7878 // Transform the "else" branch.
7879 StmtResult Else;
7880 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7881 Else = getDerived().TransformStmt(S->getElse());
7882 if (Else.isInvalid())
7883 return StmtError();
7884 } else if (S->getElse() && ConstexprConditionValue &&
7885 *ConstexprConditionValue) {
7886 // Same thing here as with <then> branch, we are discarding it, we can't
7887 // replace it with NULL nor NullStmt as we need to keep for source location
7888 // range, for CoverageMapping
7889 Else = new (getSema().Context)
7890 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
7891 }
7892
7893 if (!getDerived().AlwaysRebuild() &&
7894 Init.get() == S->getInit() &&
7895 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7896 Then.get() == S->getThen() &&
7897 Else.get() == S->getElse())
7898 return S;
7899
7900 return getDerived().RebuildIfStmt(
7901 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
7902 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
7903}
7904
7905template<typename Derived>
7906StmtResult
7907TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
7908 // Transform the initialization statement
7909 StmtResult Init = getDerived().TransformStmt(S->getInit());
7910 if (Init.isInvalid())
7911 return StmtError();
7912
7913 // Transform the condition.
7914 Sema::ConditionResult Cond = getDerived().TransformCondition(
7915 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
7916 Sema::ConditionKind::Switch);
7917 if (Cond.isInvalid())
7918 return StmtError();
7919
7920 // Rebuild the switch statement.
7921 StmtResult Switch =
7922 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
7923 Init.get(), Cond, S->getRParenLoc());
7924 if (Switch.isInvalid())
7925 return StmtError();
7926
7927 // Transform the body of the switch statement.
7928 StmtResult Body = getDerived().TransformStmt(S->getBody());
7929 if (Body.isInvalid())
7930 return StmtError();
7931
7932 // Complete the switch statement.
7933 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
7934 Body.get());
7935}
7936
7937template<typename Derived>
7938StmtResult
7939TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
7940 // Transform the condition
7941 Sema::ConditionResult Cond = getDerived().TransformCondition(
7942 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
7943 Sema::ConditionKind::Boolean);
7944 if (Cond.isInvalid())
7945 return StmtError();
7946
7947 // Transform the body
7948 StmtResult Body = getDerived().TransformStmt(S->getBody());
7949 if (Body.isInvalid())
7950 return StmtError();
7951
7952 if (!getDerived().AlwaysRebuild() &&
7953 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7954 Body.get() == S->getBody())
7955 return Owned(S);
7956
7957 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
7958 Cond, S->getRParenLoc(), Body.get());
7959}
7960
7961template<typename Derived>
7962StmtResult
7963TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
7964 // Transform the body
7965 StmtResult Body = getDerived().TransformStmt(S->getBody());
7966 if (Body.isInvalid())
7967 return StmtError();
7968
7969 // Transform the condition
7970 ExprResult Cond = getDerived().TransformExpr(S->getCond());
7971 if (Cond.isInvalid())
7972 return StmtError();
7973
7974 if (!getDerived().AlwaysRebuild() &&
7975 Cond.get() == S->getCond() &&
7976 Body.get() == S->getBody())
7977 return S;
7978
7979 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
7980 /*FIXME:*/S->getWhileLoc(), Cond.get(),
7981 S->getRParenLoc());
7982}
7983
7984template<typename Derived>
7985StmtResult
7986TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
7987 if (getSema().getLangOpts().OpenMP)
7988 getSema().startOpenMPLoop();
7989
7990 // Transform the initialization statement
7991 StmtResult Init = getDerived().TransformStmt(S->getInit());
7992 if (Init.isInvalid())
7993 return StmtError();
7994
7995 // In OpenMP loop region loop control variable must be captured and be
7996 // private. Perform analysis of first part (if any).
7997 if (getSema().getLangOpts().OpenMP && Init.isUsable())
7998 getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
7999
8000 // Transform the condition
8001 Sema::ConditionResult Cond = getDerived().TransformCondition(
8002 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8003 Sema::ConditionKind::Boolean);
8004 if (Cond.isInvalid())
8005 return StmtError();
8006
8007 // Transform the increment
8008 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8009 if (Inc.isInvalid())
8010 return StmtError();
8011
8012 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8013 if (S->getInc() && !FullInc.get())
8014 return StmtError();
8015
8016 // Transform the body
8017 StmtResult Body = getDerived().TransformStmt(S->getBody());
8018 if (Body.isInvalid())
8019 return StmtError();
8020
8021 if (!getDerived().AlwaysRebuild() &&
8022 Init.get() == S->getInit() &&
8023 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8024 Inc.get() == S->getInc() &&
8025 Body.get() == S->getBody())
8026 return S;
8027
8028 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8029 Init.get(), Cond, FullInc,
8030 S->getRParenLoc(), Body.get());
8031}
8032
8033template<typename Derived>
8034StmtResult
8035TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8036 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8037 S->getLabel());
8038 if (!LD)
8039 return StmtError();
8040
8041 // Goto statements must always be rebuilt, to resolve the label.
8042 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8043 cast<LabelDecl>(LD));
8044}
8045
8046template<typename Derived>
8047StmtResult
8048TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8049 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8050 if (Target.isInvalid())
8051 return StmtError();
8052 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8053
8054 if (!getDerived().AlwaysRebuild() &&
8055 Target.get() == S->getTarget())
8056 return S;
8057
8058 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8059 Target.get());
8060}
8061
8062template<typename Derived>
8063StmtResult
8064TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8065 return S;
8066}
8067
8068template<typename Derived>
8069StmtResult
8070TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8071 return S;
8072}
8073
8074template<typename Derived>
8075StmtResult
8076TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8077 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8078 /*NotCopyInit*/false);
8079 if (Result.isInvalid())
8080 return StmtError();
8081
8082 // FIXME: We always rebuild the return statement because there is no way
8083 // to tell whether the return type of the function has changed.
8084 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8085}
8086
8087template<typename Derived>
8088StmtResult
8089TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8090 bool DeclChanged = false;
8091 SmallVector<Decl *, 4> Decls;
8092 for (auto *D : S->decls()) {
8093 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8094 if (!Transformed)
8095 return StmtError();
8096
8097 if (Transformed != D)
8098 DeclChanged = true;
8099
8100 Decls.push_back(Transformed);
8101 }
8102
8103 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8104 return S;
8105
8106 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8107}
8108
8109template<typename Derived>
8110StmtResult
8111TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8112
8113 SmallVector<Expr*, 8> Constraints;
8114 SmallVector<Expr*, 8> Exprs;
8115 SmallVector<IdentifierInfo *, 4> Names;
8116
8117 ExprResult AsmString;
8118 SmallVector<Expr*, 8> Clobbers;
8119
8120 bool ExprsChanged = false;
8121
8122 // Go through the outputs.
8123 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8124 Names.push_back(S->getOutputIdentifier(i: I));
8125
8126 // No need to transform the constraint literal.
8127 Constraints.push_back(S->getOutputConstraintLiteral(i: I));
8128
8129 // Transform the output expr.
8130 Expr *OutputExpr = S->getOutputExpr(i: I);
8131 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8132 if (Result.isInvalid())
8133 return StmtError();
8134
8135 ExprsChanged |= Result.get() != OutputExpr;
8136
8137 Exprs.push_back(Result.get());
8138 }
8139
8140 // Go through the inputs.
8141 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8142 Names.push_back(S->getInputIdentifier(i: I));
8143
8144 // No need to transform the constraint literal.
8145 Constraints.push_back(S->getInputConstraintLiteral(i: I));
8146
8147 // Transform the input expr.
8148 Expr *InputExpr = S->getInputExpr(i: I);
8149 ExprResult Result = getDerived().TransformExpr(InputExpr);
8150 if (Result.isInvalid())
8151 return StmtError();
8152
8153 ExprsChanged |= Result.get() != InputExpr;
8154
8155 Exprs.push_back(Result.get());
8156 }
8157
8158 // Go through the Labels.
8159 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8160 Names.push_back(S->getLabelIdentifier(i: I));
8161
8162 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8163 if (Result.isInvalid())
8164 return StmtError();
8165 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8166 Exprs.push_back(Result.get());
8167 }
8168 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8169 return S;
8170
8171 // Go through the clobbers.
8172 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8173 Clobbers.push_back(S->getClobberStringLiteral(i: I));
8174
8175 // No need to transform the asm string literal.
8176 AsmString = S->getAsmString();
8177 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8178 S->isVolatile(), S->getNumOutputs(),
8179 S->getNumInputs(), Names.data(),
8180 Constraints, Exprs, AsmString.get(),
8181 Clobbers, S->getNumLabels(),
8182 S->getRParenLoc());
8183}
8184
8185template<typename Derived>
8186StmtResult
8187TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8188 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8189
8190 bool HadError = false, HadChange = false;
8191
8192 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8193 SmallVector<Expr*, 8> TransformedExprs;
8194 TransformedExprs.reserve(SrcExprs.size());
8195 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8196 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8197 if (!Result.isUsable()) {
8198 HadError = true;
8199 } else {
8200 HadChange |= (Result.get() != SrcExprs[i]);
8201 TransformedExprs.push_back(Result.get());
8202 }
8203 }
8204
8205 if (HadError) return StmtError();
8206 if (!HadChange && !getDerived().AlwaysRebuild())
8207 return Owned(S);
8208
8209 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8210 AsmToks, S->getAsmString(),
8211 S->getNumOutputs(), S->getNumInputs(),
8212 S->getAllConstraints(), S->getClobbers(),
8213 TransformedExprs, S->getEndLoc());
8214}
8215
8216// C++ Coroutines
8217template<typename Derived>
8218StmtResult
8219TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8220 auto *ScopeInfo = SemaRef.getCurFunction();
8221 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8222 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8223 ScopeInfo->NeedsCoroutineSuspends &&
8224 ScopeInfo->CoroutineSuspends.first == nullptr &&
8225 ScopeInfo->CoroutineSuspends.second == nullptr &&
8226 "expected clean scope info");
8227
8228 // Set that we have (possibly-invalid) suspend points before we do anything
8229 // that may fail.
8230 ScopeInfo->setNeedsCoroutineSuspends(false);
8231
8232 // We re-build the coroutine promise object (and the coroutine parameters its
8233 // type and constructor depend on) based on the types used in our current
8234 // function. We must do so, and set it on the current FunctionScopeInfo,
8235 // before attempting to transform the other parts of the coroutine body
8236 // statement, such as the implicit suspend statements (because those
8237 // statements reference the FunctionScopeInfo::CoroutinePromise).
8238 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8239 return StmtError();
8240 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8241 if (!Promise)
8242 return StmtError();
8243 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8244 ScopeInfo->CoroutinePromise = Promise;
8245
8246 // Transform the implicit coroutine statements constructed using dependent
8247 // types during the previous parse: initial and final suspensions, the return
8248 // object, and others. We also transform the coroutine function's body.
8249 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8250 if (InitSuspend.isInvalid())
8251 return StmtError();
8252 StmtResult FinalSuspend =
8253 getDerived().TransformStmt(S->getFinalSuspendStmt());
8254 if (FinalSuspend.isInvalid() ||
8255 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8256 return StmtError();
8257 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8258 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8259
8260 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8261 if (BodyRes.isInvalid())
8262 return StmtError();
8263
8264 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8265 if (Builder.isInvalid())
8266 return StmtError();
8267
8268 Expr *ReturnObject = S->getReturnValueInit();
8269 assert(ReturnObject && "the return object is expected to be valid");
8270 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8271 /*NoCopyInit*/ false);
8272 if (Res.isInvalid())
8273 return StmtError();
8274 Builder.ReturnValue = Res.get();
8275
8276 // If during the previous parse the coroutine still had a dependent promise
8277 // statement, we may need to build some implicit coroutine statements
8278 // (such as exception and fallthrough handlers) for the first time.
8279 if (S->hasDependentPromiseType()) {
8280 // We can only build these statements, however, if the current promise type
8281 // is not dependent.
8282 if (!Promise->getType()->isDependentType()) {
8283 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8284 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8285 "these nodes should not have been built yet");
8286 if (!Builder.buildDependentStatements())
8287 return StmtError();
8288 }
8289 } else {
8290 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8291 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8292 if (Res.isInvalid())
8293 return StmtError();
8294 Builder.OnFallthrough = Res.get();
8295 }
8296
8297 if (auto *OnException = S->getExceptionHandler()) {
8298 StmtResult Res = getDerived().TransformStmt(OnException);
8299 if (Res.isInvalid())
8300 return StmtError();
8301 Builder.OnException = Res.get();
8302 }
8303
8304 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8305 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8306 if (Res.isInvalid())
8307 return StmtError();
8308 Builder.ReturnStmtOnAllocFailure = Res.get();
8309 }
8310
8311 // Transform any additional statements we may have already built
8312 assert(S->getAllocate() && S->getDeallocate() &&
8313 "allocation and deallocation calls must already be built");
8314 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8315 if (AllocRes.isInvalid())
8316 return StmtError();
8317 Builder.Allocate = AllocRes.get();
8318
8319 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8320 if (DeallocRes.isInvalid())
8321 return StmtError();
8322 Builder.Deallocate = DeallocRes.get();
8323
8324 if (auto *ResultDecl = S->getResultDecl()) {
8325 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8326 if (Res.isInvalid())
8327 return StmtError();
8328 Builder.ResultDecl = Res.get();
8329 }
8330
8331 if (auto *ReturnStmt = S->getReturnStmt()) {
8332 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8333 if (Res.isInvalid())
8334 return StmtError();
8335 Builder.ReturnStmt = Res.get();
8336 }
8337 }
8338
8339 return getDerived().RebuildCoroutineBodyStmt(Builder);
8340}
8341
8342template<typename Derived>
8343StmtResult
8344TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8345 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8346 /*NotCopyInit*/false);
8347 if (Result.isInvalid())
8348 return StmtError();
8349
8350 // Always rebuild; we don't know if this needs to be injected into a new
8351 // context or if the promise type has changed.
8352 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8353 S->isImplicit());
8354}
8355
8356template <typename Derived>
8357ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8358 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8359 /*NotCopyInit*/ false);
8360 if (Operand.isInvalid())
8361 return ExprError();
8362
8363 // Rebuild the common-expr from the operand rather than transforming it
8364 // separately.
8365
8366 // FIXME: getCurScope() should not be used during template instantiation.
8367 // We should pick up the set of unqualified lookup results for operator
8368 // co_await during the initial parse.
8369 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8370 getSema().getCurScope(), E->getKeywordLoc());
8371
8372 // Always rebuild; we don't know if this needs to be injected into a new
8373 // context or if the promise type has changed.
8374 return getDerived().RebuildCoawaitExpr(
8375 E->getKeywordLoc(), Operand.get(),
8376 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8377}
8378
8379template <typename Derived>
8380ExprResult
8381TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8382 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8383 /*NotCopyInit*/ false);
8384 if (OperandResult.isInvalid())
8385 return ExprError();
8386
8387 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8388 E->getOperatorCoawaitLookup());
8389
8390 if (LookupResult.isInvalid())
8391 return ExprError();
8392
8393 // Always rebuild; we don't know if this needs to be injected into a new
8394 // context or if the promise type has changed.
8395 return getDerived().RebuildDependentCoawaitExpr(
8396 E->getKeywordLoc(), OperandResult.get(),
8397 cast<UnresolvedLookupExpr>(LookupResult.get()));
8398}
8399
8400template<typename Derived>
8401ExprResult
8402TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8403 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8404 /*NotCopyInit*/false);
8405 if (Result.isInvalid())
8406 return ExprError();
8407
8408 // Always rebuild; we don't know if this needs to be injected into a new
8409 // context or if the promise type has changed.
8410 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8411}
8412
8413// Objective-C Statements.
8414
8415template<typename Derived>
8416StmtResult
8417TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8418 // Transform the body of the @try.
8419 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8420 if (TryBody.isInvalid())
8421 return StmtError();
8422
8423 // Transform the @catch statements (if present).
8424 bool AnyCatchChanged = false;
8425 SmallVector<Stmt*, 8> CatchStmts;
8426 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8427 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8428 if (Catch.isInvalid())
8429 return StmtError();
8430 if (Catch.get() != S->getCatchStmt(I))
8431 AnyCatchChanged = true;
8432 CatchStmts.push_back(Catch.get());
8433 }
8434
8435 // Transform the @finally statement (if present).
8436 StmtResult Finally;
8437 if (S->getFinallyStmt()) {
8438 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8439 if (Finally.isInvalid())
8440 return StmtError();
8441 }
8442
8443 // If nothing changed, just retain this statement.
8444 if (!getDerived().AlwaysRebuild() &&
8445 TryBody.get() == S->getTryBody() &&
8446 !AnyCatchChanged &&
8447 Finally.get() == S->getFinallyStmt())
8448 return S;
8449
8450 // Build a new statement.
8451 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8452 CatchStmts, Finally.get());
8453}
8454
8455template<typename Derived>
8456StmtResult
8457TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8458 // Transform the @catch parameter, if there is one.
8459 VarDecl *Var = nullptr;
8460 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8461 TypeSourceInfo *TSInfo = nullptr;
8462 if (FromVar->getTypeSourceInfo()) {
8463 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8464 if (!TSInfo)
8465 return StmtError();
8466 }
8467
8468 QualType T;
8469 if (TSInfo)
8470 T = TSInfo->getType();
8471 else {
8472 T = getDerived().TransformType(FromVar->getType());
8473 if (T.isNull())
8474 return StmtError();
8475 }
8476
8477 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8478 if (!Var)
8479 return StmtError();
8480 }
8481
8482 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8483 if (Body.isInvalid())
8484 return StmtError();
8485
8486 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8487 S->getRParenLoc(),
8488 Var, Body.get());
8489}
8490
8491template<typename Derived>
8492StmtResult
8493TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8494 // Transform the body.
8495 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8496 if (Body.isInvalid())
8497 return StmtError();
8498
8499 // If nothing changed, just retain this statement.
8500 if (!getDerived().AlwaysRebuild() &&
8501 Body.get() == S->getFinallyBody())
8502 return S;
8503
8504 // Build a new statement.
8505 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8506 Body.get());
8507}
8508
8509template<typename Derived>
8510StmtResult
8511TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8512 ExprResult Operand;
8513 if (S->getThrowExpr()) {
8514 Operand = getDerived().TransformExpr(S->getThrowExpr());
8515 if (Operand.isInvalid())
8516 return StmtError();
8517 }
8518
8519 if (!getDerived().AlwaysRebuild() &&
8520 Operand.get() == S->getThrowExpr())
8521 return S;
8522
8523 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8524}
8525
8526template<typename Derived>
8527StmtResult
8528TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8529 ObjCAtSynchronizedStmt *S) {
8530 // Transform the object we are locking.
8531 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8532 if (Object.isInvalid())
8533 return StmtError();
8534 Object =
8535 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8536 Object.get());
8537 if (Object.isInvalid())
8538 return StmtError();
8539
8540 // Transform the body.
8541 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8542 if (Body.isInvalid())
8543 return StmtError();
8544
8545 // If nothing change, just retain the current statement.
8546 if (!getDerived().AlwaysRebuild() &&
8547 Object.get() == S->getSynchExpr() &&
8548 Body.get() == S->getSynchBody())
8549 return S;
8550
8551 // Build a new statement.
8552 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8553 Object.get(), Body.get());
8554}
8555
8556template<typename Derived>
8557StmtResult
8558TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8559 ObjCAutoreleasePoolStmt *S) {
8560 // Transform the body.
8561 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8562 if (Body.isInvalid())
8563 return StmtError();
8564
8565 // If nothing changed, just retain this statement.
8566 if (!getDerived().AlwaysRebuild() &&
8567 Body.get() == S->getSubStmt())
8568 return S;
8569
8570 // Build a new statement.
8571 return getDerived().RebuildObjCAutoreleasePoolStmt(
8572 S->getAtLoc(), Body.get());
8573}
8574
8575template<typename Derived>
8576StmtResult
8577TreeTransform<Derived>::TransformObjCForCollectionStmt(
8578 ObjCForCollectionStmt *S) {
8579 // Transform the element statement.
8580 StmtResult Element =
8581 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8582 if (Element.isInvalid())
8583 return StmtError();
8584
8585 // Transform the collection expression.
8586 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8587 if (Collection.isInvalid())
8588 return StmtError();
8589
8590 // Transform the body.
8591 StmtResult Body = getDerived().TransformStmt(S->getBody());
8592 if (Body.isInvalid())
8593 return StmtError();
8594
8595 // If nothing changed, just retain this statement.
8596 if (!getDerived().AlwaysRebuild() &&
8597 Element.get() == S->getElement() &&
8598 Collection.get() == S->getCollection() &&
8599 Body.get() == S->getBody())
8600 return S;
8601
8602 // Build a new statement.
8603 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8604 Element.get(),
8605 Collection.get(),
8606 S->getRParenLoc(),
8607 Body.get());
8608}
8609
8610template <typename Derived>
8611StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8612 // Transform the exception declaration, if any.
8613 VarDecl *Var = nullptr;
8614 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8615 TypeSourceInfo *T =
8616 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8617 if (!T)
8618 return StmtError();
8619
8620 Var = getDerived().RebuildExceptionDecl(
8621 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8622 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8623 if (!Var || Var->isInvalidDecl())
8624 return StmtError();
8625 }
8626
8627 // Transform the actual exception handler.
8628 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8629 if (Handler.isInvalid())
8630 return StmtError();
8631
8632 if (!getDerived().AlwaysRebuild() && !Var &&
8633 Handler.get() == S->getHandlerBlock())
8634 return S;
8635
8636 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8637}
8638
8639template <typename Derived>
8640StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8641 // Transform the try block itself.
8642 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8643 if (TryBlock.isInvalid())
8644 return StmtError();
8645
8646 // Transform the handlers.
8647 bool HandlerChanged = false;
8648 SmallVector<Stmt *, 8> Handlers;
8649 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8650 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
8651 if (Handler.isInvalid())
8652 return StmtError();
8653
8654 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
8655 Handlers.push_back(Handler.getAs<Stmt>());
8656 }
8657
8658 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8659 !HandlerChanged)
8660 return S;
8661
8662 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8663 Handlers);
8664}
8665
8666template<typename Derived>
8667StmtResult
8668TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8669 EnterExpressionEvaluationContext ForRangeInitContext(
8670 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
8671 /*LambdaContextDecl=*/nullptr,
8672 Sema::ExpressionEvaluationContextRecord::EK_Other,
8673 getSema().getLangOpts().CPlusPlus23);
8674
8675 // P2718R0 - Lifetime extension in range-based for loops.
8676 if (getSema().getLangOpts().CPlusPlus23) {
8677 auto &LastRecord = getSema().ExprEvalContexts.back();
8678 LastRecord.InLifetimeExtendingContext = true;
8679
8680 // Materialize non-`cv void` prvalue temporaries in discarded
8681 // expressions. These materialized temporaries may be lifetime-extented.
8682 LastRecord.InMaterializeTemporaryObjectContext = true;
8683 }
8684 StmtResult Init =
8685 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8686 if (Init.isInvalid())
8687 return StmtError();
8688
8689 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8690 if (Range.isInvalid())
8691 return StmtError();
8692
8693 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
8694 assert(getSema().getLangOpts().CPlusPlus23 ||
8695 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
8696 auto ForRangeLifetimeExtendTemps =
8697 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
8698
8699 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8700 if (Begin.isInvalid())
8701 return StmtError();
8702 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8703 if (End.isInvalid())
8704 return StmtError();
8705
8706 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8707 if (Cond.isInvalid())
8708 return StmtError();
8709 if (Cond.get())
8710 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
8711 if (Cond.isInvalid())
8712 return StmtError();
8713 if (Cond.get())
8714 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
8715
8716 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8717 if (Inc.isInvalid())
8718 return StmtError();
8719 if (Inc.get())
8720 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
8721
8722 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8723 if (LoopVar.isInvalid())
8724 return StmtError();
8725
8726 StmtResult NewStmt = S;
8727 if (getDerived().AlwaysRebuild() ||
8728 Init.get() != S->getInit() ||
8729 Range.get() != S->getRangeStmt() ||
8730 Begin.get() != S->getBeginStmt() ||
8731 End.get() != S->getEndStmt() ||
8732 Cond.get() != S->getCond() ||
8733 Inc.get() != S->getInc() ||
8734 LoopVar.get() != S->getLoopVarStmt()) {
8735 NewStmt = getDerived().RebuildCXXForRangeStmt(
8736 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8737 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8738 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8739 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8740 // Might not have attached any initializer to the loop variable.
8741 getSema().ActOnInitializerError(
8742 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8743 return StmtError();
8744 }
8745 }
8746
8747 StmtResult Body = getDerived().TransformStmt(S->getBody());
8748 if (Body.isInvalid())
8749 return StmtError();
8750
8751 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8752 // it now so we have a new statement to attach the body to.
8753 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8754 NewStmt = getDerived().RebuildCXXForRangeStmt(
8755 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8756 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8757 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8758 if (NewStmt.isInvalid())
8759 return StmtError();
8760 }
8761
8762 if (NewStmt.get() == S)
8763 return S;
8764
8765 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
8766}
8767
8768template<typename Derived>
8769StmtResult
8770TreeTransform<Derived>::TransformMSDependentExistsStmt(
8771 MSDependentExistsStmt *S) {
8772 // Transform the nested-name-specifier, if any.
8773 NestedNameSpecifierLoc QualifierLoc;
8774 if (S->getQualifierLoc()) {
8775 QualifierLoc
8776 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8777 if (!QualifierLoc)
8778 return StmtError();
8779 }
8780
8781 // Transform the declaration name.
8782 DeclarationNameInfo NameInfo = S->getNameInfo();
8783 if (NameInfo.getName()) {
8784 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8785 if (!NameInfo.getName())
8786 return StmtError();
8787 }
8788
8789 // Check whether anything changed.
8790 if (!getDerived().AlwaysRebuild() &&
8791 QualifierLoc == S->getQualifierLoc() &&
8792 NameInfo.getName() == S->getNameInfo().getName())
8793 return S;
8794
8795 // Determine whether this name exists, if we can.
8796 CXXScopeSpec SS;
8797 SS.Adopt(Other: QualifierLoc);
8798 bool Dependent = false;
8799 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8800 case Sema::IER_Exists:
8801 if (S->isIfExists())
8802 break;
8803
8804 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8805
8806 case Sema::IER_DoesNotExist:
8807 if (S->isIfNotExists())
8808 break;
8809
8810 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8811
8812 case Sema::IER_Dependent:
8813 Dependent = true;
8814 break;
8815
8816 case Sema::IER_Error:
8817 return StmtError();
8818 }
8819
8820 // We need to continue with the instantiation, so do so now.
8821 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8822 if (SubStmt.isInvalid())
8823 return StmtError();
8824
8825 // If we have resolved the name, just transform to the substatement.
8826 if (!Dependent)
8827 return SubStmt;
8828
8829 // The name is still dependent, so build a dependent expression again.
8830 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8831 S->isIfExists(),
8832 QualifierLoc,
8833 NameInfo,
8834 SubStmt.get());
8835}
8836
8837template<typename Derived>
8838ExprResult
8839TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8840 NestedNameSpecifierLoc QualifierLoc;
8841 if (E->getQualifierLoc()) {
8842 QualifierLoc
8843 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8844 if (!QualifierLoc)
8845 return ExprError();
8846 }
8847
8848 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8849 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8850 if (!PD)
8851 return ExprError();
8852
8853 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8854 if (Base.isInvalid())
8855 return ExprError();
8856
8857 return new (SemaRef.getASTContext())
8858 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8859 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
8860 QualifierLoc, E->getMemberLoc());
8861}
8862
8863template <typename Derived>
8864ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8865 MSPropertySubscriptExpr *E) {
8866 auto BaseRes = getDerived().TransformExpr(E->getBase());
8867 if (BaseRes.isInvalid())
8868 return ExprError();
8869 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8870 if (IdxRes.isInvalid())
8871 return ExprError();
8872
8873 if (!getDerived().AlwaysRebuild() &&
8874 BaseRes.get() == E->getBase() &&
8875 IdxRes.get() == E->getIdx())
8876 return E;
8877
8878 return getDerived().RebuildArraySubscriptExpr(
8879 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8880}
8881
8882template <typename Derived>
8883StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8884 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8885 if (TryBlock.isInvalid())
8886 return StmtError();
8887
8888 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8889 if (Handler.isInvalid())
8890 return StmtError();
8891
8892 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8893 Handler.get() == S->getHandler())
8894 return S;
8895
8896 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8897 TryBlock.get(), Handler.get());
8898}
8899
8900template <typename Derived>
8901StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
8902 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8903 if (Block.isInvalid())
8904 return StmtError();
8905
8906 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
8907}
8908
8909template <typename Derived>
8910StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
8911 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
8912 if (FilterExpr.isInvalid())
8913 return StmtError();
8914
8915 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8916 if (Block.isInvalid())
8917 return StmtError();
8918
8919 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
8920 Block.get());
8921}
8922
8923template <typename Derived>
8924StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
8925 if (isa<SEHFinallyStmt>(Handler))
8926 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
8927 else
8928 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
8929}
8930
8931template<typename Derived>
8932StmtResult
8933TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
8934 return S;
8935}
8936
8937//===----------------------------------------------------------------------===//
8938// OpenMP directive transformation
8939//===----------------------------------------------------------------------===//
8940
8941template <typename Derived>
8942StmtResult
8943TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
8944 // OMPCanonicalLoops are eliminated during transformation, since they will be
8945 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
8946 // after transformation.
8947 return getDerived().TransformStmt(L->getLoopStmt());
8948}
8949
8950template <typename Derived>
8951StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
8952 OMPExecutableDirective *D) {
8953
8954 // Transform the clauses
8955 llvm::SmallVector<OMPClause *, 16> TClauses;
8956 ArrayRef<OMPClause *> Clauses = D->clauses();
8957 TClauses.reserve(Clauses.size());
8958 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
8959 I != E; ++I) {
8960 if (*I) {
8961 getDerived().getSema().StartOpenMPClause((*I)->getClauseKind());
8962 OMPClause *Clause = getDerived().TransformOMPClause(*I);
8963 getDerived().getSema().EndOpenMPClause();
8964 if (Clause)
8965 TClauses.push_back(Clause);
8966 } else {
8967 TClauses.push_back(nullptr);
8968 }
8969 }
8970 StmtResult AssociatedStmt;
8971 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
8972 getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(),
8973 /*CurScope=*/nullptr);
8974 StmtResult Body;
8975 {
8976 Sema::CompoundScopeRAII CompoundScope(getSema());
8977 Stmt *CS;
8978 if (D->getDirectiveKind() == OMPD_atomic ||
8979 D->getDirectiveKind() == OMPD_critical ||
8980 D->getDirectiveKind() == OMPD_section ||
8981 D->getDirectiveKind() == OMPD_master)
8982 CS = D->getAssociatedStmt();
8983 else
8984 CS = D->getRawStmt();
8985 Body = getDerived().TransformStmt(CS);
8986 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
8987 getSema().getLangOpts().OpenMPIRBuilder)
8988 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
8989 }
8990 AssociatedStmt =
8991 getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses);
8992 if (AssociatedStmt.isInvalid()) {
8993 return StmtError();
8994 }
8995 }
8996 if (TClauses.size() != Clauses.size()) {
8997 return StmtError();
8998 }
8999
9000 // Transform directive name for 'omp critical' directive.
9001 DeclarationNameInfo DirName;
9002 if (D->getDirectiveKind() == OMPD_critical) {
9003 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9004 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9005 }
9006 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9007 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9008 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9009 } else if (D->getDirectiveKind() == OMPD_cancel) {
9010 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9011 }
9012
9013 return getDerived().RebuildOMPExecutableDirective(
9014 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9015 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
9016 D->getMappedDirective());
9017}
9018
9019template <typename Derived>
9020StmtResult
9021TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9022 // TODO: Fix This
9023 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9024 << getOpenMPDirectiveName(D->getDirectiveKind());
9025 return StmtError();
9026}
9027
9028template <typename Derived>
9029StmtResult
9030TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9031 DeclarationNameInfo DirName;
9032 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
9033 D->getBeginLoc());
9034 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9035 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9036 return Res;
9037}
9038
9039template <typename Derived>
9040StmtResult
9041TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9042 DeclarationNameInfo DirName;
9043 getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
9044 D->getBeginLoc());
9045 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9046 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9047 return Res;
9048}
9049
9050template <typename Derived>
9051StmtResult
9052TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9053 DeclarationNameInfo DirName;
9054 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
9055 nullptr, D->getBeginLoc());
9056 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9057 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9058 return Res;
9059}
9060
9061template <typename Derived>
9062StmtResult
9063TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9064 DeclarationNameInfo DirName;
9065 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
9066 nullptr, D->getBeginLoc());
9067 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9068 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9069 return Res;
9070}
9071
9072template <typename Derived>
9073StmtResult
9074TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9075 DeclarationNameInfo DirName;
9076 getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
9077 D->getBeginLoc());
9078 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9079 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9080 return Res;
9081}
9082
9083template <typename Derived>
9084StmtResult
9085TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9086 DeclarationNameInfo DirName;
9087 getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr,
9088 D->getBeginLoc());
9089 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9090 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9091 return Res;
9092}
9093
9094template <typename Derived>
9095StmtResult
9096TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9097 DeclarationNameInfo DirName;
9098 getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
9099 D->getBeginLoc());
9100 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9101 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9102 return Res;
9103}
9104
9105template <typename Derived>
9106StmtResult
9107TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9108 DeclarationNameInfo DirName;
9109 getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
9110 D->getBeginLoc());
9111 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9112 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9113 return Res;
9114}
9115
9116template <typename Derived>
9117StmtResult
9118TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9119 DeclarationNameInfo DirName;
9120 getDerived().getSema().StartOpenMPDSABlock(OMPD_scope, DirName, nullptr,
9121 D->getBeginLoc());
9122 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9123 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9124 return Res;
9125}
9126
9127template <typename Derived>
9128StmtResult
9129TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9130 DeclarationNameInfo DirName;
9131 getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
9132 D->getBeginLoc());
9133 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9134 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9135 return Res;
9136}
9137
9138template <typename Derived>
9139StmtResult
9140TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9141 DeclarationNameInfo DirName;
9142 getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
9143 D->getBeginLoc());
9144 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9145 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9146 return Res;
9147}
9148
9149template <typename Derived>
9150StmtResult
9151TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9152 getDerived().getSema().StartOpenMPDSABlock(
9153 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9154 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9155 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9156 return Res;
9157}
9158
9159template <typename Derived>
9160StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9161 OMPParallelForDirective *D) {
9162 DeclarationNameInfo DirName;
9163 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
9164 nullptr, D->getBeginLoc());
9165 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9166 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9167 return Res;
9168}
9169
9170template <typename Derived>
9171StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9172 OMPParallelForSimdDirective *D) {
9173 DeclarationNameInfo DirName;
9174 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName,
9175 nullptr, D->getBeginLoc());
9176 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9177 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9178 return Res;
9179}
9180
9181template <typename Derived>
9182StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9183 OMPParallelMasterDirective *D) {
9184 DeclarationNameInfo DirName;
9185 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_master, DirName,
9186 nullptr, D->getBeginLoc());
9187 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9188 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9189 return Res;
9190}
9191
9192template <typename Derived>
9193StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9194 OMPParallelMaskedDirective *D) {
9195 DeclarationNameInfo DirName;
9196 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_masked, DirName,
9197 nullptr, D->getBeginLoc());
9198 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9199 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9200 return Res;
9201}
9202
9203template <typename Derived>
9204StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9205 OMPParallelSectionsDirective *D) {
9206 DeclarationNameInfo DirName;
9207 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
9208 nullptr, D->getBeginLoc());
9209 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9210 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9211 return Res;
9212}
9213
9214template <typename Derived>
9215StmtResult
9216TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9217 DeclarationNameInfo DirName;
9218 getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr,
9219 D->getBeginLoc());
9220 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9221 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9222 return Res;
9223}
9224
9225template <typename Derived>
9226StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9227 OMPTaskyieldDirective *D) {
9228 DeclarationNameInfo DirName;
9229 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr,
9230 D->getBeginLoc());
9231 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9232 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9233 return Res;
9234}
9235
9236template <typename Derived>
9237StmtResult
9238TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9239 DeclarationNameInfo DirName;
9240 getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr,
9241 D->getBeginLoc());
9242 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9243 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9244 return Res;
9245}
9246
9247template <typename Derived>
9248StmtResult
9249TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9250 DeclarationNameInfo DirName;
9251 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr,
9252 D->getBeginLoc());
9253 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9254 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9255 return Res;
9256}
9257
9258template <typename Derived>
9259StmtResult
9260TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9261 DeclarationNameInfo DirName;
9262 getDerived().getSema().StartOpenMPDSABlock(OMPD_error, DirName, nullptr,
9263 D->getBeginLoc());
9264 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9265 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9266 return Res;
9267}
9268
9269template <typename Derived>
9270StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9271 OMPTaskgroupDirective *D) {
9272 DeclarationNameInfo DirName;
9273 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr,
9274 D->getBeginLoc());
9275 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9276 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9277 return Res;
9278}
9279
9280template <typename Derived>
9281StmtResult
9282TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9283 DeclarationNameInfo DirName;
9284 getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
9285 D->getBeginLoc());
9286 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9287 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9288 return Res;
9289}
9290
9291template <typename Derived>
9292StmtResult
9293TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9294 DeclarationNameInfo DirName;
9295 getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr,
9296 D->getBeginLoc());
9297 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9298 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9299 return Res;
9300}
9301
9302template <typename Derived>
9303StmtResult
9304TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9305 DeclarationNameInfo DirName;
9306 getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr,
9307 D->getBeginLoc());
9308 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9309 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9310 return Res;
9311}
9312
9313template <typename Derived>
9314StmtResult
9315TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9316 DeclarationNameInfo DirName;
9317 getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr,
9318 D->getBeginLoc());
9319 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9320 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9321 return Res;
9322}
9323
9324template <typename Derived>
9325StmtResult
9326TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9327 DeclarationNameInfo DirName;
9328 getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr,
9329 D->getBeginLoc());
9330 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9331 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9332 return Res;
9333}
9334
9335template <typename Derived>
9336StmtResult
9337TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9338 DeclarationNameInfo DirName;
9339 getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr,
9340 D->getBeginLoc());
9341 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9342 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9343 return Res;
9344}
9345
9346template <typename Derived>
9347StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9348 OMPTargetDataDirective *D) {
9349 DeclarationNameInfo DirName;
9350 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr,
9351 D->getBeginLoc());
9352 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9353 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9354 return Res;
9355}
9356
9357template <typename Derived>
9358StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9359 OMPTargetEnterDataDirective *D) {
9360 DeclarationNameInfo DirName;
9361 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName,
9362 nullptr, D->getBeginLoc());
9363 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9364 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9365 return Res;
9366}
9367
9368template <typename Derived>
9369StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9370 OMPTargetExitDataDirective *D) {
9371 DeclarationNameInfo DirName;
9372 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName,
9373 nullptr, D->getBeginLoc());
9374 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9375 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9376 return Res;
9377}
9378
9379template <typename Derived>
9380StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9381 OMPTargetParallelDirective *D) {
9382 DeclarationNameInfo DirName;
9383 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName,
9384 nullptr, D->getBeginLoc());
9385 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9386 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9387 return Res;
9388}
9389
9390template <typename Derived>
9391StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9392 OMPTargetParallelForDirective *D) {
9393 DeclarationNameInfo DirName;
9394 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName,
9395 nullptr, D->getBeginLoc());
9396 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9397 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9398 return Res;
9399}
9400
9401template <typename Derived>
9402StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9403 OMPTargetUpdateDirective *D) {
9404 DeclarationNameInfo DirName;
9405 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName,
9406 nullptr, D->getBeginLoc());
9407 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9408 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9409 return Res;
9410}
9411
9412template <typename Derived>
9413StmtResult
9414TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9415 DeclarationNameInfo DirName;
9416 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr,
9417 D->getBeginLoc());
9418 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9419 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9420 return Res;
9421}
9422
9423template <typename Derived>
9424StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9425 OMPCancellationPointDirective *D) {
9426 DeclarationNameInfo DirName;
9427 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName,
9428 nullptr, D->getBeginLoc());
9429 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9430 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9431 return Res;
9432}
9433
9434template <typename Derived>
9435StmtResult
9436TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9437 DeclarationNameInfo DirName;
9438 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr,
9439 D->getBeginLoc());
9440 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9441 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9442 return Res;
9443}
9444
9445template <typename Derived>
9446StmtResult
9447TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9448 DeclarationNameInfo DirName;
9449 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr,
9450 D->getBeginLoc());
9451 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9452 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9453 return Res;
9454}
9455
9456template <typename Derived>
9457StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9458 OMPTaskLoopSimdDirective *D) {
9459 DeclarationNameInfo DirName;
9460 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName,
9461 nullptr, D->getBeginLoc());
9462 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9463 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9464 return Res;
9465}
9466
9467template <typename Derived>
9468StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9469 OMPMasterTaskLoopDirective *D) {
9470 DeclarationNameInfo DirName;
9471 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop, DirName,
9472 nullptr, D->getBeginLoc());
9473 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9474 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9475 return Res;
9476}
9477
9478template <typename Derived>
9479StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9480 OMPMaskedTaskLoopDirective *D) {
9481 DeclarationNameInfo DirName;
9482 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop, DirName,
9483 nullptr, D->getBeginLoc());
9484 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9485 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9486 return Res;
9487}
9488
9489template <typename Derived>
9490StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9491 OMPMasterTaskLoopSimdDirective *D) {
9492 DeclarationNameInfo DirName;
9493 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop_simd, DirName,
9494 nullptr, D->getBeginLoc());
9495 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9496 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9497 return Res;
9498}
9499
9500template <typename Derived>
9501StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9502 OMPMaskedTaskLoopSimdDirective *D) {
9503 DeclarationNameInfo DirName;
9504 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop_simd, DirName,
9505 nullptr, D->getBeginLoc());
9506 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9507 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9508 return Res;
9509}
9510
9511template <typename Derived>
9512StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9513 OMPParallelMasterTaskLoopDirective *D) {
9514 DeclarationNameInfo DirName;
9515 getDerived().getSema().StartOpenMPDSABlock(
9516 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9517 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9518 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9519 return Res;
9520}
9521
9522template <typename Derived>
9523StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9524 OMPParallelMaskedTaskLoopDirective *D) {
9525 DeclarationNameInfo DirName;
9526 getDerived().getSema().StartOpenMPDSABlock(
9527 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9528 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9529 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9530 return Res;
9531}
9532
9533template <typename Derived>
9534StmtResult
9535TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9536 OMPParallelMasterTaskLoopSimdDirective *D) {
9537 DeclarationNameInfo DirName;
9538 getDerived().getSema().StartOpenMPDSABlock(
9539 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9540 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9541 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9542 return Res;
9543}
9544
9545template <typename Derived>
9546StmtResult
9547TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9548 OMPParallelMaskedTaskLoopSimdDirective *D) {
9549 DeclarationNameInfo DirName;
9550 getDerived().getSema().StartOpenMPDSABlock(
9551 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9552 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9553 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9554 return Res;
9555}
9556
9557template <typename Derived>
9558StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9559 OMPDistributeDirective *D) {
9560 DeclarationNameInfo DirName;
9561 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr,
9562 D->getBeginLoc());
9563 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9564 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9565 return Res;
9566}
9567
9568template <typename Derived>
9569StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9570 OMPDistributeParallelForDirective *D) {
9571 DeclarationNameInfo DirName;
9572 getDerived().getSema().StartOpenMPDSABlock(
9573 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9574 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9575 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9576 return Res;
9577}
9578
9579template <typename Derived>
9580StmtResult
9581TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9582 OMPDistributeParallelForSimdDirective *D) {
9583 DeclarationNameInfo DirName;
9584 getDerived().getSema().StartOpenMPDSABlock(
9585 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9586 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9587 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9588 return Res;
9589}
9590
9591template <typename Derived>
9592StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9593 OMPDistributeSimdDirective *D) {
9594 DeclarationNameInfo DirName;
9595 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName,
9596 nullptr, D->getBeginLoc());
9597 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9598 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9599 return Res;
9600}
9601
9602template <typename Derived>
9603StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9604 OMPTargetParallelForSimdDirective *D) {
9605 DeclarationNameInfo DirName;
9606 getDerived().getSema().StartOpenMPDSABlock(
9607 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9608 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9609 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9610 return Res;
9611}
9612
9613template <typename Derived>
9614StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9615 OMPTargetSimdDirective *D) {
9616 DeclarationNameInfo DirName;
9617 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr,
9618 D->getBeginLoc());
9619 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9620 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9621 return Res;
9622}
9623
9624template <typename Derived>
9625StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9626 OMPTeamsDistributeDirective *D) {
9627 DeclarationNameInfo DirName;
9628 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName,
9629 nullptr, D->getBeginLoc());
9630 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9631 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9632 return Res;
9633}
9634
9635template <typename Derived>
9636StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9637 OMPTeamsDistributeSimdDirective *D) {
9638 DeclarationNameInfo DirName;
9639 getDerived().getSema().StartOpenMPDSABlock(
9640 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9641 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9642 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9643 return Res;
9644}
9645
9646template <typename Derived>
9647StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9648 OMPTeamsDistributeParallelForSimdDirective *D) {
9649 DeclarationNameInfo DirName;
9650 getDerived().getSema().StartOpenMPDSABlock(
9651 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9652 D->getBeginLoc());
9653 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9654 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9655 return Res;
9656}
9657
9658template <typename Derived>
9659StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9660 OMPTeamsDistributeParallelForDirective *D) {
9661 DeclarationNameInfo DirName;
9662 getDerived().getSema().StartOpenMPDSABlock(
9663 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9664 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9665 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9666 return Res;
9667}
9668
9669template <typename Derived>
9670StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9671 OMPTargetTeamsDirective *D) {
9672 DeclarationNameInfo DirName;
9673 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName,
9674 nullptr, D->getBeginLoc());
9675 auto Res = getDerived().TransformOMPExecutableDirective(D);
9676 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9677 return Res;
9678}
9679
9680template <typename Derived>
9681StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9682 OMPTargetTeamsDistributeDirective *D) {
9683 DeclarationNameInfo DirName;
9684 getDerived().getSema().StartOpenMPDSABlock(
9685 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9686 auto Res = getDerived().TransformOMPExecutableDirective(D);
9687 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9688 return Res;
9689}
9690
9691template <typename Derived>
9692StmtResult
9693TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9694 OMPTargetTeamsDistributeParallelForDirective *D) {
9695 DeclarationNameInfo DirName;
9696 getDerived().getSema().StartOpenMPDSABlock(
9697 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9698 D->getBeginLoc());
9699 auto Res = getDerived().TransformOMPExecutableDirective(D);
9700 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9701 return Res;
9702}
9703
9704template <typename Derived>
9705StmtResult TreeTransform<Derived>::
9706 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9707 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9708 DeclarationNameInfo DirName;
9709 getDerived().getSema().StartOpenMPDSABlock(
9710 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9711 D->getBeginLoc());
9712 auto Res = getDerived().TransformOMPExecutableDirective(D);
9713 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9714 return Res;
9715}
9716
9717template <typename Derived>
9718StmtResult
9719TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9720 OMPTargetTeamsDistributeSimdDirective *D) {
9721 DeclarationNameInfo DirName;
9722 getDerived().getSema().StartOpenMPDSABlock(
9723 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9724 auto Res = getDerived().TransformOMPExecutableDirective(D);
9725 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9726 return Res;
9727}
9728
9729template <typename Derived>
9730StmtResult
9731TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9732 DeclarationNameInfo DirName;
9733 getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr,
9734 D->getBeginLoc());
9735 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9736 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9737 return Res;
9738}
9739
9740template <typename Derived>
9741StmtResult
9742TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9743 DeclarationNameInfo DirName;
9744 getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr,
9745 D->getBeginLoc());
9746 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9747 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9748 return Res;
9749}
9750
9751template <typename Derived>
9752StmtResult
9753TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9754 DeclarationNameInfo DirName;
9755 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked, DirName, nullptr,
9756 D->getBeginLoc());
9757 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9758 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9759 return Res;
9760}
9761
9762template <typename Derived>
9763StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9764 OMPGenericLoopDirective *D) {
9765 DeclarationNameInfo DirName;
9766 getDerived().getSema().StartOpenMPDSABlock(OMPD_loop, DirName, nullptr,
9767 D->getBeginLoc());
9768 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9769 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9770 return Res;
9771}
9772
9773template <typename Derived>
9774StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9775 OMPTeamsGenericLoopDirective *D) {
9776 DeclarationNameInfo DirName;
9777 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_loop, DirName, nullptr,
9778 D->getBeginLoc());
9779 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9780 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9781 return Res;
9782}
9783
9784template <typename Derived>
9785StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9786 OMPTargetTeamsGenericLoopDirective *D) {
9787 DeclarationNameInfo DirName;
9788 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_loop, DirName,
9789 nullptr, D->getBeginLoc());
9790 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9791 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9792 return Res;
9793}
9794
9795template <typename Derived>
9796StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9797 OMPParallelGenericLoopDirective *D) {
9798 DeclarationNameInfo DirName;
9799 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_loop, DirName,
9800 nullptr, D->getBeginLoc());
9801 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9802 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9803 return Res;
9804}
9805
9806template <typename Derived>
9807StmtResult
9808TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9809 OMPTargetParallelGenericLoopDirective *D) {
9810 DeclarationNameInfo DirName;
9811 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_loop, DirName,
9812 nullptr, D->getBeginLoc());
9813 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9814 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9815 return Res;
9816}
9817
9818//===----------------------------------------------------------------------===//
9819// OpenMP clause transformation
9820//===----------------------------------------------------------------------===//
9821template <typename Derived>
9822OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9823 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9824 if (Cond.isInvalid())
9825 return nullptr;
9826 return getDerived().RebuildOMPIfClause(
9827 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9828 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9829}
9830
9831template <typename Derived>
9832OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9833 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9834 if (Cond.isInvalid())
9835 return nullptr;
9836 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9837 C->getLParenLoc(), C->getEndLoc());
9838}
9839
9840template <typename Derived>
9841OMPClause *
9842TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9843 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9844 if (NumThreads.isInvalid())
9845 return nullptr;
9846 return getDerived().RebuildOMPNumThreadsClause(
9847 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9848}
9849
9850template <typename Derived>
9851OMPClause *
9852TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9853 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9854 if (E.isInvalid())
9855 return nullptr;
9856 return getDerived().RebuildOMPSafelenClause(
9857 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9858}
9859
9860template <typename Derived>
9861OMPClause *
9862TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9863 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9864 if (E.isInvalid())
9865 return nullptr;
9866 return getDerived().RebuildOMPAllocatorClause(
9867 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9868}
9869
9870template <typename Derived>
9871OMPClause *
9872TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9873 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9874 if (E.isInvalid())
9875 return nullptr;
9876 return getDerived().RebuildOMPSimdlenClause(
9877 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9878}
9879
9880template <typename Derived>
9881OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9882 SmallVector<Expr *, 4> TransformedSizes;
9883 TransformedSizes.reserve(N: C->getNumSizes());
9884 bool Changed = false;
9885 for (Expr *E : C->getSizesRefs()) {
9886 if (!E) {
9887 TransformedSizes.push_back(Elt: nullptr);
9888 continue;
9889 }
9890
9891 ExprResult T = getDerived().TransformExpr(E);
9892 if (T.isInvalid())
9893 return nullptr;
9894 if (E != T.get())
9895 Changed = true;
9896 TransformedSizes.push_back(Elt: T.get());
9897 }
9898
9899 if (!Changed && !getDerived().AlwaysRebuild())
9900 return C;
9901 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
9902 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
9903}
9904
9905template <typename Derived>
9906OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
9907 if (!getDerived().AlwaysRebuild())
9908 return C;
9909 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
9910}
9911
9912template <typename Derived>
9913OMPClause *
9914TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
9915 ExprResult T = getDerived().TransformExpr(C->getFactor());
9916 if (T.isInvalid())
9917 return nullptr;
9918 Expr *Factor = T.get();
9919 bool Changed = Factor != C->getFactor();
9920
9921 if (!Changed && !getDerived().AlwaysRebuild())
9922 return C;
9923 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
9924 EndLoc: C->getEndLoc());
9925}
9926
9927template <typename Derived>
9928OMPClause *
9929TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
9930 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
9931 if (E.isInvalid())
9932 return nullptr;
9933 return getDerived().RebuildOMPCollapseClause(
9934 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9935}
9936
9937template <typename Derived>
9938OMPClause *
9939TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
9940 return getDerived().RebuildOMPDefaultClause(
9941 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
9942 C->getLParenLoc(), C->getEndLoc());
9943}
9944
9945template <typename Derived>
9946OMPClause *
9947TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
9948 return getDerived().RebuildOMPProcBindClause(
9949 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
9950 C->getLParenLoc(), C->getEndLoc());
9951}
9952
9953template <typename Derived>
9954OMPClause *
9955TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
9956 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
9957 if (E.isInvalid())
9958 return nullptr;
9959 return getDerived().RebuildOMPScheduleClause(
9960 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
9961 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
9962 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
9963 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
9964}
9965
9966template <typename Derived>
9967OMPClause *
9968TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
9969 ExprResult E;
9970 if (auto *Num = C->getNumForLoops()) {
9971 E = getDerived().TransformExpr(Num);
9972 if (E.isInvalid())
9973 return nullptr;
9974 }
9975 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
9976 C->getLParenLoc(), E.get());
9977}
9978
9979template <typename Derived>
9980OMPClause *
9981TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
9982 ExprResult E;
9983 if (Expr *Evt = C->getEventHandler()) {
9984 E = getDerived().TransformExpr(Evt);
9985 if (E.isInvalid())
9986 return nullptr;
9987 }
9988 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
9989 C->getLParenLoc(), C->getEndLoc());
9990}
9991
9992template <typename Derived>
9993OMPClause *
9994TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
9995 // No need to rebuild this clause, no template-dependent parameters.
9996 return C;
9997}
9998
9999template <typename Derived>
10000OMPClause *
10001TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10002 // No need to rebuild this clause, no template-dependent parameters.
10003 return C;
10004}
10005
10006template <typename Derived>
10007OMPClause *
10008TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10009 // No need to rebuild this clause, no template-dependent parameters.
10010 return C;
10011}
10012
10013template <typename Derived>
10014OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10015 // No need to rebuild this clause, no template-dependent parameters.
10016 return C;
10017}
10018
10019template <typename Derived>
10020OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10021 // No need to rebuild this clause, no template-dependent parameters.
10022 return C;
10023}
10024
10025template <typename Derived>
10026OMPClause *
10027TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10028 // No need to rebuild this clause, no template-dependent parameters.
10029 return C;
10030}
10031
10032template <typename Derived>
10033OMPClause *
10034TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10035 // No need to rebuild this clause, no template-dependent parameters.
10036 return C;
10037}
10038
10039template <typename Derived>
10040OMPClause *
10041TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10042 // No need to rebuild this clause, no template-dependent parameters.
10043 return C;
10044}
10045
10046template <typename Derived>
10047OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10048 // No need to rebuild this clause, no template-dependent parameters.
10049 return C;
10050}
10051
10052template <typename Derived>
10053OMPClause *
10054TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10055 // No need to rebuild this clause, no template-dependent parameters.
10056 return C;
10057}
10058
10059template <typename Derived>
10060OMPClause *
10061TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10062 // No need to rebuild this clause, no template-dependent parameters.
10063 return C;
10064}
10065
10066template <typename Derived>
10067OMPClause *
10068TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10069 // No need to rebuild this clause, no template-dependent parameters.
10070 return C;
10071}
10072
10073template <typename Derived>
10074OMPClause *
10075TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10076 // No need to rebuild this clause, no template-dependent parameters.
10077 return C;
10078}
10079
10080template <typename Derived>
10081OMPClause *
10082TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10083 // No need to rebuild this clause, no template-dependent parameters.
10084 return C;
10085}
10086
10087template <typename Derived>
10088OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10089 // No need to rebuild this clause, no template-dependent parameters.
10090 return C;
10091}
10092
10093template <typename Derived>
10094OMPClause *
10095TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10096 // No need to rebuild this clause, no template-dependent parameters.
10097 return C;
10098}
10099
10100template <typename Derived>
10101OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10102 // No need to rebuild this clause, no template-dependent parameters.
10103 return C;
10104}
10105
10106template <typename Derived>
10107OMPClause *
10108TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10109 // No need to rebuild this clause, no template-dependent parameters.
10110 return C;
10111}
10112
10113template <typename Derived>
10114OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10115 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10116 if (IVR.isInvalid())
10117 return nullptr;
10118
10119 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10120 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10121 for (Expr *E : llvm::drop_begin(C->varlists())) {
10122 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10123 if (ER.isInvalid())
10124 return nullptr;
10125 InteropInfo.PreferTypes.push_back(ER.get());
10126 }
10127 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10128 C->getBeginLoc(), C->getLParenLoc(),
10129 C->getVarLoc(), C->getEndLoc());
10130}
10131
10132template <typename Derived>
10133OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10134 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10135 if (ER.isInvalid())
10136 return nullptr;
10137 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10138 C->getLParenLoc(), C->getVarLoc(),
10139 C->getEndLoc());
10140}
10141
10142template <typename Derived>
10143OMPClause *
10144TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10145 ExprResult ER;
10146 if (Expr *IV = C->getInteropVar()) {
10147 ER = getDerived().TransformExpr(IV);
10148 if (ER.isInvalid())
10149 return nullptr;
10150 }
10151 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10152 C->getLParenLoc(), C->getVarLoc(),
10153 C->getEndLoc());
10154}
10155
10156template <typename Derived>
10157OMPClause *
10158TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10159 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10160 if (Cond.isInvalid())
10161 return nullptr;
10162 return getDerived().RebuildOMPNovariantsClause(
10163 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10164}
10165
10166template <typename Derived>
10167OMPClause *
10168TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10169 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10170 if (Cond.isInvalid())
10171 return nullptr;
10172 return getDerived().RebuildOMPNocontextClause(
10173 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10174}
10175
10176template <typename Derived>
10177OMPClause *
10178TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10179 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10180 if (ThreadID.isInvalid())
10181 return nullptr;
10182 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10183 C->getLParenLoc(), C->getEndLoc());
10184}
10185
10186template <typename Derived>
10187OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10188 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10189 if (E.isInvalid())
10190 return nullptr;
10191 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10192 C->getLParenLoc(), C->getEndLoc());
10193}
10194
10195template <typename Derived>
10196OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10197 OMPUnifiedAddressClause *C) {
10198 llvm_unreachable("unified_address clause cannot appear in dependent context");
10199}
10200
10201template <typename Derived>
10202OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10203 OMPUnifiedSharedMemoryClause *C) {
10204 llvm_unreachable(
10205 "unified_shared_memory clause cannot appear in dependent context");
10206}
10207
10208template <typename Derived>
10209OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10210 OMPReverseOffloadClause *C) {
10211 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10212}
10213
10214template <typename Derived>
10215OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10216 OMPDynamicAllocatorsClause *C) {
10217 llvm_unreachable(
10218 "dynamic_allocators clause cannot appear in dependent context");
10219}
10220
10221template <typename Derived>
10222OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10223 OMPAtomicDefaultMemOrderClause *C) {
10224 llvm_unreachable(
10225 "atomic_default_mem_order clause cannot appear in dependent context");
10226}
10227
10228template <typename Derived>
10229OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10230 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10231 C->getBeginLoc(), C->getLParenLoc(),
10232 C->getEndLoc());
10233}
10234
10235template <typename Derived>
10236OMPClause *
10237TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10238 return getDerived().RebuildOMPSeverityClause(
10239 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10240 C->getLParenLoc(), C->getEndLoc());
10241}
10242
10243template <typename Derived>
10244OMPClause *
10245TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10246 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10247 if (E.isInvalid())
10248 return nullptr;
10249 return getDerived().RebuildOMPMessageClause(
10250 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10251 C->getEndLoc());
10252}
10253
10254template <typename Derived>
10255OMPClause *
10256TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10257 llvm::SmallVector<Expr *, 16> Vars;
10258 Vars.reserve(C->varlist_size());
10259 for (auto *VE : C->varlists()) {
10260 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10261 if (EVar.isInvalid())
10262 return nullptr;
10263 Vars.push_back(EVar.get());
10264 }
10265 return getDerived().RebuildOMPPrivateClause(
10266 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10267}
10268
10269template <typename Derived>
10270OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10271 OMPFirstprivateClause *C) {
10272 llvm::SmallVector<Expr *, 16> Vars;
10273 Vars.reserve(C->varlist_size());
10274 for (auto *VE : C->varlists()) {
10275 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10276 if (EVar.isInvalid())
10277 return nullptr;
10278 Vars.push_back(EVar.get());
10279 }
10280 return getDerived().RebuildOMPFirstprivateClause(
10281 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10282}
10283
10284template <typename Derived>
10285OMPClause *
10286TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10287 llvm::SmallVector<Expr *, 16> Vars;
10288 Vars.reserve(C->varlist_size());
10289 for (auto *VE : C->varlists()) {
10290 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10291 if (EVar.isInvalid())
10292 return nullptr;
10293 Vars.push_back(EVar.get());
10294 }
10295 return getDerived().RebuildOMPLastprivateClause(
10296 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10297 C->getLParenLoc(), C->getEndLoc());
10298}
10299
10300template <typename Derived>
10301OMPClause *
10302TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10303 llvm::SmallVector<Expr *, 16> Vars;
10304 Vars.reserve(C->varlist_size());
10305 for (auto *VE : C->varlists()) {
10306 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10307 if (EVar.isInvalid())
10308 return nullptr;
10309 Vars.push_back(EVar.get());
10310 }
10311 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10312 C->getLParenLoc(), C->getEndLoc());
10313}
10314
10315template <typename Derived>
10316OMPClause *
10317TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10318 llvm::SmallVector<Expr *, 16> Vars;
10319 Vars.reserve(C->varlist_size());
10320 for (auto *VE : C->varlists()) {
10321 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10322 if (EVar.isInvalid())
10323 return nullptr;
10324 Vars.push_back(EVar.get());
10325 }
10326 CXXScopeSpec ReductionIdScopeSpec;
10327 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10328
10329 DeclarationNameInfo NameInfo = C->getNameInfo();
10330 if (NameInfo.getName()) {
10331 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10332 if (!NameInfo.getName())
10333 return nullptr;
10334 }
10335 // Build a list of all UDR decls with the same names ranged by the Scopes.
10336 // The Scope boundary is a duplication of the previous decl.
10337 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10338 for (auto *E : C->reduction_ops()) {
10339 // Transform all the decls.
10340 if (E) {
10341 auto *ULE = cast<UnresolvedLookupExpr>(E);
10342 UnresolvedSet<8> Decls;
10343 for (auto *D : ULE->decls()) {
10344 NamedDecl *InstD =
10345 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10346 Decls.addDecl(InstD, InstD->getAccess());
10347 }
10348 UnresolvedReductions.push_back(
10349 UnresolvedLookupExpr::Create(
10350 SemaRef.Context, /*NamingClass=*/nullptr,
10351 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context),
10352 NameInfo, /*ADL=*/true, ULE->isOverloaded(),
10353 Decls.begin(), Decls.end()));
10354 } else
10355 UnresolvedReductions.push_back(nullptr);
10356 }
10357 return getDerived().RebuildOMPReductionClause(
10358 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10359 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10360 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10361}
10362
10363template <typename Derived>
10364OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10365 OMPTaskReductionClause *C) {
10366 llvm::SmallVector<Expr *, 16> Vars;
10367 Vars.reserve(C->varlist_size());
10368 for (auto *VE : C->varlists()) {
10369 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10370 if (EVar.isInvalid())
10371 return nullptr;
10372 Vars.push_back(EVar.get());
10373 }
10374 CXXScopeSpec ReductionIdScopeSpec;
10375 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10376
10377 DeclarationNameInfo NameInfo = C->getNameInfo();
10378 if (NameInfo.getName()) {
10379 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10380 if (!NameInfo.getName())
10381 return nullptr;
10382 }
10383 // Build a list of all UDR decls with the same names ranged by the Scopes.
10384 // The Scope boundary is a duplication of the previous decl.
10385 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10386 for (auto *E : C->reduction_ops()) {
10387 // Transform all the decls.
10388 if (E) {
10389 auto *ULE = cast<UnresolvedLookupExpr>(E);
10390 UnresolvedSet<8> Decls;
10391 for (auto *D : ULE->decls()) {
10392 NamedDecl *InstD =
10393 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10394 Decls.addDecl(InstD, InstD->getAccess());
10395 }
10396 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10397 SemaRef.Context, /*NamingClass=*/nullptr,
10398 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10399 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10400 } else
10401 UnresolvedReductions.push_back(nullptr);
10402 }
10403 return getDerived().RebuildOMPTaskReductionClause(
10404 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10405 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10406}
10407
10408template <typename Derived>
10409OMPClause *
10410TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10411 llvm::SmallVector<Expr *, 16> Vars;
10412 Vars.reserve(C->varlist_size());
10413 for (auto *VE : C->varlists()) {
10414 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10415 if (EVar.isInvalid())
10416 return nullptr;
10417 Vars.push_back(EVar.get());
10418 }
10419 CXXScopeSpec ReductionIdScopeSpec;
10420 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
10421
10422 DeclarationNameInfo NameInfo = C->getNameInfo();
10423 if (NameInfo.getName()) {
10424 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10425 if (!NameInfo.getName())
10426 return nullptr;
10427 }
10428 // Build a list of all UDR decls with the same names ranged by the Scopes.
10429 // The Scope boundary is a duplication of the previous decl.
10430 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10431 for (auto *E : C->reduction_ops()) {
10432 // Transform all the decls.
10433 if (E) {
10434 auto *ULE = cast<UnresolvedLookupExpr>(E);
10435 UnresolvedSet<8> Decls;
10436 for (auto *D : ULE->decls()) {
10437 NamedDecl *InstD =
10438 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10439 Decls.addDecl(InstD, InstD->getAccess());
10440 }
10441 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10442 SemaRef.Context, /*NamingClass=*/nullptr,
10443 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10444 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10445 } else
10446 UnresolvedReductions.push_back(nullptr);
10447 }
10448 return getDerived().RebuildOMPInReductionClause(
10449 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10450 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10451}
10452
10453template <typename Derived>
10454OMPClause *
10455TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10456 llvm::SmallVector<Expr *, 16> Vars;
10457 Vars.reserve(C->varlist_size());
10458 for (auto *VE : C->varlists()) {
10459 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10460 if (EVar.isInvalid())
10461 return nullptr;
10462 Vars.push_back(EVar.get());
10463 }
10464 ExprResult Step = getDerived().TransformExpr(C->getStep());
10465 if (Step.isInvalid())
10466 return nullptr;
10467 return getDerived().RebuildOMPLinearClause(
10468 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10469 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10470 C->getEndLoc());
10471}
10472
10473template <typename Derived>
10474OMPClause *
10475TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10476 llvm::SmallVector<Expr *, 16> Vars;
10477 Vars.reserve(C->varlist_size());
10478 for (auto *VE : C->varlists()) {
10479 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10480 if (EVar.isInvalid())
10481 return nullptr;
10482 Vars.push_back(EVar.get());
10483 }
10484 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10485 if (Alignment.isInvalid())
10486 return nullptr;
10487 return getDerived().RebuildOMPAlignedClause(
10488 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10489 C->getColonLoc(), C->getEndLoc());
10490}
10491
10492template <typename Derived>
10493OMPClause *
10494TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10495 llvm::SmallVector<Expr *, 16> Vars;
10496 Vars.reserve(C->varlist_size());
10497 for (auto *VE : C->varlists()) {
10498 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10499 if (EVar.isInvalid())
10500 return nullptr;
10501 Vars.push_back(EVar.get());
10502 }
10503 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10504 C->getLParenLoc(), C->getEndLoc());
10505}
10506
10507template <typename Derived>
10508OMPClause *
10509TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10510 llvm::SmallVector<Expr *, 16> Vars;
10511 Vars.reserve(C->varlist_size());
10512 for (auto *VE : C->varlists()) {
10513 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10514 if (EVar.isInvalid())
10515 return nullptr;
10516 Vars.push_back(EVar.get());
10517 }
10518 return getDerived().RebuildOMPCopyprivateClause(
10519 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10520}
10521
10522template <typename Derived>
10523OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10524 llvm::SmallVector<Expr *, 16> Vars;
10525 Vars.reserve(C->varlist_size());
10526 for (auto *VE : C->varlists()) {
10527 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10528 if (EVar.isInvalid())
10529 return nullptr;
10530 Vars.push_back(EVar.get());
10531 }
10532 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10533 C->getLParenLoc(), C->getEndLoc());
10534}
10535
10536template <typename Derived>
10537OMPClause *
10538TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10539 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10540 if (E.isInvalid())
10541 return nullptr;
10542 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10543 C->getLParenLoc(), C->getEndLoc());
10544}
10545
10546template <typename Derived>
10547OMPClause *
10548TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10549 llvm::SmallVector<Expr *, 16> Vars;
10550 Expr *DepModifier = C->getModifier();
10551 if (DepModifier) {
10552 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10553 if (DepModRes.isInvalid())
10554 return nullptr;
10555 DepModifier = DepModRes.get();
10556 }
10557 Vars.reserve(C->varlist_size());
10558 for (auto *VE : C->varlists()) {
10559 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10560 if (EVar.isInvalid())
10561 return nullptr;
10562 Vars.push_back(EVar.get());
10563 }
10564 return getDerived().RebuildOMPDependClause(
10565 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10566 C->getOmpAllMemoryLoc()},
10567 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10568}
10569
10570template <typename Derived>
10571OMPClause *
10572TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10573 ExprResult E = getDerived().TransformExpr(C->getDevice());
10574 if (E.isInvalid())
10575 return nullptr;
10576 return getDerived().RebuildOMPDeviceClause(
10577 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10578 C->getModifierLoc(), C->getEndLoc());
10579}
10580
10581template <typename Derived, class T>
10582bool transformOMPMappableExprListClause(
10583 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10584 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10585 DeclarationNameInfo &MapperIdInfo,
10586 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10587 // Transform expressions in the list.
10588 Vars.reserve(N: C->varlist_size());
10589 for (auto *VE : C->varlists()) {
10590 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10591 if (EVar.isInvalid())
10592 return true;
10593 Vars.push_back(Elt: EVar.get());
10594 }
10595 // Transform mapper scope specifier and identifier.
10596 NestedNameSpecifierLoc QualifierLoc;
10597 if (C->getMapperQualifierLoc()) {
10598 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10599 C->getMapperQualifierLoc());
10600 if (!QualifierLoc)
10601 return true;
10602 }
10603 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
10604 MapperIdInfo = C->getMapperIdInfo();
10605 if (MapperIdInfo.getName()) {
10606 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10607 if (!MapperIdInfo.getName())
10608 return true;
10609 }
10610 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10611 // the previous user-defined mapper lookup in dependent environment.
10612 for (auto *E : C->mapperlists()) {
10613 // Transform all the decls.
10614 if (E) {
10615 auto *ULE = cast<UnresolvedLookupExpr>(E);
10616 UnresolvedSet<8> Decls;
10617 for (auto *D : ULE->decls()) {
10618 NamedDecl *InstD =
10619 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10620 Decls.addDecl(InstD, InstD->getAccess());
10621 }
10622 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
10623 TT.getSema().Context, /*NamingClass=*/nullptr,
10624 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
10625 MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
10626 Decls.end()));
10627 } else {
10628 UnresolvedMappers.push_back(Elt: nullptr);
10629 }
10630 }
10631 return false;
10632}
10633
10634template <typename Derived>
10635OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10636 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10637 llvm::SmallVector<Expr *, 16> Vars;
10638 Expr *IteratorModifier = C->getIteratorModifier();
10639 if (IteratorModifier) {
10640 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10641 if (MapModRes.isInvalid())
10642 return nullptr;
10643 IteratorModifier = MapModRes.get();
10644 }
10645 CXXScopeSpec MapperIdScopeSpec;
10646 DeclarationNameInfo MapperIdInfo;
10647 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10648 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10649 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10650 return nullptr;
10651 return getDerived().RebuildOMPMapClause(
10652 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10653 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10654 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10655}
10656
10657template <typename Derived>
10658OMPClause *
10659TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10660 Expr *Allocator = C->getAllocator();
10661 if (Allocator) {
10662 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10663 if (AllocatorRes.isInvalid())
10664 return nullptr;
10665 Allocator = AllocatorRes.get();
10666 }
10667 llvm::SmallVector<Expr *, 16> Vars;
10668 Vars.reserve(C->varlist_size());
10669 for (auto *VE : C->varlists()) {
10670 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10671 if (EVar.isInvalid())
10672 return nullptr;
10673 Vars.push_back(EVar.get());
10674 }
10675 return getDerived().RebuildOMPAllocateClause(
10676 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10677 C->getEndLoc());
10678}
10679
10680template <typename Derived>
10681OMPClause *
10682TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10683 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10684 if (E.isInvalid())
10685 return nullptr;
10686 return getDerived().RebuildOMPNumTeamsClause(
10687 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10688}
10689
10690template <typename Derived>
10691OMPClause *
10692TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10693 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10694 if (E.isInvalid())
10695 return nullptr;
10696 return getDerived().RebuildOMPThreadLimitClause(
10697 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10698}
10699
10700template <typename Derived>
10701OMPClause *
10702TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10703 ExprResult E = getDerived().TransformExpr(C->getPriority());
10704 if (E.isInvalid())
10705 return nullptr;
10706 return getDerived().RebuildOMPPriorityClause(
10707 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10708}
10709
10710template <typename Derived>
10711OMPClause *
10712TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10713 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10714 if (E.isInvalid())
10715 return nullptr;
10716 return getDerived().RebuildOMPGrainsizeClause(
10717 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10718 C->getModifierLoc(), C->getEndLoc());
10719}
10720
10721template <typename Derived>
10722OMPClause *
10723TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10724 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10725 if (E.isInvalid())
10726 return nullptr;
10727 return getDerived().RebuildOMPNumTasksClause(
10728 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10729 C->getModifierLoc(), C->getEndLoc());
10730}
10731
10732template <typename Derived>
10733OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10734 ExprResult E = getDerived().TransformExpr(C->getHint());
10735 if (E.isInvalid())
10736 return nullptr;
10737 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10738 C->getLParenLoc(), C->getEndLoc());
10739}
10740
10741template <typename Derived>
10742OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10743 OMPDistScheduleClause *C) {
10744 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10745 if (E.isInvalid())
10746 return nullptr;
10747 return getDerived().RebuildOMPDistScheduleClause(
10748 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10749 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10750}
10751
10752template <typename Derived>
10753OMPClause *
10754TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10755 // Rebuild Defaultmap Clause since we need to invoke the checking of
10756 // defaultmap(none:variable-category) after template initialization.
10757 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10758 C->getDefaultmapKind(),
10759 C->getBeginLoc(),
10760 C->getLParenLoc(),
10761 C->getDefaultmapModifierLoc(),
10762 C->getDefaultmapKindLoc(),
10763 C->getEndLoc());
10764}
10765
10766template <typename Derived>
10767OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10768 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10769 llvm::SmallVector<Expr *, 16> Vars;
10770 CXXScopeSpec MapperIdScopeSpec;
10771 DeclarationNameInfo MapperIdInfo;
10772 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10773 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10774 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10775 return nullptr;
10776 return getDerived().RebuildOMPToClause(
10777 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10778 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10779}
10780
10781template <typename Derived>
10782OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10783 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10784 llvm::SmallVector<Expr *, 16> Vars;
10785 CXXScopeSpec MapperIdScopeSpec;
10786 DeclarationNameInfo MapperIdInfo;
10787 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10788 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10789 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10790 return nullptr;
10791 return getDerived().RebuildOMPFromClause(
10792 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10793 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10794}
10795
10796template <typename Derived>
10797OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10798 OMPUseDevicePtrClause *C) {
10799 llvm::SmallVector<Expr *, 16> Vars;
10800 Vars.reserve(C->varlist_size());
10801 for (auto *VE : C->varlists()) {
10802 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10803 if (EVar.isInvalid())
10804 return nullptr;
10805 Vars.push_back(EVar.get());
10806 }
10807 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10808 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10809}
10810
10811template <typename Derived>
10812OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10813 OMPUseDeviceAddrClause *C) {
10814 llvm::SmallVector<Expr *, 16> Vars;
10815 Vars.reserve(C->varlist_size());
10816 for (auto *VE : C->varlists()) {
10817 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10818 if (EVar.isInvalid())
10819 return nullptr;
10820 Vars.push_back(EVar.get());
10821 }
10822 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10823 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10824}
10825
10826template <typename Derived>
10827OMPClause *
10828TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10829 llvm::SmallVector<Expr *, 16> Vars;
10830 Vars.reserve(C->varlist_size());
10831 for (auto *VE : C->varlists()) {
10832 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10833 if (EVar.isInvalid())
10834 return nullptr;
10835 Vars.push_back(EVar.get());
10836 }
10837 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10838 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10839}
10840
10841template <typename Derived>
10842OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10843 OMPHasDeviceAddrClause *C) {
10844 llvm::SmallVector<Expr *, 16> Vars;
10845 Vars.reserve(C->varlist_size());
10846 for (auto *VE : C->varlists()) {
10847 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10848 if (EVar.isInvalid())
10849 return nullptr;
10850 Vars.push_back(EVar.get());
10851 }
10852 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10853 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10854}
10855
10856template <typename Derived>
10857OMPClause *
10858TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10859 llvm::SmallVector<Expr *, 16> Vars;
10860 Vars.reserve(C->varlist_size());
10861 for (auto *VE : C->varlists()) {
10862 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10863 if (EVar.isInvalid())
10864 return nullptr;
10865 Vars.push_back(EVar.get());
10866 }
10867 return getDerived().RebuildOMPNontemporalClause(
10868 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10869}
10870
10871template <typename Derived>
10872OMPClause *
10873TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10874 llvm::SmallVector<Expr *, 16> Vars;
10875 Vars.reserve(C->varlist_size());
10876 for (auto *VE : C->varlists()) {
10877 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10878 if (EVar.isInvalid())
10879 return nullptr;
10880 Vars.push_back(EVar.get());
10881 }
10882 return getDerived().RebuildOMPInclusiveClause(
10883 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10884}
10885
10886template <typename Derived>
10887OMPClause *
10888TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10889 llvm::SmallVector<Expr *, 16> Vars;
10890 Vars.reserve(C->varlist_size());
10891 for (auto *VE : C->varlists()) {
10892 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10893 if (EVar.isInvalid())
10894 return nullptr;
10895 Vars.push_back(EVar.get());
10896 }
10897 return getDerived().RebuildOMPExclusiveClause(
10898 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10899}
10900
10901template <typename Derived>
10902OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
10903 OMPUsesAllocatorsClause *C) {
10904 SmallVector<Sema::UsesAllocatorsData, 16> Data;
10905 Data.reserve(C->getNumberOfAllocators());
10906 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
10907 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
10908 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
10909 if (Allocator.isInvalid())
10910 continue;
10911 ExprResult AllocatorTraits;
10912 if (Expr *AT = D.AllocatorTraits) {
10913 AllocatorTraits = getDerived().TransformExpr(AT);
10914 if (AllocatorTraits.isInvalid())
10915 continue;
10916 }
10917 Sema::UsesAllocatorsData &NewD = Data.emplace_back();
10918 NewD.Allocator = Allocator.get();
10919 NewD.AllocatorTraits = AllocatorTraits.get();
10920 NewD.LParenLoc = D.LParenLoc;
10921 NewD.RParenLoc = D.RParenLoc;
10922 }
10923 return getDerived().RebuildOMPUsesAllocatorsClause(
10924 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10925}
10926
10927template <typename Derived>
10928OMPClause *
10929TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
10930 SmallVector<Expr *, 4> Locators;
10931 Locators.reserve(N: C->varlist_size());
10932 ExprResult ModifierRes;
10933 if (Expr *Modifier = C->getModifier()) {
10934 ModifierRes = getDerived().TransformExpr(Modifier);
10935 if (ModifierRes.isInvalid())
10936 return nullptr;
10937 }
10938 for (Expr *E : C->varlists()) {
10939 ExprResult Locator = getDerived().TransformExpr(E);
10940 if (Locator.isInvalid())
10941 continue;
10942 Locators.push_back(Locator.get());
10943 }
10944 return getDerived().RebuildOMPAffinityClause(
10945 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
10946 ModifierRes.get(), Locators);
10947}
10948
10949template <typename Derived>
10950OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
10951 return getDerived().RebuildOMPOrderClause(
10952 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
10953 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
10954}
10955
10956template <typename Derived>
10957OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
10958 return getDerived().RebuildOMPBindClause(
10959 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
10960 C->getLParenLoc(), C->getEndLoc());
10961}
10962
10963template <typename Derived>
10964OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
10965 OMPXDynCGroupMemClause *C) {
10966 ExprResult Size = getDerived().TransformExpr(C->getSize());
10967 if (Size.isInvalid())
10968 return nullptr;
10969 return getDerived().RebuildOMPXDynCGroupMemClause(
10970 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10971}
10972
10973template <typename Derived>
10974OMPClause *
10975TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *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().RebuildOMPDoacrossClause(
10985 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
10986 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10987}
10988
10989template <typename Derived>
10990OMPClause *
10991TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
10992 SmallVector<const Attr *> NewAttrs;
10993 for (auto *A : C->getAttrs())
10994 NewAttrs.push_back(getDerived().TransformAttr(A));
10995 return getDerived().RebuildOMPXAttributeClause(
10996 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10997}
10998
10999template <typename Derived>
11000OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11001 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11002}
11003
11004//===----------------------------------------------------------------------===//
11005// OpenACC transformation
11006//===----------------------------------------------------------------------===//
11007template <typename Derived>
11008StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
11009 OpenACCComputeConstruct *C) {
11010 // TODO OpenACC: Transform clauses.
11011
11012 // Transform Structured Block.
11013 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
11014
11015 return getDerived().RebuildOpenACCComputeConstruct(
11016 C->getDirectiveKind(), C->getBeginLoc(), C->getEndLoc(), StrBlock);
11017}
11018
11019//===----------------------------------------------------------------------===//
11020// Expression transformation
11021//===----------------------------------------------------------------------===//
11022template<typename Derived>
11023ExprResult
11024TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
11025 return TransformExpr(E: E->getSubExpr());
11026}
11027
11028template <typename Derived>
11029ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
11030 SYCLUniqueStableNameExpr *E) {
11031 if (!E->isTypeDependent())
11032 return E;
11033
11034 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
11035
11036 if (!NewT)
11037 return ExprError();
11038
11039 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
11040 return E;
11041
11042 return getDerived().RebuildSYCLUniqueStableNameExpr(
11043 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
11044}
11045
11046template<typename Derived>
11047ExprResult
11048TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
11049 if (!E->isTypeDependent())
11050 return E;
11051
11052 return getDerived().RebuildPredefinedExpr(E->getLocation(),
11053 E->getIdentKind());
11054}
11055
11056template<typename Derived>
11057ExprResult
11058TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
11059 NestedNameSpecifierLoc QualifierLoc;
11060 if (E->getQualifierLoc()) {
11061 QualifierLoc
11062 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11063 if (!QualifierLoc)
11064 return ExprError();
11065 }
11066
11067 ValueDecl *ND
11068 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
11069 E->getDecl()));
11070 if (!ND)
11071 return ExprError();
11072
11073 NamedDecl *Found = ND;
11074 if (E->getFoundDecl() != E->getDecl()) {
11075 Found = cast_or_null<NamedDecl>(
11076 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
11077 if (!Found)
11078 return ExprError();
11079 }
11080
11081 DeclarationNameInfo NameInfo = E->getNameInfo();
11082 if (NameInfo.getName()) {
11083 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11084 if (!NameInfo.getName())
11085 return ExprError();
11086 }
11087
11088 if (!getDerived().AlwaysRebuild() &&
11089 QualifierLoc == E->getQualifierLoc() &&
11090 ND == E->getDecl() &&
11091 Found == E->getFoundDecl() &&
11092 NameInfo.getName() == E->getDecl()->getDeclName() &&
11093 !E->hasExplicitTemplateArgs()) {
11094
11095 // Mark it referenced in the new context regardless.
11096 // FIXME: this is a bit instantiation-specific.
11097 SemaRef.MarkDeclRefReferenced(E);
11098
11099 return E;
11100 }
11101
11102 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
11103 if (E->hasExplicitTemplateArgs()) {
11104 TemplateArgs = &TransArgs;
11105 TransArgs.setLAngleLoc(E->getLAngleLoc());
11106 TransArgs.setRAngleLoc(E->getRAngleLoc());
11107 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11108 E->getNumTemplateArgs(),
11109 TransArgs))
11110 return ExprError();
11111 }
11112
11113 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
11114 Found, TemplateArgs);
11115}
11116
11117template<typename Derived>
11118ExprResult
11119TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
11120 return E;
11121}
11122
11123template <typename Derived>
11124ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
11125 FixedPointLiteral *E) {
11126 return E;
11127}
11128
11129template<typename Derived>
11130ExprResult
11131TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
11132 return E;
11133}
11134
11135template<typename Derived>
11136ExprResult
11137TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
11138 return E;
11139}
11140
11141template<typename Derived>
11142ExprResult
11143TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
11144 return E;
11145}
11146
11147template<typename Derived>
11148ExprResult
11149TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
11150 return E;
11151}
11152
11153template<typename Derived>
11154ExprResult
11155TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
11156 return getDerived().TransformCallExpr(E);
11157}
11158
11159template<typename Derived>
11160ExprResult
11161TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
11162 ExprResult ControllingExpr;
11163 TypeSourceInfo *ControllingType = nullptr;
11164 if (E->isExprPredicate())
11165 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
11166 else
11167 ControllingType = getDerived().TransformType(E->getControllingType());
11168
11169 if (ControllingExpr.isInvalid() && !ControllingType)
11170 return ExprError();
11171
11172 SmallVector<Expr *, 4> AssocExprs;
11173 SmallVector<TypeSourceInfo *, 4> AssocTypes;
11174 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
11175 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
11176 if (TSI) {
11177 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
11178 if (!AssocType)
11179 return ExprError();
11180 AssocTypes.push_back(AssocType);
11181 } else {
11182 AssocTypes.push_back(nullptr);
11183 }
11184
11185 ExprResult AssocExpr =
11186 getDerived().TransformExpr(Assoc.getAssociationExpr());
11187 if (AssocExpr.isInvalid())
11188 return ExprError();
11189 AssocExprs.push_back(AssocExpr.get());
11190 }
11191
11192 if (!ControllingType)
11193 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
11194 E->getDefaultLoc(),
11195 E->getRParenLoc(),
11196 ControllingExpr.get(),
11197 AssocTypes,
11198 AssocExprs);
11199 return getDerived().RebuildGenericSelectionExpr(
11200 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11201 ControllingType, AssocTypes, AssocExprs);
11202}
11203
11204template<typename Derived>
11205ExprResult
11206TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11207 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11208 if (SubExpr.isInvalid())
11209 return ExprError();
11210
11211 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11212 return E;
11213
11214 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11215 E->getRParen());
11216}
11217
11218/// The operand of a unary address-of operator has special rules: it's
11219/// allowed to refer to a non-static member of a class even if there's no 'this'
11220/// object available.
11221template<typename Derived>
11222ExprResult
11223TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
11224 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
11225 return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
11226 else
11227 return getDerived().TransformExpr(E);
11228}
11229
11230template<typename Derived>
11231ExprResult
11232TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
11233 ExprResult SubExpr;
11234 if (E->getOpcode() == UO_AddrOf)
11235 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
11236 else
11237 SubExpr = TransformExpr(E: E->getSubExpr());
11238 if (SubExpr.isInvalid())
11239 return ExprError();
11240
11241 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11242 return E;
11243
11244 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11245 E->getOpcode(),
11246 SubExpr.get());
11247}
11248
11249template<typename Derived>
11250ExprResult
11251TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11252 // Transform the type.
11253 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11254 if (!Type)
11255 return ExprError();
11256
11257 // Transform all of the components into components similar to what the
11258 // parser uses.
11259 // FIXME: It would be slightly more efficient in the non-dependent case to
11260 // just map FieldDecls, rather than requiring the rebuilder to look for
11261 // the fields again. However, __builtin_offsetof is rare enough in
11262 // template code that we don't care.
11263 bool ExprChanged = false;
11264 typedef Sema::OffsetOfComponent Component;
11265 SmallVector<Component, 4> Components;
11266 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11267 const OffsetOfNode &ON = E->getComponent(Idx: I);
11268 Component Comp;
11269 Comp.isBrackets = true;
11270 Comp.LocStart = ON.getSourceRange().getBegin();
11271 Comp.LocEnd = ON.getSourceRange().getEnd();
11272 switch (ON.getKind()) {
11273 case OffsetOfNode::Array: {
11274 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
11275 ExprResult Index = getDerived().TransformExpr(FromIndex);
11276 if (Index.isInvalid())
11277 return ExprError();
11278
11279 ExprChanged = ExprChanged || Index.get() != FromIndex;
11280 Comp.isBrackets = true;
11281 Comp.U.E = Index.get();
11282 break;
11283 }
11284
11285 case OffsetOfNode::Field:
11286 case OffsetOfNode::Identifier:
11287 Comp.isBrackets = false;
11288 Comp.U.IdentInfo = ON.getFieldName();
11289 if (!Comp.U.IdentInfo)
11290 continue;
11291
11292 break;
11293
11294 case OffsetOfNode::Base:
11295 // Will be recomputed during the rebuild.
11296 continue;
11297 }
11298
11299 Components.push_back(Comp);
11300 }
11301
11302 // If nothing changed, retain the existing expression.
11303 if (!getDerived().AlwaysRebuild() &&
11304 Type == E->getTypeSourceInfo() &&
11305 !ExprChanged)
11306 return E;
11307
11308 // Build a new offsetof expression.
11309 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11310 Components, E->getRParenLoc());
11311}
11312
11313template<typename Derived>
11314ExprResult
11315TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
11316 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
11317 "opaque value expression requires transformation");
11318 return E;
11319}
11320
11321template<typename Derived>
11322ExprResult
11323TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
11324 return E;
11325}
11326
11327template <typename Derived>
11328ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
11329 llvm::SmallVector<Expr *, 8> Children;
11330 bool Changed = false;
11331 for (Expr *C : E->subExpressions()) {
11332 ExprResult NewC = getDerived().TransformExpr(C);
11333 if (NewC.isInvalid())
11334 return ExprError();
11335 Children.push_back(NewC.get());
11336
11337 Changed |= NewC.get() != C;
11338 }
11339 if (!getDerived().AlwaysRebuild() && !Changed)
11340 return E;
11341 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
11342 Children, E->getType());
11343}
11344
11345template<typename Derived>
11346ExprResult
11347TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
11348 // Rebuild the syntactic form. The original syntactic form has
11349 // opaque-value expressions in it, so strip those away and rebuild
11350 // the result. This is a really awful way of doing this, but the
11351 // better solution (rebuilding the semantic expressions and
11352 // rebinding OVEs as necessary) doesn't work; we'd need
11353 // TreeTransform to not strip away implicit conversions.
11354 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
11355 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
11356 if (result.isInvalid()) return ExprError();
11357
11358 // If that gives us a pseudo-object result back, the pseudo-object
11359 // expression must have been an lvalue-to-rvalue conversion which we
11360 // should reapply.
11361 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
11362 result = SemaRef.checkPseudoObjectRValue(E: result.get());
11363
11364 return result;
11365}
11366
11367template<typename Derived>
11368ExprResult
11369TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11370 UnaryExprOrTypeTraitExpr *E) {
11371 if (E->isArgumentType()) {
11372 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11373
11374 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11375 if (!NewT)
11376 return ExprError();
11377
11378 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11379 return E;
11380
11381 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11382 E->getKind(),
11383 E->getSourceRange());
11384 }
11385
11386 // C++0x [expr.sizeof]p1:
11387 // The operand is either an expression, which is an unevaluated operand
11388 // [...]
11389 EnterExpressionEvaluationContext Unevaluated(
11390 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
11391 Sema::ReuseLambdaContextDecl);
11392
11393 // Try to recover if we have something like sizeof(T::X) where X is a type.
11394 // Notably, there must be *exactly* one set of parens if X is a type.
11395 TypeSourceInfo *RecoveryTSI = nullptr;
11396 ExprResult SubExpr;
11397 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11398 if (auto *DRE =
11399 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11400 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11401 PE, DRE, false, &RecoveryTSI);
11402 else
11403 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11404
11405 if (RecoveryTSI) {
11406 return getDerived().RebuildUnaryExprOrTypeTrait(
11407 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11408 } else if (SubExpr.isInvalid())
11409 return ExprError();
11410
11411 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11412 return E;
11413
11414 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11415 E->getOperatorLoc(),
11416 E->getKind(),
11417 E->getSourceRange());
11418}
11419
11420template<typename Derived>
11421ExprResult
11422TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11423 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11424 if (LHS.isInvalid())
11425 return ExprError();
11426
11427 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11428 if (RHS.isInvalid())
11429 return ExprError();
11430
11431
11432 if (!getDerived().AlwaysRebuild() &&
11433 LHS.get() == E->getLHS() &&
11434 RHS.get() == E->getRHS())
11435 return E;
11436
11437 return getDerived().RebuildArraySubscriptExpr(
11438 LHS.get(),
11439 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11440}
11441
11442template <typename Derived>
11443ExprResult
11444TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11445 ExprResult Base = getDerived().TransformExpr(E->getBase());
11446 if (Base.isInvalid())
11447 return ExprError();
11448
11449 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11450 if (RowIdx.isInvalid())
11451 return ExprError();
11452
11453 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11454 if (ColumnIdx.isInvalid())
11455 return ExprError();
11456
11457 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11458 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11459 return E;
11460
11461 return getDerived().RebuildMatrixSubscriptExpr(
11462 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11463}
11464
11465template <typename Derived>
11466ExprResult
11467TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
11468 ExprResult Base = getDerived().TransformExpr(E->getBase());
11469 if (Base.isInvalid())
11470 return ExprError();
11471
11472 ExprResult LowerBound;
11473 if (E->getLowerBound()) {
11474 LowerBound = getDerived().TransformExpr(E->getLowerBound());
11475 if (LowerBound.isInvalid())
11476 return ExprError();
11477 }
11478
11479 ExprResult Length;
11480 if (E->getLength()) {
11481 Length = getDerived().TransformExpr(E->getLength());
11482 if (Length.isInvalid())
11483 return ExprError();
11484 }
11485
11486 ExprResult Stride;
11487 if (Expr *Str = E->getStride()) {
11488 Stride = getDerived().TransformExpr(Str);
11489 if (Stride.isInvalid())
11490 return ExprError();
11491 }
11492
11493 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11494 LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())
11495 return E;
11496
11497 return getDerived().RebuildOMPArraySectionExpr(
11498 Base.get(), E->getBase()->getEndLoc(), LowerBound.get(),
11499 E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(),
11500 E->getRBracketLoc());
11501}
11502
11503template <typename Derived>
11504ExprResult
11505TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
11506 ExprResult Base = getDerived().TransformExpr(E->getBase());
11507 if (Base.isInvalid())
11508 return ExprError();
11509
11510 SmallVector<Expr *, 4> Dims;
11511 bool ErrorFound = false;
11512 for (Expr *Dim : E->getDimensions()) {
11513 ExprResult DimRes = getDerived().TransformExpr(Dim);
11514 if (DimRes.isInvalid()) {
11515 ErrorFound = true;
11516 continue;
11517 }
11518 Dims.push_back(Elt: DimRes.get());
11519 }
11520
11521 if (ErrorFound)
11522 return ExprError();
11523 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
11524 E->getRParenLoc(), Dims,
11525 E->getBracketsRanges());
11526}
11527
11528template <typename Derived>
11529ExprResult
11530TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
11531 unsigned NumIterators = E->numOfIterators();
11532 SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators);
11533
11534 bool ErrorFound = false;
11535 bool NeedToRebuild = getDerived().AlwaysRebuild();
11536 for (unsigned I = 0; I < NumIterators; ++I) {
11537 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
11538 Data[I].DeclIdent = D->getIdentifier();
11539 Data[I].DeclIdentLoc = D->getLocation();
11540 if (D->getLocation() == D->getBeginLoc()) {
11541 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
11542 "Implicit type must be int.");
11543 } else {
11544 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
11545 QualType DeclTy = getDerived().TransformType(D->getType());
11546 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
11547 }
11548 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
11549 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
11550 ExprResult End = getDerived().TransformExpr(Range.End);
11551 ExprResult Step = getDerived().TransformExpr(Range.Step);
11552 ErrorFound = ErrorFound ||
11553 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
11554 !Data[I].Type.get().isNull())) ||
11555 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
11556 if (ErrorFound)
11557 continue;
11558 Data[I].Range.Begin = Begin.get();
11559 Data[I].Range.End = End.get();
11560 Data[I].Range.Step = Step.get();
11561 Data[I].AssignLoc = E->getAssignLoc(I);
11562 Data[I].ColonLoc = E->getColonLoc(I);
11563 Data[I].SecColonLoc = E->getSecondColonLoc(I);
11564 NeedToRebuild =
11565 NeedToRebuild ||
11566 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
11567 D->getType().getTypePtrOrNull()) ||
11568 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
11569 Range.Step != Data[I].Range.Step;
11570 }
11571 if (ErrorFound)
11572 return ExprError();
11573 if (!NeedToRebuild)
11574 return E;
11575
11576 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
11577 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
11578 if (!Res.isUsable())
11579 return Res;
11580 auto *IE = cast<OMPIteratorExpr>(Res.get());
11581 for (unsigned I = 0; I < NumIterators; ++I)
11582 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
11583 IE->getIteratorDecl(I));
11584 return Res;
11585}
11586
11587template<typename Derived>
11588ExprResult
11589TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
11590 // Transform the callee.
11591 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11592 if (Callee.isInvalid())
11593 return ExprError();
11594
11595 // Transform arguments.
11596 bool ArgChanged = false;
11597 SmallVector<Expr*, 8> Args;
11598 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11599 &ArgChanged))
11600 return ExprError();
11601
11602 if (!getDerived().AlwaysRebuild() &&
11603 Callee.get() == E->getCallee() &&
11604 !ArgChanged)
11605 return SemaRef.MaybeBindToTemporary(E);
11606
11607 // FIXME: Wrong source location information for the '('.
11608 SourceLocation FakeLParenLoc
11609 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11610
11611 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11612 if (E->hasStoredFPFeatures()) {
11613 FPOptionsOverride NewOverrides = E->getFPFeatures();
11614 getSema().CurFPFeatures =
11615 NewOverrides.applyOverrides(getSema().getLangOpts());
11616 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11617 }
11618
11619 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11620 Args,
11621 E->getRParenLoc());
11622}
11623
11624template<typename Derived>
11625ExprResult
11626TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
11627 ExprResult Base = getDerived().TransformExpr(E->getBase());
11628 if (Base.isInvalid())
11629 return ExprError();
11630
11631 NestedNameSpecifierLoc QualifierLoc;
11632 if (E->hasQualifier()) {
11633 QualifierLoc
11634 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11635
11636 if (!QualifierLoc)
11637 return ExprError();
11638 }
11639 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
11640
11641 ValueDecl *Member
11642 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
11643 E->getMemberDecl()));
11644 if (!Member)
11645 return ExprError();
11646
11647 NamedDecl *FoundDecl = E->getFoundDecl();
11648 if (FoundDecl == E->getMemberDecl()) {
11649 FoundDecl = Member;
11650 } else {
11651 FoundDecl = cast_or_null<NamedDecl>(
11652 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
11653 if (!FoundDecl)
11654 return ExprError();
11655 }
11656
11657 if (!getDerived().AlwaysRebuild() &&
11658 Base.get() == E->getBase() &&
11659 QualifierLoc == E->getQualifierLoc() &&
11660 Member == E->getMemberDecl() &&
11661 FoundDecl == E->getFoundDecl() &&
11662 !E->hasExplicitTemplateArgs()) {
11663
11664 // Skip for member expression of (this->f), rebuilt thisi->f is needed
11665 // for Openmp where the field need to be privatizized in the case.
11666 if (!(isa<CXXThisExpr>(E->getBase()) &&
11667 getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) {
11668 // Mark it referenced in the new context regardless.
11669 // FIXME: this is a bit instantiation-specific.
11670 SemaRef.MarkMemberReferenced(E);
11671 return E;
11672 }
11673 }
11674
11675 TemplateArgumentListInfo TransArgs;
11676 if (E->hasExplicitTemplateArgs()) {
11677 TransArgs.setLAngleLoc(E->getLAngleLoc());
11678 TransArgs.setRAngleLoc(E->getRAngleLoc());
11679 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11680 E->getNumTemplateArgs(),
11681 TransArgs))
11682 return ExprError();
11683 }
11684
11685 // FIXME: Bogus source location for the operator
11686 SourceLocation FakeOperatorLoc =
11687 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
11688
11689 // FIXME: to do this check properly, we will need to preserve the
11690 // first-qualifier-in-scope here, just in case we had a dependent
11691 // base (and therefore couldn't do the check) and a
11692 // nested-name-qualifier (and therefore could do the lookup).
11693 NamedDecl *FirstQualifierInScope = nullptr;
11694 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
11695 if (MemberNameInfo.getName()) {
11696 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
11697 if (!MemberNameInfo.getName())
11698 return ExprError();
11699 }
11700
11701 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
11702 E->isArrow(),
11703 QualifierLoc,
11704 TemplateKWLoc,
11705 MemberNameInfo,
11706 Member,
11707 FoundDecl,
11708 (E->hasExplicitTemplateArgs()
11709 ? &TransArgs : nullptr),
11710 FirstQualifierInScope);
11711}
11712
11713template<typename Derived>
11714ExprResult
11715TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
11716 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11717 if (LHS.isInvalid())
11718 return ExprError();
11719
11720 ExprResult RHS =
11721 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
11722 if (RHS.isInvalid())
11723 return ExprError();
11724
11725 if (!getDerived().AlwaysRebuild() &&
11726 LHS.get() == E->getLHS() &&
11727 RHS.get() == E->getRHS())
11728 return E;
11729
11730 if (E->isCompoundAssignmentOp())
11731 // FPFeatures has already been established from trailing storage
11732 return getDerived().RebuildBinaryOperator(
11733 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
11734 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11735 FPOptionsOverride NewOverrides(E->getFPFeatures());
11736 getSema().CurFPFeatures =
11737 NewOverrides.applyOverrides(getSema().getLangOpts());
11738 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11739 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
11740 LHS.get(), RHS.get());
11741}
11742
11743template <typename Derived>
11744ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
11745 CXXRewrittenBinaryOperator *E) {
11746 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
11747
11748 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
11749 if (LHS.isInvalid())
11750 return ExprError();
11751
11752 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
11753 if (RHS.isInvalid())
11754 return ExprError();
11755
11756 // Extract the already-resolved callee declarations so that we can restrict
11757 // ourselves to using them as the unqualified lookup results when rebuilding.
11758 UnresolvedSet<2> UnqualLookups;
11759 bool ChangedAnyLookups = false;
11760 Expr *PossibleBinOps[] = {E->getSemanticForm(),
11761 const_cast<Expr *>(Decomp.InnerBinOp)};
11762 for (Expr *PossibleBinOp : PossibleBinOps) {
11763 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
11764 if (!Op)
11765 continue;
11766 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
11767 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
11768 continue;
11769
11770 // Transform the callee in case we built a call to a local extern
11771 // declaration.
11772 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
11773 E->getOperatorLoc(), Callee->getFoundDecl()));
11774 if (!Found)
11775 return ExprError();
11776 if (Found != Callee->getFoundDecl())
11777 ChangedAnyLookups = true;
11778 UnqualLookups.addDecl(Found);
11779 }
11780
11781 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
11782 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
11783 // Mark all functions used in the rewrite as referenced. Note that when
11784 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
11785 // function calls, and/or there might be a user-defined conversion sequence
11786 // applied to the operands of the <.
11787 // FIXME: this is a bit instantiation-specific.
11788 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
11789 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
11790 return E;
11791 }
11792
11793 return getDerived().RebuildCXXRewrittenBinaryOperator(
11794 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
11795}
11796
11797template<typename Derived>
11798ExprResult
11799TreeTransform<Derived>::TransformCompoundAssignOperator(
11800 CompoundAssignOperator *E) {
11801 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11802 FPOptionsOverride NewOverrides(E->getFPFeatures());
11803 getSema().CurFPFeatures =
11804 NewOverrides.applyOverrides(getSema().getLangOpts());
11805 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11806 return getDerived().TransformBinaryOperator(E);
11807}
11808
11809template<typename Derived>
11810ExprResult TreeTransform<Derived>::
11811TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
11812 // Just rebuild the common and RHS expressions and see whether we
11813 // get any changes.
11814
11815 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
11816 if (commonExpr.isInvalid())
11817 return ExprError();
11818
11819 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
11820 if (rhs.isInvalid())
11821 return ExprError();
11822
11823 if (!getDerived().AlwaysRebuild() &&
11824 commonExpr.get() == e->getCommon() &&
11825 rhs.get() == e->getFalseExpr())
11826 return e;
11827
11828 return getDerived().RebuildConditionalOperator(commonExpr.get(),
11829 e->getQuestionLoc(),
11830 nullptr,
11831 e->getColonLoc(),
11832 rhs.get());
11833}
11834
11835template<typename Derived>
11836ExprResult
11837TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
11838 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11839 if (Cond.isInvalid())
11840 return ExprError();
11841
11842 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11843 if (LHS.isInvalid())
11844 return ExprError();
11845
11846 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11847 if (RHS.isInvalid())
11848 return ExprError();
11849
11850 if (!getDerived().AlwaysRebuild() &&
11851 Cond.get() == E->getCond() &&
11852 LHS.get() == E->getLHS() &&
11853 RHS.get() == E->getRHS())
11854 return E;
11855
11856 return getDerived().RebuildConditionalOperator(Cond.get(),
11857 E->getQuestionLoc(),
11858 LHS.get(),
11859 E->getColonLoc(),
11860 RHS.get());
11861}
11862
11863template<typename Derived>
11864ExprResult
11865TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
11866 // Implicit casts are eliminated during transformation, since they
11867 // will be recomputed by semantic analysis after transformation.
11868 return getDerived().TransformExpr(E->getSubExprAsWritten());
11869}
11870
11871template<typename Derived>
11872ExprResult
11873TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
11874 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
11875 if (!Type)
11876 return ExprError();
11877
11878 ExprResult SubExpr
11879 = getDerived().TransformExpr(E->getSubExprAsWritten());
11880 if (SubExpr.isInvalid())
11881 return ExprError();
11882
11883 if (!getDerived().AlwaysRebuild() &&
11884 Type == E->getTypeInfoAsWritten() &&
11885 SubExpr.get() == E->getSubExpr())
11886 return E;
11887
11888 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
11889 Type,
11890 E->getRParenLoc(),
11891 SubExpr.get());
11892}
11893
11894template<typename Derived>
11895ExprResult
11896TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
11897 TypeSourceInfo *OldT = E->getTypeSourceInfo();
11898 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11899 if (!NewT)
11900 return ExprError();
11901
11902 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
11903 if (Init.isInvalid())
11904 return ExprError();
11905
11906 if (!getDerived().AlwaysRebuild() &&
11907 OldT == NewT &&
11908 Init.get() == E->getInitializer())
11909 return SemaRef.MaybeBindToTemporary(E);
11910
11911 // Note: the expression type doesn't necessarily match the
11912 // type-as-written, but that's okay, because it should always be
11913 // derivable from the initializer.
11914
11915 return getDerived().RebuildCompoundLiteralExpr(
11916 E->getLParenLoc(), NewT,
11917 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
11918}
11919
11920template<typename Derived>
11921ExprResult
11922TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
11923 ExprResult Base = getDerived().TransformExpr(E->getBase());
11924 if (Base.isInvalid())
11925 return ExprError();
11926
11927 if (!getDerived().AlwaysRebuild() &&
11928 Base.get() == E->getBase())
11929 return E;
11930
11931 // FIXME: Bad source location
11932 SourceLocation FakeOperatorLoc =
11933 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
11934 return getDerived().RebuildExtVectorElementExpr(
11935 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
11936 E->getAccessor());
11937}
11938
11939template<typename Derived>
11940ExprResult
11941TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
11942 if (InitListExpr *Syntactic = E->getSyntacticForm())
11943 E = Syntactic;
11944
11945 bool InitChanged = false;
11946
11947 EnterExpressionEvaluationContext Context(
11948 getSema(), EnterExpressionEvaluationContext::InitList);
11949
11950 SmallVector<Expr*, 4> Inits;
11951 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
11952 Inits, &InitChanged))
11953 return ExprError();
11954
11955 if (!getDerived().AlwaysRebuild() && !InitChanged) {
11956 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
11957 // in some cases. We can't reuse it in general, because the syntactic and
11958 // semantic forms are linked, and we can't know that semantic form will
11959 // match even if the syntactic form does.
11960 }
11961
11962 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
11963 E->getRBraceLoc());
11964}
11965
11966template<typename Derived>
11967ExprResult
11968TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
11969 Designation Desig;
11970
11971 // transform the initializer value
11972 ExprResult Init = getDerived().TransformExpr(E->getInit());
11973 if (Init.isInvalid())
11974 return ExprError();
11975
11976 // transform the designators.
11977 SmallVector<Expr*, 4> ArrayExprs;
11978 bool ExprChanged = false;
11979 for (const DesignatedInitExpr::Designator &D : E->designators()) {
11980 if (D.isFieldDesignator()) {
11981 if (D.getFieldDecl()) {
11982 FieldDecl *Field = cast_or_null<FieldDecl>(
11983 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
11984 if (Field != D.getFieldDecl())
11985 // Rebuild the expression when the transformed FieldDecl is
11986 // different to the already assigned FieldDecl.
11987 ExprChanged = true;
11988 if (Field->isAnonymousStructOrUnion())
11989 continue;
11990 } else {
11991 // Ensure that the designator expression is rebuilt when there isn't
11992 // a resolved FieldDecl in the designator as we don't want to assign
11993 // a FieldDecl to a pattern designator that will be instantiated again.
11994 ExprChanged = true;
11995 }
11996 Desig.AddDesignator(Designator::CreateFieldDesignator(
11997 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
11998 continue;
11999 }
12000
12001 if (D.isArrayDesignator()) {
12002 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
12003 if (Index.isInvalid())
12004 return ExprError();
12005
12006 Desig.AddDesignator(
12007 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
12008
12009 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
12010 ArrayExprs.push_back(Index.get());
12011 continue;
12012 }
12013
12014 assert(D.isArrayRangeDesignator() && "New kind of designator?");
12015 ExprResult Start
12016 = getDerived().TransformExpr(E->getArrayRangeStart(D));
12017 if (Start.isInvalid())
12018 return ExprError();
12019
12020 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
12021 if (End.isInvalid())
12022 return ExprError();
12023
12024 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
12025 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
12026
12027 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
12028 End.get() != E->getArrayRangeEnd(D);
12029
12030 ArrayExprs.push_back(Start.get());
12031 ArrayExprs.push_back(End.get());
12032 }
12033
12034 if (!getDerived().AlwaysRebuild() &&
12035 Init.get() == E->getInit() &&
12036 !ExprChanged)
12037 return E;
12038
12039 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
12040 E->getEqualOrColonLoc(),
12041 E->usesGNUSyntax(), Init.get());
12042}
12043
12044// Seems that if TransformInitListExpr() only works on the syntactic form of an
12045// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
12046template<typename Derived>
12047ExprResult
12048TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
12049 DesignatedInitUpdateExpr *E) {
12050 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
12051 "initializer");
12052 return ExprError();
12053}
12054
12055template<typename Derived>
12056ExprResult
12057TreeTransform<Derived>::TransformNoInitExpr(
12058 NoInitExpr *E) {
12059 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
12060 return ExprError();
12061}
12062
12063template<typename Derived>
12064ExprResult
12065TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
12066 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
12067 return ExprError();
12068}
12069
12070template<typename Derived>
12071ExprResult
12072TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
12073 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
12074 return ExprError();
12075}
12076
12077template<typename Derived>
12078ExprResult
12079TreeTransform<Derived>::TransformImplicitValueInitExpr(
12080 ImplicitValueInitExpr *E) {
12081 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
12082
12083 // FIXME: Will we ever have proper type location here? Will we actually
12084 // need to transform the type?
12085 QualType T = getDerived().TransformType(E->getType());
12086 if (T.isNull())
12087 return ExprError();
12088
12089 if (!getDerived().AlwaysRebuild() &&
12090 T == E->getType())
12091 return E;
12092
12093 return getDerived().RebuildImplicitValueInitExpr(T);
12094}
12095
12096template<typename Derived>
12097ExprResult
12098TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
12099 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
12100 if (!TInfo)
12101 return ExprError();
12102
12103 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12104 if (SubExpr.isInvalid())
12105 return ExprError();
12106
12107 if (!getDerived().AlwaysRebuild() &&
12108 TInfo == E->getWrittenTypeInfo() &&
12109 SubExpr.get() == E->getSubExpr())
12110 return E;
12111
12112 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
12113 TInfo, E->getRParenLoc());
12114}
12115
12116template<typename Derived>
12117ExprResult
12118TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
12119 bool ArgumentChanged = false;
12120 SmallVector<Expr*, 4> Inits;
12121 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
12122 ArgChanged: &ArgumentChanged))
12123 return ExprError();
12124
12125 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
12126 Inits,
12127 E->getRParenLoc());
12128}
12129
12130/// Transform an address-of-label expression.
12131///
12132/// By default, the transformation of an address-of-label expression always
12133/// rebuilds the expression, so that the label identifier can be resolved to
12134/// the corresponding label statement by semantic analysis.
12135template<typename Derived>
12136ExprResult
12137TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
12138 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
12139 E->getLabel());
12140 if (!LD)
12141 return ExprError();
12142
12143 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
12144 cast<LabelDecl>(LD));
12145}
12146
12147template<typename Derived>
12148ExprResult
12149TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
12150 SemaRef.ActOnStartStmtExpr();
12151 StmtResult SubStmt
12152 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
12153 if (SubStmt.isInvalid()) {
12154 SemaRef.ActOnStmtExprError();
12155 return ExprError();
12156 }
12157
12158 unsigned OldDepth = E->getTemplateDepth();
12159 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
12160
12161 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
12162 SubStmt.get() == E->getSubStmt()) {
12163 // Calling this an 'error' is unintuitive, but it does the right thing.
12164 SemaRef.ActOnStmtExprError();
12165 return SemaRef.MaybeBindToTemporary(E);
12166 }
12167
12168 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
12169 E->getRParenLoc(), NewDepth);
12170}
12171
12172template<typename Derived>
12173ExprResult
12174TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
12175 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12176 if (Cond.isInvalid())
12177 return ExprError();
12178
12179 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12180 if (LHS.isInvalid())
12181 return ExprError();
12182
12183 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12184 if (RHS.isInvalid())
12185 return ExprError();
12186
12187 if (!getDerived().AlwaysRebuild() &&
12188 Cond.get() == E->getCond() &&
12189 LHS.get() == E->getLHS() &&
12190 RHS.get() == E->getRHS())
12191 return E;
12192
12193 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
12194 Cond.get(), LHS.get(), RHS.get(),
12195 E->getRParenLoc());
12196}
12197
12198template<typename Derived>
12199ExprResult
12200TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12201 return E;
12202}
12203
12204template<typename Derived>
12205ExprResult
12206TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12207 switch (E->getOperator()) {
12208 case OO_New:
12209 case OO_Delete:
12210 case OO_Array_New:
12211 case OO_Array_Delete:
12212 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12213
12214 case OO_Subscript:
12215 case OO_Call: {
12216 // This is a call to an object's operator().
12217 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12218
12219 // Transform the object itself.
12220 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
12221 if (Object.isInvalid())
12222 return ExprError();
12223
12224 // FIXME: Poor location information
12225 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12226 Loc: static_cast<Expr *>(Object.get())->getEndLoc());
12227
12228 // Transform the call arguments.
12229 SmallVector<Expr*, 8> Args;
12230 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12231 Args))
12232 return ExprError();
12233
12234 if (E->getOperator() == OO_Subscript)
12235 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12236 Args, E->getEndLoc());
12237
12238 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12239 E->getEndLoc());
12240 }
12241
12242#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12243 case OO_##Name: \
12244 break;
12245
12246#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12247#include "clang/Basic/OperatorKinds.def"
12248
12249 case OO_Conditional:
12250 llvm_unreachable("conditional operator is not actually overloadable");
12251
12252 case OO_None:
12253 case NUM_OVERLOADED_OPERATORS:
12254 llvm_unreachable("not an overloaded operator?");
12255 }
12256
12257 ExprResult First;
12258 if (E->getOperator() == OO_Amp)
12259 First = getDerived().TransformAddressOfOperand(E->getArg(0));
12260 else
12261 First = getDerived().TransformExpr(E->getArg(0));
12262 if (First.isInvalid())
12263 return ExprError();
12264
12265 ExprResult Second;
12266 if (E->getNumArgs() == 2) {
12267 Second =
12268 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
12269 if (Second.isInvalid())
12270 return ExprError();
12271 }
12272
12273 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12274 FPOptionsOverride NewOverrides(E->getFPFeatures());
12275 getSema().CurFPFeatures =
12276 NewOverrides.applyOverrides(getSema().getLangOpts());
12277 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12278
12279 Expr *Callee = E->getCallee();
12280 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
12281 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12282 Sema::LookupOrdinaryName);
12283 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12284 return ExprError();
12285
12286 return getDerived().RebuildCXXOperatorCallExpr(
12287 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12288 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12289 }
12290
12291 UnresolvedSet<1> Functions;
12292 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
12293 Callee = ICE->getSubExprAsWritten();
12294 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
12295 ValueDecl *VD = cast_or_null<ValueDecl>(
12296 getDerived().TransformDecl(DR->getLocation(), DR));
12297 if (!VD)
12298 return ExprError();
12299
12300 if (!isa<CXXMethodDecl>(VD))
12301 Functions.addDecl(VD);
12302
12303 return getDerived().RebuildCXXOperatorCallExpr(
12304 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12305 /*RequiresADL=*/false, Functions, First.get(), Second.get());
12306}
12307
12308template<typename Derived>
12309ExprResult
12310TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
12311 return getDerived().TransformCallExpr(E);
12312}
12313
12314template <typename Derived>
12315ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
12316 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
12317 getSema().CurContext != E->getParentContext();
12318
12319 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
12320 return E;
12321
12322 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
12323 E->getBeginLoc(), E->getEndLoc(),
12324 getSema().CurContext);
12325}
12326
12327template<typename Derived>
12328ExprResult
12329TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
12330 // Transform the callee.
12331 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12332 if (Callee.isInvalid())
12333 return ExprError();
12334
12335 // Transform exec config.
12336 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
12337 if (EC.isInvalid())
12338 return ExprError();
12339
12340 // Transform arguments.
12341 bool ArgChanged = false;
12342 SmallVector<Expr*, 8> Args;
12343 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12344 &ArgChanged))
12345 return ExprError();
12346
12347 if (!getDerived().AlwaysRebuild() &&
12348 Callee.get() == E->getCallee() &&
12349 !ArgChanged)
12350 return SemaRef.MaybeBindToTemporary(E);
12351
12352 // FIXME: Wrong source location information for the '('.
12353 SourceLocation FakeLParenLoc
12354 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12355 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12356 Args,
12357 E->getRParenLoc(), EC.get());
12358}
12359
12360template<typename Derived>
12361ExprResult
12362TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
12363 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12364 if (!Type)
12365 return ExprError();
12366
12367 ExprResult SubExpr
12368 = getDerived().TransformExpr(E->getSubExprAsWritten());
12369 if (SubExpr.isInvalid())
12370 return ExprError();
12371
12372 if (!getDerived().AlwaysRebuild() &&
12373 Type == E->getTypeInfoAsWritten() &&
12374 SubExpr.get() == E->getSubExpr())
12375 return E;
12376 return getDerived().RebuildCXXNamedCastExpr(
12377 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
12378 Type, E->getAngleBrackets().getEnd(),
12379 // FIXME. this should be '(' location
12380 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
12381}
12382
12383template<typename Derived>
12384ExprResult
12385TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
12386 TypeSourceInfo *TSI =
12387 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12388 if (!TSI)
12389 return ExprError();
12390
12391 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12392 if (Sub.isInvalid())
12393 return ExprError();
12394
12395 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12396 Sub.get(), BCE->getEndLoc());
12397}
12398
12399template<typename Derived>
12400ExprResult
12401TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12402 return getDerived().TransformCXXNamedCastExpr(E);
12403}
12404
12405template<typename Derived>
12406ExprResult
12407TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12408 return getDerived().TransformCXXNamedCastExpr(E);
12409}
12410
12411template<typename Derived>
12412ExprResult
12413TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12414 CXXReinterpretCastExpr *E) {
12415 return getDerived().TransformCXXNamedCastExpr(E);
12416}
12417
12418template<typename Derived>
12419ExprResult
12420TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12421 return getDerived().TransformCXXNamedCastExpr(E);
12422}
12423
12424template<typename Derived>
12425ExprResult
12426TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12427 return getDerived().TransformCXXNamedCastExpr(E);
12428}
12429
12430template<typename Derived>
12431ExprResult
12432TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12433 CXXFunctionalCastExpr *E) {
12434 TypeSourceInfo *Type =
12435 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12436 if (!Type)
12437 return ExprError();
12438
12439 ExprResult SubExpr
12440 = getDerived().TransformExpr(E->getSubExprAsWritten());
12441 if (SubExpr.isInvalid())
12442 return ExprError();
12443
12444 if (!getDerived().AlwaysRebuild() &&
12445 Type == E->getTypeInfoAsWritten() &&
12446 SubExpr.get() == E->getSubExpr())
12447 return E;
12448
12449 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12450 E->getLParenLoc(),
12451 SubExpr.get(),
12452 E->getRParenLoc(),
12453 E->isListInitialization());
12454}
12455
12456template<typename Derived>
12457ExprResult
12458TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12459 if (E->isTypeOperand()) {
12460 TypeSourceInfo *TInfo
12461 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12462 if (!TInfo)
12463 return ExprError();
12464
12465 if (!getDerived().AlwaysRebuild() &&
12466 TInfo == E->getTypeOperandSourceInfo())
12467 return E;
12468
12469 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12470 TInfo, E->getEndLoc());
12471 }
12472
12473 // Typeid's operand is an unevaluated context, unless it's a polymorphic
12474 // type. We must not unilaterally enter unevaluated context here, as then
12475 // semantic processing can re-transform an already transformed operand.
12476 Expr *Op = E->getExprOperand();
12477 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
12478 if (E->isGLValue())
12479 if (auto *RecordT = Op->getType()->getAs<RecordType>())
12480 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
12481 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
12482
12483 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
12484 Sema::ReuseLambdaContextDecl);
12485
12486 ExprResult SubExpr = getDerived().TransformExpr(Op);
12487 if (SubExpr.isInvalid())
12488 return ExprError();
12489
12490 if (!getDerived().AlwaysRebuild() &&
12491 SubExpr.get() == E->getExprOperand())
12492 return E;
12493
12494 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12495 SubExpr.get(), E->getEndLoc());
12496}
12497
12498template<typename Derived>
12499ExprResult
12500TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
12501 if (E->isTypeOperand()) {
12502 TypeSourceInfo *TInfo
12503 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12504 if (!TInfo)
12505 return ExprError();
12506
12507 if (!getDerived().AlwaysRebuild() &&
12508 TInfo == E->getTypeOperandSourceInfo())
12509 return E;
12510
12511 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12512 TInfo, E->getEndLoc());
12513 }
12514
12515 EnterExpressionEvaluationContext Unevaluated(
12516 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12517
12518 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
12519 if (SubExpr.isInvalid())
12520 return ExprError();
12521
12522 if (!getDerived().AlwaysRebuild() &&
12523 SubExpr.get() == E->getExprOperand())
12524 return E;
12525
12526 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12527 SubExpr.get(), E->getEndLoc());
12528}
12529
12530template<typename Derived>
12531ExprResult
12532TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
12533 return E;
12534}
12535
12536template<typename Derived>
12537ExprResult
12538TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
12539 CXXNullPtrLiteralExpr *E) {
12540 return E;
12541}
12542
12543template<typename Derived>
12544ExprResult
12545TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
12546
12547 // In lambdas, the qualifiers of the type depends of where in
12548 // the call operator `this` appear, and we do not have a good way to
12549 // rebuild this information, so we transform the type.
12550 //
12551 // In other contexts, the type of `this` may be overrided
12552 // for type deduction, so we need to recompute it.
12553 QualType T = getSema().getCurLambda() ?
12554 getDerived().TransformType(E->getType())
12555 : getSema().getCurrentThisType();
12556
12557 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
12558 // Mark it referenced in the new context regardless.
12559 // FIXME: this is a bit instantiation-specific.
12560 getSema().MarkThisReferenced(E);
12561 return E;
12562 }
12563
12564 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
12565}
12566
12567template<typename Derived>
12568ExprResult
12569TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
12570 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12571 if (SubExpr.isInvalid())
12572 return ExprError();
12573
12574 if (!getDerived().AlwaysRebuild() &&
12575 SubExpr.get() == E->getSubExpr())
12576 return E;
12577
12578 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
12579 E->isThrownVariableInScope());
12580}
12581
12582template<typename Derived>
12583ExprResult
12584TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
12585 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
12586 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
12587 if (!Param)
12588 return ExprError();
12589
12590 ExprResult InitRes;
12591 if (E->hasRewrittenInit()) {
12592 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
12593 if (InitRes.isInvalid())
12594 return ExprError();
12595 }
12596
12597 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
12598 E->getUsedContext() == SemaRef.CurContext &&
12599 InitRes.get() == E->getRewrittenExpr())
12600 return E;
12601
12602 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
12603 InitRes.get());
12604}
12605
12606template<typename Derived>
12607ExprResult
12608TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
12609 FieldDecl *Field = cast_or_null<FieldDecl>(
12610 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
12611 if (!Field)
12612 return ExprError();
12613
12614 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
12615 E->getUsedContext() == SemaRef.CurContext)
12616 return E;
12617
12618 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
12619}
12620
12621template<typename Derived>
12622ExprResult
12623TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
12624 CXXScalarValueInitExpr *E) {
12625 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
12626 if (!T)
12627 return ExprError();
12628
12629 if (!getDerived().AlwaysRebuild() &&
12630 T == E->getTypeSourceInfo())
12631 return E;
12632
12633 return getDerived().RebuildCXXScalarValueInitExpr(T,
12634 /*FIXME:*/T->getTypeLoc().getEndLoc(),
12635 E->getRParenLoc());
12636}
12637
12638template<typename Derived>
12639ExprResult
12640TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
12641 // Transform the type that we're allocating
12642 TypeSourceInfo *AllocTypeInfo =
12643 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
12644 if (!AllocTypeInfo)
12645 return ExprError();
12646
12647 // Transform the size of the array we're allocating (if any).
12648 std::optional<Expr *> ArraySize;
12649 if (E->isArray()) {
12650 ExprResult NewArraySize;
12651 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
12652 NewArraySize = getDerived().TransformExpr(*OldArraySize);
12653 if (NewArraySize.isInvalid())
12654 return ExprError();
12655 }
12656 ArraySize = NewArraySize.get();
12657 }
12658
12659 // Transform the placement arguments (if any).
12660 bool ArgumentChanged = false;
12661 SmallVector<Expr*, 8> PlacementArgs;
12662 if (getDerived().TransformExprs(E->getPlacementArgs(),
12663 E->getNumPlacementArgs(), true,
12664 PlacementArgs, &ArgumentChanged))
12665 return ExprError();
12666
12667 // Transform the initializer (if any).
12668 Expr *OldInit = E->getInitializer();
12669 ExprResult NewInit;
12670 if (OldInit)
12671 NewInit = getDerived().TransformInitializer(OldInit, true);
12672 if (NewInit.isInvalid())
12673 return ExprError();
12674
12675 // Transform new operator and delete operator.
12676 FunctionDecl *OperatorNew = nullptr;
12677 if (E->getOperatorNew()) {
12678 OperatorNew = cast_or_null<FunctionDecl>(
12679 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
12680 if (!OperatorNew)
12681 return ExprError();
12682 }
12683
12684 FunctionDecl *OperatorDelete = nullptr;
12685 if (E->getOperatorDelete()) {
12686 OperatorDelete = cast_or_null<FunctionDecl>(
12687 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12688 if (!OperatorDelete)
12689 return ExprError();
12690 }
12691
12692 if (!getDerived().AlwaysRebuild() &&
12693 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
12694 ArraySize == E->getArraySize() &&
12695 NewInit.get() == OldInit &&
12696 OperatorNew == E->getOperatorNew() &&
12697 OperatorDelete == E->getOperatorDelete() &&
12698 !ArgumentChanged) {
12699 // Mark any declarations we need as referenced.
12700 // FIXME: instantiation-specific.
12701 if (OperatorNew)
12702 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
12703 if (OperatorDelete)
12704 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
12705
12706 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
12707 QualType ElementType
12708 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
12709 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
12710 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
12711 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record)) {
12712 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
12713 }
12714 }
12715 }
12716
12717 return E;
12718 }
12719
12720 QualType AllocType = AllocTypeInfo->getType();
12721 if (!ArraySize) {
12722 // If no array size was specified, but the new expression was
12723 // instantiated with an array type (e.g., "new T" where T is
12724 // instantiated with "int[4]"), extract the outer bound from the
12725 // array type as our array size. We do this with constant and
12726 // dependently-sized array types.
12727 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
12728 if (!ArrayT) {
12729 // Do nothing
12730 } else if (const ConstantArrayType *ConsArrayT
12731 = dyn_cast<ConstantArrayType>(ArrayT)) {
12732 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
12733 type: SemaRef.Context.getSizeType(),
12734 /*FIXME:*/ l: E->getBeginLoc());
12735 AllocType = ConsArrayT->getElementType();
12736 } else if (const DependentSizedArrayType *DepArrayT
12737 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
12738 if (DepArrayT->getSizeExpr()) {
12739 ArraySize = DepArrayT->getSizeExpr();
12740 AllocType = DepArrayT->getElementType();
12741 }
12742 }
12743 }
12744
12745 return getDerived().RebuildCXXNewExpr(
12746 E->getBeginLoc(), E->isGlobalNew(),
12747 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
12748 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
12749 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
12750}
12751
12752template<typename Derived>
12753ExprResult
12754TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
12755 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
12756 if (Operand.isInvalid())
12757 return ExprError();
12758
12759 // Transform the delete operator, if known.
12760 FunctionDecl *OperatorDelete = nullptr;
12761 if (E->getOperatorDelete()) {
12762 OperatorDelete = cast_or_null<FunctionDecl>(
12763 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12764 if (!OperatorDelete)
12765 return ExprError();
12766 }
12767
12768 if (!getDerived().AlwaysRebuild() &&
12769 Operand.get() == E->getArgument() &&
12770 OperatorDelete == E->getOperatorDelete()) {
12771 // Mark any declarations we need as referenced.
12772 // FIXME: instantiation-specific.
12773 if (OperatorDelete)
12774 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
12775
12776 if (!E->getArgument()->isTypeDependent()) {
12777 QualType Destroyed = SemaRef.Context.getBaseElementType(
12778 QT: E->getDestroyedType());
12779 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
12780 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
12781 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
12782 SemaRef.LookupDestructor(Class: Record));
12783 }
12784 }
12785
12786 return E;
12787 }
12788
12789 return getDerived().RebuildCXXDeleteExpr(
12790 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
12791}
12792
12793template<typename Derived>
12794ExprResult
12795TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
12796 CXXPseudoDestructorExpr *E) {
12797 ExprResult Base = getDerived().TransformExpr(E->getBase());
12798 if (Base.isInvalid())
12799 return ExprError();
12800
12801 ParsedType ObjectTypePtr;
12802 bool MayBePseudoDestructor = false;
12803 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
12804 OpLoc: E->getOperatorLoc(),
12805 OpKind: E->isArrow()? tok::arrow : tok::period,
12806 ObjectType&: ObjectTypePtr,
12807 MayBePseudoDestructor);
12808 if (Base.isInvalid())
12809 return ExprError();
12810
12811 QualType ObjectType = ObjectTypePtr.get();
12812 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
12813 if (QualifierLoc) {
12814 QualifierLoc
12815 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
12816 if (!QualifierLoc)
12817 return ExprError();
12818 }
12819 CXXScopeSpec SS;
12820 SS.Adopt(Other: QualifierLoc);
12821
12822 PseudoDestructorTypeStorage Destroyed;
12823 if (E->getDestroyedTypeInfo()) {
12824 TypeSourceInfo *DestroyedTypeInfo
12825 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
12826 ObjectType, nullptr, SS);
12827 if (!DestroyedTypeInfo)
12828 return ExprError();
12829 Destroyed = DestroyedTypeInfo;
12830 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
12831 // We aren't likely to be able to resolve the identifier down to a type
12832 // now anyway, so just retain the identifier.
12833 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
12834 E->getDestroyedTypeLoc());
12835 } else {
12836 // Look for a destructor known with the given name.
12837 ParsedType T = SemaRef.getDestructorName(
12838 II&: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
12839 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
12840 if (!T)
12841 return ExprError();
12842
12843 Destroyed
12844 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
12845 Loc: E->getDestroyedTypeLoc());
12846 }
12847
12848 TypeSourceInfo *ScopeTypeInfo = nullptr;
12849 if (E->getScopeTypeInfo()) {
12850 CXXScopeSpec EmptySS;
12851 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
12852 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
12853 if (!ScopeTypeInfo)
12854 return ExprError();
12855 }
12856
12857 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
12858 E->getOperatorLoc(),
12859 E->isArrow(),
12860 SS,
12861 ScopeTypeInfo,
12862 E->getColonColonLoc(),
12863 E->getTildeLoc(),
12864 Destroyed);
12865}
12866
12867template <typename Derived>
12868bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
12869 bool RequiresADL,
12870 LookupResult &R) {
12871 // Transform all the decls.
12872 bool AllEmptyPacks = true;
12873 for (auto *OldD : Old->decls()) {
12874 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
12875 if (!InstD) {
12876 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
12877 // This can happen because of dependent hiding.
12878 if (isa<UsingShadowDecl>(OldD))
12879 continue;
12880 else {
12881 R.clear();
12882 return true;
12883 }
12884 }
12885
12886 // Expand using pack declarations.
12887 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
12888 ArrayRef<NamedDecl*> Decls = SingleDecl;
12889 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
12890 Decls = UPD->expansions();
12891
12892 // Expand using declarations.
12893 for (auto *D : Decls) {
12894 if (auto *UD = dyn_cast<UsingDecl>(D)) {
12895 for (auto *SD : UD->shadows())
12896 R.addDecl(SD);
12897 } else {
12898 R.addDecl(D);
12899 }
12900 }
12901
12902 AllEmptyPacks &= Decls.empty();
12903 };
12904
12905 // C++ [temp.res]/8.4.2:
12906 // The program is ill-formed, no diagnostic required, if [...] lookup for
12907 // a name in the template definition found a using-declaration, but the
12908 // lookup in the corresponding scope in the instantiation odoes not find
12909 // any declarations because the using-declaration was a pack expansion and
12910 // the corresponding pack is empty
12911 if (AllEmptyPacks && !RequiresADL) {
12912 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
12913 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
12914 return true;
12915 }
12916
12917 // Resolve a kind, but don't do any further analysis. If it's
12918 // ambiguous, the callee needs to deal with it.
12919 R.resolveKind();
12920 return false;
12921}
12922
12923template<typename Derived>
12924ExprResult
12925TreeTransform<Derived>::TransformUnresolvedLookupExpr(
12926 UnresolvedLookupExpr *Old) {
12927 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
12928 Sema::LookupOrdinaryName);
12929
12930 // Transform the declaration set.
12931 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
12932 return ExprError();
12933
12934 // Rebuild the nested-name qualifier, if present.
12935 CXXScopeSpec SS;
12936 if (Old->getQualifierLoc()) {
12937 NestedNameSpecifierLoc QualifierLoc
12938 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
12939 if (!QualifierLoc)
12940 return ExprError();
12941
12942 SS.Adopt(Other: QualifierLoc);
12943 }
12944
12945 if (Old->getNamingClass()) {
12946 CXXRecordDecl *NamingClass
12947 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
12948 Old->getNameLoc(),
12949 Old->getNamingClass()));
12950 if (!NamingClass) {
12951 R.clear();
12952 return ExprError();
12953 }
12954
12955 R.setNamingClass(NamingClass);
12956 }
12957
12958 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
12959
12960 // If we have neither explicit template arguments, nor the template keyword,
12961 // it's a normal declaration name or member reference.
12962 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) {
12963 NamedDecl *D = R.getAsSingle<NamedDecl>();
12964 // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an
12965 // instance member. In other contexts, BuildPossibleImplicitMemberExpr will
12966 // give a good diagnostic.
12967 if (D && D->isCXXInstanceMember()) {
12968 return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R,
12969 /*TemplateArgs=*/TemplateArgs: nullptr,
12970 /*Scope=*/S: nullptr);
12971 }
12972
12973 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
12974 }
12975
12976 // If we have template arguments, rebuild them, then rebuild the
12977 // templateid expression.
12978 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
12979 if (Old->hasExplicitTemplateArgs() &&
12980 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12981 Old->getNumTemplateArgs(),
12982 TransArgs)) {
12983 R.clear();
12984 return ExprError();
12985 }
12986
12987 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
12988 Old->requiresADL(), &TransArgs);
12989}
12990
12991template<typename Derived>
12992ExprResult
12993TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
12994 bool ArgChanged = false;
12995 SmallVector<TypeSourceInfo *, 4> Args;
12996 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
12997 TypeSourceInfo *From = E->getArg(I);
12998 TypeLoc FromTL = From->getTypeLoc();
12999 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
13000 TypeLocBuilder TLB;
13001 TLB.reserve(Requested: FromTL.getFullDataSize());
13002 QualType To = getDerived().TransformType(TLB, FromTL);
13003 if (To.isNull())
13004 return ExprError();
13005
13006 if (To == From->getType())
13007 Args.push_back(From);
13008 else {
13009 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13010 ArgChanged = true;
13011 }
13012 continue;
13013 }
13014
13015 ArgChanged = true;
13016
13017 // We have a pack expansion. Instantiate it.
13018 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
13019 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
13020 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13021 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
13022
13023 // Determine whether the set of unexpanded parameter packs can and should
13024 // be expanded.
13025 bool Expand = true;
13026 bool RetainExpansion = false;
13027 std::optional<unsigned> OrigNumExpansions =
13028 ExpansionTL.getTypePtr()->getNumExpansions();
13029 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13030 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
13031 PatternTL.getSourceRange(),
13032 Unexpanded,
13033 Expand, RetainExpansion,
13034 NumExpansions))
13035 return ExprError();
13036
13037 if (!Expand) {
13038 // The transform has determined that we should perform a simple
13039 // transformation on the pack expansion, producing another pack
13040 // expansion.
13041 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13042
13043 TypeLocBuilder TLB;
13044 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
13045
13046 QualType To = getDerived().TransformType(TLB, PatternTL);
13047 if (To.isNull())
13048 return ExprError();
13049
13050 To = getDerived().RebuildPackExpansionType(To,
13051 PatternTL.getSourceRange(),
13052 ExpansionTL.getEllipsisLoc(),
13053 NumExpansions);
13054 if (To.isNull())
13055 return ExprError();
13056
13057 PackExpansionTypeLoc ToExpansionTL
13058 = TLB.push<PackExpansionTypeLoc>(To);
13059 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13060 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13061 continue;
13062 }
13063
13064 // Expand the pack expansion by substituting for each argument in the
13065 // pack(s).
13066 for (unsigned I = 0; I != *NumExpansions; ++I) {
13067 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
13068 TypeLocBuilder TLB;
13069 TLB.reserve(Requested: PatternTL.getFullDataSize());
13070 QualType To = getDerived().TransformType(TLB, PatternTL);
13071 if (To.isNull())
13072 return ExprError();
13073
13074 if (To->containsUnexpandedParameterPack()) {
13075 To = getDerived().RebuildPackExpansionType(To,
13076 PatternTL.getSourceRange(),
13077 ExpansionTL.getEllipsisLoc(),
13078 NumExpansions);
13079 if (To.isNull())
13080 return ExprError();
13081
13082 PackExpansionTypeLoc ToExpansionTL
13083 = TLB.push<PackExpansionTypeLoc>(To);
13084 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13085 }
13086
13087 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13088 }
13089
13090 if (!RetainExpansion)
13091 continue;
13092
13093 // If we're supposed to retain a pack expansion, do so by temporarily
13094 // forgetting the partially-substituted parameter pack.
13095 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13096
13097 TypeLocBuilder TLB;
13098 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
13099
13100 QualType To = getDerived().TransformType(TLB, PatternTL);
13101 if (To.isNull())
13102 return ExprError();
13103
13104 To = getDerived().RebuildPackExpansionType(To,
13105 PatternTL.getSourceRange(),
13106 ExpansionTL.getEllipsisLoc(),
13107 NumExpansions);
13108 if (To.isNull())
13109 return ExprError();
13110
13111 PackExpansionTypeLoc ToExpansionTL
13112 = TLB.push<PackExpansionTypeLoc>(To);
13113 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13114 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
13115 }
13116
13117 if (!getDerived().AlwaysRebuild() && !ArgChanged)
13118 return E;
13119
13120 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
13121 E->getEndLoc());
13122}
13123
13124template<typename Derived>
13125ExprResult
13126TreeTransform<Derived>::TransformConceptSpecializationExpr(
13127 ConceptSpecializationExpr *E) {
13128 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
13129 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
13130 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13131 Old->NumTemplateArgs, TransArgs))
13132 return ExprError();
13133
13134 return getDerived().RebuildConceptSpecializationExpr(
13135 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
13136 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
13137 &TransArgs);
13138}
13139
13140template<typename Derived>
13141ExprResult
13142TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
13143 SmallVector<ParmVarDecl*, 4> TransParams;
13144 SmallVector<QualType, 4> TransParamTypes;
13145 Sema::ExtParameterInfoBuilder ExtParamInfos;
13146
13147 // C++2a [expr.prim.req]p2
13148 // Expressions appearing within a requirement-body are unevaluated operands.
13149 EnterExpressionEvaluationContext Ctx(
13150 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13151 Sema::ReuseLambdaContextDecl);
13152
13153 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
13154 C&: getSema().Context, DC: getSema().CurContext,
13155 StartLoc: E->getBody()->getBeginLoc());
13156
13157 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
13158
13159 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
13160 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
13161 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
13162
13163 for (ParmVarDecl *Param : TransParams)
13164 if (Param)
13165 Param->setDeclContext(Body);
13166
13167 // On failure to transform, TransformRequiresTypeParams returns an expression
13168 // in the event that the transformation of the type params failed in some way.
13169 // It is expected that this will result in a 'not satisfied' Requires clause
13170 // when instantiating.
13171 if (!TypeParamResult.isUnset())
13172 return TypeParamResult;
13173
13174 SmallVector<concepts::Requirement *, 4> TransReqs;
13175 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
13176 TransReqs))
13177 return ExprError();
13178
13179 for (concepts::Requirement *Req : TransReqs) {
13180 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
13181 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
13182 ER->getReturnTypeRequirement()
13183 .getTypeConstraintTemplateParameterList()->getParam(0)
13184 ->setDeclContext(Body);
13185 }
13186 }
13187 }
13188
13189 return getDerived().RebuildRequiresExpr(
13190 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
13191 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
13192}
13193
13194template<typename Derived>
13195bool TreeTransform<Derived>::TransformRequiresExprRequirements(
13196 ArrayRef<concepts::Requirement *> Reqs,
13197 SmallVectorImpl<concepts::Requirement *> &Transformed) {
13198 for (concepts::Requirement *Req : Reqs) {
13199 concepts::Requirement *TransReq = nullptr;
13200 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
13201 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13202 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
13203 TransReq = getDerived().TransformExprRequirement(ExprReq);
13204 else
13205 TransReq = getDerived().TransformNestedRequirement(
13206 cast<concepts::NestedRequirement>(Req));
13207 if (!TransReq)
13208 return true;
13209 Transformed.push_back(TransReq);
13210 }
13211 return false;
13212}
13213
13214template<typename Derived>
13215concepts::TypeRequirement *
13216TreeTransform<Derived>::TransformTypeRequirement(
13217 concepts::TypeRequirement *Req) {
13218 if (Req->isSubstitutionFailure()) {
13219 if (getDerived().AlwaysRebuild())
13220 return getDerived().RebuildTypeRequirement(
13221 Req->getSubstitutionDiagnostic());
13222 return Req;
13223 }
13224 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13225 if (!TransType)
13226 return nullptr;
13227 return getDerived().RebuildTypeRequirement(TransType);
13228}
13229
13230template<typename Derived>
13231concepts::ExprRequirement *
13232TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
13233 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13234 if (Req->isExprSubstitutionFailure())
13235 TransExpr = Req->getExprSubstitutionDiagnostic();
13236 else {
13237 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13238 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13239 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
13240 if (TransExprRes.isInvalid())
13241 return nullptr;
13242 TransExpr = TransExprRes.get();
13243 }
13244
13245 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13246 const auto &RetReq = Req->getReturnTypeRequirement();
13247 if (RetReq.isEmpty())
13248 TransRetReq.emplace();
13249 else if (RetReq.isSubstitutionFailure())
13250 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
13251 else if (RetReq.isTypeConstraint()) {
13252 TemplateParameterList *OrigTPL =
13253 RetReq.getTypeConstraintTemplateParameterList();
13254 TemplateParameterList *TPL =
13255 getDerived().TransformTemplateParameterList(OrigTPL);
13256 if (!TPL)
13257 return nullptr;
13258 TransRetReq.emplace(TPL);
13259 }
13260 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13261 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13262 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13263 Req->getNoexceptLoc(),
13264 std::move(*TransRetReq));
13265 return getDerived().RebuildExprRequirement(
13266 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
13267 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
13268}
13269
13270template<typename Derived>
13271concepts::NestedRequirement *
13272TreeTransform<Derived>::TransformNestedRequirement(
13273 concepts::NestedRequirement *Req) {
13274 if (Req->hasInvalidConstraint()) {
13275 if (getDerived().AlwaysRebuild())
13276 return getDerived().RebuildNestedRequirement(
13277 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
13278 return Req;
13279 }
13280 ExprResult TransConstraint =
13281 getDerived().TransformExpr(Req->getConstraintExpr());
13282 if (TransConstraint.isInvalid())
13283 return nullptr;
13284 return getDerived().RebuildNestedRequirement(TransConstraint.get());
13285}
13286
13287template<typename Derived>
13288ExprResult
13289TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
13290 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
13291 if (!T)
13292 return ExprError();
13293
13294 if (!getDerived().AlwaysRebuild() &&
13295 T == E->getQueriedTypeSourceInfo())
13296 return E;
13297
13298 ExprResult SubExpr;
13299 {
13300 EnterExpressionEvaluationContext Unevaluated(
13301 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13302 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
13303 if (SubExpr.isInvalid())
13304 return ExprError();
13305
13306 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
13307 return E;
13308 }
13309
13310 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
13311 SubExpr.get(), E->getEndLoc());
13312}
13313
13314template<typename Derived>
13315ExprResult
13316TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
13317 ExprResult SubExpr;
13318 {
13319 EnterExpressionEvaluationContext Unevaluated(
13320 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13321 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
13322 if (SubExpr.isInvalid())
13323 return ExprError();
13324
13325 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
13326 return E;
13327 }
13328
13329 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
13330 SubExpr.get(), E->getEndLoc());
13331}
13332
13333template <typename Derived>
13334ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
13335 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
13336 TypeSourceInfo **RecoveryTSI) {
13337 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
13338 DRE, AddrTaken, RecoveryTSI);
13339
13340 // Propagate both errors and recovered types, which return ExprEmpty.
13341 if (!NewDRE.isUsable())
13342 return NewDRE;
13343
13344 // We got an expr, wrap it up in parens.
13345 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
13346 return PE;
13347 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
13348 PE->getRParen());
13349}
13350
13351template <typename Derived>
13352ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13353 DependentScopeDeclRefExpr *E) {
13354 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/IsAddressOfOperand: false,
13355 RecoveryTSI: nullptr);
13356}
13357
13358template <typename Derived>
13359ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13360 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
13361 TypeSourceInfo **RecoveryTSI) {
13362 assert(E->getQualifierLoc());
13363 NestedNameSpecifierLoc QualifierLoc =
13364 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13365 if (!QualifierLoc)
13366 return ExprError();
13367 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13368
13369 // TODO: If this is a conversion-function-id, verify that the
13370 // destination type name (if present) resolves the same way after
13371 // instantiation as it did in the local scope.
13372
13373 DeclarationNameInfo NameInfo =
13374 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
13375 if (!NameInfo.getName())
13376 return ExprError();
13377
13378 if (!E->hasExplicitTemplateArgs()) {
13379 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
13380 // Note: it is sufficient to compare the Name component of NameInfo:
13381 // if name has not changed, DNLoc has not changed either.
13382 NameInfo.getName() == E->getDeclName())
13383 return E;
13384
13385 return getDerived().RebuildDependentScopeDeclRefExpr(
13386 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
13387 IsAddressOfOperand, RecoveryTSI);
13388 }
13389
13390 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13391 if (getDerived().TransformTemplateArguments(
13392 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13393 return ExprError();
13394
13395 return getDerived().RebuildDependentScopeDeclRefExpr(
13396 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13397 RecoveryTSI);
13398}
13399
13400template<typename Derived>
13401ExprResult
13402TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13403 // CXXConstructExprs other than for list-initialization and
13404 // CXXTemporaryObjectExpr are always implicit, so when we have
13405 // a 1-argument construction we just transform that argument.
13406 if (getDerived().AllowSkippingCXXConstructExpr() &&
13407 ((E->getNumArgs() == 1 ||
13408 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
13409 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
13410 !E->isListInitialization()))
13411 return getDerived().TransformInitializer(E->getArg(Arg: 0),
13412 /*DirectInit*/ false);
13413
13414 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13415
13416 QualType T = getDerived().TransformType(E->getType());
13417 if (T.isNull())
13418 return ExprError();
13419
13420 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13421 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13422 if (!Constructor)
13423 return ExprError();
13424
13425 bool ArgumentChanged = false;
13426 SmallVector<Expr*, 8> Args;
13427 {
13428 EnterExpressionEvaluationContext Context(
13429 getSema(), EnterExpressionEvaluationContext::InitList,
13430 E->isListInitialization());
13431 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13432 &ArgumentChanged))
13433 return ExprError();
13434 }
13435
13436 if (!getDerived().AlwaysRebuild() &&
13437 T == E->getType() &&
13438 Constructor == E->getConstructor() &&
13439 !ArgumentChanged) {
13440 // Mark the constructor as referenced.
13441 // FIXME: Instantiation-specific
13442 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13443 return E;
13444 }
13445
13446 return getDerived().RebuildCXXConstructExpr(
13447 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
13448 E->hadMultipleCandidates(), E->isListInitialization(),
13449 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
13450 E->getConstructionKind(), E->getParenOrBraceRange());
13451}
13452
13453template<typename Derived>
13454ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
13455 CXXInheritedCtorInitExpr *E) {
13456 QualType T = getDerived().TransformType(E->getType());
13457 if (T.isNull())
13458 return ExprError();
13459
13460 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13461 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13462 if (!Constructor)
13463 return ExprError();
13464
13465 if (!getDerived().AlwaysRebuild() &&
13466 T == E->getType() &&
13467 Constructor == E->getConstructor()) {
13468 // Mark the constructor as referenced.
13469 // FIXME: Instantiation-specific
13470 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13471 return E;
13472 }
13473
13474 return getDerived().RebuildCXXInheritedCtorInitExpr(
13475 T, E->getLocation(), Constructor,
13476 E->constructsVBase(), E->inheritedFromVBase());
13477}
13478
13479/// Transform a C++ temporary-binding expression.
13480///
13481/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
13482/// transform the subexpression and return that.
13483template<typename Derived>
13484ExprResult
13485TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
13486 if (auto *Dtor = E->getTemporary()->getDestructor())
13487 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13488 const_cast<CXXDestructorDecl *>(Dtor));
13489 return getDerived().TransformExpr(E->getSubExpr());
13490}
13491
13492/// Transform a C++ expression that contains cleanups that should
13493/// be run after the expression is evaluated.
13494///
13495/// Since ExprWithCleanups nodes are implicitly generated, we
13496/// just transform the subexpression and return that.
13497template<typename Derived>
13498ExprResult
13499TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
13500 return getDerived().TransformExpr(E->getSubExpr());
13501}
13502
13503template<typename Derived>
13504ExprResult
13505TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
13506 CXXTemporaryObjectExpr *E) {
13507 TypeSourceInfo *T =
13508 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13509 if (!T)
13510 return ExprError();
13511
13512 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13513 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13514 if (!Constructor)
13515 return ExprError();
13516
13517 bool ArgumentChanged = false;
13518 SmallVector<Expr*, 8> Args;
13519 Args.reserve(E->getNumArgs());
13520 {
13521 EnterExpressionEvaluationContext Context(
13522 getSema(), EnterExpressionEvaluationContext::InitList,
13523 E->isListInitialization());
13524 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
13525 ArgChanged: &ArgumentChanged))
13526 return ExprError();
13527 }
13528
13529 if (!getDerived().AlwaysRebuild() &&
13530 T == E->getTypeSourceInfo() &&
13531 Constructor == E->getConstructor() &&
13532 !ArgumentChanged) {
13533 // FIXME: Instantiation-specific
13534 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13535 return SemaRef.MaybeBindToTemporary(E);
13536 }
13537
13538 // FIXME: We should just pass E->isListInitialization(), but we're not
13539 // prepared to handle list-initialization without a child InitListExpr.
13540 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
13541 return getDerived().RebuildCXXTemporaryObjectExpr(
13542 T, LParenLoc, Args, E->getEndLoc(),
13543 /*ListInitialization=*/LParenLoc.isInvalid());
13544}
13545
13546template<typename Derived>
13547ExprResult
13548TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
13549 // Transform any init-capture expressions before entering the scope of the
13550 // lambda body, because they are not semantically within that scope.
13551 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
13552 struct TransformedInitCapture {
13553 // The location of the ... if the result is retaining a pack expansion.
13554 SourceLocation EllipsisLoc;
13555 // Zero or more expansions of the init-capture.
13556 SmallVector<InitCaptureInfoTy, 4> Expansions;
13557 };
13558 SmallVector<TransformedInitCapture, 4> InitCaptures;
13559 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
13560 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13561 CEnd = E->capture_end();
13562 C != CEnd; ++C) {
13563 if (!E->isInitCapture(Capture: C))
13564 continue;
13565
13566 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
13567 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13568
13569 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
13570 std::optional<unsigned> NumExpansions) {
13571 ExprResult NewExprInitResult = getDerived().TransformInitializer(
13572 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
13573
13574 if (NewExprInitResult.isInvalid()) {
13575 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
13576 return;
13577 }
13578 Expr *NewExprInit = NewExprInitResult.get();
13579
13580 QualType NewInitCaptureType =
13581 getSema().buildLambdaInitCaptureInitialization(
13582 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
13583 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
13584 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
13585 VarDecl::CInit,
13586 NewExprInit);
13587 Result.Expansions.push_back(
13588 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
13589 };
13590
13591 // If this is an init-capture pack, consider expanding the pack now.
13592 if (OldVD->isParameterPack()) {
13593 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
13594 ->getTypeLoc()
13595 .castAs<PackExpansionTypeLoc>();
13596 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13597 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
13598
13599 // Determine whether the set of unexpanded parameter packs can and should
13600 // be expanded.
13601 bool Expand = true;
13602 bool RetainExpansion = false;
13603 std::optional<unsigned> OrigNumExpansions =
13604 ExpansionTL.getTypePtr()->getNumExpansions();
13605 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13606 if (getDerived().TryExpandParameterPacks(
13607 ExpansionTL.getEllipsisLoc(),
13608 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
13609 RetainExpansion, NumExpansions))
13610 return ExprError();
13611 if (Expand) {
13612 for (unsigned I = 0; I != *NumExpansions; ++I) {
13613 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13614 SubstInitCapture(SourceLocation(), std::nullopt);
13615 }
13616 }
13617 if (!Expand || RetainExpansion) {
13618 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13619 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
13620 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
13621 }
13622 } else {
13623 SubstInitCapture(SourceLocation(), std::nullopt);
13624 }
13625 }
13626
13627 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
13628 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
13629
13630 // Create the local class that will describe the lambda.
13631
13632 // FIXME: DependencyKind below is wrong when substituting inside a templated
13633 // context that isn't a DeclContext (such as a variable template), or when
13634 // substituting an unevaluated lambda inside of a function's parameter's type
13635 // - as parameter types are not instantiated from within a function's DC. We
13636 // use evaluation contexts to distinguish the function parameter case.
13637 CXXRecordDecl::LambdaDependencyKind DependencyKind =
13638 CXXRecordDecl::LDK_Unknown;
13639 if ((getSema().isUnevaluatedContext() ||
13640 getSema().isConstantEvaluatedContext()) &&
13641 (getSema().CurContext->isFileContext() ||
13642 !getSema().CurContext->getParent()->isDependentContext()))
13643 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
13644
13645 CXXRecordDecl *OldClass = E->getLambdaClass();
13646 CXXRecordDecl *Class = getSema().createLambdaClosureType(
13647 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
13648 E->getCaptureDefault());
13649 getDerived().transformedLocalDecl(OldClass, {Class});
13650
13651 CXXMethodDecl *NewCallOperator =
13652 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
13653 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
13654
13655 // Enter the scope of the lambda.
13656 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
13657 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
13658 E->hasExplicitParameters(), E->isMutable());
13659
13660 // Introduce the context of the call operator.
13661 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
13662 /*NewThisContext*/false);
13663
13664 bool Invalid = false;
13665
13666 // Transform captures.
13667 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13668 CEnd = E->capture_end();
13669 C != CEnd; ++C) {
13670 // When we hit the first implicit capture, tell Sema that we've finished
13671 // the list of explicit captures.
13672 if (C->isImplicit())
13673 break;
13674
13675 // Capturing 'this' is trivial.
13676 if (C->capturesThis()) {
13677 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13678 /*BuildAndDiagnose*/ true, nullptr,
13679 C->getCaptureKind() == LCK_StarThis);
13680 continue;
13681 }
13682 // Captured expression will be recaptured during captured variables
13683 // rebuilding.
13684 if (C->capturesVLAType())
13685 continue;
13686
13687 // Rebuild init-captures, including the implied field declaration.
13688 if (E->isInitCapture(Capture: C)) {
13689 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
13690
13691 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13692 llvm::SmallVector<Decl*, 4> NewVDs;
13693
13694 for (InitCaptureInfoTy &Info : NewC.Expansions) {
13695 ExprResult Init = Info.first;
13696 QualType InitQualType = Info.second;
13697 if (Init.isInvalid() || InitQualType.isNull()) {
13698 Invalid = true;
13699 break;
13700 }
13701 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
13702 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
13703 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
13704 getSema().CurContext);
13705 if (!NewVD) {
13706 Invalid = true;
13707 break;
13708 }
13709 NewVDs.push_back(NewVD);
13710 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
13711 }
13712
13713 if (Invalid)
13714 break;
13715
13716 getDerived().transformedLocalDecl(OldVD, NewVDs);
13717 continue;
13718 }
13719
13720 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13721
13722 // Determine the capture kind for Sema.
13723 Sema::TryCaptureKind Kind
13724 = C->isImplicit()? Sema::TryCapture_Implicit
13725 : C->getCaptureKind() == LCK_ByCopy
13726 ? Sema::TryCapture_ExplicitByVal
13727 : Sema::TryCapture_ExplicitByRef;
13728 SourceLocation EllipsisLoc;
13729 if (C->isPackExpansion()) {
13730 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
13731 bool ShouldExpand = false;
13732 bool RetainExpansion = false;
13733 std::optional<unsigned> NumExpansions;
13734 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
13735 C->getLocation(),
13736 Unexpanded,
13737 ShouldExpand, RetainExpansion,
13738 NumExpansions)) {
13739 Invalid = true;
13740 continue;
13741 }
13742
13743 if (ShouldExpand) {
13744 // The transform has determined that we should perform an expansion;
13745 // transform and capture each of the arguments.
13746 // expansion of the pattern. Do so.
13747 auto *Pack = cast<VarDecl>(C->getCapturedVar());
13748 for (unsigned I = 0; I != *NumExpansions; ++I) {
13749 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13750 VarDecl *CapturedVar
13751 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
13752 Pack));
13753 if (!CapturedVar) {
13754 Invalid = true;
13755 continue;
13756 }
13757
13758 // Capture the transformed variable.
13759 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
13760 }
13761
13762 // FIXME: Retain a pack expansion if RetainExpansion is true.
13763
13764 continue;
13765 }
13766
13767 EllipsisLoc = C->getEllipsisLoc();
13768 }
13769
13770 // Transform the captured variable.
13771 auto *CapturedVar = cast_or_null<ValueDecl>(
13772 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13773 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
13774 Invalid = true;
13775 continue;
13776 }
13777
13778 // Capture the transformed variable.
13779 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
13780 EllipsisLoc);
13781 }
13782 getSema().finishLambdaExplicitCaptures(LSI);
13783
13784 // Transform the template parameters, and add them to the current
13785 // instantiation scope. The null case is handled correctly.
13786 auto TPL = getDerived().TransformTemplateParameterList(
13787 E->getTemplateParameterList());
13788 LSI->GLTemplateParameterList = TPL;
13789 if (TPL)
13790 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
13791 TPL);
13792
13793 // Transform the type of the original lambda's call operator.
13794 // The transformation MUST be done in the CurrentInstantiationScope since
13795 // it introduces a mapping of the original to the newly created
13796 // transformed parameters.
13797 TypeSourceInfo *NewCallOpTSI = nullptr;
13798 {
13799 auto OldCallOpTypeLoc =
13800 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
13801
13802 auto TransformFunctionProtoTypeLoc =
13803 [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
13804 SmallVector<QualType, 4> ExceptionStorage;
13805 return this->TransformFunctionProtoType(
13806 TLB, FPTL, nullptr, Qualifiers(),
13807 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13808 return TransformExceptionSpec(Loc: FPTL.getBeginLoc(), ESI,
13809 Exceptions&: ExceptionStorage, Changed);
13810 });
13811 };
13812
13813 QualType NewCallOpType;
13814 TypeLocBuilder NewCallOpTLBuilder;
13815
13816 if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
13817 NewCallOpType = this->TransformAttributedType(
13818 NewCallOpTLBuilder, ATL,
13819 [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
13820 return TransformFunctionProtoTypeLoc(
13821 TLB, TL.castAs<FunctionProtoTypeLoc>());
13822 });
13823 } else {
13824 auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
13825 NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
13826 }
13827
13828 if (NewCallOpType.isNull())
13829 return ExprError();
13830 NewCallOpTSI =
13831 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
13832 }
13833
13834 ArrayRef<ParmVarDecl *> Params;
13835 if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
13836 Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
13837 } else {
13838 auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
13839 Params = FPTL.getParams();
13840 }
13841
13842 getSema().CompleteLambdaCallOperator(
13843 NewCallOperator, E->getCallOperator()->getLocation(),
13844 E->getCallOperator()->getInnerLocStart(),
13845 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
13846 E->getCallOperator()->getConstexprKind(),
13847 E->getCallOperator()->getStorageClass(), Params,
13848 E->hasExplicitResultType());
13849
13850 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
13851 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
13852
13853 {
13854 // Number the lambda for linkage purposes if necessary.
13855 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
13856
13857 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
13858 if (getDerived().ReplacingOriginal()) {
13859 Numbering = OldClass->getLambdaNumbering();
13860 }
13861
13862 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
13863 }
13864
13865 // FIXME: Sema's lambda-building mechanism expects us to push an expression
13866 // evaluation context even if we're not transforming the function body.
13867 getSema().PushExpressionEvaluationContext(
13868 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
13869
13870 Sema::CodeSynthesisContext C;
13871 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
13872 C.PointOfInstantiation = E->getBody()->getBeginLoc();
13873 getSema().pushCodeSynthesisContext(C);
13874
13875 // Instantiate the body of the lambda expression.
13876 StmtResult Body =
13877 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
13878
13879 getSema().popCodeSynthesisContext();
13880
13881 // ActOnLambda* will pop the function scope for us.
13882 FuncScopeCleanup.disable();
13883
13884 if (Body.isInvalid()) {
13885 SavedContext.pop();
13886 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
13887 /*IsInstantiation=*/true);
13888 return ExprError();
13889 }
13890
13891 // Copy the LSI before ActOnFinishFunctionBody removes it.
13892 // FIXME: This is dumb. Store the lambda information somewhere that outlives
13893 // the call operator.
13894 auto LSICopy = *LSI;
13895 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
13896 /*IsInstantiation*/ true);
13897 SavedContext.pop();
13898
13899 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
13900 &LSICopy);
13901}
13902
13903template<typename Derived>
13904StmtResult
13905TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
13906 return TransformStmt(S);
13907}
13908
13909template<typename Derived>
13910StmtResult
13911TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
13912 // Transform captures.
13913 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13914 CEnd = E->capture_end();
13915 C != CEnd; ++C) {
13916 // When we hit the first implicit capture, tell Sema that we've finished
13917 // the list of explicit captures.
13918 if (!C->isImplicit())
13919 continue;
13920
13921 // Capturing 'this' is trivial.
13922 if (C->capturesThis()) {
13923 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13924 /*BuildAndDiagnose*/ true, nullptr,
13925 C->getCaptureKind() == LCK_StarThis);
13926 continue;
13927 }
13928 // Captured expression will be recaptured during captured variables
13929 // rebuilding.
13930 if (C->capturesVLAType())
13931 continue;
13932
13933 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13934 assert(!E->isInitCapture(C) && "implicit init-capture?");
13935
13936 // Transform the captured variable.
13937 VarDecl *CapturedVar = cast_or_null<VarDecl>(
13938 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13939 if (!CapturedVar || CapturedVar->isInvalidDecl())
13940 return StmtError();
13941
13942 // Capture the transformed variable.
13943 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
13944 }
13945
13946 return S;
13947}
13948
13949template<typename Derived>
13950ExprResult
13951TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
13952 CXXUnresolvedConstructExpr *E) {
13953 TypeSourceInfo *T =
13954 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13955 if (!T)
13956 return ExprError();
13957
13958 bool ArgumentChanged = false;
13959 SmallVector<Expr*, 8> Args;
13960 Args.reserve(E->getNumArgs());
13961 {
13962 EnterExpressionEvaluationContext Context(
13963 getSema(), EnterExpressionEvaluationContext::InitList,
13964 E->isListInitialization());
13965 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
13966 &ArgumentChanged))
13967 return ExprError();
13968 }
13969
13970 if (!getDerived().AlwaysRebuild() &&
13971 T == E->getTypeSourceInfo() &&
13972 !ArgumentChanged)
13973 return E;
13974
13975 // FIXME: we're faking the locations of the commas
13976 return getDerived().RebuildCXXUnresolvedConstructExpr(
13977 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
13978}
13979
13980template<typename Derived>
13981ExprResult
13982TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
13983 CXXDependentScopeMemberExpr *E) {
13984 // Transform the base of the expression.
13985 ExprResult Base((Expr*) nullptr);
13986 Expr *OldBase;
13987 QualType BaseType;
13988 QualType ObjectType;
13989 if (!E->isImplicitAccess()) {
13990 OldBase = E->getBase();
13991 Base = getDerived().TransformExpr(OldBase);
13992 if (Base.isInvalid())
13993 return ExprError();
13994
13995 // Start the member reference and compute the object's type.
13996 ParsedType ObjectTy;
13997 bool MayBePseudoDestructor = false;
13998 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
13999 OpLoc: E->getOperatorLoc(),
14000 OpKind: E->isArrow()? tok::arrow : tok::period,
14001 ObjectType&: ObjectTy,
14002 MayBePseudoDestructor);
14003 if (Base.isInvalid())
14004 return ExprError();
14005
14006 ObjectType = ObjectTy.get();
14007 BaseType = ((Expr*) Base.get())->getType();
14008 } else {
14009 OldBase = nullptr;
14010 BaseType = getDerived().TransformType(E->getBaseType());
14011 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
14012 }
14013
14014 // Transform the first part of the nested-name-specifier that qualifies
14015 // the member name.
14016 NamedDecl *FirstQualifierInScope
14017 = getDerived().TransformFirstQualifierInScope(
14018 E->getFirstQualifierFoundInScope(),
14019 E->getQualifierLoc().getBeginLoc());
14020
14021 NestedNameSpecifierLoc QualifierLoc;
14022 if (E->getQualifier()) {
14023 QualifierLoc
14024 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
14025 ObjectType,
14026 FirstQualifierInScope);
14027 if (!QualifierLoc)
14028 return ExprError();
14029 }
14030
14031 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14032
14033 // TODO: If this is a conversion-function-id, verify that the
14034 // destination type name (if present) resolves the same way after
14035 // instantiation as it did in the local scope.
14036
14037 DeclarationNameInfo NameInfo
14038 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
14039 if (!NameInfo.getName())
14040 return ExprError();
14041
14042 if (!E->hasExplicitTemplateArgs()) {
14043 // This is a reference to a member without an explicitly-specified
14044 // template argument list. Optimize for this common case.
14045 if (!getDerived().AlwaysRebuild() &&
14046 Base.get() == OldBase &&
14047 BaseType == E->getBaseType() &&
14048 QualifierLoc == E->getQualifierLoc() &&
14049 NameInfo.getName() == E->getMember() &&
14050 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
14051 return E;
14052
14053 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14054 BaseType,
14055 E->isArrow(),
14056 E->getOperatorLoc(),
14057 QualifierLoc,
14058 TemplateKWLoc,
14059 FirstQualifierInScope,
14060 NameInfo,
14061 /*TemplateArgs*/nullptr);
14062 }
14063
14064 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14065 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14066 E->getNumTemplateArgs(),
14067 TransArgs))
14068 return ExprError();
14069
14070 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14071 BaseType,
14072 E->isArrow(),
14073 E->getOperatorLoc(),
14074 QualifierLoc,
14075 TemplateKWLoc,
14076 FirstQualifierInScope,
14077 NameInfo,
14078 &TransArgs);
14079}
14080
14081template <typename Derived>
14082ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
14083 UnresolvedMemberExpr *Old) {
14084 // Transform the base of the expression.
14085 ExprResult Base((Expr *)nullptr);
14086 QualType BaseType;
14087 if (!Old->isImplicitAccess()) {
14088 Base = getDerived().TransformExpr(Old->getBase());
14089 if (Base.isInvalid())
14090 return ExprError();
14091 Base =
14092 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
14093 if (Base.isInvalid())
14094 return ExprError();
14095 BaseType = Base.get()->getType();
14096 } else {
14097 BaseType = getDerived().TransformType(Old->getBaseType());
14098 }
14099
14100 NestedNameSpecifierLoc QualifierLoc;
14101 if (Old->getQualifierLoc()) {
14102 QualifierLoc =
14103 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14104 if (!QualifierLoc)
14105 return ExprError();
14106 }
14107
14108 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14109
14110 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
14111
14112 // Transform the declaration set.
14113 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
14114 return ExprError();
14115
14116 // Determine the naming class.
14117 if (Old->getNamingClass()) {
14118 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
14119 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
14120 if (!NamingClass)
14121 return ExprError();
14122
14123 R.setNamingClass(NamingClass);
14124 }
14125
14126 TemplateArgumentListInfo TransArgs;
14127 if (Old->hasExplicitTemplateArgs()) {
14128 TransArgs.setLAngleLoc(Old->getLAngleLoc());
14129 TransArgs.setRAngleLoc(Old->getRAngleLoc());
14130 if (getDerived().TransformTemplateArguments(
14131 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
14132 return ExprError();
14133 }
14134
14135 // FIXME: to do this check properly, we will need to preserve the
14136 // first-qualifier-in-scope here, just in case we had a dependent
14137 // base (and therefore couldn't do the check) and a
14138 // nested-name-qualifier (and therefore could do the lookup).
14139 NamedDecl *FirstQualifierInScope = nullptr;
14140
14141 return getDerived().RebuildUnresolvedMemberExpr(
14142 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
14143 TemplateKWLoc, FirstQualifierInScope, R,
14144 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
14145}
14146
14147template<typename Derived>
14148ExprResult
14149TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
14150 EnterExpressionEvaluationContext Unevaluated(
14151 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14152 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
14153 if (SubExpr.isInvalid())
14154 return ExprError();
14155
14156 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
14157 return E;
14158
14159 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
14160}
14161
14162template<typename Derived>
14163ExprResult
14164TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
14165 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
14166 if (Pattern.isInvalid())
14167 return ExprError();
14168
14169 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
14170 return E;
14171
14172 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
14173 E->getNumExpansions());
14174}
14175
14176template<typename Derived>
14177ExprResult
14178TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
14179 // If E is not value-dependent, then nothing will change when we transform it.
14180 // Note: This is an instantiation-centric view.
14181 if (!E->isValueDependent())
14182 return E;
14183
14184 EnterExpressionEvaluationContext Unevaluated(
14185 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
14186
14187 ArrayRef<TemplateArgument> PackArgs;
14188 TemplateArgument ArgStorage;
14189
14190 // Find the argument list to transform.
14191 if (E->isPartiallySubstituted()) {
14192 PackArgs = E->getPartialArguments();
14193 } else if (E->isValueDependent()) {
14194 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
14195 bool ShouldExpand = false;
14196 bool RetainExpansion = false;
14197 std::optional<unsigned> NumExpansions;
14198 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
14199 Unexpanded,
14200 ShouldExpand, RetainExpansion,
14201 NumExpansions))
14202 return ExprError();
14203
14204 // If we need to expand the pack, build a template argument from it and
14205 // expand that.
14206 if (ShouldExpand) {
14207 auto *Pack = E->getPack();
14208 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
14209 ArgStorage = getSema().Context.getPackExpansionType(
14210 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
14211 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
14212 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
14213 } else {
14214 auto *VD = cast<ValueDecl>(Pack);
14215 ExprResult DRE = getSema().BuildDeclRefExpr(
14216 VD, VD->getType().getNonLValueExprType(getSema().Context),
14217 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
14218 E->getPackLoc());
14219 if (DRE.isInvalid())
14220 return ExprError();
14221 ArgStorage = new (getSema().Context)
14222 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
14223 E->getPackLoc(), std::nullopt);
14224 }
14225 PackArgs = ArgStorage;
14226 }
14227 }
14228
14229 // If we're not expanding the pack, just transform the decl.
14230 if (!PackArgs.size()) {
14231 auto *Pack = cast_or_null<NamedDecl>(
14232 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
14233 if (!Pack)
14234 return ExprError();
14235 return getDerived().RebuildSizeOfPackExpr(
14236 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
14237 std::nullopt, std::nullopt);
14238 }
14239
14240 // Try to compute the result without performing a partial substitution.
14241 std::optional<unsigned> Result = 0;
14242 for (const TemplateArgument &Arg : PackArgs) {
14243 if (!Arg.isPackExpansion()) {
14244 Result = *Result + 1;
14245 continue;
14246 }
14247
14248 TemplateArgumentLoc ArgLoc;
14249 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
14250
14251 // Find the pattern of the pack expansion.
14252 SourceLocation Ellipsis;
14253 std::optional<unsigned> OrigNumExpansions;
14254 TemplateArgumentLoc Pattern =
14255 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
14256 OrigNumExpansions);
14257
14258 // Substitute under the pack expansion. Do not expand the pack (yet).
14259 TemplateArgumentLoc OutPattern;
14260 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14261 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
14262 /*Uneval*/ true))
14263 return true;
14264
14265 // See if we can determine the number of arguments from the result.
14266 std::optional<unsigned> NumExpansions =
14267 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
14268 if (!NumExpansions) {
14269 // No: we must be in an alias template expansion, and we're going to need
14270 // to actually expand the packs.
14271 Result = std::nullopt;
14272 break;
14273 }
14274
14275 Result = *Result + *NumExpansions;
14276 }
14277
14278 // Common case: we could determine the number of expansions without
14279 // substituting.
14280 if (Result)
14281 return getDerived().RebuildSizeOfPackExpr(
14282 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14283 *Result, std::nullopt);
14284
14285 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
14286 E->getPackLoc());
14287 {
14288 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
14289 typedef TemplateArgumentLocInventIterator<
14290 Derived, const TemplateArgument*> PackLocIterator;
14291 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
14292 PackLocIterator(*this, PackArgs.end()),
14293 TransformedPackArgs, /*Uneval*/true))
14294 return ExprError();
14295 }
14296
14297 // Check whether we managed to fully-expand the pack.
14298 // FIXME: Is it possible for us to do so and not hit the early exit path?
14299 SmallVector<TemplateArgument, 8> Args;
14300 bool PartialSubstitution = false;
14301 for (auto &Loc : TransformedPackArgs.arguments()) {
14302 Args.push_back(Loc.getArgument());
14303 if (Loc.getArgument().isPackExpansion())
14304 PartialSubstitution = true;
14305 }
14306
14307 if (PartialSubstitution)
14308 return getDerived().RebuildSizeOfPackExpr(
14309 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14310 std::nullopt, Args);
14311
14312 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
14313 E->getPackLoc(), E->getRParenLoc(),
14314 Args.size(), std::nullopt);
14315}
14316
14317template <typename Derived>
14318ExprResult
14319TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
14320 if (!E->isValueDependent())
14321 return E;
14322
14323 // Transform the index
14324 ExprResult IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
14325 if (IndexExpr.isInvalid())
14326 return ExprError();
14327
14328 SmallVector<Expr *, 5> ExpandedExprs;
14329 if (E->getExpressions().empty()) {
14330 Expr *Pattern = E->getPackIdExpression();
14331 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14332 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
14333 Unexpanded);
14334 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14335
14336 // Determine whether the set of unexpanded parameter packs can and should
14337 // be expanded.
14338 bool ShouldExpand = true;
14339 bool RetainExpansion = false;
14340 std::optional<unsigned> OrigNumExpansions;
14341 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14342 if (getDerived().TryExpandParameterPacks(
14343 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
14344 ShouldExpand, RetainExpansion, NumExpansions))
14345 return true;
14346 if (!ShouldExpand) {
14347 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14348 ExprResult Pack = getDerived().TransformExpr(Pattern);
14349 if (Pack.isInvalid())
14350 return ExprError();
14351 return getDerived().RebuildPackIndexingExpr(
14352 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
14353 std::nullopt);
14354 }
14355 for (unsigned I = 0; I != *NumExpansions; ++I) {
14356 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14357 ExprResult Out = getDerived().TransformExpr(Pattern);
14358 if (Out.isInvalid())
14359 return true;
14360 if (Out.get()->containsUnexpandedParameterPack()) {
14361 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
14362 OrigNumExpansions);
14363 if (Out.isInvalid())
14364 return true;
14365 }
14366 ExpandedExprs.push_back(Out.get());
14367 }
14368 // If we're supposed to retain a pack expansion, do so by temporarily
14369 // forgetting the partially-substituted parameter pack.
14370 if (RetainExpansion) {
14371 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14372
14373 ExprResult Out = getDerived().TransformExpr(Pattern);
14374 if (Out.isInvalid())
14375 return true;
14376
14377 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
14378 OrigNumExpansions);
14379 if (Out.isInvalid())
14380 return true;
14381 ExpandedExprs.push_back(Out.get());
14382 }
14383 }
14384
14385 else {
14386 if (getDerived().TransformExprs(E->getExpressions().data(),
14387 E->getExpressions().size(), false,
14388 ExpandedExprs))
14389 return ExprError();
14390 }
14391
14392 return getDerived().RebuildPackIndexingExpr(
14393 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
14394 IndexExpr.get(), ExpandedExprs,
14395 /*EmptyPack=*/ExpandedExprs.size() == 0);
14396}
14397
14398template<typename Derived>
14399ExprResult
14400TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
14401 SubstNonTypeTemplateParmPackExpr *E) {
14402 // Default behavior is to do nothing with this transformation.
14403 return E;
14404}
14405
14406template<typename Derived>
14407ExprResult
14408TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
14409 SubstNonTypeTemplateParmExpr *E) {
14410 // Default behavior is to do nothing with this transformation.
14411 return E;
14412}
14413
14414template<typename Derived>
14415ExprResult
14416TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
14417 // Default behavior is to do nothing with this transformation.
14418 return E;
14419}
14420
14421template<typename Derived>
14422ExprResult
14423TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
14424 MaterializeTemporaryExpr *E) {
14425 return getDerived().TransformExpr(E->getSubExpr());
14426}
14427
14428template<typename Derived>
14429ExprResult
14430TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
14431 UnresolvedLookupExpr *Callee = nullptr;
14432 if (Expr *OldCallee = E->getCallee()) {
14433 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
14434 if (CalleeResult.isInvalid())
14435 return ExprError();
14436 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
14437 }
14438
14439 Expr *Pattern = E->getPattern();
14440
14441 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14442 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
14443 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14444
14445 // Determine whether the set of unexpanded parameter packs can and should
14446 // be expanded.
14447 bool Expand = true;
14448 bool RetainExpansion = false;
14449 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
14450 NumExpansions = OrigNumExpansions;
14451 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
14452 Pattern->getSourceRange(),
14453 Unexpanded,
14454 Expand, RetainExpansion,
14455 NumExpansions))
14456 return true;
14457
14458 if (!Expand) {
14459 // Do not expand any packs here, just transform and rebuild a fold
14460 // expression.
14461 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14462
14463 ExprResult LHS =
14464 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
14465 if (LHS.isInvalid())
14466 return true;
14467
14468 ExprResult RHS =
14469 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
14470 if (RHS.isInvalid())
14471 return true;
14472
14473 if (!getDerived().AlwaysRebuild() &&
14474 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
14475 return E;
14476
14477 return getDerived().RebuildCXXFoldExpr(
14478 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
14479 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
14480 }
14481
14482 // Formally a fold expression expands to nested parenthesized expressions.
14483 // Enforce this limit to avoid creating trees so deep we can't safely traverse
14484 // them.
14485 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
14486 SemaRef.Diag(E->getEllipsisLoc(),
14487 clang::diag::err_fold_expression_limit_exceeded)
14488 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
14489 << E->getSourceRange();
14490 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
14491 return ExprError();
14492 }
14493
14494 // The transform has determined that we should perform an elementwise
14495 // expansion of the pattern. Do so.
14496 ExprResult Result = getDerived().TransformExpr(E->getInit());
14497 if (Result.isInvalid())
14498 return true;
14499 bool LeftFold = E->isLeftFold();
14500
14501 // If we're retaining an expansion for a right fold, it is the innermost
14502 // component and takes the init (if any).
14503 if (!LeftFold && RetainExpansion) {
14504 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14505
14506 ExprResult Out = getDerived().TransformExpr(Pattern);
14507 if (Out.isInvalid())
14508 return true;
14509
14510 Result = getDerived().RebuildCXXFoldExpr(
14511 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
14512 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
14513 if (Result.isInvalid())
14514 return true;
14515 }
14516
14517 for (unsigned I = 0; I != *NumExpansions; ++I) {
14518 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
14519 getSema(), LeftFold ? I : *NumExpansions - I - 1);
14520 ExprResult Out = getDerived().TransformExpr(Pattern);
14521 if (Out.isInvalid())
14522 return true;
14523
14524 if (Out.get()->containsUnexpandedParameterPack()) {
14525 // We still have a pack; retain a pack expansion for this slice.
14526 Result = getDerived().RebuildCXXFoldExpr(
14527 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
14528 E->getOperator(), E->getEllipsisLoc(),
14529 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
14530 OrigNumExpansions);
14531 } else if (Result.isUsable()) {
14532 // We've got down to a single element; build a binary operator.
14533 Expr *LHS = LeftFold ? Result.get() : Out.get();
14534 Expr *RHS = LeftFold ? Out.get() : Result.get();
14535 if (Callee) {
14536 UnresolvedSet<16> Functions;
14537 Functions.append(Callee->decls_begin(), Callee->decls_end());
14538 Result = getDerived().RebuildCXXOperatorCallExpr(
14539 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
14540 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
14541 Functions, LHS, RHS);
14542 } else {
14543 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
14544 E->getOperator(), LHS, RHS);
14545 }
14546 } else
14547 Result = Out;
14548
14549 if (Result.isInvalid())
14550 return true;
14551 }
14552
14553 // If we're retaining an expansion for a left fold, it is the outermost
14554 // component and takes the complete expansion so far as its init (if any).
14555 if (LeftFold && RetainExpansion) {
14556 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14557
14558 ExprResult Out = getDerived().TransformExpr(Pattern);
14559 if (Out.isInvalid())
14560 return true;
14561
14562 Result = getDerived().RebuildCXXFoldExpr(
14563 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
14564 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
14565 if (Result.isInvalid())
14566 return true;
14567 }
14568
14569 // If we had no init and an empty pack, and we're not retaining an expansion,
14570 // then produce a fallback value or error.
14571 if (Result.isUnset())
14572 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
14573 E->getOperator());
14574
14575 return Result;
14576}
14577
14578template <typename Derived>
14579ExprResult
14580TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
14581 SmallVector<Expr *, 4> TransformedInits;
14582 ArrayRef<Expr *> InitExprs = E->getInitExprs();
14583 if (TransformExprs(Inputs: InitExprs.data(), NumInputs: InitExprs.size(), IsCall: true,
14584 Outputs&: TransformedInits))
14585 return ExprError();
14586
14587 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
14588 E->getEndLoc());
14589}
14590
14591template<typename Derived>
14592ExprResult
14593TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
14594 CXXStdInitializerListExpr *E) {
14595 return getDerived().TransformExpr(E->getSubExpr());
14596}
14597
14598template<typename Derived>
14599ExprResult
14600TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
14601 return SemaRef.MaybeBindToTemporary(E);
14602}
14603
14604template<typename Derived>
14605ExprResult
14606TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
14607 return E;
14608}
14609
14610template<typename Derived>
14611ExprResult
14612TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
14613 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14614 if (SubExpr.isInvalid())
14615 return ExprError();
14616
14617 if (!getDerived().AlwaysRebuild() &&
14618 SubExpr.get() == E->getSubExpr())
14619 return E;
14620
14621 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
14622}
14623
14624template<typename Derived>
14625ExprResult
14626TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
14627 // Transform each of the elements.
14628 SmallVector<Expr *, 8> Elements;
14629 bool ArgChanged = false;
14630 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
14631 /*IsCall=*/false, Elements, &ArgChanged))
14632 return ExprError();
14633
14634 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14635 return SemaRef.MaybeBindToTemporary(E);
14636
14637 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
14638 Elements.data(),
14639 Elements.size());
14640}
14641
14642template<typename Derived>
14643ExprResult
14644TreeTransform<Derived>::TransformObjCDictionaryLiteral(
14645 ObjCDictionaryLiteral *E) {
14646 // Transform each of the elements.
14647 SmallVector<ObjCDictionaryElement, 8> Elements;
14648 bool ArgChanged = false;
14649 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
14650 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
14651
14652 if (OrigElement.isPackExpansion()) {
14653 // This key/value element is a pack expansion.
14654 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14655 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
14656 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
14657 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14658
14659 // Determine whether the set of unexpanded parameter packs can
14660 // and should be expanded.
14661 bool Expand = true;
14662 bool RetainExpansion = false;
14663 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
14664 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14665 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
14666 OrigElement.Value->getEndLoc());
14667 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
14668 PatternRange, Unexpanded, Expand,
14669 RetainExpansion, NumExpansions))
14670 return ExprError();
14671
14672 if (!Expand) {
14673 // The transform has determined that we should perform a simple
14674 // transformation on the pack expansion, producing another pack
14675 // expansion.
14676 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14677 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14678 if (Key.isInvalid())
14679 return ExprError();
14680
14681 if (Key.get() != OrigElement.Key)
14682 ArgChanged = true;
14683
14684 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14685 if (Value.isInvalid())
14686 return ExprError();
14687
14688 if (Value.get() != OrigElement.Value)
14689 ArgChanged = true;
14690
14691 ObjCDictionaryElement Expansion = {
14692 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
14693 };
14694 Elements.push_back(Expansion);
14695 continue;
14696 }
14697
14698 // Record right away that the argument was changed. This needs
14699 // to happen even if the array expands to nothing.
14700 ArgChanged = true;
14701
14702 // The transform has determined that we should perform an elementwise
14703 // expansion of the pattern. Do so.
14704 for (unsigned I = 0; I != *NumExpansions; ++I) {
14705 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14706 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14707 if (Key.isInvalid())
14708 return ExprError();
14709
14710 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14711 if (Value.isInvalid())
14712 return ExprError();
14713
14714 ObjCDictionaryElement Element = {
14715 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
14716 };
14717
14718 // If any unexpanded parameter packs remain, we still have a
14719 // pack expansion.
14720 // FIXME: Can this really happen?
14721 if (Key.get()->containsUnexpandedParameterPack() ||
14722 Value.get()->containsUnexpandedParameterPack())
14723 Element.EllipsisLoc = OrigElement.EllipsisLoc;
14724
14725 Elements.push_back(Element);
14726 }
14727
14728 // FIXME: Retain a pack expansion if RetainExpansion is true.
14729
14730 // We've finished with this pack expansion.
14731 continue;
14732 }
14733
14734 // Transform and check key.
14735 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14736 if (Key.isInvalid())
14737 return ExprError();
14738
14739 if (Key.get() != OrigElement.Key)
14740 ArgChanged = true;
14741
14742 // Transform and check value.
14743 ExprResult Value
14744 = getDerived().TransformExpr(OrigElement.Value);
14745 if (Value.isInvalid())
14746 return ExprError();
14747
14748 if (Value.get() != OrigElement.Value)
14749 ArgChanged = true;
14750
14751 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
14752 .NumExpansions: std::nullopt};
14753 Elements.push_back(Element);
14754 }
14755
14756 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14757 return SemaRef.MaybeBindToTemporary(E);
14758
14759 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
14760 Elements);
14761}
14762
14763template<typename Derived>
14764ExprResult
14765TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
14766 TypeSourceInfo *EncodedTypeInfo
14767 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
14768 if (!EncodedTypeInfo)
14769 return ExprError();
14770
14771 if (!getDerived().AlwaysRebuild() &&
14772 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
14773 return E;
14774
14775 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
14776 EncodedTypeInfo,
14777 E->getRParenLoc());
14778}
14779
14780template<typename Derived>
14781ExprResult TreeTransform<Derived>::
14782TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
14783 // This is a kind of implicit conversion, and it needs to get dropped
14784 // and recomputed for the same general reasons that ImplicitCastExprs
14785 // do, as well a more specific one: this expression is only valid when
14786 // it appears *immediately* as an argument expression.
14787 return getDerived().TransformExpr(E->getSubExpr());
14788}
14789
14790template<typename Derived>
14791ExprResult TreeTransform<Derived>::
14792TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
14793 TypeSourceInfo *TSInfo
14794 = getDerived().TransformType(E->getTypeInfoAsWritten());
14795 if (!TSInfo)
14796 return ExprError();
14797
14798 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
14799 if (Result.isInvalid())
14800 return ExprError();
14801
14802 if (!getDerived().AlwaysRebuild() &&
14803 TSInfo == E->getTypeInfoAsWritten() &&
14804 Result.get() == E->getSubExpr())
14805 return E;
14806
14807 return SemaRef.BuildObjCBridgedCast(LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(),
14808 BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
14809 SubExpr: Result.get());
14810}
14811
14812template <typename Derived>
14813ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
14814 ObjCAvailabilityCheckExpr *E) {
14815 return E;
14816}
14817
14818template<typename Derived>
14819ExprResult
14820TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
14821 // Transform arguments.
14822 bool ArgChanged = false;
14823 SmallVector<Expr*, 8> Args;
14824 Args.reserve(E->getNumArgs());
14825 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
14826 &ArgChanged))
14827 return ExprError();
14828
14829 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
14830 // Class message: transform the receiver type.
14831 TypeSourceInfo *ReceiverTypeInfo
14832 = getDerived().TransformType(E->getClassReceiverTypeInfo());
14833 if (!ReceiverTypeInfo)
14834 return ExprError();
14835
14836 // If nothing changed, just retain the existing message send.
14837 if (!getDerived().AlwaysRebuild() &&
14838 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
14839 return SemaRef.MaybeBindToTemporary(E);
14840
14841 // Build a new class message send.
14842 SmallVector<SourceLocation, 16> SelLocs;
14843 E->getSelectorLocs(SelLocs&: SelLocs);
14844 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
14845 E->getSelector(),
14846 SelLocs,
14847 E->getMethodDecl(),
14848 E->getLeftLoc(),
14849 Args,
14850 E->getRightLoc());
14851 }
14852 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
14853 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
14854 if (!E->getMethodDecl())
14855 return ExprError();
14856
14857 // Build a new class message send to 'super'.
14858 SmallVector<SourceLocation, 16> SelLocs;
14859 E->getSelectorLocs(SelLocs&: SelLocs);
14860 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
14861 E->getSelector(),
14862 SelLocs,
14863 E->getReceiverType(),
14864 E->getMethodDecl(),
14865 E->getLeftLoc(),
14866 Args,
14867 E->getRightLoc());
14868 }
14869
14870 // Instance message: transform the receiver
14871 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
14872 "Only class and instance messages may be instantiated");
14873 ExprResult Receiver
14874 = getDerived().TransformExpr(E->getInstanceReceiver());
14875 if (Receiver.isInvalid())
14876 return ExprError();
14877
14878 // If nothing changed, just retain the existing message send.
14879 if (!getDerived().AlwaysRebuild() &&
14880 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
14881 return SemaRef.MaybeBindToTemporary(E);
14882
14883 // Build a new instance message send.
14884 SmallVector<SourceLocation, 16> SelLocs;
14885 E->getSelectorLocs(SelLocs&: SelLocs);
14886 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
14887 E->getSelector(),
14888 SelLocs,
14889 E->getMethodDecl(),
14890 E->getLeftLoc(),
14891 Args,
14892 E->getRightLoc());
14893}
14894
14895template<typename Derived>
14896ExprResult
14897TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
14898 return E;
14899}
14900
14901template<typename Derived>
14902ExprResult
14903TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
14904 return E;
14905}
14906
14907template<typename Derived>
14908ExprResult
14909TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
14910 // Transform the base expression.
14911 ExprResult Base = getDerived().TransformExpr(E->getBase());
14912 if (Base.isInvalid())
14913 return ExprError();
14914
14915 // We don't need to transform the ivar; it will never change.
14916
14917 // If nothing changed, just retain the existing expression.
14918 if (!getDerived().AlwaysRebuild() &&
14919 Base.get() == E->getBase())
14920 return E;
14921
14922 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
14923 E->getLocation(),
14924 E->isArrow(), E->isFreeIvar());
14925}
14926
14927template<typename Derived>
14928ExprResult
14929TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
14930 // 'super' and types never change. Property never changes. Just
14931 // retain the existing expression.
14932 if (!E->isObjectReceiver())
14933 return E;
14934
14935 // Transform the base expression.
14936 ExprResult Base = getDerived().TransformExpr(E->getBase());
14937 if (Base.isInvalid())
14938 return ExprError();
14939
14940 // We don't need to transform the property; it will never change.
14941
14942 // If nothing changed, just retain the existing expression.
14943 if (!getDerived().AlwaysRebuild() &&
14944 Base.get() == E->getBase())
14945 return E;
14946
14947 if (E->isExplicitProperty())
14948 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14949 E->getExplicitProperty(),
14950 E->getLocation());
14951
14952 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14953 SemaRef.Context.PseudoObjectTy,
14954 E->getImplicitPropertyGetter(),
14955 E->getImplicitPropertySetter(),
14956 E->getLocation());
14957}
14958
14959template<typename Derived>
14960ExprResult
14961TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
14962 // Transform the base expression.
14963 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
14964 if (Base.isInvalid())
14965 return ExprError();
14966
14967 // Transform the key expression.
14968 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
14969 if (Key.isInvalid())
14970 return ExprError();
14971
14972 // If nothing changed, just retain the existing expression.
14973 if (!getDerived().AlwaysRebuild() &&
14974 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
14975 return E;
14976
14977 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
14978 Base.get(), Key.get(),
14979 E->getAtIndexMethodDecl(),
14980 E->setAtIndexMethodDecl());
14981}
14982
14983template<typename Derived>
14984ExprResult
14985TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
14986 // Transform the base expression.
14987 ExprResult Base = getDerived().TransformExpr(E->getBase());
14988 if (Base.isInvalid())
14989 return ExprError();
14990
14991 // If nothing changed, just retain the existing expression.
14992 if (!getDerived().AlwaysRebuild() &&
14993 Base.get() == E->getBase())
14994 return E;
14995
14996 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
14997 E->getOpLoc(),
14998 E->isArrow());
14999}
15000
15001template<typename Derived>
15002ExprResult
15003TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
15004 bool ArgumentChanged = false;
15005 SmallVector<Expr*, 8> SubExprs;
15006 SubExprs.reserve(E->getNumSubExprs());
15007 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15008 SubExprs, &ArgumentChanged))
15009 return ExprError();
15010
15011 if (!getDerived().AlwaysRebuild() &&
15012 !ArgumentChanged)
15013 return E;
15014
15015 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
15016 SubExprs,
15017 E->getRParenLoc());
15018}
15019
15020template<typename Derived>
15021ExprResult
15022TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
15023 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15024 if (SrcExpr.isInvalid())
15025 return ExprError();
15026
15027 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
15028 if (!Type)
15029 return ExprError();
15030
15031 if (!getDerived().AlwaysRebuild() &&
15032 Type == E->getTypeSourceInfo() &&
15033 SrcExpr.get() == E->getSrcExpr())
15034 return E;
15035
15036 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
15037 SrcExpr.get(), Type,
15038 E->getRParenLoc());
15039}
15040
15041template<typename Derived>
15042ExprResult
15043TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
15044 BlockDecl *oldBlock = E->getBlockDecl();
15045
15046 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
15047 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
15048
15049 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
15050 blockScope->TheDecl->setBlockMissingReturnType(
15051 oldBlock->blockMissingReturnType());
15052
15053 SmallVector<ParmVarDecl*, 4> params;
15054 SmallVector<QualType, 4> paramTypes;
15055
15056 const FunctionProtoType *exprFunctionType = E->getFunctionType();
15057
15058 // Parameter substitution.
15059 Sema::ExtParameterInfoBuilder extParamInfos;
15060 if (getDerived().TransformFunctionTypeParams(
15061 E->getCaretLocation(), oldBlock->parameters(), nullptr,
15062 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
15063 extParamInfos)) {
15064 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15065 return ExprError();
15066 }
15067
15068 QualType exprResultType =
15069 getDerived().TransformType(exprFunctionType->getReturnType());
15070
15071 auto epi = exprFunctionType->getExtProtoInfo();
15072 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
15073
15074 QualType functionType =
15075 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
15076 blockScope->FunctionType = functionType;
15077
15078 // Set the parameters on the block decl.
15079 if (!params.empty())
15080 blockScope->TheDecl->setParams(params);
15081
15082 if (!oldBlock->blockMissingReturnType()) {
15083 blockScope->HasImplicitReturnType = false;
15084 blockScope->ReturnType = exprResultType;
15085 }
15086
15087 // Transform the body
15088 StmtResult body = getDerived().TransformStmt(E->getBody());
15089 if (body.isInvalid()) {
15090 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15091 return ExprError();
15092 }
15093
15094#ifndef NDEBUG
15095 // In builds with assertions, make sure that we captured everything we
15096 // captured before.
15097 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
15098 for (const auto &I : oldBlock->captures()) {
15099 VarDecl *oldCapture = I.getVariable();
15100
15101 // Ignore parameter packs.
15102 if (oldCapture->isParameterPack())
15103 continue;
15104
15105 VarDecl *newCapture =
15106 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
15107 oldCapture));
15108 assert(blockScope->CaptureMap.count(newCapture));
15109 }
15110
15111 // The this pointer may not be captured by the instantiated block, even when
15112 // it's captured by the original block, if the expression causing the
15113 // capture is in the discarded branch of a constexpr if statement.
15114 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
15115 "this pointer isn't captured in the old block");
15116 }
15117#endif
15118
15119 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
15120 /*Scope=*/CurScope: nullptr);
15121}
15122
15123template<typename Derived>
15124ExprResult
15125TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
15126 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15127 if (SrcExpr.isInvalid())
15128 return ExprError();
15129
15130 QualType Type = getDerived().TransformType(E->getType());
15131
15132 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
15133 RParenLoc: E->getRParenLoc());
15134}
15135
15136template<typename Derived>
15137ExprResult
15138TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
15139 bool ArgumentChanged = false;
15140 SmallVector<Expr*, 8> SubExprs;
15141 SubExprs.reserve(E->getNumSubExprs());
15142 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15143 SubExprs, &ArgumentChanged))
15144 return ExprError();
15145
15146 if (!getDerived().AlwaysRebuild() &&
15147 !ArgumentChanged)
15148 return E;
15149
15150 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
15151 E->getOp(), E->getRParenLoc());
15152}
15153
15154//===----------------------------------------------------------------------===//
15155// Type reconstruction
15156//===----------------------------------------------------------------------===//
15157
15158template<typename Derived>
15159QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
15160 SourceLocation Star) {
15161 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
15162 Entity: getDerived().getBaseEntity());
15163}
15164
15165template<typename Derived>
15166QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
15167 SourceLocation Star) {
15168 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
15169 Entity: getDerived().getBaseEntity());
15170}
15171
15172template<typename Derived>
15173QualType
15174TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
15175 bool WrittenAsLValue,
15176 SourceLocation Sigil) {
15177 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
15178 Loc: Sigil, Entity: getDerived().getBaseEntity());
15179}
15180
15181template<typename Derived>
15182QualType
15183TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
15184 QualType ClassType,
15185 SourceLocation Sigil) {
15186 return SemaRef.BuildMemberPointerType(T: PointeeType, Class: ClassType, Loc: Sigil,
15187 Entity: getDerived().getBaseEntity());
15188}
15189
15190template<typename Derived>
15191QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
15192 const ObjCTypeParamDecl *Decl,
15193 SourceLocation ProtocolLAngleLoc,
15194 ArrayRef<ObjCProtocolDecl *> Protocols,
15195 ArrayRef<SourceLocation> ProtocolLocs,
15196 SourceLocation ProtocolRAngleLoc) {
15197 return SemaRef.BuildObjCTypeParamType(Decl,
15198 ProtocolLAngleLoc, Protocols: Protocols,
15199 ProtocolLocs, ProtocolRAngleLoc,
15200 /*FailOnError=*/FailOnError: true);
15201}
15202
15203template<typename Derived>
15204QualType TreeTransform<Derived>::RebuildObjCObjectType(
15205 QualType BaseType,
15206 SourceLocation Loc,
15207 SourceLocation TypeArgsLAngleLoc,
15208 ArrayRef<TypeSourceInfo *> TypeArgs,
15209 SourceLocation TypeArgsRAngleLoc,
15210 SourceLocation ProtocolLAngleLoc,
15211 ArrayRef<ObjCProtocolDecl *> Protocols,
15212 ArrayRef<SourceLocation> ProtocolLocs,
15213 SourceLocation ProtocolRAngleLoc) {
15214 return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs: TypeArgs,
15215 TypeArgsRAngleLoc, ProtocolLAngleLoc,
15216 Protocols: Protocols, ProtocolLocs, ProtocolRAngleLoc,
15217 /*FailOnError=*/FailOnError: true,
15218 /*Rebuilding=*/Rebuilding: true);
15219}
15220
15221template<typename Derived>
15222QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
15223 QualType PointeeType,
15224 SourceLocation Star) {
15225 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
15226}
15227
15228template <typename Derived>
15229QualType TreeTransform<Derived>::RebuildArrayType(
15230 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
15231 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
15232 if (SizeExpr || !Size)
15233 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
15234 Quals: IndexTypeQuals, Brackets: BracketsRange,
15235 Entity: getDerived().getBaseEntity());
15236
15237 QualType Types[] = {
15238 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
15239 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
15240 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
15241 };
15242 QualType SizeType;
15243 for (const auto &T : Types)
15244 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
15245 SizeType = T;
15246 break;
15247 }
15248
15249 // Note that we can return a VariableArrayType here in the case where
15250 // the element type was a dependent VariableArrayType.
15251 IntegerLiteral *ArraySize
15252 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
15253 /*FIXME*/l: BracketsRange.getBegin());
15254 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
15255 Quals: IndexTypeQuals, Brackets: BracketsRange,
15256 Entity: getDerived().getBaseEntity());
15257}
15258
15259template <typename Derived>
15260QualType TreeTransform<Derived>::RebuildConstantArrayType(
15261 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
15262 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
15263 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
15264 IndexTypeQuals, BracketsRange);
15265}
15266
15267template <typename Derived>
15268QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
15269 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
15270 SourceRange BracketsRange) {
15271 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
15272 IndexTypeQuals, BracketsRange);
15273}
15274
15275template <typename Derived>
15276QualType TreeTransform<Derived>::RebuildVariableArrayType(
15277 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
15278 unsigned IndexTypeQuals, SourceRange BracketsRange) {
15279 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
15280 SizeExpr,
15281 IndexTypeQuals, BracketsRange);
15282}
15283
15284template <typename Derived>
15285QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
15286 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
15287 unsigned IndexTypeQuals, SourceRange BracketsRange) {
15288 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
15289 SizeExpr,
15290 IndexTypeQuals, BracketsRange);
15291}
15292
15293template <typename Derived>
15294QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
15295 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
15296 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
15297 AttrLoc: AttributeLoc);
15298}
15299
15300template <typename Derived>
15301QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
15302 unsigned NumElements,
15303 VectorKind VecKind) {
15304 // FIXME: semantic checking!
15305 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
15306}
15307
15308template <typename Derived>
15309QualType TreeTransform<Derived>::RebuildDependentVectorType(
15310 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
15311 VectorKind VecKind) {
15312 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
15313}
15314
15315template<typename Derived>
15316QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
15317 unsigned NumElements,
15318 SourceLocation AttributeLoc) {
15319 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
15320 NumElements, true);
15321 IntegerLiteral *VectorSize
15322 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
15323 AttributeLoc);
15324 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
15325}
15326
15327template<typename Derived>
15328QualType
15329TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
15330 Expr *SizeExpr,
15331 SourceLocation AttributeLoc) {
15332 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
15333}
15334
15335template <typename Derived>
15336QualType TreeTransform<Derived>::RebuildConstantMatrixType(
15337 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
15338 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
15339 NumColumns);
15340}
15341
15342template <typename Derived>
15343QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
15344 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
15345 SourceLocation AttributeLoc) {
15346 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
15347 AttrLoc: AttributeLoc);
15348}
15349
15350template<typename Derived>
15351QualType TreeTransform<Derived>::RebuildFunctionProtoType(
15352 QualType T,
15353 MutableArrayRef<QualType> ParamTypes,
15354 const FunctionProtoType::ExtProtoInfo &EPI) {
15355 return SemaRef.BuildFunctionType(T, ParamTypes: ParamTypes,
15356 Loc: getDerived().getBaseLocation(),
15357 Entity: getDerived().getBaseEntity(),
15358 EPI);
15359}
15360
15361template<typename Derived>
15362QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
15363 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
15364}
15365
15366template<typename Derived>
15367QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
15368 Decl *D) {
15369 assert(D && "no decl found");
15370 if (D->isInvalidDecl()) return QualType();
15371
15372 // FIXME: Doesn't account for ObjCInterfaceDecl!
15373 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
15374 // A valid resolved using typename pack expansion decl can have multiple
15375 // UsingDecls, but they must each have exactly one type, and it must be
15376 // the same type in every case. But we must have at least one expansion!
15377 if (UPD->expansions().empty()) {
15378 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
15379 << UPD->isCXXClassMember() << UPD;
15380 return QualType();
15381 }
15382
15383 // We might still have some unresolved types. Try to pick a resolved type
15384 // if we can. The final instantiation will check that the remaining
15385 // unresolved types instantiate to the type we pick.
15386 QualType FallbackT;
15387 QualType T;
15388 for (auto *E : UPD->expansions()) {
15389 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
15390 if (ThisT.isNull())
15391 continue;
15392 else if (ThisT->getAs<UnresolvedUsingType>())
15393 FallbackT = ThisT;
15394 else if (T.isNull())
15395 T = ThisT;
15396 else
15397 assert(getSema().Context.hasSameType(ThisT, T) &&
15398 "mismatched resolved types in using pack expansion");
15399 }
15400 return T.isNull() ? FallbackT : T;
15401 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
15402 assert(Using->hasTypename() &&
15403 "UnresolvedUsingTypenameDecl transformed to non-typename using");
15404
15405 // A valid resolved using typename decl points to exactly one type decl.
15406 assert(++Using->shadow_begin() == Using->shadow_end());
15407
15408 UsingShadowDecl *Shadow = *Using->shadow_begin();
15409 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: Loc))
15410 return QualType();
15411 return SemaRef.Context.getUsingType(
15412 Found: Shadow, Underlying: SemaRef.Context.getTypeDeclType(
15413 Decl: cast<TypeDecl>(Shadow->getTargetDecl())));
15414 } else {
15415 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
15416 "UnresolvedUsingTypenameDecl transformed to non-using decl");
15417 return SemaRef.Context.getTypeDeclType(
15418 Decl: cast<UnresolvedUsingTypenameDecl>(D));
15419 }
15420}
15421
15422template <typename Derived>
15423QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
15424 TypeOfKind Kind) {
15425 return SemaRef.BuildTypeofExprType(E, Kind);
15426}
15427
15428template<typename Derived>
15429QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
15430 TypeOfKind Kind) {
15431 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
15432}
15433
15434template <typename Derived>
15435QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
15436 return SemaRef.BuildDecltypeType(E);
15437}
15438
15439template <typename Derived>
15440QualType TreeTransform<Derived>::RebuildPackIndexingType(
15441 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
15442 SourceLocation EllipsisLoc, bool FullySubstituted,
15443 ArrayRef<QualType> Expansions) {
15444 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
15445 FullySubstituted, Expansions);
15446}
15447
15448template<typename Derived>
15449QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
15450 UnaryTransformType::UTTKind UKind,
15451 SourceLocation Loc) {
15452 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
15453}
15454
15455template<typename Derived>
15456QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
15457 TemplateName Template,
15458 SourceLocation TemplateNameLoc,
15459 TemplateArgumentListInfo &TemplateArgs) {
15460 return SemaRef.CheckTemplateIdType(Template, TemplateLoc: TemplateNameLoc, TemplateArgs);
15461}
15462
15463template<typename Derived>
15464QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
15465 SourceLocation KWLoc) {
15466 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
15467}
15468
15469template<typename Derived>
15470QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
15471 SourceLocation KWLoc,
15472 bool isReadPipe) {
15473 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
15474 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
15475}
15476
15477template <typename Derived>
15478QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
15479 unsigned NumBits,
15480 SourceLocation Loc) {
15481 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
15482 NumBits, true);
15483 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
15484 SemaRef.Context.IntTy, Loc);
15485 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
15486}
15487
15488template <typename Derived>
15489QualType TreeTransform<Derived>::RebuildDependentBitIntType(
15490 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
15491 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
15492}
15493
15494template<typename Derived>
15495TemplateName
15496TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15497 bool TemplateKW,
15498 TemplateDecl *Template) {
15499 return SemaRef.Context.getQualifiedTemplateName(NNS: SS.getScopeRep(), TemplateKeyword: TemplateKW,
15500 Template: TemplateName(Template));
15501}
15502
15503template<typename Derived>
15504TemplateName
15505TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15506 SourceLocation TemplateKWLoc,
15507 const IdentifierInfo &Name,
15508 SourceLocation NameLoc,
15509 QualType ObjectType,
15510 NamedDecl *FirstQualifierInScope,
15511 bool AllowInjectedClassName) {
15512 UnqualifiedId TemplateName;
15513 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
15514 Sema::TemplateTy Template;
15515 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
15516 TemplateName, ParsedType::make(P: ObjectType),
15517 /*EnteringContext=*/false, Template,
15518 AllowInjectedClassName);
15519 return Template.get();
15520}
15521
15522template<typename Derived>
15523TemplateName
15524TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15525 SourceLocation TemplateKWLoc,
15526 OverloadedOperatorKind Operator,
15527 SourceLocation NameLoc,
15528 QualType ObjectType,
15529 bool AllowInjectedClassName) {
15530 UnqualifiedId Name;
15531 // FIXME: Bogus location information.
15532 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
15533 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
15534 Sema::TemplateTy Template;
15535 getSema().ActOnTemplateName(
15536 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
15537 /*EnteringContext=*/false, Template, AllowInjectedClassName);
15538 return Template.get();
15539}
15540
15541template <typename Derived>
15542ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
15543 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
15544 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
15545 Expr *Second) {
15546 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
15547
15548 if (First->getObjectKind() == OK_ObjCProperty) {
15549 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
15550 if (BinaryOperator::isAssignmentOp(Opc))
15551 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/S: nullptr, OpLoc, Opcode: Opc,
15552 LHS: First, RHS: Second);
15553 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
15554 if (Result.isInvalid())
15555 return ExprError();
15556 First = Result.get();
15557 }
15558
15559 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
15560 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
15561 if (Result.isInvalid())
15562 return ExprError();
15563 Second = Result.get();
15564 }
15565
15566 // Determine whether this should be a builtin operation.
15567 if (Op == OO_Subscript) {
15568 if (!First->getType()->isOverloadableType() &&
15569 !Second->getType()->isOverloadableType())
15570 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
15571 OpLoc);
15572 } else if (Op == OO_Arrow) {
15573 // It is possible that the type refers to a RecoveryExpr created earlier
15574 // in the tree transformation.
15575 if (First->getType()->isDependentType())
15576 return ExprError();
15577 // -> is never a builtin operation.
15578 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
15579 } else if (Second == nullptr || isPostIncDec) {
15580 if (!First->getType()->isOverloadableType() ||
15581 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
15582 // The argument is not of overloadable type, or this is an expression
15583 // of the form &Class::member, so try to create a built-in unary
15584 // operation.
15585 UnaryOperatorKind Opc
15586 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
15587
15588 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
15589 }
15590 } else {
15591 if (!First->getType()->isOverloadableType() &&
15592 !Second->getType()->isOverloadableType()) {
15593 // Neither of the arguments is an overloadable type, so try to
15594 // create a built-in binary operation.
15595 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
15596 ExprResult Result
15597 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
15598 if (Result.isInvalid())
15599 return ExprError();
15600
15601 return Result;
15602 }
15603 }
15604
15605 // Add any functions found via argument-dependent lookup.
15606 Expr *Args[2] = { First, Second };
15607 unsigned NumArgs = 1 + (Second != nullptr);
15608
15609 // Create the overloaded operator invocation for unary operators.
15610 if (NumArgs == 1 || isPostIncDec) {
15611 UnaryOperatorKind Opc
15612 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
15613 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
15614 RequiresADL);
15615 }
15616
15617 // Create the overloaded operator invocation for binary operators.
15618 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
15619 ExprResult Result = SemaRef.CreateOverloadedBinOp(
15620 OpLoc, Opc, Fns: Functions, LHS: Args[0], RHS: Args[1], RequiresADL);
15621 if (Result.isInvalid())
15622 return ExprError();
15623
15624 return Result;
15625}
15626
15627template<typename Derived>
15628ExprResult
15629TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
15630 SourceLocation OperatorLoc,
15631 bool isArrow,
15632 CXXScopeSpec &SS,
15633 TypeSourceInfo *ScopeType,
15634 SourceLocation CCLoc,
15635 SourceLocation TildeLoc,
15636 PseudoDestructorTypeStorage Destroyed) {
15637 QualType BaseType = Base->getType();
15638 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
15639 (!isArrow && !BaseType->getAs<RecordType>()) ||
15640 (isArrow && BaseType->getAs<PointerType>() &&
15641 !BaseType->castAs<PointerType>()->getPointeeType()
15642 ->template getAs<RecordType>())){
15643 // This pseudo-destructor expression is still a pseudo-destructor.
15644 return SemaRef.BuildPseudoDestructorExpr(
15645 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
15646 CCLoc, TildeLoc, DestroyedType: Destroyed);
15647 }
15648
15649 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
15650 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
15651 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
15652 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
15653 NameInfo.setNamedTypeInfo(DestroyedType);
15654
15655 // The scope type is now known to be a valid nested name specifier
15656 // component. Tack it on to the end of the nested name specifier.
15657 if (ScopeType) {
15658 if (!ScopeType->getType()->getAs<TagType>()) {
15659 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
15660 diag::err_expected_class_or_namespace)
15661 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
15662 return ExprError();
15663 }
15664 SS.Extend(Context&: SemaRef.Context, TemplateKWLoc: SourceLocation(), TL: ScopeType->getTypeLoc(),
15665 ColonColonLoc: CCLoc);
15666 }
15667
15668 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
15669 return getSema().BuildMemberReferenceExpr(Base, BaseType,
15670 OperatorLoc, isArrow,
15671 SS, TemplateKWLoc,
15672 /*FIXME: FirstQualifier*/ nullptr,
15673 NameInfo,
15674 /*TemplateArgs*/ nullptr,
15675 /*S*/nullptr);
15676}
15677
15678template<typename Derived>
15679StmtResult
15680TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
15681 SourceLocation Loc = S->getBeginLoc();
15682 CapturedDecl *CD = S->getCapturedDecl();
15683 unsigned NumParams = CD->getNumParams();
15684 unsigned ContextParamPos = CD->getContextParamPosition();
15685 SmallVector<Sema::CapturedParamNameType, 4> Params;
15686 for (unsigned I = 0; I < NumParams; ++I) {
15687 if (I != ContextParamPos) {
15688 Params.push_back(
15689 std::make_pair(
15690 CD->getParam(i: I)->getName(),
15691 getDerived().TransformType(CD->getParam(i: I)->getType())));
15692 } else {
15693 Params.push_back(std::make_pair(StringRef(), QualType()));
15694 }
15695 }
15696 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
15697 S->getCapturedRegionKind(), Params);
15698 StmtResult Body;
15699 {
15700 Sema::CompoundScopeRAII CompoundScope(getSema());
15701 Body = getDerived().TransformStmt(S->getCapturedStmt());
15702 }
15703
15704 if (Body.isInvalid()) {
15705 getSema().ActOnCapturedRegionError();
15706 return StmtError();
15707 }
15708
15709 return getSema().ActOnCapturedRegionEnd(Body.get());
15710}
15711
15712} // end namespace clang
15713
15714#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15715

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