1//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a semantic tree transformation that takes a given
9// AST and rebuilds it, possibly transforming some nodes in the process.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
16#include "CoroutineStmtBuilder.h"
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
23#include "clang/AST/ExprConcepts.h"
24#include "clang/AST/ExprObjC.h"
25#include "clang/AST/ExprOpenMP.h"
26#include "clang/AST/OpenMPClause.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
30#include "clang/AST/StmtOpenACC.h"
31#include "clang/AST/StmtOpenMP.h"
32#include "clang/AST/StmtSYCL.h"
33#include "clang/Basic/DiagnosticParse.h"
34#include "clang/Basic/OpenMPKinds.h"
35#include "clang/Sema/Designator.h"
36#include "clang/Sema/EnterExpressionEvaluationContext.h"
37#include "clang/Sema/Lookup.h"
38#include "clang/Sema/Ownership.h"
39#include "clang/Sema/ParsedTemplate.h"
40#include "clang/Sema/ScopeInfo.h"
41#include "clang/Sema/SemaDiagnostic.h"
42#include "clang/Sema/SemaHLSL.h"
43#include "clang/Sema/SemaInternal.h"
44#include "clang/Sema/SemaObjC.h"
45#include "clang/Sema/SemaOpenACC.h"
46#include "clang/Sema/SemaOpenMP.h"
47#include "clang/Sema/SemaPseudoObject.h"
48#include "clang/Sema/SemaSYCL.h"
49#include "clang/Sema/Template.h"
50#include "llvm/ADT/ArrayRef.h"
51#include "llvm/Support/ErrorHandling.h"
52#include <algorithm>
53#include <optional>
54
55using namespace llvm::omp;
56
57namespace clang {
58using namespace sema;
59
60// This helper class is used to facilitate pack expansion during tree transform.
61struct UnexpandedInfo {
62 SourceLocation Ellipsis;
63 UnsignedOrNone OrigNumExpansions = std::nullopt;
64
65 bool Expand = false;
66 bool RetainExpansion = false;
67 UnsignedOrNone NumExpansions = std::nullopt;
68 bool ExpandUnderForgetSubstitions = false;
69};
70
71/// A semantic tree transformation that allows one to transform one
72/// abstract syntax tree into another.
73///
74/// A new tree transformation is defined by creating a new subclass \c X of
75/// \c TreeTransform<X> and then overriding certain operations to provide
76/// behavior specific to that transformation. For example, template
77/// instantiation is implemented as a tree transformation where the
78/// transformation of TemplateTypeParmType nodes involves substituting the
79/// template arguments for their corresponding template parameters; a similar
80/// transformation is performed for non-type template parameters and
81/// template template parameters.
82///
83/// This tree-transformation template uses static polymorphism to allow
84/// subclasses to customize any of its operations. Thus, a subclass can
85/// override any of the transformation or rebuild operators by providing an
86/// operation with the same signature as the default implementation. The
87/// overriding function should not be virtual.
88///
89/// Semantic tree transformations are split into two stages, either of which
90/// can be replaced by a subclass. The "transform" step transforms an AST node
91/// or the parts of an AST node using the various transformation functions,
92/// then passes the pieces on to the "rebuild" step, which constructs a new AST
93/// node of the appropriate kind from the pieces. The default transformation
94/// routines recursively transform the operands to composite AST nodes (e.g.,
95/// the pointee type of a PointerType node) and, if any of those operand nodes
96/// were changed by the transformation, invokes the rebuild operation to create
97/// a new AST node.
98///
99/// Subclasses can customize the transformation at various levels. The
100/// most coarse-grained transformations involve replacing TransformType(),
101/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
102/// TransformTemplateName(), or TransformTemplateArgument() with entirely
103/// new implementations.
104///
105/// For more fine-grained transformations, subclasses can replace any of the
106/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
107/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
108/// replacing TransformTemplateTypeParmType() allows template instantiation
109/// to substitute template arguments for their corresponding template
110/// parameters. Additionally, subclasses can override the \c RebuildXXX
111/// functions to control how AST nodes are rebuilt when their operands change.
112/// By default, \c TreeTransform will invoke semantic analysis to rebuild
113/// AST nodes. However, certain other tree transformations (e.g, cloning) may
114/// be able to use more efficient rebuild steps.
115///
116/// There are a handful of other functions that can be overridden, allowing one
117/// to avoid traversing nodes that don't need any transformation
118/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
119/// operands have not changed (\c AlwaysRebuild()), and customize the
120/// default locations and entity names used for type-checking
121/// (\c getBaseLocation(), \c getBaseEntity()).
122template<typename Derived>
123class TreeTransform {
124 /// Private RAII object that helps us forget and then re-remember
125 /// the template argument corresponding to a partially-substituted parameter
126 /// pack.
127 class ForgetPartiallySubstitutedPackRAII {
128 Derived &Self;
129 TemplateArgument Old;
130 // Set the pack expansion index to -1 to avoid pack substitution and
131 // indicate that parameter packs should be instantiated as themselves.
132 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
133
134 public:
135 ForgetPartiallySubstitutedPackRAII(Derived &Self)
136 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
137 Old = Self.ForgetPartiallySubstitutedPack();
138 }
139
140 ~ForgetPartiallySubstitutedPackRAII() {
141 Self.RememberPartiallySubstitutedPack(Old);
142 }
143 ForgetPartiallySubstitutedPackRAII(
144 const ForgetPartiallySubstitutedPackRAII &) = delete;
145 ForgetPartiallySubstitutedPackRAII &
146 operator=(const ForgetPartiallySubstitutedPackRAII &) = delete;
147 };
148
149protected:
150 Sema &SemaRef;
151
152 /// The set of local declarations that have been transformed, for
153 /// cases where we are forced to build new declarations within the transformer
154 /// rather than in the subclass (e.g., lambda closure types).
155 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
156
157public:
158 /// Initializes a new tree transformer.
159 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
160
161 /// Retrieves a reference to the derived class.
162 Derived &getDerived() { return static_cast<Derived&>(*this); }
163
164 /// Retrieves a reference to the derived class.
165 const Derived &getDerived() const {
166 return static_cast<const Derived&>(*this);
167 }
168
169 static inline ExprResult Owned(Expr *E) { return E; }
170 static inline StmtResult Owned(Stmt *S) { return S; }
171
172 /// Retrieves a reference to the semantic analysis object used for
173 /// this tree transform.
174 Sema &getSema() const { return SemaRef; }
175
176 /// Whether the transformation should always rebuild AST nodes, even
177 /// if none of the children have changed.
178 ///
179 /// Subclasses may override this function to specify when the transformation
180 /// should rebuild all AST nodes.
181 ///
182 /// We must always rebuild all AST nodes when performing variadic template
183 /// pack expansion, in order to avoid violating the AST invariant that each
184 /// statement node appears at most once in its containing declaration.
185 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
186
187 /// Whether the transformation is forming an expression or statement that
188 /// replaces the original. In this case, we'll reuse mangling numbers from
189 /// existing lambdas.
190 bool ReplacingOriginal() { return false; }
191
192 /// Wether CXXConstructExpr can be skipped when they are implicit.
193 /// They will be reconstructed when used if needed.
194 /// This is useful when the user that cause rebuilding of the
195 /// CXXConstructExpr is outside of the expression at which the TreeTransform
196 /// started.
197 bool AllowSkippingCXXConstructExpr() { return true; }
198
199 /// Returns the location of the entity being transformed, if that
200 /// information was not available elsewhere in the AST.
201 ///
202 /// By default, returns no source-location information. Subclasses can
203 /// provide an alternative implementation that provides better location
204 /// information.
205 SourceLocation getBaseLocation() { return SourceLocation(); }
206
207 /// Returns the name of the entity being transformed, if that
208 /// information was not available elsewhere in the AST.
209 ///
210 /// By default, returns an empty name. Subclasses can provide an alternative
211 /// implementation with a more precise name.
212 DeclarationName getBaseEntity() { return DeclarationName(); }
213
214 /// Sets the "base" location and entity when that
215 /// information is known based on another transformation.
216 ///
217 /// By default, the source location and entity are ignored. Subclasses can
218 /// override this function to provide a customized implementation.
219 void setBase(SourceLocation Loc, DeclarationName Entity) { }
220
221 /// RAII object that temporarily sets the base location and entity
222 /// used for reporting diagnostics in types.
223 class TemporaryBase {
224 TreeTransform &Self;
225 SourceLocation OldLocation;
226 DeclarationName OldEntity;
227
228 public:
229 TemporaryBase(TreeTransform &Self, SourceLocation Location,
230 DeclarationName Entity) : Self(Self) {
231 OldLocation = Self.getDerived().getBaseLocation();
232 OldEntity = Self.getDerived().getBaseEntity();
233
234 if (Location.isValid())
235 Self.getDerived().setBase(Location, Entity);
236 }
237
238 ~TemporaryBase() {
239 Self.getDerived().setBase(OldLocation, OldEntity);
240 }
241 TemporaryBase(const TemporaryBase &) = delete;
242 TemporaryBase &operator=(const TemporaryBase &) = delete;
243 };
244
245 /// Determine whether the given type \p T has already been
246 /// transformed.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine
249 /// to short-circuit evaluation when it is known that a given type will
250 /// not change. For example, template instantiation need not traverse
251 /// non-dependent types.
252 bool AlreadyTransformed(QualType T) {
253 return T.isNull();
254 }
255
256 /// Transform a template parameter depth level.
257 ///
258 /// During a transformation that transforms template parameters, this maps
259 /// an old template parameter depth to a new depth.
260 unsigned TransformTemplateDepth(unsigned Depth) {
261 return Depth;
262 }
263
264 /// Determine whether the given call argument should be dropped, e.g.,
265 /// because it is a default argument.
266 ///
267 /// Subclasses can provide an alternative implementation of this routine to
268 /// determine which kinds of call arguments get dropped. By default,
269 /// CXXDefaultArgument nodes are dropped (prior to transformation).
270 bool DropCallArgument(Expr *E) {
271 return E->isDefaultArgument();
272 }
273
274 /// Determine whether we should expand a pack expansion with the
275 /// given set of parameter packs into separate arguments by repeatedly
276 /// transforming the pattern.
277 ///
278 /// By default, the transformer never tries to expand pack expansions.
279 /// Subclasses can override this routine to provide different behavior.
280 ///
281 /// \param EllipsisLoc The location of the ellipsis that identifies the
282 /// pack expansion.
283 ///
284 /// \param PatternRange The source range that covers the entire pattern of
285 /// the pack expansion.
286 ///
287 /// \param Unexpanded The set of unexpanded parameter packs within the
288 /// pattern.
289 ///
290 /// \param ShouldExpand Will be set to \c true if the transformer should
291 /// expand the corresponding pack expansions into separate arguments. When
292 /// set, \c NumExpansions must also be set.
293 ///
294 /// \param RetainExpansion Whether the caller should add an unexpanded
295 /// pack expansion after all of the expanded arguments. This is used
296 /// when extending explicitly-specified template argument packs per
297 /// C++0x [temp.arg.explicit]p9.
298 ///
299 /// \param NumExpansions The number of separate arguments that will be in
300 /// the expanded form of the corresponding pack expansion. This is both an
301 /// input and an output parameter, which can be set by the caller if the
302 /// number of expansions is known a priori (e.g., due to a prior substitution)
303 /// and will be set by the callee when the number of expansions is known.
304 /// The callee must set this value when \c ShouldExpand is \c true; it may
305 /// set this value in other cases.
306 ///
307 /// \returns true if an error occurred (e.g., because the parameter packs
308 /// are to be instantiated with arguments of different lengths), false
309 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
310 /// must be set.
311 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
312 SourceRange PatternRange,
313 ArrayRef<UnexpandedParameterPack> Unexpanded,
314 bool FailOnPackProducingTemplates,
315 bool &ShouldExpand, bool &RetainExpansion,
316 UnsignedOrNone &NumExpansions) {
317 ShouldExpand = false;
318 return false;
319 }
320
321 /// "Forget" about the partially-substituted pack template argument,
322 /// when performing an instantiation that must preserve the parameter pack
323 /// use.
324 ///
325 /// This routine is meant to be overridden by the template instantiator.
326 TemplateArgument ForgetPartiallySubstitutedPack() {
327 return TemplateArgument();
328 }
329
330 /// "Remember" the partially-substituted pack template argument
331 /// after performing an instantiation that must preserve the parameter pack
332 /// use.
333 ///
334 /// This routine is meant to be overridden by the template instantiator.
335 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
336
337 /// "Forget" the template substitution to allow transforming the AST without
338 /// any template instantiations. This is used to expand template packs when
339 /// their size is not known in advance (e.g. for builtins that produce type
340 /// packs).
341 MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }
342 void RememberSubstitution(MultiLevelTemplateArgumentList) {}
343
344private:
345 struct ForgetSubstitutionRAII {
346 Derived &Self;
347 MultiLevelTemplateArgumentList Old;
348
349 public:
350 ForgetSubstitutionRAII(Derived &Self) : Self(Self) {
351 Old = Self.ForgetSubstitution();
352 }
353
354 ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }
355 };
356
357public:
358 /// Note to the derived class when a function parameter pack is
359 /// being expanded.
360 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
361
362 /// Transforms the given type into another type.
363 ///
364 /// By default, this routine transforms a type by creating a
365 /// TypeSourceInfo for it and delegating to the appropriate
366 /// function. This is expensive, but we don't mind, because
367 /// this method is deprecated anyway; all users should be
368 /// switched to storing TypeSourceInfos.
369 ///
370 /// \returns the transformed type.
371 QualType TransformType(QualType T);
372
373 /// Transforms the given type-with-location into a new
374 /// type-with-location.
375 ///
376 /// By default, this routine transforms a type by delegating to the
377 /// appropriate TransformXXXType to build a new type. Subclasses
378 /// may override this function (to take over all type
379 /// transformations) or some set of the TransformXXXType functions
380 /// to alter the transformation.
381 TypeSourceInfo *TransformType(TypeSourceInfo *TSI);
382
383 /// Transform the given type-with-location into a new
384 /// type, collecting location information in the given builder
385 /// as necessary.
386 ///
387 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
388
389 /// Transform a type that is permitted to produce a
390 /// DeducedTemplateSpecializationType.
391 ///
392 /// This is used in the (relatively rare) contexts where it is acceptable
393 /// for transformation to produce a class template type with deduced
394 /// template arguments.
395 /// @{
396 QualType TransformTypeWithDeducedTST(QualType T);
397 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *TSI);
398 /// @}
399
400 /// The reason why the value of a statement is not discarded, if any.
401 enum class StmtDiscardKind {
402 Discarded,
403 NotDiscarded,
404 StmtExprResult,
405 };
406
407 /// Transform the given statement.
408 ///
409 /// By default, this routine transforms a statement by delegating to the
410 /// appropriate TransformXXXStmt function to transform a specific kind of
411 /// statement or the TransformExpr() function to transform an expression.
412 /// Subclasses may override this function to transform statements using some
413 /// other mechanism.
414 ///
415 /// \returns the transformed statement.
416 StmtResult TransformStmt(Stmt *S,
417 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
418
419 /// Transform the given statement.
420 ///
421 /// By default, this routine transforms a statement by delegating to the
422 /// appropriate TransformOMPXXXClause function to transform a specific kind
423 /// of clause. Subclasses may override this function to transform statements
424 /// using some other mechanism.
425 ///
426 /// \returns the transformed OpenMP clause.
427 OMPClause *TransformOMPClause(OMPClause *S);
428
429 /// Transform the given attribute.
430 ///
431 /// By default, this routine transforms a statement by delegating to the
432 /// appropriate TransformXXXAttr function to transform a specific kind
433 /// of attribute. Subclasses may override this function to transform
434 /// attributed statements/types using some other mechanism.
435 ///
436 /// \returns the transformed attribute
437 const Attr *TransformAttr(const Attr *S);
438
439 // Transform the given statement attribute.
440 //
441 // Delegates to the appropriate TransformXXXAttr function to transform a
442 // specific kind of statement attribute. Unlike the non-statement taking
443 // version of this, this implements all attributes, not just pragmas.
444 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
445 const Attr *A);
446
447 // Transform the specified attribute.
448 //
449 // Subclasses should override the transformation of attributes with a pragma
450 // spelling to transform expressions stored within the attribute.
451 //
452 // \returns the transformed attribute.
453#define ATTR(X) \
454 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
455#include "clang/Basic/AttrList.inc"
456
457 // Transform the specified attribute.
458 //
459 // Subclasses should override the transformation of attributes to do
460 // transformation and checking of statement attributes. By default, this
461 // delegates to the non-statement taking version.
462 //
463 // \returns the transformed attribute.
464#define ATTR(X) \
465 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
466 const X##Attr *A) { \
467 return getDerived().Transform##X##Attr(A); \
468 }
469#include "clang/Basic/AttrList.inc"
470
471 /// Transform the given expression.
472 ///
473 /// By default, this routine transforms an expression by delegating to the
474 /// appropriate TransformXXXExpr function to build a new expression.
475 /// Subclasses may override this function to transform expressions using some
476 /// other mechanism.
477 ///
478 /// \returns the transformed expression.
479 ExprResult TransformExpr(Expr *E);
480
481 /// Transform the given initializer.
482 ///
483 /// By default, this routine transforms an initializer by stripping off the
484 /// semantic nodes added by initialization, then passing the result to
485 /// TransformExpr or TransformExprs.
486 ///
487 /// \returns the transformed initializer.
488 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
489
490 /// Transform the given list of expressions.
491 ///
492 /// This routine transforms a list of expressions by invoking
493 /// \c TransformExpr() for each subexpression. However, it also provides
494 /// support for variadic templates by expanding any pack expansions (if the
495 /// derived class permits such expansion) along the way. When pack expansions
496 /// are present, the number of outputs may not equal the number of inputs.
497 ///
498 /// \param Inputs The set of expressions to be transformed.
499 ///
500 /// \param NumInputs The number of expressions in \c Inputs.
501 ///
502 /// \param IsCall If \c true, then this transform is being performed on
503 /// function-call arguments, and any arguments that should be dropped, will
504 /// be.
505 ///
506 /// \param Outputs The transformed input expressions will be added to this
507 /// vector.
508 ///
509 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
510 /// due to transformation.
511 ///
512 /// \returns true if an error occurred, false otherwise.
513 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
514 SmallVectorImpl<Expr *> &Outputs,
515 bool *ArgChanged = nullptr);
516
517 /// Transform the given declaration, which is referenced from a type
518 /// or expression.
519 ///
520 /// By default, acts as the identity function on declarations, unless the
521 /// transformer has had to transform the declaration itself. Subclasses
522 /// may override this function to provide alternate behavior.
523 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
524 llvm::DenseMap<Decl *, Decl *>::iterator Known
525 = TransformedLocalDecls.find(Val: D);
526 if (Known != TransformedLocalDecls.end())
527 return Known->second;
528
529 return D;
530 }
531
532 /// Transform the specified condition.
533 ///
534 /// By default, this transforms the variable and expression and rebuilds
535 /// the condition.
536 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
537 Expr *Expr,
538 Sema::ConditionKind Kind);
539
540 /// Transform the attributes associated with the given declaration and
541 /// place them on the new declaration.
542 ///
543 /// By default, this operation does nothing. Subclasses may override this
544 /// behavior to transform attributes.
545 void transformAttrs(Decl *Old, Decl *New) { }
546
547 /// Note that a local declaration has been transformed by this
548 /// transformer.
549 ///
550 /// Local declarations are typically transformed via a call to
551 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
552 /// the transformer itself has to transform the declarations. This routine
553 /// can be overridden by a subclass that keeps track of such mappings.
554 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
555 assert(New.size() == 1 &&
556 "must override transformedLocalDecl if performing pack expansion");
557 TransformedLocalDecls[Old] = New.front();
558 }
559
560 /// Transform the definition of the given declaration.
561 ///
562 /// By default, invokes TransformDecl() to transform the declaration.
563 /// Subclasses may override this function to provide alternate behavior.
564 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
565 return getDerived().TransformDecl(Loc, D);
566 }
567
568 /// Transform the given declaration, which was the first part of a
569 /// nested-name-specifier in a member access expression.
570 ///
571 /// This specific declaration transformation only applies to the first
572 /// identifier in a nested-name-specifier of a member access expression, e.g.,
573 /// the \c T in \c x->T::member
574 ///
575 /// By default, invokes TransformDecl() to transform the declaration.
576 /// Subclasses may override this function to provide alternate behavior.
577 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
578 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
579 }
580
581 /// Transform the set of declarations in an OverloadExpr.
582 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
583 LookupResult &R);
584
585 /// Transform the given nested-name-specifier with source-location
586 /// information.
587 ///
588 /// By default, transforms all of the types and declarations within the
589 /// nested-name-specifier. Subclasses may override this function to provide
590 /// alternate behavior.
591 NestedNameSpecifierLoc
592 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
593 QualType ObjectType = QualType(),
594 NamedDecl *FirstQualifierInScope = nullptr);
595
596 /// Transform the given declaration name.
597 ///
598 /// By default, transforms the types of conversion function, constructor,
599 /// and destructor names and then (if needed) rebuilds the declaration name.
600 /// Identifiers and selectors are returned unmodified. Subclasses may
601 /// override this function to provide alternate behavior.
602 DeclarationNameInfo
603 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
604
605 bool TransformRequiresExprRequirements(
606 ArrayRef<concepts::Requirement *> Reqs,
607 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
608 concepts::TypeRequirement *
609 TransformTypeRequirement(concepts::TypeRequirement *Req);
610 concepts::ExprRequirement *
611 TransformExprRequirement(concepts::ExprRequirement *Req);
612 concepts::NestedRequirement *
613 TransformNestedRequirement(concepts::NestedRequirement *Req);
614
615 /// Transform the given template name.
616 ///
617 /// \param SS The nested-name-specifier that qualifies the template
618 /// name. This nested-name-specifier must already have been transformed.
619 ///
620 /// \param Name The template name to transform.
621 ///
622 /// \param NameLoc The source location of the template name.
623 ///
624 /// \param ObjectType If we're translating a template name within a member
625 /// access expression, this is the type of the object whose member template
626 /// is being referenced.
627 ///
628 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
629 /// also refers to a name within the current (lexical) scope, this is the
630 /// declaration it refers to.
631 ///
632 /// By default, transforms the template name by transforming the declarations
633 /// and nested-name-specifiers that occur within the template name.
634 /// Subclasses may override this function to provide alternate behavior.
635 TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
636 SourceLocation TemplateKWLoc,
637 TemplateName Name, SourceLocation NameLoc,
638 QualType ObjectType = QualType(),
639 NamedDecl *FirstQualifierInScope = nullptr,
640 bool AllowInjectedClassName = false);
641
642 TemplateName TransformConceptTemplateName(TemplateName Name,
643 SourceLocation NameLoc);
644
645 /// Transform the given template argument.
646 ///
647 /// By default, this operation transforms the type, expression, or
648 /// declaration stored within the template argument and constructs a
649 /// new template argument from the transformed result. Subclasses may
650 /// override this function to provide alternate behavior.
651 ///
652 /// Returns true if there was an error.
653 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
654 TemplateArgumentLoc &Output,
655 bool Uneval = false);
656
657 TemplateArgument TransformNamedTemplateTemplateArgument(
658 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
659 TemplateName Name, SourceLocation NameLoc);
660
661 /// Transform the given set of template arguments.
662 ///
663 /// By default, this operation transforms all of the template arguments
664 /// in the input set using \c TransformTemplateArgument(), and appends
665 /// the transformed arguments to the output list.
666 ///
667 /// Note that this overload of \c TransformTemplateArguments() is merely
668 /// a convenience function. Subclasses that wish to override this behavior
669 /// should override the iterator-based member template version.
670 ///
671 /// \param Inputs The set of template arguments to be transformed.
672 ///
673 /// \param NumInputs The number of template arguments in \p Inputs.
674 ///
675 /// \param Outputs The set of transformed template arguments output by this
676 /// routine.
677 ///
678 /// Returns true if an error occurred.
679 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
680 unsigned NumInputs,
681 TemplateArgumentListInfo &Outputs,
682 bool Uneval = false) {
683 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
684 Uneval);
685 }
686
687 /// Transform the given set of template arguments.
688 ///
689 /// By default, this operation transforms all of the template arguments
690 /// in the input set using \c TransformTemplateArgument(), and appends
691 /// the transformed arguments to the output list.
692 ///
693 /// \param First An iterator to the first template argument.
694 ///
695 /// \param Last An iterator one step past the last template argument.
696 ///
697 /// \param Outputs The set of transformed template arguments output by this
698 /// routine.
699 ///
700 /// Returns true if an error occurred.
701 template<typename InputIterator>
702 bool TransformTemplateArguments(InputIterator First,
703 InputIterator Last,
704 TemplateArgumentListInfo &Outputs,
705 bool Uneval = false);
706
707 template <typename InputIterator>
708 bool TransformConceptTemplateArguments(InputIterator First,
709 InputIterator Last,
710 TemplateArgumentListInfo &Outputs,
711 bool Uneval = false);
712
713 /// Checks if the argument pack from \p In will need to be expanded and does
714 /// the necessary prework.
715 /// Whether the expansion is needed is captured in Info.Expand.
716 ///
717 /// - When the expansion is required, \p Out will be a template pattern that
718 /// would need to be expanded.
719 /// - When the expansion must not happen, \p Out will be a pack that must be
720 /// returned to the outputs directly.
721 ///
722 /// \return true iff the error occurred
723 bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
724 TemplateArgumentLoc &Out, UnexpandedInfo &Info);
725
726 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
727 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
728 TemplateArgumentLoc &ArgLoc);
729
730 /// Fakes up a TypeSourceInfo for a type.
731 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
732 return SemaRef.Context.getTrivialTypeSourceInfo(T,
733 Loc: getDerived().getBaseLocation());
734 }
735
736#define ABSTRACT_TYPELOC(CLASS, PARENT)
737#define TYPELOC(CLASS, PARENT) \
738 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
739#include "clang/AST/TypeLocNodes.def"
740
741 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
742 TemplateTypeParmTypeLoc TL,
743 bool SuppressObjCLifetime);
744 QualType
745 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
746 SubstTemplateTypeParmPackTypeLoc TL,
747 bool SuppressObjCLifetime);
748
749 template<typename Fn>
750 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
751 FunctionProtoTypeLoc TL,
752 CXXRecordDecl *ThisContext,
753 Qualifiers ThisTypeQuals,
754 Fn TransformExceptionSpec);
755
756 bool TransformExceptionSpec(SourceLocation Loc,
757 FunctionProtoType::ExceptionSpecInfo &ESI,
758 SmallVectorImpl<QualType> &Exceptions,
759 bool &Changed);
760
761 StmtResult TransformSEHHandler(Stmt *Handler);
762
763 QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,
764 TemplateSpecializationTypeLoc TL,
765 QualType ObjectType,
766 NamedDecl *FirstQualifierInScope,
767 bool AllowInjectedClassName);
768
769 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);
770
771 /// Transforms the parameters of a function type into the
772 /// given vectors.
773 ///
774 /// The result vectors should be kept in sync; null entries in the
775 /// variables vector are acceptable.
776 ///
777 /// LastParamTransformed, if non-null, will be set to the index of the last
778 /// parameter on which transformation was started. In the event of an error,
779 /// this will contain the parameter which failed to instantiate.
780 ///
781 /// Return true on error.
782 bool TransformFunctionTypeParams(
783 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
784 const QualType *ParamTypes,
785 const FunctionProtoType::ExtParameterInfo *ParamInfos,
786 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
787 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
788
789 bool TransformFunctionTypeParams(
790 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
791 const QualType *ParamTypes,
792 const FunctionProtoType::ExtParameterInfo *ParamInfos,
793 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
794 Sema::ExtParameterInfoBuilder &PInfos) {
795 return getDerived().TransformFunctionTypeParams(
796 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
797 }
798
799 /// Transforms the parameters of a requires expresison into the given vectors.
800 ///
801 /// The result vectors should be kept in sync; null entries in the
802 /// variables vector are acceptable.
803 ///
804 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
805 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
806 /// which are cases where transformation shouldn't continue.
807 ExprResult TransformRequiresTypeParams(
808 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
809 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
810 SmallVectorImpl<QualType> &PTypes,
811 SmallVectorImpl<ParmVarDecl *> &TransParams,
812 Sema::ExtParameterInfoBuilder &PInfos) {
813 if (getDerived().TransformFunctionTypeParams(
814 KWLoc, Params, /*ParamTypes=*/nullptr,
815 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
816 return ExprError();
817
818 return ExprResult{};
819 }
820
821 /// Transforms a single function-type parameter. Return null
822 /// on error.
823 ///
824 /// \param indexAdjustment - A number to add to the parameter's
825 /// scope index; can be negative
826 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
827 int indexAdjustment,
828 UnsignedOrNone NumExpansions,
829 bool ExpectParameterPack);
830
831 /// Transform the body of a lambda-expression.
832 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
833 /// Alternative implementation of TransformLambdaBody that skips transforming
834 /// the body.
835 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
836
837 CXXRecordDecl::LambdaDependencyKind
838 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
839 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
840 LSI->Lambda->getLambdaDependencyKind());
841 }
842
843 ExprResult TransformLambdaConstraint(Expr *AC) { return AC; }
844
845 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
846
847 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
848 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
849
850 TemplateParameterList *TransformTemplateParameterList(
851 TemplateParameterList *TPL) {
852 return TPL;
853 }
854
855 ExprResult TransformAddressOfOperand(Expr *E);
856
857 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
858 bool IsAddressOfOperand,
859 TypeSourceInfo **RecoveryTSI);
860
861 ExprResult TransformParenDependentScopeDeclRefExpr(
862 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
863 TypeSourceInfo **RecoveryTSI);
864
865 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
866 bool IsAddressOfOperand);
867
868 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
869
870 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
871
872// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
873// amount of stack usage with clang.
874#define STMT(Node, Parent) \
875 LLVM_ATTRIBUTE_NOINLINE \
876 StmtResult Transform##Node(Node *S);
877#define VALUESTMT(Node, Parent) \
878 LLVM_ATTRIBUTE_NOINLINE \
879 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
880#define EXPR(Node, Parent) \
881 LLVM_ATTRIBUTE_NOINLINE \
882 ExprResult Transform##Node(Node *E);
883#define ABSTRACT_STMT(Stmt)
884#include "clang/AST/StmtNodes.inc"
885
886#define GEN_CLANG_CLAUSE_CLASS
887#define CLAUSE_CLASS(Enum, Str, Class) \
888 LLVM_ATTRIBUTE_NOINLINE \
889 OMPClause *Transform##Class(Class *S);
890#include "llvm/Frontend/OpenMP/OMP.inc"
891
892 /// Build a new qualified type given its unqualified type and type location.
893 ///
894 /// By default, this routine adds type qualifiers only to types that can
895 /// have qualifiers, and silently suppresses those qualifiers that are not
896 /// permitted. Subclasses may override this routine to provide different
897 /// behavior.
898 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
899
900 /// Build a new pointer type given its pointee type.
901 ///
902 /// By default, performs semantic analysis when building the pointer type.
903 /// Subclasses may override this routine to provide different behavior.
904 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
905
906 /// Build a new block pointer type given its pointee type.
907 ///
908 /// By default, performs semantic analysis when building the block pointer
909 /// type. Subclasses may override this routine to provide different behavior.
910 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
911
912 /// Build a new reference type given the type it references.
913 ///
914 /// By default, performs semantic analysis when building the
915 /// reference type. Subclasses may override this routine to provide
916 /// different behavior.
917 ///
918 /// \param LValue whether the type was written with an lvalue sigil
919 /// or an rvalue sigil.
920 QualType RebuildReferenceType(QualType ReferentType,
921 bool LValue,
922 SourceLocation Sigil);
923
924 /// Build a new member pointer type given the pointee type and the
925 /// qualifier it refers into.
926 ///
927 /// By default, performs semantic analysis when building the member pointer
928 /// type. Subclasses may override this routine to provide different behavior.
929 QualType RebuildMemberPointerType(QualType PointeeType,
930 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
931 SourceLocation Sigil);
932
933 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
934 SourceLocation ProtocolLAngleLoc,
935 ArrayRef<ObjCProtocolDecl *> Protocols,
936 ArrayRef<SourceLocation> ProtocolLocs,
937 SourceLocation ProtocolRAngleLoc);
938
939 /// Build an Objective-C object type.
940 ///
941 /// By default, performs semantic analysis when building the object type.
942 /// Subclasses may override this routine to provide different behavior.
943 QualType RebuildObjCObjectType(QualType BaseType,
944 SourceLocation Loc,
945 SourceLocation TypeArgsLAngleLoc,
946 ArrayRef<TypeSourceInfo *> TypeArgs,
947 SourceLocation TypeArgsRAngleLoc,
948 SourceLocation ProtocolLAngleLoc,
949 ArrayRef<ObjCProtocolDecl *> Protocols,
950 ArrayRef<SourceLocation> ProtocolLocs,
951 SourceLocation ProtocolRAngleLoc);
952
953 /// Build a new Objective-C object pointer type given the pointee type.
954 ///
955 /// By default, directly builds the pointer type, with no additional semantic
956 /// analysis.
957 QualType RebuildObjCObjectPointerType(QualType PointeeType,
958 SourceLocation Star);
959
960 /// Build a new array type given the element type, size
961 /// modifier, size of the array (if known), size expression, and index type
962 /// qualifiers.
963 ///
964 /// By default, performs semantic analysis when building the array type.
965 /// Subclasses may override this routine to provide different behavior.
966 /// Also by default, all of the other Rebuild*Array
967 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
968 const llvm::APInt *Size, Expr *SizeExpr,
969 unsigned IndexTypeQuals, SourceRange BracketsRange);
970
971 /// Build a new constant array type given the element type, size
972 /// modifier, (known) size of the array, and index type qualifiers.
973 ///
974 /// By default, performs semantic analysis when building the array type.
975 /// Subclasses may override this routine to provide different behavior.
976 QualType RebuildConstantArrayType(QualType ElementType,
977 ArraySizeModifier SizeMod,
978 const llvm::APInt &Size, Expr *SizeExpr,
979 unsigned IndexTypeQuals,
980 SourceRange BracketsRange);
981
982 /// Build a new incomplete array type given the element type, size
983 /// modifier, and index type qualifiers.
984 ///
985 /// By default, performs semantic analysis when building the array type.
986 /// Subclasses may override this routine to provide different behavior.
987 QualType RebuildIncompleteArrayType(QualType ElementType,
988 ArraySizeModifier SizeMod,
989 unsigned IndexTypeQuals,
990 SourceRange BracketsRange);
991
992 /// Build a new variable-length array type given the element type,
993 /// size modifier, size expression, and index type qualifiers.
994 ///
995 /// By default, performs semantic analysis when building the array type.
996 /// Subclasses may override this routine to provide different behavior.
997 QualType RebuildVariableArrayType(QualType ElementType,
998 ArraySizeModifier SizeMod, Expr *SizeExpr,
999 unsigned IndexTypeQuals,
1000 SourceRange BracketsRange);
1001
1002 /// Build a new dependent-sized array type given the element type,
1003 /// size modifier, size expression, and index type qualifiers.
1004 ///
1005 /// By default, performs semantic analysis when building the array type.
1006 /// Subclasses may override this routine to provide different behavior.
1007 QualType RebuildDependentSizedArrayType(QualType ElementType,
1008 ArraySizeModifier SizeMod,
1009 Expr *SizeExpr,
1010 unsigned IndexTypeQuals,
1011 SourceRange BracketsRange);
1012
1013 /// Build a new vector type given the element type and
1014 /// number of elements.
1015 ///
1016 /// By default, performs semantic analysis when building the vector type.
1017 /// Subclasses may override this routine to provide different behavior.
1018 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
1019 VectorKind VecKind);
1020
1021 /// Build a new potentially dependently-sized extended vector type
1022 /// given the element type and number of elements.
1023 ///
1024 /// By default, performs semantic analysis when building the vector type.
1025 /// Subclasses may override this routine to provide different behavior.
1026 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
1027 SourceLocation AttributeLoc, VectorKind);
1028
1029 /// Build a new extended vector type given the element type and
1030 /// number of elements.
1031 ///
1032 /// By default, performs semantic analysis when building the vector type.
1033 /// Subclasses may override this routine to provide different behavior.
1034 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
1035 SourceLocation AttributeLoc);
1036
1037 /// Build a new potentially dependently-sized extended vector type
1038 /// given the element type and number of elements.
1039 ///
1040 /// By default, performs semantic analysis when building the vector type.
1041 /// Subclasses may override this routine to provide different behavior.
1042 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
1043 Expr *SizeExpr,
1044 SourceLocation AttributeLoc);
1045
1046 /// Build a new matrix type given the element type and dimensions.
1047 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
1048 unsigned NumColumns,
1049 SourceLocation AttributeLoc);
1050
1051 /// Build a new matrix type given the type and dependently-defined
1052 /// dimensions.
1053 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1054 Expr *ColumnExpr,
1055 SourceLocation AttributeLoc);
1056
1057 /// Build a new DependentAddressSpaceType or return the pointee
1058 /// type variable with the correct address space (retrieved from
1059 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1060 /// where the address space remains dependent.
1061 ///
1062 /// By default, performs semantic analysis when building the type with address
1063 /// space applied. Subclasses may override this routine to provide different
1064 /// behavior.
1065 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1066 Expr *AddrSpaceExpr,
1067 SourceLocation AttributeLoc);
1068
1069 /// Build a new function type.
1070 ///
1071 /// By default, performs semantic analysis when building the function type.
1072 /// Subclasses may override this routine to provide different behavior.
1073 QualType RebuildFunctionProtoType(QualType T,
1074 MutableArrayRef<QualType> ParamTypes,
1075 const FunctionProtoType::ExtProtoInfo &EPI);
1076
1077 /// Build a new unprototyped function type.
1078 QualType RebuildFunctionNoProtoType(QualType ResultType);
1079
1080 /// Rebuild an unresolved typename type, given the decl that
1081 /// the UnresolvedUsingTypenameDecl was transformed to.
1082 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1083 NestedNameSpecifier Qualifier,
1084 SourceLocation NameLoc, Decl *D);
1085
1086 /// Build a new type found via an alias.
1087 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1088 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1089 QualType UnderlyingType) {
1090 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1091 }
1092
1093 /// Build a new typedef type.
1094 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1095 NestedNameSpecifier Qualifier,
1096 TypedefNameDecl *Typedef) {
1097 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1098 }
1099
1100 /// Build a new MacroDefined type.
1101 QualType RebuildMacroQualifiedType(QualType T,
1102 const IdentifierInfo *MacroII) {
1103 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1104 }
1105
1106 /// Build a new class/struct/union/enum type.
1107 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1108 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1109 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1110 /*OwnsTag=*/OwnsTag: false);
1111 }
1112 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1113 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1114 }
1115
1116 /// Build a new typeof(expr) type.
1117 ///
1118 /// By default, performs semantic analysis when building the typeof type.
1119 /// Subclasses may override this routine to provide different behavior.
1120 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1121 TypeOfKind Kind);
1122
1123 /// Build a new typeof(type) type.
1124 ///
1125 /// By default, builds a new TypeOfType with the given underlying type.
1126 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1127
1128 /// Build a new unary transform type.
1129 QualType RebuildUnaryTransformType(QualType BaseType,
1130 UnaryTransformType::UTTKind UKind,
1131 SourceLocation Loc);
1132
1133 /// Build a new C++11 decltype type.
1134 ///
1135 /// By default, performs semantic analysis when building the decltype type.
1136 /// Subclasses may override this routine to provide different behavior.
1137 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1138
1139 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1140 SourceLocation Loc,
1141 SourceLocation EllipsisLoc,
1142 bool FullySubstituted,
1143 ArrayRef<QualType> Expansions = {});
1144
1145 /// Build a new C++11 auto type.
1146 ///
1147 /// By default, builds a new AutoType with the given deduced type.
1148 QualType RebuildAutoType(DeducedKind DK, QualType DeducedAsType,
1149 AutoTypeKeyword Keyword,
1150 TemplateName TypeConstraintConcept,
1151 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1152 return SemaRef.Context.getAutoType(
1153 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1154 }
1155
1156 /// By default, builds a new DeducedTemplateSpecializationType with the given
1157 /// deduced type.
1158 QualType RebuildDeducedTemplateSpecializationType(
1159 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1160 TemplateName Template) {
1161 return SemaRef.Context.getDeducedTemplateSpecializationType(
1162 DK, DeducedAsType, Keyword, Template);
1163 }
1164
1165 /// Build a new template specialization type.
1166 ///
1167 /// By default, performs semantic analysis when building the template
1168 /// specialization type. Subclasses may override this routine to provide
1169 /// different behavior.
1170 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1171 TemplateName Template,
1172 SourceLocation TemplateLoc,
1173 TemplateArgumentListInfo &Args);
1174
1175 /// Build a new parenthesized type.
1176 ///
1177 /// By default, builds a new ParenType type from the inner type.
1178 /// Subclasses may override this routine to provide different behavior.
1179 QualType RebuildParenType(QualType InnerType) {
1180 return SemaRef.BuildParenType(T: InnerType);
1181 }
1182
1183 /// Build a new typename type that refers to an identifier.
1184 ///
1185 /// By default, performs semantic analysis when building the typename type
1186 /// (or elaborated type). Subclasses may override this routine to provide
1187 /// different behavior.
1188 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1189 SourceLocation KeywordLoc,
1190 NestedNameSpecifierLoc QualifierLoc,
1191 const IdentifierInfo *Id,
1192 SourceLocation IdLoc,
1193 bool DeducedTSTContext) {
1194 CXXScopeSpec SS;
1195 SS.Adopt(Other: QualifierLoc);
1196
1197 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1198 // If the name is still dependent, just build a new dependent name type.
1199 if (!SemaRef.computeDeclContext(SS))
1200 return SemaRef.Context.getDependentNameType(Keyword,
1201 NNS: QualifierLoc.getNestedNameSpecifier(),
1202 Name: Id);
1203 }
1204
1205 if (Keyword == ElaboratedTypeKeyword::None ||
1206 Keyword == ElaboratedTypeKeyword::Typename) {
1207 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1208 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1209 }
1210
1211 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1212
1213 // We had a dependent elaborated-type-specifier that has been transformed
1214 // into a non-dependent elaborated-type-specifier. Find the tag we're
1215 // referring to.
1216 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1217 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1218 if (!DC)
1219 return QualType();
1220
1221 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1222 return QualType();
1223
1224 TagDecl *Tag = nullptr;
1225 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1226 switch (Result.getResultKind()) {
1227 case LookupResultKind::NotFound:
1228 case LookupResultKind::NotFoundInCurrentInstantiation:
1229 break;
1230
1231 case LookupResultKind::Found:
1232 Tag = Result.getAsSingle<TagDecl>();
1233 break;
1234
1235 case LookupResultKind::FoundOverloaded:
1236 case LookupResultKind::FoundUnresolvedValue:
1237 llvm_unreachable("Tag lookup cannot find non-tags");
1238
1239 case LookupResultKind::Ambiguous:
1240 // Let the LookupResult structure handle ambiguities.
1241 return QualType();
1242 }
1243
1244 if (!Tag) {
1245 // Check where the name exists but isn't a tag type and use that to emit
1246 // better diagnostics.
1247 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1248 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1249 switch (Result.getResultKind()) {
1250 case LookupResultKind::Found:
1251 case LookupResultKind::FoundOverloaded:
1252 case LookupResultKind::FoundUnresolvedValue: {
1253 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1254 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1255 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1256 << SomeDecl << NTK << Kind;
1257 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1258 break;
1259 }
1260 default:
1261 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1262 << Kind << Id << DC << QualifierLoc.getSourceRange();
1263 break;
1264 }
1265 return QualType();
1266 }
1267 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1268 NewTagLoc: IdLoc, Name: Id)) {
1269 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1270 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1271 return QualType();
1272 }
1273 return getDerived().RebuildTagType(
1274 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1275 }
1276
1277 /// Build a new pack expansion type.
1278 ///
1279 /// By default, builds a new PackExpansionType type from the given pattern.
1280 /// Subclasses may override this routine to provide different behavior.
1281 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1282 SourceLocation EllipsisLoc,
1283 UnsignedOrNone NumExpansions) {
1284 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1285 NumExpansions);
1286 }
1287
1288 /// Build a new atomic type given its value type.
1289 ///
1290 /// By default, performs semantic analysis when building the atomic type.
1291 /// Subclasses may override this routine to provide different behavior.
1292 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1293
1294 /// Build a new pipe type given its value type.
1295 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1296 bool isReadPipe);
1297
1298 /// Build a bit-precise int given its value type.
1299 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1300 SourceLocation Loc);
1301
1302 /// Build a dependent bit-precise int given its value type.
1303 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1304 SourceLocation Loc);
1305
1306 /// Build a new template name given a nested name specifier, a flag
1307 /// indicating whether the "template" keyword was provided, and the template
1308 /// that the template name refers to.
1309 ///
1310 /// By default, builds the new template name directly. Subclasses may override
1311 /// this routine to provide different behavior.
1312 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1313 TemplateName Name);
1314
1315 /// Build a new template name given a nested name specifier and the
1316 /// name that is referred to as a template.
1317 ///
1318 /// By default, performs semantic analysis to determine whether the name can
1319 /// be resolved to a specific template, then builds the appropriate kind of
1320 /// template name. Subclasses may override this routine to provide different
1321 /// behavior.
1322 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1323 SourceLocation TemplateKWLoc,
1324 const IdentifierInfo &Name,
1325 SourceLocation NameLoc, QualType ObjectType,
1326 bool AllowInjectedClassName);
1327
1328 /// Build a new template name given a nested name specifier and the
1329 /// overloaded operator name that is referred to as a template.
1330 ///
1331 /// By default, performs semantic analysis to determine whether the name can
1332 /// be resolved to a specific template, then builds the appropriate kind of
1333 /// template name. Subclasses may override this routine to provide different
1334 /// behavior.
1335 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1336 SourceLocation TemplateKWLoc,
1337 OverloadedOperatorKind Operator,
1338 SourceLocation NameLoc, QualType ObjectType,
1339 bool AllowInjectedClassName);
1340
1341 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1342 SourceLocation TemplateKWLoc,
1343 IdentifierOrOverloadedOperator IO,
1344 SourceLocation NameLoc, QualType ObjectType,
1345 bool AllowInjectedClassName);
1346
1347 /// Build a new template name given a template template parameter pack
1348 /// and the
1349 ///
1350 /// By default, performs semantic analysis to determine whether the name can
1351 /// be resolved to a specific template, then builds the appropriate kind of
1352 /// template name. Subclasses may override this routine to provide different
1353 /// behavior.
1354 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1355 Decl *AssociatedDecl, unsigned Index,
1356 bool Final) {
1357 return getSema().Context.getSubstTemplateTemplateParmPack(
1358 ArgPack, AssociatedDecl, Index, Final);
1359 }
1360
1361 /// Build a new pack-index-template-name ([temp.names]).
1362 ///
1363 /// By default, performs semantic analysis to build the new template name.
1364 /// Subclasses may override this routine to provide different behavior.
1365 TemplateName
1366 RebuildPackIndexingTemplateName(TemplateName Pattern, Expr *IndexExpr,
1367 bool FullySubstituted,
1368 ArrayRef<TemplateName> Expansions = {}) {
1369 return getSema().BuildPackIndexingTemplateName(
1370 Pattern, IndexExpr, FullySubstituted, Expansions);
1371 }
1372
1373 /// Build a new compound statement.
1374 ///
1375 /// By default, performs semantic analysis to build the new statement.
1376 /// Subclasses may override this routine to provide different behavior.
1377 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1378 MultiStmtArg Statements,
1379 SourceLocation RBraceLoc,
1380 bool IsStmtExpr) {
1381 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1382 IsStmtExpr);
1383 }
1384
1385 /// Build a new case 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 RebuildCaseStmt(SourceLocation CaseLoc,
1390 Expr *LHS,
1391 SourceLocation EllipsisLoc,
1392 Expr *RHS,
1393 SourceLocation ColonLoc) {
1394 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1395 ColonLoc);
1396 }
1397
1398 /// Attach the body to a new case statement.
1399 ///
1400 /// By default, performs semantic analysis to build the new statement.
1401 /// Subclasses may override this routine to provide different behavior.
1402 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1403 getSema().ActOnCaseStmtBody(S, Body);
1404 return S;
1405 }
1406
1407 /// Build a new default statement.
1408 ///
1409 /// By default, performs semantic analysis to build the new statement.
1410 /// Subclasses may override this routine to provide different behavior.
1411 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1412 SourceLocation ColonLoc,
1413 Stmt *SubStmt) {
1414 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1415 /*CurScope=*/nullptr);
1416 }
1417
1418 /// Build a new label statement.
1419 ///
1420 /// By default, performs semantic analysis to build the new statement.
1421 /// Subclasses may override this routine to provide different behavior.
1422 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1423 SourceLocation ColonLoc, Stmt *SubStmt) {
1424 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1425 }
1426
1427 /// Build a new attributed statement.
1428 ///
1429 /// By default, performs semantic analysis to build the new statement.
1430 /// Subclasses may override this routine to provide different behavior.
1431 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1432 ArrayRef<const Attr *> Attrs,
1433 Stmt *SubStmt) {
1434 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1435 return StmtError();
1436 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1437 }
1438
1439 /// Build a new "if" statement.
1440 ///
1441 /// By default, performs semantic analysis to build the new statement.
1442 /// Subclasses may override this routine to provide different behavior.
1443 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1444 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1445 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1446 SourceLocation ElseLoc, Stmt *Else) {
1447 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1448 Then, ElseLoc, Else);
1449 }
1450
1451 /// Start building a new switch 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 RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1456 SourceLocation LParenLoc, Stmt *Init,
1457 Sema::ConditionResult Cond,
1458 SourceLocation RParenLoc) {
1459 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1460 RParenLoc);
1461 }
1462
1463 /// Attach the body to the switch 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 RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1468 Stmt *Switch, Stmt *Body) {
1469 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1470 }
1471
1472 /// Build a new while 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 RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1477 Sema::ConditionResult Cond,
1478 SourceLocation RParenLoc, Stmt *Body) {
1479 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1480 }
1481
1482 /// Build a new do-while 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 RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1487 SourceLocation WhileLoc, SourceLocation LParenLoc,
1488 Expr *Cond, SourceLocation RParenLoc) {
1489 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1490 Cond, RParenLoc);
1491 }
1492
1493 /// Build a new for statement.
1494 ///
1495 /// By default, performs semantic analysis to build the new statement.
1496 /// Subclasses may override this routine to provide different behavior.
1497 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1498 Stmt *Init, Sema::ConditionResult Cond,
1499 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1500 Stmt *Body) {
1501 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1502 Inc, RParenLoc, Body);
1503 }
1504
1505 /// Build a new goto statement.
1506 ///
1507 /// By default, performs semantic analysis to build the new statement.
1508 /// Subclasses may override this routine to provide different behavior.
1509 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1510 LabelDecl *Label) {
1511 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1512 }
1513
1514 /// Build a new indirect goto statement.
1515 ///
1516 /// By default, performs semantic analysis to build the new statement.
1517 /// Subclasses may override this routine to provide different behavior.
1518 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1519 SourceLocation StarLoc,
1520 Expr *Target) {
1521 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1522 }
1523
1524 /// Build a new return statement.
1525 ///
1526 /// By default, performs semantic analysis to build the new statement.
1527 /// Subclasses may override this routine to provide different behavior.
1528 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1529 return getSema().BuildReturnStmt(ReturnLoc, Result);
1530 }
1531
1532 /// Build a new declaration statement.
1533 ///
1534 /// By default, performs semantic analysis to build the new statement.
1535 /// Subclasses may override this routine to provide different behavior.
1536 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1537 SourceLocation StartLoc, SourceLocation EndLoc) {
1538 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1539 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1540 }
1541
1542 /// Build a new inline asm statement.
1543 ///
1544 /// By default, performs semantic analysis to build the new statement.
1545 /// Subclasses may override this routine to provide different behavior.
1546 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1547 bool IsVolatile, unsigned NumOutputs,
1548 unsigned NumInputs, IdentifierInfo **Names,
1549 MultiExprArg Constraints, MultiExprArg Exprs,
1550 Expr *AsmString, MultiExprArg Clobbers,
1551 unsigned NumLabels,
1552 SourceLocation RParenLoc) {
1553 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1554 NumInputs, Names, Constraints, Exprs,
1555 AsmString, Clobbers, NumLabels, RParenLoc);
1556 }
1557
1558 /// Build a new MS style inline asm statement.
1559 ///
1560 /// By default, performs semantic analysis to build the new statement.
1561 /// Subclasses may override this routine to provide different behavior.
1562 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1563 ArrayRef<Token> AsmToks,
1564 StringRef AsmString,
1565 unsigned NumOutputs, unsigned NumInputs,
1566 ArrayRef<StringRef> Constraints,
1567 ArrayRef<StringRef> Clobbers,
1568 ArrayRef<Expr*> Exprs,
1569 SourceLocation EndLoc) {
1570 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1571 NumOutputs, NumInputs,
1572 Constraints, Clobbers, Exprs, EndLoc);
1573 }
1574
1575 /// Build a new co_return statement.
1576 ///
1577 /// By default, performs semantic analysis to build the new statement.
1578 /// Subclasses may override this routine to provide different behavior.
1579 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1580 bool IsImplicit) {
1581 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1582 }
1583
1584 /// Build a new co_await expression.
1585 ///
1586 /// By default, performs semantic analysis to build the new expression.
1587 /// Subclasses may override this routine to provide different behavior.
1588 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1589 UnresolvedLookupExpr *OpCoawaitLookup,
1590 bool IsImplicit) {
1591 // This function rebuilds a coawait-expr given its operator.
1592 // For an explicit coawait-expr, the rebuild involves the full set
1593 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1594 // including calling await_transform().
1595 // For an implicit coawait-expr, we need to rebuild the "operator
1596 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1597 // This mirrors how the implicit CoawaitExpr is originally created
1598 // in Sema::ActOnCoroutineBodyStart().
1599 if (IsImplicit) {
1600 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1601 CoawaitLoc, Operand, OpCoawaitLookup);
1602 if (Suspend.isInvalid())
1603 return ExprError();
1604 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1605 Suspend.get(), true);
1606 }
1607
1608 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1609 OpCoawaitLookup);
1610 }
1611
1612 /// Build a new co_await expression.
1613 ///
1614 /// By default, performs semantic analysis to build the new expression.
1615 /// Subclasses may override this routine to provide different behavior.
1616 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1617 Expr *Result,
1618 UnresolvedLookupExpr *Lookup) {
1619 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1620 }
1621
1622 /// Build a new co_yield expression.
1623 ///
1624 /// By default, performs semantic analysis to build the new expression.
1625 /// Subclasses may override this routine to provide different behavior.
1626 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1627 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1628 }
1629
1630 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1631 return getSema().BuildCoroutineBodyStmt(Args);
1632 }
1633
1634 /// Build a new Objective-C \@try statement.
1635 ///
1636 /// By default, performs semantic analysis to build the new statement.
1637 /// Subclasses may override this routine to provide different behavior.
1638 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1639 Stmt *TryBody,
1640 MultiStmtArg CatchStmts,
1641 Stmt *Finally) {
1642 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1643 Finally);
1644 }
1645
1646 /// Rebuild an Objective-C exception declaration.
1647 ///
1648 /// By default, performs semantic analysis to build the new declaration.
1649 /// Subclasses may override this routine to provide different behavior.
1650 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1651 TypeSourceInfo *TInfo, QualType T) {
1652 return getSema().ObjC().BuildObjCExceptionDecl(
1653 TInfo, T, ExceptionDecl->getInnerLocStart(),
1654 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1655 }
1656
1657 /// Build a new Objective-C \@catch statement.
1658 ///
1659 /// By default, performs semantic analysis to build the new statement.
1660 /// Subclasses may override this routine to provide different behavior.
1661 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1662 SourceLocation RParenLoc,
1663 VarDecl *Var,
1664 Stmt *Body) {
1665 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1666 }
1667
1668 /// Build a new Objective-C \@finally statement.
1669 ///
1670 /// By default, performs semantic analysis to build the new statement.
1671 /// Subclasses may override this routine to provide different behavior.
1672 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1673 Stmt *Body) {
1674 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1675 }
1676
1677 /// Build a new Objective-C \@throw statement.
1678 ///
1679 /// By default, performs semantic analysis to build the new statement.
1680 /// Subclasses may override this routine to provide different behavior.
1681 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1682 Expr *Operand) {
1683 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1684 }
1685
1686 /// Build a new OpenMP Canonical loop.
1687 ///
1688 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1689 /// OMPCanonicalLoop.
1690 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1691 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1692 }
1693
1694 /// Build a new OpenMP executable directive.
1695 ///
1696 /// By default, performs semantic analysis to build the new statement.
1697 /// Subclasses may override this routine to provide different behavior.
1698 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1699 DeclarationNameInfo DirName,
1700 OpenMPDirectiveKind CancelRegion,
1701 ArrayRef<OMPClause *> Clauses,
1702 Stmt *AStmt, SourceLocation StartLoc,
1703 SourceLocation EndLoc) {
1704
1705 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1706 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1707 }
1708
1709 /// Build a new OpenMP informational directive.
1710 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1711 DeclarationNameInfo DirName,
1712 ArrayRef<OMPClause *> Clauses,
1713 Stmt *AStmt,
1714 SourceLocation StartLoc,
1715 SourceLocation EndLoc) {
1716
1717 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1718 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1719 }
1720
1721 /// Build a new OpenMP 'if' clause.
1722 ///
1723 /// By default, performs semantic analysis to build the new OpenMP clause.
1724 /// Subclasses may override this routine to provide different behavior.
1725 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1726 Expr *Condition, SourceLocation StartLoc,
1727 SourceLocation LParenLoc,
1728 SourceLocation NameModifierLoc,
1729 SourceLocation ColonLoc,
1730 SourceLocation EndLoc) {
1731 return getSema().OpenMP().ActOnOpenMPIfClause(
1732 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1733 EndLoc);
1734 }
1735
1736 /// Build a new OpenMP 'final' clause.
1737 ///
1738 /// By default, performs semantic analysis to build the new OpenMP clause.
1739 /// Subclasses may override this routine to provide different behavior.
1740 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1741 SourceLocation LParenLoc,
1742 SourceLocation EndLoc) {
1743 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1744 LParenLoc, EndLoc);
1745 }
1746
1747 /// Build a new OpenMP 'num_threads' clause.
1748 ///
1749 /// By default, performs semantic analysis to build the new OpenMP clause.
1750 /// Subclasses may override this routine to provide different behavior.
1751 OMPClause *RebuildOMPNumThreadsClause(
1752 ArrayRef<Expr *> VarList,
1753 OpenMPNumThreadsClauseModifier PrescriptivenessModifier,
1754 SourceLocation PrescriptivenessModifierLoc,
1755 OpenMPNumThreadsClauseModifier DimsModifier, Expr *DimsModifierExpr,
1756 SourceLocation DimsModifierLoc, SourceLocation StartLoc,
1757 SourceLocation LParenLoc, SourceLocation EndLoc) {
1758 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1759 VarList, PrescriptivenessModifier, PrescriptivenessModifierLoc,
1760 DimsModifier, DimsModifierExpr, DimsModifierLoc, StartLoc, LParenLoc,
1761 EndLoc);
1762 }
1763
1764 /// Build a new OpenMP 'safelen' clause.
1765 ///
1766 /// By default, performs semantic analysis to build the new OpenMP clause.
1767 /// Subclasses may override this routine to provide different behavior.
1768 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1769 SourceLocation LParenLoc,
1770 SourceLocation EndLoc) {
1771 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1772 EndLoc);
1773 }
1774
1775 /// Build a new OpenMP 'simdlen' clause.
1776 ///
1777 /// By default, performs semantic analysis to build the new OpenMP clause.
1778 /// Subclasses may override this routine to provide different behavior.
1779 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1780 SourceLocation LParenLoc,
1781 SourceLocation EndLoc) {
1782 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1783 EndLoc);
1784 }
1785
1786 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1787 SourceLocation StartLoc,
1788 SourceLocation LParenLoc,
1789 SourceLocation EndLoc) {
1790 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1791 EndLoc);
1792 }
1793
1794 OMPClause *RebuildOMPCountsClause(ArrayRef<Expr *> Counts,
1795 SourceLocation StartLoc,
1796 SourceLocation LParenLoc,
1797 SourceLocation EndLoc,
1798 std::optional<unsigned> FillIdx,
1799 SourceLocation FillLoc) {
1800 unsigned FillCount = FillIdx ? 1 : 0;
1801 return getSema().OpenMP().ActOnOpenMPCountsClause(
1802 Counts, StartLoc, LParenLoc, EndLoc, FillIdx, FillLoc, FillCount);
1803 }
1804
1805 /// Build a new OpenMP 'permutation' clause.
1806 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1807 SourceLocation StartLoc,
1808 SourceLocation LParenLoc,
1809 SourceLocation EndLoc) {
1810 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1811 LParenLoc, EndLoc);
1812 }
1813
1814 /// Build a new OpenMP 'full' clause.
1815 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1816 SourceLocation EndLoc) {
1817 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1818 }
1819
1820 /// Build a new OpenMP 'partial' clause.
1821 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1822 SourceLocation LParenLoc,
1823 SourceLocation EndLoc) {
1824 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1825 LParenLoc, EndLoc);
1826 }
1827
1828 /// Build a new OpenMP 'depth' clause.
1829 OMPClause *RebuildOMPDepthClause(Expr *Depth, SourceLocation StartLoc,
1830 SourceLocation LParenLoc,
1831 SourceLocation EndLoc) {
1832 return getSema().OpenMP().ActOnOpenMPDepthClause(Depth, StartLoc, LParenLoc,
1833 EndLoc);
1834 }
1835
1836 OMPClause *
1837 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1838 SourceLocation LParenLoc, SourceLocation FirstLoc,
1839 SourceLocation CountLoc, SourceLocation EndLoc) {
1840 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1841 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1842 }
1843
1844 /// Build a new OpenMP 'allocator' clause.
1845 ///
1846 /// By default, performs semantic analysis to build the new OpenMP clause.
1847 /// Subclasses may override this routine to provide different behavior.
1848 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1849 SourceLocation LParenLoc,
1850 SourceLocation EndLoc) {
1851 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1852 EndLoc);
1853 }
1854
1855 /// Build a new OpenMP 'collapse' clause.
1856 ///
1857 /// By default, performs semantic analysis to build the new OpenMP clause.
1858 /// Subclasses may override this routine to provide different behavior.
1859 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1860 SourceLocation LParenLoc,
1861 SourceLocation EndLoc) {
1862 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1863 LParenLoc, EndLoc);
1864 }
1865
1866 /// Build a new OpenMP 'default' clause.
1867 ///
1868 /// By default, performs semantic analysis to build the new OpenMP clause.
1869 /// Subclasses may override this routine to provide different behavior.
1870 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1871 OpenMPDefaultClauseVariableCategory VCKind,
1872 SourceLocation VCLoc,
1873 SourceLocation StartLoc,
1874 SourceLocation LParenLoc,
1875 SourceLocation EndLoc) {
1876 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1877 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1878 }
1879
1880 /// Build a new OpenMP 'proc_bind' clause.
1881 ///
1882 /// By default, performs semantic analysis to build the new OpenMP clause.
1883 /// Subclasses may override this routine to provide different behavior.
1884 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1885 SourceLocation KindKwLoc,
1886 SourceLocation StartLoc,
1887 SourceLocation LParenLoc,
1888 SourceLocation EndLoc) {
1889 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1890 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1891 }
1892 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1893 SourceLocation StartLoc,
1894 SourceLocation LParenLoc,
1895 SourceLocation EndLoc) {
1896 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1897 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1898 }
1899
1900 /// Build a new OpenMP 'schedule' clause.
1901 ///
1902 /// By default, performs semantic analysis to build the new OpenMP clause.
1903 /// Subclasses may override this routine to provide different behavior.
1904 OMPClause *RebuildOMPScheduleClause(
1905 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1906 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1907 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1908 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1909 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1910 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1911 CommaLoc, EndLoc);
1912 }
1913
1914 /// Build a new OpenMP 'ordered' clause.
1915 ///
1916 /// By default, performs semantic analysis to build the new OpenMP clause.
1917 /// Subclasses may override this routine to provide different behavior.
1918 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1919 SourceLocation EndLoc,
1920 SourceLocation LParenLoc, Expr *Num) {
1921 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1922 LParenLoc, Num);
1923 }
1924
1925 /// Build a new OpenMP 'nowait' clause.
1926 ///
1927 /// By default, performs semantic analysis to build the new OpenMP clause.
1928 /// Subclasses may override this routine to provide different behavior.
1929 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1930 SourceLocation LParenLoc,
1931 SourceLocation EndLoc) {
1932 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1933 LParenLoc, Condition);
1934 }
1935
1936 /// Build a new OpenMP 'private' clause.
1937 ///
1938 /// By default, performs semantic analysis to build the new OpenMP clause.
1939 /// Subclasses may override this routine to provide different behavior.
1940 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1941 SourceLocation StartLoc,
1942 SourceLocation LParenLoc,
1943 SourceLocation EndLoc) {
1944 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1945 LParenLoc, EndLoc);
1946 }
1947
1948 /// Build a new OpenMP 'firstprivate' clause.
1949 ///
1950 /// By default, performs semantic analysis to build the new OpenMP clause.
1951 /// Subclasses may override this routine to provide different behavior.
1952 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1953 SourceLocation StartLoc,
1954 SourceLocation LParenLoc,
1955 SourceLocation EndLoc) {
1956 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1957 LParenLoc, EndLoc);
1958 }
1959
1960 /// Build a new OpenMP 'lastprivate' clause.
1961 ///
1962 /// By default, performs semantic analysis to build the new OpenMP clause.
1963 /// Subclasses may override this routine to provide different behavior.
1964 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1965 OpenMPLastprivateModifier LPKind,
1966 SourceLocation LPKindLoc,
1967 SourceLocation ColonLoc,
1968 SourceLocation StartLoc,
1969 SourceLocation LParenLoc,
1970 SourceLocation EndLoc) {
1971 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1972 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1973 }
1974
1975 /// Build a new OpenMP 'shared' clause.
1976 ///
1977 /// By default, performs semantic analysis to build the new OpenMP clause.
1978 /// Subclasses may override this routine to provide different behavior.
1979 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1980 SourceLocation StartLoc,
1981 SourceLocation LParenLoc,
1982 SourceLocation EndLoc) {
1983 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1984 LParenLoc, EndLoc);
1985 }
1986
1987 /// Build a new OpenMP 'reduction' clause.
1988 ///
1989 /// By default, performs semantic analysis to build the new statement.
1990 /// Subclasses may override this routine to provide different behavior.
1991 OMPClause *RebuildOMPReductionClause(
1992 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1993 OpenMPOriginalSharingModifier OriginalSharingModifier,
1994 SourceLocation StartLoc, SourceLocation LParenLoc,
1995 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1996 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1997 const DeclarationNameInfo &ReductionId,
1998 ArrayRef<Expr *> UnresolvedReductions) {
1999 return getSema().OpenMP().ActOnOpenMPReductionClause(
2000 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
2001 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
2002 UnresolvedReductions);
2003 }
2004
2005 /// Build a new OpenMP 'task_reduction' clause.
2006 ///
2007 /// By default, performs semantic analysis to build the new statement.
2008 /// Subclasses may override this routine to provide different behavior.
2009 OMPClause *RebuildOMPTaskReductionClause(
2010 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2011 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
2012 CXXScopeSpec &ReductionIdScopeSpec,
2013 const DeclarationNameInfo &ReductionId,
2014 ArrayRef<Expr *> UnresolvedReductions) {
2015 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
2016 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2017 ReductionId, UnresolvedReductions);
2018 }
2019
2020 /// Build a new OpenMP 'in_reduction' clause.
2021 ///
2022 /// By default, performs semantic analysis to build the new statement.
2023 /// Subclasses may override this routine to provide different behavior.
2024 OMPClause *
2025 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2026 SourceLocation LParenLoc, SourceLocation ColonLoc,
2027 SourceLocation EndLoc,
2028 CXXScopeSpec &ReductionIdScopeSpec,
2029 const DeclarationNameInfo &ReductionId,
2030 ArrayRef<Expr *> UnresolvedReductions) {
2031 return getSema().OpenMP().ActOnOpenMPInReductionClause(
2032 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2033 ReductionId, UnresolvedReductions);
2034 }
2035
2036 /// Build a new OpenMP 'linear' clause.
2037 ///
2038 /// By default, performs semantic analysis to build the new OpenMP clause.
2039 /// Subclasses may override this routine to provide different behavior.
2040 OMPClause *RebuildOMPLinearClause(
2041 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2042 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2043 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2044 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2045 return getSema().OpenMP().ActOnOpenMPLinearClause(
2046 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2047 StepModifierLoc, EndLoc);
2048 }
2049
2050 /// Build a new OpenMP 'aligned' clause.
2051 ///
2052 /// By default, performs semantic analysis to build the new OpenMP clause.
2053 /// Subclasses may override this routine to provide different behavior.
2054 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2055 SourceLocation StartLoc,
2056 SourceLocation LParenLoc,
2057 SourceLocation ColonLoc,
2058 SourceLocation EndLoc) {
2059 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2060 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2061 }
2062
2063 /// Build a new OpenMP 'copyin' clause.
2064 ///
2065 /// By default, performs semantic analysis to build the new OpenMP clause.
2066 /// Subclasses may override this routine to provide different behavior.
2067 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2068 SourceLocation StartLoc,
2069 SourceLocation LParenLoc,
2070 SourceLocation EndLoc) {
2071 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2072 LParenLoc, EndLoc);
2073 }
2074
2075 /// Build a new OpenMP 'copyprivate' clause.
2076 ///
2077 /// By default, performs semantic analysis to build the new OpenMP clause.
2078 /// Subclasses may override this routine to provide different behavior.
2079 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2080 SourceLocation StartLoc,
2081 SourceLocation LParenLoc,
2082 SourceLocation EndLoc) {
2083 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2084 LParenLoc, EndLoc);
2085 }
2086
2087 /// Build a new OpenMP 'flush' pseudo clause.
2088 ///
2089 /// By default, performs semantic analysis to build the new OpenMP clause.
2090 /// Subclasses may override this routine to provide different behavior.
2091 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2092 SourceLocation StartLoc,
2093 SourceLocation LParenLoc,
2094 SourceLocation EndLoc) {
2095 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2096 LParenLoc, EndLoc);
2097 }
2098
2099 /// Build a new OpenMP 'depobj' pseudo clause.
2100 ///
2101 /// By default, performs semantic analysis to build the new OpenMP clause.
2102 /// Subclasses may override this routine to provide different behavior.
2103 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2104 SourceLocation LParenLoc,
2105 SourceLocation EndLoc) {
2106 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2107 LParenLoc, EndLoc);
2108 }
2109
2110 /// Build a new OpenMP 'depend' pseudo clause.
2111 ///
2112 /// By default, performs semantic analysis to build the new OpenMP clause.
2113 /// Subclasses may override this routine to provide different behavior.
2114 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2115 Expr *DepModifier, ArrayRef<Expr *> VarList,
2116 SourceLocation StartLoc,
2117 SourceLocation LParenLoc,
2118 SourceLocation EndLoc) {
2119 return getSema().OpenMP().ActOnOpenMPDependClause(
2120 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2121 }
2122
2123 /// Build a new OpenMP 'device' clause.
2124 ///
2125 /// By default, performs semantic analysis to build the new statement.
2126 /// Subclasses may override this routine to provide different behavior.
2127 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2128 Expr *Device, SourceLocation StartLoc,
2129 SourceLocation LParenLoc,
2130 SourceLocation ModifierLoc,
2131 SourceLocation EndLoc) {
2132 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2133 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2134 }
2135
2136 /// Build a new OpenMP 'map' clause.
2137 ///
2138 /// By default, performs semantic analysis to build the new OpenMP clause.
2139 /// Subclasses may override this routine to provide different behavior.
2140 OMPClause *RebuildOMPMapClause(
2141 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2142 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2143 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2144 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2145 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2146 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2147 return getSema().OpenMP().ActOnOpenMPMapClause(
2148 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2149 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2150 ColonLoc, VarList, Locs,
2151 /*NoDiagnose=*/false, UnresolvedMappers);
2152 }
2153
2154 /// Build a new OpenMP 'allocate' clause.
2155 ///
2156 /// By default, performs semantic analysis to build the new OpenMP clause.
2157 /// Subclasses may override this routine to provide different behavior.
2158 OMPClause *
2159 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2160 OpenMPAllocateClauseModifier FirstModifier,
2161 SourceLocation FirstModifierLoc,
2162 OpenMPAllocateClauseModifier SecondModifier,
2163 SourceLocation SecondModifierLoc,
2164 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2165 SourceLocation LParenLoc, SourceLocation ColonLoc,
2166 SourceLocation EndLoc) {
2167 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2168 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2169 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2170 }
2171
2172 /// Build a new OpenMP 'num_teams' clause.
2173 ///
2174 /// By default, performs semantic analysis to build the new statement.
2175 /// Subclasses may override this routine to provide different behavior.
2176 OMPClause *RebuildOMPNumTeamsClause(
2177 ArrayRef<Expr *> VarList, OpenMPNumTeamsClauseModifier Modifier,
2178 Expr *ModifierExpr, SourceLocation ModifierLoc,
2179 OpenMPNumTeamsClauseModifier ModifierExtra, Expr *ModifierExtraExpr,
2180 SourceLocation ModifierExtraLoc, SourceLocation StartLoc,
2181 SourceLocation LParenLoc, SourceLocation EndLoc) {
2182 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(
2183 VarList, Modifier, ModifierExpr, ModifierLoc, ModifierExtra,
2184 ModifierExtraExpr, ModifierExtraLoc, StartLoc, LParenLoc, EndLoc);
2185 }
2186
2187 /// Build a new OpenMP 'thread_limit' clause.
2188 ///
2189 /// By default, performs semantic analysis to build the new statement.
2190 /// Subclasses may override this routine to provide different behavior.
2191 OMPClause *RebuildOMPThreadLimitClause(
2192 ArrayRef<Expr *> VarList, OpenMPThreadLimitClauseModifier Modifier,
2193 Expr *ModifierExpr, SourceLocation ModifierLoc, SourceLocation StartLoc,
2194 SourceLocation LParenLoc, SourceLocation EndLoc) {
2195 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(
2196 VarList, Modifier, ModifierExpr, ModifierLoc, StartLoc, LParenLoc,
2197 EndLoc);
2198 }
2199
2200 /// Build a new OpenMP 'priority' clause.
2201 ///
2202 /// By default, performs semantic analysis to build the new statement.
2203 /// Subclasses may override this routine to provide different behavior.
2204 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2205 SourceLocation LParenLoc,
2206 SourceLocation EndLoc) {
2207 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2208 LParenLoc, EndLoc);
2209 }
2210
2211 /// Build a new OpenMP 'grainsize' clause.
2212 ///
2213 /// By default, performs semantic analysis to build the new statement.
2214 /// Subclasses may override this routine to provide different behavior.
2215 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2216 Expr *Device, SourceLocation StartLoc,
2217 SourceLocation LParenLoc,
2218 SourceLocation ModifierLoc,
2219 SourceLocation EndLoc) {
2220 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2221 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2222 }
2223
2224 /// Build a new OpenMP 'num_tasks' clause.
2225 ///
2226 /// By default, performs semantic analysis to build the new statement.
2227 /// Subclasses may override this routine to provide different behavior.
2228 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2229 Expr *NumTasks, SourceLocation StartLoc,
2230 SourceLocation LParenLoc,
2231 SourceLocation ModifierLoc,
2232 SourceLocation EndLoc) {
2233 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2234 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2235 }
2236
2237 /// Build a new OpenMP 'hint' clause.
2238 ///
2239 /// By default, performs semantic analysis to build the new statement.
2240 /// Subclasses may override this routine to provide different behavior.
2241 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2242 SourceLocation LParenLoc,
2243 SourceLocation EndLoc) {
2244 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2245 EndLoc);
2246 }
2247
2248 /// Build a new OpenMP 'detach' clause.
2249 ///
2250 /// By default, performs semantic analysis to build the new statement.
2251 /// Subclasses may override this routine to provide different behavior.
2252 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2253 SourceLocation LParenLoc,
2254 SourceLocation EndLoc) {
2255 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2256 EndLoc);
2257 }
2258
2259 /// Build a new OpenMP 'dist_schedule' 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 *
2264 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2265 Expr *ChunkSize, SourceLocation StartLoc,
2266 SourceLocation LParenLoc, SourceLocation KindLoc,
2267 SourceLocation CommaLoc, SourceLocation EndLoc) {
2268 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2269 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2270 }
2271
2272 /// Build a new OpenMP 'to' clause.
2273 ///
2274 /// By default, performs semantic analysis to build the new statement.
2275 /// Subclasses may override this routine to provide different behavior.
2276 OMPClause *
2277 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2278 ArrayRef<SourceLocation> MotionModifiersLoc,
2279 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2280 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2281 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2282 ArrayRef<Expr *> UnresolvedMappers) {
2283 return getSema().OpenMP().ActOnOpenMPToClause(
2284 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2285 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2286 UnresolvedMappers);
2287 }
2288
2289 /// Build a new OpenMP 'from' clause.
2290 ///
2291 /// By default, performs semantic analysis to build the new statement.
2292 /// Subclasses may override this routine to provide different behavior.
2293 OMPClause *
2294 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2295 ArrayRef<SourceLocation> MotionModifiersLoc,
2296 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2297 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2298 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2299 ArrayRef<Expr *> UnresolvedMappers) {
2300 return getSema().OpenMP().ActOnOpenMPFromClause(
2301 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2302 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2303 UnresolvedMappers);
2304 }
2305
2306 /// Build a new OpenMP 'use_device_ptr' clause.
2307 ///
2308 /// By default, performs semantic analysis to build the new OpenMP clause.
2309 /// Subclasses may override this routine to provide different behavior.
2310 OMPClause *RebuildOMPUseDevicePtrClause(
2311 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2312 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2313 SourceLocation FallbackModifierLoc) {
2314 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2315 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2316 }
2317
2318 /// Build a new OpenMP 'use_device_addr' clause.
2319 ///
2320 /// By default, performs semantic analysis to build the new OpenMP clause.
2321 /// Subclasses may override this routine to provide different behavior.
2322 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2323 const OMPVarListLocTy &Locs) {
2324 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2325 }
2326
2327 /// Build a new OpenMP 'is_device_ptr' clause.
2328 ///
2329 /// By default, performs semantic analysis to build the new OpenMP clause.
2330 /// Subclasses may override this routine to provide different behavior.
2331 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2332 const OMPVarListLocTy &Locs) {
2333 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2334 }
2335
2336 /// Build a new OpenMP 'has_device_addr' clause.
2337 ///
2338 /// By default, performs semantic analysis to build the new OpenMP clause.
2339 /// Subclasses may override this routine to provide different behavior.
2340 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2341 const OMPVarListLocTy &Locs) {
2342 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2343 }
2344
2345 /// Build a new OpenMP 'defaultmap' clause.
2346 ///
2347 /// By default, performs semantic analysis to build the new OpenMP clause.
2348 /// Subclasses may override this routine to provide different behavior.
2349 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2350 OpenMPDefaultmapClauseKind Kind,
2351 SourceLocation StartLoc,
2352 SourceLocation LParenLoc,
2353 SourceLocation MLoc,
2354 SourceLocation KindLoc,
2355 SourceLocation EndLoc) {
2356 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2357 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2358 }
2359
2360 /// Build a new OpenMP 'nontemporal' clause.
2361 ///
2362 /// By default, performs semantic analysis to build the new OpenMP clause.
2363 /// Subclasses may override this routine to provide different behavior.
2364 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2365 SourceLocation StartLoc,
2366 SourceLocation LParenLoc,
2367 SourceLocation EndLoc) {
2368 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2369 LParenLoc, EndLoc);
2370 }
2371
2372 /// Build a new OpenMP 'inclusive' clause.
2373 ///
2374 /// By default, performs semantic analysis to build the new OpenMP clause.
2375 /// Subclasses may override this routine to provide different behavior.
2376 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2377 SourceLocation StartLoc,
2378 SourceLocation LParenLoc,
2379 SourceLocation EndLoc) {
2380 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2381 LParenLoc, EndLoc);
2382 }
2383
2384 /// Build a new OpenMP 'exclusive' clause.
2385 ///
2386 /// By default, performs semantic analysis to build the new OpenMP clause.
2387 /// Subclasses may override this routine to provide different behavior.
2388 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2389 SourceLocation StartLoc,
2390 SourceLocation LParenLoc,
2391 SourceLocation EndLoc) {
2392 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2393 LParenLoc, EndLoc);
2394 }
2395
2396 /// Build a new OpenMP 'uses_allocators' clause.
2397 ///
2398 /// By default, performs semantic analysis to build the new OpenMP clause.
2399 /// Subclasses may override this routine to provide different behavior.
2400 OMPClause *RebuildOMPUsesAllocatorsClause(
2401 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2402 SourceLocation LParenLoc, SourceLocation EndLoc) {
2403 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2404 StartLoc, LParenLoc, EndLoc, Data);
2405 }
2406
2407 /// Build a new OpenMP 'affinity' clause.
2408 ///
2409 /// By default, performs semantic analysis to build the new OpenMP clause.
2410 /// Subclasses may override this routine to provide different behavior.
2411 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2412 SourceLocation LParenLoc,
2413 SourceLocation ColonLoc,
2414 SourceLocation EndLoc, Expr *Modifier,
2415 ArrayRef<Expr *> Locators) {
2416 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2417 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2418 }
2419
2420 /// Build a new OpenMP 'order' 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 *RebuildOMPOrderClause(
2425 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2426 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2427 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2428 return getSema().OpenMP().ActOnOpenMPOrderClause(
2429 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2430 }
2431
2432 /// Build a new OpenMP 'init' 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 *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2437 SourceLocation StartLoc,
2438 SourceLocation LParenLoc,
2439 SourceLocation VarLoc,
2440 SourceLocation EndLoc) {
2441 return getSema().OpenMP().ActOnOpenMPInitClause(
2442 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2443 }
2444
2445 /// Build a new OpenMP 'use' 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 *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2450 SourceLocation LParenLoc,
2451 SourceLocation VarLoc, SourceLocation EndLoc) {
2452 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2453 LParenLoc, VarLoc, EndLoc);
2454 }
2455
2456 /// Build a new OpenMP 'destroy' clause.
2457 ///
2458 /// By default, performs semantic analysis to build the new OpenMP clause.
2459 /// Subclasses may override this routine to provide different behavior.
2460 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2461 SourceLocation LParenLoc,
2462 SourceLocation VarLoc,
2463 SourceLocation EndLoc) {
2464 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2465 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2466 }
2467
2468 /// Build a new OpenMP 'novariants' clause.
2469 ///
2470 /// By default, performs semantic analysis to build the new OpenMP clause.
2471 /// Subclasses may override this routine to provide different behavior.
2472 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2473 SourceLocation StartLoc,
2474 SourceLocation LParenLoc,
2475 SourceLocation EndLoc) {
2476 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2477 LParenLoc, EndLoc);
2478 }
2479
2480 /// Build a new OpenMP 'nocontext' clause.
2481 ///
2482 /// By default, performs semantic analysis to build the new OpenMP clause.
2483 /// Subclasses may override this routine to provide different behavior.
2484 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2485 SourceLocation LParenLoc,
2486 SourceLocation EndLoc) {
2487 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2488 LParenLoc, EndLoc);
2489 }
2490
2491 /// Build a new OpenMP 'filter' clause.
2492 ///
2493 /// By default, performs semantic analysis to build the new OpenMP clause.
2494 /// Subclasses may override this routine to provide different behavior.
2495 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2496 SourceLocation LParenLoc,
2497 SourceLocation EndLoc) {
2498 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2499 LParenLoc, EndLoc);
2500 }
2501
2502 /// Build a new OpenMP 'bind' clause.
2503 ///
2504 /// By default, performs semantic analysis to build the new OpenMP clause.
2505 /// Subclasses may override this routine to provide different behavior.
2506 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2507 SourceLocation KindLoc,
2508 SourceLocation StartLoc,
2509 SourceLocation LParenLoc,
2510 SourceLocation EndLoc) {
2511 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2512 LParenLoc, EndLoc);
2513 }
2514
2515 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2516 ///
2517 /// By default, performs semantic analysis to build the new OpenMP clause.
2518 /// Subclasses may override this routine to provide different behavior.
2519 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2520 SourceLocation LParenLoc,
2521 SourceLocation EndLoc) {
2522 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2523 LParenLoc, EndLoc);
2524 }
2525
2526 /// Build a new OpenMP 'dyn_groupprivate' clause.
2527 ///
2528 /// By default, performs semantic analysis to build the new OpenMP clause.
2529 /// Subclasses may override this routine to provide different behavior.
2530 OMPClause *RebuildOMPDynGroupprivateClause(
2531 OpenMPDynGroupprivateClauseModifier M1,
2532 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2533 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2534 SourceLocation M2Loc, SourceLocation EndLoc) {
2535 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2536 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2537 }
2538
2539 /// Build a new OpenMP 'ompx_attribute' clause.
2540 ///
2541 /// By default, performs semantic analysis to build the new OpenMP clause.
2542 /// Subclasses may override this routine to provide different behavior.
2543 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2544 SourceLocation StartLoc,
2545 SourceLocation LParenLoc,
2546 SourceLocation EndLoc) {
2547 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2548 LParenLoc, EndLoc);
2549 }
2550
2551 /// Build a new OpenMP 'ompx_bare' clause.
2552 ///
2553 /// By default, performs semantic analysis to build the new OpenMP clause.
2554 /// Subclasses may override this routine to provide different behavior.
2555 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2556 SourceLocation EndLoc) {
2557 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2558 }
2559
2560 /// Build a new OpenMP 'align' clause.
2561 ///
2562 /// By default, performs semantic analysis to build the new OpenMP clause.
2563 /// Subclasses may override this routine to provide different behavior.
2564 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2565 SourceLocation LParenLoc,
2566 SourceLocation EndLoc) {
2567 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2568 EndLoc);
2569 }
2570
2571 /// Build a new OpenMP 'at' clause.
2572 ///
2573 /// By default, performs semantic analysis to build the new OpenMP clause.
2574 /// Subclasses may override this routine to provide different behavior.
2575 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2576 SourceLocation StartLoc,
2577 SourceLocation LParenLoc,
2578 SourceLocation EndLoc) {
2579 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2580 LParenLoc, EndLoc);
2581 }
2582
2583 /// Build a new OpenMP 'severity' clause.
2584 ///
2585 /// By default, performs semantic analysis to build the new OpenMP clause.
2586 /// Subclasses may override this routine to provide different behavior.
2587 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2588 SourceLocation KwLoc,
2589 SourceLocation StartLoc,
2590 SourceLocation LParenLoc,
2591 SourceLocation EndLoc) {
2592 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2593 LParenLoc, EndLoc);
2594 }
2595
2596 /// Build a new OpenMP 'message' clause.
2597 ///
2598 /// By default, performs semantic analysis to build the new OpenMP clause.
2599 /// Subclasses may override this routine to provide different behavior.
2600 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2601 SourceLocation LParenLoc,
2602 SourceLocation EndLoc) {
2603 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2604 EndLoc);
2605 }
2606
2607 /// Build a new OpenMP 'doacross' clause.
2608 ///
2609 /// By default, performs semantic analysis to build the new OpenMP clause.
2610 /// Subclasses may override this routine to provide different behavior.
2611 OMPClause *
2612 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2613 SourceLocation DepLoc, SourceLocation ColonLoc,
2614 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2615 SourceLocation LParenLoc, SourceLocation EndLoc) {
2616 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2617 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2618 }
2619
2620 /// Build a new OpenMP 'holds' clause.
2621 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2622 SourceLocation LParenLoc,
2623 SourceLocation EndLoc) {
2624 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2625 EndLoc);
2626 }
2627
2628 /// Rebuild the operand to an Objective-C \@synchronized statement.
2629 ///
2630 /// By default, performs semantic analysis to build the new statement.
2631 /// Subclasses may override this routine to provide different behavior.
2632 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2633 Expr *object) {
2634 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2635 }
2636
2637 /// Build a new Objective-C \@synchronized statement.
2638 ///
2639 /// By default, performs semantic analysis to build the new statement.
2640 /// Subclasses may override this routine to provide different behavior.
2641 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2642 Expr *Object, Stmt *Body) {
2643 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2644 }
2645
2646 /// Build a new Objective-C \@autoreleasepool statement.
2647 ///
2648 /// By default, performs semantic analysis to build the new statement.
2649 /// Subclasses may override this routine to provide different behavior.
2650 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2651 Stmt *Body) {
2652 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2653 }
2654
2655 /// Build a new Objective-C fast enumeration statement.
2656 ///
2657 /// By default, performs semantic analysis to build the new statement.
2658 /// Subclasses may override this routine to provide different behavior.
2659 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2660 Stmt *Element,
2661 Expr *Collection,
2662 SourceLocation RParenLoc,
2663 Stmt *Body) {
2664 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2665 ForLoc, Element, Collection, RParenLoc);
2666 if (ForEachStmt.isInvalid())
2667 return StmtError();
2668
2669 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2670 Body);
2671 }
2672
2673 /// Build a new C++ exception declaration.
2674 ///
2675 /// By default, performs semantic analysis to build the new decaration.
2676 /// Subclasses may override this routine to provide different behavior.
2677 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2678 TypeSourceInfo *Declarator,
2679 SourceLocation StartLoc,
2680 SourceLocation IdLoc,
2681 IdentifierInfo *Id) {
2682 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2683 StartLoc, IdLoc, Id);
2684 if (Var)
2685 getSema().CurContext->addDecl(Var);
2686 return Var;
2687 }
2688
2689 /// Build a new C++ catch statement.
2690 ///
2691 /// By default, performs semantic analysis to build the new statement.
2692 /// Subclasses may override this routine to provide different behavior.
2693 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2694 VarDecl *ExceptionDecl,
2695 Stmt *Handler) {
2696 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2697 Handler));
2698 }
2699
2700 /// Build a new C++ try statement.
2701 ///
2702 /// By default, performs semantic analysis to build the new statement.
2703 /// Subclasses may override this routine to provide different behavior.
2704 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2705 ArrayRef<Stmt *> Handlers) {
2706 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2707 }
2708
2709 /// Build a new C++0x range-based for statement.
2710 ///
2711 /// By default, performs semantic analysis to build the new statement.
2712 /// Subclasses may override this routine to provide different behavior.
2713 StmtResult RebuildCXXForRangeStmt(
2714 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2715 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2716 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2717 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2718 // If we've just learned that the range is actually an Objective-C
2719 // collection, treat this as an Objective-C fast enumeration loop.
2720 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2721 if (RangeStmt->isSingleDecl()) {
2722 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2723 if (RangeVar->isInvalidDecl())
2724 return StmtError();
2725
2726 Expr *RangeExpr = RangeVar->getInit();
2727 if (!RangeExpr->isTypeDependent() &&
2728 RangeExpr->getType()->isObjCObjectPointerType()) {
2729 // FIXME: Support init-statements in Objective-C++20 ranged for
2730 // statement.
2731 if (Init) {
2732 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2733 DiagID: diag::err_objc_for_range_init_stmt)
2734 << Init->getSourceRange();
2735 }
2736 return getSema().ObjC().ActOnObjCForCollectionStmt(
2737 ForLoc, LoopVar, RangeExpr, RParenLoc);
2738 }
2739 }
2740 }
2741 }
2742
2743 return getSema().BuildCXXForRangeStmt(
2744 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2745 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2746 }
2747
2748 /// Build a new C++0x range-based for statement.
2749 ///
2750 /// By default, performs semantic analysis to build the new statement.
2751 /// Subclasses may override this routine to provide different behavior.
2752 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2753 bool IsIfExists,
2754 NestedNameSpecifierLoc QualifierLoc,
2755 DeclarationNameInfo NameInfo,
2756 Stmt *Nested) {
2757 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2758 QualifierLoc, NameInfo, Nested);
2759 }
2760
2761 /// Attach body to a C++0x range-based for statement.
2762 ///
2763 /// By default, performs semantic analysis to finish the new statement.
2764 /// Subclasses may override this routine to provide different behavior.
2765 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2766 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2767 }
2768
2769 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2770 Stmt *TryBlock, Stmt *Handler) {
2771 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2772 }
2773
2774 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2775 Stmt *Block) {
2776 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2777 }
2778
2779 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2780 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2781 }
2782
2783 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2784 SourceLocation LParen,
2785 SourceLocation RParen,
2786 TypeSourceInfo *TSI) {
2787 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2788 TSI);
2789 }
2790
2791 /// Build a new predefined expression.
2792 ///
2793 /// By default, performs semantic analysis to build the new expression.
2794 /// Subclasses may override this routine to provide different behavior.
2795 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2796 return getSema().BuildPredefinedExpr(Loc, IK);
2797 }
2798
2799 /// Build a new expression that references a declaration.
2800 ///
2801 /// By default, performs semantic analysis to build the new expression.
2802 /// Subclasses may override this routine to provide different behavior.
2803 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2804 LookupResult &R,
2805 bool RequiresADL) {
2806 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2807 }
2808
2809
2810 /// Build a new expression that references a declaration.
2811 ///
2812 /// By default, performs semantic analysis to build the new expression.
2813 /// Subclasses may override this routine to provide different behavior.
2814 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2815 ValueDecl *VD,
2816 const DeclarationNameInfo &NameInfo,
2817 NamedDecl *Found,
2818 TemplateArgumentListInfo *TemplateArgs) {
2819 CXXScopeSpec SS;
2820 SS.Adopt(Other: QualifierLoc);
2821 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2822 TemplateArgs);
2823 }
2824
2825 /// Build a new expression in parentheses.
2826 ///
2827 /// By default, performs semantic analysis to build the new expression.
2828 /// Subclasses may override this routine to provide different behavior.
2829 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2830 SourceLocation RParen) {
2831 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2832 }
2833
2834 /// Build a new pseudo-destructor expression.
2835 ///
2836 /// By default, performs semantic analysis to build the new expression.
2837 /// Subclasses may override this routine to provide different behavior.
2838 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2839 SourceLocation OperatorLoc,
2840 bool isArrow,
2841 CXXScopeSpec &SS,
2842 TypeSourceInfo *ScopeType,
2843 SourceLocation CCLoc,
2844 SourceLocation TildeLoc,
2845 PseudoDestructorTypeStorage Destroyed);
2846
2847 /// Build a new unary operator expression.
2848 ///
2849 /// By default, performs semantic analysis to build the new expression.
2850 /// Subclasses may override this routine to provide different behavior.
2851 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2852 UnaryOperatorKind Opc,
2853 Expr *SubExpr) {
2854 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2855 }
2856
2857 /// Build a new builtin offsetof expression.
2858 ///
2859 /// By default, performs semantic analysis to build the new expression.
2860 /// Subclasses may override this routine to provide different behavior.
2861 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2862 TypeSourceInfo *Type, const Designation &Desig,
2863 SourceLocation RParenLoc) {
2864 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Desig, RParenLoc);
2865 }
2866
2867 /// Build a new sizeof, alignof or vec_step expression with a
2868 /// type argument.
2869 ///
2870 /// By default, performs semantic analysis to build the new expression.
2871 /// Subclasses may override this routine to provide different behavior.
2872 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2873 SourceLocation OpLoc,
2874 UnaryExprOrTypeTrait ExprKind,
2875 SourceRange R) {
2876 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2877 }
2878
2879 /// Build a new sizeof, alignof or vec step expression with an
2880 /// expression argument.
2881 ///
2882 /// By default, performs semantic analysis to build the new expression.
2883 /// Subclasses may override this routine to provide different behavior.
2884 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2885 UnaryExprOrTypeTrait ExprKind,
2886 SourceRange R) {
2887 ExprResult Result
2888 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2889 if (Result.isInvalid())
2890 return ExprError();
2891
2892 return Result;
2893 }
2894
2895 /// Build a new array subscript expression.
2896 ///
2897 /// By default, performs semantic analysis to build the new expression.
2898 /// Subclasses may override this routine to provide different behavior.
2899 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2900 SourceLocation LBracketLoc,
2901 Expr *RHS,
2902 SourceLocation RBracketLoc) {
2903 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2904 LBracketLoc, RHS,
2905 RBracketLoc);
2906 }
2907
2908 /// Build a new matrix single subscript expression.
2909 ///
2910 /// By default, performs semantic analysis to build the new expression.
2911 /// Subclasses may override this routine to provide different behavior.
2912 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2913 SourceLocation RBracketLoc) {
2914 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2915 RBracketLoc);
2916 }
2917
2918 /// Build a new matrix subscript expression.
2919 ///
2920 /// By default, performs semantic analysis to build the new expression.
2921 /// Subclasses may override this routine to provide different behavior.
2922 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2923 Expr *ColumnIdx,
2924 SourceLocation RBracketLoc) {
2925 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2926 RBracketLoc);
2927 }
2928
2929 /// Build a new array section expression.
2930 ///
2931 /// By default, performs semantic analysis to build the new expression.
2932 /// Subclasses may override this routine to provide different behavior.
2933 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2934 SourceLocation LBracketLoc,
2935 Expr *LowerBound,
2936 SourceLocation ColonLocFirst,
2937 SourceLocation ColonLocSecond,
2938 Expr *Length, Expr *Stride,
2939 SourceLocation RBracketLoc) {
2940 if (IsOMPArraySection)
2941 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2942 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2943 Stride, RBracketLoc);
2944
2945 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2946 "Stride/second colon not allowed for OpenACC");
2947
2948 return getSema().OpenACC().ActOnArraySectionExpr(
2949 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2950 }
2951
2952 /// Build a new array shaping expression.
2953 ///
2954 /// By default, performs semantic analysis to build the new expression.
2955 /// Subclasses may override this routine to provide different behavior.
2956 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2957 SourceLocation RParenLoc,
2958 ArrayRef<Expr *> Dims,
2959 ArrayRef<SourceRange> BracketsRanges) {
2960 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2961 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2962 }
2963
2964 /// Build a new iterator expression.
2965 ///
2966 /// By default, performs semantic analysis to build the new expression.
2967 /// Subclasses may override this routine to provide different behavior.
2968 ExprResult
2969 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2970 SourceLocation RLoc,
2971 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2972 return getSema().OpenMP().ActOnOMPIteratorExpr(
2973 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2974 }
2975
2976 /// Build a new call expression.
2977 ///
2978 /// By default, performs semantic analysis to build the new expression.
2979 /// Subclasses may override this routine to provide different behavior.
2980 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2981 MultiExprArg Args,
2982 SourceLocation RParenLoc,
2983 Expr *ExecConfig = nullptr) {
2984 return getSema().ActOnCallExpr(
2985 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2986 }
2987
2988 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2989 MultiExprArg Args,
2990 SourceLocation RParenLoc) {
2991 return getSema().ActOnArraySubscriptExpr(
2992 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2993 }
2994
2995 /// Build a new member access expression.
2996 ///
2997 /// By default, performs semantic analysis to build the new expression.
2998 /// Subclasses may override this routine to provide different behavior.
2999 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
3000 bool isArrow,
3001 NestedNameSpecifierLoc QualifierLoc,
3002 SourceLocation TemplateKWLoc,
3003 const DeclarationNameInfo &MemberNameInfo,
3004 ValueDecl *Member,
3005 NamedDecl *FoundDecl,
3006 const TemplateArgumentListInfo *ExplicitTemplateArgs,
3007 NamedDecl *FirstQualifierInScope) {
3008 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
3009 isArrow);
3010 if (!Member->getDeclName()) {
3011 // We have a reference to an unnamed field. This is always the
3012 // base of an anonymous struct/union member access, i.e. the
3013 // field is always of record type.
3014 assert(Member->getType()->isRecordType() &&
3015 "unnamed member not of record type?");
3016
3017 BaseResult =
3018 getSema().PerformObjectMemberConversion(BaseResult.get(),
3019 QualifierLoc.getNestedNameSpecifier(),
3020 FoundDecl, Member);
3021 if (BaseResult.isInvalid())
3022 return ExprError();
3023 Base = BaseResult.get();
3024
3025 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
3026 // from the AST, so we need to re-insert them if needed (since
3027 // `BuildFieldRefereneExpr()` doesn't do this).
3028 if (!isArrow && Base->isPRValue()) {
3029 BaseResult = getSema().TemporaryMaterializationConversion(Base);
3030 if (BaseResult.isInvalid())
3031 return ExprError();
3032 Base = BaseResult.get();
3033 }
3034
3035 CXXScopeSpec EmptySS;
3036 return getSema().BuildFieldReferenceExpr(
3037 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
3038 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
3039 MemberNameInfo);
3040 }
3041
3042 CXXScopeSpec SS;
3043 SS.Adopt(Other: QualifierLoc);
3044
3045 Base = BaseResult.get();
3046 if (Base->containsErrors())
3047 return ExprError();
3048
3049 QualType BaseType = Base->getType();
3050
3051 if (isArrow && !BaseType->isPointerType())
3052 return ExprError();
3053
3054 // FIXME: this involves duplicating earlier analysis in a lot of
3055 // cases; we should avoid this when possible.
3056 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3057 R.addDecl(D: FoundDecl);
3058 R.resolveKind();
3059
3060 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3061 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3062 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3063 ->getType()
3064 ->getPointeeType()
3065 ->getAsCXXRecordDecl()) {
3066 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3067 // In unevaluated contexts, an expression supposed to be a member access
3068 // might reference a member in an unrelated class.
3069 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3070 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3071 VK_LValue, Member->getLocation());
3072 }
3073 }
3074
3075 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3076 SS, TemplateKWLoc,
3077 FirstQualifierInScope,
3078 R, ExplicitTemplateArgs,
3079 /*S*/nullptr);
3080 }
3081
3082 /// Build a new binary operator expression.
3083 ///
3084 /// By default, performs semantic analysis to build the new expression.
3085 /// Subclasses may override this routine to provide different behavior.
3086 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3087 Expr *LHS, Expr *RHS,
3088 bool ForFoldExpression = false) {
3089 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3090 ForFoldExpression);
3091 }
3092
3093 /// Build a new rewritten operator expression.
3094 ///
3095 /// By default, performs semantic analysis to build the new expression.
3096 /// Subclasses may override this routine to provide different behavior.
3097 ExprResult RebuildCXXRewrittenBinaryOperator(
3098 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3099 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3100 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3101 RHS, /*RequiresADL*/false);
3102 }
3103
3104 /// Build a new conditional operator expression.
3105 ///
3106 /// By default, performs semantic analysis to build the new expression.
3107 /// Subclasses may override this routine to provide different behavior.
3108 ExprResult RebuildConditionalOperator(Expr *Cond,
3109 SourceLocation QuestionLoc,
3110 Expr *LHS,
3111 SourceLocation ColonLoc,
3112 Expr *RHS) {
3113 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3114 LHS, RHS);
3115 }
3116
3117 /// Build a new C-style cast expression.
3118 ///
3119 /// By default, performs semantic analysis to build the new expression.
3120 /// Subclasses may override this routine to provide different behavior.
3121 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3122 TypeSourceInfo *TInfo,
3123 SourceLocation RParenLoc,
3124 Expr *SubExpr) {
3125 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3126 SubExpr);
3127 }
3128
3129 /// Build a new compound literal expression.
3130 ///
3131 /// By default, performs semantic analysis to build the new expression.
3132 /// Subclasses may override this routine to provide different behavior.
3133 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3134 TypeSourceInfo *TInfo,
3135 SourceLocation RParenLoc,
3136 Expr *Init) {
3137 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3138 Init);
3139 }
3140
3141 /// Build a new extended vector or matrix element access expression.
3142 ///
3143 /// By default, performs semantic analysis to build the new expression.
3144 /// Subclasses may override this routine to provide different behavior.
3145 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3146 SourceLocation OpLoc,
3147 bool IsArrow,
3148 SourceLocation AccessorLoc,
3149 IdentifierInfo &Accessor) {
3150
3151 CXXScopeSpec SS;
3152 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3153 return getSema().BuildMemberReferenceExpr(
3154 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3155 /*FirstQualifierInScope*/ nullptr, NameInfo,
3156 /* TemplateArgs */ nullptr,
3157 /*S*/ nullptr);
3158 }
3159
3160 /// Build a new initializer list expression.
3161 ///
3162 /// By default, performs semantic analysis to build the new expression.
3163 /// Subclasses may override this routine to provide different behavior.
3164 ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits,
3165 SourceLocation RBraceLoc, bool IsExplicit) {
3166 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc, IsExplicit);
3167 }
3168
3169 /// Build a new designated initializer expression.
3170 ///
3171 /// By default, performs semantic analysis to build the new expression.
3172 /// Subclasses may override this routine to provide different behavior.
3173 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3174 MultiExprArg ArrayExprs,
3175 SourceLocation EqualOrColonLoc,
3176 bool GNUSyntax,
3177 Expr *Init) {
3178 ExprResult Result
3179 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3180 Init);
3181 if (Result.isInvalid())
3182 return ExprError();
3183
3184 return Result;
3185 }
3186
3187 /// Build a new value-initialized expression.
3188 ///
3189 /// By default, builds the implicit value initialization without performing
3190 /// any semantic analysis. Subclasses may override this routine to provide
3191 /// different behavior.
3192 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3193 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3194 }
3195
3196 /// Build a new \c va_arg expression.
3197 ///
3198 /// By default, performs semantic analysis to build the new expression.
3199 /// Subclasses may override this routine to provide different behavior.
3200 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3201 Expr *SubExpr, TypeSourceInfo *TInfo,
3202 SourceLocation RParenLoc) {
3203 return getSema().BuildVAArgExpr(BuiltinLoc,
3204 SubExpr, TInfo,
3205 RParenLoc);
3206 }
3207
3208 /// Build a new expression list in parentheses.
3209 ///
3210 /// By default, performs semantic analysis to build the new expression.
3211 /// Subclasses may override this routine to provide different behavior.
3212 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3213 MultiExprArg SubExprs,
3214 SourceLocation RParenLoc) {
3215 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3216 }
3217
3218 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3219 unsigned NumUserSpecifiedExprs,
3220 SourceLocation InitLoc,
3221 SourceLocation LParenLoc,
3222 SourceLocation RParenLoc) {
3223 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3224 InitLoc, LParenLoc, RParenLoc);
3225 }
3226
3227 /// Build a new address-of-label expression.
3228 ///
3229 /// By default, performs semantic analysis, using the name of the label
3230 /// rather than attempting to map the label statement itself.
3231 /// Subclasses may override this routine to provide different behavior.
3232 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3233 SourceLocation LabelLoc, LabelDecl *Label) {
3234 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3235 }
3236
3237 /// Build a new GNU statement expression.
3238 ///
3239 /// By default, performs semantic analysis to build the new expression.
3240 /// Subclasses may override this routine to provide different behavior.
3241 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3242 SourceLocation RParenLoc, unsigned TemplateDepth) {
3243 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3244 TemplateDepth);
3245 }
3246
3247 /// Build a new __builtin_choose_expr 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 RebuildChooseExpr(SourceLocation BuiltinLoc,
3252 Expr *Cond, Expr *LHS, Expr *RHS,
3253 SourceLocation RParenLoc) {
3254 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3255 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3256 RPLoc: RParenLoc);
3257 }
3258
3259 /// Build a new generic selection expression with an expression predicate.
3260 ///
3261 /// By default, performs semantic analysis to build the new expression.
3262 /// Subclasses may override this routine to provide different behavior.
3263 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3264 SourceLocation DefaultLoc,
3265 SourceLocation RParenLoc,
3266 Expr *ControllingExpr,
3267 ArrayRef<TypeSourceInfo *> Types,
3268 ArrayRef<Expr *> Exprs) {
3269 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3270 /*PredicateIsExpr=*/true,
3271 ControllingExpr, Types, Exprs);
3272 }
3273
3274 /// Build a new generic selection expression with a type predicate.
3275 ///
3276 /// By default, performs semantic analysis to build the new expression.
3277 /// Subclasses may override this routine to provide different behavior.
3278 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3279 SourceLocation DefaultLoc,
3280 SourceLocation RParenLoc,
3281 TypeSourceInfo *ControllingType,
3282 ArrayRef<TypeSourceInfo *> Types,
3283 ArrayRef<Expr *> Exprs) {
3284 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3285 /*PredicateIsExpr=*/false,
3286 ControllingType, Types, Exprs);
3287 }
3288
3289 /// Build a new overloaded operator call expression.
3290 ///
3291 /// By default, performs semantic analysis to build the new expression.
3292 /// The semantic analysis provides the behavior of template instantiation,
3293 /// copying with transformations that turn what looks like an overloaded
3294 /// operator call into a use of a builtin operator, performing
3295 /// argument-dependent lookup, etc. Subclasses may override this routine to
3296 /// provide different behavior.
3297 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3298 SourceLocation OpLoc,
3299 SourceLocation CalleeLoc,
3300 bool RequiresADL,
3301 const UnresolvedSetImpl &Functions,
3302 Expr *First, Expr *Second);
3303
3304 /// Build a new C++ "named" cast expression, such as static_cast or
3305 /// reinterpret_cast.
3306 ///
3307 /// By default, this routine dispatches to one of the more-specific routines
3308 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3309 /// Subclasses may override this routine to provide different behavior.
3310 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3311 Stmt::StmtClass Class,
3312 SourceLocation LAngleLoc,
3313 TypeSourceInfo *TInfo,
3314 SourceLocation RAngleLoc,
3315 SourceLocation LParenLoc,
3316 Expr *SubExpr,
3317 SourceLocation RParenLoc) {
3318 switch (Class) {
3319 case Stmt::CXXStaticCastExprClass:
3320 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3321 RAngleLoc, LParenLoc,
3322 SubExpr, RParenLoc);
3323
3324 case Stmt::CXXDynamicCastExprClass:
3325 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3326 RAngleLoc, LParenLoc,
3327 SubExpr, RParenLoc);
3328
3329 case Stmt::CXXReinterpretCastExprClass:
3330 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3331 RAngleLoc, LParenLoc,
3332 SubExpr,
3333 RParenLoc);
3334
3335 case Stmt::CXXConstCastExprClass:
3336 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3337 RAngleLoc, LParenLoc,
3338 SubExpr, RParenLoc);
3339
3340 case Stmt::CXXAddrspaceCastExprClass:
3341 return getDerived().RebuildCXXAddrspaceCastExpr(
3342 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3343
3344 default:
3345 llvm_unreachable("Invalid C++ named cast");
3346 }
3347 }
3348
3349 /// Build a new C++ static_cast expression.
3350 ///
3351 /// By default, performs semantic analysis to build the new expression.
3352 /// Subclasses may override this routine to provide different behavior.
3353 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3354 SourceLocation LAngleLoc,
3355 TypeSourceInfo *TInfo,
3356 SourceLocation RAngleLoc,
3357 SourceLocation LParenLoc,
3358 Expr *SubExpr,
3359 SourceLocation RParenLoc) {
3360 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3361 TInfo, SubExpr,
3362 SourceRange(LAngleLoc, RAngleLoc),
3363 SourceRange(LParenLoc, RParenLoc));
3364 }
3365
3366 /// Build a new C++ dynamic_cast expression.
3367 ///
3368 /// By default, performs semantic analysis to build the new expression.
3369 /// Subclasses may override this routine to provide different behavior.
3370 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3371 SourceLocation LAngleLoc,
3372 TypeSourceInfo *TInfo,
3373 SourceLocation RAngleLoc,
3374 SourceLocation LParenLoc,
3375 Expr *SubExpr,
3376 SourceLocation RParenLoc) {
3377 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3378 TInfo, SubExpr,
3379 SourceRange(LAngleLoc, RAngleLoc),
3380 SourceRange(LParenLoc, RParenLoc));
3381 }
3382
3383 /// Build a new C++ reinterpret_cast expression.
3384 ///
3385 /// By default, performs semantic analysis to build the new expression.
3386 /// Subclasses may override this routine to provide different behavior.
3387 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3388 SourceLocation LAngleLoc,
3389 TypeSourceInfo *TInfo,
3390 SourceLocation RAngleLoc,
3391 SourceLocation LParenLoc,
3392 Expr *SubExpr,
3393 SourceLocation RParenLoc) {
3394 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3395 TInfo, SubExpr,
3396 SourceRange(LAngleLoc, RAngleLoc),
3397 SourceRange(LParenLoc, RParenLoc));
3398 }
3399
3400 /// Build a new C++ const_cast expression.
3401 ///
3402 /// By default, performs semantic analysis to build the new expression.
3403 /// Subclasses may override this routine to provide different behavior.
3404 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3405 SourceLocation LAngleLoc,
3406 TypeSourceInfo *TInfo,
3407 SourceLocation RAngleLoc,
3408 SourceLocation LParenLoc,
3409 Expr *SubExpr,
3410 SourceLocation RParenLoc) {
3411 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3412 TInfo, SubExpr,
3413 SourceRange(LAngleLoc, RAngleLoc),
3414 SourceRange(LParenLoc, RParenLoc));
3415 }
3416
3417 ExprResult
3418 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3419 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3420 SourceLocation LParenLoc, Expr *SubExpr,
3421 SourceLocation RParenLoc) {
3422 return getSema().BuildCXXNamedCast(
3423 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3424 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3425 }
3426
3427 /// Build a new C++ functional-style cast expression.
3428 ///
3429 /// By default, performs semantic analysis to build the new expression.
3430 /// Subclasses may override this routine to provide different behavior.
3431 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3432 SourceLocation LParenLoc,
3433 Expr *Sub,
3434 SourceLocation RParenLoc,
3435 bool ListInitialization) {
3436 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3437 // CXXParenListInitExpr. Pass its expanded arguments so that the
3438 // CXXParenListInitExpr can be rebuilt.
3439 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3440 return getSema().BuildCXXTypeConstructExpr(
3441 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3442 RParenLoc, ListInitialization);
3443
3444 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3445 return getSema().BuildCXXTypeConstructExpr(
3446 TInfo, LParenLoc, PLE->getUserSpecifiedInitExprs(), RParenLoc,
3447 ListInitialization);
3448
3449 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3450 MultiExprArg(&Sub, 1), RParenLoc,
3451 ListInitialization);
3452 }
3453
3454 /// Build a new C++ __builtin_bit_cast expression.
3455 ///
3456 /// By default, performs semantic analysis to build the new expression.
3457 /// Subclasses may override this routine to provide different behavior.
3458 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3459 TypeSourceInfo *TSI, Expr *Sub,
3460 SourceLocation RParenLoc) {
3461 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3462 }
3463
3464 /// Build a new C++ typeid(type) expression.
3465 ///
3466 /// By default, performs semantic analysis to build the new expression.
3467 /// Subclasses may override this routine to provide different behavior.
3468 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3469 SourceLocation TypeidLoc,
3470 TypeSourceInfo *Operand,
3471 SourceLocation RParenLoc) {
3472 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3473 RParenLoc);
3474 }
3475
3476
3477 /// Build a new C++ typeid(expr) expression.
3478 ///
3479 /// By default, performs semantic analysis to build the new expression.
3480 /// Subclasses may override this routine to provide different behavior.
3481 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3482 SourceLocation TypeidLoc,
3483 Expr *Operand,
3484 SourceLocation RParenLoc) {
3485 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3486 RParenLoc);
3487 }
3488
3489 /// Build a new C++ __uuidof(type) expression.
3490 ///
3491 /// By default, performs semantic analysis to build the new expression.
3492 /// Subclasses may override this routine to provide different behavior.
3493 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3494 TypeSourceInfo *Operand,
3495 SourceLocation RParenLoc) {
3496 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3497 }
3498
3499 /// Build a new C++ __uuidof(expr) expression.
3500 ///
3501 /// By default, performs semantic analysis to build the new expression.
3502 /// Subclasses may override this routine to provide different behavior.
3503 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3504 Expr *Operand, SourceLocation RParenLoc) {
3505 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3506 }
3507
3508 /// Build a new C++ "this" expression.
3509 ///
3510 /// By default, performs semantic analysis to build a new "this" expression.
3511 /// Subclasses may override this routine to provide different behavior.
3512 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3513 QualType ThisType,
3514 bool isImplicit) {
3515 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3516 return ExprError();
3517 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3518 }
3519
3520 /// Build a new C++ throw expression.
3521 ///
3522 /// By default, performs semantic analysis to build the new expression.
3523 /// Subclasses may override this routine to provide different behavior.
3524 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3525 bool IsThrownVariableInScope) {
3526 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3527 }
3528
3529 /// Build a new C++ default-argument expression.
3530 ///
3531 /// By default, builds a new default-argument expression, which does not
3532 /// require any semantic analysis. Subclasses may override this routine to
3533 /// provide different behavior.
3534 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3535 Expr *RewrittenExpr) {
3536 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3537 RewrittenExpr, UsedContext: getSema().CurContext);
3538 }
3539
3540 /// Build a new C++11 default-initialization expression.
3541 ///
3542 /// By default, builds a new default field initialization expression, which
3543 /// does not require any semantic analysis. Subclasses may override this
3544 /// routine to provide different behavior.
3545 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field,
3546 Expr *RewrittenInit) {
3547 return CXXDefaultInitExpr::Create(Ctx: getSema().Context, Loc, Field,
3548 UsedContext: getSema().CurContext, RewrittenInitExpr: RewrittenInit);
3549 }
3550
3551 /// Build a new C++ zero-initialization 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 RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3556 SourceLocation LParenLoc,
3557 SourceLocation RParenLoc) {
3558 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3559 /*ListInitialization=*/false);
3560 }
3561
3562 /// Build a new C++ "new" expression.
3563 ///
3564 /// By default, performs semantic analysis to build the new expression.
3565 /// Subclasses may override this routine to provide different behavior.
3566 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3567 SourceLocation PlacementLParen,
3568 MultiExprArg PlacementArgs,
3569 SourceLocation PlacementRParen,
3570 SourceRange TypeIdParens, QualType AllocatedType,
3571 TypeSourceInfo *AllocatedTypeInfo,
3572 std::optional<Expr *> ArraySize,
3573 SourceRange DirectInitRange, Expr *Initializer) {
3574 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3575 PlacementLParen,
3576 PlacementArgs,
3577 PlacementRParen,
3578 TypeIdParens,
3579 AllocatedType,
3580 AllocatedTypeInfo,
3581 ArraySize,
3582 DirectInitRange,
3583 Initializer);
3584 }
3585
3586 /// Build a new C++ "delete" expression.
3587 ///
3588 /// By default, performs semantic analysis to build the new expression.
3589 /// Subclasses may override this routine to provide different behavior.
3590 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3591 bool IsGlobalDelete,
3592 bool IsArrayForm,
3593 Expr *Operand) {
3594 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3595 Operand);
3596 }
3597
3598 /// Build a new type trait expression.
3599 ///
3600 /// By default, performs semantic analysis to build the new expression.
3601 /// Subclasses may override this routine to provide different behavior.
3602 ExprResult RebuildTypeTrait(TypeTrait Trait,
3603 SourceLocation StartLoc,
3604 ArrayRef<TypeSourceInfo *> Args,
3605 SourceLocation RParenLoc) {
3606 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3607 }
3608
3609 /// Build a new array type trait expression.
3610 ///
3611 /// By default, performs semantic analysis to build the new expression.
3612 /// Subclasses may override this routine to provide different behavior.
3613 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3614 SourceLocation StartLoc,
3615 TypeSourceInfo *TSInfo,
3616 Expr *DimExpr,
3617 SourceLocation RParenLoc) {
3618 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3619 }
3620
3621 /// Build a new expression trait expression.
3622 ///
3623 /// By default, performs semantic analysis to build the new expression.
3624 /// Subclasses may override this routine to provide different behavior.
3625 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3626 SourceLocation StartLoc,
3627 Expr *Queried,
3628 SourceLocation RParenLoc) {
3629 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3630 }
3631
3632 /// Build a new (previously unresolved) declaration reference
3633 /// 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 RebuildDependentScopeDeclRefExpr(
3638 NestedNameSpecifierLoc QualifierLoc,
3639 SourceLocation TemplateKWLoc,
3640 const DeclarationNameInfo &NameInfo,
3641 const TemplateArgumentListInfo *TemplateArgs,
3642 bool IsAddressOfOperand,
3643 TypeSourceInfo **RecoveryTSI) {
3644 CXXScopeSpec SS;
3645 SS.Adopt(Other: QualifierLoc);
3646
3647 if (TemplateArgs || TemplateKWLoc.isValid())
3648 return getSema().BuildQualifiedTemplateIdExpr(
3649 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3650
3651 return getSema().BuildQualifiedDeclarationNameExpr(
3652 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3653 }
3654
3655 /// Build a new template-id expression.
3656 ///
3657 /// By default, performs semantic analysis to build the new expression.
3658 /// Subclasses may override this routine to provide different behavior.
3659 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3660 SourceLocation TemplateKWLoc,
3661 LookupResult &R,
3662 bool RequiresADL,
3663 const TemplateArgumentListInfo *TemplateArgs) {
3664 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3665 TemplateArgs);
3666 }
3667
3668 /// Build a new object-construction expression.
3669 ///
3670 /// By default, performs semantic analysis to build the new expression.
3671 /// Subclasses may override this routine to provide different behavior.
3672 ExprResult RebuildCXXConstructExpr(
3673 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3674 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3675 bool ListInitialization, bool StdInitListInitialization,
3676 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3677 SourceRange ParenRange) {
3678 // Reconstruct the constructor we originally found, which might be
3679 // different if this is a call to an inherited constructor.
3680 CXXConstructorDecl *FoundCtor = Constructor;
3681 if (Constructor->isInheritingConstructor())
3682 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3683
3684 SmallVector<Expr *, 8> ConvertedArgs;
3685 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3686 ConvertedArgs))
3687 return ExprError();
3688
3689 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3690 IsElidable,
3691 ConvertedArgs,
3692 HadMultipleCandidates,
3693 ListInitialization,
3694 StdInitListInitialization,
3695 RequiresZeroInit, ConstructKind,
3696 ParenRange);
3697 }
3698
3699 /// Build a new implicit construction via inherited constructor
3700 /// expression.
3701 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3702 CXXConstructorDecl *Constructor,
3703 bool ConstructsVBase,
3704 bool InheritedFromVBase) {
3705 return new (getSema().Context) CXXInheritedCtorInitExpr(
3706 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3707 }
3708
3709 /// Build a new object-construction expression.
3710 ///
3711 /// By default, performs semantic analysis to build the new expression.
3712 /// Subclasses may override this routine to provide different behavior.
3713 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3714 SourceLocation LParenOrBraceLoc,
3715 MultiExprArg Args,
3716 SourceLocation RParenOrBraceLoc,
3717 bool ListInitialization) {
3718 return getSema().BuildCXXTypeConstructExpr(
3719 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3720 }
3721
3722 /// Build a new object-construction expression.
3723 ///
3724 /// By default, performs semantic analysis to build the new expression.
3725 /// Subclasses may override this routine to provide different behavior.
3726 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3727 SourceLocation LParenLoc,
3728 MultiExprArg Args,
3729 SourceLocation RParenLoc,
3730 bool ListInitialization) {
3731 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3732 RParenLoc, ListInitialization);
3733 }
3734
3735 /// Build a new member reference expression.
3736 ///
3737 /// By default, performs semantic analysis to build the new expression.
3738 /// Subclasses may override this routine to provide different behavior.
3739 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3740 QualType BaseType,
3741 bool IsArrow,
3742 SourceLocation OperatorLoc,
3743 NestedNameSpecifierLoc QualifierLoc,
3744 SourceLocation TemplateKWLoc,
3745 NamedDecl *FirstQualifierInScope,
3746 const DeclarationNameInfo &MemberNameInfo,
3747 const TemplateArgumentListInfo *TemplateArgs) {
3748 CXXScopeSpec SS;
3749 SS.Adopt(Other: QualifierLoc);
3750
3751 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3752 OpLoc: OperatorLoc, IsArrow,
3753 SS, TemplateKWLoc,
3754 FirstQualifierInScope,
3755 NameInfo: MemberNameInfo,
3756 TemplateArgs, /*S*/S: nullptr);
3757 }
3758
3759 /// Build a new member reference expression.
3760 ///
3761 /// By default, performs semantic analysis to build the new expression.
3762 /// Subclasses may override this routine to provide different behavior.
3763 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3764 SourceLocation OperatorLoc,
3765 bool IsArrow,
3766 NestedNameSpecifierLoc QualifierLoc,
3767 SourceLocation TemplateKWLoc,
3768 NamedDecl *FirstQualifierInScope,
3769 LookupResult &R,
3770 const TemplateArgumentListInfo *TemplateArgs) {
3771 CXXScopeSpec SS;
3772 SS.Adopt(Other: QualifierLoc);
3773
3774 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3775 OpLoc: OperatorLoc, IsArrow,
3776 SS, TemplateKWLoc,
3777 FirstQualifierInScope,
3778 R, TemplateArgs, /*S*/S: nullptr);
3779 }
3780
3781 /// Build a new noexcept expression.
3782 ///
3783 /// By default, performs semantic analysis to build the new expression.
3784 /// Subclasses may override this routine to provide different behavior.
3785 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3786 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3787 }
3788
3789 UnsignedOrNone
3790 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3791
3792 /// Build a new expression to compute the length of a parameter pack.
3793 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3794 SourceLocation PackLoc,
3795 SourceLocation RParenLoc,
3796 UnsignedOrNone Length,
3797 ArrayRef<TemplateArgument> PartialArgs) {
3798 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3799 RParenLoc, Length, PartialArgs);
3800 }
3801
3802 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3803 SourceLocation RSquareLoc,
3804 Expr *PackIdExpression, Expr *IndexExpr,
3805 ArrayRef<Expr *> ExpandedExprs,
3806 bool FullySubstituted = false) {
3807 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3808 IndexExpr, RSquareLoc, ExpandedExprs,
3809 FullySubstituted);
3810 }
3811
3812 /// Build a new expression representing a call to a source location
3813 /// builtin.
3814 ///
3815 /// By default, performs semantic analysis to build the new expression.
3816 /// Subclasses may override this routine to provide different behavior.
3817 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3818 SourceLocation BuiltinLoc,
3819 SourceLocation RPLoc,
3820 DeclContext *ParentContext) {
3821 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3822 ParentContext);
3823 }
3824
3825 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3826 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3827 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3828 TemplateArgumentListInfo *TALI) {
3829 CXXScopeSpec SS;
3830 SS.Adopt(Other: NNS);
3831 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3832 ConceptNameInfo,
3833 FoundDecl,
3834 NamedConcept, TALI);
3835 if (Result.isInvalid())
3836 return ExprError();
3837 return Result;
3838 }
3839
3840 /// \brief Build a new requires expression.
3841 ///
3842 /// By default, performs semantic analysis to build the new expression.
3843 /// Subclasses may override this routine to provide different behavior.
3844 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3845 RequiresExprBodyDecl *Body,
3846 SourceLocation LParenLoc,
3847 ArrayRef<ParmVarDecl *> LocalParameters,
3848 SourceLocation RParenLoc,
3849 ArrayRef<concepts::Requirement *> Requirements,
3850 SourceLocation ClosingBraceLoc) {
3851 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3852 LocalParameters, RParenLoc, Requirements,
3853 RBraceLoc: ClosingBraceLoc);
3854 }
3855
3856 concepts::TypeRequirement *
3857 RebuildTypeRequirement(
3858 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3859 return SemaRef.BuildTypeRequirement(SubstDiag);
3860 }
3861
3862 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3863 return SemaRef.BuildTypeRequirement(Type: T);
3864 }
3865
3866 concepts::ExprRequirement *
3867 RebuildExprRequirement(
3868 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3869 SourceLocation NoexceptLoc,
3870 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3871 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3872 ReturnTypeRequirement: std::move(Ret));
3873 }
3874
3875 concepts::ExprRequirement *
3876 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3877 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3878 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3879 ReturnTypeRequirement: std::move(Ret));
3880 }
3881
3882 concepts::NestedRequirement *
3883 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3884 const ASTConstraintSatisfaction &Satisfaction) {
3885 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3886 Satisfaction);
3887 }
3888
3889 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3890 return SemaRef.BuildNestedRequirement(E: Constraint);
3891 }
3892
3893 /// \brief Build a new Objective-C boxed expression.
3894 ///
3895 /// By default, performs semantic analysis to build the new expression.
3896 /// Subclasses may override this routine to provide different behavior.
3897 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3898 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3899 }
3900
3901 /// Build a new Objective-C array literal.
3902 ///
3903 /// By default, performs semantic analysis to build the new expression.
3904 /// Subclasses may override this routine to provide different behavior.
3905 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3906 Expr **Elements, unsigned NumElements) {
3907 return getSema().ObjC().BuildObjCArrayLiteral(
3908 Range, MultiExprArg(Elements, NumElements));
3909 }
3910
3911 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3912 Expr *Base, Expr *Key,
3913 ObjCMethodDecl *getterMethod,
3914 ObjCMethodDecl *setterMethod) {
3915 return getSema().ObjC().BuildObjCSubscriptExpression(
3916 RB, Base, Key, getterMethod, setterMethod);
3917 }
3918
3919 /// Build a new Objective-C dictionary literal.
3920 ///
3921 /// By default, performs semantic analysis to build the new expression.
3922 /// Subclasses may override this routine to provide different behavior.
3923 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3924 MutableArrayRef<ObjCDictionaryElement> Elements) {
3925 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3926 }
3927
3928 /// Build a new Objective-C \@encode expression.
3929 ///
3930 /// By default, performs semantic analysis to build the new expression.
3931 /// Subclasses may override this routine to provide different behavior.
3932 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3933 TypeSourceInfo *EncodeTypeInfo,
3934 SourceLocation RParenLoc) {
3935 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3936 RParenLoc);
3937 }
3938
3939 /// Build a new Objective-C class message.
3940 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3941 Selector Sel,
3942 ArrayRef<SourceLocation> SelectorLocs,
3943 ObjCMethodDecl *Method,
3944 SourceLocation LBracLoc,
3945 MultiExprArg Args,
3946 SourceLocation RBracLoc) {
3947 return SemaRef.ObjC().BuildClassMessage(
3948 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3949 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3950 RBracLoc, Args);
3951 }
3952
3953 /// Build a new Objective-C instance message.
3954 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3955 Selector Sel,
3956 ArrayRef<SourceLocation> SelectorLocs,
3957 ObjCMethodDecl *Method,
3958 SourceLocation LBracLoc,
3959 MultiExprArg Args,
3960 SourceLocation RBracLoc) {
3961 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3962 /*SuperLoc=*/SuperLoc: SourceLocation(),
3963 Sel, Method, LBracLoc,
3964 SelectorLocs, RBracLoc, Args);
3965 }
3966
3967 /// Build a new Objective-C instance/class message to 'super'.
3968 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3969 Selector Sel,
3970 ArrayRef<SourceLocation> SelectorLocs,
3971 QualType SuperType,
3972 ObjCMethodDecl *Method,
3973 SourceLocation LBracLoc,
3974 MultiExprArg Args,
3975 SourceLocation RBracLoc) {
3976 return Method->isInstanceMethod()
3977 ? SemaRef.ObjC().BuildInstanceMessage(
3978 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3979 SelectorLocs, RBracLoc, Args)
3980 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3981 Sel, Method, LBracLoc,
3982 SelectorLocs, RBracLoc, Args);
3983 }
3984
3985 /// Build a new Objective-C ivar reference expression.
3986 ///
3987 /// By default, performs semantic analysis to build the new expression.
3988 /// Subclasses may override this routine to provide different behavior.
3989 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3990 SourceLocation IvarLoc,
3991 bool IsArrow, bool IsFreeIvar) {
3992 CXXScopeSpec SS;
3993 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3994 ExprResult Result = getSema().BuildMemberReferenceExpr(
3995 BaseArg, BaseArg->getType(),
3996 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3997 /*FirstQualifierInScope=*/nullptr, NameInfo,
3998 /*TemplateArgs=*/nullptr,
3999 /*S=*/nullptr);
4000 if (IsFreeIvar && Result.isUsable())
4001 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
4002 return Result;
4003 }
4004
4005 /// Build a new Objective-C property reference expression.
4006 ///
4007 /// By default, performs semantic analysis to build the new expression.
4008 /// Subclasses may override this routine to provide different behavior.
4009 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
4010 ObjCPropertyDecl *Property,
4011 SourceLocation PropertyLoc) {
4012 CXXScopeSpec SS;
4013 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
4014 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4015 /*FIXME:*/PropertyLoc,
4016 /*IsArrow=*/false,
4017 SS, SourceLocation(),
4018 /*FirstQualifierInScope=*/nullptr,
4019 NameInfo,
4020 /*TemplateArgs=*/nullptr,
4021 /*S=*/nullptr);
4022 }
4023
4024 /// Build a new Objective-C property reference expression.
4025 ///
4026 /// By default, performs semantic analysis to build the new expression.
4027 /// Subclasses may override this routine to provide different behavior.
4028 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
4029 ObjCMethodDecl *Getter,
4030 ObjCMethodDecl *Setter,
4031 SourceLocation PropertyLoc) {
4032 // Since these expressions can only be value-dependent, we do not
4033 // need to perform semantic analysis again.
4034 return Owned(
4035 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
4036 VK_LValue, OK_ObjCProperty,
4037 PropertyLoc, Base));
4038 }
4039
4040 /// Build a new Objective-C "isa" expression.
4041 ///
4042 /// By default, performs semantic analysis to build the new expression.
4043 /// Subclasses may override this routine to provide different behavior.
4044 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4045 SourceLocation OpLoc, bool IsArrow) {
4046 CXXScopeSpec SS;
4047 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4048 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4049 OpLoc, IsArrow,
4050 SS, SourceLocation(),
4051 /*FirstQualifierInScope=*/nullptr,
4052 NameInfo,
4053 /*TemplateArgs=*/nullptr,
4054 /*S=*/nullptr);
4055 }
4056
4057 /// Build a new shuffle vector expression.
4058 ///
4059 /// By default, performs semantic analysis to build the new expression.
4060 /// Subclasses may override this routine to provide different behavior.
4061 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4062 MultiExprArg SubExprs,
4063 SourceLocation RParenLoc) {
4064 // Find the declaration for __builtin_shufflevector
4065 const IdentifierInfo &Name
4066 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4067 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4068 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4069 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4070
4071 // Build a reference to the __builtin_shufflevector builtin
4072 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4073 Expr *Callee = new (SemaRef.Context)
4074 DeclRefExpr(SemaRef.Context, Builtin, false,
4075 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4076 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4077 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4078 CK: CK_BuiltinFnToFnPtr).get();
4079
4080 // Build the CallExpr
4081 ExprResult TheCall = CallExpr::Create(
4082 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4083 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4084 FPFeatures: FPOptionsOverride());
4085
4086 // Type-check the __builtin_shufflevector expression.
4087 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4088 }
4089
4090 /// Build a new convert vector expression.
4091 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4092 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4093 SourceLocation RParenLoc) {
4094 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4095 }
4096
4097 /// Build a new template argument pack expansion.
4098 ///
4099 /// By default, performs semantic analysis to build a new pack expansion
4100 /// for a template argument. Subclasses may override this routine to provide
4101 /// different behavior.
4102 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4103 SourceLocation EllipsisLoc,
4104 UnsignedOrNone NumExpansions) {
4105 switch (Pattern.getArgument().getKind()) {
4106 case TemplateArgument::Expression: {
4107 ExprResult Result
4108 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4109 EllipsisLoc, NumExpansions);
4110 if (Result.isInvalid())
4111 return TemplateArgumentLoc();
4112
4113 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4114 /*IsCanonical=*/false),
4115 Result.get());
4116 }
4117
4118 case TemplateArgument::Template:
4119 return TemplateArgumentLoc(
4120 SemaRef.Context,
4121 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4122 NumExpansions),
4123 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4124 Pattern.getTemplateNameLoc(), EllipsisLoc);
4125
4126 case TemplateArgument::Null:
4127 case TemplateArgument::Integral:
4128 case TemplateArgument::Declaration:
4129 case TemplateArgument::StructuralValue:
4130 case TemplateArgument::Pack:
4131 case TemplateArgument::TemplateExpansion:
4132 case TemplateArgument::NullPtr:
4133 llvm_unreachable("Pack expansion pattern has no parameter packs");
4134
4135 case TemplateArgument::Type:
4136 if (TypeSourceInfo *Expansion
4137 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4138 EllipsisLoc,
4139 NumExpansions))
4140 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4141 Expansion);
4142 break;
4143 }
4144
4145 return TemplateArgumentLoc();
4146 }
4147
4148 /// Build a new expression pack expansion.
4149 ///
4150 /// By default, performs semantic analysis to build a new pack expansion
4151 /// for an expression. Subclasses may override this routine to provide
4152 /// different behavior.
4153 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4154 UnsignedOrNone NumExpansions) {
4155 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4156 }
4157
4158 /// Build a new C++1z fold-expression.
4159 ///
4160 /// By default, performs semantic analysis in order to build a new fold
4161 /// expression.
4162 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4163 SourceLocation LParenLoc, Expr *LHS,
4164 BinaryOperatorKind Operator,
4165 SourceLocation EllipsisLoc, Expr *RHS,
4166 SourceLocation RParenLoc,
4167 UnsignedOrNone NumExpansions) {
4168 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4169 EllipsisLoc, RHS, RParenLoc,
4170 NumExpansions);
4171 }
4172
4173 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4174 LambdaScopeInfo *LSI) {
4175 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4176 if (Expr *Init = PVD->getInit())
4177 LSI->ContainsUnexpandedParameterPack |=
4178 Init->containsUnexpandedParameterPack();
4179 else if (PVD->hasUninstantiatedDefaultArg())
4180 LSI->ContainsUnexpandedParameterPack |=
4181 PVD->getUninstantiatedDefaultArg()
4182 ->containsUnexpandedParameterPack();
4183 }
4184 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4185 }
4186
4187 /// Build an empty C++1z fold-expression with the given operator.
4188 ///
4189 /// By default, produces the fallback value for the fold-expression, or
4190 /// produce an error if there is no fallback value.
4191 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4192 BinaryOperatorKind Operator) {
4193 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4194 }
4195
4196 /// Build a new atomic operation expression.
4197 ///
4198 /// By default, performs semantic analysis to build the new expression.
4199 /// Subclasses may override this routine to provide different behavior.
4200 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4201 AtomicExpr::AtomicOp Op,
4202 SourceLocation RParenLoc) {
4203 // Use this for all of the locations, since we don't know the difference
4204 // between the call and the expr at this point.
4205 SourceRange Range{BuiltinLoc, RParenLoc};
4206 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4207 Sema::AtomicArgumentOrder::AST);
4208 }
4209
4210 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4211 ArrayRef<Expr *> SubExprs, QualType Type) {
4212 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4213 }
4214
4215 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4216 SourceLocation BeginLoc,
4217 SourceLocation DirLoc,
4218 SourceLocation EndLoc,
4219 ArrayRef<OpenACCClause *> Clauses,
4220 StmtResult StrBlock) {
4221 return getSema().OpenACC().ActOnEndStmtDirective(
4222 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4223 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4224 }
4225
4226 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4227 SourceLocation DirLoc,
4228 SourceLocation EndLoc,
4229 ArrayRef<OpenACCClause *> Clauses,
4230 StmtResult Loop) {
4231 return getSema().OpenACC().ActOnEndStmtDirective(
4232 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4233 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4234 Clauses, Loop);
4235 }
4236
4237 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4238 SourceLocation BeginLoc,
4239 SourceLocation DirLoc,
4240 SourceLocation EndLoc,
4241 ArrayRef<OpenACCClause *> Clauses,
4242 StmtResult Loop) {
4243 return getSema().OpenACC().ActOnEndStmtDirective(
4244 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4245 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4246 }
4247
4248 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4249 SourceLocation DirLoc,
4250 SourceLocation EndLoc,
4251 ArrayRef<OpenACCClause *> Clauses,
4252 StmtResult StrBlock) {
4253 return getSema().OpenACC().ActOnEndStmtDirective(
4254 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4255 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4256 Clauses, StrBlock);
4257 }
4258
4259 StmtResult
4260 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4261 SourceLocation DirLoc, SourceLocation EndLoc,
4262 ArrayRef<OpenACCClause *> Clauses) {
4263 return getSema().OpenACC().ActOnEndStmtDirective(
4264 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4265 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4266 Clauses, {});
4267 }
4268
4269 StmtResult
4270 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4271 SourceLocation DirLoc, SourceLocation EndLoc,
4272 ArrayRef<OpenACCClause *> Clauses) {
4273 return getSema().OpenACC().ActOnEndStmtDirective(
4274 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4275 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4276 Clauses, {});
4277 }
4278
4279 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4280 SourceLocation DirLoc,
4281 SourceLocation EndLoc,
4282 ArrayRef<OpenACCClause *> Clauses,
4283 StmtResult StrBlock) {
4284 return getSema().OpenACC().ActOnEndStmtDirective(
4285 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4286 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4287 Clauses, StrBlock);
4288 }
4289
4290 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4291 SourceLocation DirLoc,
4292 SourceLocation EndLoc,
4293 ArrayRef<OpenACCClause *> Clauses) {
4294 return getSema().OpenACC().ActOnEndStmtDirective(
4295 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4296 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4297 Clauses, {});
4298 }
4299
4300 StmtResult
4301 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4302 SourceLocation DirLoc, SourceLocation EndLoc,
4303 ArrayRef<OpenACCClause *> Clauses) {
4304 return getSema().OpenACC().ActOnEndStmtDirective(
4305 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4306 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4307 Clauses, {});
4308 }
4309
4310 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4311 SourceLocation DirLoc,
4312 SourceLocation EndLoc,
4313 ArrayRef<OpenACCClause *> Clauses) {
4314 return getSema().OpenACC().ActOnEndStmtDirective(
4315 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4316 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4317 Clauses, {});
4318 }
4319
4320 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4321 SourceLocation DirLoc,
4322 SourceLocation EndLoc,
4323 ArrayRef<OpenACCClause *> Clauses) {
4324 return getSema().OpenACC().ActOnEndStmtDirective(
4325 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4326 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4327 Clauses, {});
4328 }
4329
4330 StmtResult RebuildOpenACCWaitConstruct(
4331 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4332 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4333 SourceLocation RParenLoc, SourceLocation EndLoc,
4334 ArrayRef<OpenACCClause *> Clauses) {
4335 llvm::SmallVector<Expr *> Exprs;
4336 Exprs.push_back(Elt: DevNumExpr);
4337 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4338 return getSema().OpenACC().ActOnEndStmtDirective(
4339 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4340 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4341 }
4342
4343 StmtResult RebuildOpenACCCacheConstruct(
4344 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4345 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4346 SourceLocation RParenLoc, SourceLocation EndLoc) {
4347 return getSema().OpenACC().ActOnEndStmtDirective(
4348 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4349 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4350 }
4351
4352 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4353 SourceLocation DirLoc,
4354 OpenACCAtomicKind AtKind,
4355 SourceLocation EndLoc,
4356 ArrayRef<OpenACCClause *> Clauses,
4357 StmtResult AssociatedStmt) {
4358 return getSema().OpenACC().ActOnEndStmtDirective(
4359 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4360 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4361 AssociatedStmt);
4362 }
4363
4364 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4365 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4366 }
4367
4368 ExprResult
4369 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl, unsigned Index,
4370 QualType ParamType, SourceLocation Loc,
4371 TemplateArgument Arg,
4372 UnsignedOrNone PackIndex, bool Final) {
4373 return getSema().BuildSubstNonTypeTemplateParmExpr(
4374 AssociatedDecl, Index, ParamType, Loc, Arg, PackIndex, Final);
4375 }
4376
4377 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4378 SourceLocation StartLoc,
4379 SourceLocation LParenLoc,
4380 SourceLocation EndLoc) {
4381 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4382 LParenLoc, EndLoc);
4383 }
4384
4385private:
4386 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4387 QualType ObjectType,
4388 NamedDecl *FirstQualifierInScope);
4389
4390 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4391 QualType ObjectType,
4392 NamedDecl *FirstQualifierInScope) {
4393 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4394 return TSInfo;
4395
4396 TypeLocBuilder TLB;
4397 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4398 ObjectType, FirstQualifierInScope);
4399 if (T.isNull())
4400 return nullptr;
4401 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4402 }
4403
4404 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4405 DependentNameTypeLoc TL,
4406 bool DeducibleTSTContext,
4407 QualType ObjectType = QualType(),
4408 NamedDecl *UnqualLookup = nullptr);
4409
4410 llvm::SmallVector<OpenACCClause *>
4411 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4412 ArrayRef<const OpenACCClause *> OldClauses);
4413
4414 OpenACCClause *
4415 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4416 OpenACCDirectiveKind DirKind,
4417 const OpenACCClause *OldClause);
4418};
4419
4420template <typename Derived>
4421StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4422 if (!S)
4423 return S;
4424
4425 switch (S->getStmtClass()) {
4426 case Stmt::NoStmtClass: break;
4427
4428 // Transform individual statement nodes
4429 // Pass SDK into statements that can produce a value
4430#define STMT(Node, Parent) \
4431 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4432#define VALUESTMT(Node, Parent) \
4433 case Stmt::Node##Class: \
4434 return getDerived().Transform##Node(cast<Node>(S), SDK);
4435#define ABSTRACT_STMT(Node)
4436#define EXPR(Node, Parent)
4437#include "clang/AST/StmtNodes.inc"
4438
4439 // Transform expressions by calling TransformExpr.
4440#define STMT(Node, Parent)
4441#define ABSTRACT_STMT(Stmt)
4442#define EXPR(Node, Parent) case Stmt::Node##Class:
4443#include "clang/AST/StmtNodes.inc"
4444 {
4445 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4446
4447 if (SDK == StmtDiscardKind::StmtExprResult)
4448 E = getSema().ActOnStmtExprResult(E);
4449 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4450 }
4451 }
4452
4453 return S;
4454}
4455
4456template<typename Derived>
4457OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4458 if (!S)
4459 return S;
4460
4461 switch (S->getClauseKind()) {
4462 default: break;
4463 // Transform individual clause nodes
4464#define GEN_CLANG_CLAUSE_CLASS
4465#define CLAUSE_CLASS(Enum, Str, Class) \
4466 case Enum: \
4467 return getDerived().Transform##Class(cast<Class>(S));
4468#include "llvm/Frontend/OpenMP/OMP.inc"
4469 }
4470
4471 return S;
4472}
4473
4474
4475template<typename Derived>
4476ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4477 if (!E)
4478 return E;
4479
4480 switch (E->getStmtClass()) {
4481 case Stmt::NoStmtClass: break;
4482#define STMT(Node, Parent) case Stmt::Node##Class: break;
4483#define ABSTRACT_STMT(Stmt)
4484#define EXPR(Node, Parent) \
4485 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4486#include "clang/AST/StmtNodes.inc"
4487 }
4488
4489 return E;
4490}
4491
4492template<typename Derived>
4493ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4494 bool NotCopyInit) {
4495 // Initializers are instantiated like expressions, except that various outer
4496 // layers are stripped.
4497 if (!Init)
4498 return Init;
4499
4500 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4501 Init = FE->getSubExpr();
4502
4503 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4504 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4505 Init = OVE->getSourceExpr();
4506 }
4507
4508 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4509 Init = MTE->getSubExpr();
4510
4511 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4512 Init = Binder->getSubExpr();
4513
4514 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4515 Init = ICE->getSubExprAsWritten();
4516
4517 if (CXXStdInitializerListExpr *ILE =
4518 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4519 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4520
4521 // If this is copy-initialization, we only need to reconstruct
4522 // InitListExprs. Other forms of copy-initialization will be a no-op if
4523 // the initializer is already the right type.
4524 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4525 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4526 return getDerived().TransformExpr(Init);
4527
4528 // Revert value-initialization back to empty parens.
4529 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4530 SourceRange Parens = VIE->getSourceRange();
4531 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4532 Parens.getEnd());
4533 }
4534
4535 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4536 if (isa<ImplicitValueInitExpr>(Val: Init))
4537 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4538 SourceLocation());
4539
4540 // Revert initialization by constructor back to a parenthesized or braced list
4541 // of expressions. Any other form of initializer can just be reused directly.
4542 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4543 return getDerived().TransformExpr(Init);
4544
4545 // If the initialization implicitly converted an initializer list to a
4546 // std::initializer_list object, unwrap the std::initializer_list too.
4547 if (Construct && Construct->isStdInitListInitialization())
4548 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4549
4550 // Enter a list-init context if this was list initialization.
4551 EnterExpressionEvaluationContext Context(
4552 getSema(), EnterExpressionEvaluationContext::InitList,
4553 Construct->isListInitialization());
4554
4555 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4556 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4557 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4558 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4559 SmallVector<Expr*, 8> NewArgs;
4560 bool ArgChanged = false;
4561 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4562 /*IsCall*/true, NewArgs, &ArgChanged))
4563 return ExprError();
4564
4565 // If this was list initialization, revert to syntactic list form.
4566 if (Construct->isListInitialization())
4567 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4568 Construct->getEndLoc(),
4569 /*IsExplicit=*/true);
4570
4571 // Build a ParenListExpr to represent anything else.
4572 SourceRange Parens = Construct->getParenOrBraceRange();
4573 if (Parens.isInvalid()) {
4574 // This was a variable declaration's initialization for which no initializer
4575 // was specified.
4576 assert(NewArgs.empty() &&
4577 "no parens or braces but have direct init with arguments?");
4578 return ExprEmpty();
4579 }
4580 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4581 Parens.getEnd());
4582}
4583
4584template<typename Derived>
4585bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4586 unsigned NumInputs,
4587 bool IsCall,
4588 SmallVectorImpl<Expr *> &Outputs,
4589 bool *ArgChanged) {
4590 for (unsigned I = 0; I != NumInputs; ++I) {
4591 // If requested, drop call arguments that need to be dropped.
4592 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4593 if (ArgChanged)
4594 *ArgChanged = true;
4595
4596 break;
4597 }
4598
4599 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4600 Expr *Pattern = Expansion->getPattern();
4601
4602 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4603 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4604 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4605
4606 // Determine whether the set of unexpanded parameter packs can and should
4607 // be expanded.
4608 bool Expand = true;
4609 bool RetainExpansion = false;
4610 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4611 UnsignedOrNone NumExpansions = OrigNumExpansions;
4612 if (getDerived().TryExpandParameterPacks(
4613 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4614 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4615 RetainExpansion, NumExpansions))
4616 return true;
4617
4618 if (!Expand) {
4619 // The transform has determined that we should perform a simple
4620 // transformation on the pack expansion, producing another pack
4621 // expansion.
4622 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4623 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4624 if (OutPattern.isInvalid())
4625 return true;
4626
4627 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4628 Expansion->getEllipsisLoc(),
4629 NumExpansions);
4630 if (Out.isInvalid())
4631 return true;
4632
4633 if (ArgChanged)
4634 *ArgChanged = true;
4635 Outputs.push_back(Elt: Out.get());
4636 continue;
4637 }
4638
4639 // Record right away that the argument was changed. This needs
4640 // to happen even if the array expands to nothing.
4641 if (ArgChanged) *ArgChanged = true;
4642
4643 // The transform has determined that we should perform an elementwise
4644 // expansion of the pattern. Do so.
4645 for (unsigned I = 0; I != *NumExpansions; ++I) {
4646 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4647 ExprResult Out = getDerived().TransformExpr(Pattern);
4648 if (Out.isInvalid())
4649 return true;
4650
4651 if (Out.get()->containsUnexpandedParameterPack()) {
4652 Out = getDerived().RebuildPackExpansion(
4653 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4654 if (Out.isInvalid())
4655 return true;
4656 }
4657
4658 Outputs.push_back(Elt: Out.get());
4659 }
4660
4661 // If we're supposed to retain a pack expansion, do so by temporarily
4662 // forgetting the partially-substituted parameter pack.
4663 if (RetainExpansion) {
4664 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4665
4666 ExprResult Out = getDerived().TransformExpr(Pattern);
4667 if (Out.isInvalid())
4668 return true;
4669
4670 Out = getDerived().RebuildPackExpansion(
4671 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4672 if (Out.isInvalid())
4673 return true;
4674
4675 Outputs.push_back(Elt: Out.get());
4676 }
4677
4678 continue;
4679 }
4680
4681 ExprResult Result =
4682 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4683 : getDerived().TransformExpr(Inputs[I]);
4684 if (Result.isInvalid())
4685 return true;
4686
4687 if (Result.get() != Inputs[I] && ArgChanged)
4688 *ArgChanged = true;
4689
4690 Outputs.push_back(Elt: Result.get());
4691 }
4692
4693 return false;
4694}
4695
4696template <typename Derived>
4697Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4698 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4699
4700 EnterExpressionEvaluationContext Eval(
4701 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4702 /*LambdaContextDecl=*/nullptr,
4703 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4704 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4705
4706 if (Var) {
4707 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4708 getDerived().TransformDefinition(Var->getLocation(), Var));
4709
4710 if (!ConditionVar)
4711 return Sema::ConditionError();
4712
4713 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4714 }
4715
4716 if (Expr) {
4717 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4718
4719 if (CondExpr.isInvalid())
4720 return Sema::ConditionError();
4721
4722 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4723 /*MissingOK=*/true);
4724 }
4725
4726 return Sema::ConditionResult();
4727}
4728
4729template <typename Derived>
4730NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4731 NestedNameSpecifierLoc NNS, QualType ObjectType,
4732 NamedDecl *FirstQualifierInScope) {
4733 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4734
4735 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4736 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4737 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4738 Qualifiers.push_back(Elt: Qualifier);
4739 };
4740 insertNNS(NNS);
4741
4742 CXXScopeSpec SS;
4743 while (!Qualifiers.empty()) {
4744 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4745 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4746
4747 switch (QNNS.getKind()) {
4748 case NestedNameSpecifier::Kind::Null:
4749 llvm_unreachable("unexpected null nested name specifier");
4750
4751 case NestedNameSpecifier::Kind::Namespace: {
4752 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4753 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4754 QNNS.getAsNamespaceAndPrefix().Namespace)));
4755 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4756 break;
4757 }
4758
4759 case NestedNameSpecifier::Kind::Global:
4760 // There is no meaningful transformation that one could perform on the
4761 // global scope.
4762 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4763 break;
4764
4765 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4766 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4767 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4768 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4769 ColonColonLoc: Q.getEndLoc());
4770 break;
4771 }
4772
4773 case NestedNameSpecifier::Kind::Type: {
4774 assert(SS.isEmpty());
4775 TypeLoc TL = Q.castAsTypeLoc();
4776
4777 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4778 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4779 if (QualifierLoc) {
4780 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4781 QualifierLoc, ObjectType, FirstQualifierInScope);
4782 if (!QualifierLoc)
4783 return NestedNameSpecifierLoc();
4784 ObjectType = QualType();
4785 FirstQualifierInScope = nullptr;
4786 }
4787 SS.Adopt(Other: QualifierLoc);
4788 Sema::NestedNameSpecInfo IdInfo(
4789 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4790 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4791 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4792 EnteringContext: false, SS,
4793 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4794 return NestedNameSpecifierLoc();
4795 return SS.getWithLocInContext(Context&: SemaRef.Context);
4796 }
4797
4798 QualType T = TL.getType();
4799 TypeLocBuilder TLB;
4800 if (!getDerived().AlreadyTransformed(T)) {
4801 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4802 FirstQualifierInScope);
4803 if (T.isNull())
4804 return NestedNameSpecifierLoc();
4805 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4806 }
4807
4808 if (T->isDependentType() || T->isRecordType() ||
4809 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4810 if (T->isEnumeralType())
4811 SemaRef.Diag(Loc: TL.getBeginLoc(),
4812 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4813 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4814 break;
4815 }
4816 // If the nested-name-specifier is an invalid type def, don't emit an
4817 // error because a previous error should have already been emitted.
4818 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4819 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4820 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4821 << T << SS.getRange();
4822 }
4823 return NestedNameSpecifierLoc();
4824 }
4825 }
4826 }
4827
4828 // Don't rebuild the nested-name-specifier if we don't have to.
4829 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4830 !getDerived().AlwaysRebuild())
4831 return NNS;
4832
4833 // If we can re-use the source-location data from the original
4834 // nested-name-specifier, do so.
4835 if (SS.location_size() == NNS.getDataLength() &&
4836 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4837 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4838
4839 // Allocate new nested-name-specifier location information.
4840 return SS.getWithLocInContext(Context&: SemaRef.Context);
4841}
4842
4843template<typename Derived>
4844DeclarationNameInfo
4845TreeTransform<Derived>
4846::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4847 DeclarationName Name = NameInfo.getName();
4848 if (!Name)
4849 return DeclarationNameInfo();
4850
4851 switch (Name.getNameKind()) {
4852 case DeclarationName::Identifier:
4853 case DeclarationName::ObjCZeroArgSelector:
4854 case DeclarationName::ObjCOneArgSelector:
4855 case DeclarationName::ObjCMultiArgSelector:
4856 case DeclarationName::CXXOperatorName:
4857 case DeclarationName::CXXLiteralOperatorName:
4858 case DeclarationName::CXXUsingDirective:
4859 return NameInfo;
4860
4861 case DeclarationName::CXXDeductionGuideName: {
4862 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4863 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4864 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4865 if (!NewTemplate)
4866 return DeclarationNameInfo();
4867
4868 DeclarationNameInfo NewNameInfo(NameInfo);
4869 NewNameInfo.setName(
4870 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4871 return NewNameInfo;
4872 }
4873
4874 case DeclarationName::CXXConstructorName:
4875 case DeclarationName::CXXDestructorName:
4876 case DeclarationName::CXXConversionFunctionName: {
4877 TypeSourceInfo *NewTInfo;
4878 CanQualType NewCanTy;
4879 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4880 NewTInfo = getDerived().TransformType(OldTInfo);
4881 if (!NewTInfo)
4882 return DeclarationNameInfo();
4883 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4884 }
4885 else {
4886 NewTInfo = nullptr;
4887 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4888 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4889 if (NewT.isNull())
4890 return DeclarationNameInfo();
4891 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4892 }
4893
4894 DeclarationName NewName
4895 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4896 Ty: NewCanTy);
4897 DeclarationNameInfo NewNameInfo(NameInfo);
4898 NewNameInfo.setName(NewName);
4899 NewNameInfo.setNamedTypeInfo(NewTInfo);
4900 return NewNameInfo;
4901 }
4902 }
4903
4904 llvm_unreachable("Unknown name kind.");
4905}
4906
4907template <typename Derived>
4908TemplateName TreeTransform<Derived>::RebuildTemplateName(
4909 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4910 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4911 QualType ObjectType, bool AllowInjectedClassName) {
4912 if (const IdentifierInfo *II = IO.getIdentifier())
4913 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4914 ObjectType, AllowInjectedClassName);
4915 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4916 NameLoc, ObjectType,
4917 AllowInjectedClassName);
4918}
4919
4920template <typename Derived>
4921TemplateName TreeTransform<Derived>::TransformTemplateName(
4922 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4923 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4924 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4925 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4926 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4927
4928 if (QualifierLoc) {
4929 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4930 QualifierLoc, ObjectType, FirstQualifierInScope);
4931 if (!QualifierLoc)
4932 return TemplateName();
4933 }
4934
4935 NestedNameSpecifierLoc UnderlyingQualifier;
4936 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4937 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4938 FirstQualifierInScope, AllowInjectedClassName);
4939 if (NewUnderlyingName.isNull())
4940 return TemplateName();
4941 assert(!UnderlyingQualifier && "unexpected qualifier");
4942
4943 if (!getDerived().AlwaysRebuild() &&
4944 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4945 NewUnderlyingName == UnderlyingName)
4946 return Name;
4947 CXXScopeSpec SS;
4948 SS.Adopt(Other: QualifierLoc);
4949 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4950 NewUnderlyingName);
4951 }
4952
4953 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4954 if (QualifierLoc) {
4955 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4956 QualifierLoc, ObjectType, FirstQualifierInScope);
4957 if (!QualifierLoc)
4958 return TemplateName();
4959 // The qualifier-in-scope and object type only apply to the leftmost
4960 // entity.
4961 ObjectType = QualType();
4962 }
4963
4964 if (!getDerived().AlwaysRebuild() &&
4965 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4966 ObjectType.isNull())
4967 return Name;
4968
4969 CXXScopeSpec SS;
4970 SS.Adopt(Other: QualifierLoc);
4971 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4972 NameLoc, ObjectType,
4973 AllowInjectedClassName);
4974 }
4975
4976 if (SubstTemplateTemplateParmStorage *S =
4977 Name.getAsSubstTemplateTemplateParm()) {
4978 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4979
4980 NestedNameSpecifierLoc ReplacementQualifierLoc;
4981 TemplateName ReplacementName = S->getReplacement();
4982 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4983 NestedNameSpecifierLocBuilder Builder;
4984 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4985 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4986 }
4987
4988 TemplateName NewName = getDerived().TransformTemplateName(
4989 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4990 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4991 if (NewName.isNull())
4992 return TemplateName();
4993 Decl *AssociatedDecl =
4994 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4995 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4996 AssociatedDecl == S->getAssociatedDecl())
4997 return Name;
4998 return SemaRef.Context.getSubstTemplateTemplateParm(
4999 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
5000 Final: S->getFinal());
5001 }
5002
5003 if (PackIndexingTemplateStorage *PI = Name.getAsPackIndexingTemplate()) {
5004 assert(!QualifierLoc && "Unexpected qualified pack-index-template-name");
5005
5006 ExprResult IndexExpr;
5007 {
5008 EnterExpressionEvaluationContext ConstantContext(
5009 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5010 IndexExpr = getDerived().TransformExpr(PI->getIndexExpr());
5011 if (IndexExpr.isInvalid())
5012 return TemplateName();
5013 }
5014
5015 auto TransformOne = [&](TemplateName N) {
5016 NestedNameSpecifierLoc NoQualifier;
5017 return getDerived().TransformTemplateName(
5018 NoQualifier, TemplateKWLoc, N, NameLoc, ObjectType,
5019 FirstQualifierInScope, AllowInjectedClassName);
5020 };
5021
5022 TemplateName Pattern = PI->getPattern();
5023 SmallVector<TemplateName, 4> SubstitutedNames;
5024 ArrayRef<TemplateName> Names = PI->getExpansions();
5025
5026 bool NotYetExpanded = Names.empty();
5027 bool FullySubstituted = true;
5028
5029 if (Names.empty() && !PI->expandsToEmptyPack())
5030 Names = ArrayRef(&Pattern, 1);
5031
5032 for (TemplateName N : Names) {
5033 if (!N.containsUnexpandedParameterPack()) {
5034 TemplateName Transformed = TransformOne(N);
5035 if (Transformed.isNull())
5036 return TemplateName();
5037 SubstitutedNames.push_back(Elt: Transformed);
5038 continue;
5039 }
5040
5041 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5042 getSema().collectUnexpandedParameterPacks(N, Unexpanded);
5043 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5044
5045 bool ShouldExpand = true;
5046 bool RetainExpansion = false;
5047 UnsignedOrNone NumExpansions = std::nullopt;
5048 if (getDerived().TryExpandParameterPacks(
5049 NameLoc, SourceRange(), Unexpanded,
5050 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
5051 RetainExpansion, NumExpansions))
5052 return TemplateName();
5053
5054 if (!ShouldExpand) {
5055 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5056 TemplateName Pack = TransformOne(N);
5057 if (Pack.isNull())
5058 return TemplateName();
5059 if (NotYetExpanded) {
5060 FullySubstituted = false;
5061 return getDerived().RebuildPackIndexingTemplateName(
5062 Pack, IndexExpr.get(), FullySubstituted);
5063 }
5064 SubstitutedNames.push_back(Elt: Pack);
5065 continue;
5066 }
5067
5068 for (unsigned I = 0; I != *NumExpansions; ++I) {
5069 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5070 TemplateName Out = TransformOne(N);
5071 if (Out.isNull())
5072 return TemplateName();
5073 SubstitutedNames.push_back(Elt: Out);
5074 FullySubstituted &= !Out.containsUnexpandedParameterPack();
5075 }
5076
5077 // If we're supposed to retain a pack expansion, do so by temporarily
5078 // forgetting the partially-substituted parameter pack.
5079 if (RetainExpansion) {
5080 FullySubstituted = false;
5081 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5082 TemplateName Out = TransformOne(N);
5083 if (Out.isNull())
5084 return TemplateName();
5085 SubstitutedNames.push_back(Elt: Out);
5086 }
5087 }
5088
5089 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5090 TemplateName NewPattern = TransformOne(Pattern);
5091 if (NewPattern.isNull())
5092 return TemplateName();
5093
5094 return getDerived().RebuildPackIndexingTemplateName(
5095 NewPattern, IndexExpr.get(), FullySubstituted, SubstitutedNames);
5096 }
5097
5098 assert(!Name.getAsDeducedTemplateName() &&
5099 "DeducedTemplateName should not escape partial ordering");
5100
5101 // FIXME: Preserve UsingTemplateName.
5102 if (auto *Template = Name.getAsTemplateDecl()) {
5103 assert(!QualifierLoc && "Unexpected qualifier");
5104 return TemplateName(cast_or_null<TemplateDecl>(
5105 getDerived().TransformDecl(NameLoc, Template)));
5106 }
5107
5108 if (SubstTemplateTemplateParmPackStorage *SubstPack
5109 = Name.getAsSubstTemplateTemplateParmPack()) {
5110 assert(!QualifierLoc &&
5111 "Unexpected qualified SubstTemplateTemplateParmPack");
5112 return getDerived().RebuildTemplateName(
5113 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
5114 SubstPack->getIndex(), SubstPack->getFinal());
5115 }
5116
5117 // These should be getting filtered out before they reach the AST.
5118 llvm_unreachable("overloaded function decl survived to here");
5119}
5120
5121template <typename Derived>
5122TemplateName
5123TreeTransform<Derived>::TransformConceptTemplateName(TemplateName Name,
5124 SourceLocation NameLoc) {
5125 NestedNameSpecifierLoc QualifierLoc;
5126 return getDerived().TransformTemplateName(
5127 QualifierLoc, /*TemplateKWLoc=*/SourceLocation(), Name, NameLoc);
5128}
5129
5130template <typename Derived>
5131TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
5132 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
5133 TemplateName Name, SourceLocation NameLoc) {
5134 TemplateName TN = getDerived().TransformTemplateName(
5135 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
5136 if (TN.isNull())
5137 return TemplateArgument();
5138 return TemplateArgument(TN);
5139}
5140
5141template<typename Derived>
5142void TreeTransform<Derived>::InventTemplateArgumentLoc(
5143 const TemplateArgument &Arg,
5144 TemplateArgumentLoc &Output) {
5145 Output = getSema().getTrivialTemplateArgumentLoc(
5146 Arg, QualType(), getDerived().getBaseLocation());
5147}
5148
5149template <typename Derived>
5150bool TreeTransform<Derived>::TransformTemplateArgument(
5151 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5152 bool Uneval) {
5153 const TemplateArgument &Arg = Input.getArgument();
5154 switch (Arg.getKind()) {
5155 case TemplateArgument::Null:
5156 case TemplateArgument::Pack:
5157 llvm_unreachable("Unexpected TemplateArgument");
5158
5159 case TemplateArgument::Integral:
5160 case TemplateArgument::NullPtr:
5161 case TemplateArgument::Declaration:
5162 case TemplateArgument::StructuralValue: {
5163 // Transform a resolved template argument straight to a resolved template
5164 // argument. We get here when substituting into an already-substituted
5165 // template type argument during concept satisfaction checking.
5166 QualType T = Arg.getNonTypeTemplateArgumentType();
5167 QualType NewT = getDerived().TransformType(T);
5168 if (NewT.isNull())
5169 return true;
5170
5171 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5172 ? Arg.getAsDecl()
5173 : nullptr;
5174 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5175 getDerived().getBaseLocation(), D))
5176 : nullptr;
5177 if (D && !NewD)
5178 return true;
5179
5180 if (NewT == T && D == NewD)
5181 Output = Input;
5182 else if (Arg.getKind() == TemplateArgument::Integral)
5183 Output = TemplateArgumentLoc(
5184 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5185 TemplateArgumentLocInfo());
5186 else if (Arg.getKind() == TemplateArgument::NullPtr)
5187 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5188 TemplateArgumentLocInfo());
5189 else if (Arg.getKind() == TemplateArgument::Declaration)
5190 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5191 TemplateArgumentLocInfo());
5192 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5193 Output = TemplateArgumentLoc(
5194 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5195 TemplateArgumentLocInfo());
5196 else
5197 llvm_unreachable("unexpected template argument kind");
5198
5199 return false;
5200 }
5201
5202 case TemplateArgument::Type: {
5203 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5204 if (!TSI)
5205 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5206
5207 TSI = getDerived().TransformType(TSI);
5208 if (!TSI)
5209 return true;
5210
5211 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5212 return false;
5213 }
5214
5215 case TemplateArgument::Template: {
5216 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5217
5218 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5219 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5220 Input.getTemplateNameLoc());
5221 if (Out.isNull())
5222 return true;
5223 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5224 QualifierLoc, Input.getTemplateNameLoc());
5225 return false;
5226 }
5227
5228 case TemplateArgument::TemplateExpansion:
5229 llvm_unreachable("Caller should expand pack expansions");
5230
5231 case TemplateArgument::Expression: {
5232 // Template argument expressions are constant expressions.
5233 EnterExpressionEvaluationContext Unevaluated(
5234 getSema(),
5235 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5236 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5237 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5238 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5239
5240 Expr *InputExpr = Input.getSourceExpression();
5241 if (!InputExpr)
5242 InputExpr = Input.getArgument().getAsExpr();
5243
5244 ExprResult E = getDerived().TransformExpr(InputExpr);
5245 E = SemaRef.ActOnConstantExpression(Res: E);
5246 if (E.isInvalid())
5247 return true;
5248 Output = TemplateArgumentLoc(
5249 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5250 return false;
5251 }
5252 }
5253
5254 // Work around bogus GCC warning
5255 return true;
5256}
5257
5258/// Iterator adaptor that invents template argument location information
5259/// for each of the template arguments in its underlying iterator.
5260template<typename Derived, typename InputIterator>
5261class TemplateArgumentLocInventIterator {
5262 TreeTransform<Derived> &Self;
5263 InputIterator Iter;
5264
5265public:
5266 typedef TemplateArgumentLoc value_type;
5267 typedef TemplateArgumentLoc reference;
5268 typedef typename std::iterator_traits<InputIterator>::difference_type
5269 difference_type;
5270 typedef std::input_iterator_tag iterator_category;
5271
5272 class pointer {
5273 TemplateArgumentLoc Arg;
5274
5275 public:
5276 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5277
5278 const TemplateArgumentLoc *operator->() const { return &Arg; }
5279 };
5280
5281 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5282 InputIterator Iter)
5283 : Self(Self), Iter(Iter) { }
5284
5285 TemplateArgumentLocInventIterator &operator++() {
5286 ++Iter;
5287 return *this;
5288 }
5289
5290 TemplateArgumentLocInventIterator operator++(int) {
5291 TemplateArgumentLocInventIterator Old(*this);
5292 ++(*this);
5293 return Old;
5294 }
5295
5296 reference operator*() const {
5297 TemplateArgumentLoc Result;
5298 Self.InventTemplateArgumentLoc(*Iter, Result);
5299 return Result;
5300 }
5301
5302 pointer operator->() const { return pointer(**this); }
5303
5304 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5305 const TemplateArgumentLocInventIterator &Y) {
5306 return X.Iter == Y.Iter;
5307 }
5308
5309 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5310 const TemplateArgumentLocInventIterator &Y) {
5311 return X.Iter != Y.Iter;
5312 }
5313};
5314
5315template<typename Derived>
5316template<typename InputIterator>
5317bool TreeTransform<Derived>::TransformTemplateArguments(
5318 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5319 bool Uneval) {
5320 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5321 TemplateArgumentLoc Out;
5322 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5323 // Unpack argument packs, which we translate them into separate
5324 // arguments.
5325 // FIXME: We could do much better if we could guarantee that the
5326 // TemplateArgumentLocInfo for the pack expansion would be usable for
5327 // all of the template arguments in the argument pack.
5328 typedef TemplateArgumentLocInventIterator<Derived,
5329 TemplateArgument::pack_iterator>
5330 PackLocIterator;
5331
5332 TemplateArgumentListInfo *PackOutput = &Outputs;
5333 TemplateArgumentListInfo New;
5334
5335 if (TransformTemplateArguments(
5336 PackLocIterator(*this, In.getArgument().pack_begin()),
5337 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5338 Uneval))
5339 return true;
5340
5341 continue;
5342 }
5343
5344 if (In.getArgument().isPackExpansion()) {
5345 UnexpandedInfo Info;
5346 TemplateArgumentLoc Prepared;
5347 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5348 return true;
5349 if (!Info.Expand) {
5350 Outputs.addArgument(Loc: Prepared);
5351 continue;
5352 }
5353
5354 // The transform has determined that we should perform an elementwise
5355 // expansion of the pattern. Do so.
5356 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5357 if (Info.ExpandUnderForgetSubstitions)
5358 ForgetSubst.emplace(getDerived());
5359 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5360 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5361
5362 TemplateArgumentLoc Out;
5363 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5364 return true;
5365
5366 if (Out.getArgument().containsUnexpandedParameterPack()) {
5367 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5368 Info.OrigNumExpansions);
5369 if (Out.getArgument().isNull())
5370 return true;
5371 }
5372
5373 Outputs.addArgument(Loc: Out);
5374 }
5375
5376 // If we're supposed to retain a pack expansion, do so by temporarily
5377 // forgetting the partially-substituted parameter pack.
5378 if (Info.RetainExpansion) {
5379 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5380
5381 TemplateArgumentLoc Out;
5382 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5383 return true;
5384
5385 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5386 Info.OrigNumExpansions);
5387 if (Out.getArgument().isNull())
5388 return true;
5389
5390 Outputs.addArgument(Loc: Out);
5391 }
5392
5393 continue;
5394 }
5395
5396 // The simple case:
5397 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5398 return true;
5399
5400 Outputs.addArgument(Loc: Out);
5401 }
5402
5403 return false;
5404}
5405
5406template <typename Derived>
5407template <typename InputIterator>
5408bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5409 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5410 bool Uneval) {
5411
5412 // [C++26][temp.constr.normal]
5413 // any non-dependent concept template argument
5414 // is substituted into the constraint-expression of C.
5415 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5416 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5417 };
5418
5419 for (; First != Last; ++First) {
5420 TemplateArgumentLoc Out;
5421 TemplateArgumentLoc In = *First;
5422
5423 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5424 typedef TemplateArgumentLocInventIterator<Derived,
5425 TemplateArgument::pack_iterator>
5426 PackLocIterator;
5427 if (TransformConceptTemplateArguments(
5428 PackLocIterator(*this, In.getArgument().pack_begin()),
5429 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5430 Uneval))
5431 return true;
5432 continue;
5433 }
5434
5435 if (!isNonDependentConceptArgument(In.getArgument())) {
5436 Outputs.addArgument(Loc: In);
5437 continue;
5438 }
5439
5440 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5441 return true;
5442
5443 Outputs.addArgument(Loc: Out);
5444 }
5445
5446 return false;
5447}
5448
5449// FIXME: Find ways to reduce code duplication for pack expansions.
5450template <typename Derived>
5451bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5452 bool Uneval,
5453 TemplateArgumentLoc &Out,
5454 UnexpandedInfo &Info) {
5455 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5456 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5457 TemplateArgumentLoc &Pattern) {
5458 assert(Arg.getArgument().isPackExpansion());
5459 // We have a pack expansion, for which we will be substituting into the
5460 // pattern.
5461 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5462 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5463 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5464 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5465 if (IsLateExpansionAttempt) {
5466 // Request expansion only when there is an opportunity to expand a pack
5467 // that required a substituion first.
5468 bool SawPackTypes =
5469 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5470 return isa<const SubstBuiltinTemplatePackType *>(Val: P.first);
5471 });
5472 if (!SawPackTypes) {
5473 Info.Expand = false;
5474 return false;
5475 }
5476 }
5477 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5478
5479 // Determine whether the set of unexpanded parameter packs can and
5480 // should be expanded.
5481 Info.Expand = true;
5482 Info.RetainExpansion = false;
5483 Info.NumExpansions = Info.OrigNumExpansions;
5484 return getDerived().TryExpandParameterPacks(
5485 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5486 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5487 Info.RetainExpansion, Info.NumExpansions);
5488 };
5489
5490 TemplateArgumentLoc Pattern;
5491 if (ComputeInfo(In, false, Info, Pattern))
5492 return true;
5493
5494 if (Info.Expand) {
5495 Out = Pattern;
5496 return false;
5497 }
5498
5499 // The transform has determined that we should perform a simple
5500 // transformation on the pack expansion, producing another pack
5501 // expansion.
5502 TemplateArgumentLoc OutPattern;
5503 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5504 std::in_place, getSema(), std::nullopt);
5505 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5506 return true;
5507
5508 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5509 Info.NumExpansions);
5510 if (Out.getArgument().isNull())
5511 return true;
5512 SubstIndex.reset();
5513
5514 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5515 return false;
5516
5517 // Some packs will learn their length after substitution, e.g.
5518 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5519 // value of `T`.
5520 //
5521 // We only expand after we know sizes of all packs, check if this is the case
5522 // or not. However, we avoid a full template substitution and only do
5523 // expanstions after this point.
5524
5525 // E.g. when substituting template arguments of tuple with {T -> int} in the
5526 // following example:
5527 // template <class T>
5528 // struct TupleWithInt {
5529 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5530 // };
5531 // TupleWithInt<int>::type y;
5532 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5533 // length and run `ComputeInfo()` to provide the necessary information to our
5534 // caller.
5535 //
5536 // Note that we may still have situations where builtin is not going to be
5537 // expanded. For example:
5538 // template <class T>
5539 // struct Foo {
5540 // template <class U> using tuple_with_t =
5541 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5542 // tuple_with_t<short>;
5543 // }
5544 // Because the substitution into `type` happens in dependent context, `type`
5545 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5546 // and the caller will not be able to expand it.
5547 ForgetSubstitutionRAII ForgetSubst(getDerived());
5548 if (ComputeInfo(Out, true, Info, OutPattern))
5549 return true;
5550 if (!Info.Expand)
5551 return false;
5552 Out = OutPattern;
5553 Info.ExpandUnderForgetSubstitions = true;
5554 return false;
5555}
5556
5557//===----------------------------------------------------------------------===//
5558// Type transformation
5559//===----------------------------------------------------------------------===//
5560
5561template<typename Derived>
5562QualType TreeTransform<Derived>::TransformType(QualType T) {
5563 if (getDerived().AlreadyTransformed(T))
5564 return T;
5565
5566 // Temporary workaround. All of these transformations should
5567 // eventually turn into transformations on TypeLocs.
5568 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5569 T, getDerived().getBaseLocation());
5570
5571 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5572
5573 if (!NewTSI)
5574 return QualType();
5575
5576 return NewTSI->getType();
5577}
5578
5579template <typename Derived>
5580TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5581 // Refine the base location to the type's location.
5582 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5583 getDerived().getBaseEntity());
5584 if (getDerived().AlreadyTransformed(TSI->getType()))
5585 return TSI;
5586
5587 TypeLocBuilder TLB;
5588
5589 TypeLoc TL = TSI->getTypeLoc();
5590 TLB.reserve(Requested: TL.getFullDataSize());
5591
5592 QualType Result = getDerived().TransformType(TLB, TL);
5593 if (Result.isNull())
5594 return nullptr;
5595
5596 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5597}
5598
5599template<typename Derived>
5600QualType
5601TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5602 switch (T.getTypeLocClass()) {
5603#define ABSTRACT_TYPELOC(CLASS, PARENT)
5604#define TYPELOC(CLASS, PARENT) \
5605 case TypeLoc::CLASS: \
5606 return getDerived().Transform##CLASS##Type(TLB, \
5607 T.castAs<CLASS##TypeLoc>());
5608#include "clang/AST/TypeLocNodes.def"
5609 }
5610
5611 llvm_unreachable("unhandled type loc!");
5612}
5613
5614template<typename Derived>
5615QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5616 if (!isa<DependentNameType>(Val: T))
5617 return TransformType(T);
5618
5619 if (getDerived().AlreadyTransformed(T))
5620 return T;
5621 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5622 T, getDerived().getBaseLocation());
5623 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5624 return NewTSI ? NewTSI->getType() : QualType();
5625}
5626
5627template <typename Derived>
5628TypeSourceInfo *
5629TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5630 if (!isa<DependentNameType>(Val: TSI->getType()))
5631 return TransformType(TSI);
5632
5633 // Refine the base location to the type's location.
5634 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5635 getDerived().getBaseEntity());
5636 if (getDerived().AlreadyTransformed(TSI->getType()))
5637 return TSI;
5638
5639 TypeLocBuilder TLB;
5640
5641 TypeLoc TL = TSI->getTypeLoc();
5642 TLB.reserve(Requested: TL.getFullDataSize());
5643
5644 auto QTL = TL.getAs<QualifiedTypeLoc>();
5645 if (QTL)
5646 TL = QTL.getUnqualifiedLoc();
5647
5648 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5649
5650 QualType Result = getDerived().TransformDependentNameType(
5651 TLB, DNTL, /*DeducedTSTContext*/true);
5652 if (Result.isNull())
5653 return nullptr;
5654
5655 if (QTL) {
5656 Result = getDerived().RebuildQualifiedType(Result, QTL);
5657 if (Result.isNull())
5658 return nullptr;
5659 TLB.TypeWasModifiedSafely(T: Result);
5660 }
5661
5662 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5663}
5664
5665template<typename Derived>
5666QualType
5667TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5668 QualifiedTypeLoc T) {
5669 QualType Result;
5670 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5671 auto SuppressObjCLifetime =
5672 T.getType().getLocalQualifiers().hasObjCLifetime();
5673 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5674 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5675 SuppressObjCLifetime);
5676 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5677 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5678 TLB, STTP, SuppressObjCLifetime);
5679 } else {
5680 Result = getDerived().TransformType(TLB, UnqualTL);
5681 }
5682
5683 if (Result.isNull())
5684 return QualType();
5685
5686 Result = getDerived().RebuildQualifiedType(Result, T);
5687
5688 if (Result.isNull())
5689 return QualType();
5690
5691 // RebuildQualifiedType might have updated the type, but not in a way
5692 // that invalidates the TypeLoc. (There's no location information for
5693 // qualifiers.)
5694 TLB.TypeWasModifiedSafely(T: Result);
5695
5696 return Result;
5697}
5698
5699template <typename Derived>
5700QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5701 QualifiedTypeLoc TL) {
5702
5703 SourceLocation Loc = TL.getBeginLoc();
5704 Qualifiers Quals = TL.getType().getLocalQualifiers();
5705
5706 if ((T.getAddressSpace() != LangAS::Default &&
5707 Quals.getAddressSpace() != LangAS::Default) &&
5708 T.getAddressSpace() != Quals.getAddressSpace()) {
5709 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5710 << TL.getType() << T;
5711 return QualType();
5712 }
5713
5714 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5715 if (LocalPointerAuth.isPresent()) {
5716 if (T.getPointerAuth().isPresent()) {
5717 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5718 return QualType();
5719 }
5720 if (!T->isDependentType()) {
5721 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5722 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5723 return QualType();
5724 }
5725 }
5726 }
5727 // C++ [dcl.fct]p7:
5728 // [When] adding cv-qualifications on top of the function type [...] the
5729 // cv-qualifiers are ignored.
5730 if (T->isFunctionType()) {
5731 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5732 AddressSpace: Quals.getAddressSpace());
5733 return T;
5734 }
5735
5736 // C++ [dcl.ref]p1:
5737 // when the cv-qualifiers are introduced through the use of a typedef-name
5738 // or decltype-specifier [...] the cv-qualifiers are ignored.
5739 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5740 // applied to a reference type.
5741 if (T->isReferenceType()) {
5742 // The only qualifier that applies to a reference type is restrict.
5743 if (!Quals.hasRestrict())
5744 return T;
5745 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5746 }
5747
5748 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5749 // resulting type.
5750 if (Quals.hasObjCLifetime()) {
5751 if (!T->isObjCLifetimeType() && !T->isDependentType())
5752 Quals.removeObjCLifetime();
5753 else if (T.getObjCLifetime()) {
5754 // Objective-C ARC:
5755 // A lifetime qualifier applied to a substituted template parameter
5756 // overrides the lifetime qualifier from the template argument.
5757 const AutoType *AutoTy;
5758 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5759 // 'auto' types behave the same way as template parameters.
5760 QualType Deduced = AutoTy->getDeducedType();
5761 Qualifiers Qs = Deduced.getQualifiers();
5762 Qs.removeObjCLifetime();
5763 Deduced =
5764 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5765 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5766 Keyword: AutoTy->getKeyword(),
5767 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5768 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5769 } else {
5770 // Otherwise, complain about the addition of a qualifier to an
5771 // already-qualified type.
5772 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5773 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5774 Quals.removeObjCLifetime();
5775 }
5776 }
5777 }
5778
5779 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5780}
5781
5782template <typename Derived>
5783QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5784 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5785 NamedDecl *FirstQualifierInScope) {
5786 assert(!getDerived().AlreadyTransformed(TL.getType()));
5787
5788 switch (TL.getTypeLocClass()) {
5789 case TypeLoc::TemplateSpecialization:
5790 return getDerived().TransformTemplateSpecializationType(
5791 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5792 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5793 case TypeLoc::DependentName:
5794 return getDerived().TransformDependentNameType(
5795 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5796 ObjectType, FirstQualifierInScope);
5797 default:
5798 // Any dependent canonical type can appear here, through type alias
5799 // templates.
5800 return getDerived().TransformType(TLB, TL);
5801 }
5802}
5803
5804template <class TyLoc> static inline
5805QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5806 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5807 NewT.setNameLoc(T.getNameLoc());
5808 return T.getType();
5809}
5810
5811template<typename Derived>
5812QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5813 BuiltinTypeLoc T) {
5814 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5815 NewT.setBuiltinLoc(T.getBuiltinLoc());
5816 if (T.needsExtraLocalData())
5817 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5818 return T.getType();
5819}
5820
5821template<typename Derived>
5822QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5823 ComplexTypeLoc T) {
5824 // FIXME: recurse?
5825 return TransformTypeSpecType(TLB, T);
5826}
5827
5828template <typename Derived>
5829QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5830 AdjustedTypeLoc TL) {
5831 // Adjustments applied during transformation are handled elsewhere.
5832 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5833}
5834
5835template<typename Derived>
5836QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5837 DecayedTypeLoc TL) {
5838 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5839 if (OriginalType.isNull())
5840 return QualType();
5841
5842 QualType Result = TL.getType();
5843 if (getDerived().AlwaysRebuild() ||
5844 OriginalType != TL.getOriginalLoc().getType())
5845 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5846 TLB.push<DecayedTypeLoc>(T: Result);
5847 // Nothing to set for DecayedTypeLoc.
5848 return Result;
5849}
5850
5851template <typename Derived>
5852QualType
5853TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5854 ArrayParameterTypeLoc TL) {
5855 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5856 if (OriginalType.isNull())
5857 return QualType();
5858
5859 QualType Result = TL.getType();
5860 if (getDerived().AlwaysRebuild() ||
5861 OriginalType != TL.getElementLoc().getType())
5862 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5863 TLB.push<ArrayParameterTypeLoc>(T: Result);
5864 // Nothing to set for ArrayParameterTypeLoc.
5865 return Result;
5866}
5867
5868template<typename Derived>
5869QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5870 PointerTypeLoc TL) {
5871 QualType PointeeType
5872 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5873 if (PointeeType.isNull())
5874 return QualType();
5875
5876 QualType Result = TL.getType();
5877 if (PointeeType->getAs<ObjCObjectType>()) {
5878 // A dependent pointer type 'T *' has is being transformed such
5879 // that an Objective-C class type is being replaced for 'T'. The
5880 // resulting pointer type is an ObjCObjectPointerType, not a
5881 // PointerType.
5882 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5883
5884 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5885 NewT.setStarLoc(TL.getStarLoc());
5886 return Result;
5887 }
5888
5889 if (getDerived().AlwaysRebuild() ||
5890 PointeeType != TL.getPointeeLoc().getType()) {
5891 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5892 if (Result.isNull())
5893 return QualType();
5894 }
5895
5896 // Objective-C ARC can add lifetime qualifiers to the type that we're
5897 // pointing to.
5898 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5899
5900 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5901 NewT.setSigilLoc(TL.getSigilLoc());
5902 return Result;
5903}
5904
5905template<typename Derived>
5906QualType
5907TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5908 BlockPointerTypeLoc TL) {
5909 QualType PointeeType
5910 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5911 if (PointeeType.isNull())
5912 return QualType();
5913
5914 QualType Result = TL.getType();
5915 if (getDerived().AlwaysRebuild() ||
5916 PointeeType != TL.getPointeeLoc().getType()) {
5917 Result = getDerived().RebuildBlockPointerType(PointeeType,
5918 TL.getSigilLoc());
5919 if (Result.isNull())
5920 return QualType();
5921 }
5922
5923 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5924 NewT.setSigilLoc(TL.getSigilLoc());
5925 return Result;
5926}
5927
5928/// Transforms a reference type. Note that somewhat paradoxically we
5929/// don't care whether the type itself is an l-value type or an r-value
5930/// type; we only care if the type was *written* as an l-value type
5931/// or an r-value type.
5932template<typename Derived>
5933QualType
5934TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5935 ReferenceTypeLoc TL) {
5936 const ReferenceType *T = TL.getTypePtr();
5937
5938 // Note that this works with the pointee-as-written.
5939 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5940 if (PointeeType.isNull())
5941 return QualType();
5942
5943 QualType Result = TL.getType();
5944 if (getDerived().AlwaysRebuild() ||
5945 PointeeType != T->getPointeeTypeAsWritten()) {
5946 Result = getDerived().RebuildReferenceType(PointeeType,
5947 T->isSpelledAsLValue(),
5948 TL.getSigilLoc());
5949 if (Result.isNull())
5950 return QualType();
5951 }
5952
5953 // Objective-C ARC can add lifetime qualifiers to the type that we're
5954 // referring to.
5955 TLB.TypeWasModifiedSafely(
5956 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5957
5958 // r-value references can be rebuilt as l-value references.
5959 ReferenceTypeLoc NewTL;
5960 if (isa<LValueReferenceType>(Val: Result))
5961 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5962 else
5963 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5964 NewTL.setSigilLoc(TL.getSigilLoc());
5965
5966 return Result;
5967}
5968
5969template<typename Derived>
5970QualType
5971TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5972 LValueReferenceTypeLoc TL) {
5973 return TransformReferenceType(TLB, TL);
5974}
5975
5976template<typename Derived>
5977QualType
5978TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5979 RValueReferenceTypeLoc TL) {
5980 return TransformReferenceType(TLB, TL);
5981}
5982
5983template<typename Derived>
5984QualType
5985TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5986 MemberPointerTypeLoc TL) {
5987 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5988 if (PointeeType.isNull())
5989 return QualType();
5990
5991 const MemberPointerType *T = TL.getTypePtr();
5992
5993 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5994 NestedNameSpecifierLoc NewQualifierLoc =
5995 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5996 if (!NewQualifierLoc)
5997 return QualType();
5998
5999 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
6000 if (OldCls) {
6001 NewCls = cast_or_null<CXXRecordDecl>(
6002 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
6003 if (!NewCls)
6004 return QualType();
6005 }
6006
6007 QualType Result = TL.getType();
6008 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
6009 NewQualifierLoc.getNestedNameSpecifier() !=
6010 OldQualifierLoc.getNestedNameSpecifier() ||
6011 NewCls != OldCls) {
6012 CXXScopeSpec SS;
6013 SS.Adopt(Other: NewQualifierLoc);
6014 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
6015 TL.getStarLoc());
6016 if (Result.isNull())
6017 return QualType();
6018 }
6019
6020 // If we had to adjust the pointee type when building a member pointer, make
6021 // sure to push TypeLoc info for it.
6022 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
6023 if (MPT && PointeeType != MPT->getPointeeType()) {
6024 assert(isa<AdjustedType>(MPT->getPointeeType()));
6025 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
6026 }
6027
6028 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
6029 NewTL.setSigilLoc(TL.getSigilLoc());
6030 NewTL.setQualifierLoc(NewQualifierLoc);
6031
6032 return Result;
6033}
6034
6035template<typename Derived>
6036QualType
6037TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
6038 ConstantArrayTypeLoc TL) {
6039 const ConstantArrayType *T = TL.getTypePtr();
6040 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6041 if (ElementType.isNull())
6042 return QualType();
6043
6044 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6045 Expr *OldSize = TL.getSizeExpr();
6046 if (!OldSize)
6047 OldSize = const_cast<Expr*>(T->getSizeExpr());
6048 Expr *NewSize = nullptr;
6049 if (OldSize) {
6050 EnterExpressionEvaluationContext Unevaluated(
6051 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6052 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
6053 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
6054 }
6055
6056 QualType Result = TL.getType();
6057 if (getDerived().AlwaysRebuild() ||
6058 ElementType != T->getElementType() ||
6059 (T->getSizeExpr() && NewSize != OldSize)) {
6060 Result = getDerived().RebuildConstantArrayType(ElementType,
6061 T->getSizeModifier(),
6062 T->getSize(), NewSize,
6063 T->getIndexTypeCVRQualifiers(),
6064 TL.getBracketsRange());
6065 if (Result.isNull())
6066 return QualType();
6067 }
6068
6069 // We might have either a ConstantArrayType or a VariableArrayType now:
6070 // a ConstantArrayType is allowed to have an element type which is a
6071 // VariableArrayType if the type is dependent. Fortunately, all array
6072 // types have the same location layout.
6073 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6074 NewTL.setLBracketLoc(TL.getLBracketLoc());
6075 NewTL.setRBracketLoc(TL.getRBracketLoc());
6076 NewTL.setSizeExpr(NewSize);
6077
6078 return Result;
6079}
6080
6081template<typename Derived>
6082QualType TreeTransform<Derived>::TransformIncompleteArrayType(
6083 TypeLocBuilder &TLB,
6084 IncompleteArrayTypeLoc TL) {
6085 const IncompleteArrayType *T = TL.getTypePtr();
6086 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6087 if (ElementType.isNull())
6088 return QualType();
6089
6090 QualType Result = TL.getType();
6091 if (getDerived().AlwaysRebuild() ||
6092 ElementType != T->getElementType()) {
6093 Result = getDerived().RebuildIncompleteArrayType(ElementType,
6094 T->getSizeModifier(),
6095 T->getIndexTypeCVRQualifiers(),
6096 TL.getBracketsRange());
6097 if (Result.isNull())
6098 return QualType();
6099 }
6100
6101 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
6102 NewTL.setLBracketLoc(TL.getLBracketLoc());
6103 NewTL.setRBracketLoc(TL.getRBracketLoc());
6104 NewTL.setSizeExpr(nullptr);
6105
6106 return Result;
6107}
6108
6109template<typename Derived>
6110QualType
6111TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
6112 VariableArrayTypeLoc TL) {
6113 const VariableArrayType *T = TL.getTypePtr();
6114 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6115 if (ElementType.isNull())
6116 return QualType();
6117
6118 ExprResult SizeResult;
6119 {
6120 EnterExpressionEvaluationContext Context(
6121 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
6122 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
6123 }
6124 if (SizeResult.isInvalid())
6125 return QualType();
6126 SizeResult =
6127 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
6128 if (SizeResult.isInvalid())
6129 return QualType();
6130
6131 Expr *Size = SizeResult.get();
6132
6133 QualType Result = TL.getType();
6134 if (getDerived().AlwaysRebuild() ||
6135 ElementType != T->getElementType() ||
6136 Size != T->getSizeExpr()) {
6137 Result = getDerived().RebuildVariableArrayType(ElementType,
6138 T->getSizeModifier(),
6139 Size,
6140 T->getIndexTypeCVRQualifiers(),
6141 TL.getBracketsRange());
6142 if (Result.isNull())
6143 return QualType();
6144 }
6145
6146 // We might have constant size array now, but fortunately it has the same
6147 // location layout.
6148 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6149 NewTL.setLBracketLoc(TL.getLBracketLoc());
6150 NewTL.setRBracketLoc(TL.getRBracketLoc());
6151 NewTL.setSizeExpr(Size);
6152
6153 return Result;
6154}
6155
6156template<typename Derived>
6157QualType
6158TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6159 DependentSizedArrayTypeLoc TL) {
6160 const DependentSizedArrayType *T = TL.getTypePtr();
6161 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6162 if (ElementType.isNull())
6163 return QualType();
6164
6165 // Array bounds are constant expressions.
6166 EnterExpressionEvaluationContext Unevaluated(
6167 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6168
6169 // If we have a VLA then it won't be a constant.
6170 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6171
6172 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6173 Expr *origSize = TL.getSizeExpr();
6174 if (!origSize) origSize = T->getSizeExpr();
6175
6176 ExprResult sizeResult
6177 = getDerived().TransformExpr(origSize);
6178 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6179 if (sizeResult.isInvalid())
6180 return QualType();
6181
6182 Expr *size = sizeResult.get();
6183
6184 QualType Result = TL.getType();
6185 if (getDerived().AlwaysRebuild() ||
6186 ElementType != T->getElementType() ||
6187 size != origSize) {
6188 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6189 T->getSizeModifier(),
6190 size,
6191 T->getIndexTypeCVRQualifiers(),
6192 TL.getBracketsRange());
6193 if (Result.isNull())
6194 return QualType();
6195 }
6196
6197 // We might have any sort of array type now, but fortunately they
6198 // all have the same location layout.
6199 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6200 NewTL.setLBracketLoc(TL.getLBracketLoc());
6201 NewTL.setRBracketLoc(TL.getRBracketLoc());
6202 NewTL.setSizeExpr(size);
6203
6204 return Result;
6205}
6206
6207template <typename Derived>
6208QualType TreeTransform<Derived>::TransformDependentVectorType(
6209 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6210 const DependentVectorType *T = TL.getTypePtr();
6211 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6212 if (ElementType.isNull())
6213 return QualType();
6214
6215 EnterExpressionEvaluationContext Unevaluated(
6216 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6217
6218 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6219 Size = SemaRef.ActOnConstantExpression(Res: Size);
6220 if (Size.isInvalid())
6221 return QualType();
6222
6223 QualType Result = TL.getType();
6224 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6225 Size.get() != T->getSizeExpr()) {
6226 Result = getDerived().RebuildDependentVectorType(
6227 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6228 if (Result.isNull())
6229 return QualType();
6230 }
6231
6232 // Result might be dependent or not.
6233 if (isa<DependentVectorType>(Val: Result)) {
6234 DependentVectorTypeLoc NewTL =
6235 TLB.push<DependentVectorTypeLoc>(T: Result);
6236 NewTL.setNameLoc(TL.getNameLoc());
6237 } else {
6238 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6239 NewTL.setNameLoc(TL.getNameLoc());
6240 }
6241
6242 return Result;
6243}
6244
6245template<typename Derived>
6246QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6247 TypeLocBuilder &TLB,
6248 DependentSizedExtVectorTypeLoc TL) {
6249 const DependentSizedExtVectorType *T = TL.getTypePtr();
6250
6251 // FIXME: ext vector locs should be nested
6252 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6253 if (ElementType.isNull())
6254 return QualType();
6255
6256 // Vector sizes are constant expressions.
6257 EnterExpressionEvaluationContext Unevaluated(
6258 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6259
6260 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6261 Size = SemaRef.ActOnConstantExpression(Res: Size);
6262 if (Size.isInvalid())
6263 return QualType();
6264
6265 QualType Result = TL.getType();
6266 if (getDerived().AlwaysRebuild() ||
6267 ElementType != T->getElementType() ||
6268 Size.get() != T->getSizeExpr()) {
6269 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6270 Size.get(),
6271 T->getAttributeLoc());
6272 if (Result.isNull())
6273 return QualType();
6274 }
6275
6276 // Result might be dependent or not.
6277 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6278 DependentSizedExtVectorTypeLoc NewTL
6279 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6280 NewTL.setNameLoc(TL.getNameLoc());
6281 } else {
6282 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6283 NewTL.setNameLoc(TL.getNameLoc());
6284 }
6285
6286 return Result;
6287}
6288
6289template <typename Derived>
6290QualType
6291TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6292 ConstantMatrixTypeLoc TL) {
6293 const ConstantMatrixType *T = TL.getTypePtr();
6294 QualType ElementType = getDerived().TransformType(T->getElementType());
6295 if (ElementType.isNull())
6296 return QualType();
6297
6298 QualType Result = TL.getType();
6299 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6300 Result = getDerived().RebuildConstantMatrixType(
6301 ElementType, T->getNumRows(), T->getNumColumns(), TL.getAttrNameLoc());
6302 if (Result.isNull())
6303 return QualType();
6304 }
6305
6306 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6307 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6308 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6309 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6310 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6311
6312 return Result;
6313}
6314
6315template <typename Derived>
6316QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6317 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6318 const DependentSizedMatrixType *T = TL.getTypePtr();
6319
6320 QualType ElementType = getDerived().TransformType(T->getElementType());
6321 if (ElementType.isNull()) {
6322 return QualType();
6323 }
6324
6325 // Matrix dimensions are constant expressions.
6326 EnterExpressionEvaluationContext Unevaluated(
6327 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6328
6329 Expr *origRows = TL.getAttrRowOperand();
6330 if (!origRows)
6331 origRows = T->getRowExpr();
6332 Expr *origColumns = TL.getAttrColumnOperand();
6333 if (!origColumns)
6334 origColumns = T->getColumnExpr();
6335
6336 ExprResult rowResult = getDerived().TransformExpr(origRows);
6337 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6338 if (rowResult.isInvalid())
6339 return QualType();
6340
6341 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6342 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6343 if (columnResult.isInvalid())
6344 return QualType();
6345
6346 Expr *rows = rowResult.get();
6347 Expr *columns = columnResult.get();
6348
6349 QualType Result = TL.getType();
6350 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6351 rows != origRows || columns != origColumns) {
6352 Result = getDerived().RebuildDependentSizedMatrixType(
6353 ElementType, rows, columns, T->getAttributeLoc());
6354
6355 if (Result.isNull())
6356 return QualType();
6357 }
6358
6359 // We might have any sort of matrix type now, but fortunately they
6360 // all have the same location layout.
6361 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6362 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6363 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6364 NewTL.setAttrRowOperand(rows);
6365 NewTL.setAttrColumnOperand(columns);
6366 return Result;
6367}
6368
6369template <typename Derived>
6370QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6371 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6372 const DependentAddressSpaceType *T = TL.getTypePtr();
6373
6374 QualType pointeeType =
6375 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6376
6377 if (pointeeType.isNull())
6378 return QualType();
6379
6380 // Address spaces are constant expressions.
6381 EnterExpressionEvaluationContext Unevaluated(
6382 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6383
6384 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6385 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6386 if (AddrSpace.isInvalid())
6387 return QualType();
6388
6389 QualType Result = TL.getType();
6390 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6391 AddrSpace.get() != T->getAddrSpaceExpr()) {
6392 Result = getDerived().RebuildDependentAddressSpaceType(
6393 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6394 if (Result.isNull())
6395 return QualType();
6396 }
6397
6398 // Result might be dependent or not.
6399 if (isa<DependentAddressSpaceType>(Val: Result)) {
6400 DependentAddressSpaceTypeLoc NewTL =
6401 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6402
6403 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6404 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6405 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6406
6407 } else {
6408 TLB.TypeWasModifiedSafely(T: Result);
6409 }
6410
6411 return Result;
6412}
6413
6414template <typename Derived>
6415QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6416 VectorTypeLoc TL) {
6417 const VectorType *T = TL.getTypePtr();
6418 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6419 if (ElementType.isNull())
6420 return QualType();
6421
6422 QualType Result = TL.getType();
6423 if (getDerived().AlwaysRebuild() ||
6424 ElementType != T->getElementType()) {
6425 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6426 T->getVectorKind());
6427 if (Result.isNull())
6428 return QualType();
6429 }
6430
6431 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6432 NewTL.setNameLoc(TL.getNameLoc());
6433
6434 return Result;
6435}
6436
6437template<typename Derived>
6438QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6439 ExtVectorTypeLoc TL) {
6440 const VectorType *T = TL.getTypePtr();
6441 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6442 if (ElementType.isNull())
6443 return QualType();
6444
6445 QualType Result = TL.getType();
6446 if (getDerived().AlwaysRebuild() ||
6447 ElementType != T->getElementType()) {
6448 Result = getDerived().RebuildExtVectorType(ElementType,
6449 T->getNumElements(),
6450 /*FIXME*/ SourceLocation());
6451 if (Result.isNull())
6452 return QualType();
6453 }
6454
6455 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6456 NewTL.setNameLoc(TL.getNameLoc());
6457
6458 return Result;
6459}
6460
6461template <typename Derived>
6462ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6463 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6464 bool ExpectParameterPack) {
6465 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6466 TypeSourceInfo *NewTSI = nullptr;
6467
6468 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6469 // If we're substituting into a pack expansion type and we know the
6470 // length we want to expand to, just substitute for the pattern.
6471 TypeLoc OldTL = OldTSI->getTypeLoc();
6472 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6473
6474 TypeLocBuilder TLB;
6475 TypeLoc NewTL = OldTSI->getTypeLoc();
6476 TLB.reserve(Requested: NewTL.getFullDataSize());
6477
6478 QualType Result = getDerived().TransformType(TLB,
6479 OldExpansionTL.getPatternLoc());
6480 if (Result.isNull())
6481 return nullptr;
6482
6483 Result = RebuildPackExpansionType(Pattern: Result,
6484 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6485 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6486 NumExpansions);
6487 if (Result.isNull())
6488 return nullptr;
6489
6490 PackExpansionTypeLoc NewExpansionTL
6491 = TLB.push<PackExpansionTypeLoc>(T: Result);
6492 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6493 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6494 } else
6495 NewTSI = getDerived().TransformType(OldTSI);
6496 if (!NewTSI)
6497 return nullptr;
6498
6499 if (NewTSI == OldTSI && indexAdjustment == 0)
6500 return OldParm;
6501
6502 ParmVarDecl *newParm = ParmVarDecl::Create(
6503 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6504 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6505 TInfo: NewTSI, S: OldParm->getStorageClass(),
6506 /* DefArg */ DefArg: nullptr);
6507 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6508 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6509 getDerived().transformedLocalDecl(OldParm, {newParm});
6510 return newParm;
6511}
6512
6513template <typename Derived>
6514bool TreeTransform<Derived>::TransformFunctionTypeParams(
6515 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6516 const QualType *ParamTypes,
6517 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6518 SmallVectorImpl<QualType> &OutParamTypes,
6519 SmallVectorImpl<ParmVarDecl *> *PVars,
6520 Sema::ExtParameterInfoBuilder &PInfos,
6521 unsigned *LastParamTransformed) {
6522 int indexAdjustment = 0;
6523
6524 unsigned NumParams = Params.size();
6525 for (unsigned i = 0; i != NumParams; ++i) {
6526 if (LastParamTransformed)
6527 *LastParamTransformed = i;
6528 if (ParmVarDecl *OldParm = Params[i]) {
6529 assert(OldParm->getFunctionScopeIndex() == i);
6530
6531 UnsignedOrNone NumExpansions = std::nullopt;
6532 ParmVarDecl *NewParm = nullptr;
6533 if (OldParm->isParameterPack()) {
6534 // We have a function parameter pack that may need to be expanded.
6535 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6536
6537 // Find the parameter packs that could be expanded.
6538 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6539 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6540 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6541 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6542
6543 // Determine whether we should expand the parameter packs.
6544 bool ShouldExpand = false;
6545 bool RetainExpansion = false;
6546 UnsignedOrNone OrigNumExpansions = std::nullopt;
6547 if (Unexpanded.size() > 0) {
6548 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6549 NumExpansions = OrigNumExpansions;
6550 if (getDerived().TryExpandParameterPacks(
6551 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6552 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6553 ShouldExpand, RetainExpansion, NumExpansions)) {
6554 return true;
6555 }
6556 } else {
6557#ifndef NDEBUG
6558 const AutoType *AT =
6559 Pattern.getType().getTypePtr()->getContainedAutoType();
6560 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6561 "Could not find parameter packs or undeduced auto type!");
6562#endif
6563 }
6564
6565 if (ShouldExpand) {
6566 // Expand the function parameter pack into multiple, separate
6567 // parameters.
6568 getDerived().ExpandingFunctionParameterPack(OldParm);
6569 for (unsigned I = 0; I != *NumExpansions; ++I) {
6570 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6571 ParmVarDecl *NewParm
6572 = getDerived().TransformFunctionTypeParam(OldParm,
6573 indexAdjustment++,
6574 OrigNumExpansions,
6575 /*ExpectParameterPack=*/false);
6576 if (!NewParm)
6577 return true;
6578
6579 if (ParamInfos)
6580 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6581 OutParamTypes.push_back(Elt: NewParm->getType());
6582 if (PVars)
6583 PVars->push_back(Elt: NewParm);
6584 }
6585
6586 // If we're supposed to retain a pack expansion, do so by temporarily
6587 // forgetting the partially-substituted parameter pack.
6588 if (RetainExpansion) {
6589 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6590 ParmVarDecl *NewParm
6591 = getDerived().TransformFunctionTypeParam(OldParm,
6592 indexAdjustment++,
6593 OrigNumExpansions,
6594 /*ExpectParameterPack=*/false);
6595 if (!NewParm)
6596 return true;
6597
6598 if (ParamInfos)
6599 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6600 OutParamTypes.push_back(Elt: NewParm->getType());
6601 if (PVars)
6602 PVars->push_back(Elt: NewParm);
6603 }
6604
6605 // The next parameter should have the same adjustment as the
6606 // last thing we pushed, but we post-incremented indexAdjustment
6607 // on every push. Also, if we push nothing, the adjustment should
6608 // go down by one.
6609 indexAdjustment--;
6610
6611 // We're done with the pack expansion.
6612 continue;
6613 }
6614
6615 // We'll substitute the parameter now without expanding the pack
6616 // expansion.
6617 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6618 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6619 indexAdjustment,
6620 NumExpansions,
6621 /*ExpectParameterPack=*/true);
6622 assert(NewParm->isParameterPack() &&
6623 "Parameter pack no longer a parameter pack after "
6624 "transformation.");
6625 } else {
6626 NewParm = getDerived().TransformFunctionTypeParam(
6627 OldParm, indexAdjustment, std::nullopt,
6628 /*ExpectParameterPack=*/false);
6629 }
6630
6631 if (!NewParm)
6632 return true;
6633
6634 if (ParamInfos)
6635 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6636 OutParamTypes.push_back(Elt: NewParm->getType());
6637 if (PVars)
6638 PVars->push_back(Elt: NewParm);
6639 continue;
6640 }
6641
6642 // Deal with the possibility that we don't have a parameter
6643 // declaration for this parameter.
6644 assert(ParamTypes);
6645 QualType OldType = ParamTypes[i];
6646 bool IsPackExpansion = false;
6647 UnsignedOrNone NumExpansions = std::nullopt;
6648 QualType NewType;
6649 if (const PackExpansionType *Expansion
6650 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6651 // We have a function parameter pack that may need to be expanded.
6652 QualType Pattern = Expansion->getPattern();
6653 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6654 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6655
6656 // Determine whether we should expand the parameter packs.
6657 bool ShouldExpand = false;
6658 bool RetainExpansion = false;
6659 if (getDerived().TryExpandParameterPacks(
6660 Loc, SourceRange(), Unexpanded,
6661 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6662 RetainExpansion, NumExpansions)) {
6663 return true;
6664 }
6665
6666 if (ShouldExpand) {
6667 // Expand the function parameter pack into multiple, separate
6668 // parameters.
6669 for (unsigned I = 0; I != *NumExpansions; ++I) {
6670 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6671 QualType NewType = getDerived().TransformType(Pattern);
6672 if (NewType.isNull())
6673 return true;
6674
6675 if (NewType->containsUnexpandedParameterPack()) {
6676 NewType = getSema().getASTContext().getPackExpansionType(
6677 NewType, std::nullopt);
6678
6679 if (NewType.isNull())
6680 return true;
6681 }
6682
6683 if (ParamInfos)
6684 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6685 OutParamTypes.push_back(Elt: NewType);
6686 if (PVars)
6687 PVars->push_back(Elt: nullptr);
6688 }
6689
6690 // We're done with the pack expansion.
6691 continue;
6692 }
6693
6694 // If we're supposed to retain a pack expansion, do so by temporarily
6695 // forgetting the partially-substituted parameter pack.
6696 if (RetainExpansion) {
6697 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6698 QualType NewType = getDerived().TransformType(Pattern);
6699 if (NewType.isNull())
6700 return true;
6701
6702 if (ParamInfos)
6703 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6704 OutParamTypes.push_back(Elt: NewType);
6705 if (PVars)
6706 PVars->push_back(Elt: nullptr);
6707 }
6708
6709 // We'll substitute the parameter now without expanding the pack
6710 // expansion.
6711 OldType = Expansion->getPattern();
6712 IsPackExpansion = true;
6713 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6714 NewType = getDerived().TransformType(OldType);
6715 } else {
6716 NewType = getDerived().TransformType(OldType);
6717 }
6718
6719 if (NewType.isNull())
6720 return true;
6721
6722 if (IsPackExpansion)
6723 NewType = getSema().Context.getPackExpansionType(NewType,
6724 NumExpansions);
6725
6726 if (ParamInfos)
6727 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6728 OutParamTypes.push_back(Elt: NewType);
6729 if (PVars)
6730 PVars->push_back(Elt: nullptr);
6731 }
6732
6733#ifndef NDEBUG
6734 if (PVars) {
6735 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6736 if (ParmVarDecl *parm = (*PVars)[i])
6737 assert(parm->getFunctionScopeIndex() == i);
6738 }
6739#endif
6740
6741 return false;
6742}
6743
6744template<typename Derived>
6745QualType
6746TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6747 FunctionProtoTypeLoc TL) {
6748 SmallVector<QualType, 4> ExceptionStorage;
6749 return getDerived().TransformFunctionProtoType(
6750 TLB, TL, nullptr, Qualifiers(),
6751 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6752 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6753 ExceptionStorage, Changed);
6754 });
6755}
6756
6757template<typename Derived> template<typename Fn>
6758QualType TreeTransform<Derived>::TransformFunctionProtoType(
6759 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6760 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6761
6762 // Transform the parameters and return type.
6763 //
6764 // We are required to instantiate the params and return type in source order.
6765 // When the function has a trailing return type, we instantiate the
6766 // parameters before the return type, since the return type can then refer
6767 // to the parameters themselves (via decltype, sizeof, etc.).
6768 //
6769 SmallVector<QualType, 4> ParamTypes;
6770 SmallVector<ParmVarDecl*, 4> ParamDecls;
6771 Sema::ExtParameterInfoBuilder ExtParamInfos;
6772 const FunctionProtoType *T = TL.getTypePtr();
6773
6774 QualType ResultType;
6775
6776 if (T->hasTrailingReturn()) {
6777 if (getDerived().TransformFunctionTypeParams(
6778 TL.getBeginLoc(), TL.getParams(),
6779 TL.getTypePtr()->param_type_begin(),
6780 T->getExtParameterInfosOrNull(),
6781 ParamTypes, &ParamDecls, ExtParamInfos))
6782 return QualType();
6783
6784 {
6785 // C++11 [expr.prim.general]p3:
6786 // If a declaration declares a member function or member function
6787 // template of a class X, the expression this is a prvalue of type
6788 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6789 // and the end of the function-definition, member-declarator, or
6790 // declarator.
6791 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6792 Sema::CXXThisScopeRAII ThisScope(
6793 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6794
6795 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6796 if (ResultType.isNull())
6797 return QualType();
6798 }
6799 }
6800 else {
6801 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6802 if (ResultType.isNull())
6803 return QualType();
6804
6805 if (getDerived().TransformFunctionTypeParams(
6806 TL.getBeginLoc(), TL.getParams(),
6807 TL.getTypePtr()->param_type_begin(),
6808 T->getExtParameterInfosOrNull(),
6809 ParamTypes, &ParamDecls, ExtParamInfos))
6810 return QualType();
6811 }
6812
6813 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6814
6815 bool EPIChanged = false;
6816 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6817 return QualType();
6818
6819 // Handle extended parameter information.
6820 if (auto NewExtParamInfos =
6821 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6822 if (!EPI.ExtParameterInfos ||
6823 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6824 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6825 EPIChanged = true;
6826 }
6827 EPI.ExtParameterInfos = NewExtParamInfos;
6828 } else if (EPI.ExtParameterInfos) {
6829 EPIChanged = true;
6830 EPI.ExtParameterInfos = nullptr;
6831 }
6832
6833 // Transform any function effects with unevaluated conditions.
6834 // Hold this set in a local for the rest of this function, since EPI
6835 // may need to hold a FunctionEffectsRef pointing into it.
6836 std::optional<FunctionEffectSet> NewFX;
6837 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6838 NewFX.emplace();
6839 EnterExpressionEvaluationContext Unevaluated(
6840 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6841
6842 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6843 FunctionEffectWithCondition NewEC = PrevEC;
6844 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6845 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6846 if (NewExpr.isInvalid())
6847 return QualType();
6848 std::optional<FunctionEffectMode> Mode =
6849 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6850 if (!Mode)
6851 return QualType();
6852
6853 // The condition expression has been transformed, and re-evaluated.
6854 // It may or may not have become constant.
6855 switch (*Mode) {
6856 case FunctionEffectMode::True:
6857 NewEC.Cond = {};
6858 break;
6859 case FunctionEffectMode::False:
6860 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6861 NewEC.Cond = {};
6862 break;
6863 case FunctionEffectMode::Dependent:
6864 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6865 break;
6866 case FunctionEffectMode::None:
6867 llvm_unreachable(
6868 "FunctionEffectMode::None shouldn't be possible here");
6869 }
6870 }
6871 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6872 NewAttrLoc: TL.getBeginLoc())) {
6873 FunctionEffectSet::Conflicts Errs;
6874 NewFX->insert(NewEC, Errs);
6875 assert(Errs.empty());
6876 }
6877 }
6878 EPI.FunctionEffects = *NewFX;
6879 EPIChanged = true;
6880 }
6881
6882 QualType Result = TL.getType();
6883 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6884 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6885 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6886 if (Result.isNull())
6887 return QualType();
6888 }
6889
6890 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6891 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6892 NewTL.setLParenLoc(TL.getLParenLoc());
6893 NewTL.setRParenLoc(TL.getRParenLoc());
6894 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6895 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6896 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6897 NewTL.setParam(i, VD: ParamDecls[i]);
6898
6899 return Result;
6900}
6901
6902template<typename Derived>
6903bool TreeTransform<Derived>::TransformExceptionSpec(
6904 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6905 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6906 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6907
6908 // Instantiate a dynamic noexcept expression, if any.
6909 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6910 // Update this scrope because ContextDecl in Sema will be used in
6911 // TransformExpr.
6912 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6913 Sema::CXXThisScopeRAII ThisScope(
6914 SemaRef, Method ? Method->getParent() : nullptr,
6915 Method ? Method->getMethodQualifiers() : Qualifiers{},
6916 Method != nullptr);
6917 EnterExpressionEvaluationContext Unevaluated(
6918 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6919 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6920 if (NoexceptExpr.isInvalid())
6921 return true;
6922
6923 ExceptionSpecificationType EST = ESI.Type;
6924 NoexceptExpr =
6925 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6926 if (NoexceptExpr.isInvalid())
6927 return true;
6928
6929 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6930 Changed = true;
6931 ESI.NoexceptExpr = NoexceptExpr.get();
6932 ESI.Type = EST;
6933 }
6934
6935 if (ESI.Type != EST_Dynamic)
6936 return false;
6937
6938 // Instantiate a dynamic exception specification's type.
6939 for (QualType T : ESI.Exceptions) {
6940 if (const PackExpansionType *PackExpansion =
6941 T->getAs<PackExpansionType>()) {
6942 Changed = true;
6943
6944 // We have a pack expansion. Instantiate it.
6945 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6946 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6947 Unexpanded);
6948 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6949
6950 // Determine whether the set of unexpanded parameter packs can and
6951 // should
6952 // be expanded.
6953 bool Expand = false;
6954 bool RetainExpansion = false;
6955 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6956 // FIXME: Track the location of the ellipsis (and track source location
6957 // information for the types in the exception specification in general).
6958 if (getDerived().TryExpandParameterPacks(
6959 Loc, SourceRange(), Unexpanded,
6960 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6961 NumExpansions))
6962 return true;
6963
6964 if (!Expand) {
6965 // We can't expand this pack expansion into separate arguments yet;
6966 // just substitute into the pattern and create a new pack expansion
6967 // type.
6968 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6969 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6970 if (U.isNull())
6971 return true;
6972
6973 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6974 Exceptions.push_back(Elt: U);
6975 continue;
6976 }
6977
6978 // Substitute into the pack expansion pattern for each slice of the
6979 // pack.
6980 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6981 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6982
6983 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6984 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6985 return true;
6986
6987 Exceptions.push_back(Elt: U);
6988 }
6989 } else {
6990 QualType U = getDerived().TransformType(T);
6991 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6992 return true;
6993 if (T != U)
6994 Changed = true;
6995
6996 Exceptions.push_back(Elt: U);
6997 }
6998 }
6999
7000 ESI.Exceptions = Exceptions;
7001 if (ESI.Exceptions.empty())
7002 ESI.Type = EST_DynamicNone;
7003 return false;
7004}
7005
7006template<typename Derived>
7007QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
7008 TypeLocBuilder &TLB,
7009 FunctionNoProtoTypeLoc TL) {
7010 const FunctionNoProtoType *T = TL.getTypePtr();
7011 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
7012 if (ResultType.isNull())
7013 return QualType();
7014
7015 QualType Result = TL.getType();
7016 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
7017 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
7018
7019 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
7020 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
7021 NewTL.setLParenLoc(TL.getLParenLoc());
7022 NewTL.setRParenLoc(TL.getRParenLoc());
7023 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
7024
7025 return Result;
7026}
7027
7028template <typename Derived>
7029QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
7030 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
7031
7032 const UnresolvedUsingType *T = TL.getTypePtr();
7033 bool Changed = false;
7034
7035 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7036 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7037 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7038 if (!QualifierLoc)
7039 return QualType();
7040 Changed |= QualifierLoc != OldQualifierLoc;
7041 }
7042
7043 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
7044 if (!D)
7045 return QualType();
7046 Changed |= D != T->getDecl();
7047
7048 QualType Result = TL.getType();
7049 if (getDerived().AlwaysRebuild() || Changed) {
7050 Result = getDerived().RebuildUnresolvedUsingType(
7051 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
7052 D);
7053 if (Result.isNull())
7054 return QualType();
7055 }
7056
7057 if (isa<UsingType>(Val: Result))
7058 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7059 QualifierLoc, NameLoc: TL.getNameLoc());
7060 else
7061 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7062 QualifierLoc, NameLoc: TL.getNameLoc());
7063 return Result;
7064}
7065
7066template <typename Derived>
7067QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
7068 UsingTypeLoc TL) {
7069 const UsingType *T = TL.getTypePtr();
7070 bool Changed = false;
7071
7072 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7073 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7074 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7075 if (!QualifierLoc)
7076 return QualType();
7077 Changed |= QualifierLoc != OldQualifierLoc;
7078 }
7079
7080 auto *D = cast_or_null<UsingShadowDecl>(
7081 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7082 if (!D)
7083 return QualType();
7084 Changed |= D != T->getDecl();
7085
7086 QualType UnderlyingType = getDerived().TransformType(T->desugar());
7087 if (UnderlyingType.isNull())
7088 return QualType();
7089 Changed |= UnderlyingType != T->desugar();
7090
7091 QualType Result = TL.getType();
7092 if (getDerived().AlwaysRebuild() || Changed) {
7093 Result = getDerived().RebuildUsingType(
7094 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
7095 UnderlyingType);
7096 if (Result.isNull())
7097 return QualType();
7098 }
7099 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
7100 NameLoc: TL.getNameLoc());
7101 return Result;
7102}
7103
7104template<typename Derived>
7105QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
7106 TypedefTypeLoc TL) {
7107 const TypedefType *T = TL.getTypePtr();
7108 bool Changed = false;
7109
7110 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7111 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7112 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7113 if (!QualifierLoc)
7114 return QualType();
7115 Changed |= QualifierLoc != OldQualifierLoc;
7116 }
7117
7118 auto *Typedef = cast_or_null<TypedefNameDecl>(
7119 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7120 if (!Typedef)
7121 return QualType();
7122 Changed |= Typedef != T->getDecl();
7123
7124 // FIXME: Transform the UnderlyingType if different from decl.
7125
7126 QualType Result = TL.getType();
7127 if (getDerived().AlwaysRebuild() || Changed) {
7128 Result = getDerived().RebuildTypedefType(
7129 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
7130 if (Result.isNull())
7131 return QualType();
7132 }
7133
7134 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7135 QualifierLoc, NameLoc: TL.getNameLoc());
7136 return Result;
7137}
7138
7139template<typename Derived>
7140QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
7141 TypeOfExprTypeLoc TL) {
7142 // typeof expressions are not potentially evaluated contexts
7143 EnterExpressionEvaluationContext Unevaluated(
7144 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7145 Sema::ReuseLambdaContextDecl);
7146
7147 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7148 if (E.isInvalid())
7149 return QualType();
7150
7151 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7152 if (E.isInvalid())
7153 return QualType();
7154
7155 QualType Result = TL.getType();
7156 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7157 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7158 Result =
7159 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7160 if (Result.isNull())
7161 return QualType();
7162 }
7163
7164 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7165 NewTL.setTypeofLoc(TL.getTypeofLoc());
7166 NewTL.setLParenLoc(TL.getLParenLoc());
7167 NewTL.setRParenLoc(TL.getRParenLoc());
7168
7169 return Result;
7170}
7171
7172template<typename Derived>
7173QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7174 TypeOfTypeLoc TL) {
7175 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7176 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7177 if (!New_Under_TI)
7178 return QualType();
7179
7180 QualType Result = TL.getType();
7181 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7182 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7183 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7184 if (Result.isNull())
7185 return QualType();
7186 }
7187
7188 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7189 NewTL.setTypeofLoc(TL.getTypeofLoc());
7190 NewTL.setLParenLoc(TL.getLParenLoc());
7191 NewTL.setRParenLoc(TL.getRParenLoc());
7192 NewTL.setUnmodifiedTInfo(New_Under_TI);
7193
7194 return Result;
7195}
7196
7197template<typename Derived>
7198QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7199 DecltypeTypeLoc TL) {
7200 const DecltypeType *T = TL.getTypePtr();
7201
7202 // decltype expressions are not potentially evaluated contexts
7203 EnterExpressionEvaluationContext Unevaluated(
7204 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7205 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7206
7207 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7208 if (E.isInvalid())
7209 return QualType();
7210
7211 E = getSema().ActOnDecltypeExpression(E.get());
7212 if (E.isInvalid())
7213 return QualType();
7214
7215 QualType Result = TL.getType();
7216 if (getDerived().AlwaysRebuild() ||
7217 E.get() != T->getUnderlyingExpr()) {
7218 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7219 if (Result.isNull())
7220 return QualType();
7221 }
7222 else E.get();
7223
7224 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7225 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7226 NewTL.setRParenLoc(TL.getRParenLoc());
7227 return Result;
7228}
7229
7230template <typename Derived>
7231QualType
7232TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7233 PackIndexingTypeLoc TL) {
7234 // Transform the index
7235 ExprResult IndexExpr;
7236 {
7237 EnterExpressionEvaluationContext ConstantContext(
7238 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7239
7240 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7241 if (IndexExpr.isInvalid())
7242 return QualType();
7243 }
7244 QualType Pattern = TL.getPattern();
7245
7246 const PackIndexingType *PIT = TL.getTypePtr();
7247 SmallVector<QualType, 5> SubtitutedTypes;
7248 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7249
7250 bool NotYetExpanded = Types.empty();
7251 bool FullySubstituted = true;
7252
7253 if (Types.empty() && !PIT->expandsToEmptyPack())
7254 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7255
7256 for (QualType T : Types) {
7257 if (!T->containsUnexpandedParameterPack()) {
7258 QualType Transformed = getDerived().TransformType(T);
7259 if (Transformed.isNull())
7260 return QualType();
7261 SubtitutedTypes.push_back(Elt: Transformed);
7262 continue;
7263 }
7264
7265 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7266 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7267 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7268 // Determine whether the set of unexpanded parameter packs can and should
7269 // be expanded.
7270 bool ShouldExpand = true;
7271 bool RetainExpansion = false;
7272 UnsignedOrNone NumExpansions = std::nullopt;
7273 if (getDerived().TryExpandParameterPacks(
7274 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7275 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7276 RetainExpansion, NumExpansions))
7277 return QualType();
7278 if (!ShouldExpand) {
7279 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7280 // FIXME: should we keep TypeLoc for individual expansions in
7281 // PackIndexingTypeLoc?
7282 TypeSourceInfo *TI =
7283 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7284 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7285 if (Pack.isNull())
7286 return QualType();
7287 if (NotYetExpanded) {
7288 FullySubstituted = false;
7289 QualType Out = getDerived().RebuildPackIndexingType(
7290 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7291 FullySubstituted);
7292 if (Out.isNull())
7293 return QualType();
7294
7295 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7296 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7297 return Out;
7298 }
7299 SubtitutedTypes.push_back(Elt: Pack);
7300 continue;
7301 }
7302 for (unsigned I = 0; I != *NumExpansions; ++I) {
7303 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7304 QualType Out = getDerived().TransformType(T);
7305 if (Out.isNull())
7306 return QualType();
7307 SubtitutedTypes.push_back(Elt: Out);
7308 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7309 }
7310 // If we're supposed to retain a pack expansion, do so by temporarily
7311 // forgetting the partially-substituted parameter pack.
7312 if (RetainExpansion) {
7313 FullySubstituted = false;
7314 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7315 QualType Out = getDerived().TransformType(T);
7316 if (Out.isNull())
7317 return QualType();
7318 SubtitutedTypes.push_back(Elt: Out);
7319 }
7320 }
7321
7322 // A pack indexing type can appear in a larger pack expansion,
7323 // e.g. `Pack...[pack_of_indexes]...`
7324 // so we need to temporarily disable substitution of pack elements
7325 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7326 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7327
7328 QualType Out = getDerived().RebuildPackIndexingType(
7329 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7330 FullySubstituted, SubtitutedTypes);
7331 if (Out.isNull())
7332 return Out;
7333
7334 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7335 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7336 return Out;
7337}
7338
7339template<typename Derived>
7340QualType TreeTransform<Derived>::TransformUnaryTransformType(
7341 TypeLocBuilder &TLB,
7342 UnaryTransformTypeLoc TL) {
7343 QualType Result = TL.getType();
7344 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7345 if (Result->isDependentType()) {
7346 const UnaryTransformType *T = TL.getTypePtr();
7347
7348 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7349 if (!NewBaseTSI)
7350 return QualType();
7351 QualType NewBase = NewBaseTSI->getType();
7352
7353 Result = getDerived().RebuildUnaryTransformType(NewBase,
7354 T->getUTTKind(),
7355 TL.getKWLoc());
7356 if (Result.isNull())
7357 return QualType();
7358 }
7359
7360 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7361 NewTL.setKWLoc(TL.getKWLoc());
7362 NewTL.setParensRange(TL.getParensRange());
7363 NewTL.setUnderlyingTInfo(NewBaseTSI);
7364 return Result;
7365}
7366
7367template<typename Derived>
7368QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7369 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7370 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7371
7372 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7373 TemplateName TemplateName = getDerived().TransformTemplateName(
7374 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7375 TL.getTemplateNameLoc());
7376 if (TemplateName.isNull())
7377 return QualType();
7378
7379 QualType OldDeduced = T->getDeducedType();
7380 QualType NewDeduced;
7381 if (!OldDeduced.isNull()) {
7382 NewDeduced = getDerived().TransformType(OldDeduced);
7383 if (NewDeduced.isNull())
7384 return QualType();
7385 }
7386
7387 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7388 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7389 NewDeduced, T->getKeyword(), TemplateName);
7390 if (Result.isNull())
7391 return QualType();
7392
7393 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7394 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7395 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7396 NewTL.setQualifierLoc(QualifierLoc);
7397 return Result;
7398}
7399
7400template <typename Derived>
7401QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7402 TagTypeLoc TL) {
7403 const TagType *T = TL.getTypePtr();
7404
7405 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7406 if (QualifierLoc) {
7407 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7408 if (!QualifierLoc)
7409 return QualType();
7410 }
7411
7412 auto *TD = cast_or_null<TagDecl>(
7413 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7414 if (!TD)
7415 return QualType();
7416
7417 QualType Result = TL.getType();
7418 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7419 TD != T->getDecl()) {
7420 if (T->isCanonicalUnqualified())
7421 Result = getDerived().RebuildCanonicalTagType(TD);
7422 else
7423 Result = getDerived().RebuildTagType(
7424 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7425 if (Result.isNull())
7426 return QualType();
7427 }
7428
7429 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7430 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7431 NewTL.setQualifierLoc(QualifierLoc);
7432 NewTL.setNameLoc(TL.getNameLoc());
7433
7434 return Result;
7435}
7436
7437template <typename Derived>
7438QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7439 EnumTypeLoc TL) {
7440 return getDerived().TransformTagType(TLB, TL);
7441}
7442
7443template <typename Derived>
7444QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7445 RecordTypeLoc TL) {
7446 return getDerived().TransformTagType(TLB, TL);
7447}
7448
7449template<typename Derived>
7450QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7451 TypeLocBuilder &TLB,
7452 InjectedClassNameTypeLoc TL) {
7453 return getDerived().TransformTagType(TLB, TL);
7454}
7455
7456template<typename Derived>
7457QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7458 TypeLocBuilder &TLB,
7459 TemplateTypeParmTypeLoc TL) {
7460 return getDerived().TransformTemplateTypeParmType(
7461 TLB, TL,
7462 /*SuppressObjCLifetime=*/false);
7463}
7464
7465template <typename Derived>
7466QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7467 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7468 return TransformTypeSpecType(TLB, T: TL);
7469}
7470
7471template<typename Derived>
7472QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7473 TypeLocBuilder &TLB,
7474 SubstTemplateTypeParmTypeLoc TL) {
7475 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7476
7477 Decl *NewReplaced =
7478 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7479
7480 // Substitute into the replacement type, which itself might involve something
7481 // that needs to be transformed. This only tends to occur with default
7482 // template arguments of template template parameters.
7483 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7484 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7485 if (Replacement.isNull())
7486 return QualType();
7487
7488 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7489 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7490 Final: T->getFinal());
7491
7492 // Propagate type-source information.
7493 SubstTemplateTypeParmTypeLoc NewTL
7494 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7495 NewTL.setNameLoc(TL.getNameLoc());
7496 return Result;
7497
7498}
7499template <typename Derived>
7500QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7501 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7502 return TransformTypeSpecType(TLB, T: TL);
7503}
7504
7505template<typename Derived>
7506QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7507 TypeLocBuilder &TLB,
7508 SubstTemplateTypeParmPackTypeLoc TL) {
7509 return getDerived().TransformSubstTemplateTypeParmPackType(
7510 TLB, TL, /*SuppressObjCLifetime=*/false);
7511}
7512
7513template <typename Derived>
7514QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7515 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7516 return TransformTypeSpecType(TLB, T: TL);
7517}
7518
7519template<typename Derived>
7520QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7521 AtomicTypeLoc TL) {
7522 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7523 if (ValueType.isNull())
7524 return QualType();
7525
7526 QualType Result = TL.getType();
7527 if (getDerived().AlwaysRebuild() ||
7528 ValueType != TL.getValueLoc().getType()) {
7529 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7530 if (Result.isNull())
7531 return QualType();
7532 }
7533
7534 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7535 NewTL.setKWLoc(TL.getKWLoc());
7536 NewTL.setLParenLoc(TL.getLParenLoc());
7537 NewTL.setRParenLoc(TL.getRParenLoc());
7538
7539 return Result;
7540}
7541
7542template <typename Derived>
7543QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7544 PipeTypeLoc TL) {
7545 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7546 if (ValueType.isNull())
7547 return QualType();
7548
7549 QualType Result = TL.getType();
7550 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7551 const PipeType *PT = Result->castAs<PipeType>();
7552 bool isReadPipe = PT->isReadOnly();
7553 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7554 if (Result.isNull())
7555 return QualType();
7556 }
7557
7558 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7559 NewTL.setKWLoc(TL.getKWLoc());
7560
7561 return Result;
7562}
7563
7564template <typename Derived>
7565QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7566 BitIntTypeLoc TL) {
7567 const BitIntType *EIT = TL.getTypePtr();
7568 QualType Result = TL.getType();
7569
7570 if (getDerived().AlwaysRebuild()) {
7571 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7572 EIT->getNumBits(), TL.getNameLoc());
7573 if (Result.isNull())
7574 return QualType();
7575 }
7576
7577 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7578 NewTL.setNameLoc(TL.getNameLoc());
7579 return Result;
7580}
7581
7582template <typename Derived>
7583QualType TreeTransform<Derived>::TransformDependentBitIntType(
7584 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7585 const DependentBitIntType *EIT = TL.getTypePtr();
7586
7587 EnterExpressionEvaluationContext Unevaluated(
7588 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7589 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7590 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7591
7592 if (BitsExpr.isInvalid())
7593 return QualType();
7594
7595 QualType Result = TL.getType();
7596
7597 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7598 Result = getDerived().RebuildDependentBitIntType(
7599 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7600
7601 if (Result.isNull())
7602 return QualType();
7603 }
7604
7605 if (isa<DependentBitIntType>(Val: Result)) {
7606 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7607 NewTL.setNameLoc(TL.getNameLoc());
7608 } else {
7609 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7610 NewTL.setNameLoc(TL.getNameLoc());
7611 }
7612 return Result;
7613}
7614
7615template <typename Derived>
7616QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7617 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7618 llvm_unreachable("This type does not need to be transformed.");
7619}
7620
7621 /// Simple iterator that traverses the template arguments in a
7622 /// container that provides a \c getArgLoc() member function.
7623 ///
7624 /// This iterator is intended to be used with the iterator form of
7625 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7626 template<typename ArgLocContainer>
7627 class TemplateArgumentLocContainerIterator {
7628 ArgLocContainer *Container;
7629 unsigned Index;
7630
7631 public:
7632 typedef TemplateArgumentLoc value_type;
7633 typedef TemplateArgumentLoc reference;
7634 typedef int difference_type;
7635 typedef std::input_iterator_tag iterator_category;
7636
7637 class pointer {
7638 TemplateArgumentLoc Arg;
7639
7640 public:
7641 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7642
7643 const TemplateArgumentLoc *operator->() const {
7644 return &Arg;
7645 }
7646 };
7647
7648
7649 TemplateArgumentLocContainerIterator() {}
7650
7651 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7652 unsigned Index)
7653 : Container(&Container), Index(Index) { }
7654
7655 TemplateArgumentLocContainerIterator &operator++() {
7656 ++Index;
7657 return *this;
7658 }
7659
7660 TemplateArgumentLocContainerIterator operator++(int) {
7661 TemplateArgumentLocContainerIterator Old(*this);
7662 ++(*this);
7663 return Old;
7664 }
7665
7666 TemplateArgumentLoc operator*() const {
7667 return Container->getArgLoc(Index);
7668 }
7669
7670 pointer operator->() const {
7671 return pointer(Container->getArgLoc(Index));
7672 }
7673
7674 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7675 const TemplateArgumentLocContainerIterator &Y) {
7676 return X.Container == Y.Container && X.Index == Y.Index;
7677 }
7678
7679 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7680 const TemplateArgumentLocContainerIterator &Y) {
7681 return !(X == Y);
7682 }
7683 };
7684
7685template<typename Derived>
7686QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7687 AutoTypeLoc TL) {
7688 const AutoType *T = TL.getTypePtr();
7689 QualType OldDeduced = T->getDeducedType();
7690 QualType NewDeduced;
7691 if (!OldDeduced.isNull()) {
7692 NewDeduced = getDerived().TransformType(OldDeduced);
7693 if (NewDeduced.isNull())
7694 return QualType();
7695 }
7696
7697 TemplateName NewCD;
7698 TemplateArgumentListInfo NewTemplateArgs;
7699 NestedNameSpecifierLoc NewNestedNameSpec;
7700 if (T->isConstrained()) {
7701 assert(TL.getConceptReference());
7702 NewCD = getDerived().TransformConceptTemplateName(
7703 T->getTypeConstraintConcept(), TL.getConceptNameLoc());
7704 if (NewCD.isNull())
7705 return QualType();
7706
7707 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7708 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7709 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7710 if (getDerived().TransformTemplateArguments(
7711 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7712 NewTemplateArgs))
7713 return QualType();
7714
7715 if (TL.getNestedNameSpecifierLoc()) {
7716 NewNestedNameSpec
7717 = getDerived().TransformNestedNameSpecifierLoc(
7718 TL.getNestedNameSpecifierLoc());
7719 if (!NewNestedNameSpec)
7720 return QualType();
7721 }
7722 }
7723
7724 QualType Result = TL.getType();
7725 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7726 T->isDependentType() || T->isConstrained()) {
7727 // FIXME: Maybe don't rebuild if all template arguments are the same.
7728 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7729 NewArgList.reserve(N: NewTemplateArgs.size());
7730 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7731 NewArgList.push_back(Elt: ArgLoc.getArgument());
7732 Result = getDerived().RebuildAutoType(
7733 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7734 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7735 if (Result.isNull())
7736 return QualType();
7737 }
7738
7739 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7740 NewTL.setNameLoc(TL.getNameLoc());
7741 NewTL.setRParenLoc(TL.getRParenLoc());
7742 NewTL.setConceptReference(nullptr);
7743
7744 if (T->isConstrained()) {
7745 DeclarationName ConceptName =
7746 SemaRef.Context
7747 .getNameForTemplate(Name: TL.getTypePtr()->getTypeConstraintConcept(),
7748 NameLoc: TL.getConceptNameLoc())
7749 .getName();
7750 DeclarationNameInfo DNI =
7751 DeclarationNameInfo(ConceptName, TL.getConceptNameLoc(), ConceptName);
7752 auto *CR = ConceptReference::Create(
7753 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7754 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7755 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7756 NewTL.setConceptReference(CR);
7757 }
7758
7759 return Result;
7760}
7761
7762template <typename Derived>
7763QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7764 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7765 return getDerived().TransformTemplateSpecializationType(
7766 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7767 /*AllowInjectedClassName=*/false);
7768}
7769
7770template <typename Derived>
7771QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7772 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7773 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7774 const TemplateSpecializationType *T = TL.getTypePtr();
7775
7776 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7777 TemplateName Template = getDerived().TransformTemplateName(
7778 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7779 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7780 AllowInjectedClassName);
7781 if (Template.isNull())
7782 return QualType();
7783
7784 TemplateArgumentListInfo NewTemplateArgs;
7785 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7786 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7787 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7788 ArgIterator;
7789 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7790 ArgIterator(TL, TL.getNumArgs()),
7791 NewTemplateArgs))
7792 return QualType();
7793
7794 // This needs to be rebuilt if either the arguments changed, or if the
7795 // original template changed. If the template changed, and even if the
7796 // arguments didn't change, these arguments might not correspond to their
7797 // respective parameters, therefore needing conversions.
7798 QualType Result = getDerived().RebuildTemplateSpecializationType(
7799 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7800 NewTemplateArgs);
7801
7802 if (!Result.isNull()) {
7803 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7804 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7805 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7806 }
7807
7808 return Result;
7809}
7810
7811template <typename Derived>
7812QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7813 AttributedTypeLoc TL) {
7814 const AttributedType *oldType = TL.getTypePtr();
7815 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7816 if (modifiedType.isNull())
7817 return QualType();
7818
7819 // HLSL: re-validate matrix-layout markers after substitution. If the
7820 // post-substitution type is no longer a matrix, diagnose now.
7821 if (SemaRef.getLangOpts().HLSL &&
7822 SemaRef.HLSL().diagnoseMatrixLayoutInstantiation(
7823 K: oldType->getAttrKind(), T: modifiedType,
7824 Loc: TL.getAttr() ? TL.getAttr()->getLocation()
7825 : TL.getModifiedLoc().getBeginLoc()))
7826 return QualType();
7827
7828 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7829 const Attr *oldAttr = TL.getAttr();
7830 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7831 if (oldAttr && !newAttr)
7832 return QualType();
7833
7834 QualType result = TL.getType();
7835
7836 // FIXME: dependent operand expressions?
7837 if (getDerived().AlwaysRebuild() ||
7838 modifiedType != oldType->getModifiedType()) {
7839 // If the equivalent type is equal to the modified type, we don't want to
7840 // transform it as well because:
7841 //
7842 // 1. The transformation would yield the same result and is therefore
7843 // superfluous, and
7844 //
7845 // 2. Transforming the same type twice can cause problems, e.g. if it
7846 // is a FunctionProtoType, we may end up instantiating the function
7847 // parameters twice, which causes an assertion since the parameters
7848 // are already bound to their counterparts in the template for this
7849 // instantiation.
7850 //
7851 QualType equivalentType = modifiedType;
7852 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7853 TypeLocBuilder AuxiliaryTLB;
7854 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7855 equivalentType =
7856 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7857 if (equivalentType.isNull())
7858 return QualType();
7859 }
7860
7861 if (SemaRef.getLangOpts().HLSL) {
7862 if (oldType->getAttrKind() == attr::HLSLRowMajor)
7863 equivalentType = SemaRef.Context.getMatrixTypeWithLayout(
7864 T: equivalentType, Layout: MatrixType::LayoutKind::RowMajor);
7865 else if (oldType->getAttrKind() == attr::HLSLColumnMajor)
7866 equivalentType = SemaRef.Context.getMatrixTypeWithLayout(
7867 T: equivalentType, Layout: MatrixType::LayoutKind::ColumnMajor);
7868 }
7869
7870 // Check whether we can add nullability; it is only represented as
7871 // type sugar, and therefore cannot be diagnosed in any other way.
7872 if (auto nullability = oldType->getImmediateNullability()) {
7873 if (!modifiedType->canHaveNullability()) {
7874 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7875 : TL.getModifiedLoc().getBeginLoc()),
7876 DiagID: diag::err_nullability_nonpointer)
7877 << DiagNullabilityKind(*nullability, false) << modifiedType;
7878 return QualType();
7879 }
7880 }
7881
7882 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7883 modifiedType,
7884 equivalentType,
7885 attr: TL.getAttr());
7886 }
7887
7888 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7889 newTL.setAttr(newAttr);
7890 return result;
7891}
7892
7893template <typename Derived>
7894QualType TreeTransform<Derived>::TransformCountAttributedType(
7895 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7896 const CountAttributedType *OldTy = TL.getTypePtr();
7897 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7898 if (InnerTy.isNull())
7899 return QualType();
7900
7901 Expr *OldCount = TL.getCountExpr();
7902 Expr *NewCount = nullptr;
7903 if (OldCount) {
7904 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7905 if (CountResult.isInvalid())
7906 return QualType();
7907 NewCount = CountResult.get();
7908 }
7909
7910 QualType Result = TL.getType();
7911 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7912 OldCount != NewCount) {
7913 // Currently, CountAttributedType can only wrap incomplete array types.
7914 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7915 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7916 }
7917
7918 TLB.push<CountAttributedTypeLoc>(T: Result);
7919 return Result;
7920}
7921
7922template <typename Derived>
7923QualType
7924TreeTransform<Derived>::TransformLateParsedAttrType(TypeLocBuilder &TLB,
7925 LateParsedAttrTypeLoc TL) {
7926 const LateParsedAttrType *OldTy = TL.getTypePtr();
7927 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7928 if (InnerTy.isNull())
7929 return QualType();
7930
7931 QualType Result = TL.getType();
7932 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getWrappedType()) {
7933 Result = SemaRef.Context.getLateParsedAttrType(
7934 Wrapped: InnerTy, LateParsedAttr: OldTy->getLateParsedAttribute());
7935 }
7936
7937 LateParsedAttrTypeLoc newTL = TLB.push<LateParsedAttrTypeLoc>(T: Result);
7938 newTL.setAttrNameLoc(TL.getAttrNameLoc());
7939 return Result;
7940}
7941
7942template <typename Derived>
7943QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7944 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7945 // The BTFTagAttributedType is available for C only.
7946 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7947}
7948
7949template <typename Derived>
7950QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7951 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7952 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7953 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7954 if (InnerTy.isNull())
7955 return QualType();
7956
7957 QualType Result = TL.getType();
7958 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7959 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7960 Wrapped: InnerTy);
7961 if (Result.isNull())
7962 return QualType();
7963 }
7964
7965 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7966 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7967 return Result;
7968}
7969
7970template <typename Derived>
7971QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7972 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7973
7974 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7975
7976 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7977 if (WrappedTy.isNull())
7978 return QualType();
7979
7980 QualType ContainedTy = QualType();
7981 QualType OldContainedTy = oldType->getContainedType();
7982 TypeSourceInfo *ContainedTSI = nullptr;
7983 if (!OldContainedTy.isNull()) {
7984 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7985 if (!oldContainedTSI)
7986 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7987 OldContainedTy, SourceLocation());
7988 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7989 if (!ContainedTSI)
7990 return QualType();
7991 ContainedTy = ContainedTSI->getType();
7992 }
7993
7994 HLSLAttributedResourceType::Attributes Attrs = oldType->getAttrs();
7995 if (Attrs.SampleCountExpr) {
7996 ExprResult SampleCountResult =
7997 getDerived().TransformExpr(Attrs.SampleCountExpr);
7998 if (SampleCountResult.isInvalid())
7999 return QualType();
8000 Attrs.SampleCountExpr = SampleCountResult.get();
8001 }
8002
8003 QualType Result = TL.getType();
8004 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
8005 ContainedTy != oldType->getContainedType() ||
8006 Attrs.SampleCountExpr != oldType->getSampleCountExpr()) {
8007 Result = SemaRef.Context.getHLSLAttributedResourceType(Wrapped: WrappedTy,
8008 Contained: ContainedTy, Attrs);
8009 }
8010
8011 HLSLAttributedResourceTypeLoc NewTL =
8012 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
8013 NewTL.setSourceRange(TL.getLocalSourceRange());
8014 NewTL.setContainedTypeSourceInfo(ContainedTSI);
8015 return Result;
8016}
8017
8018template <typename Derived>
8019QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
8020 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
8021 // No transformations needed.
8022 return TL.getType();
8023}
8024
8025template<typename Derived>
8026QualType
8027TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
8028 ParenTypeLoc TL) {
8029 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8030 if (Inner.isNull())
8031 return QualType();
8032
8033 QualType Result = TL.getType();
8034 if (getDerived().AlwaysRebuild() ||
8035 Inner != TL.getInnerLoc().getType()) {
8036 Result = getDerived().RebuildParenType(Inner);
8037 if (Result.isNull())
8038 return QualType();
8039 }
8040
8041 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
8042 NewTL.setLParenLoc(TL.getLParenLoc());
8043 NewTL.setRParenLoc(TL.getRParenLoc());
8044 return Result;
8045}
8046
8047template <typename Derived>
8048QualType
8049TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
8050 MacroQualifiedTypeLoc TL) {
8051 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8052 if (Inner.isNull())
8053 return QualType();
8054
8055 QualType Result = TL.getType();
8056 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
8057 Result =
8058 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
8059 if (Result.isNull())
8060 return QualType();
8061 }
8062
8063 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
8064 NewTL.setExpansionLoc(TL.getExpansionLoc());
8065 return Result;
8066}
8067
8068template<typename Derived>
8069QualType TreeTransform<Derived>::TransformDependentNameType(
8070 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
8071 return TransformDependentNameType(TLB, TL, false);
8072}
8073
8074template <typename Derived>
8075QualType TreeTransform<Derived>::TransformDependentNameType(
8076 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
8077 QualType ObjectType, NamedDecl *UnqualLookup) {
8078 const DependentNameType *T = TL.getTypePtr();
8079
8080 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
8081 if (QualifierLoc) {
8082 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
8083 QualifierLoc, ObjectType, UnqualLookup);
8084 if (!QualifierLoc)
8085 return QualType();
8086 } else {
8087 assert((ObjectType.isNull() && !UnqualLookup) &&
8088 "must be transformed by TransformNestedNameSpecifierLoc");
8089 }
8090
8091 QualType Result
8092 = getDerived().RebuildDependentNameType(T->getKeyword(),
8093 TL.getElaboratedKeywordLoc(),
8094 QualifierLoc,
8095 T->getIdentifier(),
8096 TL.getNameLoc(),
8097 DeducedTSTContext);
8098 if (Result.isNull())
8099 return QualType();
8100
8101 if (isa<TagType>(Val: Result)) {
8102 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
8103 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8104 NewTL.setQualifierLoc(QualifierLoc);
8105 NewTL.setNameLoc(TL.getNameLoc());
8106 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
8107 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
8108 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8109 NewTL.setTemplateNameLoc(TL.getNameLoc());
8110 NewTL.setQualifierLoc(QualifierLoc);
8111 } else if (isa<TypedefType>(Val: Result)) {
8112 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
8113 QualifierLoc, NameLoc: TL.getNameLoc());
8114 } else if (isa<UnresolvedUsingType>(Val: Result)) {
8115 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
8116 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
8117 } else {
8118 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
8119 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8120 NewTL.setQualifierLoc(QualifierLoc);
8121 NewTL.setNameLoc(TL.getNameLoc());
8122 }
8123 return Result;
8124}
8125
8126template<typename Derived>
8127QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
8128 PackExpansionTypeLoc TL) {
8129 QualType Pattern
8130 = getDerived().TransformType(TLB, TL.getPatternLoc());
8131 if (Pattern.isNull())
8132 return QualType();
8133
8134 QualType Result = TL.getType();
8135 if (getDerived().AlwaysRebuild() ||
8136 Pattern != TL.getPatternLoc().getType()) {
8137 Result = getDerived().RebuildPackExpansionType(Pattern,
8138 TL.getPatternLoc().getSourceRange(),
8139 TL.getEllipsisLoc(),
8140 TL.getTypePtr()->getNumExpansions());
8141 if (Result.isNull())
8142 return QualType();
8143 }
8144
8145 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
8146 NewT.setEllipsisLoc(TL.getEllipsisLoc());
8147 return Result;
8148}
8149
8150template<typename Derived>
8151QualType
8152TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
8153 ObjCInterfaceTypeLoc TL) {
8154 // ObjCInterfaceType is never dependent.
8155 TLB.pushFullCopy(L: TL);
8156 return TL.getType();
8157}
8158
8159template<typename Derived>
8160QualType
8161TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
8162 ObjCTypeParamTypeLoc TL) {
8163 const ObjCTypeParamType *T = TL.getTypePtr();
8164 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
8165 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
8166 if (!OTP)
8167 return QualType();
8168
8169 QualType Result = TL.getType();
8170 if (getDerived().AlwaysRebuild() ||
8171 OTP != T->getDecl()) {
8172 Result = getDerived().RebuildObjCTypeParamType(
8173 OTP, TL.getProtocolLAngleLoc(),
8174 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8175 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8176 if (Result.isNull())
8177 return QualType();
8178 }
8179
8180 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
8181 if (TL.getNumProtocols()) {
8182 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8183 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8184 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8185 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8186 }
8187 return Result;
8188}
8189
8190template<typename Derived>
8191QualType
8192TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
8193 ObjCObjectTypeLoc TL) {
8194 // Transform base type.
8195 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
8196 if (BaseType.isNull())
8197 return QualType();
8198
8199 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8200
8201 // Transform type arguments.
8202 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8203 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8204 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8205 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8206 QualType TypeArg = TypeArgInfo->getType();
8207 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8208 AnyChanged = true;
8209
8210 // We have a pack expansion. Instantiate it.
8211 const auto *PackExpansion = PackExpansionLoc.getType()
8212 ->castAs<PackExpansionType>();
8213 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8214 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8215 Unexpanded);
8216 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8217
8218 // Determine whether the set of unexpanded parameter packs can
8219 // and should be expanded.
8220 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8221 bool Expand = false;
8222 bool RetainExpansion = false;
8223 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8224 if (getDerived().TryExpandParameterPacks(
8225 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8226 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8227 RetainExpansion, NumExpansions))
8228 return QualType();
8229
8230 if (!Expand) {
8231 // We can't expand this pack expansion into separate arguments yet;
8232 // just substitute into the pattern and create a new pack expansion
8233 // type.
8234 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8235
8236 TypeLocBuilder TypeArgBuilder;
8237 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8238 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8239 PatternLoc);
8240 if (NewPatternType.isNull())
8241 return QualType();
8242
8243 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8244 Pattern: NewPatternType, NumExpansions);
8245 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8246 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8247 NewTypeArgInfos.push_back(
8248 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8249 continue;
8250 }
8251
8252 // Substitute into the pack expansion pattern for each slice of the
8253 // pack.
8254 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8255 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8256
8257 TypeLocBuilder TypeArgBuilder;
8258 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8259
8260 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8261 PatternLoc);
8262 if (NewTypeArg.isNull())
8263 return QualType();
8264
8265 NewTypeArgInfos.push_back(
8266 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8267 }
8268
8269 continue;
8270 }
8271
8272 TypeLocBuilder TypeArgBuilder;
8273 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8274 QualType NewTypeArg =
8275 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8276 if (NewTypeArg.isNull())
8277 return QualType();
8278
8279 // If nothing changed, just keep the old TypeSourceInfo.
8280 if (NewTypeArg == TypeArg) {
8281 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8282 continue;
8283 }
8284
8285 NewTypeArgInfos.push_back(
8286 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8287 AnyChanged = true;
8288 }
8289
8290 QualType Result = TL.getType();
8291 if (getDerived().AlwaysRebuild() || AnyChanged) {
8292 // Rebuild the type.
8293 Result = getDerived().RebuildObjCObjectType(
8294 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8295 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8296 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8297 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8298
8299 if (Result.isNull())
8300 return QualType();
8301 }
8302
8303 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8304 NewT.setHasBaseTypeAsWritten(true);
8305 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8306 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8307 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8308 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8309 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8310 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8311 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8312 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8313 return Result;
8314}
8315
8316template<typename Derived>
8317QualType
8318TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8319 ObjCObjectPointerTypeLoc TL) {
8320 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8321 if (PointeeType.isNull())
8322 return QualType();
8323
8324 QualType Result = TL.getType();
8325 if (getDerived().AlwaysRebuild() ||
8326 PointeeType != TL.getPointeeLoc().getType()) {
8327 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8328 TL.getStarLoc());
8329 if (Result.isNull())
8330 return QualType();
8331 }
8332
8333 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8334 NewT.setStarLoc(TL.getStarLoc());
8335 return Result;
8336}
8337
8338//===----------------------------------------------------------------------===//
8339// Statement transformation
8340//===----------------------------------------------------------------------===//
8341template<typename Derived>
8342StmtResult
8343TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8344 return S;
8345}
8346
8347template<typename Derived>
8348StmtResult
8349TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8350 return getDerived().TransformCompoundStmt(S, false);
8351}
8352
8353template<typename Derived>
8354StmtResult
8355TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8356 bool IsStmtExpr) {
8357 Sema::CompoundScopeRAII CompoundScope(getSema());
8358 Sema::FPFeaturesStateRAII FPSave(getSema());
8359 if (S->hasStoredFPFeatures())
8360 getSema().resetFPOptions(
8361 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8362
8363 bool SubStmtInvalid = false;
8364 bool SubStmtChanged = false;
8365 SmallVector<Stmt*, 8> Statements;
8366 for (auto *B : S->body()) {
8367 StmtResult Result = getDerived().TransformStmt(
8368 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8369 : StmtDiscardKind::Discarded);
8370
8371 if (Result.isInvalid()) {
8372 // Immediately fail if this was a DeclStmt, since it's very
8373 // likely that this will cause problems for future statements.
8374 if (isa<DeclStmt>(Val: B))
8375 return StmtError();
8376
8377 // Otherwise, just keep processing substatements and fail later.
8378 SubStmtInvalid = true;
8379 continue;
8380 }
8381
8382 SubStmtChanged = SubStmtChanged || Result.get() != B;
8383 Statements.push_back(Elt: Result.getAs<Stmt>());
8384 }
8385
8386 if (SubStmtInvalid)
8387 return StmtError();
8388
8389 if (!getDerived().AlwaysRebuild() &&
8390 !SubStmtChanged)
8391 return S;
8392
8393 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8394 Statements,
8395 S->getRBracLoc(),
8396 IsStmtExpr);
8397}
8398
8399template<typename Derived>
8400StmtResult
8401TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8402 ExprResult LHS, RHS;
8403 {
8404 EnterExpressionEvaluationContext Unevaluated(
8405 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8406
8407 // Transform the left-hand case value.
8408 LHS = getDerived().TransformExpr(S->getLHS());
8409 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8410 if (LHS.isInvalid())
8411 return StmtError();
8412
8413 // Transform the right-hand case value (for the GNU case-range extension).
8414 RHS = getDerived().TransformExpr(S->getRHS());
8415 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8416 if (RHS.isInvalid())
8417 return StmtError();
8418 }
8419
8420 // Build the case statement.
8421 // Case statements are always rebuilt so that they will attached to their
8422 // transformed switch statement.
8423 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8424 LHS.get(),
8425 S->getEllipsisLoc(),
8426 RHS.get(),
8427 S->getColonLoc());
8428 if (Case.isInvalid())
8429 return StmtError();
8430
8431 // Transform the statement following the case
8432 StmtResult SubStmt =
8433 getDerived().TransformStmt(S->getSubStmt());
8434 if (SubStmt.isInvalid())
8435 return StmtError();
8436
8437 // Attach the body to the case statement
8438 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8439}
8440
8441template <typename Derived>
8442StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8443 // Transform the statement following the default case
8444 StmtResult SubStmt =
8445 getDerived().TransformStmt(S->getSubStmt());
8446 if (SubStmt.isInvalid())
8447 return StmtError();
8448
8449 // Default statements are always rebuilt
8450 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8451 SubStmt.get());
8452}
8453
8454template<typename Derived>
8455StmtResult
8456TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8457 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8458 if (SubStmt.isInvalid())
8459 return StmtError();
8460
8461 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8462 S->getDecl());
8463 if (!LD)
8464 return StmtError();
8465
8466 // If we're transforming "in-place" (we're not creating new local
8467 // declarations), assume we're replacing the old label statement
8468 // and clear out the reference to it.
8469 if (LD == S->getDecl())
8470 S->getDecl()->setStmt(nullptr);
8471
8472 // FIXME: Pass the real colon location in.
8473 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8474 cast<LabelDecl>(Val: LD), SourceLocation(),
8475 SubStmt.get());
8476}
8477
8478template <typename Derived>
8479const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8480 if (!R)
8481 return R;
8482
8483 switch (R->getKind()) {
8484// Transform attributes by calling TransformXXXAttr.
8485#define ATTR(X) \
8486 case attr::X: \
8487 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8488#include "clang/Basic/AttrList.inc"
8489 }
8490 return R;
8491}
8492
8493template <typename Derived>
8494const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8495 const Stmt *InstS,
8496 const Attr *R) {
8497 if (!R)
8498 return R;
8499
8500 switch (R->getKind()) {
8501// Transform attributes by calling TransformStmtXXXAttr.
8502#define ATTR(X) \
8503 case attr::X: \
8504 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8505#include "clang/Basic/AttrList.inc"
8506 }
8507 return TransformAttr(R);
8508}
8509
8510template <typename Derived>
8511StmtResult
8512TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8513 StmtDiscardKind SDK) {
8514 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8515 if (SubStmt.isInvalid())
8516 return StmtError();
8517
8518 bool AttrsChanged = false;
8519 SmallVector<const Attr *, 1> Attrs;
8520
8521 // Visit attributes and keep track if any are transformed.
8522 for (const auto *I : S->getAttrs()) {
8523 const Attr *R =
8524 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8525 AttrsChanged |= (I != R);
8526 if (R)
8527 Attrs.push_back(Elt: R);
8528 }
8529
8530 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8531 return S;
8532
8533 // If transforming the attributes failed for all of the attributes in the
8534 // statement, don't make an AttributedStmt without attributes.
8535 if (Attrs.empty())
8536 return SubStmt;
8537
8538 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8539 SubStmt.get());
8540}
8541
8542template<typename Derived>
8543StmtResult
8544TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8545 // Transform the initialization statement
8546 StmtResult Init = getDerived().TransformStmt(S->getInit());
8547 if (Init.isInvalid())
8548 return StmtError();
8549
8550 Sema::ConditionResult Cond;
8551 if (!S->isConsteval()) {
8552 // Transform the condition
8553 Cond = getDerived().TransformCondition(
8554 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8555 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8556 : Sema::ConditionKind::Boolean);
8557 if (Cond.isInvalid())
8558 return StmtError();
8559 }
8560
8561 // If this is a constexpr if, determine which arm we should instantiate.
8562 std::optional<bool> ConstexprConditionValue;
8563 if (S->isConstexpr())
8564 ConstexprConditionValue = Cond.getKnownValue();
8565
8566 // Transform the "then" branch.
8567 StmtResult Then;
8568 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8569 EnterExpressionEvaluationContext Ctx(
8570 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8571 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8572 S->isNonNegatedConsteval());
8573
8574 Then = getDerived().TransformStmt(S->getThen());
8575 if (Then.isInvalid())
8576 return StmtError();
8577 } else {
8578 // Discarded branch is replaced with empty CompoundStmt so we can keep
8579 // proper source location for start and end of original branch, so
8580 // subsequent transformations like CoverageMapping work properly
8581 Then = new (getSema().Context)
8582 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8583 }
8584
8585 // Transform the "else" branch.
8586 StmtResult Else;
8587 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8588 EnterExpressionEvaluationContext Ctx(
8589 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8590 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8591 S->isNegatedConsteval());
8592
8593 Else = getDerived().TransformStmt(S->getElse());
8594 if (Else.isInvalid())
8595 return StmtError();
8596 } else if (S->getElse() && ConstexprConditionValue &&
8597 *ConstexprConditionValue) {
8598 // Same thing here as with <then> branch, we are discarding it, we can't
8599 // replace it with NULL nor NullStmt as we need to keep for source location
8600 // range, for CoverageMapping
8601 Else = new (getSema().Context)
8602 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8603 }
8604
8605 if (!getDerived().AlwaysRebuild() &&
8606 Init.get() == S->getInit() &&
8607 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8608 Then.get() == S->getThen() &&
8609 Else.get() == S->getElse())
8610 return S;
8611
8612 return getDerived().RebuildIfStmt(
8613 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8614 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8615}
8616
8617template<typename Derived>
8618StmtResult
8619TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8620 // Transform the initialization statement
8621 StmtResult Init = getDerived().TransformStmt(S->getInit());
8622 if (Init.isInvalid())
8623 return StmtError();
8624
8625 // Transform the condition.
8626 Sema::ConditionResult Cond = getDerived().TransformCondition(
8627 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8628 Sema::ConditionKind::Switch);
8629 if (Cond.isInvalid())
8630 return StmtError();
8631
8632 // Rebuild the switch statement.
8633 StmtResult Switch =
8634 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8635 Init.get(), Cond, S->getRParenLoc());
8636 if (Switch.isInvalid())
8637 return StmtError();
8638
8639 // Transform the body of the switch statement.
8640 StmtResult Body = getDerived().TransformStmt(S->getBody());
8641
8642 // Complete the switch statement.
8643 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8644 Body.get());
8645}
8646
8647template<typename Derived>
8648StmtResult
8649TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8650 // Transform the condition
8651 Sema::ConditionResult Cond = getDerived().TransformCondition(
8652 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8653 Sema::ConditionKind::Boolean);
8654 if (Cond.isInvalid())
8655 return StmtError();
8656
8657 // OpenACC Restricts a while-loop inside of certain construct/clause
8658 // combinations, so diagnose that here in OpenACC mode.
8659 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8660 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8661
8662 // Transform the body
8663 StmtResult Body = getDerived().TransformStmt(S->getBody());
8664 if (Body.isInvalid())
8665 return StmtError();
8666
8667 if (!getDerived().AlwaysRebuild() &&
8668 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8669 Body.get() == S->getBody())
8670 return Owned(S);
8671
8672 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8673 Cond, S->getRParenLoc(), Body.get());
8674}
8675
8676template<typename Derived>
8677StmtResult
8678TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8679 // OpenACC Restricts a do-loop inside of certain construct/clause
8680 // combinations, so diagnose that here in OpenACC mode.
8681 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8682 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8683
8684 // Transform the body
8685 StmtResult Body = getDerived().TransformStmt(S->getBody());
8686 if (Body.isInvalid())
8687 return StmtError();
8688
8689 // Transform the condition
8690 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8691 if (Cond.isInvalid())
8692 return StmtError();
8693
8694 if (!getDerived().AlwaysRebuild() &&
8695 Cond.get() == S->getCond() &&
8696 Body.get() == S->getBody())
8697 return S;
8698
8699 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8700 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8701 S->getRParenLoc());
8702}
8703
8704template<typename Derived>
8705StmtResult
8706TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8707 if (getSema().getLangOpts().getOpenMPVersion())
8708 getSema().OpenMP().startOpenMPLoop();
8709
8710 // Transform the initialization statement
8711 StmtResult Init = getDerived().TransformStmt(S->getInit());
8712 if (Init.isInvalid())
8713 return StmtError();
8714
8715 // In OpenMP loop region loop control variable must be captured and be
8716 // private. Perform analysis of first part (if any).
8717 if (getSema().getLangOpts().getOpenMPVersion() && Init.isUsable())
8718 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8719 Init.get());
8720
8721 // Transform the condition
8722 Sema::ConditionResult Cond = getDerived().TransformCondition(
8723 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8724 Sema::ConditionKind::Boolean);
8725 if (Cond.isInvalid())
8726 return StmtError();
8727
8728 // Transform the increment
8729 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8730 if (Inc.isInvalid())
8731 return StmtError();
8732
8733 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8734 if (S->getInc() && !FullInc.get())
8735 return StmtError();
8736
8737 // OpenACC Restricts a for-loop inside of certain construct/clause
8738 // combinations, so diagnose that here in OpenACC mode.
8739 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8740 SemaRef.OpenACC().ActOnForStmtBegin(
8741 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8742 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8743
8744 // Transform the body
8745 StmtResult Body = getDerived().TransformStmt(S->getBody());
8746 if (Body.isInvalid())
8747 return StmtError();
8748
8749 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8750
8751 if (!getDerived().AlwaysRebuild() &&
8752 Init.get() == S->getInit() &&
8753 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8754 Inc.get() == S->getInc() &&
8755 Body.get() == S->getBody())
8756 return S;
8757
8758 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8759 Init.get(), Cond, FullInc,
8760 S->getRParenLoc(), Body.get());
8761}
8762
8763template<typename Derived>
8764StmtResult
8765TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8766 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8767 S->getLabel());
8768 if (!LD)
8769 return StmtError();
8770
8771 // Goto statements must always be rebuilt, to resolve the label.
8772 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8773 cast<LabelDecl>(Val: LD));
8774}
8775
8776template<typename Derived>
8777StmtResult
8778TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8779 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8780 if (Target.isInvalid())
8781 return StmtError();
8782 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8783
8784 if (!getDerived().AlwaysRebuild() &&
8785 Target.get() == S->getTarget())
8786 return S;
8787
8788 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8789 Target.get());
8790}
8791
8792template<typename Derived>
8793StmtResult
8794TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8795 if (!S->hasLabelTarget())
8796 return S;
8797
8798 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8799 S->getLabelDecl());
8800 if (!LD)
8801 return StmtError();
8802
8803 return new (SemaRef.Context)
8804 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8805}
8806
8807template<typename Derived>
8808StmtResult
8809TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8810 if (!S->hasLabelTarget())
8811 return S;
8812
8813 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8814 S->getLabelDecl());
8815 if (!LD)
8816 return StmtError();
8817
8818 return new (SemaRef.Context)
8819 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8820}
8821
8822template <typename Derived>
8823StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8824 StmtResult Result = getDerived().TransformStmt(S->getBody());
8825 if (!Result.isUsable())
8826 return StmtError();
8827 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8828}
8829
8830template<typename Derived>
8831StmtResult
8832TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8833 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8834 /*NotCopyInit*/false);
8835 if (Result.isInvalid())
8836 return StmtError();
8837
8838 // FIXME: We always rebuild the return statement because there is no way
8839 // to tell whether the return type of the function has changed.
8840 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8841}
8842
8843template<typename Derived>
8844StmtResult
8845TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8846 bool DeclChanged = false;
8847 SmallVector<Decl *, 4> Decls;
8848 LambdaScopeInfo *LSI = getSema().getCurLambda();
8849 for (auto *D : S->decls()) {
8850 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8851 if (!Transformed)
8852 return StmtError();
8853
8854 if (Transformed != D)
8855 DeclChanged = true;
8856
8857 if (LSI) {
8858 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8859 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8860 LSI->ContainsUnexpandedParameterPack |=
8861 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8862 } else {
8863 LSI->ContainsUnexpandedParameterPack |=
8864 getSema()
8865 .getASTContext()
8866 .getTypeDeclType(TD)
8867 ->containsUnexpandedParameterPack();
8868 }
8869 }
8870 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8871 LSI->ContainsUnexpandedParameterPack |=
8872 VD->getType()->containsUnexpandedParameterPack();
8873 }
8874
8875 Decls.push_back(Elt: Transformed);
8876 }
8877
8878 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8879 return S;
8880
8881 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8882}
8883
8884template<typename Derived>
8885StmtResult
8886TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8887
8888 SmallVector<Expr*, 8> Constraints;
8889 SmallVector<Expr*, 8> Exprs;
8890 SmallVector<IdentifierInfo *, 4> Names;
8891
8892 SmallVector<Expr*, 8> Clobbers;
8893
8894 bool ExprsChanged = false;
8895
8896 auto RebuildString = [&](Expr *E) {
8897 ExprResult Result = getDerived().TransformExpr(E);
8898 if (!Result.isUsable())
8899 return Result;
8900 if (Result.get() != E) {
8901 ExprsChanged = true;
8902 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8903 }
8904 return Result;
8905 };
8906
8907 // Go through the outputs.
8908 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8909 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8910
8911 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8912 if (Result.isInvalid())
8913 return StmtError();
8914
8915 Constraints.push_back(Elt: Result.get());
8916
8917 // Transform the output expr.
8918 Expr *OutputExpr = S->getOutputExpr(i: I);
8919 Result = getDerived().TransformExpr(OutputExpr);
8920 if (Result.isInvalid())
8921 return StmtError();
8922
8923 ExprsChanged |= Result.get() != OutputExpr;
8924
8925 Exprs.push_back(Elt: Result.get());
8926 }
8927
8928 // Go through the inputs.
8929 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8930 Names.push_back(Elt: S->getInputIdentifier(i: I));
8931
8932 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8933 if (Result.isInvalid())
8934 return StmtError();
8935
8936 Constraints.push_back(Elt: Result.get());
8937
8938 // Transform the input expr.
8939 Expr *InputExpr = S->getInputExpr(i: I);
8940 Result = getDerived().TransformExpr(InputExpr);
8941 if (Result.isInvalid())
8942 return StmtError();
8943
8944 ExprsChanged |= Result.get() != InputExpr;
8945
8946 Exprs.push_back(Elt: Result.get());
8947 }
8948
8949 // Go through the Labels.
8950 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8951 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8952
8953 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8954 if (Result.isInvalid())
8955 return StmtError();
8956 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8957 Exprs.push_back(Elt: Result.get());
8958 }
8959
8960 // Go through the clobbers.
8961 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8962 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8963 if (Result.isInvalid())
8964 return StmtError();
8965 Clobbers.push_back(Elt: Result.get());
8966 }
8967
8968 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8969 if (AsmString.isInvalid())
8970 return StmtError();
8971
8972 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8973 return S;
8974
8975 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8976 S->isVolatile(), S->getNumOutputs(),
8977 S->getNumInputs(), Names.data(),
8978 Constraints, Exprs, AsmString.get(),
8979 Clobbers, S->getNumLabels(),
8980 S->getRParenLoc());
8981}
8982
8983template<typename Derived>
8984StmtResult
8985TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8986 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8987
8988 bool HadError = false, HadChange = false;
8989
8990 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8991 SmallVector<Expr*, 8> TransformedExprs;
8992 TransformedExprs.reserve(N: SrcExprs.size());
8993 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8994 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8995 if (!Result.isUsable()) {
8996 HadError = true;
8997 } else {
8998 HadChange |= (Result.get() != SrcExprs[i]);
8999 TransformedExprs.push_back(Elt: Result.get());
9000 }
9001 }
9002
9003 if (HadError) return StmtError();
9004 if (!HadChange && !getDerived().AlwaysRebuild())
9005 return Owned(S);
9006
9007 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
9008 AsmToks, S->getAsmString(),
9009 S->getNumOutputs(), S->getNumInputs(),
9010 S->getAllConstraints(), S->getClobbers(),
9011 TransformedExprs, S->getEndLoc());
9012}
9013
9014// C++ Coroutines
9015template<typename Derived>
9016StmtResult
9017TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
9018 auto *ScopeInfo = SemaRef.getCurFunction();
9019 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
9020 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
9021 ScopeInfo->NeedsCoroutineSuspends &&
9022 ScopeInfo->CoroutineSuspends.first == nullptr &&
9023 ScopeInfo->CoroutineSuspends.second == nullptr &&
9024 "expected clean scope info");
9025
9026 // Set that we have (possibly-invalid) suspend points before we do anything
9027 // that may fail.
9028 ScopeInfo->setNeedsCoroutineSuspends(false);
9029
9030 // We re-build the coroutine promise object (and the coroutine parameters its
9031 // type and constructor depend on) based on the types used in our current
9032 // function. We must do so, and set it on the current FunctionScopeInfo,
9033 // before attempting to transform the other parts of the coroutine body
9034 // statement, such as the implicit suspend statements (because those
9035 // statements reference the FunctionScopeInfo::CoroutinePromise).
9036 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
9037 return StmtError();
9038 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
9039 if (!Promise)
9040 return StmtError();
9041 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
9042 ScopeInfo->CoroutinePromise = Promise;
9043
9044 // Transform the implicit coroutine statements constructed using dependent
9045 // types during the previous parse: initial and final suspensions, the return
9046 // object, and others. We also transform the coroutine function's body.
9047 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
9048 if (InitSuspend.isInvalid())
9049 return StmtError();
9050 StmtResult FinalSuspend =
9051 getDerived().TransformStmt(S->getFinalSuspendStmt());
9052 if (FinalSuspend.isInvalid() ||
9053 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
9054 return StmtError();
9055 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
9056 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
9057
9058 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
9059 if (BodyRes.isInvalid())
9060 return StmtError();
9061
9062 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
9063 if (Builder.isInvalid())
9064 return StmtError();
9065
9066 Expr *ReturnObject = S->getReturnValueInit();
9067 assert(ReturnObject && "the return object is expected to be valid");
9068 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
9069 /*NoCopyInit*/ false);
9070 if (Res.isInvalid())
9071 return StmtError();
9072 Builder.ReturnValue = Res.get();
9073
9074 // If during the previous parse the coroutine still had a dependent promise
9075 // statement, we may need to build some implicit coroutine statements
9076 // (such as exception and fallthrough handlers) for the first time.
9077 if (S->hasDependentPromiseType()) {
9078 // We can only build these statements, however, if the current promise type
9079 // is not dependent.
9080 if (!Promise->getType()->isDependentType()) {
9081 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
9082 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
9083 "these nodes should not have been built yet");
9084 if (!Builder.buildDependentStatements())
9085 return StmtError();
9086 }
9087 } else {
9088 if (auto *OnFallthrough = S->getFallthroughHandler()) {
9089 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
9090 if (Res.isInvalid())
9091 return StmtError();
9092 Builder.OnFallthrough = Res.get();
9093 }
9094
9095 if (auto *OnException = S->getExceptionHandler()) {
9096 StmtResult Res = getDerived().TransformStmt(OnException);
9097 if (Res.isInvalid())
9098 return StmtError();
9099 Builder.OnException = Res.get();
9100 }
9101
9102 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
9103 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
9104 if (Res.isInvalid())
9105 return StmtError();
9106 Builder.ReturnStmtOnAllocFailure = Res.get();
9107 }
9108
9109 // Transform any additional statements we may have already built
9110 assert(S->getAllocate() && S->getDeallocate() &&
9111 "allocation and deallocation calls must already be built");
9112 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
9113 if (AllocRes.isInvalid())
9114 return StmtError();
9115 Builder.Allocate = AllocRes.get();
9116
9117 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
9118 if (DeallocRes.isInvalid())
9119 return StmtError();
9120 Builder.Deallocate = DeallocRes.get();
9121
9122 if (auto *ResultDecl = S->getResultDecl()) {
9123 StmtResult Res = getDerived().TransformStmt(ResultDecl);
9124 if (Res.isInvalid())
9125 return StmtError();
9126 Builder.ResultDecl = Res.get();
9127 }
9128
9129 if (auto *ReturnStmt = S->getReturnStmt()) {
9130 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
9131 if (Res.isInvalid())
9132 return StmtError();
9133 Builder.ReturnStmt = Res.get();
9134 }
9135 }
9136
9137 return getDerived().RebuildCoroutineBodyStmt(Builder);
9138}
9139
9140template<typename Derived>
9141StmtResult
9142TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
9143 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
9144 /*NotCopyInit*/false);
9145 if (Result.isInvalid())
9146 return StmtError();
9147
9148 // Always rebuild; we don't know if this needs to be injected into a new
9149 // context or if the promise type has changed.
9150 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
9151 S->isImplicit());
9152}
9153
9154template <typename Derived>
9155ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
9156 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
9157 /*NotCopyInit*/ false);
9158 if (Operand.isInvalid())
9159 return ExprError();
9160
9161 // Rebuild the common-expr from the operand rather than transforming it
9162 // separately.
9163
9164 // FIXME: getCurScope() should not be used during template instantiation.
9165 // We should pick up the set of unqualified lookup results for operator
9166 // co_await during the initial parse.
9167 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
9168 getSema().getCurScope(), E->getKeywordLoc());
9169
9170 // Always rebuild; we don't know if this needs to be injected into a new
9171 // context or if the promise type has changed.
9172 return getDerived().RebuildCoawaitExpr(
9173 E->getKeywordLoc(), Operand.get(),
9174 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
9175}
9176
9177template <typename Derived>
9178ExprResult
9179TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
9180 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
9181 /*NotCopyInit*/ false);
9182 if (OperandResult.isInvalid())
9183 return ExprError();
9184
9185 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
9186 E->getOperatorCoawaitLookup());
9187
9188 if (LookupResult.isInvalid())
9189 return ExprError();
9190
9191 // Always rebuild; we don't know if this needs to be injected into a new
9192 // context or if the promise type has changed.
9193 return getDerived().RebuildDependentCoawaitExpr(
9194 E->getKeywordLoc(), OperandResult.get(),
9195 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
9196}
9197
9198template<typename Derived>
9199ExprResult
9200TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9201 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9202 /*NotCopyInit*/false);
9203 if (Result.isInvalid())
9204 return ExprError();
9205
9206 // Always rebuild; we don't know if this needs to be injected into a new
9207 // context or if the promise type has changed.
9208 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9209}
9210
9211// Objective-C Statements.
9212
9213template<typename Derived>
9214StmtResult
9215TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9216 // Transform the body of the @try.
9217 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9218 if (TryBody.isInvalid())
9219 return StmtError();
9220
9221 // Transform the @catch statements (if present).
9222 bool AnyCatchChanged = false;
9223 SmallVector<Stmt*, 8> CatchStmts;
9224 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9225 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9226 if (Catch.isInvalid())
9227 return StmtError();
9228 if (Catch.get() != S->getCatchStmt(I))
9229 AnyCatchChanged = true;
9230 CatchStmts.push_back(Elt: Catch.get());
9231 }
9232
9233 // Transform the @finally statement (if present).
9234 StmtResult Finally;
9235 if (S->getFinallyStmt()) {
9236 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9237 if (Finally.isInvalid())
9238 return StmtError();
9239 }
9240
9241 // If nothing changed, just retain this statement.
9242 if (!getDerived().AlwaysRebuild() &&
9243 TryBody.get() == S->getTryBody() &&
9244 !AnyCatchChanged &&
9245 Finally.get() == S->getFinallyStmt())
9246 return S;
9247
9248 // Build a new statement.
9249 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9250 CatchStmts, Finally.get());
9251}
9252
9253template<typename Derived>
9254StmtResult
9255TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9256 // Transform the @catch parameter, if there is one.
9257 VarDecl *Var = nullptr;
9258 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9259 TypeSourceInfo *TSInfo = nullptr;
9260 if (FromVar->getTypeSourceInfo()) {
9261 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9262 if (!TSInfo)
9263 return StmtError();
9264 }
9265
9266 QualType T;
9267 if (TSInfo)
9268 T = TSInfo->getType();
9269 else {
9270 T = getDerived().TransformType(FromVar->getType());
9271 if (T.isNull())
9272 return StmtError();
9273 }
9274
9275 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9276 if (!Var)
9277 return StmtError();
9278 }
9279
9280 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9281 if (Body.isInvalid())
9282 return StmtError();
9283
9284 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9285 S->getRParenLoc(),
9286 Var, Body.get());
9287}
9288
9289template<typename Derived>
9290StmtResult
9291TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9292 // Transform the body.
9293 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9294 if (Body.isInvalid())
9295 return StmtError();
9296
9297 // If nothing changed, just retain this statement.
9298 if (!getDerived().AlwaysRebuild() &&
9299 Body.get() == S->getFinallyBody())
9300 return S;
9301
9302 // Build a new statement.
9303 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9304 Body.get());
9305}
9306
9307template<typename Derived>
9308StmtResult
9309TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9310 ExprResult Operand;
9311 if (S->getThrowExpr()) {
9312 Operand = getDerived().TransformExpr(S->getThrowExpr());
9313 if (Operand.isInvalid())
9314 return StmtError();
9315 }
9316
9317 if (!getDerived().AlwaysRebuild() &&
9318 Operand.get() == S->getThrowExpr())
9319 return S;
9320
9321 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9322}
9323
9324template<typename Derived>
9325StmtResult
9326TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9327 ObjCAtSynchronizedStmt *S) {
9328 // Transform the object we are locking.
9329 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9330 if (Object.isInvalid())
9331 return StmtError();
9332 Object =
9333 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9334 Object.get());
9335 if (Object.isInvalid())
9336 return StmtError();
9337
9338 // Transform the body.
9339 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9340 if (Body.isInvalid())
9341 return StmtError();
9342
9343 // If nothing change, just retain the current statement.
9344 if (!getDerived().AlwaysRebuild() &&
9345 Object.get() == S->getSynchExpr() &&
9346 Body.get() == S->getSynchBody())
9347 return S;
9348
9349 // Build a new statement.
9350 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9351 Object.get(), Body.get());
9352}
9353
9354template<typename Derived>
9355StmtResult
9356TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9357 ObjCAutoreleasePoolStmt *S) {
9358 // Transform the body.
9359 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9360 if (Body.isInvalid())
9361 return StmtError();
9362
9363 // If nothing changed, just retain this statement.
9364 if (!getDerived().AlwaysRebuild() &&
9365 Body.get() == S->getSubStmt())
9366 return S;
9367
9368 // Build a new statement.
9369 return getDerived().RebuildObjCAutoreleasePoolStmt(
9370 S->getAtLoc(), Body.get());
9371}
9372
9373template<typename Derived>
9374StmtResult
9375TreeTransform<Derived>::TransformObjCForCollectionStmt(
9376 ObjCForCollectionStmt *S) {
9377 // Transform the element statement.
9378 StmtResult Element = getDerived().TransformStmt(
9379 S->getElement(), StmtDiscardKind::NotDiscarded);
9380 if (Element.isInvalid())
9381 return StmtError();
9382
9383 // Transform the collection expression.
9384 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9385 if (Collection.isInvalid())
9386 return StmtError();
9387
9388 // Transform the body.
9389 StmtResult Body = getDerived().TransformStmt(S->getBody());
9390 if (Body.isInvalid())
9391 return StmtError();
9392
9393 // If nothing changed, just retain this statement.
9394 if (!getDerived().AlwaysRebuild() &&
9395 Element.get() == S->getElement() &&
9396 Collection.get() == S->getCollection() &&
9397 Body.get() == S->getBody())
9398 return S;
9399
9400 // Build a new statement.
9401 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9402 Element.get(),
9403 Collection.get(),
9404 S->getRParenLoc(),
9405 Body.get());
9406}
9407
9408template <typename Derived>
9409StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9410 // Transform the exception declaration, if any.
9411 VarDecl *Var = nullptr;
9412 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9413 TypeSourceInfo *T =
9414 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9415 if (!T)
9416 return StmtError();
9417
9418 Var = getDerived().RebuildExceptionDecl(
9419 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9420 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9421 if (!Var || Var->isInvalidDecl())
9422 return StmtError();
9423 }
9424
9425 // Transform the actual exception handler.
9426 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9427 if (Handler.isInvalid())
9428 return StmtError();
9429
9430 if (!getDerived().AlwaysRebuild() && !Var &&
9431 Handler.get() == S->getHandlerBlock())
9432 return S;
9433
9434 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9435}
9436
9437template <typename Derived>
9438StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9439 // Transform the try block itself.
9440 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9441 if (TryBlock.isInvalid())
9442 return StmtError();
9443
9444 // Transform the handlers.
9445 bool HandlerChanged = false;
9446 SmallVector<Stmt *, 8> Handlers;
9447 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9448 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9449 if (Handler.isInvalid())
9450 return StmtError();
9451
9452 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9453 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9454 }
9455
9456 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9457
9458 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9459 !HandlerChanged)
9460 return S;
9461
9462 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9463 Handlers);
9464}
9465
9466template<typename Derived>
9467StmtResult
9468TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9469 EnterExpressionEvaluationContext ForRangeInitContext(
9470 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9471 /*LambdaContextDecl=*/nullptr,
9472 Sema::ExpressionEvaluationContextRecord::EK_Other,
9473 getSema().getLangOpts().CPlusPlus23);
9474
9475 // P2718R0 - Lifetime extension in range-based for loops.
9476 if (getSema().getLangOpts().CPlusPlus23) {
9477 auto &LastRecord = getSema().currentEvaluationContext();
9478 LastRecord.InLifetimeExtendingContext = true;
9479 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9480 }
9481 StmtResult Init =
9482 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9483 if (Init.isInvalid())
9484 return StmtError();
9485
9486 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9487 if (Range.isInvalid())
9488 return StmtError();
9489
9490 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9491 assert(getSema().getLangOpts().CPlusPlus23 ||
9492 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9493 auto ForRangeLifetimeExtendTemps =
9494 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9495
9496 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9497 if (Begin.isInvalid())
9498 return StmtError();
9499 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9500 if (End.isInvalid())
9501 return StmtError();
9502
9503 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9504 if (Cond.isInvalid())
9505 return StmtError();
9506 if (Cond.get())
9507 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9508 if (Cond.isInvalid())
9509 return StmtError();
9510 if (Cond.get())
9511 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9512
9513 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9514 if (Inc.isInvalid())
9515 return StmtError();
9516 if (Inc.get())
9517 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9518
9519 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9520 if (LoopVar.isInvalid())
9521 return StmtError();
9522
9523 StmtResult NewStmt = S;
9524 if (getDerived().AlwaysRebuild() ||
9525 Init.get() != S->getInit() ||
9526 Range.get() != S->getRangeStmt() ||
9527 Begin.get() != S->getBeginStmt() ||
9528 End.get() != S->getEndStmt() ||
9529 Cond.get() != S->getCond() ||
9530 Inc.get() != S->getInc() ||
9531 LoopVar.get() != S->getLoopVarStmt()) {
9532 NewStmt = getDerived().RebuildCXXForRangeStmt(
9533 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9534 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9535 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9536 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9537 // Might not have attached any initializer to the loop variable.
9538 getSema().ActOnInitializerError(
9539 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9540 return StmtError();
9541 }
9542 }
9543
9544 // OpenACC Restricts a while-loop inside of certain construct/clause
9545 // combinations, so diagnose that here in OpenACC mode.
9546 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9547 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9548
9549 StmtResult Body = getDerived().TransformStmt(S->getBody());
9550 if (Body.isInvalid())
9551 return StmtError();
9552
9553 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9554
9555 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9556 // it now so we have a new statement to attach the body to.
9557 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9558 NewStmt = getDerived().RebuildCXXForRangeStmt(
9559 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9560 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9561 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9562 if (NewStmt.isInvalid())
9563 return StmtError();
9564 }
9565
9566 if (NewStmt.get() == S)
9567 return S;
9568
9569 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9570}
9571
9572template <typename Derived>
9573StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtPattern(
9574 CXXExpansionStmtPattern *S) {
9575 assert(SemaRef.CurContext->isExpansionStmt());
9576
9577 Decl *ESD =
9578 getDerived().TransformDecl(S->getDecl()->getLocation(), S->getDecl());
9579 if (!ESD || ESD->isInvalidDecl())
9580 return StmtError();
9581 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9582
9583 // This is required because some parts of an expansion statement (e.g. the
9584 // init-statement) are not in a dependent context and must thus be transformed
9585 // in the parent context.
9586 auto TransformStmtInParentContext = [&](Stmt *SubStmt) -> StmtResult {
9587 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9588 /*NewThis=*/false);
9589 return getDerived().TransformStmt(SubStmt);
9590 };
9591
9592 Stmt *Init = S->getInit();
9593 if (Init) {
9594 StmtResult SR = TransformStmtInParentContext(Init);
9595 if (SR.isInvalid())
9596 return StmtError();
9597 Init = SR.get();
9598 }
9599
9600 // Collect lifetime-extended temporaries in case this ends up being a
9601 // destructuring or iterating expansion statement.
9602 //
9603 // CWG 3140: Additionally, for iterating expansions statements, we need to
9604 // apply lifetime extension to the initializer of the range.
9605 ExprResult ExpansionInitializer;
9606 StmtResult Range;
9607 SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
9608 if (S->isDependent() || S->isIterating()) {
9609 EnterExpressionEvaluationContext ExprEvalCtx(
9610 SemaRef, SemaRef.currentEvaluationContext().Context);
9611 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9612 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9613
9614 if (S->isDependent()) {
9615 // The expansion initializer should not be in the context of the expansion
9616 // statement because it isn't instantiated when the expansion statement is
9617 // expanded.
9618 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9619 /*NewThis=*/false);
9620 ExpansionInitializer =
9621 getDerived().TransformExpr(S->getExpansionInitializer());
9622 if (ExpansionInitializer.isInvalid())
9623 return StmtError();
9624 } else if (S->isIterating()) {
9625 Range = TransformStmtInParentContext(S->getRangeVarStmt());
9626 if (Range.isInvalid())
9627 return StmtError();
9628 }
9629
9630 ExpansionInitializer =
9631 SemaRef.MaybeCreateExprWithCleanups(SubExpr: ExpansionInitializer);
9632
9633 LifetimeExtendTemps =
9634 SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps;
9635 }
9636
9637 CXXExpansionStmtPattern *NewPattern = nullptr;
9638 if (S->isEnumerating()) {
9639 StmtResult ExpansionVar =
9640 getDerived().TransformStmt(S->getExpansionVarStmt());
9641 if (ExpansionVar.isInvalid())
9642 return StmtError();
9643
9644 NewPattern = CXXExpansionStmtPattern::CreateEnumerating(
9645 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9646 LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(), RParenLoc: S->getRParenLoc());
9647 } else if (S->isIterating()) {
9648 StmtResult Begin = TransformStmtInParentContext(S->getBeginVarStmt());
9649 StmtResult Iter = TransformStmtInParentContext(S->getIterVarStmt());
9650 if (Begin.isInvalid() || Iter.isInvalid())
9651 return StmtError();
9652
9653 // The expansion variable is part of the pattern only and never ends
9654 // up in the instantiations, so keep it in the expansion statement's
9655 // DeclContext.
9656 StmtResult ExpansionVar =
9657 getDerived().TransformStmt(S->getExpansionVarStmt());
9658 if (ExpansionVar.isInvalid())
9659 return StmtError();
9660
9661 NewPattern = CXXExpansionStmtPattern::CreateIterating(
9662 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9663 Range: Range.getAs<DeclStmt>(), Begin: Begin.getAs<DeclStmt>(),
9664 Iter: Iter.getAs<DeclStmt>(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9665 RParenLoc: S->getRParenLoc());
9666
9667 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9668 RangeVar: NewPattern->getRangeVar(), Temporaries: LifetimeExtendTemps);
9669 } else if (S->isDependent()) {
9670 StmtResult ExpansionVar =
9671 getDerived().TransformStmt(S->getExpansionVarStmt());
9672 if (ExpansionVar.isInvalid())
9673 return StmtError();
9674
9675 StmtResult Res = SemaRef.BuildNonEnumeratingCXXExpansionStmtPattern(
9676 ESD: NewESD, Init, ExpansionVarStmt: ExpansionVar.getAs<DeclStmt>(),
9677 ExpansionInitializer: ExpansionInitializer.get(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9678 RParenLoc: S->getRParenLoc(), LifetimeExtendTemps);
9679
9680 if (Res.isInvalid())
9681 return StmtError();
9682
9683 NewPattern = cast<CXXExpansionStmtPattern>(Val: Res.get());
9684 } else {
9685 // The only time we instantiate an expansion statement is if its expansion
9686 // size is dependent (otherwise, we only instantiate the expansions and
9687 // leave the underlying CXXExpansionStmtPattern as-is). Since destructuring
9688 // expansion statements never have a dependent size, we should never get
9689 // here.
9690 llvm_unreachable("destructuring pattern should never be instantiated");
9691 }
9692
9693 StmtResult Body = getDerived().TransformStmt(S->getBody());
9694 if (Body.isInvalid())
9695 return StmtError();
9696
9697 return SemaRef.FinishCXXExpansionStmt(Expansion: NewPattern, Body: Body.get());
9698}
9699
9700template <typename Derived>
9701StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtInstantiation(
9702 CXXExpansionStmtInstantiation *S) {
9703 bool SubStmtChanged = false;
9704 auto TransformStmts = [&](SmallVectorImpl<Stmt *> &NewStmts,
9705 ArrayRef<Stmt *> OldStmts) {
9706 for (Stmt *OldDS : OldStmts) {
9707 StmtResult NewDS = getDerived().TransformStmt(OldDS);
9708 if (NewDS.isInvalid())
9709 return true;
9710
9711 SubStmtChanged |= NewDS.get() != OldDS;
9712 NewStmts.push_back(Elt: NewDS.get());
9713 }
9714
9715 return false;
9716 };
9717
9718 Decl *ESD =
9719 getDerived().TransformDecl(S->getParent()->getLocation(), S->getParent());
9720 if (!ESD || ESD->isInvalidDecl())
9721 return StmtError();
9722 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9723
9724 SmallVector<Stmt *> PreambleStmts;
9725 SmallVector<Stmt *> Instantiations;
9726
9727 // Apply lifetime extension to the preamble statements if this was a
9728 // destructuring expansion statement.
9729 {
9730 EnterExpressionEvaluationContext ExprEvalCtx(
9731 SemaRef, SemaRef.currentEvaluationContext().Context);
9732 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9733 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9734 if (TransformStmts(PreambleStmts, S->getPreambleStmts()))
9735 return StmtError();
9736
9737 if (S->shouldApplyLifetimeExtensionToPreamble()) {
9738 auto *VD =
9739 cast<VarDecl>(Val: cast<DeclStmt>(Val: PreambleStmts.front())->getSingleDecl());
9740 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9741 RangeVar: VD, Temporaries: SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps);
9742 }
9743 }
9744
9745 if (TransformStmts(Instantiations, S->getInstantiations()))
9746 return StmtError();
9747
9748 if (!getDerived().AlwaysRebuild() && !SubStmtChanged)
9749 return S;
9750
9751 return CXXExpansionStmtInstantiation::Create(
9752 C&: SemaRef.Context, Parent: NewESD, Instantiations, PreambleStmts,
9753 ShouldApplyLifetimeExtensionToPreamble: S->shouldApplyLifetimeExtensionToPreamble());
9754}
9755
9756template <typename Derived>
9757ExprResult TreeTransform<Derived>::TransformCXXExpansionSelectExpr(
9758 CXXExpansionSelectExpr *E) {
9759 ExprResult Range = getDerived().TransformExpr(E->getRangeExpr());
9760 ExprResult Idx = getDerived().TransformExpr(E->getIndexExpr());
9761 if (Range.isInvalid() || Idx.isInvalid())
9762 return ExprError();
9763
9764 if (!getDerived().AlwaysRebuild() && Range.get() == E->getRangeExpr() &&
9765 Idx.get() == E->getIndexExpr())
9766 return E;
9767
9768 return SemaRef.BuildCXXExpansionSelectExpr(Range: Range.getAs<InitListExpr>(),
9769 Idx: Idx.get());
9770}
9771
9772template<typename Derived>
9773StmtResult
9774TreeTransform<Derived>::TransformMSDependentExistsStmt(
9775 MSDependentExistsStmt *S) {
9776 // Transform the nested-name-specifier, if any.
9777 NestedNameSpecifierLoc QualifierLoc;
9778 if (S->getQualifierLoc()) {
9779 QualifierLoc
9780 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9781 if (!QualifierLoc)
9782 return StmtError();
9783 }
9784
9785 // Transform the declaration name.
9786 DeclarationNameInfo NameInfo = S->getNameInfo();
9787 if (NameInfo.getName()) {
9788 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9789 if (!NameInfo.getName())
9790 return StmtError();
9791 }
9792
9793 // Check whether anything changed.
9794 if (!getDerived().AlwaysRebuild() &&
9795 QualifierLoc == S->getQualifierLoc() &&
9796 NameInfo.getName() == S->getNameInfo().getName())
9797 return S;
9798
9799 // Determine whether this name exists, if we can.
9800 CXXScopeSpec SS;
9801 SS.Adopt(Other: QualifierLoc);
9802 bool Dependent = false;
9803 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9804 case IfExistsResult::Exists:
9805 if (S->isIfExists())
9806 break;
9807
9808 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9809
9810 case IfExistsResult::DoesNotExist:
9811 if (S->isIfNotExists())
9812 break;
9813
9814 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9815
9816 case IfExistsResult::Dependent:
9817 Dependent = true;
9818 break;
9819
9820 case IfExistsResult::Error:
9821 return StmtError();
9822 }
9823
9824 // We need to continue with the instantiation, so do so now.
9825 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9826 if (SubStmt.isInvalid())
9827 return StmtError();
9828
9829 // If we have resolved the name, just transform to the substatement.
9830 if (!Dependent)
9831 return SubStmt;
9832
9833 // The name is still dependent, so build a dependent expression again.
9834 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9835 S->isIfExists(),
9836 QualifierLoc,
9837 NameInfo,
9838 SubStmt.get());
9839}
9840
9841template<typename Derived>
9842ExprResult
9843TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9844 NestedNameSpecifierLoc QualifierLoc;
9845 if (E->getQualifierLoc()) {
9846 QualifierLoc
9847 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9848 if (!QualifierLoc)
9849 return ExprError();
9850 }
9851
9852 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9853 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9854 if (!PD)
9855 return ExprError();
9856
9857 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9858 if (Base.isInvalid())
9859 return ExprError();
9860
9861 return new (SemaRef.getASTContext())
9862 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9863 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9864 QualifierLoc, E->getMemberLoc());
9865}
9866
9867template <typename Derived>
9868ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9869 MSPropertySubscriptExpr *E) {
9870 auto BaseRes = getDerived().TransformExpr(E->getBase());
9871 if (BaseRes.isInvalid())
9872 return ExprError();
9873 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9874 if (IdxRes.isInvalid())
9875 return ExprError();
9876
9877 if (!getDerived().AlwaysRebuild() &&
9878 BaseRes.get() == E->getBase() &&
9879 IdxRes.get() == E->getIdx())
9880 return E;
9881
9882 return getDerived().RebuildArraySubscriptExpr(
9883 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9884}
9885
9886template <typename Derived>
9887StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9888 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9889 if (TryBlock.isInvalid())
9890 return StmtError();
9891
9892 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9893 if (Handler.isInvalid())
9894 return StmtError();
9895
9896 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9897 Handler.get() == S->getHandler())
9898 return S;
9899
9900 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9901 TryBlock.get(), Handler.get());
9902}
9903
9904template <typename Derived>
9905StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9906 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9907 if (Block.isInvalid())
9908 return StmtError();
9909
9910 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9911}
9912
9913template <typename Derived>
9914StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9915 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9916 if (FilterExpr.isInvalid())
9917 return StmtError();
9918
9919 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9920 if (Block.isInvalid())
9921 return StmtError();
9922
9923 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9924 Block.get());
9925}
9926
9927template <typename Derived>
9928StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9929 if (isa<SEHFinallyStmt>(Val: Handler))
9930 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9931 else
9932 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9933}
9934
9935template<typename Derived>
9936StmtResult
9937TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9938 return S;
9939}
9940
9941//===----------------------------------------------------------------------===//
9942// OpenMP directive transformation
9943//===----------------------------------------------------------------------===//
9944
9945template <typename Derived>
9946StmtResult
9947TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9948 // OMPCanonicalLoops are eliminated during transformation, since they will be
9949 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9950 // after transformation.
9951 return getDerived().TransformStmt(L->getLoopStmt());
9952}
9953
9954template <typename Derived>
9955StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9956 OMPExecutableDirective *D) {
9957
9958 // Transform the clauses
9959 llvm::SmallVector<OMPClause *, 16> TClauses;
9960 ArrayRef<OMPClause *> Clauses = D->clauses();
9961 TClauses.reserve(N: Clauses.size());
9962 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9963 I != E; ++I) {
9964 if (*I) {
9965 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9966 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9967 getDerived().getSema().OpenMP().EndOpenMPClause();
9968 if (Clause)
9969 TClauses.push_back(Elt: Clause);
9970 } else {
9971 TClauses.push_back(Elt: nullptr);
9972 }
9973 }
9974 StmtResult AssociatedStmt;
9975 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9976 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9977 D->getDirectiveKind(),
9978 /*CurScope=*/nullptr);
9979 StmtResult Body;
9980 {
9981 Sema::CompoundScopeRAII CompoundScope(getSema());
9982 Stmt *CS;
9983 if (D->getDirectiveKind() == OMPD_atomic ||
9984 D->getDirectiveKind() == OMPD_critical ||
9985 D->getDirectiveKind() == OMPD_section ||
9986 D->getDirectiveKind() == OMPD_master)
9987 CS = D->getAssociatedStmt();
9988 else
9989 CS = D->getRawStmt();
9990 Body = getDerived().TransformStmt(CS);
9991 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9992 getSema().getLangOpts().OpenMPIRBuilder)
9993 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9994 }
9995 AssociatedStmt =
9996 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9997 if (AssociatedStmt.isInvalid()) {
9998 return StmtError();
9999 }
10000 }
10001 if (TClauses.size() != Clauses.size()) {
10002 return StmtError();
10003 }
10004
10005 // Transform directive name for 'omp critical' directive.
10006 DeclarationNameInfo DirName;
10007 if (D->getDirectiveKind() == OMPD_critical) {
10008 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
10009 DirName = getDerived().TransformDeclarationNameInfo(DirName);
10010 }
10011 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
10012 if (D->getDirectiveKind() == OMPD_cancellation_point) {
10013 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
10014 } else if (D->getDirectiveKind() == OMPD_cancel) {
10015 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
10016 }
10017
10018 return getDerived().RebuildOMPExecutableDirective(
10019 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
10020 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
10021}
10022
10023/// This is mostly the same as above, but allows 'informational' class
10024/// directives when rebuilding the stmt. It still takes an
10025/// OMPExecutableDirective-type argument because we're reusing that as the
10026/// superclass for the 'assume' directive at present, instead of defining a
10027/// mostly-identical OMPInformationalDirective parent class.
10028template <typename Derived>
10029StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
10030 OMPExecutableDirective *D) {
10031
10032 // Transform the clauses
10033 llvm::SmallVector<OMPClause *, 16> TClauses;
10034 ArrayRef<OMPClause *> Clauses = D->clauses();
10035 TClauses.reserve(N: Clauses.size());
10036 for (OMPClause *C : Clauses) {
10037 if (C) {
10038 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
10039 OMPClause *Clause = getDerived().TransformOMPClause(C);
10040 getDerived().getSema().OpenMP().EndOpenMPClause();
10041 if (Clause)
10042 TClauses.push_back(Elt: Clause);
10043 } else {
10044 TClauses.push_back(Elt: nullptr);
10045 }
10046 }
10047 StmtResult AssociatedStmt;
10048 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
10049 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
10050 D->getDirectiveKind(),
10051 /*CurScope=*/nullptr);
10052 StmtResult Body;
10053 {
10054 Sema::CompoundScopeRAII CompoundScope(getSema());
10055 assert(D->getDirectiveKind() == OMPD_assume &&
10056 "Unexpected informational directive");
10057 Stmt *CS = D->getAssociatedStmt();
10058 Body = getDerived().TransformStmt(CS);
10059 }
10060 AssociatedStmt =
10061 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
10062 if (AssociatedStmt.isInvalid())
10063 return StmtError();
10064 }
10065 if (TClauses.size() != Clauses.size())
10066 return StmtError();
10067
10068 DeclarationNameInfo DirName;
10069
10070 return getDerived().RebuildOMPInformationalDirective(
10071 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
10072 D->getBeginLoc(), D->getEndLoc());
10073}
10074
10075template <typename Derived>
10076StmtResult
10077TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
10078 // TODO: Fix This
10079 llvm::omp::Version OMPVersion =
10080 getDerived().getSema().getLangOpts().getOpenMPVersion();
10081 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
10082 << getOpenMPDirectiveName(D: D->getDirectiveKind(), V: OMPVersion);
10083 return StmtError();
10084}
10085
10086template <typename Derived>
10087StmtResult
10088TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
10089 DeclarationNameInfo DirName;
10090 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10091 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
10092 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10093 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10094 return Res;
10095}
10096
10097template <typename Derived>
10098StmtResult
10099TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
10100 DeclarationNameInfo DirName;
10101 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10102 OMPD_simd, DirName, nullptr, D->getBeginLoc());
10103 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10104 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10105 return Res;
10106}
10107
10108template <typename Derived>
10109StmtResult
10110TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
10111 DeclarationNameInfo DirName;
10112 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10113 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10114 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10115 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10116 return Res;
10117}
10118
10119template <typename Derived>
10120StmtResult
10121TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
10122 DeclarationNameInfo DirName;
10123 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10124 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10125 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10126 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10127 return Res;
10128}
10129
10130template <typename Derived>
10131StmtResult
10132TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
10133 DeclarationNameInfo DirName;
10134 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10135 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10136 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10137 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10138 return Res;
10139}
10140
10141template <typename Derived>
10142StmtResult
10143TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
10144 DeclarationNameInfo DirName;
10145 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10146 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10147 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10148 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10149 return Res;
10150}
10151
10152template <typename Derived>
10153StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
10154 OMPInterchangeDirective *D) {
10155 DeclarationNameInfo DirName;
10156 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10157 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10158 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10159 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10160 return Res;
10161}
10162
10163template <typename Derived>
10164StmtResult
10165TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) {
10166 DeclarationNameInfo DirName;
10167 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10168 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10169 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10170 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10171 return Res;
10172}
10173
10174template <typename Derived>
10175StmtResult
10176TreeTransform<Derived>::TransformOMPFlattenDirective(OMPFlattenDirective *D) {
10177 DeclarationNameInfo DirName;
10178 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10179 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10180 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10181 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10182 return Res;
10183}
10184
10185template <typename Derived>
10186StmtResult
10187TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
10188 DeclarationNameInfo DirName;
10189 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10190 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10191 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10192 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10193 return Res;
10194}
10195
10196template <typename Derived>
10197StmtResult
10198TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
10199 DeclarationNameInfo DirName;
10200 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10201 OMPD_for, DirName, nullptr, D->getBeginLoc());
10202 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10203 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10204 return Res;
10205}
10206
10207template <typename Derived>
10208StmtResult
10209TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
10210 DeclarationNameInfo DirName;
10211 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10212 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
10213 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10214 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10215 return Res;
10216}
10217
10218template <typename Derived>
10219StmtResult
10220TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
10221 DeclarationNameInfo DirName;
10222 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10223 OMPD_sections, DirName, nullptr, D->getBeginLoc());
10224 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10225 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10226 return Res;
10227}
10228
10229template <typename Derived>
10230StmtResult
10231TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
10232 DeclarationNameInfo DirName;
10233 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10234 OMPD_section, DirName, nullptr, D->getBeginLoc());
10235 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10236 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10237 return Res;
10238}
10239
10240template <typename Derived>
10241StmtResult
10242TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
10243 DeclarationNameInfo DirName;
10244 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10245 OMPD_scope, DirName, nullptr, D->getBeginLoc());
10246 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10247 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10248 return Res;
10249}
10250
10251template <typename Derived>
10252StmtResult
10253TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
10254 DeclarationNameInfo DirName;
10255 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10256 OMPD_single, DirName, nullptr, D->getBeginLoc());
10257 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10258 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10259 return Res;
10260}
10261
10262template <typename Derived>
10263StmtResult
10264TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
10265 DeclarationNameInfo DirName;
10266 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10267 OMPD_master, DirName, nullptr, D->getBeginLoc());
10268 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10269 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10270 return Res;
10271}
10272
10273template <typename Derived>
10274StmtResult
10275TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
10276 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10277 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
10278 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10279 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10280 return Res;
10281}
10282
10283template <typename Derived>
10284StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
10285 OMPParallelForDirective *D) {
10286 DeclarationNameInfo DirName;
10287 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10288 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
10289 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10290 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10291 return Res;
10292}
10293
10294template <typename Derived>
10295StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
10296 OMPParallelForSimdDirective *D) {
10297 DeclarationNameInfo DirName;
10298 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10299 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10300 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10301 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10302 return Res;
10303}
10304
10305template <typename Derived>
10306StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
10307 OMPParallelMasterDirective *D) {
10308 DeclarationNameInfo DirName;
10309 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10310 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
10311 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10312 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10313 return Res;
10314}
10315
10316template <typename Derived>
10317StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
10318 OMPParallelMaskedDirective *D) {
10319 DeclarationNameInfo DirName;
10320 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10321 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
10322 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10323 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10324 return Res;
10325}
10326
10327template <typename Derived>
10328StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
10329 OMPParallelSectionsDirective *D) {
10330 DeclarationNameInfo DirName;
10331 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10332 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
10333 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10334 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10335 return Res;
10336}
10337
10338template <typename Derived>
10339StmtResult
10340TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
10341 DeclarationNameInfo DirName;
10342 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10343 OMPD_task, DirName, nullptr, D->getBeginLoc());
10344 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10345 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10346 return Res;
10347}
10348
10349template <typename Derived>
10350StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
10351 OMPTaskyieldDirective *D) {
10352 DeclarationNameInfo DirName;
10353 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10354 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
10355 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10356 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10357 return Res;
10358}
10359
10360template <typename Derived>
10361StmtResult
10362TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
10363 DeclarationNameInfo DirName;
10364 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10365 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
10366 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10367 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10368 return Res;
10369}
10370
10371template <typename Derived>
10372StmtResult
10373TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
10374 DeclarationNameInfo DirName;
10375 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10376 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
10377 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10378 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10379 return Res;
10380}
10381
10382template <typename Derived>
10383StmtResult
10384TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
10385 DeclarationNameInfo DirName;
10386 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10387 OMPD_assume, DirName, nullptr, D->getBeginLoc());
10388 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
10389 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10390 return Res;
10391}
10392
10393template <typename Derived>
10394StmtResult
10395TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
10396 DeclarationNameInfo DirName;
10397 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10398 OMPD_error, DirName, nullptr, D->getBeginLoc());
10399 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10400 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10401 return Res;
10402}
10403
10404template <typename Derived>
10405StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
10406 OMPTaskgroupDirective *D) {
10407 DeclarationNameInfo DirName;
10408 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10409 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
10410 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10411 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10412 return Res;
10413}
10414
10415template <typename Derived>
10416StmtResult
10417TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
10418 DeclarationNameInfo DirName;
10419 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10420 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10421 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10422 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10423 return Res;
10424}
10425
10426template <typename Derived>
10427StmtResult
10428TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10429 DeclarationNameInfo DirName;
10430 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10431 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10432 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10433 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10434 return Res;
10435}
10436
10437template <typename Derived>
10438StmtResult
10439TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10440 DeclarationNameInfo DirName;
10441 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10442 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10443 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10444 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10445 return Res;
10446}
10447
10448template <typename Derived>
10449StmtResult TreeTransform<Derived>::TransformOMPOrderedStandaloneDirective(
10450 OMPOrderedStandaloneDirective *D) {
10451 DeclarationNameInfo DirName;
10452 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10453 OMPD_ordered_standalone, DirName, nullptr, D->getBeginLoc());
10454 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10455 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10456 return Res;
10457}
10458
10459template <typename Derived>
10460StmtResult TreeTransform<Derived>::TransformOMPOrderedBlockAssocDirective(
10461 OMPOrderedBlockAssocDirective *D) {
10462 DeclarationNameInfo DirName;
10463 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10464 OMPD_ordered_blockassoc, DirName, nullptr, D->getBeginLoc());
10465 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10466 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10467 return Res;
10468}
10469
10470template <typename Derived>
10471StmtResult
10472TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10473 DeclarationNameInfo DirName;
10474 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10475 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10476 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10477 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10478 return Res;
10479}
10480
10481template <typename Derived>
10482StmtResult
10483TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10484 DeclarationNameInfo DirName;
10485 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10486 OMPD_target, DirName, nullptr, D->getBeginLoc());
10487 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10488 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10489 return Res;
10490}
10491
10492template <typename Derived>
10493StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10494 OMPTargetDataDirective *D) {
10495 DeclarationNameInfo DirName;
10496 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10497 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10498 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10499 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10500 return Res;
10501}
10502
10503template <typename Derived>
10504StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10505 OMPTargetEnterDataDirective *D) {
10506 DeclarationNameInfo DirName;
10507 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10508 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10509 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10510 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10511 return Res;
10512}
10513
10514template <typename Derived>
10515StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10516 OMPTargetExitDataDirective *D) {
10517 DeclarationNameInfo DirName;
10518 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10519 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10520 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10521 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10522 return Res;
10523}
10524
10525template <typename Derived>
10526StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10527 OMPTargetParallelDirective *D) {
10528 DeclarationNameInfo DirName;
10529 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10530 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10531 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10532 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10533 return Res;
10534}
10535
10536template <typename Derived>
10537StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10538 OMPTargetParallelForDirective *D) {
10539 DeclarationNameInfo DirName;
10540 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10541 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10542 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10543 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10544 return Res;
10545}
10546
10547template <typename Derived>
10548StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10549 OMPTargetUpdateDirective *D) {
10550 DeclarationNameInfo DirName;
10551 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10552 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10553 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10554 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10555 return Res;
10556}
10557
10558template <typename Derived>
10559StmtResult
10560TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10561 DeclarationNameInfo DirName;
10562 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10563 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10564 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10565 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10566 return Res;
10567}
10568
10569template <typename Derived>
10570StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10571 OMPCancellationPointDirective *D) {
10572 DeclarationNameInfo DirName;
10573 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10574 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10575 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10576 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10577 return Res;
10578}
10579
10580template <typename Derived>
10581StmtResult
10582TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10583 DeclarationNameInfo DirName;
10584 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10585 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10586 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10587 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10588 return Res;
10589}
10590
10591template <typename Derived>
10592StmtResult
10593TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10594 DeclarationNameInfo DirName;
10595 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10596 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10597 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10598 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10599 return Res;
10600}
10601
10602template <typename Derived>
10603StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10604 OMPTaskLoopSimdDirective *D) {
10605 DeclarationNameInfo DirName;
10606 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10607 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10608 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10609 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10610 return Res;
10611}
10612
10613template <typename Derived>
10614StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10615 OMPMasterTaskLoopDirective *D) {
10616 DeclarationNameInfo DirName;
10617 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10618 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10619 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10620 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10621 return Res;
10622}
10623
10624template <typename Derived>
10625StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10626 OMPMaskedTaskLoopDirective *D) {
10627 DeclarationNameInfo DirName;
10628 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10629 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10630 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10631 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10632 return Res;
10633}
10634
10635template <typename Derived>
10636StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10637 OMPMasterTaskLoopSimdDirective *D) {
10638 DeclarationNameInfo DirName;
10639 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10640 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10641 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10642 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10643 return Res;
10644}
10645
10646template <typename Derived>
10647StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10648 OMPMaskedTaskLoopSimdDirective *D) {
10649 DeclarationNameInfo DirName;
10650 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10651 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10652 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10653 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10654 return Res;
10655}
10656
10657template <typename Derived>
10658StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10659 OMPParallelMasterTaskLoopDirective *D) {
10660 DeclarationNameInfo DirName;
10661 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10662 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10663 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10664 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10665 return Res;
10666}
10667
10668template <typename Derived>
10669StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10670 OMPParallelMaskedTaskLoopDirective *D) {
10671 DeclarationNameInfo DirName;
10672 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10673 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10674 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10675 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10676 return Res;
10677}
10678
10679template <typename Derived>
10680StmtResult
10681TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10682 OMPParallelMasterTaskLoopSimdDirective *D) {
10683 DeclarationNameInfo DirName;
10684 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10685 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10686 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10687 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10688 return Res;
10689}
10690
10691template <typename Derived>
10692StmtResult
10693TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10694 OMPParallelMaskedTaskLoopSimdDirective *D) {
10695 DeclarationNameInfo DirName;
10696 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10697 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10698 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10699 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10700 return Res;
10701}
10702
10703template <typename Derived>
10704StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10705 OMPDistributeDirective *D) {
10706 DeclarationNameInfo DirName;
10707 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10708 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10709 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10710 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10711 return Res;
10712}
10713
10714template <typename Derived>
10715StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10716 OMPDistributeParallelForDirective *D) {
10717 DeclarationNameInfo DirName;
10718 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10719 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10720 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10721 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10722 return Res;
10723}
10724
10725template <typename Derived>
10726StmtResult
10727TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10728 OMPDistributeParallelForSimdDirective *D) {
10729 DeclarationNameInfo DirName;
10730 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10731 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10732 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10733 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10734 return Res;
10735}
10736
10737template <typename Derived>
10738StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10739 OMPDistributeSimdDirective *D) {
10740 DeclarationNameInfo DirName;
10741 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10742 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10743 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10744 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10745 return Res;
10746}
10747
10748template <typename Derived>
10749StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10750 OMPTargetParallelForSimdDirective *D) {
10751 DeclarationNameInfo DirName;
10752 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10753 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10754 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10755 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10756 return Res;
10757}
10758
10759template <typename Derived>
10760StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10761 OMPTargetSimdDirective *D) {
10762 DeclarationNameInfo DirName;
10763 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10764 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10765 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10766 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10767 return Res;
10768}
10769
10770template <typename Derived>
10771StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10772 OMPTeamsDistributeDirective *D) {
10773 DeclarationNameInfo DirName;
10774 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10775 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10776 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10777 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10778 return Res;
10779}
10780
10781template <typename Derived>
10782StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10783 OMPTeamsDistributeSimdDirective *D) {
10784 DeclarationNameInfo DirName;
10785 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10786 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10787 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10788 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10789 return Res;
10790}
10791
10792template <typename Derived>
10793StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10794 OMPTeamsDistributeParallelForSimdDirective *D) {
10795 DeclarationNameInfo DirName;
10796 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10797 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10798 D->getBeginLoc());
10799 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10800 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10801 return Res;
10802}
10803
10804template <typename Derived>
10805StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10806 OMPTeamsDistributeParallelForDirective *D) {
10807 DeclarationNameInfo DirName;
10808 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10809 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10810 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10811 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10812 return Res;
10813}
10814
10815template <typename Derived>
10816StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10817 OMPTargetTeamsDirective *D) {
10818 DeclarationNameInfo DirName;
10819 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10820 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10821 auto Res = getDerived().TransformOMPExecutableDirective(D);
10822 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10823 return Res;
10824}
10825
10826template <typename Derived>
10827StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10828 OMPTargetTeamsDistributeDirective *D) {
10829 DeclarationNameInfo DirName;
10830 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10831 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10832 auto Res = getDerived().TransformOMPExecutableDirective(D);
10833 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10834 return Res;
10835}
10836
10837template <typename Derived>
10838StmtResult
10839TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10840 OMPTargetTeamsDistributeParallelForDirective *D) {
10841 DeclarationNameInfo DirName;
10842 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10843 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10844 D->getBeginLoc());
10845 auto Res = getDerived().TransformOMPExecutableDirective(D);
10846 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10847 return Res;
10848}
10849
10850template <typename Derived>
10851StmtResult TreeTransform<Derived>::
10852 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10853 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10854 DeclarationNameInfo DirName;
10855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10856 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10857 D->getBeginLoc());
10858 auto Res = getDerived().TransformOMPExecutableDirective(D);
10859 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10860 return Res;
10861}
10862
10863template <typename Derived>
10864StmtResult
10865TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10866 OMPTargetTeamsDistributeSimdDirective *D) {
10867 DeclarationNameInfo DirName;
10868 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10869 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10870 auto Res = getDerived().TransformOMPExecutableDirective(D);
10871 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10872 return Res;
10873}
10874
10875template <typename Derived>
10876StmtResult
10877TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10878 DeclarationNameInfo DirName;
10879 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10880 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10881 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10882 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10883 return Res;
10884}
10885
10886template <typename Derived>
10887StmtResult
10888TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10889 DeclarationNameInfo DirName;
10890 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10891 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10892 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10893 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10894 return Res;
10895}
10896
10897template <typename Derived>
10898StmtResult
10899TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10900 DeclarationNameInfo DirName;
10901 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10902 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10903 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10904 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10905 return Res;
10906}
10907
10908template <typename Derived>
10909StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10910 OMPGenericLoopDirective *D) {
10911 DeclarationNameInfo DirName;
10912 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10913 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10914 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10915 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10916 return Res;
10917}
10918
10919template <typename Derived>
10920StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10921 OMPTeamsGenericLoopDirective *D) {
10922 DeclarationNameInfo DirName;
10923 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10924 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10925 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10926 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10927 return Res;
10928}
10929
10930template <typename Derived>
10931StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10932 OMPTargetTeamsGenericLoopDirective *D) {
10933 DeclarationNameInfo DirName;
10934 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10935 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10936 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10937 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10938 return Res;
10939}
10940
10941template <typename Derived>
10942StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10943 OMPParallelGenericLoopDirective *D) {
10944 DeclarationNameInfo DirName;
10945 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10946 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10947 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10948 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10949 return Res;
10950}
10951
10952template <typename Derived>
10953StmtResult
10954TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10955 OMPTargetParallelGenericLoopDirective *D) {
10956 DeclarationNameInfo DirName;
10957 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10958 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10959 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10960 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10961 return Res;
10962}
10963
10964//===----------------------------------------------------------------------===//
10965// OpenMP clause transformation
10966//===----------------------------------------------------------------------===//
10967template <typename Derived>
10968OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10969 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10970 if (Cond.isInvalid())
10971 return nullptr;
10972 return getDerived().RebuildOMPIfClause(
10973 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10974 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10975}
10976
10977template <typename Derived>
10978OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10979 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10980 if (Cond.isInvalid())
10981 return nullptr;
10982 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10983 C->getLParenLoc(), C->getEndLoc());
10984}
10985
10986template <typename Derived>
10987OMPClause *
10988TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10989 llvm::SmallVector<Expr *, 3> Vars;
10990 Vars.reserve(N: C->varlist_size());
10991 for (auto *VE : C->varlist()) {
10992 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10993 if (EVar.isInvalid())
10994 return nullptr;
10995 Vars.push_back(Elt: EVar.get());
10996 }
10997 Expr *DimsModifierExpr = C->getDimsModifierExpr();
10998 if (DimsModifierExpr) {
10999 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: DimsModifierExpr));
11000 if (EVar.isInvalid())
11001 return nullptr;
11002 DimsModifierExpr = EVar.get();
11003 }
11004 return getDerived().RebuildOMPNumThreadsClause(
11005 Vars, C->getPrescriptivenessModifier(),
11006 C->getPrescriptivenessModifierLoc(), C->getDimsModifier(),
11007 DimsModifierExpr, C->getDimsModifierLoc(), C->getBeginLoc(),
11008 C->getLParenLoc(), C->getEndLoc());
11009}
11010
11011template <typename Derived>
11012OMPClause *
11013TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
11014 ExprResult E = getDerived().TransformExpr(C->getSafelen());
11015 if (E.isInvalid())
11016 return nullptr;
11017 return getDerived().RebuildOMPSafelenClause(
11018 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11019}
11020
11021template <typename Derived>
11022OMPClause *
11023TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
11024 ExprResult E = getDerived().TransformExpr(C->getAllocator());
11025 if (E.isInvalid())
11026 return nullptr;
11027 return getDerived().RebuildOMPAllocatorClause(
11028 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11029}
11030
11031template <typename Derived>
11032OMPClause *
11033TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
11034 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
11035 if (E.isInvalid())
11036 return nullptr;
11037 return getDerived().RebuildOMPSimdlenClause(
11038 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11039}
11040
11041template <typename Derived>
11042OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
11043 SmallVector<Expr *, 4> TransformedSizes;
11044 TransformedSizes.reserve(N: C->getNumSizes());
11045 bool Changed = false;
11046 for (Expr *E : C->getSizesRefs()) {
11047 if (!E) {
11048 TransformedSizes.push_back(Elt: nullptr);
11049 continue;
11050 }
11051
11052 ExprResult T = getDerived().TransformExpr(E);
11053 if (T.isInvalid())
11054 return nullptr;
11055 if (E != T.get())
11056 Changed = true;
11057 TransformedSizes.push_back(Elt: T.get());
11058 }
11059
11060 if (!Changed && !getDerived().AlwaysRebuild())
11061 return C;
11062 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
11063 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11064}
11065
11066template <typename Derived>
11067OMPClause *
11068TreeTransform<Derived>::TransformOMPCountsClause(OMPCountsClause *C) {
11069 SmallVector<Expr *, 4> TransformedCounts;
11070 TransformedCounts.reserve(N: C->getNumCounts());
11071 for (Expr *E : C->getCountsRefs()) {
11072 if (!E) {
11073 TransformedCounts.push_back(Elt: nullptr);
11074 continue;
11075 }
11076
11077 ExprResult T = getDerived().TransformExpr(E);
11078 if (T.isInvalid())
11079 return nullptr;
11080 TransformedCounts.push_back(Elt: T.get());
11081 }
11082
11083 return RebuildOMPCountsClause(Counts: TransformedCounts, StartLoc: C->getBeginLoc(),
11084 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc(),
11085 FillIdx: C->getOmpFillIndex(), FillLoc: C->getOmpFillLoc());
11086}
11087
11088template <typename Derived>
11089OMPClause *
11090TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
11091 SmallVector<Expr *> TransformedArgs;
11092 TransformedArgs.reserve(N: C->getNumLoops());
11093 bool Changed = false;
11094 for (Expr *E : C->getArgsRefs()) {
11095 if (!E) {
11096 TransformedArgs.push_back(Elt: nullptr);
11097 continue;
11098 }
11099
11100 ExprResult T = getDerived().TransformExpr(E);
11101 if (T.isInvalid())
11102 return nullptr;
11103 if (E != T.get())
11104 Changed = true;
11105 TransformedArgs.push_back(Elt: T.get());
11106 }
11107
11108 if (!Changed && !getDerived().AlwaysRebuild())
11109 return C;
11110 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
11111 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11112}
11113
11114template <typename Derived>
11115OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
11116 if (!getDerived().AlwaysRebuild())
11117 return C;
11118 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
11119}
11120
11121template <typename Derived>
11122OMPClause *
11123TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
11124 ExprResult T = getDerived().TransformExpr(C->getFactor());
11125 if (T.isInvalid())
11126 return nullptr;
11127 Expr *Factor = T.get();
11128 bool Changed = Factor != C->getFactor();
11129
11130 if (!Changed && !getDerived().AlwaysRebuild())
11131 return C;
11132 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
11133 EndLoc: C->getEndLoc());
11134}
11135
11136template <typename Derived>
11137OMPClause *TreeTransform<Derived>::TransformOMPDepthClause(OMPDepthClause *C) {
11138 ExprResult T = getDerived().TransformExpr(C->getDepth());
11139 if (T.isInvalid())
11140 return nullptr;
11141 Expr *Depth = T.get();
11142 bool Changed = Depth != C->getDepth();
11143
11144 if (!Changed && !getDerived().AlwaysRebuild())
11145 return C;
11146 return RebuildOMPDepthClause(Depth, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
11147 EndLoc: C->getEndLoc());
11148}
11149
11150template <typename Derived>
11151OMPClause *
11152TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
11153 ExprResult F = getDerived().TransformExpr(C->getFirst());
11154 if (F.isInvalid())
11155 return nullptr;
11156
11157 ExprResult Cn = getDerived().TransformExpr(C->getCount());
11158 if (Cn.isInvalid())
11159 return nullptr;
11160
11161 Expr *First = F.get();
11162 Expr *Count = Cn.get();
11163
11164 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
11165
11166 // If no changes and AlwaysRebuild() is false, return the original clause
11167 if (!Changed && !getDerived().AlwaysRebuild())
11168 return C;
11169
11170 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
11171 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
11172 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
11173}
11174
11175template <typename Derived>
11176OMPClause *
11177TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
11178 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
11179 if (E.isInvalid())
11180 return nullptr;
11181 return getDerived().RebuildOMPCollapseClause(
11182 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11183}
11184
11185template <typename Derived>
11186OMPClause *
11187TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
11188 return getDerived().RebuildOMPDefaultClause(
11189 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
11190 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
11191 C->getEndLoc());
11192}
11193
11194template <typename Derived>
11195OMPClause *
11196TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
11197 // No need to rebuild this clause, no template-dependent parameters.
11198 return C;
11199}
11200
11201template <typename Derived>
11202OMPClause *
11203TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
11204 Expr *Impex = C->getImpexType();
11205 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
11206
11207 if (TransformedImpex.isInvalid())
11208 return nullptr;
11209
11210 return getDerived().RebuildOMPTransparentClause(
11211 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
11212 C->getEndLoc());
11213}
11214
11215template <typename Derived>
11216OMPClause *
11217TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
11218 return getDerived().RebuildOMPProcBindClause(
11219 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
11220 C->getLParenLoc(), C->getEndLoc());
11221}
11222
11223template <typename Derived>
11224OMPClause *
11225TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
11226 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11227 if (E.isInvalid())
11228 return nullptr;
11229 return getDerived().RebuildOMPScheduleClause(
11230 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
11231 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11232 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
11233 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11234}
11235
11236template <typename Derived>
11237OMPClause *
11238TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
11239 ExprResult E;
11240 if (auto *Num = C->getNumForLoops()) {
11241 E = getDerived().TransformExpr(Num);
11242 if (E.isInvalid())
11243 return nullptr;
11244 }
11245 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
11246 C->getLParenLoc(), E.get());
11247}
11248
11249template <typename Derived>
11250OMPClause *
11251TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
11252 ExprResult E;
11253 if (Expr *Evt = C->getEventHandler()) {
11254 E = getDerived().TransformExpr(Evt);
11255 if (E.isInvalid())
11256 return nullptr;
11257 }
11258 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
11259 C->getLParenLoc(), C->getEndLoc());
11260}
11261
11262template <typename Derived>
11263OMPClause *
11264TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
11265 ExprResult Cond;
11266 if (auto *Condition = C->getCondition()) {
11267 Cond = getDerived().TransformExpr(Condition);
11268 if (Cond.isInvalid())
11269 return nullptr;
11270 }
11271 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
11272 C->getLParenLoc(), C->getEndLoc());
11273}
11274
11275template <typename Derived>
11276OMPClause *
11277TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
11278 // No need to rebuild this clause, no template-dependent parameters.
11279 return C;
11280}
11281
11282template <typename Derived>
11283OMPClause *
11284TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
11285 // No need to rebuild this clause, no template-dependent parameters.
11286 return C;
11287}
11288
11289template <typename Derived>
11290OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
11291 // No need to rebuild this clause, no template-dependent parameters.
11292 return C;
11293}
11294
11295template <typename Derived>
11296OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
11297 // No need to rebuild this clause, no template-dependent parameters.
11298 return C;
11299}
11300
11301template <typename Derived>
11302OMPClause *
11303TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
11304 // No need to rebuild this clause, no template-dependent parameters.
11305 return C;
11306}
11307
11308template <typename Derived>
11309OMPClause *TreeTransform<Derived>::TransformOMPUpdateDependObjectsClause(
11310 OMPUpdateDependObjectsClause *C) {
11311 // No need to rebuild this clause, no template-dependent parameters.
11312 return C;
11313}
11314
11315template <typename Derived>
11316OMPClause *
11317TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
11318 // No need to rebuild this clause, no template-dependent parameters.
11319 return C;
11320}
11321
11322template <typename Derived>
11323OMPClause *
11324TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
11325 // No need to rebuild this clause, no template-dependent parameters.
11326 return C;
11327}
11328
11329template <typename Derived>
11330OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
11331 // No need to rebuild this clause, no template-dependent parameters.
11332 return C;
11333}
11334
11335template <typename Derived>
11336OMPClause *
11337TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
11338 return C;
11339}
11340
11341template <typename Derived>
11342OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
11343 ExprResult E = getDerived().TransformExpr(C->getExpr());
11344 if (E.isInvalid())
11345 return nullptr;
11346 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
11347 C->getLParenLoc(), C->getEndLoc());
11348}
11349
11350template <typename Derived>
11351OMPClause *
11352TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
11353 return C;
11354}
11355
11356template <typename Derived>
11357OMPClause *
11358TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
11359 return C;
11360}
11361template <typename Derived>
11362OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
11363 OMPNoOpenMPRoutinesClause *C) {
11364 return C;
11365}
11366template <typename Derived>
11367OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
11368 OMPNoOpenMPConstructsClause *C) {
11369 return C;
11370}
11371template <typename Derived>
11372OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
11373 OMPNoParallelismClause *C) {
11374 return C;
11375}
11376
11377template <typename Derived>
11378OMPClause *
11379TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
11380 // No need to rebuild this clause, no template-dependent parameters.
11381 return C;
11382}
11383
11384template <typename Derived>
11385OMPClause *
11386TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
11387 // No need to rebuild this clause, no template-dependent parameters.
11388 return C;
11389}
11390
11391template <typename Derived>
11392OMPClause *
11393TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
11394 // No need to rebuild this clause, no template-dependent parameters.
11395 return C;
11396}
11397
11398template <typename Derived>
11399OMPClause *
11400TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
11401 // No need to rebuild this clause, no template-dependent parameters.
11402 return C;
11403}
11404
11405template <typename Derived>
11406OMPClause *
11407TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
11408 // No need to rebuild this clause, no template-dependent parameters.
11409 return C;
11410}
11411
11412template <typename Derived>
11413OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
11414 // No need to rebuild this clause, no template-dependent parameters.
11415 return C;
11416}
11417
11418template <typename Derived>
11419OMPClause *
11420TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
11421 // No need to rebuild this clause, no template-dependent parameters.
11422 return C;
11423}
11424
11425template <typename Derived>
11426OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
11427 // No need to rebuild this clause, no template-dependent parameters.
11428 return C;
11429}
11430
11431template <typename Derived>
11432OMPClause *
11433TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
11434 // No need to rebuild this clause, no template-dependent parameters.
11435 return C;
11436}
11437
11438template <typename Derived>
11439OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
11440 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
11441 if (IVR.isInvalid())
11442 return nullptr;
11443
11444 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
11445 for (OMPInitClause::PrefView P : C->prefs()) {
11446 Expr *NewFr = nullptr;
11447 if (P.Fr) {
11448 ExprResult ER = getDerived().TransformExpr(P.Fr);
11449 if (ER.isInvalid())
11450 return nullptr;
11451 NewFr = ER.get();
11452 }
11453 SmallVector<Expr *, 2> NewAttrs;
11454 NewAttrs.reserve(N: P.Attrs.size());
11455 for (Expr *A : P.Attrs) {
11456 ExprResult ER = getDerived().TransformExpr(A);
11457 if (ER.isInvalid())
11458 return nullptr;
11459 NewAttrs.push_back(Elt: ER.get());
11460 }
11461 InteropInfo.Prefs.emplace_back(Args&: NewFr, Args: std::move(NewAttrs));
11462 }
11463 InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
11464 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
11465 C->getBeginLoc(), C->getLParenLoc(),
11466 C->getVarLoc(), C->getEndLoc());
11467}
11468
11469template <typename Derived>
11470OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
11471 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
11472 if (ER.isInvalid())
11473 return nullptr;
11474 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
11475 C->getLParenLoc(), C->getVarLoc(),
11476 C->getEndLoc());
11477}
11478
11479template <typename Derived>
11480OMPClause *
11481TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
11482 ExprResult ER;
11483 if (Expr *IV = C->getInteropVar()) {
11484 ER = getDerived().TransformExpr(IV);
11485 if (ER.isInvalid())
11486 return nullptr;
11487 }
11488 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
11489 C->getLParenLoc(), C->getVarLoc(),
11490 C->getEndLoc());
11491}
11492
11493template <typename Derived>
11494OMPClause *
11495TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
11496 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11497 if (Cond.isInvalid())
11498 return nullptr;
11499 return getDerived().RebuildOMPNovariantsClause(
11500 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11501}
11502
11503template <typename Derived>
11504OMPClause *
11505TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11506 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11507 if (Cond.isInvalid())
11508 return nullptr;
11509 return getDerived().RebuildOMPNocontextClause(
11510 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11511}
11512
11513template <typename Derived>
11514OMPClause *
11515TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11516 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11517 if (ThreadID.isInvalid())
11518 return nullptr;
11519 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11520 C->getLParenLoc(), C->getEndLoc());
11521}
11522
11523template <typename Derived>
11524OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11525 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11526 if (E.isInvalid())
11527 return nullptr;
11528 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11529 C->getLParenLoc(), C->getEndLoc());
11530}
11531
11532template <typename Derived>
11533OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11534 OMPUnifiedAddressClause *C) {
11535 llvm_unreachable("unified_address clause cannot appear in dependent context");
11536}
11537
11538template <typename Derived>
11539OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11540 OMPUnifiedSharedMemoryClause *C) {
11541 llvm_unreachable(
11542 "unified_shared_memory clause cannot appear in dependent context");
11543}
11544
11545template <typename Derived>
11546OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11547 OMPReverseOffloadClause *C) {
11548 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11549}
11550
11551template <typename Derived>
11552OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11553 OMPDynamicAllocatorsClause *C) {
11554 llvm_unreachable(
11555 "dynamic_allocators clause cannot appear in dependent context");
11556}
11557
11558template <typename Derived>
11559OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11560 OMPAtomicDefaultMemOrderClause *C) {
11561 llvm_unreachable(
11562 "atomic_default_mem_order clause cannot appear in dependent context");
11563}
11564
11565template <typename Derived>
11566OMPClause *
11567TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11568 llvm_unreachable("self_maps clause cannot appear in dependent context");
11569}
11570
11571template <typename Derived>
11572OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11573 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11574 C->getBeginLoc(), C->getLParenLoc(),
11575 C->getEndLoc());
11576}
11577
11578template <typename Derived>
11579OMPClause *
11580TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11581 return getDerived().RebuildOMPSeverityClause(
11582 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11583 C->getLParenLoc(), C->getEndLoc());
11584}
11585
11586template <typename Derived>
11587OMPClause *
11588TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11589 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11590 if (E.isInvalid())
11591 return nullptr;
11592 return getDerived().RebuildOMPMessageClause(
11593 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11594}
11595
11596template <typename Derived>
11597OMPClause *
11598TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11599 llvm::SmallVector<Expr *, 16> Vars;
11600 Vars.reserve(N: C->varlist_size());
11601 for (auto *VE : C->varlist()) {
11602 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11603 if (EVar.isInvalid())
11604 return nullptr;
11605 Vars.push_back(Elt: EVar.get());
11606 }
11607 return getDerived().RebuildOMPPrivateClause(
11608 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11609}
11610
11611template <typename Derived>
11612OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11613 OMPFirstprivateClause *C) {
11614 llvm::SmallVector<Expr *, 16> Vars;
11615 Vars.reserve(N: C->varlist_size());
11616 for (auto *VE : C->varlist()) {
11617 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11618 if (EVar.isInvalid())
11619 return nullptr;
11620 Vars.push_back(Elt: EVar.get());
11621 }
11622 return getDerived().RebuildOMPFirstprivateClause(
11623 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11624}
11625
11626template <typename Derived>
11627OMPClause *
11628TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11629 llvm::SmallVector<Expr *, 16> Vars;
11630 Vars.reserve(N: C->varlist_size());
11631 for (auto *VE : C->varlist()) {
11632 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11633 if (EVar.isInvalid())
11634 return nullptr;
11635 Vars.push_back(Elt: EVar.get());
11636 }
11637 return getDerived().RebuildOMPLastprivateClause(
11638 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11639 C->getLParenLoc(), C->getEndLoc());
11640}
11641
11642template <typename Derived>
11643OMPClause *
11644TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11645 llvm::SmallVector<Expr *, 16> Vars;
11646 Vars.reserve(N: C->varlist_size());
11647 for (auto *VE : C->varlist()) {
11648 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11649 if (EVar.isInvalid())
11650 return nullptr;
11651 Vars.push_back(Elt: EVar.get());
11652 }
11653 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11654 C->getLParenLoc(), C->getEndLoc());
11655}
11656
11657template <typename Derived>
11658OMPClause *
11659TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11660 llvm::SmallVector<Expr *, 16> Vars;
11661 Vars.reserve(N: C->varlist_size());
11662 for (auto *VE : C->varlist()) {
11663 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11664 if (EVar.isInvalid())
11665 return nullptr;
11666 Vars.push_back(Elt: EVar.get());
11667 }
11668 CXXScopeSpec ReductionIdScopeSpec;
11669 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11670
11671 DeclarationNameInfo NameInfo = C->getNameInfo();
11672 if (NameInfo.getName()) {
11673 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11674 if (!NameInfo.getName())
11675 return nullptr;
11676 }
11677 // Build a list of all UDR decls with the same names ranged by the Scopes.
11678 // The Scope boundary is a duplication of the previous decl.
11679 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11680 for (auto *E : C->reduction_ops()) {
11681 // Transform all the decls.
11682 if (E) {
11683 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11684 UnresolvedSet<8> Decls;
11685 for (auto *D : ULE->decls()) {
11686 NamedDecl *InstD =
11687 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11688 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11689 }
11690 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11691 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11692 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11693 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11694 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11695 } else
11696 UnresolvedReductions.push_back(Elt: nullptr);
11697 }
11698 return getDerived().RebuildOMPReductionClause(
11699 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11700 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11701 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11702}
11703
11704template <typename Derived>
11705OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11706 OMPTaskReductionClause *C) {
11707 llvm::SmallVector<Expr *, 16> Vars;
11708 Vars.reserve(N: C->varlist_size());
11709 for (auto *VE : C->varlist()) {
11710 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11711 if (EVar.isInvalid())
11712 return nullptr;
11713 Vars.push_back(Elt: EVar.get());
11714 }
11715 CXXScopeSpec ReductionIdScopeSpec;
11716 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11717
11718 DeclarationNameInfo NameInfo = C->getNameInfo();
11719 if (NameInfo.getName()) {
11720 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11721 if (!NameInfo.getName())
11722 return nullptr;
11723 }
11724 // Build a list of all UDR decls with the same names ranged by the Scopes.
11725 // The Scope boundary is a duplication of the previous decl.
11726 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11727 for (auto *E : C->reduction_ops()) {
11728 // Transform all the decls.
11729 if (E) {
11730 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11731 UnresolvedSet<8> Decls;
11732 for (auto *D : ULE->decls()) {
11733 NamedDecl *InstD =
11734 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11735 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11736 }
11737 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11738 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11739 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11740 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11741 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11742 } else
11743 UnresolvedReductions.push_back(Elt: nullptr);
11744 }
11745 return getDerived().RebuildOMPTaskReductionClause(
11746 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11747 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11748}
11749
11750template <typename Derived>
11751OMPClause *
11752TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11753 llvm::SmallVector<Expr *, 16> Vars;
11754 Vars.reserve(N: C->varlist_size());
11755 for (auto *VE : C->varlist()) {
11756 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11757 if (EVar.isInvalid())
11758 return nullptr;
11759 Vars.push_back(Elt: EVar.get());
11760 }
11761 CXXScopeSpec ReductionIdScopeSpec;
11762 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11763
11764 DeclarationNameInfo NameInfo = C->getNameInfo();
11765 if (NameInfo.getName()) {
11766 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11767 if (!NameInfo.getName())
11768 return nullptr;
11769 }
11770 // Build a list of all UDR decls with the same names ranged by the Scopes.
11771 // The Scope boundary is a duplication of the previous decl.
11772 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11773 for (auto *E : C->reduction_ops()) {
11774 // Transform all the decls.
11775 if (E) {
11776 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11777 UnresolvedSet<8> Decls;
11778 for (auto *D : ULE->decls()) {
11779 NamedDecl *InstD =
11780 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11781 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11782 }
11783 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11784 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11785 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11786 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11787 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11788 } else
11789 UnresolvedReductions.push_back(Elt: nullptr);
11790 }
11791 return getDerived().RebuildOMPInReductionClause(
11792 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11793 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11794}
11795
11796template <typename Derived>
11797OMPClause *
11798TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11799 llvm::SmallVector<Expr *, 16> Vars;
11800 Vars.reserve(N: C->varlist_size());
11801 for (auto *VE : C->varlist()) {
11802 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11803 if (EVar.isInvalid())
11804 return nullptr;
11805 Vars.push_back(Elt: EVar.get());
11806 }
11807 ExprResult Step = getDerived().TransformExpr(C->getStep());
11808 if (Step.isInvalid())
11809 return nullptr;
11810 return getDerived().RebuildOMPLinearClause(
11811 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11812 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11813 C->getEndLoc());
11814}
11815
11816template <typename Derived>
11817OMPClause *
11818TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11819 llvm::SmallVector<Expr *, 16> Vars;
11820 Vars.reserve(N: C->varlist_size());
11821 for (auto *VE : C->varlist()) {
11822 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11823 if (EVar.isInvalid())
11824 return nullptr;
11825 Vars.push_back(Elt: EVar.get());
11826 }
11827 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11828 if (Alignment.isInvalid())
11829 return nullptr;
11830 return getDerived().RebuildOMPAlignedClause(
11831 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11832 C->getColonLoc(), C->getEndLoc());
11833}
11834
11835template <typename Derived>
11836OMPClause *
11837TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11838 llvm::SmallVector<Expr *, 16> Vars;
11839 Vars.reserve(N: C->varlist_size());
11840 for (auto *VE : C->varlist()) {
11841 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11842 if (EVar.isInvalid())
11843 return nullptr;
11844 Vars.push_back(Elt: EVar.get());
11845 }
11846 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11847 C->getLParenLoc(), C->getEndLoc());
11848}
11849
11850template <typename Derived>
11851OMPClause *
11852TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11853 llvm::SmallVector<Expr *, 16> Vars;
11854 Vars.reserve(N: C->varlist_size());
11855 for (auto *VE : C->varlist()) {
11856 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11857 if (EVar.isInvalid())
11858 return nullptr;
11859 Vars.push_back(Elt: EVar.get());
11860 }
11861 return getDerived().RebuildOMPCopyprivateClause(
11862 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11863}
11864
11865template <typename Derived>
11866OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11867 llvm::SmallVector<Expr *, 16> Vars;
11868 Vars.reserve(N: C->varlist_size());
11869 for (auto *VE : C->varlist()) {
11870 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11871 if (EVar.isInvalid())
11872 return nullptr;
11873 Vars.push_back(Elt: EVar.get());
11874 }
11875 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11876 C->getLParenLoc(), C->getEndLoc());
11877}
11878
11879template <typename Derived>
11880OMPClause *
11881TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11882 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11883 if (E.isInvalid())
11884 return nullptr;
11885 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11886 C->getLParenLoc(), C->getEndLoc());
11887}
11888
11889template <typename Derived>
11890OMPClause *
11891TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11892 llvm::SmallVector<Expr *, 16> Vars;
11893 Expr *DepModifier = C->getModifier();
11894 if (DepModifier) {
11895 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11896 if (DepModRes.isInvalid())
11897 return nullptr;
11898 DepModifier = DepModRes.get();
11899 }
11900 Vars.reserve(N: C->varlist_size());
11901 for (auto *VE : C->varlist()) {
11902 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11903 if (EVar.isInvalid())
11904 return nullptr;
11905 Vars.push_back(Elt: EVar.get());
11906 }
11907 return getDerived().RebuildOMPDependClause(
11908 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11909 C->getOmpAllMemoryLoc()},
11910 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11911}
11912
11913template <typename Derived>
11914OMPClause *
11915TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11916 ExprResult E = getDerived().TransformExpr(C->getDevice());
11917 if (E.isInvalid())
11918 return nullptr;
11919 return getDerived().RebuildOMPDeviceClause(
11920 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11921 C->getModifierLoc(), C->getEndLoc());
11922}
11923
11924template <typename Derived, class T>
11925bool transformOMPMappableExprListClause(
11926 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11927 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11928 DeclarationNameInfo &MapperIdInfo,
11929 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11930 // Transform expressions in the list.
11931 Vars.reserve(N: C->varlist_size());
11932 for (auto *VE : C->varlist()) {
11933 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11934 if (EVar.isInvalid())
11935 return true;
11936 Vars.push_back(Elt: EVar.get());
11937 }
11938 // Transform mapper scope specifier and identifier.
11939 NestedNameSpecifierLoc QualifierLoc;
11940 if (C->getMapperQualifierLoc()) {
11941 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11942 C->getMapperQualifierLoc());
11943 if (!QualifierLoc)
11944 return true;
11945 }
11946 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11947 MapperIdInfo = C->getMapperIdInfo();
11948 if (MapperIdInfo.getName()) {
11949 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11950 if (!MapperIdInfo.getName())
11951 return true;
11952 }
11953 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11954 // the previous user-defined mapper lookup in dependent environment.
11955 for (auto *E : C->mapperlists()) {
11956 // Transform all the decls.
11957 if (E) {
11958 auto *ULE = cast<UnresolvedLookupExpr>(E);
11959 UnresolvedSet<8> Decls;
11960 for (auto *D : ULE->decls()) {
11961 NamedDecl *InstD =
11962 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11963 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11964 }
11965 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11966 TT.getSema().Context, /*NamingClass=*/nullptr,
11967 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11968 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11969 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11970 } else {
11971 UnresolvedMappers.push_back(Elt: nullptr);
11972 }
11973 }
11974 return false;
11975}
11976
11977template <typename Derived>
11978OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11979 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11980 llvm::SmallVector<Expr *, 16> Vars;
11981 Expr *IteratorModifier = C->getIteratorModifier();
11982 if (IteratorModifier) {
11983 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11984 if (MapModRes.isInvalid())
11985 return nullptr;
11986 IteratorModifier = MapModRes.get();
11987 }
11988 CXXScopeSpec MapperIdScopeSpec;
11989 DeclarationNameInfo MapperIdInfo;
11990 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11991 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11992 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11993 return nullptr;
11994 return getDerived().RebuildOMPMapClause(
11995 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11996 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11997 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11998}
11999
12000template <typename Derived>
12001OMPClause *
12002TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
12003 Expr *Allocator = C->getAllocator();
12004 if (Allocator) {
12005 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
12006 if (AllocatorRes.isInvalid())
12007 return nullptr;
12008 Allocator = AllocatorRes.get();
12009 }
12010 Expr *Alignment = C->getAlignment();
12011 if (Alignment) {
12012 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
12013 if (AlignmentRes.isInvalid())
12014 return nullptr;
12015 Alignment = AlignmentRes.get();
12016 }
12017 llvm::SmallVector<Expr *, 16> Vars;
12018 Vars.reserve(N: C->varlist_size());
12019 for (auto *VE : C->varlist()) {
12020 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12021 if (EVar.isInvalid())
12022 return nullptr;
12023 Vars.push_back(Elt: EVar.get());
12024 }
12025 return getDerived().RebuildOMPAllocateClause(
12026 Allocator, Alignment, C->getFirstAllocateModifier(),
12027 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
12028 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
12029 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
12030}
12031
12032template <typename Derived>
12033OMPClause *
12034TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
12035 llvm::SmallVector<Expr *, 3> Vars;
12036 Vars.reserve(N: C->varlist_size());
12037 for (auto *VE : C->varlist()) {
12038 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12039 if (EVar.isInvalid())
12040 return nullptr;
12041 Vars.push_back(Elt: EVar.get());
12042 }
12043 Expr *ModifierExpr = C->getModifierExpr();
12044 if (ModifierExpr) {
12045 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12046 if (EVar.isInvalid())
12047 return nullptr;
12048 ModifierExpr = EVar.get();
12049 }
12050 return getDerived().RebuildOMPNumTeamsClause(
12051 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12052 OMPC_NUMTEAMS_unknown, nullptr, SourceLocation(), C->getBeginLoc(),
12053 C->getLParenLoc(), C->getEndLoc());
12054}
12055
12056template <typename Derived>
12057OMPClause *
12058TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
12059 llvm::SmallVector<Expr *, 3> Vars;
12060 Vars.reserve(N: C->varlist_size());
12061 for (auto *VE : C->varlist()) {
12062 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12063 if (EVar.isInvalid())
12064 return nullptr;
12065 Vars.push_back(Elt: EVar.get());
12066 }
12067 Expr *ModifierExpr = C->getModifierExpr();
12068 if (ModifierExpr) {
12069 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12070 if (EVar.isInvalid())
12071 return nullptr;
12072 ModifierExpr = EVar.get();
12073 }
12074 return getDerived().RebuildOMPThreadLimitClause(
12075 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12076 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12077}
12078
12079template <typename Derived>
12080OMPClause *
12081TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
12082 ExprResult E = getDerived().TransformExpr(C->getPriority());
12083 if (E.isInvalid())
12084 return nullptr;
12085 return getDerived().RebuildOMPPriorityClause(
12086 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12087}
12088
12089template <typename Derived>
12090OMPClause *
12091TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
12092 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
12093 if (E.isInvalid())
12094 return nullptr;
12095 return getDerived().RebuildOMPGrainsizeClause(
12096 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12097 C->getModifierLoc(), C->getEndLoc());
12098}
12099
12100template <typename Derived>
12101OMPClause *
12102TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
12103 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
12104 if (E.isInvalid())
12105 return nullptr;
12106 return getDerived().RebuildOMPNumTasksClause(
12107 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12108 C->getModifierLoc(), C->getEndLoc());
12109}
12110
12111template <typename Derived>
12112OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
12113 ExprResult E = getDerived().TransformExpr(C->getHint());
12114 if (E.isInvalid())
12115 return nullptr;
12116 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
12117 C->getLParenLoc(), C->getEndLoc());
12118}
12119
12120template <typename Derived>
12121OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
12122 OMPDistScheduleClause *C) {
12123 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
12124 if (E.isInvalid())
12125 return nullptr;
12126 return getDerived().RebuildOMPDistScheduleClause(
12127 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12128 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
12129}
12130
12131template <typename Derived>
12132OMPClause *
12133TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
12134 // Rebuild Defaultmap Clause since we need to invoke the checking of
12135 // defaultmap(none:variable-category) after template initialization.
12136 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
12137 C->getDefaultmapKind(),
12138 C->getBeginLoc(),
12139 C->getLParenLoc(),
12140 C->getDefaultmapModifierLoc(),
12141 C->getDefaultmapKindLoc(),
12142 C->getEndLoc());
12143}
12144
12145template <typename Derived>
12146OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
12147 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12148 llvm::SmallVector<Expr *, 16> Vars;
12149 Expr *IteratorModifier = C->getIteratorModifier();
12150 if (IteratorModifier) {
12151 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12152 if (MapModRes.isInvalid())
12153 return nullptr;
12154 IteratorModifier = MapModRes.get();
12155 }
12156 CXXScopeSpec MapperIdScopeSpec;
12157 DeclarationNameInfo MapperIdInfo;
12158 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12159 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
12160 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12161 return nullptr;
12162 return getDerived().RebuildOMPToClause(
12163 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12164 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12165 UnresolvedMappers);
12166}
12167
12168template <typename Derived>
12169OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
12170 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12171 llvm::SmallVector<Expr *, 16> Vars;
12172 Expr *IteratorModifier = C->getIteratorModifier();
12173 if (IteratorModifier) {
12174 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12175 if (MapModRes.isInvalid())
12176 return nullptr;
12177 IteratorModifier = MapModRes.get();
12178 }
12179 CXXScopeSpec MapperIdScopeSpec;
12180 DeclarationNameInfo MapperIdInfo;
12181 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12182 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
12183 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12184 return nullptr;
12185 return getDerived().RebuildOMPFromClause(
12186 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12187 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12188 UnresolvedMappers);
12189}
12190
12191template <typename Derived>
12192OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
12193 OMPUseDevicePtrClause *C) {
12194 llvm::SmallVector<Expr *, 16> Vars;
12195 Vars.reserve(N: C->varlist_size());
12196 for (auto *VE : C->varlist()) {
12197 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12198 if (EVar.isInvalid())
12199 return nullptr;
12200 Vars.push_back(Elt: EVar.get());
12201 }
12202 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12203 return getDerived().RebuildOMPUseDevicePtrClause(
12204 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
12205}
12206
12207template <typename Derived>
12208OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
12209 OMPUseDeviceAddrClause *C) {
12210 llvm::SmallVector<Expr *, 16> Vars;
12211 Vars.reserve(N: C->varlist_size());
12212 for (auto *VE : C->varlist()) {
12213 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12214 if (EVar.isInvalid())
12215 return nullptr;
12216 Vars.push_back(Elt: EVar.get());
12217 }
12218 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12219 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
12220}
12221
12222template <typename Derived>
12223OMPClause *
12224TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
12225 llvm::SmallVector<Expr *, 16> Vars;
12226 Vars.reserve(N: C->varlist_size());
12227 for (auto *VE : C->varlist()) {
12228 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12229 if (EVar.isInvalid())
12230 return nullptr;
12231 Vars.push_back(Elt: EVar.get());
12232 }
12233 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12234 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
12235}
12236
12237template <typename Derived>
12238OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
12239 OMPHasDeviceAddrClause *C) {
12240 llvm::SmallVector<Expr *, 16> Vars;
12241 Vars.reserve(N: C->varlist_size());
12242 for (auto *VE : C->varlist()) {
12243 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12244 if (EVar.isInvalid())
12245 return nullptr;
12246 Vars.push_back(Elt: EVar.get());
12247 }
12248 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12249 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
12250}
12251
12252template <typename Derived>
12253OMPClause *
12254TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
12255 llvm::SmallVector<Expr *, 16> Vars;
12256 Vars.reserve(N: C->varlist_size());
12257 for (auto *VE : C->varlist()) {
12258 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12259 if (EVar.isInvalid())
12260 return nullptr;
12261 Vars.push_back(Elt: EVar.get());
12262 }
12263 return getDerived().RebuildOMPNontemporalClause(
12264 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12265}
12266
12267template <typename Derived>
12268OMPClause *
12269TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
12270 llvm::SmallVector<Expr *, 16> Vars;
12271 Vars.reserve(N: C->varlist_size());
12272 for (auto *VE : C->varlist()) {
12273 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12274 if (EVar.isInvalid())
12275 return nullptr;
12276 Vars.push_back(Elt: EVar.get());
12277 }
12278 return getDerived().RebuildOMPInclusiveClause(
12279 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12280}
12281
12282template <typename Derived>
12283OMPClause *
12284TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
12285 llvm::SmallVector<Expr *, 16> Vars;
12286 Vars.reserve(N: C->varlist_size());
12287 for (auto *VE : C->varlist()) {
12288 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12289 if (EVar.isInvalid())
12290 return nullptr;
12291 Vars.push_back(Elt: EVar.get());
12292 }
12293 return getDerived().RebuildOMPExclusiveClause(
12294 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12295}
12296
12297template <typename Derived>
12298OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
12299 OMPUsesAllocatorsClause *C) {
12300 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
12301 Data.reserve(N: C->getNumberOfAllocators());
12302 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
12303 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
12304 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
12305 if (Allocator.isInvalid())
12306 continue;
12307 ExprResult AllocatorTraits;
12308 if (Expr *AT = D.AllocatorTraits) {
12309 AllocatorTraits = getDerived().TransformExpr(AT);
12310 if (AllocatorTraits.isInvalid())
12311 continue;
12312 }
12313 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
12314 NewD.Allocator = Allocator.get();
12315 NewD.AllocatorTraits = AllocatorTraits.get();
12316 NewD.LParenLoc = D.LParenLoc;
12317 NewD.RParenLoc = D.RParenLoc;
12318 }
12319 return getDerived().RebuildOMPUsesAllocatorsClause(
12320 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12321}
12322
12323template <typename Derived>
12324OMPClause *
12325TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
12326 SmallVector<Expr *, 4> Locators;
12327 Locators.reserve(N: C->varlist_size());
12328 ExprResult ModifierRes;
12329 if (Expr *Modifier = C->getModifier()) {
12330 ModifierRes = getDerived().TransformExpr(Modifier);
12331 if (ModifierRes.isInvalid())
12332 return nullptr;
12333 }
12334 for (Expr *E : C->varlist()) {
12335 ExprResult Locator = getDerived().TransformExpr(E);
12336 if (Locator.isInvalid())
12337 continue;
12338 Locators.push_back(Elt: Locator.get());
12339 }
12340 return getDerived().RebuildOMPAffinityClause(
12341 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
12342 ModifierRes.get(), Locators);
12343}
12344
12345template <typename Derived>
12346OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
12347 return getDerived().RebuildOMPOrderClause(
12348 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
12349 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
12350}
12351
12352template <typename Derived>
12353OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
12354 return getDerived().RebuildOMPBindClause(
12355 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
12356 C->getLParenLoc(), C->getEndLoc());
12357}
12358
12359template <typename Derived>
12360OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
12361 OMPXDynCGroupMemClause *C) {
12362 ExprResult Size = getDerived().TransformExpr(C->getSize());
12363 if (Size.isInvalid())
12364 return nullptr;
12365 return getDerived().RebuildOMPXDynCGroupMemClause(
12366 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12367}
12368
12369template <typename Derived>
12370OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
12371 OMPDynGroupprivateClause *C) {
12372 ExprResult Size = getDerived().TransformExpr(C->getSize());
12373 if (Size.isInvalid())
12374 return nullptr;
12375 return getDerived().RebuildOMPDynGroupprivateClause(
12376 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
12377 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
12378 C->getDynGroupprivateModifierLoc(),
12379 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
12380}
12381
12382template <typename Derived>
12383OMPClause *
12384TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
12385 llvm::SmallVector<Expr *, 16> Vars;
12386 Vars.reserve(N: C->varlist_size());
12387 for (auto *VE : C->varlist()) {
12388 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12389 if (EVar.isInvalid())
12390 return nullptr;
12391 Vars.push_back(Elt: EVar.get());
12392 }
12393 return getDerived().RebuildOMPDoacrossClause(
12394 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
12395 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12396}
12397
12398template <typename Derived>
12399OMPClause *
12400TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
12401 SmallVector<const Attr *> NewAttrs;
12402 for (auto *A : C->getAttrs())
12403 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
12404 return getDerived().RebuildOMPXAttributeClause(
12405 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12406}
12407
12408template <typename Derived>
12409OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
12410 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
12411}
12412
12413//===----------------------------------------------------------------------===//
12414// OpenACC transformation
12415//===----------------------------------------------------------------------===//
12416namespace {
12417template <typename Derived>
12418class OpenACCClauseTransform final
12419 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
12420 TreeTransform<Derived> &Self;
12421 ArrayRef<const OpenACCClause *> ExistingClauses;
12422 SemaOpenACC::OpenACCParsedClause &ParsedClause;
12423 OpenACCClause *NewClause = nullptr;
12424
12425 ExprResult VisitVar(Expr *VarRef) {
12426 ExprResult Res = Self.TransformExpr(VarRef);
12427
12428 if (!Res.isUsable())
12429 return Res;
12430
12431 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12432 ParsedClause.getClauseKind(),
12433 Res.get());
12434
12435 return Res;
12436 }
12437
12438 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
12439 llvm::SmallVector<Expr *> InstantiatedVarList;
12440 for (Expr *CurVar : VarList) {
12441 ExprResult VarRef = VisitVar(VarRef: CurVar);
12442
12443 if (VarRef.isUsable())
12444 InstantiatedVarList.push_back(Elt: VarRef.get());
12445 }
12446
12447 return InstantiatedVarList;
12448 }
12449
12450public:
12451 OpenACCClauseTransform(TreeTransform<Derived> &Self,
12452 ArrayRef<const OpenACCClause *> ExistingClauses,
12453 SemaOpenACC::OpenACCParsedClause &PC)
12454 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
12455
12456 OpenACCClause *CreatedClause() const { return NewClause; }
12457
12458#define VISIT_CLAUSE(CLAUSE_NAME) \
12459 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
12460#include "clang/Basic/OpenACCClauses.def"
12461};
12462
12463template <typename Derived>
12464void OpenACCClauseTransform<Derived>::VisitDefaultClause(
12465 const OpenACCDefaultClause &C) {
12466 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
12467
12468 NewClause = OpenACCDefaultClause::Create(
12469 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
12470 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12471 EndLoc: ParsedClause.getEndLoc());
12472}
12473
12474template <typename Derived>
12475void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
12476 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12477 assert(Cond && "If constructed with invalid Condition");
12478 Sema::ConditionResult Res = Self.TransformCondition(
12479 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
12480
12481 if (Res.isInvalid() || !Res.get().second)
12482 return;
12483
12484 ParsedClause.setConditionDetails(Res.get().second);
12485
12486 NewClause = OpenACCIfClause::Create(
12487 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12488 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
12489 EndLoc: ParsedClause.getEndLoc());
12490}
12491
12492template <typename Derived>
12493void OpenACCClauseTransform<Derived>::VisitSelfClause(
12494 const OpenACCSelfClause &C) {
12495
12496 // If this is an 'update' 'self' clause, this is actually a var list instead.
12497 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
12498 llvm::SmallVector<Expr *> InstantiatedVarList;
12499 for (Expr *CurVar : C.getVarList()) {
12500 ExprResult Res = Self.TransformExpr(CurVar);
12501
12502 if (!Res.isUsable())
12503 continue;
12504
12505 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12506 ParsedClause.getClauseKind(),
12507 Res.get());
12508
12509 if (Res.isUsable())
12510 InstantiatedVarList.push_back(Elt: Res.get());
12511 }
12512
12513 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12514 ModKind: OpenACCModifierKind::Invalid);
12515
12516 NewClause = OpenACCSelfClause::Create(
12517 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12518 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12519 ParsedClause.getEndLoc());
12520 } else {
12521
12522 if (C.hasConditionExpr()) {
12523 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12524 Sema::ConditionResult Res =
12525 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12526 Sema::ConditionKind::Boolean);
12527
12528 if (Res.isInvalid() || !Res.get().second)
12529 return;
12530
12531 ParsedClause.setConditionDetails(Res.get().second);
12532 }
12533
12534 NewClause = OpenACCSelfClause::Create(
12535 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12536 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12537 ParsedClause.getEndLoc());
12538 }
12539}
12540
12541template <typename Derived>
12542void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12543 const OpenACCNumGangsClause &C) {
12544 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12545
12546 for (Expr *CurIntExpr : C.getIntExprs()) {
12547 ExprResult Res = Self.TransformExpr(CurIntExpr);
12548
12549 if (!Res.isUsable())
12550 return;
12551
12552 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12553 C.getClauseKind(),
12554 C.getBeginLoc(), Res.get());
12555 if (!Res.isUsable())
12556 return;
12557
12558 InstantiatedIntExprs.push_back(Elt: Res.get());
12559 }
12560
12561 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12562 NewClause = OpenACCNumGangsClause::Create(
12563 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12564 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12565 EndLoc: ParsedClause.getEndLoc());
12566}
12567
12568template <typename Derived>
12569void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12570 const OpenACCPrivateClause &C) {
12571 llvm::SmallVector<Expr *> InstantiatedVarList;
12572 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12573
12574 for (const auto [RefExpr, InitRecipe] :
12575 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12576 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12577
12578 if (VarRef.isUsable()) {
12579 InstantiatedVarList.push_back(Elt: VarRef.get());
12580
12581 // We only have to create a new one if it is dependent, and Sema won't
12582 // make one of these unless the type is non-dependent.
12583 if (InitRecipe.isSet())
12584 InitRecipes.push_back(Elt: InitRecipe);
12585 else
12586 InitRecipes.push_back(
12587 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12588 }
12589 }
12590 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12591 ModKind: OpenACCModifierKind::Invalid);
12592
12593 NewClause = OpenACCPrivateClause::Create(
12594 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12595 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12596 EndLoc: ParsedClause.getEndLoc());
12597}
12598
12599template <typename Derived>
12600void OpenACCClauseTransform<Derived>::VisitHostClause(
12601 const OpenACCHostClause &C) {
12602 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12603 OpenACCModifierKind::Invalid);
12604
12605 NewClause = OpenACCHostClause::Create(
12606 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12607 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12608 EndLoc: ParsedClause.getEndLoc());
12609}
12610
12611template <typename Derived>
12612void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12613 const OpenACCDeviceClause &C) {
12614 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12615 OpenACCModifierKind::Invalid);
12616
12617 NewClause = OpenACCDeviceClause::Create(
12618 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12619 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12620 EndLoc: ParsedClause.getEndLoc());
12621}
12622
12623template <typename Derived>
12624void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12625 const OpenACCFirstPrivateClause &C) {
12626 llvm::SmallVector<Expr *> InstantiatedVarList;
12627 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12628
12629 for (const auto [RefExpr, InitRecipe] :
12630 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12631 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12632
12633 if (VarRef.isUsable()) {
12634 InstantiatedVarList.push_back(Elt: VarRef.get());
12635
12636 // We only have to create a new one if it is dependent, and Sema won't
12637 // make one of these unless the type is non-dependent.
12638 if (InitRecipe.isSet())
12639 InitRecipes.push_back(Elt: InitRecipe);
12640 else
12641 InitRecipes.push_back(
12642 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12643 VarRef.get()));
12644 }
12645 }
12646 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12647 ModKind: OpenACCModifierKind::Invalid);
12648
12649 NewClause = OpenACCFirstPrivateClause::Create(
12650 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12651 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12652 EndLoc: ParsedClause.getEndLoc());
12653}
12654
12655template <typename Derived>
12656void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12657 const OpenACCNoCreateClause &C) {
12658 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12659 OpenACCModifierKind::Invalid);
12660
12661 NewClause = OpenACCNoCreateClause::Create(
12662 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12663 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12664 EndLoc: ParsedClause.getEndLoc());
12665}
12666
12667template <typename Derived>
12668void OpenACCClauseTransform<Derived>::VisitPresentClause(
12669 const OpenACCPresentClause &C) {
12670 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12671 OpenACCModifierKind::Invalid);
12672
12673 NewClause = OpenACCPresentClause::Create(
12674 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12675 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12676 EndLoc: ParsedClause.getEndLoc());
12677}
12678
12679template <typename Derived>
12680void OpenACCClauseTransform<Derived>::VisitCopyClause(
12681 const OpenACCCopyClause &C) {
12682 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12683 C.getModifierList());
12684
12685 NewClause = OpenACCCopyClause::Create(
12686 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12687 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12688 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12689 EndLoc: ParsedClause.getEndLoc());
12690}
12691
12692template <typename Derived>
12693void OpenACCClauseTransform<Derived>::VisitLinkClause(
12694 const OpenACCLinkClause &C) {
12695 llvm_unreachable("link clause not valid unless a decl transform");
12696}
12697
12698template <typename Derived>
12699void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12700 const OpenACCDeviceResidentClause &C) {
12701 llvm_unreachable("device_resident clause not valid unless a decl transform");
12702}
12703template <typename Derived>
12704void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12705 const OpenACCNoHostClause &C) {
12706 llvm_unreachable("nohost clause not valid unless a decl transform");
12707}
12708template <typename Derived>
12709void OpenACCClauseTransform<Derived>::VisitBindClause(
12710 const OpenACCBindClause &C) {
12711 llvm_unreachable("bind clause not valid unless a decl transform");
12712}
12713
12714template <typename Derived>
12715void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12716 const OpenACCCopyInClause &C) {
12717 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12718 C.getModifierList());
12719
12720 NewClause = OpenACCCopyInClause::Create(
12721 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12722 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12723 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12724 EndLoc: ParsedClause.getEndLoc());
12725}
12726
12727template <typename Derived>
12728void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12729 const OpenACCCopyOutClause &C) {
12730 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12731 C.getModifierList());
12732
12733 NewClause = OpenACCCopyOutClause::Create(
12734 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12735 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12736 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12737 EndLoc: ParsedClause.getEndLoc());
12738}
12739
12740template <typename Derived>
12741void OpenACCClauseTransform<Derived>::VisitCreateClause(
12742 const OpenACCCreateClause &C) {
12743 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12744 C.getModifierList());
12745
12746 NewClause = OpenACCCreateClause::Create(
12747 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12748 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12749 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12750 EndLoc: ParsedClause.getEndLoc());
12751}
12752template <typename Derived>
12753void OpenACCClauseTransform<Derived>::VisitAttachClause(
12754 const OpenACCAttachClause &C) {
12755 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12756
12757 // Ensure each var is a pointer type.
12758 llvm::erase_if(VarList, [&](Expr *E) {
12759 return Self.getSema().OpenACC().CheckVarIsPointerType(
12760 OpenACCClauseKind::Attach, E);
12761 });
12762
12763 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12764 NewClause = OpenACCAttachClause::Create(
12765 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12766 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12767 EndLoc: ParsedClause.getEndLoc());
12768}
12769
12770template <typename Derived>
12771void OpenACCClauseTransform<Derived>::VisitDetachClause(
12772 const OpenACCDetachClause &C) {
12773 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12774
12775 // Ensure each var is a pointer type.
12776 llvm::erase_if(VarList, [&](Expr *E) {
12777 return Self.getSema().OpenACC().CheckVarIsPointerType(
12778 OpenACCClauseKind::Detach, E);
12779 });
12780
12781 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12782 NewClause = OpenACCDetachClause::Create(
12783 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12784 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12785 EndLoc: ParsedClause.getEndLoc());
12786}
12787
12788template <typename Derived>
12789void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12790 const OpenACCDeleteClause &C) {
12791 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12792 OpenACCModifierKind::Invalid);
12793 NewClause = OpenACCDeleteClause::Create(
12794 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12795 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12796 EndLoc: ParsedClause.getEndLoc());
12797}
12798
12799template <typename Derived>
12800void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12801 const OpenACCUseDeviceClause &C) {
12802 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12803 OpenACCModifierKind::Invalid);
12804 NewClause = OpenACCUseDeviceClause::Create(
12805 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12806 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12807 EndLoc: ParsedClause.getEndLoc());
12808}
12809
12810template <typename Derived>
12811void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12812 const OpenACCDevicePtrClause &C) {
12813 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12814
12815 // Ensure each var is a pointer type.
12816 llvm::erase_if(VarList, [&](Expr *E) {
12817 return Self.getSema().OpenACC().CheckVarIsPointerType(
12818 OpenACCClauseKind::DevicePtr, E);
12819 });
12820
12821 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12822 NewClause = OpenACCDevicePtrClause::Create(
12823 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12824 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12825 EndLoc: ParsedClause.getEndLoc());
12826}
12827
12828template <typename Derived>
12829void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12830 const OpenACCNumWorkersClause &C) {
12831 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12832 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12833
12834 ExprResult Res = Self.TransformExpr(IntExpr);
12835 if (!Res.isUsable())
12836 return;
12837
12838 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12839 C.getClauseKind(),
12840 C.getBeginLoc(), Res.get());
12841 if (!Res.isUsable())
12842 return;
12843
12844 ParsedClause.setIntExprDetails(Res.get());
12845 NewClause = OpenACCNumWorkersClause::Create(
12846 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12847 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12848 EndLoc: ParsedClause.getEndLoc());
12849}
12850
12851template <typename Derived>
12852void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12853 const OpenACCDeviceNumClause &C) {
12854 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12855 assert(IntExpr && "device_num clause constructed with invalid int expr");
12856
12857 ExprResult Res = Self.TransformExpr(IntExpr);
12858 if (!Res.isUsable())
12859 return;
12860
12861 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12862 C.getClauseKind(),
12863 C.getBeginLoc(), Res.get());
12864 if (!Res.isUsable())
12865 return;
12866
12867 ParsedClause.setIntExprDetails(Res.get());
12868 NewClause = OpenACCDeviceNumClause::Create(
12869 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12870 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12871 EndLoc: ParsedClause.getEndLoc());
12872}
12873
12874template <typename Derived>
12875void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12876 const OpenACCDefaultAsyncClause &C) {
12877 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12878 assert(IntExpr && "default_async clause constructed with invalid int expr");
12879
12880 ExprResult Res = Self.TransformExpr(IntExpr);
12881 if (!Res.isUsable())
12882 return;
12883
12884 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12885 C.getClauseKind(),
12886 C.getBeginLoc(), Res.get());
12887 if (!Res.isUsable())
12888 return;
12889
12890 ParsedClause.setIntExprDetails(Res.get());
12891 NewClause = OpenACCDefaultAsyncClause::Create(
12892 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12893 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12894 EndLoc: ParsedClause.getEndLoc());
12895}
12896
12897template <typename Derived>
12898void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12899 const OpenACCVectorLengthClause &C) {
12900 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12901 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12902
12903 ExprResult Res = Self.TransformExpr(IntExpr);
12904 if (!Res.isUsable())
12905 return;
12906
12907 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12908 C.getClauseKind(),
12909 C.getBeginLoc(), Res.get());
12910 if (!Res.isUsable())
12911 return;
12912
12913 ParsedClause.setIntExprDetails(Res.get());
12914 NewClause = OpenACCVectorLengthClause::Create(
12915 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12916 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12917 EndLoc: ParsedClause.getEndLoc());
12918}
12919
12920template <typename Derived>
12921void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12922 const OpenACCAsyncClause &C) {
12923 if (C.hasIntExpr()) {
12924 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12925 if (!Res.isUsable())
12926 return;
12927
12928 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12929 C.getClauseKind(),
12930 C.getBeginLoc(), Res.get());
12931 if (!Res.isUsable())
12932 return;
12933 ParsedClause.setIntExprDetails(Res.get());
12934 }
12935
12936 NewClause = OpenACCAsyncClause::Create(
12937 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12938 LParenLoc: ParsedClause.getLParenLoc(),
12939 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12940 : nullptr,
12941 EndLoc: ParsedClause.getEndLoc());
12942}
12943
12944template <typename Derived>
12945void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12946 const OpenACCWorkerClause &C) {
12947 if (C.hasIntExpr()) {
12948 // restrictions on this expression are all "does it exist in certain
12949 // situations" that are not possible to be dependent, so the only check we
12950 // have is that it transforms, and is an int expression.
12951 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12952 if (!Res.isUsable())
12953 return;
12954
12955 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12956 C.getClauseKind(),
12957 C.getBeginLoc(), Res.get());
12958 if (!Res.isUsable())
12959 return;
12960 ParsedClause.setIntExprDetails(Res.get());
12961 }
12962
12963 NewClause = OpenACCWorkerClause::Create(
12964 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12965 LParenLoc: ParsedClause.getLParenLoc(),
12966 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12967 : nullptr,
12968 EndLoc: ParsedClause.getEndLoc());
12969}
12970
12971template <typename Derived>
12972void OpenACCClauseTransform<Derived>::VisitVectorClause(
12973 const OpenACCVectorClause &C) {
12974 if (C.hasIntExpr()) {
12975 // restrictions on this expression are all "does it exist in certain
12976 // situations" that are not possible to be dependent, so the only check we
12977 // have is that it transforms, and is an int expression.
12978 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12979 if (!Res.isUsable())
12980 return;
12981
12982 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12983 C.getClauseKind(),
12984 C.getBeginLoc(), Res.get());
12985 if (!Res.isUsable())
12986 return;
12987 ParsedClause.setIntExprDetails(Res.get());
12988 }
12989
12990 NewClause = OpenACCVectorClause::Create(
12991 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12992 LParenLoc: ParsedClause.getLParenLoc(),
12993 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12994 : nullptr,
12995 EndLoc: ParsedClause.getEndLoc());
12996}
12997
12998template <typename Derived>
12999void OpenACCClauseTransform<Derived>::VisitWaitClause(
13000 const OpenACCWaitClause &C) {
13001 if (C.hasExprs()) {
13002 Expr *DevNumExpr = nullptr;
13003 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
13004
13005 // Instantiate devnum expr if it exists.
13006 if (C.getDevNumExpr()) {
13007 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
13008 if (!Res.isUsable())
13009 return;
13010 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
13011 C.getClauseKind(),
13012 C.getBeginLoc(), Res.get());
13013 if (!Res.isUsable())
13014 return;
13015
13016 DevNumExpr = Res.get();
13017 }
13018
13019 // Instantiate queue ids.
13020 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
13021 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
13022 if (!Res.isUsable())
13023 return;
13024 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
13025 C.getClauseKind(),
13026 C.getBeginLoc(), Res.get());
13027 if (!Res.isUsable())
13028 return;
13029
13030 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
13031 }
13032
13033 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
13034 IntExprs: std::move(InstantiatedQueueIdExprs));
13035 }
13036
13037 NewClause = OpenACCWaitClause::Create(
13038 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13039 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
13040 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
13041 EndLoc: ParsedClause.getEndLoc());
13042}
13043
13044template <typename Derived>
13045void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
13046 const OpenACCDeviceTypeClause &C) {
13047 // Nothing to transform here, just create a new version of 'C'.
13048 NewClause = OpenACCDeviceTypeClause::Create(
13049 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
13050 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
13051 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
13052}
13053
13054template <typename Derived>
13055void OpenACCClauseTransform<Derived>::VisitAutoClause(
13056 const OpenACCAutoClause &C) {
13057 // Nothing to do, so just create a new node.
13058 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
13059 BeginLoc: ParsedClause.getBeginLoc(),
13060 EndLoc: ParsedClause.getEndLoc());
13061}
13062
13063template <typename Derived>
13064void OpenACCClauseTransform<Derived>::VisitIndependentClause(
13065 const OpenACCIndependentClause &C) {
13066 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
13067 BeginLoc: ParsedClause.getBeginLoc(),
13068 EndLoc: ParsedClause.getEndLoc());
13069}
13070
13071template <typename Derived>
13072void OpenACCClauseTransform<Derived>::VisitSeqClause(
13073 const OpenACCSeqClause &C) {
13074 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
13075 BeginLoc: ParsedClause.getBeginLoc(),
13076 EndLoc: ParsedClause.getEndLoc());
13077}
13078template <typename Derived>
13079void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
13080 const OpenACCFinalizeClause &C) {
13081 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
13082 BeginLoc: ParsedClause.getBeginLoc(),
13083 EndLoc: ParsedClause.getEndLoc());
13084}
13085
13086template <typename Derived>
13087void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
13088 const OpenACCIfPresentClause &C) {
13089 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
13090 BeginLoc: ParsedClause.getBeginLoc(),
13091 EndLoc: ParsedClause.getEndLoc());
13092}
13093
13094template <typename Derived>
13095void OpenACCClauseTransform<Derived>::VisitReductionClause(
13096 const OpenACCReductionClause &C) {
13097 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
13098 SmallVector<Expr *> ValidVars;
13099 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
13100
13101 for (const auto [Var, OrigRecipe] :
13102 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
13103 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
13104 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
13105 if (Res.isUsable()) {
13106 ValidVars.push_back(Elt: Res.get());
13107
13108 if (OrigRecipe.isSet())
13109 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
13110 else
13111 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
13112 C.getReductionOp(), Res.get()));
13113 }
13114 }
13115
13116 NewClause = Self.getSema().OpenACC().CheckReductionClause(
13117 ExistingClauses, ParsedClause.getDirectiveKind(),
13118 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13119 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
13120}
13121
13122template <typename Derived>
13123void OpenACCClauseTransform<Derived>::VisitCollapseClause(
13124 const OpenACCCollapseClause &C) {
13125 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
13126 assert(LoopCount && "collapse clause constructed with invalid loop count");
13127
13128 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
13129
13130 if (!NewLoopCount.isUsable())
13131 return;
13132
13133 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
13134 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13135 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
13136
13137 // FIXME: It isn't clear whether this is properly tested here, we should
13138 // probably see if we can come up with a test for this.
13139 if (!NewLoopCount.isUsable())
13140 return;
13141
13142 NewLoopCount =
13143 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
13144
13145 // FIXME: It isn't clear whether this is properly tested here, we should
13146 // probably see if we can come up with a test for this.
13147 if (!NewLoopCount.isUsable())
13148 return;
13149
13150 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
13151 NewClause = OpenACCCollapseClause::Create(
13152 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13153 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
13154 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
13155}
13156
13157template <typename Derived>
13158void OpenACCClauseTransform<Derived>::VisitTileClause(
13159 const OpenACCTileClause &C) {
13160
13161 llvm::SmallVector<Expr *> TransformedExprs;
13162
13163 for (Expr *E : C.getSizeExprs()) {
13164 ExprResult NewSizeExpr = Self.TransformExpr(E);
13165
13166 if (!NewSizeExpr.isUsable())
13167 return;
13168
13169 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
13170 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13171 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
13172
13173 // FIXME: It isn't clear whether this is properly tested here, we should
13174 // probably see if we can come up with a test for this.
13175 if (!NewSizeExpr.isUsable())
13176 return;
13177
13178 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
13179
13180 if (!NewSizeExpr.isUsable())
13181 return;
13182 TransformedExprs.push_back(Elt: NewSizeExpr.get());
13183 }
13184
13185 ParsedClause.setIntExprDetails(TransformedExprs);
13186 NewClause = OpenACCTileClause::Create(
13187 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13188 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
13189 EndLoc: ParsedClause.getEndLoc());
13190}
13191template <typename Derived>
13192void OpenACCClauseTransform<Derived>::VisitGangClause(
13193 const OpenACCGangClause &C) {
13194 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
13195 llvm::SmallVector<Expr *> TransformedIntExprs;
13196
13197 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
13198 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
13199 if (!ER.isUsable())
13200 continue;
13201
13202 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
13203 ParsedClause.getDirectiveKind(),
13204 C.getExpr(I).first, ER.get());
13205 if (!ER.isUsable())
13206 continue;
13207 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
13208 TransformedIntExprs.push_back(Elt: ER.get());
13209 }
13210
13211 NewClause = Self.getSema().OpenACC().CheckGangClause(
13212 ParsedClause.getDirectiveKind(), ExistingClauses,
13213 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13214 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
13215}
13216} // namespace
13217template <typename Derived>
13218OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
13219 ArrayRef<const OpenACCClause *> ExistingClauses,
13220 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
13221
13222 SemaOpenACC::OpenACCParsedClause ParsedClause(
13223 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
13224 ParsedClause.setEndLoc(OldClause->getEndLoc());
13225
13226 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
13227 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
13228
13229 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
13230 ParsedClause};
13231 Transform.Visit(OldClause);
13232
13233 return Transform.CreatedClause();
13234}
13235
13236template <typename Derived>
13237llvm::SmallVector<OpenACCClause *>
13238TreeTransform<Derived>::TransformOpenACCClauseList(
13239 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
13240 llvm::SmallVector<OpenACCClause *> TransformedClauses;
13241 for (const auto *Clause : OldClauses) {
13242 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
13243 TransformedClauses, DirKind, Clause))
13244 TransformedClauses.push_back(Elt: TransformedClause);
13245 }
13246 return TransformedClauses;
13247}
13248
13249template <typename Derived>
13250StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
13251 OpenACCComputeConstruct *C) {
13252 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13253
13254 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13255 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13256 C->clauses());
13257
13258 if (getSema().OpenACC().ActOnStartStmtDirective(
13259 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13260 return StmtError();
13261
13262 // Transform Structured Block.
13263 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13264 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13265 C->clauses(), TransformedClauses);
13266 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13267 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13268 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13269
13270 return getDerived().RebuildOpenACCComputeConstruct(
13271 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13272 C->getEndLoc(), TransformedClauses, StrBlock);
13273}
13274
13275template <typename Derived>
13276StmtResult
13277TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
13278
13279 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13280
13281 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13282 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13283 C->clauses());
13284
13285 if (getSema().OpenACC().ActOnStartStmtDirective(
13286 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13287 return StmtError();
13288
13289 // Transform Loop.
13290 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13291 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13292 C->clauses(), TransformedClauses);
13293 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13294 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13295 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13296
13297 return getDerived().RebuildOpenACCLoopConstruct(
13298 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13299 TransformedClauses, Loop);
13300}
13301
13302template <typename Derived>
13303StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
13304 OpenACCCombinedConstruct *C) {
13305 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13306
13307 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13308 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13309 C->clauses());
13310
13311 if (getSema().OpenACC().ActOnStartStmtDirective(
13312 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13313 return StmtError();
13314
13315 // Transform Loop.
13316 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13317 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13318 C->clauses(), TransformedClauses);
13319 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13320 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13321 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13322
13323 return getDerived().RebuildOpenACCCombinedConstruct(
13324 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13325 C->getEndLoc(), TransformedClauses, Loop);
13326}
13327
13328template <typename Derived>
13329StmtResult
13330TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
13331 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13332
13333 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13334 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13335 C->clauses());
13336 if (getSema().OpenACC().ActOnStartStmtDirective(
13337 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13338 return StmtError();
13339
13340 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13341 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13342 C->clauses(), TransformedClauses);
13343 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13344 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13345 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13346
13347 return getDerived().RebuildOpenACCDataConstruct(
13348 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13349 TransformedClauses, StrBlock);
13350}
13351
13352template <typename Derived>
13353StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
13354 OpenACCEnterDataConstruct *C) {
13355 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13356
13357 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13358 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13359 C->clauses());
13360 if (getSema().OpenACC().ActOnStartStmtDirective(
13361 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13362 return StmtError();
13363
13364 return getDerived().RebuildOpenACCEnterDataConstruct(
13365 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13366 TransformedClauses);
13367}
13368
13369template <typename Derived>
13370StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
13371 OpenACCExitDataConstruct *C) {
13372 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13373
13374 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13375 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13376 C->clauses());
13377 if (getSema().OpenACC().ActOnStartStmtDirective(
13378 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13379 return StmtError();
13380
13381 return getDerived().RebuildOpenACCExitDataConstruct(
13382 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13383 TransformedClauses);
13384}
13385
13386template <typename Derived>
13387StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
13388 OpenACCHostDataConstruct *C) {
13389 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13390
13391 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13392 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13393 C->clauses());
13394 if (getSema().OpenACC().ActOnStartStmtDirective(
13395 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13396 return StmtError();
13397
13398 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13399 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13400 C->clauses(), TransformedClauses);
13401 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13402 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13403 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13404
13405 return getDerived().RebuildOpenACCHostDataConstruct(
13406 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13407 TransformedClauses, StrBlock);
13408}
13409
13410template <typename Derived>
13411StmtResult
13412TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
13413 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13414
13415 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13416 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13417 C->clauses());
13418 if (getSema().OpenACC().ActOnStartStmtDirective(
13419 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13420 return StmtError();
13421
13422 return getDerived().RebuildOpenACCInitConstruct(
13423 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13424 TransformedClauses);
13425}
13426
13427template <typename Derived>
13428StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
13429 OpenACCShutdownConstruct *C) {
13430 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13431
13432 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13433 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13434 C->clauses());
13435 if (getSema().OpenACC().ActOnStartStmtDirective(
13436 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13437 return StmtError();
13438
13439 return getDerived().RebuildOpenACCShutdownConstruct(
13440 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13441 TransformedClauses);
13442}
13443template <typename Derived>
13444StmtResult
13445TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
13446 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13447
13448 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13449 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13450 C->clauses());
13451 if (getSema().OpenACC().ActOnStartStmtDirective(
13452 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13453 return StmtError();
13454
13455 return getDerived().RebuildOpenACCSetConstruct(
13456 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13457 TransformedClauses);
13458}
13459
13460template <typename Derived>
13461StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
13462 OpenACCUpdateConstruct *C) {
13463 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13464
13465 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13466 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13467 C->clauses());
13468 if (getSema().OpenACC().ActOnStartStmtDirective(
13469 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13470 return StmtError();
13471
13472 return getDerived().RebuildOpenACCUpdateConstruct(
13473 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13474 TransformedClauses);
13475}
13476
13477template <typename Derived>
13478StmtResult
13479TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
13480 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13481
13482 ExprResult DevNumExpr;
13483 if (C->hasDevNumExpr()) {
13484 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
13485
13486 if (DevNumExpr.isUsable())
13487 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
13488 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
13489 C->getBeginLoc(), DevNumExpr.get());
13490 }
13491
13492 llvm::SmallVector<Expr *> QueueIdExprs;
13493
13494 for (Expr *QE : C->getQueueIdExprs()) {
13495 assert(QE && "Null queue id expr?");
13496 ExprResult NewEQ = getDerived().TransformExpr(QE);
13497
13498 if (!NewEQ.isUsable())
13499 break;
13500 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
13501 OpenACCClauseKind::Invalid,
13502 C->getBeginLoc(), NewEQ.get());
13503 if (NewEQ.isUsable())
13504 QueueIdExprs.push_back(Elt: NewEQ.get());
13505 }
13506
13507 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13508 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13509 C->clauses());
13510
13511 if (getSema().OpenACC().ActOnStartStmtDirective(
13512 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13513 return StmtError();
13514
13515 return getDerived().RebuildOpenACCWaitConstruct(
13516 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13517 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
13518 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
13519}
13520template <typename Derived>
13521StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
13522 OpenACCCacheConstruct *C) {
13523 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13524
13525 llvm::SmallVector<Expr *> TransformedVarList;
13526 for (Expr *Var : C->getVarList()) {
13527 assert(Var && "Null var listexpr?");
13528
13529 ExprResult NewVar = getDerived().TransformExpr(Var);
13530
13531 if (!NewVar.isUsable())
13532 break;
13533
13534 NewVar = getSema().OpenACC().ActOnVar(
13535 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13536 if (!NewVar.isUsable())
13537 break;
13538
13539 TransformedVarList.push_back(Elt: NewVar.get());
13540 }
13541
13542 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13543 C->getBeginLoc(), {}))
13544 return StmtError();
13545
13546 return getDerived().RebuildOpenACCCacheConstruct(
13547 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13548 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13549 C->getEndLoc());
13550}
13551
13552template <typename Derived>
13553StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13554 OpenACCAtomicConstruct *C) {
13555 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13556
13557 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13558 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13559 C->clauses());
13560
13561 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13562 C->getBeginLoc(), {}))
13563 return StmtError();
13564
13565 // Transform Associated Stmt.
13566 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13567 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13568
13569 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13570 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13571 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13572 AssocStmt);
13573
13574 return getDerived().RebuildOpenACCAtomicConstruct(
13575 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13576 C->getEndLoc(), TransformedClauses, AssocStmt);
13577}
13578
13579template <typename Derived>
13580ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13581 OpenACCAsteriskSizeExpr *E) {
13582 if (getDerived().AlwaysRebuild())
13583 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13584 // Nothing can ever change, so there is never anything to transform.
13585 return E;
13586}
13587
13588//===----------------------------------------------------------------------===//
13589// Expression transformation
13590//===----------------------------------------------------------------------===//
13591template<typename Derived>
13592ExprResult
13593TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13594 return TransformExpr(E: E->getSubExpr());
13595}
13596
13597template <typename Derived>
13598ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13599 SYCLUniqueStableNameExpr *E) {
13600 if (!E->isTypeDependent())
13601 return E;
13602
13603 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13604
13605 if (!NewT)
13606 return ExprError();
13607
13608 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13609 return E;
13610
13611 return getDerived().RebuildSYCLUniqueStableNameExpr(
13612 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13613}
13614
13615template <typename Derived>
13616StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13617 UnresolvedSYCLKernelCallStmt *S) {
13618 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13619 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13620 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13621 return StmtError();
13622
13623 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13624 if (IdExpr.isInvalid())
13625 return StmtError();
13626
13627 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13628 if (Body.isInvalid())
13629 return StmtError();
13630
13631 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13632 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13633 LaunchIdExpr: IdExpr.get());
13634 if (SR.isInvalid())
13635 return StmtError();
13636
13637 return SR;
13638}
13639
13640template <typename Derived>
13641ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13642 // TODO(reflection): Implement its transform
13643
13644 switch (E->getKind()) {
13645 case ReflectionKind::Type: {
13646 TypeSourceInfo *NewT = getDerived().TransformType(
13647 const_cast<TypeSourceInfo *>(E->getTypeSourceInfo()));
13648 if (!NewT)
13649 return ExprError();
13650 return SemaRef.BuildCXXReflectExpr(OperatorLoc: E->getOperatorLoc(), TSI: NewT);
13651 }
13652 case ReflectionKind::Null:
13653 llvm_unreachable("A null reflection should not reach here");
13654 }
13655
13656 assert(false && "unknown or unimplemented reflection entities");
13657 return ExprError();
13658}
13659
13660template<typename Derived>
13661ExprResult
13662TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13663 if (!E->isTypeDependent())
13664 return E;
13665
13666 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13667 E->getIdentKind());
13668}
13669
13670template<typename Derived>
13671ExprResult
13672TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13673 NestedNameSpecifierLoc QualifierLoc;
13674 if (E->getQualifierLoc()) {
13675 QualifierLoc
13676 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13677 if (!QualifierLoc)
13678 return ExprError();
13679 }
13680
13681 ValueDecl *ND
13682 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13683 E->getDecl()));
13684 if (!ND || ND->isInvalidDecl())
13685 return ExprError();
13686
13687 NamedDecl *Found = ND;
13688 if (E->getFoundDecl() != E->getDecl()) {
13689 Found = cast_or_null<NamedDecl>(
13690 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13691 if (!Found)
13692 return ExprError();
13693 }
13694
13695 DeclarationNameInfo NameInfo = E->getNameInfo();
13696 if (NameInfo.getName()) {
13697 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13698 if (!NameInfo.getName())
13699 return ExprError();
13700 }
13701
13702 if (!getDerived().AlwaysRebuild() &&
13703 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13704 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13705 Found == E->getFoundDecl() &&
13706 NameInfo.getName() == E->getDecl()->getDeclName() &&
13707 !E->hasExplicitTemplateArgs()) {
13708
13709 // Mark it referenced in the new context regardless.
13710 // FIXME: this is a bit instantiation-specific.
13711 SemaRef.MarkDeclRefReferenced(E);
13712
13713 return E;
13714 }
13715
13716 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13717 if (E->hasExplicitTemplateArgs()) {
13718 TemplateArgs = &TransArgs;
13719 TransArgs.setLAngleLoc(E->getLAngleLoc());
13720 TransArgs.setRAngleLoc(E->getRAngleLoc());
13721 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13722 E->getNumTemplateArgs(),
13723 TransArgs))
13724 return ExprError();
13725 }
13726
13727 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13728 Found, TemplateArgs);
13729}
13730
13731template<typename Derived>
13732ExprResult
13733TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13734 return E;
13735}
13736
13737template <typename Derived>
13738ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13739 FixedPointLiteral *E) {
13740 return E;
13741}
13742
13743template<typename Derived>
13744ExprResult
13745TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13746 return E;
13747}
13748
13749template<typename Derived>
13750ExprResult
13751TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13752 return E;
13753}
13754
13755template<typename Derived>
13756ExprResult
13757TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13758 return E;
13759}
13760
13761template<typename Derived>
13762ExprResult
13763TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13764 return E;
13765}
13766
13767template<typename Derived>
13768ExprResult
13769TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13770 return getDerived().TransformCallExpr(E);
13771}
13772
13773template<typename Derived>
13774ExprResult
13775TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13776 ExprResult ControllingExpr;
13777 TypeSourceInfo *ControllingType = nullptr;
13778 if (E->isExprPredicate())
13779 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13780 else
13781 ControllingType = getDerived().TransformType(E->getControllingType());
13782
13783 if (ControllingExpr.isInvalid() && !ControllingType)
13784 return ExprError();
13785
13786 SmallVector<Expr *, 4> AssocExprs;
13787 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13788 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13789 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13790 if (TSI) {
13791 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13792 if (!AssocType)
13793 return ExprError();
13794 AssocTypes.push_back(Elt: AssocType);
13795 } else {
13796 AssocTypes.push_back(Elt: nullptr);
13797 }
13798
13799 ExprResult AssocExpr =
13800 getDerived().TransformExpr(Assoc.getAssociationExpr());
13801 if (AssocExpr.isInvalid())
13802 return ExprError();
13803 AssocExprs.push_back(Elt: AssocExpr.get());
13804 }
13805
13806 if (!ControllingType)
13807 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13808 E->getDefaultLoc(),
13809 E->getRParenLoc(),
13810 ControllingExpr.get(),
13811 AssocTypes,
13812 AssocExprs);
13813 return getDerived().RebuildGenericSelectionExpr(
13814 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13815 ControllingType, AssocTypes, AssocExprs);
13816}
13817
13818template<typename Derived>
13819ExprResult
13820TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13821 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13822 if (SubExpr.isInvalid())
13823 return ExprError();
13824
13825 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13826 return E;
13827
13828 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13829 E->getRParen());
13830}
13831
13832/// The operand of a unary address-of operator has special rules: it's
13833/// allowed to refer to a non-static member of a class even if there's no 'this'
13834/// object available.
13835template<typename Derived>
13836ExprResult
13837TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13838 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13839 return getDerived().TransformDependentScopeDeclRefExpr(
13840 DRE, /*IsAddressOfOperand=*/true, nullptr);
13841 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13842 return getDerived().TransformUnresolvedLookupExpr(
13843 ULE, /*IsAddressOfOperand=*/true);
13844 else
13845 return getDerived().TransformExpr(E);
13846}
13847
13848template<typename Derived>
13849ExprResult
13850TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13851 ExprResult SubExpr;
13852 if (E->getOpcode() == UO_AddrOf)
13853 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13854 else
13855 SubExpr = TransformExpr(E: E->getSubExpr());
13856 if (SubExpr.isInvalid())
13857 return ExprError();
13858
13859 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13860 return E;
13861
13862 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13863 E->getOpcode(),
13864 SubExpr.get());
13865}
13866
13867template<typename Derived>
13868ExprResult
13869TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13870 // Transform the type.
13871 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13872 if (!Type)
13873 return ExprError();
13874
13875 // Transform all of the components into a Designation similar to what the
13876 // parser builds.
13877 // FIXME: It would be slightly more efficient in the non-dependent case to
13878 // just map FieldDecls, rather than requiring the rebuilder to look for
13879 // the fields again. However, __builtin_offsetof is rare enough in
13880 // template code that we don't care.
13881 bool ExprChanged = false;
13882 Designation Desig;
13883 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13884 const OffsetOfNode &ON = E->getComponent(Idx: I);
13885 switch (ON.getKind()) {
13886 case OffsetOfNode::Array: {
13887 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13888 ExprResult Index = getDerived().TransformExpr(FromIndex);
13889 if (Index.isInvalid())
13890 return ExprError();
13891
13892 ExprChanged = ExprChanged || Index.get() != FromIndex;
13893 Designator AD =
13894 Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: ON.getBeginLoc());
13895 AD.setRBracketLoc(ON.getEndLoc());
13896 Desig.AddDesignator(D: AD);
13897 break;
13898 }
13899
13900 case OffsetOfNode::Field:
13901 case OffsetOfNode::Identifier: {
13902 const IdentifierInfo *Name = ON.getFieldName();
13903 if (!Name)
13904 continue;
13905 // The leading designator has no '.'; subsequent ones do.
13906 SourceLocation DotLoc =
13907 Desig.empty() ? SourceLocation() : ON.getBeginLoc();
13908 Desig.AddDesignator(
13909 D: Designator::CreateFieldDesignator(FieldName: Name, DotLoc, FieldLoc: ON.getEndLoc()));
13910 break;
13911 }
13912
13913 case OffsetOfNode::Base:
13914 // Will be recomputed during the rebuild.
13915 continue;
13916 }
13917 }
13918
13919 // If nothing changed, retain the existing expression.
13920 if (!getDerived().AlwaysRebuild() &&
13921 Type == E->getTypeSourceInfo() &&
13922 !ExprChanged)
13923 return E;
13924
13925 // Build a new offsetof expression.
13926 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, Desig,
13927 E->getRParenLoc());
13928}
13929
13930template<typename Derived>
13931ExprResult
13932TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13933 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13934 "opaque value expression requires transformation");
13935 return E;
13936}
13937
13938template <typename Derived>
13939ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13940 llvm::SmallVector<Expr *, 8> Children;
13941 bool Changed = false;
13942 for (Expr *C : E->subExpressions()) {
13943 ExprResult NewC = getDerived().TransformExpr(C);
13944 if (NewC.isInvalid())
13945 return ExprError();
13946 Children.push_back(Elt: NewC.get());
13947
13948 Changed |= NewC.get() != C;
13949 }
13950 if (!getDerived().AlwaysRebuild() && !Changed)
13951 return E;
13952 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13953 Children, E->getType());
13954}
13955
13956template<typename Derived>
13957ExprResult
13958TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13959 // Rebuild the syntactic form. The original syntactic form has
13960 // opaque-value expressions in it, so strip those away and rebuild
13961 // the result. This is a really awful way of doing this, but the
13962 // better solution (rebuilding the semantic expressions and
13963 // rebinding OVEs as necessary) doesn't work; we'd need
13964 // TreeTransform to not strip away implicit conversions.
13965 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13966 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13967 if (result.isInvalid()) return ExprError();
13968
13969 // If that gives us a pseudo-object result back, the pseudo-object
13970 // expression must have been an lvalue-to-rvalue conversion which we
13971 // should reapply.
13972 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13973 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13974
13975 return result;
13976}
13977
13978template<typename Derived>
13979ExprResult
13980TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13981 UnaryExprOrTypeTraitExpr *E) {
13982 if (E->isArgumentType()) {
13983 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13984
13985 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13986 if (!NewT)
13987 return ExprError();
13988
13989 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13990 return E;
13991
13992 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13993 E->getKind(),
13994 E->getSourceRange());
13995 }
13996
13997 // C++0x [expr.sizeof]p1:
13998 // The operand is either an expression, which is an unevaluated operand
13999 // [...]
14000 EnterExpressionEvaluationContext Unevaluated(
14001 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
14002 Sema::ReuseLambdaContextDecl);
14003
14004 // Try to recover if we have something like sizeof(T::X) where X is a type.
14005 // Notably, there must be *exactly* one set of parens if X is a type.
14006 TypeSourceInfo *RecoveryTSI = nullptr;
14007 ExprResult SubExpr;
14008 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
14009 if (auto *DRE =
14010 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
14011 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
14012 PE, DRE, false, &RecoveryTSI);
14013 else
14014 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
14015
14016 if (RecoveryTSI) {
14017 return getDerived().RebuildUnaryExprOrTypeTrait(
14018 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
14019 } else if (SubExpr.isInvalid())
14020 return ExprError();
14021
14022 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
14023 return E;
14024
14025 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
14026 E->getOperatorLoc(),
14027 E->getKind(),
14028 E->getSourceRange());
14029}
14030
14031template<typename Derived>
14032ExprResult
14033TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
14034 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14035 if (LHS.isInvalid())
14036 return ExprError();
14037
14038 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14039 if (RHS.isInvalid())
14040 return ExprError();
14041
14042
14043 if (!getDerived().AlwaysRebuild() &&
14044 LHS.get() == E->getLHS() &&
14045 RHS.get() == E->getRHS())
14046 return E;
14047
14048 return getDerived().RebuildArraySubscriptExpr(
14049 LHS.get(),
14050 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
14051}
14052
14053template <typename Derived>
14054ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
14055 MatrixSingleSubscriptExpr *E) {
14056 ExprResult Base = getDerived().TransformExpr(E->getBase());
14057 if (Base.isInvalid())
14058 return ExprError();
14059
14060 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14061 if (RowIdx.isInvalid())
14062 return ExprError();
14063
14064 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14065 RowIdx.get() == E->getRowIdx())
14066 return E;
14067
14068 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
14069 E->getRBracketLoc());
14070}
14071
14072template <typename Derived>
14073ExprResult
14074TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
14075 ExprResult Base = getDerived().TransformExpr(E->getBase());
14076 if (Base.isInvalid())
14077 return ExprError();
14078
14079 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14080 if (RowIdx.isInvalid())
14081 return ExprError();
14082
14083 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
14084 if (ColumnIdx.isInvalid())
14085 return ExprError();
14086
14087 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14088 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
14089 return E;
14090
14091 return getDerived().RebuildMatrixSubscriptExpr(
14092 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
14093}
14094
14095template <typename Derived>
14096ExprResult
14097TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
14098 ExprResult Base = getDerived().TransformExpr(E->getBase());
14099 if (Base.isInvalid())
14100 return ExprError();
14101
14102 ExprResult LowerBound;
14103 if (E->getLowerBound()) {
14104 LowerBound = getDerived().TransformExpr(E->getLowerBound());
14105 if (LowerBound.isInvalid())
14106 return ExprError();
14107 }
14108
14109 ExprResult Length;
14110 if (E->getLength()) {
14111 Length = getDerived().TransformExpr(E->getLength());
14112 if (Length.isInvalid())
14113 return ExprError();
14114 }
14115
14116 ExprResult Stride;
14117 if (E->isOMPArraySection()) {
14118 if (Expr *Str = E->getStride()) {
14119 Stride = getDerived().TransformExpr(Str);
14120 if (Stride.isInvalid())
14121 return ExprError();
14122 }
14123 }
14124
14125 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14126 LowerBound.get() == E->getLowerBound() &&
14127 Length.get() == E->getLength() &&
14128 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
14129 return E;
14130
14131 return getDerived().RebuildArraySectionExpr(
14132 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
14133 LowerBound.get(), E->getColonLocFirst(),
14134 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
14135 Length.get(), Stride.get(), E->getRBracketLoc());
14136}
14137
14138template <typename Derived>
14139ExprResult
14140TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
14141 ExprResult Base = getDerived().TransformExpr(E->getBase());
14142 if (Base.isInvalid())
14143 return ExprError();
14144
14145 SmallVector<Expr *, 4> Dims;
14146 bool ErrorFound = false;
14147 for (Expr *Dim : E->getDimensions()) {
14148 ExprResult DimRes = getDerived().TransformExpr(Dim);
14149 if (DimRes.isInvalid()) {
14150 ErrorFound = true;
14151 continue;
14152 }
14153 Dims.push_back(Elt: DimRes.get());
14154 }
14155
14156 if (ErrorFound)
14157 return ExprError();
14158 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
14159 E->getRParenLoc(), Dims,
14160 E->getBracketsRanges());
14161}
14162
14163template <typename Derived>
14164ExprResult
14165TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
14166 unsigned NumIterators = E->numOfIterators();
14167 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
14168
14169 bool ErrorFound = false;
14170 bool NeedToRebuild = getDerived().AlwaysRebuild();
14171 for (unsigned I = 0; I < NumIterators; ++I) {
14172 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
14173 Data[I].DeclIdent = D->getIdentifier();
14174 Data[I].DeclIdentLoc = D->getLocation();
14175 if (D->getLocation() == D->getBeginLoc()) {
14176 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
14177 "Implicit type must be int.");
14178 } else {
14179 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
14180 QualType DeclTy = getDerived().TransformType(D->getType());
14181 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
14182 }
14183 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
14184 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
14185 ExprResult End = getDerived().TransformExpr(Range.End);
14186 ExprResult Step = getDerived().TransformExpr(Range.Step);
14187 ErrorFound = ErrorFound ||
14188 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
14189 !Data[I].Type.get().isNull())) ||
14190 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
14191 if (ErrorFound)
14192 continue;
14193 Data[I].Range.Begin = Begin.get();
14194 Data[I].Range.End = End.get();
14195 Data[I].Range.Step = Step.get();
14196 Data[I].AssignLoc = E->getAssignLoc(I);
14197 Data[I].ColonLoc = E->getColonLoc(I);
14198 Data[I].SecColonLoc = E->getSecondColonLoc(I);
14199 NeedToRebuild =
14200 NeedToRebuild ||
14201 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
14202 D->getType().getTypePtrOrNull()) ||
14203 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
14204 Range.Step != Data[I].Range.Step;
14205 }
14206 if (ErrorFound)
14207 return ExprError();
14208 if (!NeedToRebuild)
14209 return E;
14210
14211 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
14212 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
14213 if (!Res.isUsable())
14214 return Res;
14215 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
14216 for (unsigned I = 0; I < NumIterators; ++I)
14217 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
14218 IE->getIteratorDecl(I));
14219 return Res;
14220}
14221
14222template<typename Derived>
14223ExprResult
14224TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
14225 // Transform the callee.
14226 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14227 if (Callee.isInvalid())
14228 return ExprError();
14229
14230 // Transform arguments.
14231 bool ArgChanged = false;
14232 SmallVector<Expr*, 8> Args;
14233 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14234 &ArgChanged))
14235 return ExprError();
14236
14237 if (!getDerived().AlwaysRebuild() &&
14238 Callee.get() == E->getCallee() &&
14239 !ArgChanged)
14240 return SemaRef.MaybeBindToTemporary(E);
14241
14242 // FIXME: Wrong source location information for the '('.
14243 SourceLocation FakeLParenLoc
14244 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14245
14246 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14247 if (E->hasStoredFPFeatures()) {
14248 FPOptionsOverride NewOverrides = E->getFPFeatures();
14249 getSema().CurFPFeatures =
14250 NewOverrides.applyOverrides(getSema().getLangOpts());
14251 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14252 }
14253
14254 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14255 Args,
14256 E->getRParenLoc());
14257}
14258
14259template<typename Derived>
14260ExprResult
14261TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
14262 ExprResult Base = getDerived().TransformExpr(E->getBase());
14263 if (Base.isInvalid())
14264 return ExprError();
14265
14266 NestedNameSpecifierLoc QualifierLoc;
14267 if (E->hasQualifier()) {
14268 QualifierLoc
14269 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14270
14271 if (!QualifierLoc)
14272 return ExprError();
14273 }
14274 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14275
14276 ValueDecl *Member
14277 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
14278 E->getMemberDecl()));
14279 if (!Member)
14280 return ExprError();
14281
14282 NamedDecl *FoundDecl = E->getFoundDecl();
14283 if (FoundDecl == E->getMemberDecl()) {
14284 FoundDecl = Member;
14285 } else {
14286 FoundDecl = cast_or_null<NamedDecl>(
14287 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
14288 if (!FoundDecl)
14289 return ExprError();
14290 }
14291
14292 if (!getDerived().AlwaysRebuild() &&
14293 Base.get() == E->getBase() &&
14294 QualifierLoc == E->getQualifierLoc() &&
14295 Member == E->getMemberDecl() &&
14296 FoundDecl == E->getFoundDecl() &&
14297 !E->hasExplicitTemplateArgs()) {
14298
14299 // Skip for member expression of (this->f), rebuilt thisi->f is needed
14300 // for Openmp where the field need to be privatizized in the case.
14301 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
14302 getSema().OpenMP().isOpenMPRebuildMemberExpr(
14303 cast<ValueDecl>(Val: Member)))) {
14304 // Mark it referenced in the new context regardless.
14305 // FIXME: this is a bit instantiation-specific.
14306 SemaRef.MarkMemberReferenced(E);
14307 return E;
14308 }
14309 }
14310
14311 TemplateArgumentListInfo TransArgs;
14312 if (E->hasExplicitTemplateArgs()) {
14313 TransArgs.setLAngleLoc(E->getLAngleLoc());
14314 TransArgs.setRAngleLoc(E->getRAngleLoc());
14315 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14316 E->getNumTemplateArgs(),
14317 TransArgs))
14318 return ExprError();
14319 }
14320
14321 // FIXME: Bogus source location for the operator
14322 SourceLocation FakeOperatorLoc =
14323 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
14324
14325 // FIXME: to do this check properly, we will need to preserve the
14326 // first-qualifier-in-scope here, just in case we had a dependent
14327 // base (and therefore couldn't do the check) and a
14328 // nested-name-qualifier (and therefore could do the lookup).
14329 NamedDecl *FirstQualifierInScope = nullptr;
14330 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
14331 if (MemberNameInfo.getName()) {
14332 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
14333 if (!MemberNameInfo.getName())
14334 return ExprError();
14335 }
14336
14337 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
14338 E->isArrow(),
14339 QualifierLoc,
14340 TemplateKWLoc,
14341 MemberNameInfo,
14342 Member,
14343 FoundDecl,
14344 (E->hasExplicitTemplateArgs()
14345 ? &TransArgs : nullptr),
14346 FirstQualifierInScope);
14347}
14348
14349template<typename Derived>
14350ExprResult
14351TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
14352 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14353 if (LHS.isInvalid())
14354 return ExprError();
14355
14356 ExprResult RHS =
14357 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
14358 if (RHS.isInvalid())
14359 return ExprError();
14360
14361 if (!getDerived().AlwaysRebuild() &&
14362 LHS.get() == E->getLHS() &&
14363 RHS.get() == E->getRHS())
14364 return E;
14365
14366 if (E->isCompoundAssignmentOp())
14367 // FPFeatures has already been established from trailing storage
14368 return getDerived().RebuildBinaryOperator(
14369 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
14370 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14371 FPOptionsOverride NewOverrides(E->getFPFeatures());
14372 getSema().CurFPFeatures =
14373 NewOverrides.applyOverrides(getSema().getLangOpts());
14374 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14375 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
14376 LHS.get(), RHS.get());
14377}
14378
14379template <typename Derived>
14380ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
14381 CXXRewrittenBinaryOperator *E) {
14382 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
14383
14384 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
14385 if (LHS.isInvalid())
14386 return ExprError();
14387
14388 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
14389 if (RHS.isInvalid())
14390 return ExprError();
14391
14392 // Extract the already-resolved callee declarations so that we can restrict
14393 // ourselves to using them as the unqualified lookup results when rebuilding.
14394 UnresolvedSet<2> UnqualLookups;
14395 bool ChangedAnyLookups = false;
14396 Expr *PossibleBinOps[] = {E->getSemanticForm(),
14397 const_cast<Expr *>(Decomp.InnerBinOp)};
14398 for (Expr *PossibleBinOp : PossibleBinOps) {
14399 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
14400 if (!Op)
14401 continue;
14402 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
14403 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
14404 continue;
14405
14406 // Transform the callee in case we built a call to a local extern
14407 // declaration.
14408 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
14409 E->getOperatorLoc(), Callee->getFoundDecl()));
14410 if (!Found)
14411 return ExprError();
14412 if (Found != Callee->getFoundDecl())
14413 ChangedAnyLookups = true;
14414 UnqualLookups.addDecl(D: Found);
14415 }
14416
14417 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
14418 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
14419 // Mark all functions used in the rewrite as referenced. Note that when
14420 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
14421 // function calls, and/or there might be a user-defined conversion sequence
14422 // applied to the operands of the <.
14423 // FIXME: this is a bit instantiation-specific.
14424 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
14425 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
14426 return E;
14427 }
14428
14429 return getDerived().RebuildCXXRewrittenBinaryOperator(
14430 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
14431}
14432
14433template<typename Derived>
14434ExprResult
14435TreeTransform<Derived>::TransformCompoundAssignOperator(
14436 CompoundAssignOperator *E) {
14437 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14438 FPOptionsOverride NewOverrides(E->getFPFeatures());
14439 getSema().CurFPFeatures =
14440 NewOverrides.applyOverrides(getSema().getLangOpts());
14441 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14442 return getDerived().TransformBinaryOperator(E);
14443}
14444
14445template<typename Derived>
14446ExprResult TreeTransform<Derived>::
14447TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
14448 // Just rebuild the common and RHS expressions and see whether we
14449 // get any changes.
14450
14451 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
14452 if (commonExpr.isInvalid())
14453 return ExprError();
14454
14455 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
14456 if (rhs.isInvalid())
14457 return ExprError();
14458
14459 if (!getDerived().AlwaysRebuild() &&
14460 commonExpr.get() == e->getCommon() &&
14461 rhs.get() == e->getFalseExpr())
14462 return e;
14463
14464 return getDerived().RebuildConditionalOperator(commonExpr.get(),
14465 e->getQuestionLoc(),
14466 nullptr,
14467 e->getColonLoc(),
14468 rhs.get());
14469}
14470
14471template<typename Derived>
14472ExprResult
14473TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
14474 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14475 if (Cond.isInvalid())
14476 return ExprError();
14477
14478 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14479 if (LHS.isInvalid())
14480 return ExprError();
14481
14482 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14483 if (RHS.isInvalid())
14484 return ExprError();
14485
14486 if (!getDerived().AlwaysRebuild() &&
14487 Cond.get() == E->getCond() &&
14488 LHS.get() == E->getLHS() &&
14489 RHS.get() == E->getRHS())
14490 return E;
14491
14492 return getDerived().RebuildConditionalOperator(Cond.get(),
14493 E->getQuestionLoc(),
14494 LHS.get(),
14495 E->getColonLoc(),
14496 RHS.get());
14497}
14498
14499template<typename Derived>
14500ExprResult
14501TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
14502 // Implicit casts are eliminated during transformation, since they
14503 // will be recomputed by semantic analysis after transformation.
14504 return getDerived().TransformExpr(E->getSubExprAsWritten());
14505}
14506
14507template<typename Derived>
14508ExprResult
14509TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
14510 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14511 if (!Type)
14512 return ExprError();
14513
14514 ExprResult SubExpr
14515 = getDerived().TransformExpr(E->getSubExprAsWritten());
14516 if (SubExpr.isInvalid())
14517 return ExprError();
14518
14519 if (!getDerived().AlwaysRebuild() &&
14520 Type == E->getTypeInfoAsWritten() &&
14521 SubExpr.get() == E->getSubExpr())
14522 return E;
14523
14524 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
14525 Type,
14526 E->getRParenLoc(),
14527 SubExpr.get());
14528}
14529
14530template<typename Derived>
14531ExprResult
14532TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
14533 TypeSourceInfo *OldT = E->getTypeSourceInfo();
14534 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
14535 if (!NewT)
14536 return ExprError();
14537
14538 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
14539 if (Init.isInvalid())
14540 return ExprError();
14541
14542 if (!getDerived().AlwaysRebuild() &&
14543 OldT == NewT &&
14544 Init.get() == E->getInitializer())
14545 return SemaRef.MaybeBindToTemporary(E);
14546
14547 // Note: the expression type doesn't necessarily match the
14548 // type-as-written, but that's okay, because it should always be
14549 // derivable from the initializer.
14550
14551 return getDerived().RebuildCompoundLiteralExpr(
14552 E->getLParenLoc(), NewT,
14553 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14554}
14555
14556template<typename Derived>
14557ExprResult
14558TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14559 ExprResult Base = getDerived().TransformExpr(E->getBase());
14560 if (Base.isInvalid())
14561 return ExprError();
14562
14563 if (!getDerived().AlwaysRebuild() &&
14564 Base.get() == E->getBase())
14565 return E;
14566
14567 // FIXME: Bad source location
14568 SourceLocation FakeOperatorLoc =
14569 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14570 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14571 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14572 E->getAccessor());
14573}
14574
14575template <typename Derived>
14576ExprResult
14577TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14578 ExprResult Base = getDerived().TransformExpr(E->getBase());
14579 if (Base.isInvalid())
14580 return ExprError();
14581
14582 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14583 return E;
14584
14585 // FIXME: Bad source location
14586 SourceLocation FakeOperatorLoc =
14587 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14588 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14589 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14590 E->getAccessor());
14591}
14592
14593template<typename Derived>
14594ExprResult
14595TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14596 if (InitListExpr *Syntactic = E->getSyntacticForm())
14597 E = Syntactic;
14598
14599 bool InitChanged = false;
14600
14601 EnterExpressionEvaluationContext Context(
14602 getSema(), EnterExpressionEvaluationContext::InitList);
14603
14604 SmallVector<Expr*, 4> Inits;
14605 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14606 Inits, &InitChanged))
14607 return ExprError();
14608
14609 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14610 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14611 // in some cases. We can't reuse it in general, because the syntactic and
14612 // semantic forms are linked, and we can't know that semantic form will
14613 // match even if the syntactic form does.
14614 }
14615
14616 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14617 E->getRBraceLoc(), E->isExplicit());
14618}
14619
14620template<typename Derived>
14621ExprResult
14622TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14623 Designation Desig;
14624
14625 // transform the initializer value
14626 ExprResult Init = getDerived().TransformExpr(E->getInit());
14627 if (Init.isInvalid())
14628 return ExprError();
14629
14630 // transform the designators.
14631 SmallVector<Expr*, 4> ArrayExprs;
14632 bool ExprChanged = false;
14633 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14634 if (D.isFieldDesignator()) {
14635 if (D.getFieldDecl()) {
14636 FieldDecl *Field = cast_or_null<FieldDecl>(
14637 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14638 if (Field != D.getFieldDecl())
14639 // Rebuild the expression when the transformed FieldDecl is
14640 // different to the already assigned FieldDecl.
14641 ExprChanged = true;
14642 if (Field->isAnonymousStructOrUnion())
14643 continue;
14644 } else {
14645 // Ensure that the designator expression is rebuilt when there isn't
14646 // a resolved FieldDecl in the designator as we don't want to assign
14647 // a FieldDecl to a pattern designator that will be instantiated again.
14648 ExprChanged = true;
14649 }
14650 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14651 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14652 continue;
14653 }
14654
14655 if (D.isArrayDesignator()) {
14656 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14657 if (Index.isInvalid())
14658 return ExprError();
14659
14660 Desig.AddDesignator(
14661 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14662
14663 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14664 ArrayExprs.push_back(Elt: Index.get());
14665 continue;
14666 }
14667
14668 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14669 ExprResult Start
14670 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14671 if (Start.isInvalid())
14672 return ExprError();
14673
14674 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14675 if (End.isInvalid())
14676 return ExprError();
14677
14678 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14679 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14680
14681 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14682 End.get() != E->getArrayRangeEnd(D);
14683
14684 ArrayExprs.push_back(Elt: Start.get());
14685 ArrayExprs.push_back(Elt: End.get());
14686 }
14687
14688 if (!getDerived().AlwaysRebuild() &&
14689 Init.get() == E->getInit() &&
14690 !ExprChanged)
14691 return E;
14692
14693 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14694 E->getEqualOrColonLoc(),
14695 E->usesGNUSyntax(), Init.get());
14696}
14697
14698// Seems that if TransformInitListExpr() only works on the syntactic form of an
14699// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14700template<typename Derived>
14701ExprResult
14702TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14703 DesignatedInitUpdateExpr *E) {
14704 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14705 "initializer");
14706 return ExprError();
14707}
14708
14709template<typename Derived>
14710ExprResult
14711TreeTransform<Derived>::TransformNoInitExpr(
14712 NoInitExpr *E) {
14713 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14714 return ExprError();
14715}
14716
14717template<typename Derived>
14718ExprResult
14719TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14720 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14721 return ExprError();
14722}
14723
14724template<typename Derived>
14725ExprResult
14726TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14727 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14728 return ExprError();
14729}
14730
14731template<typename Derived>
14732ExprResult
14733TreeTransform<Derived>::TransformImplicitValueInitExpr(
14734 ImplicitValueInitExpr *E) {
14735 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14736
14737 // FIXME: Will we ever have proper type location here? Will we actually
14738 // need to transform the type?
14739 QualType T = getDerived().TransformType(E->getType());
14740 if (T.isNull())
14741 return ExprError();
14742
14743 if (!getDerived().AlwaysRebuild() &&
14744 T == E->getType())
14745 return E;
14746
14747 return getDerived().RebuildImplicitValueInitExpr(T);
14748}
14749
14750template<typename Derived>
14751ExprResult
14752TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14753 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14754 if (!TInfo)
14755 return ExprError();
14756
14757 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14758 if (SubExpr.isInvalid())
14759 return ExprError();
14760
14761 if (!getDerived().AlwaysRebuild() &&
14762 TInfo == E->getWrittenTypeInfo() &&
14763 SubExpr.get() == E->getSubExpr())
14764 return E;
14765
14766 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14767 TInfo, E->getRParenLoc());
14768}
14769
14770template<typename Derived>
14771ExprResult
14772TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14773 bool ArgumentChanged = false;
14774 SmallVector<Expr*, 4> Inits;
14775 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14776 ArgChanged: &ArgumentChanged))
14777 return ExprError();
14778
14779 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14780 Inits,
14781 E->getRParenLoc());
14782}
14783
14784/// Transform an address-of-label expression.
14785///
14786/// By default, the transformation of an address-of-label expression always
14787/// rebuilds the expression, so that the label identifier can be resolved to
14788/// the corresponding label statement by semantic analysis.
14789template<typename Derived>
14790ExprResult
14791TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14792 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14793 E->getLabel());
14794 if (!LD)
14795 return ExprError();
14796
14797 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14798 cast<LabelDecl>(Val: LD));
14799}
14800
14801template<typename Derived>
14802ExprResult
14803TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14804 SemaRef.ActOnStartStmtExpr();
14805 StmtResult SubStmt
14806 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14807 if (SubStmt.isInvalid()) {
14808 SemaRef.ActOnStmtExprError();
14809 return ExprError();
14810 }
14811
14812 unsigned OldDepth = E->getTemplateDepth();
14813 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14814
14815 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14816 SubStmt.get() == E->getSubStmt()) {
14817 // Calling this an 'error' is unintuitive, but it does the right thing.
14818 SemaRef.ActOnStmtExprError();
14819 return SemaRef.MaybeBindToTemporary(E);
14820 }
14821
14822 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14823 E->getRParenLoc(), NewDepth);
14824}
14825
14826template<typename Derived>
14827ExprResult
14828TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14829 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14830 if (Cond.isInvalid())
14831 return ExprError();
14832
14833 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14834 if (LHS.isInvalid())
14835 return ExprError();
14836
14837 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14838 if (RHS.isInvalid())
14839 return ExprError();
14840
14841 if (!getDerived().AlwaysRebuild() &&
14842 Cond.get() == E->getCond() &&
14843 LHS.get() == E->getLHS() &&
14844 RHS.get() == E->getRHS())
14845 return E;
14846
14847 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14848 Cond.get(), LHS.get(), RHS.get(),
14849 E->getRParenLoc());
14850}
14851
14852template<typename Derived>
14853ExprResult
14854TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14855 return E;
14856}
14857
14858template<typename Derived>
14859ExprResult
14860TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14861 switch (E->getOperator()) {
14862 case OO_New:
14863 case OO_Delete:
14864 case OO_Array_New:
14865 case OO_Array_Delete:
14866 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14867
14868 case OO_Subscript:
14869 case OO_Call: {
14870 // This is a call to an object's operator().
14871 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14872
14873 // Transform the object itself.
14874 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14875 if (Object.isInvalid())
14876 return ExprError();
14877
14878 // FIXME: Poor location information. Also, if the location for the end of
14879 // the token is within a macro expansion, getLocForEndOfToken() will return
14880 // an invalid source location. If that happens and we have an otherwise
14881 // valid end location, use the valid one instead of the invalid one.
14882 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14883 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14884 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14885 FakeLParenLoc = EndLoc;
14886
14887 // Transform the call arguments.
14888 SmallVector<Expr*, 8> Args;
14889 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14890 Args))
14891 return ExprError();
14892
14893 if (E->getOperator() == OO_Subscript)
14894 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14895 Args, E->getEndLoc());
14896
14897 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14898 E->getEndLoc());
14899 }
14900
14901#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14902 case OO_##Name: \
14903 break;
14904
14905#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14906#include "clang/Basic/OperatorKinds.def"
14907
14908 case OO_Conditional:
14909 llvm_unreachable("conditional operator is not actually overloadable");
14910
14911 case OO_None:
14912 case NUM_OVERLOADED_OPERATORS:
14913 llvm_unreachable("not an overloaded operator?");
14914 }
14915
14916 ExprResult First;
14917 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14918 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14919 else
14920 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14921 if (First.isInvalid())
14922 return ExprError();
14923
14924 ExprResult Second;
14925 if (E->getNumArgs() == 2) {
14926 Second =
14927 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14928 if (Second.isInvalid())
14929 return ExprError();
14930 }
14931
14932 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14933 FPOptionsOverride NewOverrides(E->getFPFeatures());
14934 getSema().CurFPFeatures =
14935 NewOverrides.applyOverrides(getSema().getLangOpts());
14936 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14937
14938 Expr *Callee = E->getCallee();
14939 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14940 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14941 Sema::LookupOrdinaryName);
14942 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14943 return ExprError();
14944
14945 return getDerived().RebuildCXXOperatorCallExpr(
14946 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14947 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14948 }
14949
14950 UnresolvedSet<1> Functions;
14951 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14952 Callee = ICE->getSubExprAsWritten();
14953 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14954 ValueDecl *VD = cast_or_null<ValueDecl>(
14955 getDerived().TransformDecl(DR->getLocation(), DR));
14956 if (!VD)
14957 return ExprError();
14958
14959 if (!isa<CXXMethodDecl>(Val: VD))
14960 Functions.addDecl(D: VD);
14961
14962 return getDerived().RebuildCXXOperatorCallExpr(
14963 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14964 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14965}
14966
14967template<typename Derived>
14968ExprResult
14969TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14970 return getDerived().TransformCallExpr(E);
14971}
14972
14973template <typename Derived>
14974ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14975 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14976 getSema().CurContext != E->getParentContext();
14977
14978 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14979 return E;
14980
14981 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14982 E->getBeginLoc(), E->getEndLoc(),
14983 getSema().CurContext);
14984}
14985
14986template <typename Derived>
14987ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14988 return E;
14989}
14990
14991template<typename Derived>
14992ExprResult
14993TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14994 // Transform the callee.
14995 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14996 if (Callee.isInvalid())
14997 return ExprError();
14998
14999 // Transform exec config.
15000 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
15001 if (EC.isInvalid())
15002 return ExprError();
15003
15004 // Transform arguments.
15005 bool ArgChanged = false;
15006 SmallVector<Expr*, 8> Args;
15007 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15008 &ArgChanged))
15009 return ExprError();
15010
15011 if (!getDerived().AlwaysRebuild() &&
15012 Callee.get() == E->getCallee() &&
15013 !ArgChanged)
15014 return SemaRef.MaybeBindToTemporary(E);
15015
15016 // FIXME: Wrong source location information for the '('.
15017 SourceLocation FakeLParenLoc
15018 = ((Expr *)Callee.get())->getSourceRange().getBegin();
15019 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
15020 Args,
15021 E->getRParenLoc(), EC.get());
15022}
15023
15024template<typename Derived>
15025ExprResult
15026TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
15027 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
15028 if (!Type)
15029 return ExprError();
15030
15031 ExprResult SubExpr
15032 = getDerived().TransformExpr(E->getSubExprAsWritten());
15033 if (SubExpr.isInvalid())
15034 return ExprError();
15035
15036 if (!getDerived().AlwaysRebuild() &&
15037 Type == E->getTypeInfoAsWritten() &&
15038 SubExpr.get() == E->getSubExpr())
15039 return E;
15040 return getDerived().RebuildCXXNamedCastExpr(
15041 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
15042 Type, E->getAngleBrackets().getEnd(),
15043 // FIXME. this should be '(' location
15044 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
15045}
15046
15047template<typename Derived>
15048ExprResult
15049TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
15050 TypeSourceInfo *TSI =
15051 getDerived().TransformType(BCE->getTypeInfoAsWritten());
15052 if (!TSI)
15053 return ExprError();
15054
15055 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
15056 if (Sub.isInvalid())
15057 return ExprError();
15058
15059 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
15060 Sub.get(), BCE->getEndLoc());
15061}
15062
15063template<typename Derived>
15064ExprResult
15065TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
15066 return getDerived().TransformCXXNamedCastExpr(E);
15067}
15068
15069template<typename Derived>
15070ExprResult
15071TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
15072 return getDerived().TransformCXXNamedCastExpr(E);
15073}
15074
15075template<typename Derived>
15076ExprResult
15077TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
15078 CXXReinterpretCastExpr *E) {
15079 return getDerived().TransformCXXNamedCastExpr(E);
15080}
15081
15082template<typename Derived>
15083ExprResult
15084TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
15085 return getDerived().TransformCXXNamedCastExpr(E);
15086}
15087
15088template<typename Derived>
15089ExprResult
15090TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
15091 return getDerived().TransformCXXNamedCastExpr(E);
15092}
15093
15094template<typename Derived>
15095ExprResult
15096TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
15097 CXXFunctionalCastExpr *E) {
15098 TypeSourceInfo *Type =
15099 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
15100 if (!Type)
15101 return ExprError();
15102
15103 ExprResult SubExpr
15104 = getDerived().TransformExpr(E->getSubExprAsWritten());
15105 if (SubExpr.isInvalid())
15106 return ExprError();
15107
15108 if (!getDerived().AlwaysRebuild() &&
15109 Type == E->getTypeInfoAsWritten() &&
15110 SubExpr.get() == E->getSubExpr())
15111 return E;
15112
15113 return getDerived().RebuildCXXFunctionalCastExpr(Type,
15114 E->getLParenLoc(),
15115 SubExpr.get(),
15116 E->getRParenLoc(),
15117 E->isListInitialization());
15118}
15119
15120template<typename Derived>
15121ExprResult
15122TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
15123 if (E->isTypeOperand()) {
15124 TypeSourceInfo *TInfo
15125 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15126 if (!TInfo)
15127 return ExprError();
15128
15129 if (!getDerived().AlwaysRebuild() &&
15130 TInfo == E->getTypeOperandSourceInfo())
15131 return E;
15132
15133 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15134 TInfo, E->getEndLoc());
15135 }
15136
15137 // Typeid's operand is an unevaluated context, unless it's a polymorphic
15138 // type. We must not unilaterally enter unevaluated context here, as then
15139 // semantic processing can re-transform an already transformed operand.
15140 Expr *Op = E->getExprOperand();
15141 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
15142 if (E->isGLValue()) {
15143 QualType OpType = Op->getType();
15144 if (auto *RD = OpType->getAsCXXRecordDecl()) {
15145 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
15146 DiagID: diag::err_incomplete_typeid))
15147 return ExprError();
15148
15149 if (RD->isPolymorphic())
15150 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
15151 }
15152 }
15153
15154 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
15155 Sema::ReuseLambdaContextDecl);
15156
15157 ExprResult SubExpr = getDerived().TransformExpr(Op);
15158 if (SubExpr.isInvalid())
15159 return ExprError();
15160
15161 if (!getDerived().AlwaysRebuild() &&
15162 SubExpr.get() == E->getExprOperand())
15163 return E;
15164
15165 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15166 SubExpr.get(), E->getEndLoc());
15167}
15168
15169template<typename Derived>
15170ExprResult
15171TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
15172 if (E->isTypeOperand()) {
15173 TypeSourceInfo *TInfo
15174 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15175 if (!TInfo)
15176 return ExprError();
15177
15178 if (!getDerived().AlwaysRebuild() &&
15179 TInfo == E->getTypeOperandSourceInfo())
15180 return E;
15181
15182 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15183 TInfo, E->getEndLoc());
15184 }
15185
15186 EnterExpressionEvaluationContext Unevaluated(
15187 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15188
15189 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
15190 if (SubExpr.isInvalid())
15191 return ExprError();
15192
15193 if (!getDerived().AlwaysRebuild() &&
15194 SubExpr.get() == E->getExprOperand())
15195 return E;
15196
15197 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15198 SubExpr.get(), E->getEndLoc());
15199}
15200
15201template<typename Derived>
15202ExprResult
15203TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
15204 return E;
15205}
15206
15207template<typename Derived>
15208ExprResult
15209TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
15210 CXXNullPtrLiteralExpr *E) {
15211 return E;
15212}
15213
15214template<typename Derived>
15215ExprResult
15216TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
15217
15218 // In lambdas, the qualifiers of the type depends of where in
15219 // the call operator `this` appear, and we do not have a good way to
15220 // rebuild this information, so we transform the type.
15221 //
15222 // In other contexts, the type of `this` may be overrided
15223 // for type deduction, so we need to recompute it.
15224 //
15225 // Always recompute the type if we're in the body of a lambda, and
15226 // 'this' is dependent on a lambda's explicit object parameter; we
15227 // also need to always rebuild the expression in this case to clear
15228 // the flag.
15229 QualType T = [&]() {
15230 auto &S = getSema();
15231 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
15232 return S.getCurrentThisType();
15233 if (S.getCurLambda())
15234 return getDerived().TransformType(E->getType());
15235 return S.getCurrentThisType();
15236 }();
15237
15238 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
15239 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
15240 // Mark it referenced in the new context regardless.
15241 // FIXME: this is a bit instantiation-specific.
15242 getSema().MarkThisReferenced(E);
15243 return E;
15244 }
15245
15246 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
15247}
15248
15249template<typename Derived>
15250ExprResult
15251TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
15252 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15253 if (SubExpr.isInvalid())
15254 return ExprError();
15255
15256 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
15257
15258 if (!getDerived().AlwaysRebuild() &&
15259 SubExpr.get() == E->getSubExpr())
15260 return E;
15261
15262 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
15263 E->isThrownVariableInScope());
15264}
15265
15266template<typename Derived>
15267ExprResult
15268TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
15269 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
15270 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
15271 if (!Param)
15272 return ExprError();
15273
15274 ExprResult InitRes;
15275 if (E->hasRewrittenInit()) {
15276 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15277 if (InitRes.isInvalid())
15278 return ExprError();
15279 }
15280
15281 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
15282 E->getUsedContext() == SemaRef.CurContext &&
15283 InitRes.get() == E->getRewrittenExpr())
15284 return E;
15285
15286 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
15287 InitRes.get());
15288}
15289
15290template<typename Derived>
15291ExprResult
15292TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
15293 FieldDecl *Field = cast_or_null<FieldDecl>(
15294 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
15295 if (!Field)
15296 return ExprError();
15297
15298 ExprResult InitRes;
15299 if (E->hasRewrittenInit()) {
15300 // The initializer can refer to `this` and to other members, so it has to
15301 // be transformed in the scope of the field's class.
15302 Sema::CXXThisScopeRAII ThisScope(SemaRef, Field->getParent(), Qualifiers());
15303 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15304 if (InitRes.isInvalid())
15305 return ExprError();
15306 }
15307
15308 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
15309 E->getUsedContext() == SemaRef.CurContext &&
15310 InitRes.get() == E->getRewrittenExpr())
15311 return E;
15312
15313 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field,
15314 InitRes.get());
15315}
15316
15317template<typename Derived>
15318ExprResult
15319TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
15320 CXXScalarValueInitExpr *E) {
15321 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
15322 if (!T)
15323 return ExprError();
15324
15325 if (!getDerived().AlwaysRebuild() &&
15326 T == E->getTypeSourceInfo())
15327 return E;
15328
15329 return getDerived().RebuildCXXScalarValueInitExpr(T,
15330 /*FIXME:*/T->getTypeLoc().getEndLoc(),
15331 E->getRParenLoc());
15332}
15333
15334template<typename Derived>
15335ExprResult
15336TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
15337 // Transform the type that we're allocating
15338 TypeSourceInfo *AllocTypeInfo =
15339 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
15340 if (!AllocTypeInfo)
15341 return ExprError();
15342
15343 // Transform the size of the array we're allocating (if any).
15344 std::optional<Expr *> ArraySize;
15345 if (E->isArray()) {
15346 ExprResult NewArraySize;
15347 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
15348 NewArraySize = getDerived().TransformExpr(*OldArraySize);
15349 if (NewArraySize.isInvalid())
15350 return ExprError();
15351 }
15352 ArraySize = NewArraySize.get();
15353 }
15354
15355 // Transform the placement arguments (if any).
15356 bool ArgumentChanged = false;
15357 SmallVector<Expr*, 8> PlacementArgs;
15358 if (getDerived().TransformExprs(E->getPlacementArgs(),
15359 E->getNumPlacementArgs(), true,
15360 PlacementArgs, &ArgumentChanged))
15361 return ExprError();
15362
15363 // Transform the initializer (if any).
15364 Expr *OldInit = E->getInitializer();
15365 ExprResult NewInit;
15366 if (OldInit)
15367 NewInit = getDerived().TransformInitializer(OldInit, true);
15368 if (NewInit.isInvalid())
15369 return ExprError();
15370
15371 // Transform new operator and delete operator.
15372 FunctionDecl *OperatorNew = nullptr;
15373 if (E->getOperatorNew()) {
15374 OperatorNew = cast_or_null<FunctionDecl>(
15375 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
15376 if (!OperatorNew)
15377 return ExprError();
15378 }
15379
15380 FunctionDecl *OperatorDelete = nullptr;
15381 if (E->getOperatorDelete()) {
15382 OperatorDelete = cast_or_null<FunctionDecl>(
15383 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15384 if (!OperatorDelete)
15385 return ExprError();
15386 }
15387
15388 if (!getDerived().AlwaysRebuild() &&
15389 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
15390 ArraySize == E->getArraySize() &&
15391 NewInit.get() == OldInit &&
15392 OperatorNew == E->getOperatorNew() &&
15393 OperatorDelete == E->getOperatorDelete() &&
15394 !ArgumentChanged) {
15395 // Mark any declarations we need as referenced.
15396 // FIXME: instantiation-specific.
15397 if (OperatorNew)
15398 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
15399 if (OperatorDelete)
15400 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15401
15402 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
15403 QualType ElementType
15404 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
15405 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
15406 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
15407 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
15408 }
15409 }
15410
15411 return E;
15412 }
15413
15414 QualType AllocType = AllocTypeInfo->getType();
15415 if (!ArraySize) {
15416 // If no array size was specified, but the new expression was
15417 // instantiated with an array type (e.g., "new T" where T is
15418 // instantiated with "int[4]"), extract the outer bound from the
15419 // array type as our array size. We do this with constant and
15420 // dependently-sized array types.
15421 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
15422 if (!ArrayT) {
15423 // Do nothing
15424 } else if (const ConstantArrayType *ConsArrayT
15425 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
15426 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
15427 type: SemaRef.Context.getSizeType(),
15428 /*FIXME:*/ l: E->getBeginLoc());
15429 AllocType = ConsArrayT->getElementType();
15430 } else if (const DependentSizedArrayType *DepArrayT
15431 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
15432 if (DepArrayT->getSizeExpr()) {
15433 ArraySize = DepArrayT->getSizeExpr();
15434 AllocType = DepArrayT->getElementType();
15435 }
15436 }
15437 }
15438
15439 return getDerived().RebuildCXXNewExpr(
15440 E->getBeginLoc(), E->isGlobalNew(),
15441 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
15442 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
15443 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
15444}
15445
15446template<typename Derived>
15447ExprResult
15448TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
15449 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
15450 if (Operand.isInvalid())
15451 return ExprError();
15452
15453 // Transform the delete operator, if known.
15454 FunctionDecl *OperatorDelete = nullptr;
15455 if (E->getOperatorDelete()) {
15456 OperatorDelete = cast_or_null<FunctionDecl>(
15457 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15458 if (!OperatorDelete)
15459 return ExprError();
15460 }
15461
15462 if (!getDerived().AlwaysRebuild() &&
15463 Operand.get() == E->getArgument() &&
15464 OperatorDelete == E->getOperatorDelete()) {
15465 // Mark any declarations we need as referenced.
15466 // FIXME: instantiation-specific.
15467 if (OperatorDelete)
15468 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15469
15470 if (!E->getArgument()->isTypeDependent()) {
15471 QualType Destroyed = SemaRef.Context.getBaseElementType(
15472 QT: E->getDestroyedType());
15473 if (auto *Record = Destroyed->getAsCXXRecordDecl())
15474 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15475 Func: SemaRef.LookupDestructor(Class: Record));
15476 }
15477
15478 return E;
15479 }
15480
15481 return getDerived().RebuildCXXDeleteExpr(
15482 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
15483}
15484
15485template<typename Derived>
15486ExprResult
15487TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
15488 CXXPseudoDestructorExpr *E) {
15489 ExprResult Base = getDerived().TransformExpr(E->getBase());
15490 if (Base.isInvalid())
15491 return ExprError();
15492
15493 ParsedType ObjectTypePtr;
15494 bool MayBePseudoDestructor = false;
15495 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15496 OpLoc: E->getOperatorLoc(),
15497 OpKind: E->isArrow()? tok::arrow : tok::period,
15498 ObjectType&: ObjectTypePtr,
15499 MayBePseudoDestructor);
15500 if (Base.isInvalid())
15501 return ExprError();
15502
15503 QualType ObjectType = ObjectTypePtr.get();
15504 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
15505 if (QualifierLoc) {
15506 QualifierLoc
15507 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
15508 if (!QualifierLoc)
15509 return ExprError();
15510 }
15511 CXXScopeSpec SS;
15512 SS.Adopt(Other: QualifierLoc);
15513
15514 PseudoDestructorTypeStorage Destroyed;
15515 if (E->getDestroyedTypeInfo()) {
15516 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
15517 E->getDestroyedTypeInfo(), ObjectType,
15518 /*FirstQualifierInScope=*/nullptr);
15519 if (!DestroyedTypeInfo)
15520 return ExprError();
15521 Destroyed = DestroyedTypeInfo;
15522 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
15523 // We aren't likely to be able to resolve the identifier down to a type
15524 // now anyway, so just retain the identifier.
15525 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
15526 E->getDestroyedTypeLoc());
15527 } else {
15528 // Look for a destructor known with the given name.
15529 ParsedType T = SemaRef.getDestructorName(
15530 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
15531 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
15532 if (!T)
15533 return ExprError();
15534
15535 Destroyed
15536 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
15537 Loc: E->getDestroyedTypeLoc());
15538 }
15539
15540 TypeSourceInfo *ScopeTypeInfo = nullptr;
15541 if (E->getScopeTypeInfo()) {
15542 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
15543 E->getScopeTypeInfo(), ObjectType, nullptr);
15544 if (!ScopeTypeInfo)
15545 return ExprError();
15546 }
15547
15548 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
15549 E->getOperatorLoc(),
15550 E->isArrow(),
15551 SS,
15552 ScopeTypeInfo,
15553 E->getColonColonLoc(),
15554 E->getTildeLoc(),
15555 Destroyed);
15556}
15557
15558template <typename Derived>
15559bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
15560 bool RequiresADL,
15561 LookupResult &R) {
15562 // Transform all the decls.
15563 bool AllEmptyPacks = true;
15564 for (auto *OldD : Old->decls()) {
15565 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15566 if (!InstD) {
15567 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15568 // This can happen because of dependent hiding.
15569 if (isa<UsingShadowDecl>(Val: OldD))
15570 continue;
15571 else {
15572 R.clear();
15573 return true;
15574 }
15575 }
15576
15577 // Expand using pack declarations.
15578 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15579 ArrayRef<NamedDecl*> Decls = SingleDecl;
15580 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15581 Decls = UPD->expansions();
15582
15583 // Expand using declarations.
15584 for (auto *D : Decls) {
15585 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15586 for (auto *SD : UD->shadows())
15587 R.addDecl(D: SD);
15588 } else {
15589 R.addDecl(D);
15590 }
15591 }
15592
15593 AllEmptyPacks &= Decls.empty();
15594 }
15595
15596 // C++ [temp.res]/8.4.2:
15597 // The program is ill-formed, no diagnostic required, if [...] lookup for
15598 // a name in the template definition found a using-declaration, but the
15599 // lookup in the corresponding scope in the instantiation odoes not find
15600 // any declarations because the using-declaration was a pack expansion and
15601 // the corresponding pack is empty
15602 if (AllEmptyPacks && !RequiresADL) {
15603 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15604 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15605 return true;
15606 }
15607
15608 // Resolve a kind, but don't do any further analysis. If it's
15609 // ambiguous, the callee needs to deal with it.
15610 R.resolveKind();
15611
15612 if (Old->hasTemplateKeyword() && !R.empty()) {
15613 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15614 getSema().FilterAcceptableTemplateNames(R,
15615 /*AllowFunctionTemplates=*/true,
15616 /*AllowDependent=*/true);
15617 if (R.empty()) {
15618 // If a 'template' keyword was used, a lookup that finds only non-template
15619 // names is an error.
15620 getSema().Diag(R.getNameLoc(),
15621 diag::err_template_kw_refers_to_non_template)
15622 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15623 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15624 getSema().Diag(FoundDecl->getLocation(),
15625 diag::note_template_kw_refers_to_non_template)
15626 << R.getLookupName();
15627 return true;
15628 }
15629 }
15630
15631 return false;
15632}
15633
15634template <typename Derived>
15635ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15636 UnresolvedLookupExpr *Old) {
15637 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15638}
15639
15640template <typename Derived>
15641ExprResult
15642TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15643 bool IsAddressOfOperand) {
15644 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15645 Sema::LookupOrdinaryName);
15646
15647 // Transform the declaration set.
15648 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15649 return ExprError();
15650
15651 // Rebuild the nested-name qualifier, if present.
15652 CXXScopeSpec SS;
15653 if (Old->getQualifierLoc()) {
15654 NestedNameSpecifierLoc QualifierLoc
15655 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15656 if (!QualifierLoc)
15657 return ExprError();
15658
15659 SS.Adopt(Other: QualifierLoc);
15660 }
15661
15662 if (Old->getNamingClass()) {
15663 CXXRecordDecl *NamingClass
15664 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15665 Old->getNameLoc(),
15666 Old->getNamingClass()));
15667 if (!NamingClass) {
15668 R.clear();
15669 return ExprError();
15670 }
15671
15672 R.setNamingClass(NamingClass);
15673 }
15674
15675 // Rebuild the template arguments, if any.
15676 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15677 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15678 if (Old->hasExplicitTemplateArgs() &&
15679 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15680 Old->getNumTemplateArgs(),
15681 TransArgs)) {
15682 R.clear();
15683 return ExprError();
15684 }
15685
15686 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15687 // a non-static data member is named in an unevaluated operand, or when
15688 // a member is named in a dependent class scope function template explicit
15689 // specialization that is neither declared static nor with an explicit object
15690 // parameter.
15691 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15692 return SemaRef.BuildPossibleImplicitMemberExpr(
15693 SS, TemplateKWLoc, R,
15694 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15695 /*S=*/S: nullptr);
15696
15697 // If we have neither explicit template arguments, nor the template keyword,
15698 // it's a normal declaration name or member reference.
15699 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15700 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15701
15702 // If we have template arguments, then rebuild the template-id expression.
15703 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15704 Old->requiresADL(), &TransArgs);
15705}
15706
15707template<typename Derived>
15708ExprResult
15709TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15710 bool ArgChanged = false;
15711 SmallVector<TypeSourceInfo *, 4> Args;
15712 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15713 TypeSourceInfo *From = E->getArg(I);
15714 TypeLoc FromTL = From->getTypeLoc();
15715 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15716 TypeLocBuilder TLB;
15717 TLB.reserve(Requested: FromTL.getFullDataSize());
15718 QualType To = getDerived().TransformType(TLB, FromTL);
15719 if (To.isNull())
15720 return ExprError();
15721
15722 if (To == From->getType())
15723 Args.push_back(Elt: From);
15724 else {
15725 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15726 ArgChanged = true;
15727 }
15728 continue;
15729 }
15730
15731 ArgChanged = true;
15732
15733 // We have a pack expansion. Instantiate it.
15734 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15735 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15736 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15737 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15738
15739 // Determine whether the set of unexpanded parameter packs can and should
15740 // be expanded.
15741 bool Expand = true;
15742 bool RetainExpansion = false;
15743 UnsignedOrNone OrigNumExpansions =
15744 ExpansionTL.getTypePtr()->getNumExpansions();
15745 UnsignedOrNone NumExpansions = OrigNumExpansions;
15746 if (getDerived().TryExpandParameterPacks(
15747 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15748 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15749 RetainExpansion, NumExpansions))
15750 return ExprError();
15751
15752 if (!Expand) {
15753 // The transform has determined that we should perform a simple
15754 // transformation on the pack expansion, producing another pack
15755 // expansion.
15756 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15757
15758 TypeLocBuilder TLB;
15759 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15760
15761 QualType To = getDerived().TransformType(TLB, PatternTL);
15762 if (To.isNull())
15763 return ExprError();
15764
15765 To = getDerived().RebuildPackExpansionType(To,
15766 PatternTL.getSourceRange(),
15767 ExpansionTL.getEllipsisLoc(),
15768 NumExpansions);
15769 if (To.isNull())
15770 return ExprError();
15771
15772 PackExpansionTypeLoc ToExpansionTL
15773 = TLB.push<PackExpansionTypeLoc>(T: To);
15774 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15775 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15776 continue;
15777 }
15778
15779 // Expand the pack expansion by substituting for each argument in the
15780 // pack(s).
15781 for (unsigned I = 0; I != *NumExpansions; ++I) {
15782 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15783 TypeLocBuilder TLB;
15784 TLB.reserve(Requested: PatternTL.getFullDataSize());
15785 QualType To = getDerived().TransformType(TLB, PatternTL);
15786 if (To.isNull())
15787 return ExprError();
15788
15789 if (To->containsUnexpandedParameterPack()) {
15790 To = getDerived().RebuildPackExpansionType(To,
15791 PatternTL.getSourceRange(),
15792 ExpansionTL.getEllipsisLoc(),
15793 NumExpansions);
15794 if (To.isNull())
15795 return ExprError();
15796
15797 PackExpansionTypeLoc ToExpansionTL
15798 = TLB.push<PackExpansionTypeLoc>(T: To);
15799 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15800 }
15801
15802 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15803 }
15804
15805 if (!RetainExpansion)
15806 continue;
15807
15808 // If we're supposed to retain a pack expansion, do so by temporarily
15809 // forgetting the partially-substituted parameter pack.
15810 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15811
15812 TypeLocBuilder TLB;
15813 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15814
15815 QualType To = getDerived().TransformType(TLB, PatternTL);
15816 if (To.isNull())
15817 return ExprError();
15818
15819 To = getDerived().RebuildPackExpansionType(To,
15820 PatternTL.getSourceRange(),
15821 ExpansionTL.getEllipsisLoc(),
15822 NumExpansions);
15823 if (To.isNull())
15824 return ExprError();
15825
15826 PackExpansionTypeLoc ToExpansionTL
15827 = TLB.push<PackExpansionTypeLoc>(T: To);
15828 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15829 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15830 }
15831
15832 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15833 return E;
15834
15835 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15836 E->getEndLoc());
15837}
15838
15839template<typename Derived>
15840ExprResult
15841TreeTransform<Derived>::TransformConceptSpecializationExpr(
15842 ConceptSpecializationExpr *E) {
15843 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15844 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15845 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15846 Old->NumTemplateArgs, TransArgs))
15847 return ExprError();
15848
15849 return getDerived().RebuildConceptSpecializationExpr(
15850 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15851 E->getConceptNameInfo(), E->getFoundDecl(), E->getConceptDecl(),
15852 &TransArgs);
15853}
15854
15855template<typename Derived>
15856ExprResult
15857TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15858 SmallVector<ParmVarDecl*, 4> TransParams;
15859 SmallVector<QualType, 4> TransParamTypes;
15860 Sema::ExtParameterInfoBuilder ExtParamInfos;
15861
15862 // C++2a [expr.prim.req]p2
15863 // Expressions appearing within a requirement-body are unevaluated operands.
15864 EnterExpressionEvaluationContext Ctx(
15865 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15866 Sema::ReuseLambdaContextDecl);
15867
15868 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15869 C&: getSema().Context, DC: getSema().CurContext,
15870 StartLoc: E->getBody()->getBeginLoc());
15871
15872 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15873
15874 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15875 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15876 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15877
15878 for (ParmVarDecl *Param : TransParams)
15879 if (Param)
15880 Param->setDeclContext(Body);
15881
15882 // On failure to transform, TransformRequiresTypeParams returns an expression
15883 // in the event that the transformation of the type params failed in some way.
15884 // It is expected that this will result in a 'not satisfied' Requires clause
15885 // when instantiating.
15886 if (!TypeParamResult.isUnset())
15887 return TypeParamResult;
15888
15889 SmallVector<concepts::Requirement *, 4> TransReqs;
15890 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15891 TransReqs))
15892 return ExprError();
15893
15894 for (concepts::Requirement *Req : TransReqs) {
15895 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15896 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15897 ER->getReturnTypeRequirement()
15898 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15899 ->setDeclContext(Body);
15900 }
15901 }
15902 }
15903
15904 return getDerived().RebuildRequiresExpr(
15905 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15906 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15907}
15908
15909template<typename Derived>
15910bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15911 ArrayRef<concepts::Requirement *> Reqs,
15912 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15913 for (concepts::Requirement *Req : Reqs) {
15914 concepts::Requirement *TransReq = nullptr;
15915 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15916 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15917 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15918 TransReq = getDerived().TransformExprRequirement(ExprReq);
15919 else
15920 TransReq = getDerived().TransformNestedRequirement(
15921 cast<concepts::NestedRequirement>(Val: Req));
15922 if (!TransReq)
15923 return true;
15924 Transformed.push_back(Elt: TransReq);
15925 }
15926 return false;
15927}
15928
15929template<typename Derived>
15930concepts::TypeRequirement *
15931TreeTransform<Derived>::TransformTypeRequirement(
15932 concepts::TypeRequirement *Req) {
15933 if (Req->isSubstitutionFailure()) {
15934 if (getDerived().AlwaysRebuild())
15935 return getDerived().RebuildTypeRequirement(
15936 Req->getSubstitutionDiagnostic());
15937 return Req;
15938 }
15939 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15940 if (!TransType)
15941 return nullptr;
15942 return getDerived().RebuildTypeRequirement(TransType);
15943}
15944
15945template<typename Derived>
15946concepts::ExprRequirement *
15947TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15948 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15949 if (Req->isExprSubstitutionFailure())
15950 TransExpr = Req->getExprSubstitutionDiagnostic();
15951 else {
15952 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15953 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15954 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15955 if (TransExprRes.isInvalid())
15956 return nullptr;
15957 TransExpr = TransExprRes.get();
15958 }
15959
15960 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15961 const auto &RetReq = Req->getReturnTypeRequirement();
15962 if (RetReq.isEmpty())
15963 TransRetReq.emplace();
15964 else if (RetReq.isSubstitutionFailure())
15965 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15966 else if (RetReq.isTypeConstraint()) {
15967 TemplateParameterList *OrigTPL =
15968 RetReq.getTypeConstraintTemplateParameterList();
15969 TemplateParameterList *TPL =
15970 getDerived().TransformTemplateParameterList(OrigTPL);
15971 if (!TPL)
15972 return nullptr;
15973 TransRetReq.emplace(args&: TPL);
15974 }
15975 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15976 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15977 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15978 Req->getNoexceptLoc(),
15979 std::move(*TransRetReq));
15980 return getDerived().RebuildExprRequirement(
15981 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15982 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15983}
15984
15985template<typename Derived>
15986concepts::NestedRequirement *
15987TreeTransform<Derived>::TransformNestedRequirement(
15988 concepts::NestedRequirement *Req) {
15989 if (Req->hasInvalidConstraint()) {
15990 if (getDerived().AlwaysRebuild())
15991 return getDerived().RebuildNestedRequirement(
15992 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15993 return Req;
15994 }
15995 ExprResult TransConstraint =
15996 getDerived().TransformExpr(Req->getConstraintExpr());
15997 if (TransConstraint.isInvalid())
15998 return nullptr;
15999 return getDerived().RebuildNestedRequirement(TransConstraint.get());
16000}
16001
16002template<typename Derived>
16003ExprResult
16004TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
16005 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
16006 if (!T)
16007 return ExprError();
16008
16009 if (!getDerived().AlwaysRebuild() &&
16010 T == E->getQueriedTypeSourceInfo())
16011 return E;
16012
16013 ExprResult SubExpr;
16014 {
16015 EnterExpressionEvaluationContext Unevaluated(
16016 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16017 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
16018 if (SubExpr.isInvalid())
16019 return ExprError();
16020 }
16021
16022 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
16023 SubExpr.get(), E->getEndLoc());
16024}
16025
16026template<typename Derived>
16027ExprResult
16028TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
16029 ExprResult SubExpr;
16030 {
16031 EnterExpressionEvaluationContext Unevaluated(
16032 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16033 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
16034 if (SubExpr.isInvalid())
16035 return ExprError();
16036
16037 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
16038 return E;
16039 }
16040
16041 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
16042 SubExpr.get(), E->getEndLoc());
16043}
16044
16045template <typename Derived>
16046ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
16047 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
16048 TypeSourceInfo **RecoveryTSI) {
16049 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
16050 DRE, AddrTaken, RecoveryTSI);
16051
16052 // Propagate both errors and recovered types, which return ExprEmpty.
16053 if (!NewDRE.isUsable())
16054 return NewDRE;
16055
16056 // We got an expr, wrap it up in parens.
16057 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
16058 return PE;
16059 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
16060 PE->getRParen());
16061}
16062
16063template <typename Derived>
16064ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16065 DependentScopeDeclRefExpr *E) {
16066 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
16067 nullptr);
16068}
16069
16070template <typename Derived>
16071ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16072 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
16073 TypeSourceInfo **RecoveryTSI) {
16074 assert(E->getQualifierLoc());
16075 NestedNameSpecifierLoc QualifierLoc =
16076 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
16077 if (!QualifierLoc)
16078 return ExprError();
16079 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16080
16081 // TODO: If this is a conversion-function-id, verify that the
16082 // destination type name (if present) resolves the same way after
16083 // instantiation as it did in the local scope.
16084
16085 DeclarationNameInfo NameInfo =
16086 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
16087 if (!NameInfo.getName())
16088 return ExprError();
16089
16090 if (!E->hasExplicitTemplateArgs()) {
16091 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
16092 // Note: it is sufficient to compare the Name component of NameInfo:
16093 // if name has not changed, DNLoc has not changed either.
16094 NameInfo.getName() == E->getDeclName())
16095 return E;
16096
16097 return getDerived().RebuildDependentScopeDeclRefExpr(
16098 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
16099 IsAddressOfOperand, RecoveryTSI);
16100 }
16101
16102 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16103 if (getDerived().TransformTemplateArguments(
16104 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
16105 return ExprError();
16106
16107 return getDerived().RebuildDependentScopeDeclRefExpr(
16108 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
16109 RecoveryTSI);
16110}
16111
16112template<typename Derived>
16113ExprResult
16114TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
16115 // CXXConstructExprs other than for list-initialization and
16116 // CXXTemporaryObjectExpr are always implicit, so when we have
16117 // a 1-argument construction we just transform that argument.
16118 if (getDerived().AllowSkippingCXXConstructExpr() &&
16119 ((E->getNumArgs() == 1 ||
16120 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
16121 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
16122 !E->isListInitialization()))
16123 return getDerived().TransformInitializer(E->getArg(Arg: 0),
16124 /*DirectInit*/ false);
16125
16126 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
16127
16128 QualType T = getDerived().TransformType(E->getType());
16129 if (T.isNull())
16130 return ExprError();
16131
16132 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16133 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16134 if (!Constructor)
16135 return ExprError();
16136
16137 bool ArgumentChanged = false;
16138 SmallVector<Expr*, 8> Args;
16139 {
16140 EnterExpressionEvaluationContext Context(
16141 getSema(), EnterExpressionEvaluationContext::InitList,
16142 E->isListInitialization());
16143 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
16144 &ArgumentChanged))
16145 return ExprError();
16146 }
16147
16148 if (!getDerived().AlwaysRebuild() &&
16149 T == E->getType() &&
16150 Constructor == E->getConstructor() &&
16151 !ArgumentChanged) {
16152 // Mark the constructor as referenced.
16153 // FIXME: Instantiation-specific
16154 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16155 return E;
16156 }
16157
16158 return getDerived().RebuildCXXConstructExpr(
16159 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
16160 E->hadMultipleCandidates(), E->isListInitialization(),
16161 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
16162 E->getConstructionKind(), E->getParenOrBraceRange());
16163}
16164
16165template<typename Derived>
16166ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
16167 CXXInheritedCtorInitExpr *E) {
16168 QualType T = getDerived().TransformType(E->getType());
16169 if (T.isNull())
16170 return ExprError();
16171
16172 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16173 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16174 if (!Constructor)
16175 return ExprError();
16176
16177 if (!getDerived().AlwaysRebuild() &&
16178 T == E->getType() &&
16179 Constructor == E->getConstructor()) {
16180 // Mark the constructor as referenced.
16181 // FIXME: Instantiation-specific
16182 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16183 return E;
16184 }
16185
16186 return getDerived().RebuildCXXInheritedCtorInitExpr(
16187 T, E->getLocation(), Constructor,
16188 E->constructsVBase(), E->inheritedFromVBase());
16189}
16190
16191/// Transform a C++ temporary-binding expression.
16192///
16193/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
16194/// transform the subexpression and return that.
16195template<typename Derived>
16196ExprResult
16197TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
16198 if (auto *Dtor = E->getTemporary()->getDestructor())
16199 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
16200 Func: const_cast<CXXDestructorDecl *>(Dtor));
16201 return getDerived().TransformExpr(E->getSubExpr());
16202}
16203
16204/// Transform a C++ expression that contains cleanups that should
16205/// be run after the expression is evaluated.
16206///
16207/// Since ExprWithCleanups nodes are implicitly generated, we
16208/// just transform the subexpression and return that.
16209template<typename Derived>
16210ExprResult
16211TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
16212 return getDerived().TransformExpr(E->getSubExpr());
16213}
16214
16215template<typename Derived>
16216ExprResult
16217TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
16218 CXXTemporaryObjectExpr *E) {
16219 TypeSourceInfo *T =
16220 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16221 if (!T)
16222 return ExprError();
16223
16224 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16225 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16226 if (!Constructor)
16227 return ExprError();
16228
16229 bool ArgumentChanged = false;
16230 SmallVector<Expr*, 8> Args;
16231 Args.reserve(N: E->getNumArgs());
16232 {
16233 EnterExpressionEvaluationContext Context(
16234 getSema(), EnterExpressionEvaluationContext::InitList,
16235 E->isListInitialization());
16236 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
16237 ArgChanged: &ArgumentChanged))
16238 return ExprError();
16239
16240 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
16241 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc(),
16242 /*IsExplicit=*/IsExplicit: true);
16243 if (Res.isInvalid())
16244 return ExprError();
16245 Args = {Res.get()};
16246 }
16247 }
16248
16249 if (!getDerived().AlwaysRebuild() &&
16250 T == E->getTypeSourceInfo() &&
16251 Constructor == E->getConstructor() &&
16252 !ArgumentChanged) {
16253 // FIXME: Instantiation-specific
16254 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16255 return SemaRef.MaybeBindToTemporary(E);
16256 }
16257
16258 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
16259 return getDerived().RebuildCXXTemporaryObjectExpr(
16260 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
16261}
16262
16263template<typename Derived>
16264ExprResult
16265TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
16266 // Transform any init-capture expressions before entering the scope of the
16267 // lambda body, because they are not semantically within that scope.
16268 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
16269 struct TransformedInitCapture {
16270 // The location of the ... if the result is retaining a pack expansion.
16271 SourceLocation EllipsisLoc;
16272 // Zero or more expansions of the init-capture.
16273 SmallVector<InitCaptureInfoTy, 4> Expansions;
16274 };
16275 SmallVector<TransformedInitCapture, 4> InitCaptures;
16276 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
16277 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16278 CEnd = E->capture_end();
16279 C != CEnd; ++C) {
16280 if (!E->isInitCapture(Capture: C))
16281 continue;
16282
16283 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
16284 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16285
16286 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
16287 UnsignedOrNone NumExpansions) {
16288 ExprResult NewExprInitResult = getDerived().TransformInitializer(
16289 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
16290
16291 if (NewExprInitResult.isInvalid()) {
16292 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
16293 return;
16294 }
16295 Expr *NewExprInit = NewExprInitResult.get();
16296
16297 QualType NewInitCaptureType =
16298 getSema().buildLambdaInitCaptureInitialization(
16299 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
16300 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
16301 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
16302 VarDecl::CInit,
16303 NewExprInit);
16304 Result.Expansions.push_back(
16305 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
16306 };
16307
16308 // If this is an init-capture pack, consider expanding the pack now.
16309 if (OldVD->isParameterPack()) {
16310 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
16311 ->getTypeLoc()
16312 .castAs<PackExpansionTypeLoc>();
16313 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16314 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
16315
16316 // Determine whether the set of unexpanded parameter packs can and should
16317 // be expanded.
16318 bool Expand = true;
16319 bool RetainExpansion = false;
16320 UnsignedOrNone OrigNumExpansions =
16321 ExpansionTL.getTypePtr()->getNumExpansions();
16322 UnsignedOrNone NumExpansions = OrigNumExpansions;
16323 if (getDerived().TryExpandParameterPacks(
16324 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
16325 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
16326 RetainExpansion, NumExpansions))
16327 return ExprError();
16328 assert(!RetainExpansion && "Should not need to retain expansion after a "
16329 "capture since it cannot be extended");
16330 if (Expand) {
16331 for (unsigned I = 0; I != *NumExpansions; ++I) {
16332 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16333 SubstInitCapture(SourceLocation(), std::nullopt);
16334 }
16335 } else {
16336 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
16337 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
16338 }
16339 } else {
16340 SubstInitCapture(SourceLocation(), std::nullopt);
16341 }
16342 }
16343
16344 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
16345 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
16346
16347 // Create the local class that will describe the lambda.
16348
16349 // FIXME: DependencyKind below is wrong when substituting inside a templated
16350 // context that isn't a DeclContext (such as a variable template), or when
16351 // substituting an unevaluated lambda inside of a function's parameter's type
16352 // - as parameter types are not instantiated from within a function's DC. We
16353 // use evaluation contexts to distinguish the function parameter case.
16354 CXXRecordDecl::LambdaDependencyKind DependencyKind =
16355 CXXRecordDecl::LDK_Unknown;
16356 DeclContext *DC = getSema().CurContext;
16357 // A RequiresExprBodyDecl is not interesting for dependencies.
16358 // For the following case,
16359 //
16360 // template <typename>
16361 // concept C = requires { [] {}; };
16362 //
16363 // template <class F>
16364 // struct Widget;
16365 //
16366 // template <C F>
16367 // struct Widget<F> {};
16368 //
16369 // While we are substituting Widget<F>, the parent of DC would be
16370 // the template specialization itself. Thus, the lambda expression
16371 // will be deemed as dependent even if there are no dependent template
16372 // arguments.
16373 // (A ClassTemplateSpecializationDecl is always a dependent context.)
16374 while (DC->isRequiresExprBody() || isa<CXXExpansionStmtDecl>(Val: DC))
16375 DC = DC->getParent();
16376 if ((getSema().isUnevaluatedContext() ||
16377 getSema().isConstantEvaluatedContext()) &&
16378 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
16379 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
16380 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
16381 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
16382
16383 CXXRecordDecl *OldClass = E->getLambdaClass();
16384 CXXRecordDecl *Class = getSema().createLambdaClosureType(
16385 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
16386 E->getCaptureDefault());
16387 getDerived().transformedLocalDecl(OldClass, {Class});
16388
16389 CXXMethodDecl *NewCallOperator =
16390 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
16391
16392 // Enter the scope of the lambda.
16393 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
16394 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
16395 E->hasExplicitParameters(), E->isMutable());
16396
16397 // Introduce the context of the call operator.
16398 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
16399 /*NewThisContext*/false);
16400
16401 bool Invalid = false;
16402
16403 // Transform captures.
16404 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16405 CEnd = E->capture_end();
16406 C != CEnd; ++C) {
16407 // When we hit the first implicit capture, tell Sema that we've finished
16408 // the list of explicit captures.
16409 if (C->isImplicit())
16410 break;
16411
16412 // Capturing 'this' is trivial.
16413 if (C->capturesThis()) {
16414 // If this is a lambda that is part of a default member initialiser
16415 // and which we're instantiating outside the class that 'this' is
16416 // supposed to refer to, adjust the type of 'this' accordingly.
16417 //
16418 // Otherwise, leave the type of 'this' as-is.
16419 Sema::CXXThisScopeRAII ThisScope(
16420 getSema(),
16421 dyn_cast_if_present<CXXRecordDecl>(
16422 getSema().getFunctionLevelDeclContext()),
16423 Qualifiers());
16424 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16425 /*BuildAndDiagnose*/ true, nullptr,
16426 C->getCaptureKind() == LCK_StarThis);
16427 continue;
16428 }
16429 // Captured expression will be recaptured during captured variables
16430 // rebuilding.
16431 if (C->capturesVLAType())
16432 continue;
16433
16434 // Rebuild init-captures, including the implied field declaration.
16435 if (E->isInitCapture(Capture: C)) {
16436 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
16437
16438 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16439 llvm::SmallVector<Decl*, 4> NewVDs;
16440
16441 for (InitCaptureInfoTy &Info : NewC.Expansions) {
16442 ExprResult Init = Info.first;
16443 QualType InitQualType = Info.second;
16444 if (Init.isInvalid() || InitQualType.isNull()) {
16445 Invalid = true;
16446 break;
16447 }
16448 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
16449 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
16450 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
16451 getSema().CurContext);
16452 if (!NewVD) {
16453 Invalid = true;
16454 break;
16455 }
16456 NewVDs.push_back(Elt: NewVD);
16457 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
16458 // Cases we want to tackle:
16459 // ([C(Pack)] {}, ...)
16460 // But rule out cases e.g.
16461 // [...C = Pack()] {}
16462 if (NewC.EllipsisLoc.isInvalid())
16463 LSI->ContainsUnexpandedParameterPack |=
16464 Init.get()->containsUnexpandedParameterPack();
16465 }
16466
16467 if (Invalid)
16468 break;
16469
16470 getDerived().transformedLocalDecl(OldVD, NewVDs);
16471 continue;
16472 }
16473
16474 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16475
16476 // Determine the capture kind for Sema.
16477 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
16478 : C->getCaptureKind() == LCK_ByCopy
16479 ? TryCaptureKind::ExplicitByVal
16480 : TryCaptureKind::ExplicitByRef;
16481 SourceLocation EllipsisLoc;
16482 if (C->isPackExpansion()) {
16483 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
16484 bool ShouldExpand = false;
16485 bool RetainExpansion = false;
16486 UnsignedOrNone NumExpansions = std::nullopt;
16487 if (getDerived().TryExpandParameterPacks(
16488 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
16489 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16490 RetainExpansion, NumExpansions)) {
16491 Invalid = true;
16492 continue;
16493 }
16494
16495 if (ShouldExpand) {
16496 // The transform has determined that we should perform an expansion;
16497 // transform and capture each of the arguments.
16498 // expansion of the pattern. Do so.
16499 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
16500 for (unsigned I = 0; I != *NumExpansions; ++I) {
16501 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16502 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
16503 getDerived().TransformDecl(C->getLocation(), Pack));
16504 if (!CapturedVar) {
16505 Invalid = true;
16506 continue;
16507 }
16508
16509 // Capture the transformed variable.
16510 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
16511 }
16512
16513 // FIXME: Retain a pack expansion if RetainExpansion is true.
16514
16515 continue;
16516 }
16517
16518 EllipsisLoc = C->getEllipsisLoc();
16519 }
16520
16521 // Transform the captured variable.
16522 auto *CapturedVar = cast_or_null<ValueDecl>(
16523 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16524 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
16525 Invalid = true;
16526 continue;
16527 }
16528
16529 // This is not an init-capture; however it contains an unexpanded pack e.g.
16530 // ([Pack] {}(), ...)
16531 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
16532 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
16533
16534 // Capture the transformed variable.
16535 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
16536 EllipsisLoc);
16537 }
16538 getSema().finishLambdaExplicitCaptures(LSI);
16539
16540 // Transform the template parameters, and add them to the current
16541 // instantiation scope. The null case is handled correctly.
16542 auto TPL = getDerived().TransformTemplateParameterList(
16543 E->getTemplateParameterList());
16544 LSI->GLTemplateParameterList = TPL;
16545 if (TPL) {
16546 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
16547 TPL);
16548 LSI->ContainsUnexpandedParameterPack |=
16549 TPL->containsUnexpandedParameterPack();
16550 }
16551
16552 TypeLocBuilder NewCallOpTLBuilder;
16553 TypeLoc OldCallOpTypeLoc =
16554 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
16555 QualType NewCallOpType =
16556 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
16557 if (NewCallOpType.isNull())
16558 return ExprError();
16559 LSI->ContainsUnexpandedParameterPack |=
16560 NewCallOpType->containsUnexpandedParameterPack();
16561 TypeSourceInfo *NewCallOpTSI =
16562 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16563
16564 // The type may be an AttributedType or some other kind of sugar;
16565 // get the actual underlying FunctionProtoType.
16566 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16567 assert(FPTL && "Not a FunctionProtoType?");
16568
16569 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16570 if (TRC) {
16571 ExprResult E = getDerived().TransformLambdaConstraint(
16572 const_cast<Expr *>(TRC.ConstraintExpr));
16573 if (E.isInvalid())
16574 return E;
16575 TRC.ConstraintExpr = E.get();
16576 }
16577
16578 LSI->BeforeCompoundStatement = false;
16579 getSema().CompleteLambdaCallOperator(
16580 NewCallOperator, E->getCallOperator()->getLocation(),
16581 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16582 E->getCallOperator()->getConstexprKind(),
16583 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16584 E->hasExplicitResultType());
16585
16586 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16587 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16588
16589 {
16590 // Number the lambda for linkage purposes if necessary.
16591 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16592
16593 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16594 if (getDerived().ReplacingOriginal()) {
16595 Numbering = OldClass->getLambdaNumbering();
16596 }
16597
16598 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16599 }
16600
16601 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16602 // evaluation context even if we're not transforming the function body.
16603 getSema().PushExpressionEvaluationContextForFunction(
16604 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16605 E->getCallOperator());
16606
16607 StmtResult Body;
16608 {
16609 Sema::NonSFINAEContext _(getSema());
16610 Sema::CodeSynthesisContext C;
16611 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16612 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16613 getSema().pushCodeSynthesisContext(C);
16614
16615 // Instantiate the body of the lambda expression.
16616 Body = Invalid ? StmtError()
16617 : getDerived().TransformLambdaBody(E, E->getBody());
16618
16619 getSema().popCodeSynthesisContext();
16620 }
16621
16622 // ActOnLambda* will pop the function scope for us.
16623 FuncScopeCleanup.disable();
16624
16625 if (Body.isInvalid()) {
16626 SavedContext.pop();
16627 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16628 /*IsInstantiation=*/true);
16629 return ExprError();
16630 }
16631
16632 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16633 /*IsInstantiation=*/true,
16634 /*RetainFunctionScopeInfo=*/true);
16635 SavedContext.pop();
16636
16637 // Recompute the dependency of the lambda so that we can defer the lambda call
16638 // construction until after we have all the necessary template arguments. For
16639 // example, given
16640 //
16641 // template <class> struct S {
16642 // template <class U>
16643 // using Type = decltype([](U){}(42.0));
16644 // };
16645 // void foo() {
16646 // using T = S<int>::Type<float>;
16647 // ^~~~~~
16648 // }
16649 //
16650 // We would end up here from instantiating S<int> when ensuring its
16651 // completeness. That would transform the lambda call expression regardless of
16652 // the absence of the corresponding argument for U.
16653 //
16654 // Going ahead with unsubstituted type U makes things worse: we would soon
16655 // compare the argument type (which is float) against the parameter U
16656 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16657 // error suggesting unmatched types 'U' and 'float'!
16658 //
16659 // That said, everything will be fine if we defer that semantic checking.
16660 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16661 // dependent. Since the CallExpr's dependency boils down to the lambda's
16662 // dependency in this case, we can harness that by recomputing the dependency
16663 // from the instantiation arguments.
16664 //
16665 // FIXME: Creating the type of a lambda requires us to have a dependency
16666 // value, which happens before its substitution. We update its dependency
16667 // *after* the substitution in case we can't decide the dependency
16668 // so early, e.g. because we want to see if any of the *substituted*
16669 // parameters are dependent.
16670 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16671 Class->setLambdaDependencyKind(DependencyKind);
16672
16673 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16674 Body.get()->getEndLoc(), LSI);
16675}
16676
16677template<typename Derived>
16678StmtResult
16679TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16680 return TransformStmt(S);
16681}
16682
16683template<typename Derived>
16684StmtResult
16685TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16686 // Transform captures.
16687 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16688 CEnd = E->capture_end();
16689 C != CEnd; ++C) {
16690 // When we hit the first implicit capture, tell Sema that we've finished
16691 // the list of explicit captures.
16692 if (!C->isImplicit())
16693 continue;
16694
16695 // Capturing 'this' is trivial.
16696 if (C->capturesThis()) {
16697 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16698 /*BuildAndDiagnose*/ true, nullptr,
16699 C->getCaptureKind() == LCK_StarThis);
16700 continue;
16701 }
16702 // Captured expression will be recaptured during captured variables
16703 // rebuilding.
16704 if (C->capturesVLAType())
16705 continue;
16706
16707 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16708 assert(!E->isInitCapture(C) && "implicit init-capture?");
16709
16710 // Transform the captured variable.
16711 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16712 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16713 if (!CapturedVar || CapturedVar->isInvalidDecl())
16714 return StmtError();
16715
16716 // Capture the transformed variable.
16717 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16718 }
16719
16720 return S;
16721}
16722
16723template<typename Derived>
16724ExprResult
16725TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16726 CXXUnresolvedConstructExpr *E) {
16727 TypeSourceInfo *T =
16728 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16729 if (!T)
16730 return ExprError();
16731
16732 bool ArgumentChanged = false;
16733 SmallVector<Expr*, 8> Args;
16734 Args.reserve(N: E->getNumArgs());
16735 {
16736 EnterExpressionEvaluationContext Context(
16737 getSema(), EnterExpressionEvaluationContext::InitList,
16738 E->isListInitialization());
16739 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16740 &ArgumentChanged))
16741 return ExprError();
16742 }
16743
16744 if (!getDerived().AlwaysRebuild() &&
16745 T == E->getTypeSourceInfo() &&
16746 !ArgumentChanged)
16747 return E;
16748
16749 // FIXME: we're faking the locations of the commas
16750 return getDerived().RebuildCXXUnresolvedConstructExpr(
16751 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16752}
16753
16754template <typename Derived>
16755ExprResult TreeTransform<Derived>::TransformDependentTemplateIdExpr(
16756 DependentTemplateIdExpr *E) {
16757
16758 TemplateName Name = getDerived().TransformConceptTemplateName(
16759 E->getTemplateName(), E->getNameLoc());
16760 if (Name.isNull())
16761 return ExprError();
16762
16763 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16764 if (getDerived().TransformTemplateArguments(
16765 E->template_arguments().data(), E->getNumTemplateArgs(), TransArgs))
16766 return ExprError();
16767
16768 TemplateDecl *TD = Name.getAsTemplateDecl();
16769 if (!TD)
16770 return SemaRef.CheckVarOrConceptTemplateTemplateId(NameInfo: E->getNameInfo(), Template: Name,
16771 TemplateArgs: &TransArgs);
16772
16773 CXXScopeSpec SS;
16774
16775 LookupResult R(SemaRef, E->getNameInfo(), Sema::LookupOrdinaryName);
16776 R.addDecl(D: TD);
16777 R.resolveKind();
16778 return getDerived().RebuildTemplateIdExpr(
16779 SS, /*Template Keyword=*/SourceLocation(), R,
16780 /*RequiresADL=*/false, &TransArgs);
16781}
16782
16783template<typename Derived>
16784ExprResult
16785TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16786 CXXDependentScopeMemberExpr *E) {
16787 // Transform the base of the expression.
16788 ExprResult Base((Expr*) nullptr);
16789 Expr *OldBase;
16790 QualType BaseType;
16791 QualType ObjectType;
16792 if (!E->isImplicitAccess()) {
16793 OldBase = E->getBase();
16794 Base = getDerived().TransformExpr(OldBase);
16795 if (Base.isInvalid())
16796 return ExprError();
16797
16798 // Start the member reference and compute the object's type.
16799 ParsedType ObjectTy;
16800 bool MayBePseudoDestructor = false;
16801 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16802 OpLoc: E->getOperatorLoc(),
16803 OpKind: E->isArrow()? tok::arrow : tok::period,
16804 ObjectType&: ObjectTy,
16805 MayBePseudoDestructor);
16806 if (Base.isInvalid())
16807 return ExprError();
16808
16809 ObjectType = ObjectTy.get();
16810 BaseType = ((Expr*) Base.get())->getType();
16811 } else {
16812 OldBase = nullptr;
16813 BaseType = getDerived().TransformType(E->getBaseType());
16814 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16815 }
16816
16817 // Transform the first part of the nested-name-specifier that qualifies
16818 // the member name.
16819 NamedDecl *FirstQualifierInScope
16820 = getDerived().TransformFirstQualifierInScope(
16821 E->getFirstQualifierFoundInScope(),
16822 E->getQualifierLoc().getBeginLoc());
16823
16824 NestedNameSpecifierLoc QualifierLoc;
16825 if (E->getQualifier()) {
16826 QualifierLoc
16827 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16828 ObjectType,
16829 FirstQualifierInScope);
16830 if (!QualifierLoc)
16831 return ExprError();
16832 }
16833
16834 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16835
16836 // TODO: If this is a conversion-function-id, verify that the
16837 // destination type name (if present) resolves the same way after
16838 // instantiation as it did in the local scope.
16839
16840 DeclarationNameInfo NameInfo
16841 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16842 if (!NameInfo.getName())
16843 return ExprError();
16844
16845 if (!E->hasExplicitTemplateArgs()) {
16846 // This is a reference to a member without an explicitly-specified
16847 // template argument list. Optimize for this common case.
16848 if (!getDerived().AlwaysRebuild() &&
16849 Base.get() == OldBase &&
16850 BaseType == E->getBaseType() &&
16851 QualifierLoc == E->getQualifierLoc() &&
16852 NameInfo.getName() == E->getMember() &&
16853 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16854 return E;
16855
16856 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16857 BaseType,
16858 E->isArrow(),
16859 E->getOperatorLoc(),
16860 QualifierLoc,
16861 TemplateKWLoc,
16862 FirstQualifierInScope,
16863 NameInfo,
16864 /*TemplateArgs*/nullptr);
16865 }
16866
16867 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16868 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16869 E->getNumTemplateArgs(),
16870 TransArgs))
16871 return ExprError();
16872
16873 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16874 BaseType,
16875 E->isArrow(),
16876 E->getOperatorLoc(),
16877 QualifierLoc,
16878 TemplateKWLoc,
16879 FirstQualifierInScope,
16880 NameInfo,
16881 &TransArgs);
16882}
16883
16884template <typename Derived>
16885ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16886 UnresolvedMemberExpr *Old) {
16887 // Transform the base of the expression.
16888 ExprResult Base((Expr *)nullptr);
16889 QualType BaseType;
16890 if (!Old->isImplicitAccess()) {
16891 Base = getDerived().TransformExpr(Old->getBase());
16892 if (Base.isInvalid())
16893 return ExprError();
16894 Base =
16895 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16896 if (Base.isInvalid())
16897 return ExprError();
16898 BaseType = Base.get()->getType();
16899 } else {
16900 BaseType = getDerived().TransformType(Old->getBaseType());
16901 }
16902
16903 NestedNameSpecifierLoc QualifierLoc;
16904 if (Old->getQualifierLoc()) {
16905 QualifierLoc =
16906 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16907 if (!QualifierLoc)
16908 return ExprError();
16909 }
16910
16911 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16912
16913 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16914
16915 // Transform the declaration set.
16916 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16917 return ExprError();
16918
16919 // Determine the naming class.
16920 if (Old->getNamingClass()) {
16921 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16922 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16923 if (!NamingClass)
16924 return ExprError();
16925
16926 R.setNamingClass(NamingClass);
16927 }
16928
16929 TemplateArgumentListInfo TransArgs;
16930 if (Old->hasExplicitTemplateArgs()) {
16931 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16932 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16933 if (getDerived().TransformTemplateArguments(
16934 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16935 return ExprError();
16936 }
16937
16938 // FIXME: to do this check properly, we will need to preserve the
16939 // first-qualifier-in-scope here, just in case we had a dependent
16940 // base (and therefore couldn't do the check) and a
16941 // nested-name-qualifier (and therefore could do the lookup).
16942 NamedDecl *FirstQualifierInScope = nullptr;
16943
16944 return getDerived().RebuildUnresolvedMemberExpr(
16945 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16946 TemplateKWLoc, FirstQualifierInScope, R,
16947 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16948}
16949
16950template<typename Derived>
16951ExprResult
16952TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16953 EnterExpressionEvaluationContext Unevaluated(
16954 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16955 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16956 if (SubExpr.isInvalid())
16957 return ExprError();
16958
16959 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16960 return E;
16961
16962 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16963}
16964
16965template<typename Derived>
16966ExprResult
16967TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16968 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16969 if (Pattern.isInvalid())
16970 return ExprError();
16971
16972 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16973 return E;
16974
16975 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16976 E->getNumExpansions());
16977}
16978
16979template <typename Derived>
16980UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16981 ArrayRef<TemplateArgument> PackArgs) {
16982 UnsignedOrNone Result = 0u;
16983 for (const TemplateArgument &Arg : PackArgs) {
16984 if (!Arg.isPackExpansion()) {
16985 Result = *Result + 1;
16986 continue;
16987 }
16988
16989 TemplateArgumentLoc ArgLoc;
16990 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16991
16992 // Find the pattern of the pack expansion.
16993 SourceLocation Ellipsis;
16994 UnsignedOrNone OrigNumExpansions = std::nullopt;
16995 TemplateArgumentLoc Pattern =
16996 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16997 OrigNumExpansions);
16998
16999 // Substitute under the pack expansion. Do not expand the pack (yet).
17000 TemplateArgumentLoc OutPattern;
17001 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17002 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
17003 /*Uneval*/ true))
17004 return 1u;
17005
17006 // See if we can determine the number of arguments from the result.
17007 UnsignedOrNone NumExpansions =
17008 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
17009 if (!NumExpansions) {
17010 // No: we must be in an alias template expansion, and we're going to
17011 // need to actually expand the packs.
17012 Result = std::nullopt;
17013 break;
17014 }
17015
17016 Result = *Result + *NumExpansions;
17017 }
17018 return Result;
17019}
17020
17021template<typename Derived>
17022ExprResult
17023TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
17024 // If E is not value-dependent, then nothing will change when we transform it.
17025 // Note: This is an instantiation-centric view.
17026 if (!E->isValueDependent())
17027 return E;
17028
17029 EnterExpressionEvaluationContext Unevaluated(
17030 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
17031
17032 ArrayRef<TemplateArgument> PackArgs;
17033 TemplateArgument ArgStorage;
17034
17035 // Find the argument list to transform.
17036 if (E->isPartiallySubstituted()) {
17037 PackArgs = E->getPartialArguments();
17038 } else if (E->isValueDependent()) {
17039 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
17040 bool ShouldExpand = false;
17041 bool RetainExpansion = false;
17042 UnsignedOrNone NumExpansions = std::nullopt;
17043 if (getDerived().TryExpandParameterPacks(
17044 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
17045 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
17046 RetainExpansion, NumExpansions))
17047 return ExprError();
17048
17049 // If we need to expand the pack, build a template argument from it and
17050 // expand that.
17051 if (ShouldExpand) {
17052 auto *Pack = E->getPack();
17053 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
17054 ArgStorage = getSema().Context.getPackExpansionType(
17055 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
17056 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
17057 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
17058 } else {
17059 auto *VD = cast<ValueDecl>(Val: Pack);
17060 ExprResult DRE = getSema().BuildDeclRefExpr(
17061 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
17062 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
17063 E->getPackLoc());
17064 if (DRE.isInvalid())
17065 return ExprError();
17066 ArgStorage = TemplateArgument(
17067 new (getSema().Context)
17068 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
17069 /*IsCanonical=*/false);
17070 }
17071 PackArgs = ArgStorage;
17072 }
17073 }
17074
17075 // If we're not expanding the pack, just transform the decl.
17076 if (!PackArgs.size()) {
17077 auto *Pack = cast_or_null<NamedDecl>(
17078 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
17079 if (!Pack)
17080 return ExprError();
17081 return getDerived().RebuildSizeOfPackExpr(
17082 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
17083 std::nullopt, {});
17084 }
17085
17086 // Try to compute the result without performing a partial substitution.
17087 UnsignedOrNone Result =
17088 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
17089
17090 // Common case: we could determine the number of expansions without
17091 // substituting.
17092 if (Result)
17093 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
17094 E->getPackLoc(),
17095 E->getRParenLoc(), *Result, {});
17096
17097 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
17098 E->getPackLoc());
17099 {
17100 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
17101 typedef TemplateArgumentLocInventIterator<
17102 Derived, const TemplateArgument*> PackLocIterator;
17103 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
17104 PackLocIterator(*this, PackArgs.end()),
17105 TransformedPackArgs, /*Uneval*/true))
17106 return ExprError();
17107 }
17108
17109 // Check whether we managed to fully-expand the pack.
17110 // FIXME: Is it possible for us to do so and not hit the early exit path?
17111 SmallVector<TemplateArgument, 8> Args;
17112 bool PartialSubstitution = false;
17113 for (auto &Loc : TransformedPackArgs.arguments()) {
17114 Args.push_back(Elt: Loc.getArgument());
17115 if (Loc.getArgument().isPackExpansion())
17116 PartialSubstitution = true;
17117 }
17118
17119 if (PartialSubstitution)
17120 return getDerived().RebuildSizeOfPackExpr(
17121 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17122 std::nullopt, Args);
17123
17124 return getDerived().RebuildSizeOfPackExpr(
17125 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17126 /*Length=*/static_cast<unsigned>(Args.size()),
17127 /*PartialArgs=*/{});
17128}
17129
17130template <typename Derived>
17131ExprResult
17132TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
17133 if (!E->isValueDependent())
17134 return E;
17135
17136 // Transform the index
17137 ExprResult IndexExpr;
17138 {
17139 EnterExpressionEvaluationContext ConstantContext(
17140 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
17141 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
17142 if (IndexExpr.isInvalid())
17143 return ExprError();
17144 }
17145
17146 SmallVector<Expr *, 5> ExpandedExprs;
17147 bool FullySubstituted = true;
17148 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
17149 Expr *Pattern = E->getPackIdExpression();
17150 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17151 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
17152 Unexpanded);
17153 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17154
17155 // Determine whether the set of unexpanded parameter packs can and should
17156 // be expanded.
17157 bool ShouldExpand = true;
17158 bool RetainExpansion = false;
17159 UnsignedOrNone OrigNumExpansions = std::nullopt,
17160 NumExpansions = std::nullopt;
17161 if (getDerived().TryExpandParameterPacks(
17162 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17163 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
17164 RetainExpansion, NumExpansions))
17165 return true;
17166 if (!ShouldExpand) {
17167 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17168 ExprResult Pack = getDerived().TransformExpr(Pattern);
17169 if (Pack.isInvalid())
17170 return ExprError();
17171 return getDerived().RebuildPackIndexingExpr(
17172 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
17173 {}, /*FullySubstituted=*/false);
17174 }
17175 for (unsigned I = 0; I != *NumExpansions; ++I) {
17176 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17177 ExprResult Out = getDerived().TransformExpr(Pattern);
17178 if (Out.isInvalid())
17179 return true;
17180 if (Out.get()->containsUnexpandedParameterPack()) {
17181 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17182 OrigNumExpansions);
17183 if (Out.isInvalid())
17184 return true;
17185 FullySubstituted = false;
17186 }
17187 ExpandedExprs.push_back(Elt: Out.get());
17188 }
17189 // If we're supposed to retain a pack expansion, do so by temporarily
17190 // forgetting the partially-substituted parameter pack.
17191 if (RetainExpansion) {
17192 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17193
17194 ExprResult Out = getDerived().TransformExpr(Pattern);
17195 if (Out.isInvalid())
17196 return true;
17197
17198 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17199 OrigNumExpansions);
17200 if (Out.isInvalid())
17201 return true;
17202 FullySubstituted = false;
17203 ExpandedExprs.push_back(Elt: Out.get());
17204 }
17205 } else if (!E->expandsToEmptyPack()) {
17206 if (getDerived().TransformExprs(E->getExpressions().data(),
17207 E->getExpressions().size(), false,
17208 ExpandedExprs))
17209 return ExprError();
17210 }
17211
17212 return getDerived().RebuildPackIndexingExpr(
17213 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
17214 IndexExpr.get(), ExpandedExprs, FullySubstituted);
17215}
17216
17217template <typename Derived>
17218ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
17219 SubstNonTypeTemplateParmPackExpr *E) {
17220 if (!getSema().ArgPackSubstIndex)
17221 // We aren't expanding the parameter pack, so just return ourselves.
17222 return E;
17223
17224 TemplateArgument Pack = E->getArgumentPack();
17225 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
17226 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17227 E->getAssociatedDecl(), E->getParameterPack()->getPosition(),
17228 E->getParameterPack()->getType(), E->getParameterPackLocation(), Arg,
17229 SemaRef.getPackIndex(Pack), E->getFinal());
17230}
17231
17232template <typename Derived>
17233ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
17234 SubstNonTypeTemplateParmExpr *E) {
17235 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
17236
17237 // Insert a constant-evaluated context for the transform.
17238 // Otherwise, when a normalized constraint places the replacement inside
17239 // an unevaluated operand (e.g. decltype), entities it refers to are not
17240 // odr-used, and the constant evaluation performed by CheckTemplateArgument
17241 // below can spuriously fail for otherwise valid replacements,
17242 // e.g. when a call materializes a function parameter of class type whose
17243 // special members were never instantiated.
17244 EnterExpressionEvaluationContext ConstantEvaluated(
17245 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
17246 Sema::ReuseLambdaContextDecl,
17247 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
17248
17249 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
17250 if (Replacement.isInvalid())
17251 return true;
17252
17253 Decl *AssociatedDecl =
17254 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
17255 if (!AssociatedDecl)
17256 return true;
17257
17258 QualType ParamType = TransformType(E->getParameterType());
17259 if (ParamType.isNull())
17260 return true;
17261
17262 if (Replacement.get() == OrigReplacement &&
17263 AssociatedDecl == E->getAssociatedDecl() &&
17264 ParamType == E->getParameterType())
17265 return E;
17266
17267 if (Replacement.get() != OrigReplacement ||
17268 ParamType != E->getParameterType()) {
17269 auto *Param = cast<NonTypeTemplateParmDecl>(Val: std::get<0>(
17270 t: getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex())));
17271 // When transforming the replacement expression previously, all Sema
17272 // specific annotations, such as implicit casts, are discarded. Calling the
17273 // corresponding sema action is necessary to recover those. Otherwise,
17274 // equivalency of the result would be lost.
17275 TemplateArgument SugaredConverted, CanonicalConverted;
17276 Replacement = SemaRef.CheckTemplateArgument(
17277 Param, InstantiatedParamType: ParamType, Arg: Replacement.get(), SugaredConverted,
17278 CanonicalConverted,
17279 /*StrictCheck=*/StrictCheck: false, CTAK: Sema::CTAK_Specified);
17280 if (Replacement.isInvalid())
17281 return true;
17282 } else {
17283 // Otherwise, the same expression would have been produced.
17284 Replacement = E->getReplacement();
17285 }
17286
17287 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17288 AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(),
17289 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
17290 E->getPackIndex(), E->getFinal());
17291}
17292
17293template<typename Derived>
17294ExprResult
17295TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
17296 // Default behavior is to do nothing with this transformation.
17297 return E;
17298}
17299
17300template<typename Derived>
17301ExprResult
17302TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
17303 MaterializeTemporaryExpr *E) {
17304 return getDerived().TransformExpr(E->getSubExpr());
17305}
17306
17307template<typename Derived>
17308ExprResult
17309TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
17310 UnresolvedLookupExpr *Callee = nullptr;
17311 if (Expr *OldCallee = E->getCallee()) {
17312 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
17313 if (CalleeResult.isInvalid())
17314 return ExprError();
17315 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
17316 }
17317
17318 Expr *Pattern = E->getPattern();
17319
17320 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17321 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
17322 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17323
17324 // Determine whether the set of unexpanded parameter packs can and should
17325 // be expanded.
17326 bool Expand = true;
17327 bool RetainExpansion = false;
17328 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
17329 NumExpansions = OrigNumExpansions;
17330 if (getDerived().TryExpandParameterPacks(
17331 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17332 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17333 NumExpansions))
17334 return true;
17335
17336 if (!Expand) {
17337 // Do not expand any packs here, just transform and rebuild a fold
17338 // expression.
17339 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17340
17341 ExprResult LHS =
17342 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
17343 if (LHS.isInvalid())
17344 return true;
17345
17346 ExprResult RHS =
17347 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
17348 if (RHS.isInvalid())
17349 return true;
17350
17351 if (!getDerived().AlwaysRebuild() &&
17352 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
17353 return E;
17354
17355 return getDerived().RebuildCXXFoldExpr(
17356 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
17357 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
17358 }
17359
17360 // Formally a fold expression expands to nested parenthesized expressions.
17361 // Enforce this limit to avoid creating trees so deep we can't safely traverse
17362 // them.
17363 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
17364 SemaRef.Diag(Loc: E->getEllipsisLoc(),
17365 DiagID: clang::diag::err_fold_expression_limit_exceeded)
17366 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
17367 << E->getSourceRange();
17368 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
17369 return ExprError();
17370 }
17371
17372 // The transform has determined that we should perform an elementwise
17373 // expansion of the pattern. Do so.
17374 ExprResult Result = getDerived().TransformExpr(E->getInit());
17375 if (Result.isInvalid())
17376 return true;
17377 bool LeftFold = E->isLeftFold();
17378
17379 // If we're retaining an expansion for a right fold, it is the innermost
17380 // component and takes the init (if any).
17381 if (!LeftFold && RetainExpansion) {
17382 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17383
17384 ExprResult Out = getDerived().TransformExpr(Pattern);
17385 if (Out.isInvalid())
17386 return true;
17387
17388 Result = getDerived().RebuildCXXFoldExpr(
17389 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
17390 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
17391 if (Result.isInvalid())
17392 return true;
17393 }
17394
17395 bool WarnedOnComparison = false;
17396 for (unsigned I = 0; I != *NumExpansions; ++I) {
17397 Sema::ArgPackSubstIndexRAII SubstIndex(
17398 getSema(), LeftFold ? I : *NumExpansions - I - 1);
17399 ExprResult Out = getDerived().TransformExpr(Pattern);
17400 if (Out.isInvalid())
17401 return true;
17402
17403 if (Out.get()->containsUnexpandedParameterPack()) {
17404 // We still have a pack; retain a pack expansion for this slice.
17405 Result = getDerived().RebuildCXXFoldExpr(
17406 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
17407 E->getOperator(), E->getEllipsisLoc(),
17408 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
17409 OrigNumExpansions);
17410 } else if (Result.isUsable()) {
17411 // We've got down to a single element; build a binary operator.
17412 Expr *LHS = LeftFold ? Result.get() : Out.get();
17413 Expr *RHS = LeftFold ? Out.get() : Result.get();
17414 if (Callee) {
17415 UnresolvedSet<16> Functions;
17416 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
17417 Result = getDerived().RebuildCXXOperatorCallExpr(
17418 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
17419 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
17420 Functions, LHS, RHS);
17421 } else {
17422 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
17423 E->getOperator(), LHS, RHS,
17424 /*ForFoldExpresion=*/true);
17425 if (!WarnedOnComparison && Result.isUsable()) {
17426 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
17427 BO && BO->isComparisonOp()) {
17428 WarnedOnComparison = true;
17429 SemaRef.Diag(Loc: BO->getBeginLoc(),
17430 DiagID: diag::warn_comparison_in_fold_expression)
17431 << BO->getOpcodeStr();
17432 }
17433 }
17434 }
17435 } else
17436 Result = Out;
17437
17438 if (Result.isInvalid())
17439 return true;
17440 }
17441
17442 // If we're retaining an expansion for a left fold, it is the outermost
17443 // component and takes the complete expansion so far as its init (if any).
17444 if (LeftFold && RetainExpansion) {
17445 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17446
17447 ExprResult Out = getDerived().TransformExpr(Pattern);
17448 if (Out.isInvalid())
17449 return true;
17450
17451 Result = getDerived().RebuildCXXFoldExpr(
17452 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
17453 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
17454 if (Result.isInvalid())
17455 return true;
17456 }
17457
17458 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
17459 PE->setIsProducedByFoldExpansion();
17460
17461 // If we had no init and an empty pack, and we're not retaining an expansion,
17462 // then produce a fallback value or error.
17463 if (Result.isUnset())
17464 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
17465 E->getOperator());
17466 return Result;
17467}
17468
17469template <typename Derived>
17470ExprResult
17471TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
17472 SmallVector<Expr *, 4> TransformedInits;
17473 ArrayRef<Expr *> InitExprs = E->getInitExprs();
17474
17475 QualType T = getDerived().TransformType(E->getType());
17476
17477 bool ArgChanged = false;
17478
17479 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
17480 TransformedInits, &ArgChanged))
17481 return ExprError();
17482
17483 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
17484 return E;
17485
17486 return getDerived().RebuildCXXParenListInitExpr(
17487 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
17488 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
17489}
17490
17491template<typename Derived>
17492ExprResult
17493TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
17494 CXXStdInitializerListExpr *E) {
17495 return getDerived().TransformExpr(E->getSubExpr());
17496}
17497
17498template<typename Derived>
17499ExprResult
17500TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
17501 return SemaRef.MaybeBindToTemporary(E);
17502}
17503
17504template<typename Derived>
17505ExprResult
17506TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
17507 return E;
17508}
17509
17510template<typename Derived>
17511ExprResult
17512TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
17513 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
17514 if (SubExpr.isInvalid())
17515 return ExprError();
17516
17517 if (!getDerived().AlwaysRebuild() &&
17518 SubExpr.get() == E->getSubExpr())
17519 return E;
17520
17521 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
17522}
17523
17524template<typename Derived>
17525ExprResult
17526TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
17527 // Transform each of the elements.
17528 SmallVector<Expr *, 8> Elements;
17529 bool ArgChanged = false;
17530 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
17531 /*IsCall=*/false, Elements, &ArgChanged))
17532 return ExprError();
17533
17534 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17535 return SemaRef.MaybeBindToTemporary(E);
17536
17537 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
17538 Elements.data(),
17539 Elements.size());
17540}
17541
17542template<typename Derived>
17543ExprResult
17544TreeTransform<Derived>::TransformObjCDictionaryLiteral(
17545 ObjCDictionaryLiteral *E) {
17546 // Transform each of the elements.
17547 SmallVector<ObjCDictionaryElement, 8> Elements;
17548 bool ArgChanged = false;
17549 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
17550 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
17551
17552 if (OrigElement.isPackExpansion()) {
17553 // This key/value element is a pack expansion.
17554 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17555 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
17556 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
17557 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17558
17559 // Determine whether the set of unexpanded parameter packs can
17560 // and should be expanded.
17561 bool Expand = true;
17562 bool RetainExpansion = false;
17563 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
17564 UnsignedOrNone NumExpansions = OrigNumExpansions;
17565 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
17566 OrigElement.Value->getEndLoc());
17567 if (getDerived().TryExpandParameterPacks(
17568 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
17569 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17570 NumExpansions))
17571 return ExprError();
17572
17573 if (!Expand) {
17574 // The transform has determined that we should perform a simple
17575 // transformation on the pack expansion, producing another pack
17576 // expansion.
17577 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17578 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17579 if (Key.isInvalid())
17580 return ExprError();
17581
17582 if (Key.get() != OrigElement.Key)
17583 ArgChanged = true;
17584
17585 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17586 if (Value.isInvalid())
17587 return ExprError();
17588
17589 if (Value.get() != OrigElement.Value)
17590 ArgChanged = true;
17591
17592 ObjCDictionaryElement Expansion = {
17593 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
17594 };
17595 Elements.push_back(Elt: Expansion);
17596 continue;
17597 }
17598
17599 // Record right away that the argument was changed. This needs
17600 // to happen even if the array expands to nothing.
17601 ArgChanged = true;
17602
17603 // The transform has determined that we should perform an elementwise
17604 // expansion of the pattern. Do so.
17605 for (unsigned I = 0; I != *NumExpansions; ++I) {
17606 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17607 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17608 if (Key.isInvalid())
17609 return ExprError();
17610
17611 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17612 if (Value.isInvalid())
17613 return ExprError();
17614
17615 ObjCDictionaryElement Element = {
17616 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17617 };
17618
17619 // If any unexpanded parameter packs remain, we still have a
17620 // pack expansion.
17621 // FIXME: Can this really happen?
17622 if (Key.get()->containsUnexpandedParameterPack() ||
17623 Value.get()->containsUnexpandedParameterPack())
17624 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17625
17626 Elements.push_back(Elt: Element);
17627 }
17628
17629 // FIXME: Retain a pack expansion if RetainExpansion is true.
17630
17631 // We've finished with this pack expansion.
17632 continue;
17633 }
17634
17635 // Transform and check key.
17636 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17637 if (Key.isInvalid())
17638 return ExprError();
17639
17640 if (Key.get() != OrigElement.Key)
17641 ArgChanged = true;
17642
17643 // Transform and check value.
17644 ExprResult Value
17645 = getDerived().TransformExpr(OrigElement.Value);
17646 if (Value.isInvalid())
17647 return ExprError();
17648
17649 if (Value.get() != OrigElement.Value)
17650 ArgChanged = true;
17651
17652 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17653 .NumExpansions: std::nullopt};
17654 Elements.push_back(Elt: Element);
17655 }
17656
17657 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17658 return SemaRef.MaybeBindToTemporary(E);
17659
17660 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17661 Elements);
17662}
17663
17664template<typename Derived>
17665ExprResult
17666TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17667 TypeSourceInfo *EncodedTypeInfo
17668 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17669 if (!EncodedTypeInfo)
17670 return ExprError();
17671
17672 if (!getDerived().AlwaysRebuild() &&
17673 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17674 return E;
17675
17676 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17677 EncodedTypeInfo,
17678 E->getRParenLoc());
17679}
17680
17681template<typename Derived>
17682ExprResult TreeTransform<Derived>::
17683TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17684 // This is a kind of implicit conversion, and it needs to get dropped
17685 // and recomputed for the same general reasons that ImplicitCastExprs
17686 // do, as well a more specific one: this expression is only valid when
17687 // it appears *immediately* as an argument expression.
17688 return getDerived().TransformExpr(E->getSubExpr());
17689}
17690
17691template<typename Derived>
17692ExprResult TreeTransform<Derived>::
17693TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17694 TypeSourceInfo *TSInfo
17695 = getDerived().TransformType(E->getTypeInfoAsWritten());
17696 if (!TSInfo)
17697 return ExprError();
17698
17699 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17700 if (Result.isInvalid())
17701 return ExprError();
17702
17703 if (!getDerived().AlwaysRebuild() &&
17704 TSInfo == E->getTypeInfoAsWritten() &&
17705 Result.get() == E->getSubExpr())
17706 return E;
17707
17708 return SemaRef.ObjC().BuildObjCBridgedCast(
17709 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17710 SubExpr: Result.get());
17711}
17712
17713template <typename Derived>
17714ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17715 ObjCAvailabilityCheckExpr *E) {
17716 return E;
17717}
17718
17719template<typename Derived>
17720ExprResult
17721TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17722 // Transform arguments.
17723 bool ArgChanged = false;
17724 SmallVector<Expr*, 8> Args;
17725 Args.reserve(N: E->getNumArgs());
17726 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17727 &ArgChanged))
17728 return ExprError();
17729
17730 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17731 // Class message: transform the receiver type.
17732 TypeSourceInfo *ReceiverTypeInfo
17733 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17734 if (!ReceiverTypeInfo)
17735 return ExprError();
17736
17737 // If nothing changed, just retain the existing message send.
17738 if (!getDerived().AlwaysRebuild() &&
17739 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17740 return SemaRef.MaybeBindToTemporary(E);
17741
17742 // Build a new class message send.
17743 SmallVector<SourceLocation, 16> SelLocs;
17744 E->getSelectorLocs(SelLocs);
17745 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17746 E->getSelector(),
17747 SelLocs,
17748 E->getMethodDecl(),
17749 E->getLeftLoc(),
17750 Args,
17751 E->getRightLoc());
17752 }
17753 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17754 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17755 if (!E->getMethodDecl())
17756 return ExprError();
17757
17758 // Build a new class message send to 'super'.
17759 SmallVector<SourceLocation, 16> SelLocs;
17760 E->getSelectorLocs(SelLocs);
17761 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17762 E->getSelector(),
17763 SelLocs,
17764 E->getReceiverType(),
17765 E->getMethodDecl(),
17766 E->getLeftLoc(),
17767 Args,
17768 E->getRightLoc());
17769 }
17770
17771 // Instance message: transform the receiver
17772 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17773 "Only class and instance messages may be instantiated");
17774 ExprResult Receiver
17775 = getDerived().TransformExpr(E->getInstanceReceiver());
17776 if (Receiver.isInvalid())
17777 return ExprError();
17778
17779 // If nothing changed, just retain the existing message send.
17780 if (!getDerived().AlwaysRebuild() &&
17781 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17782 return SemaRef.MaybeBindToTemporary(E);
17783
17784 // Build a new instance message send.
17785 SmallVector<SourceLocation, 16> SelLocs;
17786 E->getSelectorLocs(SelLocs);
17787 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17788 E->getSelector(),
17789 SelLocs,
17790 E->getMethodDecl(),
17791 E->getLeftLoc(),
17792 Args,
17793 E->getRightLoc());
17794}
17795
17796template<typename Derived>
17797ExprResult
17798TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17799 return E;
17800}
17801
17802template<typename Derived>
17803ExprResult
17804TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17805 return E;
17806}
17807
17808template<typename Derived>
17809ExprResult
17810TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17811 // Transform the base expression.
17812 ExprResult Base = getDerived().TransformExpr(E->getBase());
17813 if (Base.isInvalid())
17814 return ExprError();
17815
17816 // We don't need to transform the ivar; it will never change.
17817
17818 // If nothing changed, just retain the existing expression.
17819 if (!getDerived().AlwaysRebuild() &&
17820 Base.get() == E->getBase())
17821 return E;
17822
17823 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17824 E->getLocation(),
17825 E->isArrow(), E->isFreeIvar());
17826}
17827
17828template<typename Derived>
17829ExprResult
17830TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17831 // 'super' and types never change. Property never changes. Just
17832 // retain the existing expression.
17833 if (!E->isObjectReceiver())
17834 return E;
17835
17836 // Transform the base expression.
17837 ExprResult Base = getDerived().TransformExpr(E->getBase());
17838 if (Base.isInvalid())
17839 return ExprError();
17840
17841 // We don't need to transform the property; it will never change.
17842
17843 // If nothing changed, just retain the existing expression.
17844 if (!getDerived().AlwaysRebuild() &&
17845 Base.get() == E->getBase())
17846 return E;
17847
17848 if (E->isExplicitProperty())
17849 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17850 E->getExplicitProperty(),
17851 E->getLocation());
17852
17853 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17854 SemaRef.Context.PseudoObjectTy,
17855 E->getImplicitPropertyGetter(),
17856 E->getImplicitPropertySetter(),
17857 E->getLocation());
17858}
17859
17860template<typename Derived>
17861ExprResult
17862TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17863 // Transform the base expression.
17864 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17865 if (Base.isInvalid())
17866 return ExprError();
17867
17868 // Transform the key expression.
17869 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17870 if (Key.isInvalid())
17871 return ExprError();
17872
17873 // If nothing changed, just retain the existing expression.
17874 if (!getDerived().AlwaysRebuild() &&
17875 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17876 return E;
17877
17878 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17879 Base.get(), Key.get(),
17880 E->getAtIndexMethodDecl(),
17881 E->setAtIndexMethodDecl());
17882}
17883
17884template<typename Derived>
17885ExprResult
17886TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17887 // Transform the base expression.
17888 ExprResult Base = getDerived().TransformExpr(E->getBase());
17889 if (Base.isInvalid())
17890 return ExprError();
17891
17892 // If nothing changed, just retain the existing expression.
17893 if (!getDerived().AlwaysRebuild() &&
17894 Base.get() == E->getBase())
17895 return E;
17896
17897 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17898 E->getOpLoc(),
17899 E->isArrow());
17900}
17901
17902template<typename Derived>
17903ExprResult
17904TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17905 bool ArgumentChanged = false;
17906 SmallVector<Expr*, 8> SubExprs;
17907 SubExprs.reserve(N: E->getNumSubExprs());
17908 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17909 SubExprs, &ArgumentChanged))
17910 return ExprError();
17911
17912 if (!getDerived().AlwaysRebuild() &&
17913 !ArgumentChanged)
17914 return E;
17915
17916 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17917 SubExprs,
17918 E->getRParenLoc());
17919}
17920
17921template<typename Derived>
17922ExprResult
17923TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17924 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17925 if (SrcExpr.isInvalid())
17926 return ExprError();
17927
17928 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17929 if (!Type)
17930 return ExprError();
17931
17932 if (!getDerived().AlwaysRebuild() &&
17933 Type == E->getTypeSourceInfo() &&
17934 SrcExpr.get() == E->getSrcExpr())
17935 return E;
17936
17937 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17938 SrcExpr.get(), Type,
17939 E->getRParenLoc());
17940}
17941
17942template<typename Derived>
17943ExprResult
17944TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17945 BlockDecl *oldBlock = E->getBlockDecl();
17946
17947 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17948 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17949
17950 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17951 blockScope->TheDecl->setBlockMissingReturnType(
17952 oldBlock->blockMissingReturnType());
17953
17954 SmallVector<ParmVarDecl*, 4> params;
17955 SmallVector<QualType, 4> paramTypes;
17956
17957 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17958
17959 // Parameter substitution.
17960 Sema::ExtParameterInfoBuilder extParamInfos;
17961 if (getDerived().TransformFunctionTypeParams(
17962 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17963 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17964 extParamInfos)) {
17965 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17966 return ExprError();
17967 }
17968
17969 QualType exprResultType =
17970 getDerived().TransformType(exprFunctionType->getReturnType());
17971
17972 auto epi = exprFunctionType->getExtProtoInfo();
17973 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17974
17975 QualType functionType =
17976 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17977 blockScope->FunctionType = functionType;
17978
17979 // Set the parameters on the block decl.
17980 if (!params.empty())
17981 blockScope->TheDecl->setParams(params);
17982
17983 if (!oldBlock->blockMissingReturnType()) {
17984 blockScope->HasImplicitReturnType = false;
17985 blockScope->ReturnType = exprResultType;
17986 }
17987
17988 // Transform the body
17989 StmtResult body = getDerived().TransformStmt(E->getBody());
17990 if (body.isInvalid()) {
17991 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17992 return ExprError();
17993 }
17994
17995#ifndef NDEBUG
17996 // In builds with assertions, make sure that we captured everything we
17997 // captured before.
17998 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17999 for (const auto &I : oldBlock->captures()) {
18000 VarDecl *oldCapture = I.getVariable();
18001
18002 // Ignore parameter packs.
18003 if (oldCapture->isParameterPack())
18004 continue;
18005
18006 VarDecl *newCapture =
18007 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
18008 oldCapture));
18009 assert(blockScope->CaptureMap.count(newCapture));
18010 }
18011 }
18012#endif
18013
18014 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
18015 /*Scope=*/CurScope: nullptr);
18016}
18017
18018template<typename Derived>
18019ExprResult
18020TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
18021 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
18022 if (SrcExpr.isInvalid())
18023 return ExprError();
18024
18025 QualType Type = getDerived().TransformType(E->getType());
18026
18027 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
18028 RParenLoc: E->getRParenLoc());
18029}
18030
18031template<typename Derived>
18032ExprResult
18033TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
18034 bool ArgumentChanged = false;
18035 SmallVector<Expr*, 8> SubExprs;
18036 SubExprs.reserve(N: E->getNumSubExprs());
18037 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
18038 SubExprs, &ArgumentChanged))
18039 return ExprError();
18040
18041 if (!getDerived().AlwaysRebuild() &&
18042 !ArgumentChanged)
18043 return E;
18044
18045 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
18046 E->getOp(), E->getRParenLoc());
18047}
18048
18049//===----------------------------------------------------------------------===//
18050// Type reconstruction
18051//===----------------------------------------------------------------------===//
18052
18053template<typename Derived>
18054QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
18055 SourceLocation Star) {
18056 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
18057 Entity: getDerived().getBaseEntity());
18058}
18059
18060template<typename Derived>
18061QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
18062 SourceLocation Star) {
18063 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
18064 Entity: getDerived().getBaseEntity());
18065}
18066
18067template<typename Derived>
18068QualType
18069TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
18070 bool WrittenAsLValue,
18071 SourceLocation Sigil) {
18072 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
18073 Loc: Sigil, Entity: getDerived().getBaseEntity());
18074}
18075
18076template <typename Derived>
18077QualType TreeTransform<Derived>::RebuildMemberPointerType(
18078 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
18079 SourceLocation Sigil) {
18080 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
18081 Entity: getDerived().getBaseEntity());
18082}
18083
18084template<typename Derived>
18085QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
18086 const ObjCTypeParamDecl *Decl,
18087 SourceLocation ProtocolLAngleLoc,
18088 ArrayRef<ObjCProtocolDecl *> Protocols,
18089 ArrayRef<SourceLocation> ProtocolLocs,
18090 SourceLocation ProtocolRAngleLoc) {
18091 return SemaRef.ObjC().BuildObjCTypeParamType(
18092 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18093 /*FailOnError=*/FailOnError: true);
18094}
18095
18096template<typename Derived>
18097QualType TreeTransform<Derived>::RebuildObjCObjectType(
18098 QualType BaseType,
18099 SourceLocation Loc,
18100 SourceLocation TypeArgsLAngleLoc,
18101 ArrayRef<TypeSourceInfo *> TypeArgs,
18102 SourceLocation TypeArgsRAngleLoc,
18103 SourceLocation ProtocolLAngleLoc,
18104 ArrayRef<ObjCProtocolDecl *> Protocols,
18105 ArrayRef<SourceLocation> ProtocolLocs,
18106 SourceLocation ProtocolRAngleLoc) {
18107 return SemaRef.ObjC().BuildObjCObjectType(
18108 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
18109 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18110 /*FailOnError=*/FailOnError: true,
18111 /*Rebuilding=*/Rebuilding: true);
18112}
18113
18114template<typename Derived>
18115QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
18116 QualType PointeeType,
18117 SourceLocation Star) {
18118 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
18119}
18120
18121template <typename Derived>
18122QualType TreeTransform<Derived>::RebuildArrayType(
18123 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
18124 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18125 if (SizeExpr || !Size)
18126 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
18127 Quals: IndexTypeQuals, Brackets: BracketsRange,
18128 Entity: getDerived().getBaseEntity());
18129
18130 QualType Types[] = {
18131 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
18132 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
18133 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
18134 };
18135 QualType SizeType;
18136 for (const auto &T : Types)
18137 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
18138 SizeType = T;
18139 break;
18140 }
18141
18142 // Note that we can return a VariableArrayType here in the case where
18143 // the element type was a dependent VariableArrayType.
18144 IntegerLiteral *ArraySize
18145 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
18146 /*FIXME*/l: BracketsRange.getBegin());
18147 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
18148 Quals: IndexTypeQuals, Brackets: BracketsRange,
18149 Entity: getDerived().getBaseEntity());
18150}
18151
18152template <typename Derived>
18153QualType TreeTransform<Derived>::RebuildConstantArrayType(
18154 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
18155 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18156 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
18157 IndexTypeQuals, BracketsRange);
18158}
18159
18160template <typename Derived>
18161QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
18162 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
18163 SourceRange BracketsRange) {
18164 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
18165 IndexTypeQuals, BracketsRange);
18166}
18167
18168template <typename Derived>
18169QualType TreeTransform<Derived>::RebuildVariableArrayType(
18170 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18171 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18172 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18173 SizeExpr,
18174 IndexTypeQuals, BracketsRange);
18175}
18176
18177template <typename Derived>
18178QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
18179 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18180 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18181 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18182 SizeExpr,
18183 IndexTypeQuals, BracketsRange);
18184}
18185
18186template <typename Derived>
18187QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
18188 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
18189 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
18190 AttrLoc: AttributeLoc);
18191}
18192
18193template <typename Derived>
18194QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
18195 unsigned NumElements,
18196 VectorKind VecKind) {
18197 // FIXME: semantic checking!
18198 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
18199}
18200
18201template <typename Derived>
18202QualType TreeTransform<Derived>::RebuildDependentVectorType(
18203 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
18204 VectorKind VecKind) {
18205 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
18206}
18207
18208template<typename Derived>
18209QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
18210 unsigned NumElements,
18211 SourceLocation AttributeLoc) {
18212 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18213 NumElements, true);
18214 IntegerLiteral *VectorSize
18215 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
18216 l: AttributeLoc);
18217 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
18218}
18219
18220template<typename Derived>
18221QualType
18222TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
18223 Expr *SizeExpr,
18224 SourceLocation AttributeLoc) {
18225 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
18226}
18227
18228template <typename Derived>
18229QualType TreeTransform<Derived>::RebuildConstantMatrixType(
18230 QualType ElementType, unsigned NumRows, unsigned NumColumns,
18231 SourceLocation AttributeLoc) {
18232 ASTContext &Ctx = SemaRef.Context;
18233 QualType SizeTy = Ctx.getSizeType();
18234 unsigned SizeWidth = Ctx.getIntWidth(T: SizeTy);
18235 IntegerLiteral *RowExpr = IntegerLiteral::Create(
18236 C: Ctx, V: llvm::APInt(SizeWidth, NumRows), type: SizeTy, l: AttributeLoc);
18237 IntegerLiteral *ColumnExpr = IntegerLiteral::Create(
18238 C: Ctx, V: llvm::APInt(SizeWidth, NumColumns), type: SizeTy, l: AttributeLoc);
18239 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
18240 AttrLoc: AttributeLoc);
18241}
18242
18243template <typename Derived>
18244QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
18245 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
18246 SourceLocation AttributeLoc) {
18247 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
18248 AttrLoc: AttributeLoc);
18249}
18250
18251template <typename Derived>
18252QualType TreeTransform<Derived>::RebuildFunctionProtoType(
18253 QualType T, MutableArrayRef<QualType> ParamTypes,
18254 const FunctionProtoType::ExtProtoInfo &EPI) {
18255 return SemaRef.BuildFunctionType(T, ParamTypes,
18256 Loc: getDerived().getBaseLocation(),
18257 Entity: getDerived().getBaseEntity(),
18258 EPI);
18259}
18260
18261template<typename Derived>
18262QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
18263 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
18264}
18265
18266template <typename Derived>
18267QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
18268 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
18269 SourceLocation NameLoc, Decl *D) {
18270 assert(D && "no decl found");
18271 if (D->isInvalidDecl()) return QualType();
18272
18273 // FIXME: Doesn't account for ObjCInterfaceDecl!
18274 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
18275 // A valid resolved using typename pack expansion decl can have multiple
18276 // UsingDecls, but they must each have exactly one type, and it must be
18277 // the same type in every case. But we must have at least one expansion!
18278 if (UPD->expansions().empty()) {
18279 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
18280 << UPD->isCXXClassMember() << UPD;
18281 return QualType();
18282 }
18283
18284 // We might still have some unresolved types. Try to pick a resolved type
18285 // if we can. The final instantiation will check that the remaining
18286 // unresolved types instantiate to the type we pick.
18287 QualType FallbackT;
18288 QualType T;
18289 for (auto *E : UPD->expansions()) {
18290 QualType ThisT =
18291 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
18292 if (ThisT.isNull())
18293 continue;
18294 if (ThisT->getAs<UnresolvedUsingType>())
18295 FallbackT = ThisT;
18296 else if (T.isNull())
18297 T = ThisT;
18298 else
18299 assert(getSema().Context.hasSameType(ThisT, T) &&
18300 "mismatched resolved types in using pack expansion");
18301 }
18302 return T.isNull() ? FallbackT : T;
18303 }
18304 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
18305 assert(Using->hasTypename() &&
18306 "UnresolvedUsingTypenameDecl transformed to non-typename using");
18307
18308 // A valid resolved using typename decl points to exactly one type decl.
18309 assert(++Using->shadow_begin() == Using->shadow_end());
18310
18311 UsingShadowDecl *Shadow = *Using->shadow_begin();
18312 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
18313 return QualType();
18314 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
18315 }
18316 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
18317 "UnresolvedUsingTypenameDecl transformed to non-using decl");
18318 return SemaRef.Context.getUnresolvedUsingType(
18319 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
18320}
18321
18322template <typename Derived>
18323QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
18324 TypeOfKind Kind) {
18325 return SemaRef.BuildTypeofExprType(E, Kind);
18326}
18327
18328template<typename Derived>
18329QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
18330 TypeOfKind Kind) {
18331 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
18332}
18333
18334template <typename Derived>
18335QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
18336 return SemaRef.BuildDecltypeType(E);
18337}
18338
18339template <typename Derived>
18340QualType TreeTransform<Derived>::RebuildPackIndexingType(
18341 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
18342 SourceLocation EllipsisLoc, bool FullySubstituted,
18343 ArrayRef<QualType> Expansions) {
18344 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
18345 FullySubstituted, Expansions);
18346}
18347
18348template<typename Derived>
18349QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
18350 UnaryTransformType::UTTKind UKind,
18351 SourceLocation Loc) {
18352 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
18353}
18354
18355template <typename Derived>
18356QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
18357 ElaboratedTypeKeyword Keyword, TemplateName Template,
18358 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
18359 return SemaRef.CheckTemplateIdType(
18360 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
18361 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
18362}
18363
18364template<typename Derived>
18365QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
18366 SourceLocation KWLoc) {
18367 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
18368}
18369
18370template<typename Derived>
18371QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
18372 SourceLocation KWLoc,
18373 bool isReadPipe) {
18374 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
18375 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
18376}
18377
18378template <typename Derived>
18379QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
18380 unsigned NumBits,
18381 SourceLocation Loc) {
18382 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18383 NumBits, true);
18384 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
18385 type: SemaRef.Context.IntTy, l: Loc);
18386 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
18387}
18388
18389template <typename Derived>
18390QualType TreeTransform<Derived>::RebuildDependentBitIntType(
18391 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
18392 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
18393}
18394
18395template <typename Derived>
18396TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18397 bool TemplateKW,
18398 TemplateName Name) {
18399 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
18400 Template: Name);
18401}
18402
18403template <typename Derived>
18404TemplateName TreeTransform<Derived>::RebuildTemplateName(
18405 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
18406 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
18407 UnqualifiedId TemplateName;
18408 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
18409 Sema::TemplateTy Template;
18410 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
18411 TemplateName, ParsedType::make(P: ObjectType),
18412 /*EnteringContext=*/false, Template,
18413 AllowInjectedClassName);
18414 return Template.get();
18415}
18416
18417template<typename Derived>
18418TemplateName
18419TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18420 SourceLocation TemplateKWLoc,
18421 OverloadedOperatorKind Operator,
18422 SourceLocation NameLoc,
18423 QualType ObjectType,
18424 bool AllowInjectedClassName) {
18425 UnqualifiedId Name;
18426 // FIXME: Bogus location information.
18427 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
18428 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
18429 Sema::TemplateTy Template;
18430 getSema().ActOnTemplateName(
18431 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
18432 /*EnteringContext=*/false, Template, AllowInjectedClassName);
18433 return Template.get();
18434}
18435
18436template <typename Derived>
18437ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
18438 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
18439 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
18440 Expr *Second) {
18441 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
18442
18443 if (First->getObjectKind() == OK_ObjCProperty) {
18444 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18445 if (BinaryOperator::isAssignmentOp(Opc))
18446 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
18447 Opcode: Opc, LHS: First, RHS: Second);
18448 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
18449 if (Result.isInvalid())
18450 return ExprError();
18451 First = Result.get();
18452 }
18453
18454 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
18455 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
18456 if (Result.isInvalid())
18457 return ExprError();
18458 Second = Result.get();
18459 }
18460
18461 // Determine whether this should be a builtin operation.
18462 if (Op == OO_Subscript) {
18463 if (!First->getType()->isOverloadableType() &&
18464 !Second->getType()->isOverloadableType())
18465 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
18466 OpLoc);
18467 } else if (Op == OO_Arrow) {
18468 // It is possible that the type refers to a RecoveryExpr created earlier
18469 // in the tree transformation.
18470 if (First->getType()->isDependentType())
18471 return ExprError();
18472 // -> is never a builtin operation.
18473 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
18474 } else if (Second == nullptr || isPostIncDec) {
18475 if (!First->getType()->isOverloadableType() ||
18476 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
18477 // The argument is not of overloadable type, or this is an expression
18478 // of the form &Class::member, so try to create a built-in unary
18479 // operation.
18480 UnaryOperatorKind Opc
18481 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18482
18483 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
18484 }
18485 } else {
18486 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
18487 !First->getType()->isOverloadableType() &&
18488 !Second->getType()->isOverloadableType()) {
18489 // Neither of the arguments is type-dependent or has an overloadable
18490 // type, so try to create a built-in binary operation.
18491 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18492 ExprResult Result
18493 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
18494 if (Result.isInvalid())
18495 return ExprError();
18496
18497 return Result;
18498 }
18499 }
18500
18501 // Create the overloaded operator invocation for unary operators.
18502 if (!Second || isPostIncDec) {
18503 UnaryOperatorKind Opc
18504 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18505 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
18506 RequiresADL);
18507 }
18508
18509 // Create the overloaded operator invocation for binary operators.
18510 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18511 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
18512 LHS: First, RHS: Second, RequiresADL);
18513 if (Result.isInvalid())
18514 return ExprError();
18515
18516 return Result;
18517}
18518
18519template<typename Derived>
18520ExprResult
18521TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
18522 SourceLocation OperatorLoc,
18523 bool isArrow,
18524 CXXScopeSpec &SS,
18525 TypeSourceInfo *ScopeType,
18526 SourceLocation CCLoc,
18527 SourceLocation TildeLoc,
18528 PseudoDestructorTypeStorage Destroyed) {
18529 QualType CanonicalBaseType = Base->getType().getCanonicalType();
18530 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
18531 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
18532 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
18533 !cast<PointerType>(Val&: CanonicalBaseType)
18534 ->getPointeeType()
18535 ->getAsCanonical<RecordType>())) {
18536 // This pseudo-destructor expression is still a pseudo-destructor.
18537 return SemaRef.BuildPseudoDestructorExpr(
18538 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
18539 CCLoc, TildeLoc, DestroyedType: Destroyed);
18540 }
18541
18542 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
18543 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
18544 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
18545 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
18546 NameInfo.setNamedTypeInfo(DestroyedType);
18547
18548 // The scope type is now known to be a valid nested name specifier
18549 // component. Tack it on to the nested name specifier.
18550 if (ScopeType) {
18551 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
18552 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
18553 diag::err_expected_class_or_namespace)
18554 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
18555 return ExprError();
18556 }
18557 SS.clear();
18558 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
18559 }
18560
18561 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
18562 return getSema().BuildMemberReferenceExpr(
18563 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
18564 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
18565 /*TemplateArgs*/ nullptr,
18566 /*S*/ nullptr);
18567}
18568
18569template<typename Derived>
18570StmtResult
18571TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
18572 SourceLocation Loc = S->getBeginLoc();
18573 CapturedDecl *CD = S->getCapturedDecl();
18574 unsigned NumParams = CD->getNumParams();
18575 unsigned ContextParamPos = CD->getContextParamPosition();
18576 SmallVector<Sema::CapturedParamNameType, 4> Params;
18577 for (unsigned I = 0; I < NumParams; ++I) {
18578 if (I != ContextParamPos) {
18579 Params.push_back(
18580 Elt: std::make_pair(
18581 CD->getParam(i: I)->getName(),
18582 getDerived().TransformType(CD->getParam(i: I)->getType())));
18583 } else {
18584 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
18585 }
18586 }
18587 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
18588 S->getCapturedRegionKind(), Params);
18589 StmtResult Body;
18590 {
18591 Sema::CompoundScopeRAII CompoundScope(getSema());
18592 Body = getDerived().TransformStmt(S->getCapturedStmt());
18593 }
18594
18595 if (Body.isInvalid()) {
18596 getSema().ActOnCapturedRegionError();
18597 return StmtError();
18598 }
18599
18600 return getSema().ActOnCapturedRegionEnd(Body.get());
18601}
18602
18603template <typename Derived>
18604StmtResult
18605TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18606 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18607 // function definition or instantiation of a function template specialization
18608 // and will therefore never appear in a dependent context.
18609 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18610 "context");
18611}
18612
18613template <typename Derived>
18614ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18615 // We can transform the base expression and allow argument resolution to fill
18616 // in the rest.
18617 return getDerived().TransformExpr(E->getArgLValue());
18618}
18619
18620} // end namespace clang
18621
18622#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18623