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
1050 /// Build a new matrix type given the type and dependently-defined
1051 /// dimensions.
1052 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1053 Expr *ColumnExpr,
1054 SourceLocation AttributeLoc);
1055
1056 /// Build a new DependentAddressSpaceType or return the pointee
1057 /// type variable with the correct address space (retrieved from
1058 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1059 /// where the address space remains dependent.
1060 ///
1061 /// By default, performs semantic analysis when building the type with address
1062 /// space applied. Subclasses may override this routine to provide different
1063 /// behavior.
1064 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1065 Expr *AddrSpaceExpr,
1066 SourceLocation AttributeLoc);
1067
1068 /// Build a new function type.
1069 ///
1070 /// By default, performs semantic analysis when building the function type.
1071 /// Subclasses may override this routine to provide different behavior.
1072 QualType RebuildFunctionProtoType(QualType T,
1073 MutableArrayRef<QualType> ParamTypes,
1074 const FunctionProtoType::ExtProtoInfo &EPI);
1075
1076 /// Build a new unprototyped function type.
1077 QualType RebuildFunctionNoProtoType(QualType ResultType);
1078
1079 /// Rebuild an unresolved typename type, given the decl that
1080 /// the UnresolvedUsingTypenameDecl was transformed to.
1081 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1082 NestedNameSpecifier Qualifier,
1083 SourceLocation NameLoc, Decl *D);
1084
1085 /// Build a new type found via an alias.
1086 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1087 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1088 QualType UnderlyingType) {
1089 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1090 }
1091
1092 /// Build a new typedef type.
1093 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1094 NestedNameSpecifier Qualifier,
1095 TypedefNameDecl *Typedef) {
1096 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1097 }
1098
1099 /// Build a new MacroDefined type.
1100 QualType RebuildMacroQualifiedType(QualType T,
1101 const IdentifierInfo *MacroII) {
1102 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1103 }
1104
1105 /// Build a new class/struct/union/enum type.
1106 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1107 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1108 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1109 /*OwnsTag=*/OwnsTag: false);
1110 }
1111 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1112 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1113 }
1114
1115 /// Build a new typeof(expr) type.
1116 ///
1117 /// By default, performs semantic analysis when building the typeof type.
1118 /// Subclasses may override this routine to provide different behavior.
1119 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1120 TypeOfKind Kind);
1121
1122 /// Build a new typeof(type) type.
1123 ///
1124 /// By default, builds a new TypeOfType with the given underlying type.
1125 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1126
1127 /// Build a new unary transform type.
1128 QualType RebuildUnaryTransformType(QualType BaseType,
1129 UnaryTransformType::UTTKind UKind,
1130 SourceLocation Loc);
1131
1132 /// Build a new C++11 decltype type.
1133 ///
1134 /// By default, performs semantic analysis when building the decltype type.
1135 /// Subclasses may override this routine to provide different behavior.
1136 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1137
1138 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1139 SourceLocation Loc,
1140 SourceLocation EllipsisLoc,
1141 bool FullySubstituted,
1142 ArrayRef<QualType> Expansions = {});
1143
1144 /// Build a new C++11 auto type.
1145 ///
1146 /// By default, builds a new AutoType with the given deduced type.
1147 QualType RebuildAutoType(DeducedKind DK, QualType DeducedAsType,
1148 AutoTypeKeyword Keyword,
1149 TemplateName TypeConstraintConcept,
1150 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1151 return SemaRef.Context.getAutoType(
1152 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1153 }
1154
1155 /// By default, builds a new DeducedTemplateSpecializationType with the given
1156 /// deduced type.
1157 QualType RebuildDeducedTemplateSpecializationType(
1158 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1159 TemplateName Template) {
1160 return SemaRef.Context.getDeducedTemplateSpecializationType(
1161 DK, DeducedAsType, Keyword, Template);
1162 }
1163
1164 /// Build a new template specialization type.
1165 ///
1166 /// By default, performs semantic analysis when building the template
1167 /// specialization type. Subclasses may override this routine to provide
1168 /// different behavior.
1169 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1170 TemplateName Template,
1171 SourceLocation TemplateLoc,
1172 TemplateArgumentListInfo &Args);
1173
1174 /// Build a new parenthesized type.
1175 ///
1176 /// By default, builds a new ParenType type from the inner type.
1177 /// Subclasses may override this routine to provide different behavior.
1178 QualType RebuildParenType(QualType InnerType) {
1179 return SemaRef.BuildParenType(T: InnerType);
1180 }
1181
1182 /// Build a new typename type that refers to an identifier.
1183 ///
1184 /// By default, performs semantic analysis when building the typename type
1185 /// (or elaborated type). Subclasses may override this routine to provide
1186 /// different behavior.
1187 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1188 SourceLocation KeywordLoc,
1189 NestedNameSpecifierLoc QualifierLoc,
1190 const IdentifierInfo *Id,
1191 SourceLocation IdLoc,
1192 bool DeducedTSTContext) {
1193 CXXScopeSpec SS;
1194 SS.Adopt(Other: QualifierLoc);
1195
1196 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1197 // If the name is still dependent, just build a new dependent name type.
1198 if (!SemaRef.computeDeclContext(SS))
1199 return SemaRef.Context.getDependentNameType(Keyword,
1200 NNS: QualifierLoc.getNestedNameSpecifier(),
1201 Name: Id);
1202 }
1203
1204 if (Keyword == ElaboratedTypeKeyword::None ||
1205 Keyword == ElaboratedTypeKeyword::Typename) {
1206 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1207 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1208 }
1209
1210 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1211
1212 // We had a dependent elaborated-type-specifier that has been transformed
1213 // into a non-dependent elaborated-type-specifier. Find the tag we're
1214 // referring to.
1215 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1216 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1217 if (!DC)
1218 return QualType();
1219
1220 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1221 return QualType();
1222
1223 TagDecl *Tag = nullptr;
1224 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1225 switch (Result.getResultKind()) {
1226 case LookupResultKind::NotFound:
1227 case LookupResultKind::NotFoundInCurrentInstantiation:
1228 break;
1229
1230 case LookupResultKind::Found:
1231 Tag = Result.getAsSingle<TagDecl>();
1232 break;
1233
1234 case LookupResultKind::FoundOverloaded:
1235 case LookupResultKind::FoundUnresolvedValue:
1236 llvm_unreachable("Tag lookup cannot find non-tags");
1237
1238 case LookupResultKind::Ambiguous:
1239 // Let the LookupResult structure handle ambiguities.
1240 return QualType();
1241 }
1242
1243 if (!Tag) {
1244 // Check where the name exists but isn't a tag type and use that to emit
1245 // better diagnostics.
1246 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1247 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1248 switch (Result.getResultKind()) {
1249 case LookupResultKind::Found:
1250 case LookupResultKind::FoundOverloaded:
1251 case LookupResultKind::FoundUnresolvedValue: {
1252 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1253 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1254 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1255 << SomeDecl << NTK << Kind;
1256 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1257 break;
1258 }
1259 default:
1260 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1261 << Kind << Id << DC << QualifierLoc.getSourceRange();
1262 break;
1263 }
1264 return QualType();
1265 }
1266 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1267 NewTagLoc: IdLoc, Name: Id)) {
1268 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1269 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1270 return QualType();
1271 }
1272 return getDerived().RebuildTagType(
1273 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1274 }
1275
1276 /// Build a new pack expansion type.
1277 ///
1278 /// By default, builds a new PackExpansionType type from the given pattern.
1279 /// Subclasses may override this routine to provide different behavior.
1280 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1281 SourceLocation EllipsisLoc,
1282 UnsignedOrNone NumExpansions) {
1283 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1284 NumExpansions);
1285 }
1286
1287 /// Build a new atomic type given its value type.
1288 ///
1289 /// By default, performs semantic analysis when building the atomic type.
1290 /// Subclasses may override this routine to provide different behavior.
1291 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1292
1293 /// Build a new pipe type given its value type.
1294 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1295 bool isReadPipe);
1296
1297 /// Build a bit-precise int given its value type.
1298 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1299 SourceLocation Loc);
1300
1301 /// Build a dependent bit-precise int given its value type.
1302 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1303 SourceLocation Loc);
1304
1305 /// Build a new template name given a nested name specifier, a flag
1306 /// indicating whether the "template" keyword was provided, and the template
1307 /// that the template name refers to.
1308 ///
1309 /// By default, builds the new template name directly. Subclasses may override
1310 /// this routine to provide different behavior.
1311 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1312 TemplateName Name);
1313
1314 /// Build a new template name given a nested name specifier and the
1315 /// name that is referred to as a template.
1316 ///
1317 /// By default, performs semantic analysis to determine whether the name can
1318 /// be resolved to a specific template, then builds the appropriate kind of
1319 /// template name. Subclasses may override this routine to provide different
1320 /// behavior.
1321 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1322 SourceLocation TemplateKWLoc,
1323 const IdentifierInfo &Name,
1324 SourceLocation NameLoc, QualType ObjectType,
1325 bool AllowInjectedClassName);
1326
1327 /// Build a new template name given a nested name specifier and the
1328 /// overloaded operator name that is referred to as a template.
1329 ///
1330 /// By default, performs semantic analysis to determine whether the name can
1331 /// be resolved to a specific template, then builds the appropriate kind of
1332 /// template name. Subclasses may override this routine to provide different
1333 /// behavior.
1334 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1335 SourceLocation TemplateKWLoc,
1336 OverloadedOperatorKind Operator,
1337 SourceLocation NameLoc, QualType ObjectType,
1338 bool AllowInjectedClassName);
1339
1340 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1341 SourceLocation TemplateKWLoc,
1342 IdentifierOrOverloadedOperator IO,
1343 SourceLocation NameLoc, QualType ObjectType,
1344 bool AllowInjectedClassName);
1345
1346 /// Build a new template name given a template template parameter pack
1347 /// and the
1348 ///
1349 /// By default, performs semantic analysis to determine whether the name can
1350 /// be resolved to a specific template, then builds the appropriate kind of
1351 /// template name. Subclasses may override this routine to provide different
1352 /// behavior.
1353 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1354 Decl *AssociatedDecl, unsigned Index,
1355 bool Final) {
1356 return getSema().Context.getSubstTemplateTemplateParmPack(
1357 ArgPack, AssociatedDecl, Index, Final);
1358 }
1359
1360 /// Build a new pack-index-template-name ([temp.names]).
1361 ///
1362 /// By default, performs semantic analysis to build the new template name.
1363 /// Subclasses may override this routine to provide different behavior.
1364 TemplateName
1365 RebuildPackIndexingTemplateName(TemplateName Pattern, Expr *IndexExpr,
1366 bool FullySubstituted,
1367 ArrayRef<TemplateName> Expansions = {}) {
1368 return getSema().BuildPackIndexingTemplateName(
1369 Pattern, IndexExpr, FullySubstituted, Expansions);
1370 }
1371
1372 /// Build a new compound statement.
1373 ///
1374 /// By default, performs semantic analysis to build the new statement.
1375 /// Subclasses may override this routine to provide different behavior.
1376 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1377 MultiStmtArg Statements,
1378 SourceLocation RBraceLoc,
1379 bool IsStmtExpr) {
1380 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1381 IsStmtExpr);
1382 }
1383
1384 /// Build a new case statement.
1385 ///
1386 /// By default, performs semantic analysis to build the new statement.
1387 /// Subclasses may override this routine to provide different behavior.
1388 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1389 Expr *LHS,
1390 SourceLocation EllipsisLoc,
1391 Expr *RHS,
1392 SourceLocation ColonLoc) {
1393 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1394 ColonLoc);
1395 }
1396
1397 /// Attach the body to a new case statement.
1398 ///
1399 /// By default, performs semantic analysis to build the new statement.
1400 /// Subclasses may override this routine to provide different behavior.
1401 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1402 getSema().ActOnCaseStmtBody(S, Body);
1403 return S;
1404 }
1405
1406 /// Build a new default statement.
1407 ///
1408 /// By default, performs semantic analysis to build the new statement.
1409 /// Subclasses may override this routine to provide different behavior.
1410 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1411 SourceLocation ColonLoc,
1412 Stmt *SubStmt) {
1413 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1414 /*CurScope=*/nullptr);
1415 }
1416
1417 /// Build a new label statement.
1418 ///
1419 /// By default, performs semantic analysis to build the new statement.
1420 /// Subclasses may override this routine to provide different behavior.
1421 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1422 SourceLocation ColonLoc, Stmt *SubStmt) {
1423 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1424 }
1425
1426 /// Build a new attributed statement.
1427 ///
1428 /// By default, performs semantic analysis to build the new statement.
1429 /// Subclasses may override this routine to provide different behavior.
1430 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1431 ArrayRef<const Attr *> Attrs,
1432 Stmt *SubStmt) {
1433 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1434 return StmtError();
1435 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1436 }
1437
1438 /// Build a new "if" statement.
1439 ///
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
1442 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1443 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1444 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1445 SourceLocation ElseLoc, Stmt *Else) {
1446 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1447 Then, ElseLoc, Else);
1448 }
1449
1450 /// Start building a new switch statement.
1451 ///
1452 /// By default, performs semantic analysis to build the new statement.
1453 /// Subclasses may override this routine to provide different behavior.
1454 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1455 SourceLocation LParenLoc, Stmt *Init,
1456 Sema::ConditionResult Cond,
1457 SourceLocation RParenLoc) {
1458 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1459 RParenLoc);
1460 }
1461
1462 /// Attach the body to the switch statement.
1463 ///
1464 /// By default, performs semantic analysis to build the new statement.
1465 /// Subclasses may override this routine to provide different behavior.
1466 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1467 Stmt *Switch, Stmt *Body) {
1468 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1469 }
1470
1471 /// Build a new while statement.
1472 ///
1473 /// By default, performs semantic analysis to build the new statement.
1474 /// Subclasses may override this routine to provide different behavior.
1475 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1476 Sema::ConditionResult Cond,
1477 SourceLocation RParenLoc, Stmt *Body) {
1478 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1479 }
1480
1481 /// Build a new do-while statement.
1482 ///
1483 /// By default, performs semantic analysis to build the new statement.
1484 /// Subclasses may override this routine to provide different behavior.
1485 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1486 SourceLocation WhileLoc, SourceLocation LParenLoc,
1487 Expr *Cond, SourceLocation RParenLoc) {
1488 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1489 Cond, RParenLoc);
1490 }
1491
1492 /// Build a new for statement.
1493 ///
1494 /// By default, performs semantic analysis to build the new statement.
1495 /// Subclasses may override this routine to provide different behavior.
1496 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1497 Stmt *Init, Sema::ConditionResult Cond,
1498 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1499 Stmt *Body) {
1500 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1501 Inc, RParenLoc, Body);
1502 }
1503
1504 /// Build a new goto statement.
1505 ///
1506 /// By default, performs semantic analysis to build the new statement.
1507 /// Subclasses may override this routine to provide different behavior.
1508 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1509 LabelDecl *Label) {
1510 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1511 }
1512
1513 /// Build a new indirect goto statement.
1514 ///
1515 /// By default, performs semantic analysis to build the new statement.
1516 /// Subclasses may override this routine to provide different behavior.
1517 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1518 SourceLocation StarLoc,
1519 Expr *Target) {
1520 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1521 }
1522
1523 /// Build a new return statement.
1524 ///
1525 /// By default, performs semantic analysis to build the new statement.
1526 /// Subclasses may override this routine to provide different behavior.
1527 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1528 return getSema().BuildReturnStmt(ReturnLoc, Result);
1529 }
1530
1531 /// Build a new declaration statement.
1532 ///
1533 /// By default, performs semantic analysis to build the new statement.
1534 /// Subclasses may override this routine to provide different behavior.
1535 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1536 SourceLocation StartLoc, SourceLocation EndLoc) {
1537 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1538 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1539 }
1540
1541 /// Build a new inline asm statement.
1542 ///
1543 /// By default, performs semantic analysis to build the new statement.
1544 /// Subclasses may override this routine to provide different behavior.
1545 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1546 bool IsVolatile, unsigned NumOutputs,
1547 unsigned NumInputs, IdentifierInfo **Names,
1548 MultiExprArg Constraints, MultiExprArg Exprs,
1549 Expr *AsmString, MultiExprArg Clobbers,
1550 unsigned NumLabels,
1551 SourceLocation RParenLoc) {
1552 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1553 NumInputs, Names, Constraints, Exprs,
1554 AsmString, Clobbers, NumLabels, RParenLoc);
1555 }
1556
1557 /// Build a new MS style inline asm statement.
1558 ///
1559 /// By default, performs semantic analysis to build the new statement.
1560 /// Subclasses may override this routine to provide different behavior.
1561 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1562 ArrayRef<Token> AsmToks,
1563 StringRef AsmString,
1564 unsigned NumOutputs, unsigned NumInputs,
1565 ArrayRef<StringRef> Constraints,
1566 ArrayRef<StringRef> Clobbers,
1567 ArrayRef<Expr*> Exprs,
1568 SourceLocation EndLoc) {
1569 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1570 NumOutputs, NumInputs,
1571 Constraints, Clobbers, Exprs, EndLoc);
1572 }
1573
1574 /// Build a new co_return statement.
1575 ///
1576 /// By default, performs semantic analysis to build the new statement.
1577 /// Subclasses may override this routine to provide different behavior.
1578 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1579 bool IsImplicit) {
1580 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1581 }
1582
1583 /// Build a new co_await expression.
1584 ///
1585 /// By default, performs semantic analysis to build the new expression.
1586 /// Subclasses may override this routine to provide different behavior.
1587 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1588 UnresolvedLookupExpr *OpCoawaitLookup,
1589 bool IsImplicit) {
1590 // This function rebuilds a coawait-expr given its operator.
1591 // For an explicit coawait-expr, the rebuild involves the full set
1592 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1593 // including calling await_transform().
1594 // For an implicit coawait-expr, we need to rebuild the "operator
1595 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1596 // This mirrors how the implicit CoawaitExpr is originally created
1597 // in Sema::ActOnCoroutineBodyStart().
1598 if (IsImplicit) {
1599 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1600 CoawaitLoc, Operand, OpCoawaitLookup);
1601 if (Suspend.isInvalid())
1602 return ExprError();
1603 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1604 Suspend.get(), true);
1605 }
1606
1607 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1608 OpCoawaitLookup);
1609 }
1610
1611 /// Build a new co_await expression.
1612 ///
1613 /// By default, performs semantic analysis to build the new expression.
1614 /// Subclasses may override this routine to provide different behavior.
1615 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1616 Expr *Result,
1617 UnresolvedLookupExpr *Lookup) {
1618 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1619 }
1620
1621 /// Build a new co_yield expression.
1622 ///
1623 /// By default, performs semantic analysis to build the new expression.
1624 /// Subclasses may override this routine to provide different behavior.
1625 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1626 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1627 }
1628
1629 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1630 return getSema().BuildCoroutineBodyStmt(Args);
1631 }
1632
1633 /// Build a new Objective-C \@try statement.
1634 ///
1635 /// By default, performs semantic analysis to build the new statement.
1636 /// Subclasses may override this routine to provide different behavior.
1637 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1638 Stmt *TryBody,
1639 MultiStmtArg CatchStmts,
1640 Stmt *Finally) {
1641 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1642 Finally);
1643 }
1644
1645 /// Rebuild an Objective-C exception declaration.
1646 ///
1647 /// By default, performs semantic analysis to build the new declaration.
1648 /// Subclasses may override this routine to provide different behavior.
1649 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1650 TypeSourceInfo *TInfo, QualType T) {
1651 return getSema().ObjC().BuildObjCExceptionDecl(
1652 TInfo, T, ExceptionDecl->getInnerLocStart(),
1653 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1654 }
1655
1656 /// Build a new Objective-C \@catch statement.
1657 ///
1658 /// By default, performs semantic analysis to build the new statement.
1659 /// Subclasses may override this routine to provide different behavior.
1660 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1661 SourceLocation RParenLoc,
1662 VarDecl *Var,
1663 Stmt *Body) {
1664 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1665 }
1666
1667 /// Build a new Objective-C \@finally statement.
1668 ///
1669 /// By default, performs semantic analysis to build the new statement.
1670 /// Subclasses may override this routine to provide different behavior.
1671 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1672 Stmt *Body) {
1673 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1674 }
1675
1676 /// Build a new Objective-C \@throw statement.
1677 ///
1678 /// By default, performs semantic analysis to build the new statement.
1679 /// Subclasses may override this routine to provide different behavior.
1680 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1681 Expr *Operand) {
1682 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1683 }
1684
1685 /// Build a new OpenMP Canonical loop.
1686 ///
1687 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1688 /// OMPCanonicalLoop.
1689 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1690 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1691 }
1692
1693 /// Build a new OpenMP executable directive.
1694 ///
1695 /// By default, performs semantic analysis to build the new statement.
1696 /// Subclasses may override this routine to provide different behavior.
1697 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1698 DeclarationNameInfo DirName,
1699 OpenMPDirectiveKind CancelRegion,
1700 ArrayRef<OMPClause *> Clauses,
1701 Stmt *AStmt, SourceLocation StartLoc,
1702 SourceLocation EndLoc) {
1703
1704 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1705 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1706 }
1707
1708 /// Build a new OpenMP informational directive.
1709 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1710 DeclarationNameInfo DirName,
1711 ArrayRef<OMPClause *> Clauses,
1712 Stmt *AStmt,
1713 SourceLocation StartLoc,
1714 SourceLocation EndLoc) {
1715
1716 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1717 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1718 }
1719
1720 /// Build a new OpenMP 'if' clause.
1721 ///
1722 /// By default, performs semantic analysis to build the new OpenMP clause.
1723 /// Subclasses may override this routine to provide different behavior.
1724 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1725 Expr *Condition, SourceLocation StartLoc,
1726 SourceLocation LParenLoc,
1727 SourceLocation NameModifierLoc,
1728 SourceLocation ColonLoc,
1729 SourceLocation EndLoc) {
1730 return getSema().OpenMP().ActOnOpenMPIfClause(
1731 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1732 EndLoc);
1733 }
1734
1735 /// Build a new OpenMP 'final' clause.
1736 ///
1737 /// By default, performs semantic analysis to build the new OpenMP clause.
1738 /// Subclasses may override this routine to provide different behavior.
1739 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1740 SourceLocation LParenLoc,
1741 SourceLocation EndLoc) {
1742 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1743 LParenLoc, EndLoc);
1744 }
1745
1746 /// Build a new OpenMP 'num_threads' clause.
1747 ///
1748 /// By default, performs semantic analysis to build the new OpenMP clause.
1749 /// Subclasses may override this routine to provide different behavior.
1750 OMPClause *RebuildOMPNumThreadsClause(
1751 ArrayRef<Expr *> VarList,
1752 OpenMPNumThreadsClauseModifier PrescriptivenessModifier,
1753 SourceLocation PrescriptivenessModifierLoc,
1754 OpenMPNumThreadsClauseModifier DimsModifier, Expr *DimsModifierExpr,
1755 SourceLocation DimsModifierLoc, SourceLocation StartLoc,
1756 SourceLocation LParenLoc, SourceLocation EndLoc) {
1757 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1758 VarList, PrescriptivenessModifier, PrescriptivenessModifierLoc,
1759 DimsModifier, DimsModifierExpr, DimsModifierLoc, StartLoc, LParenLoc,
1760 EndLoc);
1761 }
1762
1763 /// Build a new OpenMP 'safelen' clause.
1764 ///
1765 /// By default, performs semantic analysis to build the new OpenMP clause.
1766 /// Subclasses may override this routine to provide different behavior.
1767 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1768 SourceLocation LParenLoc,
1769 SourceLocation EndLoc) {
1770 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1771 EndLoc);
1772 }
1773
1774 /// Build a new OpenMP 'simdlen' clause.
1775 ///
1776 /// By default, performs semantic analysis to build the new OpenMP clause.
1777 /// Subclasses may override this routine to provide different behavior.
1778 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1779 SourceLocation LParenLoc,
1780 SourceLocation EndLoc) {
1781 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1782 EndLoc);
1783 }
1784
1785 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1786 SourceLocation StartLoc,
1787 SourceLocation LParenLoc,
1788 SourceLocation EndLoc) {
1789 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1790 EndLoc);
1791 }
1792
1793 OMPClause *RebuildOMPCountsClause(ArrayRef<Expr *> Counts,
1794 SourceLocation StartLoc,
1795 SourceLocation LParenLoc,
1796 SourceLocation EndLoc,
1797 std::optional<unsigned> FillIdx,
1798 SourceLocation FillLoc) {
1799 unsigned FillCount = FillIdx ? 1 : 0;
1800 return getSema().OpenMP().ActOnOpenMPCountsClause(
1801 Counts, StartLoc, LParenLoc, EndLoc, FillIdx, FillLoc, FillCount);
1802 }
1803
1804 /// Build a new OpenMP 'permutation' clause.
1805 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1806 SourceLocation StartLoc,
1807 SourceLocation LParenLoc,
1808 SourceLocation EndLoc) {
1809 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1810 LParenLoc, EndLoc);
1811 }
1812
1813 /// Build a new OpenMP 'full' clause.
1814 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1815 SourceLocation EndLoc) {
1816 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1817 }
1818
1819 /// Build a new OpenMP 'partial' clause.
1820 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1821 SourceLocation LParenLoc,
1822 SourceLocation EndLoc) {
1823 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1824 LParenLoc, EndLoc);
1825 }
1826
1827 OMPClause *
1828 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1829 SourceLocation LParenLoc, SourceLocation FirstLoc,
1830 SourceLocation CountLoc, SourceLocation EndLoc) {
1831 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1832 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1833 }
1834
1835 /// Build a new OpenMP 'allocator' clause.
1836 ///
1837 /// By default, performs semantic analysis to build the new OpenMP clause.
1838 /// Subclasses may override this routine to provide different behavior.
1839 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1840 SourceLocation LParenLoc,
1841 SourceLocation EndLoc) {
1842 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1843 EndLoc);
1844 }
1845
1846 /// Build a new OpenMP 'collapse' clause.
1847 ///
1848 /// By default, performs semantic analysis to build the new OpenMP clause.
1849 /// Subclasses may override this routine to provide different behavior.
1850 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1851 SourceLocation LParenLoc,
1852 SourceLocation EndLoc) {
1853 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1854 LParenLoc, EndLoc);
1855 }
1856
1857 /// Build a new OpenMP 'default' clause.
1858 ///
1859 /// By default, performs semantic analysis to build the new OpenMP clause.
1860 /// Subclasses may override this routine to provide different behavior.
1861 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1862 OpenMPDefaultClauseVariableCategory VCKind,
1863 SourceLocation VCLoc,
1864 SourceLocation StartLoc,
1865 SourceLocation LParenLoc,
1866 SourceLocation EndLoc) {
1867 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1868 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1869 }
1870
1871 /// Build a new OpenMP 'proc_bind' clause.
1872 ///
1873 /// By default, performs semantic analysis to build the new OpenMP clause.
1874 /// Subclasses may override this routine to provide different behavior.
1875 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1876 SourceLocation KindKwLoc,
1877 SourceLocation StartLoc,
1878 SourceLocation LParenLoc,
1879 SourceLocation EndLoc) {
1880 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1881 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1882 }
1883 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1884 SourceLocation StartLoc,
1885 SourceLocation LParenLoc,
1886 SourceLocation EndLoc) {
1887 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1888 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1889 }
1890
1891 /// Build a new OpenMP 'schedule' clause.
1892 ///
1893 /// By default, performs semantic analysis to build the new OpenMP clause.
1894 /// Subclasses may override this routine to provide different behavior.
1895 OMPClause *RebuildOMPScheduleClause(
1896 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1897 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1898 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1899 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1900 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1901 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1902 CommaLoc, EndLoc);
1903 }
1904
1905 /// Build a new OpenMP 'ordered' clause.
1906 ///
1907 /// By default, performs semantic analysis to build the new OpenMP clause.
1908 /// Subclasses may override this routine to provide different behavior.
1909 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1910 SourceLocation EndLoc,
1911 SourceLocation LParenLoc, Expr *Num) {
1912 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1913 LParenLoc, Num);
1914 }
1915
1916 /// Build a new OpenMP 'nowait' clause.
1917 ///
1918 /// By default, performs semantic analysis to build the new OpenMP clause.
1919 /// Subclasses may override this routine to provide different behavior.
1920 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1921 SourceLocation LParenLoc,
1922 SourceLocation EndLoc) {
1923 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1924 LParenLoc, Condition);
1925 }
1926
1927 /// Build a new OpenMP 'private' clause.
1928 ///
1929 /// By default, performs semantic analysis to build the new OpenMP clause.
1930 /// Subclasses may override this routine to provide different behavior.
1931 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1932 SourceLocation StartLoc,
1933 SourceLocation LParenLoc,
1934 SourceLocation EndLoc) {
1935 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1936 LParenLoc, EndLoc);
1937 }
1938
1939 /// Build a new OpenMP 'firstprivate' clause.
1940 ///
1941 /// By default, performs semantic analysis to build the new OpenMP clause.
1942 /// Subclasses may override this routine to provide different behavior.
1943 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1944 SourceLocation StartLoc,
1945 SourceLocation LParenLoc,
1946 SourceLocation EndLoc) {
1947 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1948 LParenLoc, EndLoc);
1949 }
1950
1951 /// Build a new OpenMP 'lastprivate' clause.
1952 ///
1953 /// By default, performs semantic analysis to build the new OpenMP clause.
1954 /// Subclasses may override this routine to provide different behavior.
1955 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1956 OpenMPLastprivateModifier LPKind,
1957 SourceLocation LPKindLoc,
1958 SourceLocation ColonLoc,
1959 SourceLocation StartLoc,
1960 SourceLocation LParenLoc,
1961 SourceLocation EndLoc) {
1962 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1963 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1964 }
1965
1966 /// Build a new OpenMP 'shared' clause.
1967 ///
1968 /// By default, performs semantic analysis to build the new OpenMP clause.
1969 /// Subclasses may override this routine to provide different behavior.
1970 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1971 SourceLocation StartLoc,
1972 SourceLocation LParenLoc,
1973 SourceLocation EndLoc) {
1974 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1975 LParenLoc, EndLoc);
1976 }
1977
1978 /// Build a new OpenMP 'reduction' clause.
1979 ///
1980 /// By default, performs semantic analysis to build the new statement.
1981 /// Subclasses may override this routine to provide different behavior.
1982 OMPClause *RebuildOMPReductionClause(
1983 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1984 OpenMPOriginalSharingModifier OriginalSharingModifier,
1985 SourceLocation StartLoc, SourceLocation LParenLoc,
1986 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1987 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1988 const DeclarationNameInfo &ReductionId,
1989 ArrayRef<Expr *> UnresolvedReductions) {
1990 return getSema().OpenMP().ActOnOpenMPReductionClause(
1991 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1992 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1993 UnresolvedReductions);
1994 }
1995
1996 /// Build a new OpenMP 'task_reduction' clause.
1997 ///
1998 /// By default, performs semantic analysis to build the new statement.
1999 /// Subclasses may override this routine to provide different behavior.
2000 OMPClause *RebuildOMPTaskReductionClause(
2001 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2002 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
2003 CXXScopeSpec &ReductionIdScopeSpec,
2004 const DeclarationNameInfo &ReductionId,
2005 ArrayRef<Expr *> UnresolvedReductions) {
2006 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
2007 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2008 ReductionId, UnresolvedReductions);
2009 }
2010
2011 /// Build a new OpenMP 'in_reduction' clause.
2012 ///
2013 /// By default, performs semantic analysis to build the new statement.
2014 /// Subclasses may override this routine to provide different behavior.
2015 OMPClause *
2016 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2017 SourceLocation LParenLoc, SourceLocation ColonLoc,
2018 SourceLocation EndLoc,
2019 CXXScopeSpec &ReductionIdScopeSpec,
2020 const DeclarationNameInfo &ReductionId,
2021 ArrayRef<Expr *> UnresolvedReductions) {
2022 return getSema().OpenMP().ActOnOpenMPInReductionClause(
2023 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2024 ReductionId, UnresolvedReductions);
2025 }
2026
2027 /// Build a new OpenMP 'linear' clause.
2028 ///
2029 /// By default, performs semantic analysis to build the new OpenMP clause.
2030 /// Subclasses may override this routine to provide different behavior.
2031 OMPClause *RebuildOMPLinearClause(
2032 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2033 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2034 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2035 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2036 return getSema().OpenMP().ActOnOpenMPLinearClause(
2037 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2038 StepModifierLoc, EndLoc);
2039 }
2040
2041 /// Build a new OpenMP 'aligned' clause.
2042 ///
2043 /// By default, performs semantic analysis to build the new OpenMP clause.
2044 /// Subclasses may override this routine to provide different behavior.
2045 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2046 SourceLocation StartLoc,
2047 SourceLocation LParenLoc,
2048 SourceLocation ColonLoc,
2049 SourceLocation EndLoc) {
2050 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2051 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2052 }
2053
2054 /// Build a new OpenMP 'copyin' clause.
2055 ///
2056 /// By default, performs semantic analysis to build the new OpenMP clause.
2057 /// Subclasses may override this routine to provide different behavior.
2058 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2059 SourceLocation StartLoc,
2060 SourceLocation LParenLoc,
2061 SourceLocation EndLoc) {
2062 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2063 LParenLoc, EndLoc);
2064 }
2065
2066 /// Build a new OpenMP 'copyprivate' clause.
2067 ///
2068 /// By default, performs semantic analysis to build the new OpenMP clause.
2069 /// Subclasses may override this routine to provide different behavior.
2070 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2071 SourceLocation StartLoc,
2072 SourceLocation LParenLoc,
2073 SourceLocation EndLoc) {
2074 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2075 LParenLoc, EndLoc);
2076 }
2077
2078 /// Build a new OpenMP 'flush' pseudo clause.
2079 ///
2080 /// By default, performs semantic analysis to build the new OpenMP clause.
2081 /// Subclasses may override this routine to provide different behavior.
2082 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2083 SourceLocation StartLoc,
2084 SourceLocation LParenLoc,
2085 SourceLocation EndLoc) {
2086 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2087 LParenLoc, EndLoc);
2088 }
2089
2090 /// Build a new OpenMP 'depobj' pseudo clause.
2091 ///
2092 /// By default, performs semantic analysis to build the new OpenMP clause.
2093 /// Subclasses may override this routine to provide different behavior.
2094 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2095 SourceLocation LParenLoc,
2096 SourceLocation EndLoc) {
2097 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2098 LParenLoc, EndLoc);
2099 }
2100
2101 /// Build a new OpenMP 'depend' pseudo clause.
2102 ///
2103 /// By default, performs semantic analysis to build the new OpenMP clause.
2104 /// Subclasses may override this routine to provide different behavior.
2105 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2106 Expr *DepModifier, ArrayRef<Expr *> VarList,
2107 SourceLocation StartLoc,
2108 SourceLocation LParenLoc,
2109 SourceLocation EndLoc) {
2110 return getSema().OpenMP().ActOnOpenMPDependClause(
2111 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2112 }
2113
2114 /// Build a new OpenMP 'device' clause.
2115 ///
2116 /// By default, performs semantic analysis to build the new statement.
2117 /// Subclasses may override this routine to provide different behavior.
2118 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2119 Expr *Device, SourceLocation StartLoc,
2120 SourceLocation LParenLoc,
2121 SourceLocation ModifierLoc,
2122 SourceLocation EndLoc) {
2123 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2124 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2125 }
2126
2127 /// Build a new OpenMP 'map' clause.
2128 ///
2129 /// By default, performs semantic analysis to build the new OpenMP clause.
2130 /// Subclasses may override this routine to provide different behavior.
2131 OMPClause *RebuildOMPMapClause(
2132 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2133 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2134 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2135 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2136 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2137 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2138 return getSema().OpenMP().ActOnOpenMPMapClause(
2139 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2140 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2141 ColonLoc, VarList, Locs,
2142 /*NoDiagnose=*/false, UnresolvedMappers);
2143 }
2144
2145 /// Build a new OpenMP 'allocate' clause.
2146 ///
2147 /// By default, performs semantic analysis to build the new OpenMP clause.
2148 /// Subclasses may override this routine to provide different behavior.
2149 OMPClause *
2150 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2151 OpenMPAllocateClauseModifier FirstModifier,
2152 SourceLocation FirstModifierLoc,
2153 OpenMPAllocateClauseModifier SecondModifier,
2154 SourceLocation SecondModifierLoc,
2155 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2156 SourceLocation LParenLoc, SourceLocation ColonLoc,
2157 SourceLocation EndLoc) {
2158 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2159 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2160 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2161 }
2162
2163 /// Build a new OpenMP 'num_teams' clause.
2164 ///
2165 /// By default, performs semantic analysis to build the new statement.
2166 /// Subclasses may override this routine to provide different behavior.
2167 OMPClause *RebuildOMPNumTeamsClause(
2168 ArrayRef<Expr *> VarList, OpenMPNumTeamsClauseModifier Modifier,
2169 Expr *ModifierExpr, SourceLocation ModifierLoc,
2170 OpenMPNumTeamsClauseModifier ModifierExtra, Expr *ModifierExtraExpr,
2171 SourceLocation ModifierExtraLoc, SourceLocation StartLoc,
2172 SourceLocation LParenLoc, SourceLocation EndLoc) {
2173 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(
2174 VarList, Modifier, ModifierExpr, ModifierLoc, ModifierExtra,
2175 ModifierExtraExpr, ModifierExtraLoc, StartLoc, LParenLoc, EndLoc);
2176 }
2177
2178 /// Build a new OpenMP 'thread_limit' clause.
2179 ///
2180 /// By default, performs semantic analysis to build the new statement.
2181 /// Subclasses may override this routine to provide different behavior.
2182 OMPClause *RebuildOMPThreadLimitClause(
2183 ArrayRef<Expr *> VarList, OpenMPThreadLimitClauseModifier Modifier,
2184 Expr *ModifierExpr, SourceLocation ModifierLoc, SourceLocation StartLoc,
2185 SourceLocation LParenLoc, SourceLocation EndLoc) {
2186 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(
2187 VarList, Modifier, ModifierExpr, ModifierLoc, StartLoc, LParenLoc,
2188 EndLoc);
2189 }
2190
2191 /// Build a new OpenMP 'priority' clause.
2192 ///
2193 /// By default, performs semantic analysis to build the new statement.
2194 /// Subclasses may override this routine to provide different behavior.
2195 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2196 SourceLocation LParenLoc,
2197 SourceLocation EndLoc) {
2198 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2199 LParenLoc, EndLoc);
2200 }
2201
2202 /// Build a new OpenMP 'grainsize' clause.
2203 ///
2204 /// By default, performs semantic analysis to build the new statement.
2205 /// Subclasses may override this routine to provide different behavior.
2206 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2207 Expr *Device, SourceLocation StartLoc,
2208 SourceLocation LParenLoc,
2209 SourceLocation ModifierLoc,
2210 SourceLocation EndLoc) {
2211 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2212 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2213 }
2214
2215 /// Build a new OpenMP 'num_tasks' clause.
2216 ///
2217 /// By default, performs semantic analysis to build the new statement.
2218 /// Subclasses may override this routine to provide different behavior.
2219 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2220 Expr *NumTasks, SourceLocation StartLoc,
2221 SourceLocation LParenLoc,
2222 SourceLocation ModifierLoc,
2223 SourceLocation EndLoc) {
2224 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2225 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2226 }
2227
2228 /// Build a new OpenMP 'hint' clause.
2229 ///
2230 /// By default, performs semantic analysis to build the new statement.
2231 /// Subclasses may override this routine to provide different behavior.
2232 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2233 SourceLocation LParenLoc,
2234 SourceLocation EndLoc) {
2235 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2236 EndLoc);
2237 }
2238
2239 /// Build a new OpenMP 'detach' clause.
2240 ///
2241 /// By default, performs semantic analysis to build the new statement.
2242 /// Subclasses may override this routine to provide different behavior.
2243 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2244 SourceLocation LParenLoc,
2245 SourceLocation EndLoc) {
2246 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2247 EndLoc);
2248 }
2249
2250 /// Build a new OpenMP 'dist_schedule' clause.
2251 ///
2252 /// By default, performs semantic analysis to build the new OpenMP clause.
2253 /// Subclasses may override this routine to provide different behavior.
2254 OMPClause *
2255 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2256 Expr *ChunkSize, SourceLocation StartLoc,
2257 SourceLocation LParenLoc, SourceLocation KindLoc,
2258 SourceLocation CommaLoc, SourceLocation EndLoc) {
2259 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2260 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2261 }
2262
2263 /// Build a new OpenMP 'to' clause.
2264 ///
2265 /// By default, performs semantic analysis to build the new statement.
2266 /// Subclasses may override this routine to provide different behavior.
2267 OMPClause *
2268 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2269 ArrayRef<SourceLocation> MotionModifiersLoc,
2270 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2271 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2272 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2273 ArrayRef<Expr *> UnresolvedMappers) {
2274 return getSema().OpenMP().ActOnOpenMPToClause(
2275 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2276 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2277 UnresolvedMappers);
2278 }
2279
2280 /// Build a new OpenMP 'from' clause.
2281 ///
2282 /// By default, performs semantic analysis to build the new statement.
2283 /// Subclasses may override this routine to provide different behavior.
2284 OMPClause *
2285 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2286 ArrayRef<SourceLocation> MotionModifiersLoc,
2287 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2288 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2289 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2290 ArrayRef<Expr *> UnresolvedMappers) {
2291 return getSema().OpenMP().ActOnOpenMPFromClause(
2292 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2293 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2294 UnresolvedMappers);
2295 }
2296
2297 /// Build a new OpenMP 'use_device_ptr' clause.
2298 ///
2299 /// By default, performs semantic analysis to build the new OpenMP clause.
2300 /// Subclasses may override this routine to provide different behavior.
2301 OMPClause *RebuildOMPUseDevicePtrClause(
2302 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2303 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2304 SourceLocation FallbackModifierLoc) {
2305 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2306 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2307 }
2308
2309 /// Build a new OpenMP 'use_device_addr' clause.
2310 ///
2311 /// By default, performs semantic analysis to build the new OpenMP clause.
2312 /// Subclasses may override this routine to provide different behavior.
2313 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2314 const OMPVarListLocTy &Locs) {
2315 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2316 }
2317
2318 /// Build a new OpenMP 'is_device_ptr' 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 *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2323 const OMPVarListLocTy &Locs) {
2324 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2325 }
2326
2327 /// Build a new OpenMP 'has_device_addr' 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 *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2332 const OMPVarListLocTy &Locs) {
2333 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2334 }
2335
2336 /// Build a new OpenMP 'defaultmap' 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 *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2341 OpenMPDefaultmapClauseKind Kind,
2342 SourceLocation StartLoc,
2343 SourceLocation LParenLoc,
2344 SourceLocation MLoc,
2345 SourceLocation KindLoc,
2346 SourceLocation EndLoc) {
2347 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2348 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2349 }
2350
2351 /// Build a new OpenMP 'nontemporal' clause.
2352 ///
2353 /// By default, performs semantic analysis to build the new OpenMP clause.
2354 /// Subclasses may override this routine to provide different behavior.
2355 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2356 SourceLocation StartLoc,
2357 SourceLocation LParenLoc,
2358 SourceLocation EndLoc) {
2359 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2360 LParenLoc, EndLoc);
2361 }
2362
2363 /// Build a new OpenMP 'inclusive' clause.
2364 ///
2365 /// By default, performs semantic analysis to build the new OpenMP clause.
2366 /// Subclasses may override this routine to provide different behavior.
2367 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2368 SourceLocation StartLoc,
2369 SourceLocation LParenLoc,
2370 SourceLocation EndLoc) {
2371 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2372 LParenLoc, EndLoc);
2373 }
2374
2375 /// Build a new OpenMP 'exclusive' clause.
2376 ///
2377 /// By default, performs semantic analysis to build the new OpenMP clause.
2378 /// Subclasses may override this routine to provide different behavior.
2379 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2380 SourceLocation StartLoc,
2381 SourceLocation LParenLoc,
2382 SourceLocation EndLoc) {
2383 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2384 LParenLoc, EndLoc);
2385 }
2386
2387 /// Build a new OpenMP 'uses_allocators' clause.
2388 ///
2389 /// By default, performs semantic analysis to build the new OpenMP clause.
2390 /// Subclasses may override this routine to provide different behavior.
2391 OMPClause *RebuildOMPUsesAllocatorsClause(
2392 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2393 SourceLocation LParenLoc, SourceLocation EndLoc) {
2394 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2395 StartLoc, LParenLoc, EndLoc, Data);
2396 }
2397
2398 /// Build a new OpenMP 'affinity' clause.
2399 ///
2400 /// By default, performs semantic analysis to build the new OpenMP clause.
2401 /// Subclasses may override this routine to provide different behavior.
2402 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2403 SourceLocation LParenLoc,
2404 SourceLocation ColonLoc,
2405 SourceLocation EndLoc, Expr *Modifier,
2406 ArrayRef<Expr *> Locators) {
2407 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2408 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2409 }
2410
2411 /// Build a new OpenMP 'order' clause.
2412 ///
2413 /// By default, performs semantic analysis to build the new OpenMP clause.
2414 /// Subclasses may override this routine to provide different behavior.
2415 OMPClause *RebuildOMPOrderClause(
2416 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2417 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2418 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2419 return getSema().OpenMP().ActOnOpenMPOrderClause(
2420 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2421 }
2422
2423 /// Build a new OpenMP 'init' clause.
2424 ///
2425 /// By default, performs semantic analysis to build the new OpenMP clause.
2426 /// Subclasses may override this routine to provide different behavior.
2427 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2428 SourceLocation StartLoc,
2429 SourceLocation LParenLoc,
2430 SourceLocation VarLoc,
2431 SourceLocation EndLoc) {
2432 return getSema().OpenMP().ActOnOpenMPInitClause(
2433 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2434 }
2435
2436 /// Build a new OpenMP 'use' clause.
2437 ///
2438 /// By default, performs semantic analysis to build the new OpenMP clause.
2439 /// Subclasses may override this routine to provide different behavior.
2440 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2441 SourceLocation LParenLoc,
2442 SourceLocation VarLoc, SourceLocation EndLoc) {
2443 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2444 LParenLoc, VarLoc, EndLoc);
2445 }
2446
2447 /// Build a new OpenMP 'destroy' clause.
2448 ///
2449 /// By default, performs semantic analysis to build the new OpenMP clause.
2450 /// Subclasses may override this routine to provide different behavior.
2451 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2452 SourceLocation LParenLoc,
2453 SourceLocation VarLoc,
2454 SourceLocation EndLoc) {
2455 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2456 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2457 }
2458
2459 /// Build a new OpenMP 'novariants' clause.
2460 ///
2461 /// By default, performs semantic analysis to build the new OpenMP clause.
2462 /// Subclasses may override this routine to provide different behavior.
2463 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2464 SourceLocation StartLoc,
2465 SourceLocation LParenLoc,
2466 SourceLocation EndLoc) {
2467 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2468 LParenLoc, EndLoc);
2469 }
2470
2471 /// Build a new OpenMP 'nocontext' clause.
2472 ///
2473 /// By default, performs semantic analysis to build the new OpenMP clause.
2474 /// Subclasses may override this routine to provide different behavior.
2475 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2476 SourceLocation LParenLoc,
2477 SourceLocation EndLoc) {
2478 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2479 LParenLoc, EndLoc);
2480 }
2481
2482 /// Build a new OpenMP 'filter' clause.
2483 ///
2484 /// By default, performs semantic analysis to build the new OpenMP clause.
2485 /// Subclasses may override this routine to provide different behavior.
2486 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2487 SourceLocation LParenLoc,
2488 SourceLocation EndLoc) {
2489 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2490 LParenLoc, EndLoc);
2491 }
2492
2493 /// Build a new OpenMP 'bind' clause.
2494 ///
2495 /// By default, performs semantic analysis to build the new OpenMP clause.
2496 /// Subclasses may override this routine to provide different behavior.
2497 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2498 SourceLocation KindLoc,
2499 SourceLocation StartLoc,
2500 SourceLocation LParenLoc,
2501 SourceLocation EndLoc) {
2502 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2503 LParenLoc, EndLoc);
2504 }
2505
2506 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2507 ///
2508 /// By default, performs semantic analysis to build the new OpenMP clause.
2509 /// Subclasses may override this routine to provide different behavior.
2510 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2511 SourceLocation LParenLoc,
2512 SourceLocation EndLoc) {
2513 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2514 LParenLoc, EndLoc);
2515 }
2516
2517 /// Build a new OpenMP 'dyn_groupprivate' clause.
2518 ///
2519 /// By default, performs semantic analysis to build the new OpenMP clause.
2520 /// Subclasses may override this routine to provide different behavior.
2521 OMPClause *RebuildOMPDynGroupprivateClause(
2522 OpenMPDynGroupprivateClauseModifier M1,
2523 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2524 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2525 SourceLocation M2Loc, SourceLocation EndLoc) {
2526 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2527 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2528 }
2529
2530 /// Build a new OpenMP 'ompx_attribute' clause.
2531 ///
2532 /// By default, performs semantic analysis to build the new OpenMP clause.
2533 /// Subclasses may override this routine to provide different behavior.
2534 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2535 SourceLocation StartLoc,
2536 SourceLocation LParenLoc,
2537 SourceLocation EndLoc) {
2538 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2539 LParenLoc, EndLoc);
2540 }
2541
2542 /// Build a new OpenMP 'ompx_bare' clause.
2543 ///
2544 /// By default, performs semantic analysis to build the new OpenMP clause.
2545 /// Subclasses may override this routine to provide different behavior.
2546 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2547 SourceLocation EndLoc) {
2548 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2549 }
2550
2551 /// Build a new OpenMP 'align' 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 *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2556 SourceLocation LParenLoc,
2557 SourceLocation EndLoc) {
2558 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2559 EndLoc);
2560 }
2561
2562 /// Build a new OpenMP 'at' clause.
2563 ///
2564 /// By default, performs semantic analysis to build the new OpenMP clause.
2565 /// Subclasses may override this routine to provide different behavior.
2566 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2567 SourceLocation StartLoc,
2568 SourceLocation LParenLoc,
2569 SourceLocation EndLoc) {
2570 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2571 LParenLoc, EndLoc);
2572 }
2573
2574 /// Build a new OpenMP 'severity' clause.
2575 ///
2576 /// By default, performs semantic analysis to build the new OpenMP clause.
2577 /// Subclasses may override this routine to provide different behavior.
2578 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2579 SourceLocation KwLoc,
2580 SourceLocation StartLoc,
2581 SourceLocation LParenLoc,
2582 SourceLocation EndLoc) {
2583 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2584 LParenLoc, EndLoc);
2585 }
2586
2587 /// Build a new OpenMP 'message' clause.
2588 ///
2589 /// By default, performs semantic analysis to build the new OpenMP clause.
2590 /// Subclasses may override this routine to provide different behavior.
2591 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2592 SourceLocation LParenLoc,
2593 SourceLocation EndLoc) {
2594 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2595 EndLoc);
2596 }
2597
2598 /// Build a new OpenMP 'doacross' clause.
2599 ///
2600 /// By default, performs semantic analysis to build the new OpenMP clause.
2601 /// Subclasses may override this routine to provide different behavior.
2602 OMPClause *
2603 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2604 SourceLocation DepLoc, SourceLocation ColonLoc,
2605 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2606 SourceLocation LParenLoc, SourceLocation EndLoc) {
2607 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2608 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2609 }
2610
2611 /// Build a new OpenMP 'holds' clause.
2612 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2613 SourceLocation LParenLoc,
2614 SourceLocation EndLoc) {
2615 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2616 EndLoc);
2617 }
2618
2619 /// Rebuild the operand to an Objective-C \@synchronized statement.
2620 ///
2621 /// By default, performs semantic analysis to build the new statement.
2622 /// Subclasses may override this routine to provide different behavior.
2623 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2624 Expr *object) {
2625 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2626 }
2627
2628 /// Build a new 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 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2633 Expr *Object, Stmt *Body) {
2634 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2635 }
2636
2637 /// Build a new Objective-C \@autoreleasepool 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 RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2642 Stmt *Body) {
2643 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2644 }
2645
2646 /// Build a new Objective-C fast enumeration 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 RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2651 Stmt *Element,
2652 Expr *Collection,
2653 SourceLocation RParenLoc,
2654 Stmt *Body) {
2655 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2656 ForLoc, Element, Collection, RParenLoc);
2657 if (ForEachStmt.isInvalid())
2658 return StmtError();
2659
2660 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2661 Body);
2662 }
2663
2664 /// Build a new C++ exception declaration.
2665 ///
2666 /// By default, performs semantic analysis to build the new decaration.
2667 /// Subclasses may override this routine to provide different behavior.
2668 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2669 TypeSourceInfo *Declarator,
2670 SourceLocation StartLoc,
2671 SourceLocation IdLoc,
2672 IdentifierInfo *Id) {
2673 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2674 StartLoc, IdLoc, Id);
2675 if (Var)
2676 getSema().CurContext->addDecl(Var);
2677 return Var;
2678 }
2679
2680 /// Build a new C++ catch statement.
2681 ///
2682 /// By default, performs semantic analysis to build the new statement.
2683 /// Subclasses may override this routine to provide different behavior.
2684 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2685 VarDecl *ExceptionDecl,
2686 Stmt *Handler) {
2687 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2688 Handler));
2689 }
2690
2691 /// Build a new C++ try statement.
2692 ///
2693 /// By default, performs semantic analysis to build the new statement.
2694 /// Subclasses may override this routine to provide different behavior.
2695 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2696 ArrayRef<Stmt *> Handlers) {
2697 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2698 }
2699
2700 /// Build a new C++0x range-based for 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 RebuildCXXForRangeStmt(
2705 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2706 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2707 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2708 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2709 // If we've just learned that the range is actually an Objective-C
2710 // collection, treat this as an Objective-C fast enumeration loop.
2711 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2712 if (RangeStmt->isSingleDecl()) {
2713 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2714 if (RangeVar->isInvalidDecl())
2715 return StmtError();
2716
2717 Expr *RangeExpr = RangeVar->getInit();
2718 if (!RangeExpr->isTypeDependent() &&
2719 RangeExpr->getType()->isObjCObjectPointerType()) {
2720 // FIXME: Support init-statements in Objective-C++20 ranged for
2721 // statement.
2722 if (Init) {
2723 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2724 DiagID: diag::err_objc_for_range_init_stmt)
2725 << Init->getSourceRange();
2726 }
2727 return getSema().ObjC().ActOnObjCForCollectionStmt(
2728 ForLoc, LoopVar, RangeExpr, RParenLoc);
2729 }
2730 }
2731 }
2732 }
2733
2734 return getSema().BuildCXXForRangeStmt(
2735 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2736 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2737 }
2738
2739 /// Build a new C++0x range-based for statement.
2740 ///
2741 /// By default, performs semantic analysis to build the new statement.
2742 /// Subclasses may override this routine to provide different behavior.
2743 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2744 bool IsIfExists,
2745 NestedNameSpecifierLoc QualifierLoc,
2746 DeclarationNameInfo NameInfo,
2747 Stmt *Nested) {
2748 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2749 QualifierLoc, NameInfo, Nested);
2750 }
2751
2752 /// Attach body to a C++0x range-based for statement.
2753 ///
2754 /// By default, performs semantic analysis to finish the new statement.
2755 /// Subclasses may override this routine to provide different behavior.
2756 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2757 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2758 }
2759
2760 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2761 Stmt *TryBlock, Stmt *Handler) {
2762 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2763 }
2764
2765 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2766 Stmt *Block) {
2767 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2768 }
2769
2770 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2771 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2772 }
2773
2774 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2775 SourceLocation LParen,
2776 SourceLocation RParen,
2777 TypeSourceInfo *TSI) {
2778 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2779 TSI);
2780 }
2781
2782 /// Build a new predefined expression.
2783 ///
2784 /// By default, performs semantic analysis to build the new expression.
2785 /// Subclasses may override this routine to provide different behavior.
2786 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2787 return getSema().BuildPredefinedExpr(Loc, IK);
2788 }
2789
2790 /// Build a new expression that references a declaration.
2791 ///
2792 /// By default, performs semantic analysis to build the new expression.
2793 /// Subclasses may override this routine to provide different behavior.
2794 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2795 LookupResult &R,
2796 bool RequiresADL) {
2797 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2798 }
2799
2800
2801 /// Build a new expression that references a declaration.
2802 ///
2803 /// By default, performs semantic analysis to build the new expression.
2804 /// Subclasses may override this routine to provide different behavior.
2805 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2806 ValueDecl *VD,
2807 const DeclarationNameInfo &NameInfo,
2808 NamedDecl *Found,
2809 TemplateArgumentListInfo *TemplateArgs) {
2810 CXXScopeSpec SS;
2811 SS.Adopt(Other: QualifierLoc);
2812 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2813 TemplateArgs);
2814 }
2815
2816 /// Build a new expression in parentheses.
2817 ///
2818 /// By default, performs semantic analysis to build the new expression.
2819 /// Subclasses may override this routine to provide different behavior.
2820 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2821 SourceLocation RParen) {
2822 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2823 }
2824
2825 /// Build a new pseudo-destructor expression.
2826 ///
2827 /// By default, performs semantic analysis to build the new expression.
2828 /// Subclasses may override this routine to provide different behavior.
2829 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2830 SourceLocation OperatorLoc,
2831 bool isArrow,
2832 CXXScopeSpec &SS,
2833 TypeSourceInfo *ScopeType,
2834 SourceLocation CCLoc,
2835 SourceLocation TildeLoc,
2836 PseudoDestructorTypeStorage Destroyed);
2837
2838 /// Build a new unary operator expression.
2839 ///
2840 /// By default, performs semantic analysis to build the new expression.
2841 /// Subclasses may override this routine to provide different behavior.
2842 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2843 UnaryOperatorKind Opc,
2844 Expr *SubExpr) {
2845 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2846 }
2847
2848 /// Build a new builtin offsetof expression.
2849 ///
2850 /// By default, performs semantic analysis to build the new expression.
2851 /// Subclasses may override this routine to provide different behavior.
2852 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2853 TypeSourceInfo *Type, const Designation &Desig,
2854 SourceLocation RParenLoc) {
2855 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Desig, RParenLoc);
2856 }
2857
2858 /// Build a new sizeof, alignof or vec_step expression with a
2859 /// type argument.
2860 ///
2861 /// By default, performs semantic analysis to build the new expression.
2862 /// Subclasses may override this routine to provide different behavior.
2863 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2864 SourceLocation OpLoc,
2865 UnaryExprOrTypeTrait ExprKind,
2866 SourceRange R) {
2867 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2868 }
2869
2870 /// Build a new sizeof, alignof or vec step expression with an
2871 /// expression argument.
2872 ///
2873 /// By default, performs semantic analysis to build the new expression.
2874 /// Subclasses may override this routine to provide different behavior.
2875 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2876 UnaryExprOrTypeTrait ExprKind,
2877 SourceRange R) {
2878 ExprResult Result
2879 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2880 if (Result.isInvalid())
2881 return ExprError();
2882
2883 return Result;
2884 }
2885
2886 /// Build a new array subscript expression.
2887 ///
2888 /// By default, performs semantic analysis to build the new expression.
2889 /// Subclasses may override this routine to provide different behavior.
2890 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2891 SourceLocation LBracketLoc,
2892 Expr *RHS,
2893 SourceLocation RBracketLoc) {
2894 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2895 LBracketLoc, RHS,
2896 RBracketLoc);
2897 }
2898
2899 /// Build a new matrix single subscript expression.
2900 ///
2901 /// By default, performs semantic analysis to build the new expression.
2902 /// Subclasses may override this routine to provide different behavior.
2903 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2904 SourceLocation RBracketLoc) {
2905 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2906 RBracketLoc);
2907 }
2908
2909 /// Build a new matrix subscript expression.
2910 ///
2911 /// By default, performs semantic analysis to build the new expression.
2912 /// Subclasses may override this routine to provide different behavior.
2913 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2914 Expr *ColumnIdx,
2915 SourceLocation RBracketLoc) {
2916 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2917 RBracketLoc);
2918 }
2919
2920 /// Build a new array section expression.
2921 ///
2922 /// By default, performs semantic analysis to build the new expression.
2923 /// Subclasses may override this routine to provide different behavior.
2924 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2925 SourceLocation LBracketLoc,
2926 Expr *LowerBound,
2927 SourceLocation ColonLocFirst,
2928 SourceLocation ColonLocSecond,
2929 Expr *Length, Expr *Stride,
2930 SourceLocation RBracketLoc) {
2931 if (IsOMPArraySection)
2932 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2933 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2934 Stride, RBracketLoc);
2935
2936 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2937 "Stride/second colon not allowed for OpenACC");
2938
2939 return getSema().OpenACC().ActOnArraySectionExpr(
2940 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2941 }
2942
2943 /// Build a new array shaping expression.
2944 ///
2945 /// By default, performs semantic analysis to build the new expression.
2946 /// Subclasses may override this routine to provide different behavior.
2947 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2948 SourceLocation RParenLoc,
2949 ArrayRef<Expr *> Dims,
2950 ArrayRef<SourceRange> BracketsRanges) {
2951 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2952 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2953 }
2954
2955 /// Build a new iterator expression.
2956 ///
2957 /// By default, performs semantic analysis to build the new expression.
2958 /// Subclasses may override this routine to provide different behavior.
2959 ExprResult
2960 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2961 SourceLocation RLoc,
2962 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2963 return getSema().OpenMP().ActOnOMPIteratorExpr(
2964 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2965 }
2966
2967 /// Build a new call expression.
2968 ///
2969 /// By default, performs semantic analysis to build the new expression.
2970 /// Subclasses may override this routine to provide different behavior.
2971 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2972 MultiExprArg Args,
2973 SourceLocation RParenLoc,
2974 Expr *ExecConfig = nullptr) {
2975 return getSema().ActOnCallExpr(
2976 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2977 }
2978
2979 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2980 MultiExprArg Args,
2981 SourceLocation RParenLoc) {
2982 return getSema().ActOnArraySubscriptExpr(
2983 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2984 }
2985
2986 /// Build a new member access expression.
2987 ///
2988 /// By default, performs semantic analysis to build the new expression.
2989 /// Subclasses may override this routine to provide different behavior.
2990 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2991 bool isArrow,
2992 NestedNameSpecifierLoc QualifierLoc,
2993 SourceLocation TemplateKWLoc,
2994 const DeclarationNameInfo &MemberNameInfo,
2995 ValueDecl *Member,
2996 NamedDecl *FoundDecl,
2997 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2998 NamedDecl *FirstQualifierInScope) {
2999 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
3000 isArrow);
3001 if (!Member->getDeclName()) {
3002 // We have a reference to an unnamed field. This is always the
3003 // base of an anonymous struct/union member access, i.e. the
3004 // field is always of record type.
3005 assert(Member->getType()->isRecordType() &&
3006 "unnamed member not of record type?");
3007
3008 BaseResult =
3009 getSema().PerformObjectMemberConversion(BaseResult.get(),
3010 QualifierLoc.getNestedNameSpecifier(),
3011 FoundDecl, Member);
3012 if (BaseResult.isInvalid())
3013 return ExprError();
3014 Base = BaseResult.get();
3015
3016 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
3017 // from the AST, so we need to re-insert them if needed (since
3018 // `BuildFieldRefereneExpr()` doesn't do this).
3019 if (!isArrow && Base->isPRValue()) {
3020 BaseResult = getSema().TemporaryMaterializationConversion(Base);
3021 if (BaseResult.isInvalid())
3022 return ExprError();
3023 Base = BaseResult.get();
3024 }
3025
3026 CXXScopeSpec EmptySS;
3027 return getSema().BuildFieldReferenceExpr(
3028 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
3029 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
3030 MemberNameInfo);
3031 }
3032
3033 CXXScopeSpec SS;
3034 SS.Adopt(Other: QualifierLoc);
3035
3036 Base = BaseResult.get();
3037 if (Base->containsErrors())
3038 return ExprError();
3039
3040 QualType BaseType = Base->getType();
3041
3042 if (isArrow && !BaseType->isPointerType())
3043 return ExprError();
3044
3045 // FIXME: this involves duplicating earlier analysis in a lot of
3046 // cases; we should avoid this when possible.
3047 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3048 R.addDecl(D: FoundDecl);
3049 R.resolveKind();
3050
3051 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3052 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3053 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3054 ->getType()
3055 ->getPointeeType()
3056 ->getAsCXXRecordDecl()) {
3057 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3058 // In unevaluated contexts, an expression supposed to be a member access
3059 // might reference a member in an unrelated class.
3060 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3061 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3062 VK_LValue, Member->getLocation());
3063 }
3064 }
3065
3066 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3067 SS, TemplateKWLoc,
3068 FirstQualifierInScope,
3069 R, ExplicitTemplateArgs,
3070 /*S*/nullptr);
3071 }
3072
3073 /// Build a new binary operator expression.
3074 ///
3075 /// By default, performs semantic analysis to build the new expression.
3076 /// Subclasses may override this routine to provide different behavior.
3077 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3078 Expr *LHS, Expr *RHS,
3079 bool ForFoldExpression = false) {
3080 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3081 ForFoldExpression);
3082 }
3083
3084 /// Build a new rewritten operator expression.
3085 ///
3086 /// By default, performs semantic analysis to build the new expression.
3087 /// Subclasses may override this routine to provide different behavior.
3088 ExprResult RebuildCXXRewrittenBinaryOperator(
3089 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3090 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3091 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3092 RHS, /*RequiresADL*/false);
3093 }
3094
3095 /// Build a new conditional operator expression.
3096 ///
3097 /// By default, performs semantic analysis to build the new expression.
3098 /// Subclasses may override this routine to provide different behavior.
3099 ExprResult RebuildConditionalOperator(Expr *Cond,
3100 SourceLocation QuestionLoc,
3101 Expr *LHS,
3102 SourceLocation ColonLoc,
3103 Expr *RHS) {
3104 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3105 LHS, RHS);
3106 }
3107
3108 /// Build a new C-style cast expression.
3109 ///
3110 /// By default, performs semantic analysis to build the new expression.
3111 /// Subclasses may override this routine to provide different behavior.
3112 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3113 TypeSourceInfo *TInfo,
3114 SourceLocation RParenLoc,
3115 Expr *SubExpr) {
3116 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3117 SubExpr);
3118 }
3119
3120 /// Build a new compound literal expression.
3121 ///
3122 /// By default, performs semantic analysis to build the new expression.
3123 /// Subclasses may override this routine to provide different behavior.
3124 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3125 TypeSourceInfo *TInfo,
3126 SourceLocation RParenLoc,
3127 Expr *Init) {
3128 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3129 Init);
3130 }
3131
3132 /// Build a new extended vector or matrix element access expression.
3133 ///
3134 /// By default, performs semantic analysis to build the new expression.
3135 /// Subclasses may override this routine to provide different behavior.
3136 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3137 SourceLocation OpLoc,
3138 bool IsArrow,
3139 SourceLocation AccessorLoc,
3140 IdentifierInfo &Accessor) {
3141
3142 CXXScopeSpec SS;
3143 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3144 return getSema().BuildMemberReferenceExpr(
3145 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3146 /*FirstQualifierInScope*/ nullptr, NameInfo,
3147 /* TemplateArgs */ nullptr,
3148 /*S*/ nullptr);
3149 }
3150
3151 /// Build a new initializer list expression.
3152 ///
3153 /// By default, performs semantic analysis to build the new expression.
3154 /// Subclasses may override this routine to provide different behavior.
3155 ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits,
3156 SourceLocation RBraceLoc, bool IsExplicit) {
3157 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc, IsExplicit);
3158 }
3159
3160 /// Build a new designated initializer 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 RebuildDesignatedInitExpr(Designation &Desig,
3165 MultiExprArg ArrayExprs,
3166 SourceLocation EqualOrColonLoc,
3167 bool GNUSyntax,
3168 Expr *Init) {
3169 ExprResult Result
3170 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3171 Init);
3172 if (Result.isInvalid())
3173 return ExprError();
3174
3175 return Result;
3176 }
3177
3178 /// Build a new value-initialized expression.
3179 ///
3180 /// By default, builds the implicit value initialization without performing
3181 /// any semantic analysis. Subclasses may override this routine to provide
3182 /// different behavior.
3183 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3184 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3185 }
3186
3187 /// Build a new \c va_arg expression.
3188 ///
3189 /// By default, performs semantic analysis to build the new expression.
3190 /// Subclasses may override this routine to provide different behavior.
3191 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3192 Expr *SubExpr, TypeSourceInfo *TInfo,
3193 SourceLocation RParenLoc) {
3194 return getSema().BuildVAArgExpr(BuiltinLoc,
3195 SubExpr, TInfo,
3196 RParenLoc);
3197 }
3198
3199 /// Build a new expression list in parentheses.
3200 ///
3201 /// By default, performs semantic analysis to build the new expression.
3202 /// Subclasses may override this routine to provide different behavior.
3203 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3204 MultiExprArg SubExprs,
3205 SourceLocation RParenLoc) {
3206 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3207 }
3208
3209 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3210 unsigned NumUserSpecifiedExprs,
3211 SourceLocation InitLoc,
3212 SourceLocation LParenLoc,
3213 SourceLocation RParenLoc) {
3214 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3215 InitLoc, LParenLoc, RParenLoc);
3216 }
3217
3218 /// Build a new address-of-label expression.
3219 ///
3220 /// By default, performs semantic analysis, using the name of the label
3221 /// rather than attempting to map the label statement itself.
3222 /// Subclasses may override this routine to provide different behavior.
3223 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3224 SourceLocation LabelLoc, LabelDecl *Label) {
3225 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3226 }
3227
3228 /// Build a new GNU statement expression.
3229 ///
3230 /// By default, performs semantic analysis to build the new expression.
3231 /// Subclasses may override this routine to provide different behavior.
3232 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3233 SourceLocation RParenLoc, unsigned TemplateDepth) {
3234 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3235 TemplateDepth);
3236 }
3237
3238 /// Build a new __builtin_choose_expr expression.
3239 ///
3240 /// By default, performs semantic analysis to build the new expression.
3241 /// Subclasses may override this routine to provide different behavior.
3242 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3243 Expr *Cond, Expr *LHS, Expr *RHS,
3244 SourceLocation RParenLoc) {
3245 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3246 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3247 RPLoc: RParenLoc);
3248 }
3249
3250 /// Build a new generic selection expression with an expression predicate.
3251 ///
3252 /// By default, performs semantic analysis to build the new expression.
3253 /// Subclasses may override this routine to provide different behavior.
3254 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3255 SourceLocation DefaultLoc,
3256 SourceLocation RParenLoc,
3257 Expr *ControllingExpr,
3258 ArrayRef<TypeSourceInfo *> Types,
3259 ArrayRef<Expr *> Exprs) {
3260 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3261 /*PredicateIsExpr=*/true,
3262 ControllingExpr, Types, Exprs);
3263 }
3264
3265 /// Build a new generic selection expression with a type predicate.
3266 ///
3267 /// By default, performs semantic analysis to build the new expression.
3268 /// Subclasses may override this routine to provide different behavior.
3269 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3270 SourceLocation DefaultLoc,
3271 SourceLocation RParenLoc,
3272 TypeSourceInfo *ControllingType,
3273 ArrayRef<TypeSourceInfo *> Types,
3274 ArrayRef<Expr *> Exprs) {
3275 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3276 /*PredicateIsExpr=*/false,
3277 ControllingType, Types, Exprs);
3278 }
3279
3280 /// Build a new overloaded operator call expression.
3281 ///
3282 /// By default, performs semantic analysis to build the new expression.
3283 /// The semantic analysis provides the behavior of template instantiation,
3284 /// copying with transformations that turn what looks like an overloaded
3285 /// operator call into a use of a builtin operator, performing
3286 /// argument-dependent lookup, etc. Subclasses may override this routine to
3287 /// provide different behavior.
3288 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3289 SourceLocation OpLoc,
3290 SourceLocation CalleeLoc,
3291 bool RequiresADL,
3292 const UnresolvedSetImpl &Functions,
3293 Expr *First, Expr *Second);
3294
3295 /// Build a new C++ "named" cast expression, such as static_cast or
3296 /// reinterpret_cast.
3297 ///
3298 /// By default, this routine dispatches to one of the more-specific routines
3299 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3300 /// Subclasses may override this routine to provide different behavior.
3301 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3302 Stmt::StmtClass Class,
3303 SourceLocation LAngleLoc,
3304 TypeSourceInfo *TInfo,
3305 SourceLocation RAngleLoc,
3306 SourceLocation LParenLoc,
3307 Expr *SubExpr,
3308 SourceLocation RParenLoc) {
3309 switch (Class) {
3310 case Stmt::CXXStaticCastExprClass:
3311 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3312 RAngleLoc, LParenLoc,
3313 SubExpr, RParenLoc);
3314
3315 case Stmt::CXXDynamicCastExprClass:
3316 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3317 RAngleLoc, LParenLoc,
3318 SubExpr, RParenLoc);
3319
3320 case Stmt::CXXReinterpretCastExprClass:
3321 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3322 RAngleLoc, LParenLoc,
3323 SubExpr,
3324 RParenLoc);
3325
3326 case Stmt::CXXConstCastExprClass:
3327 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3328 RAngleLoc, LParenLoc,
3329 SubExpr, RParenLoc);
3330
3331 case Stmt::CXXAddrspaceCastExprClass:
3332 return getDerived().RebuildCXXAddrspaceCastExpr(
3333 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3334
3335 default:
3336 llvm_unreachable("Invalid C++ named cast");
3337 }
3338 }
3339
3340 /// Build a new C++ static_cast expression.
3341 ///
3342 /// By default, performs semantic analysis to build the new expression.
3343 /// Subclasses may override this routine to provide different behavior.
3344 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3345 SourceLocation LAngleLoc,
3346 TypeSourceInfo *TInfo,
3347 SourceLocation RAngleLoc,
3348 SourceLocation LParenLoc,
3349 Expr *SubExpr,
3350 SourceLocation RParenLoc) {
3351 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3352 TInfo, SubExpr,
3353 SourceRange(LAngleLoc, RAngleLoc),
3354 SourceRange(LParenLoc, RParenLoc));
3355 }
3356
3357 /// Build a new C++ dynamic_cast expression.
3358 ///
3359 /// By default, performs semantic analysis to build the new expression.
3360 /// Subclasses may override this routine to provide different behavior.
3361 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3362 SourceLocation LAngleLoc,
3363 TypeSourceInfo *TInfo,
3364 SourceLocation RAngleLoc,
3365 SourceLocation LParenLoc,
3366 Expr *SubExpr,
3367 SourceLocation RParenLoc) {
3368 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3369 TInfo, SubExpr,
3370 SourceRange(LAngleLoc, RAngleLoc),
3371 SourceRange(LParenLoc, RParenLoc));
3372 }
3373
3374 /// Build a new C++ reinterpret_cast expression.
3375 ///
3376 /// By default, performs semantic analysis to build the new expression.
3377 /// Subclasses may override this routine to provide different behavior.
3378 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3379 SourceLocation LAngleLoc,
3380 TypeSourceInfo *TInfo,
3381 SourceLocation RAngleLoc,
3382 SourceLocation LParenLoc,
3383 Expr *SubExpr,
3384 SourceLocation RParenLoc) {
3385 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3386 TInfo, SubExpr,
3387 SourceRange(LAngleLoc, RAngleLoc),
3388 SourceRange(LParenLoc, RParenLoc));
3389 }
3390
3391 /// Build a new C++ const_cast expression.
3392 ///
3393 /// By default, performs semantic analysis to build the new expression.
3394 /// Subclasses may override this routine to provide different behavior.
3395 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3396 SourceLocation LAngleLoc,
3397 TypeSourceInfo *TInfo,
3398 SourceLocation RAngleLoc,
3399 SourceLocation LParenLoc,
3400 Expr *SubExpr,
3401 SourceLocation RParenLoc) {
3402 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3403 TInfo, SubExpr,
3404 SourceRange(LAngleLoc, RAngleLoc),
3405 SourceRange(LParenLoc, RParenLoc));
3406 }
3407
3408 ExprResult
3409 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3410 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3411 SourceLocation LParenLoc, Expr *SubExpr,
3412 SourceLocation RParenLoc) {
3413 return getSema().BuildCXXNamedCast(
3414 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3415 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3416 }
3417
3418 /// Build a new C++ functional-style cast expression.
3419 ///
3420 /// By default, performs semantic analysis to build the new expression.
3421 /// Subclasses may override this routine to provide different behavior.
3422 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3423 SourceLocation LParenLoc,
3424 Expr *Sub,
3425 SourceLocation RParenLoc,
3426 bool ListInitialization) {
3427 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3428 // CXXParenListInitExpr. Pass its expanded arguments so that the
3429 // CXXParenListInitExpr can be rebuilt.
3430 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3431 return getSema().BuildCXXTypeConstructExpr(
3432 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3433 RParenLoc, ListInitialization);
3434
3435 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3436 return getSema().BuildCXXTypeConstructExpr(
3437 TInfo, LParenLoc, PLE->getUserSpecifiedInitExprs(), RParenLoc,
3438 ListInitialization);
3439
3440 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3441 MultiExprArg(&Sub, 1), RParenLoc,
3442 ListInitialization);
3443 }
3444
3445 /// Build a new C++ __builtin_bit_cast expression.
3446 ///
3447 /// By default, performs semantic analysis to build the new expression.
3448 /// Subclasses may override this routine to provide different behavior.
3449 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3450 TypeSourceInfo *TSI, Expr *Sub,
3451 SourceLocation RParenLoc) {
3452 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3453 }
3454
3455 /// Build a new C++ typeid(type) expression.
3456 ///
3457 /// By default, performs semantic analysis to build the new expression.
3458 /// Subclasses may override this routine to provide different behavior.
3459 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3460 SourceLocation TypeidLoc,
3461 TypeSourceInfo *Operand,
3462 SourceLocation RParenLoc) {
3463 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3464 RParenLoc);
3465 }
3466
3467
3468 /// Build a new C++ typeid(expr) expression.
3469 ///
3470 /// By default, performs semantic analysis to build the new expression.
3471 /// Subclasses may override this routine to provide different behavior.
3472 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3473 SourceLocation TypeidLoc,
3474 Expr *Operand,
3475 SourceLocation RParenLoc) {
3476 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3477 RParenLoc);
3478 }
3479
3480 /// Build a new C++ __uuidof(type) expression.
3481 ///
3482 /// By default, performs semantic analysis to build the new expression.
3483 /// Subclasses may override this routine to provide different behavior.
3484 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3485 TypeSourceInfo *Operand,
3486 SourceLocation RParenLoc) {
3487 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3488 }
3489
3490 /// Build a new C++ __uuidof(expr) expression.
3491 ///
3492 /// By default, performs semantic analysis to build the new expression.
3493 /// Subclasses may override this routine to provide different behavior.
3494 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3495 Expr *Operand, SourceLocation RParenLoc) {
3496 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3497 }
3498
3499 /// Build a new C++ "this" expression.
3500 ///
3501 /// By default, performs semantic analysis to build a new "this" expression.
3502 /// Subclasses may override this routine to provide different behavior.
3503 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3504 QualType ThisType,
3505 bool isImplicit) {
3506 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3507 return ExprError();
3508 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3509 }
3510
3511 /// Build a new C++ throw expression.
3512 ///
3513 /// By default, performs semantic analysis to build the new expression.
3514 /// Subclasses may override this routine to provide different behavior.
3515 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3516 bool IsThrownVariableInScope) {
3517 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3518 }
3519
3520 /// Build a new C++ default-argument expression.
3521 ///
3522 /// By default, builds a new default-argument expression, which does not
3523 /// require any semantic analysis. Subclasses may override this routine to
3524 /// provide different behavior.
3525 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3526 Expr *RewrittenExpr) {
3527 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3528 RewrittenExpr, UsedContext: getSema().CurContext);
3529 }
3530
3531 /// Build a new C++11 default-initialization expression.
3532 ///
3533 /// By default, builds a new default field initialization expression, which
3534 /// does not require any semantic analysis. Subclasses may override this
3535 /// routine to provide different behavior.
3536 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3537 FieldDecl *Field) {
3538 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3539 }
3540
3541 /// Build a new C++ zero-initialization expression.
3542 ///
3543 /// By default, performs semantic analysis to build the new expression.
3544 /// Subclasses may override this routine to provide different behavior.
3545 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3546 SourceLocation LParenLoc,
3547 SourceLocation RParenLoc) {
3548 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3549 /*ListInitialization=*/false);
3550 }
3551
3552 /// Build a new C++ "new" expression.
3553 ///
3554 /// By default, performs semantic analysis to build the new expression.
3555 /// Subclasses may override this routine to provide different behavior.
3556 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3557 SourceLocation PlacementLParen,
3558 MultiExprArg PlacementArgs,
3559 SourceLocation PlacementRParen,
3560 SourceRange TypeIdParens, QualType AllocatedType,
3561 TypeSourceInfo *AllocatedTypeInfo,
3562 std::optional<Expr *> ArraySize,
3563 SourceRange DirectInitRange, Expr *Initializer) {
3564 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3565 PlacementLParen,
3566 PlacementArgs,
3567 PlacementRParen,
3568 TypeIdParens,
3569 AllocatedType,
3570 AllocatedTypeInfo,
3571 ArraySize,
3572 DirectInitRange,
3573 Initializer);
3574 }
3575
3576 /// Build a new C++ "delete" expression.
3577 ///
3578 /// By default, performs semantic analysis to build the new expression.
3579 /// Subclasses may override this routine to provide different behavior.
3580 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3581 bool IsGlobalDelete,
3582 bool IsArrayForm,
3583 Expr *Operand) {
3584 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3585 Operand);
3586 }
3587
3588 /// Build a new type trait expression.
3589 ///
3590 /// By default, performs semantic analysis to build the new expression.
3591 /// Subclasses may override this routine to provide different behavior.
3592 ExprResult RebuildTypeTrait(TypeTrait Trait,
3593 SourceLocation StartLoc,
3594 ArrayRef<TypeSourceInfo *> Args,
3595 SourceLocation RParenLoc) {
3596 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3597 }
3598
3599 /// Build a new array type trait expression.
3600 ///
3601 /// By default, performs semantic analysis to build the new expression.
3602 /// Subclasses may override this routine to provide different behavior.
3603 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3604 SourceLocation StartLoc,
3605 TypeSourceInfo *TSInfo,
3606 Expr *DimExpr,
3607 SourceLocation RParenLoc) {
3608 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3609 }
3610
3611 /// Build a new expression trait expression.
3612 ///
3613 /// By default, performs semantic analysis to build the new expression.
3614 /// Subclasses may override this routine to provide different behavior.
3615 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3616 SourceLocation StartLoc,
3617 Expr *Queried,
3618 SourceLocation RParenLoc) {
3619 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3620 }
3621
3622 /// Build a new (previously unresolved) declaration reference
3623 /// expression.
3624 ///
3625 /// By default, performs semantic analysis to build the new expression.
3626 /// Subclasses may override this routine to provide different behavior.
3627 ExprResult RebuildDependentScopeDeclRefExpr(
3628 NestedNameSpecifierLoc QualifierLoc,
3629 SourceLocation TemplateKWLoc,
3630 const DeclarationNameInfo &NameInfo,
3631 const TemplateArgumentListInfo *TemplateArgs,
3632 bool IsAddressOfOperand,
3633 TypeSourceInfo **RecoveryTSI) {
3634 CXXScopeSpec SS;
3635 SS.Adopt(Other: QualifierLoc);
3636
3637 if (TemplateArgs || TemplateKWLoc.isValid())
3638 return getSema().BuildQualifiedTemplateIdExpr(
3639 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3640
3641 return getSema().BuildQualifiedDeclarationNameExpr(
3642 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3643 }
3644
3645 /// Build a new template-id expression.
3646 ///
3647 /// By default, performs semantic analysis to build the new expression.
3648 /// Subclasses may override this routine to provide different behavior.
3649 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3650 SourceLocation TemplateKWLoc,
3651 LookupResult &R,
3652 bool RequiresADL,
3653 const TemplateArgumentListInfo *TemplateArgs) {
3654 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3655 TemplateArgs);
3656 }
3657
3658 /// Build a new object-construction expression.
3659 ///
3660 /// By default, performs semantic analysis to build the new expression.
3661 /// Subclasses may override this routine to provide different behavior.
3662 ExprResult RebuildCXXConstructExpr(
3663 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3664 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3665 bool ListInitialization, bool StdInitListInitialization,
3666 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3667 SourceRange ParenRange) {
3668 // Reconstruct the constructor we originally found, which might be
3669 // different if this is a call to an inherited constructor.
3670 CXXConstructorDecl *FoundCtor = Constructor;
3671 if (Constructor->isInheritingConstructor())
3672 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3673
3674 SmallVector<Expr *, 8> ConvertedArgs;
3675 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3676 ConvertedArgs))
3677 return ExprError();
3678
3679 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3680 IsElidable,
3681 ConvertedArgs,
3682 HadMultipleCandidates,
3683 ListInitialization,
3684 StdInitListInitialization,
3685 RequiresZeroInit, ConstructKind,
3686 ParenRange);
3687 }
3688
3689 /// Build a new implicit construction via inherited constructor
3690 /// expression.
3691 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3692 CXXConstructorDecl *Constructor,
3693 bool ConstructsVBase,
3694 bool InheritedFromVBase) {
3695 return new (getSema().Context) CXXInheritedCtorInitExpr(
3696 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3697 }
3698
3699 /// Build a new object-construction expression.
3700 ///
3701 /// By default, performs semantic analysis to build the new expression.
3702 /// Subclasses may override this routine to provide different behavior.
3703 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3704 SourceLocation LParenOrBraceLoc,
3705 MultiExprArg Args,
3706 SourceLocation RParenOrBraceLoc,
3707 bool ListInitialization) {
3708 return getSema().BuildCXXTypeConstructExpr(
3709 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3710 }
3711
3712 /// Build a new object-construction expression.
3713 ///
3714 /// By default, performs semantic analysis to build the new expression.
3715 /// Subclasses may override this routine to provide different behavior.
3716 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3717 SourceLocation LParenLoc,
3718 MultiExprArg Args,
3719 SourceLocation RParenLoc,
3720 bool ListInitialization) {
3721 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3722 RParenLoc, ListInitialization);
3723 }
3724
3725 /// Build a new member reference expression.
3726 ///
3727 /// By default, performs semantic analysis to build the new expression.
3728 /// Subclasses may override this routine to provide different behavior.
3729 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3730 QualType BaseType,
3731 bool IsArrow,
3732 SourceLocation OperatorLoc,
3733 NestedNameSpecifierLoc QualifierLoc,
3734 SourceLocation TemplateKWLoc,
3735 NamedDecl *FirstQualifierInScope,
3736 const DeclarationNameInfo &MemberNameInfo,
3737 const TemplateArgumentListInfo *TemplateArgs) {
3738 CXXScopeSpec SS;
3739 SS.Adopt(Other: QualifierLoc);
3740
3741 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3742 OpLoc: OperatorLoc, IsArrow,
3743 SS, TemplateKWLoc,
3744 FirstQualifierInScope,
3745 NameInfo: MemberNameInfo,
3746 TemplateArgs, /*S*/S: nullptr);
3747 }
3748
3749 /// Build a new member reference expression.
3750 ///
3751 /// By default, performs semantic analysis to build the new expression.
3752 /// Subclasses may override this routine to provide different behavior.
3753 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3754 SourceLocation OperatorLoc,
3755 bool IsArrow,
3756 NestedNameSpecifierLoc QualifierLoc,
3757 SourceLocation TemplateKWLoc,
3758 NamedDecl *FirstQualifierInScope,
3759 LookupResult &R,
3760 const TemplateArgumentListInfo *TemplateArgs) {
3761 CXXScopeSpec SS;
3762 SS.Adopt(Other: QualifierLoc);
3763
3764 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3765 OpLoc: OperatorLoc, IsArrow,
3766 SS, TemplateKWLoc,
3767 FirstQualifierInScope,
3768 R, TemplateArgs, /*S*/S: nullptr);
3769 }
3770
3771 /// Build a new noexcept expression.
3772 ///
3773 /// By default, performs semantic analysis to build the new expression.
3774 /// Subclasses may override this routine to provide different behavior.
3775 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3776 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3777 }
3778
3779 UnsignedOrNone
3780 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3781
3782 /// Build a new expression to compute the length of a parameter pack.
3783 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3784 SourceLocation PackLoc,
3785 SourceLocation RParenLoc,
3786 UnsignedOrNone Length,
3787 ArrayRef<TemplateArgument> PartialArgs) {
3788 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3789 RParenLoc, Length, PartialArgs);
3790 }
3791
3792 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3793 SourceLocation RSquareLoc,
3794 Expr *PackIdExpression, Expr *IndexExpr,
3795 ArrayRef<Expr *> ExpandedExprs,
3796 bool FullySubstituted = false) {
3797 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3798 IndexExpr, RSquareLoc, ExpandedExprs,
3799 FullySubstituted);
3800 }
3801
3802 /// Build a new expression representing a call to a source location
3803 /// builtin.
3804 ///
3805 /// By default, performs semantic analysis to build the new expression.
3806 /// Subclasses may override this routine to provide different behavior.
3807 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3808 SourceLocation BuiltinLoc,
3809 SourceLocation RPLoc,
3810 DeclContext *ParentContext) {
3811 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3812 ParentContext);
3813 }
3814
3815 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3816 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3817 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3818 TemplateArgumentListInfo *TALI) {
3819 CXXScopeSpec SS;
3820 SS.Adopt(Other: NNS);
3821 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3822 ConceptNameInfo,
3823 FoundDecl,
3824 NamedConcept, TALI);
3825 if (Result.isInvalid())
3826 return ExprError();
3827 return Result;
3828 }
3829
3830 /// \brief Build a new requires expression.
3831 ///
3832 /// By default, performs semantic analysis to build the new expression.
3833 /// Subclasses may override this routine to provide different behavior.
3834 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3835 RequiresExprBodyDecl *Body,
3836 SourceLocation LParenLoc,
3837 ArrayRef<ParmVarDecl *> LocalParameters,
3838 SourceLocation RParenLoc,
3839 ArrayRef<concepts::Requirement *> Requirements,
3840 SourceLocation ClosingBraceLoc) {
3841 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3842 LocalParameters, RParenLoc, Requirements,
3843 RBraceLoc: ClosingBraceLoc);
3844 }
3845
3846 concepts::TypeRequirement *
3847 RebuildTypeRequirement(
3848 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3849 return SemaRef.BuildTypeRequirement(SubstDiag);
3850 }
3851
3852 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3853 return SemaRef.BuildTypeRequirement(Type: T);
3854 }
3855
3856 concepts::ExprRequirement *
3857 RebuildExprRequirement(
3858 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3859 SourceLocation NoexceptLoc,
3860 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3861 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3862 ReturnTypeRequirement: std::move(Ret));
3863 }
3864
3865 concepts::ExprRequirement *
3866 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3867 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3868 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3869 ReturnTypeRequirement: std::move(Ret));
3870 }
3871
3872 concepts::NestedRequirement *
3873 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3874 const ASTConstraintSatisfaction &Satisfaction) {
3875 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3876 Satisfaction);
3877 }
3878
3879 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3880 return SemaRef.BuildNestedRequirement(E: Constraint);
3881 }
3882
3883 /// \brief Build a new Objective-C boxed expression.
3884 ///
3885 /// By default, performs semantic analysis to build the new expression.
3886 /// Subclasses may override this routine to provide different behavior.
3887 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3888 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3889 }
3890
3891 /// Build a new Objective-C array literal.
3892 ///
3893 /// By default, performs semantic analysis to build the new expression.
3894 /// Subclasses may override this routine to provide different behavior.
3895 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3896 Expr **Elements, unsigned NumElements) {
3897 return getSema().ObjC().BuildObjCArrayLiteral(
3898 Range, MultiExprArg(Elements, NumElements));
3899 }
3900
3901 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3902 Expr *Base, Expr *Key,
3903 ObjCMethodDecl *getterMethod,
3904 ObjCMethodDecl *setterMethod) {
3905 return getSema().ObjC().BuildObjCSubscriptExpression(
3906 RB, Base, Key, getterMethod, setterMethod);
3907 }
3908
3909 /// Build a new Objective-C dictionary literal.
3910 ///
3911 /// By default, performs semantic analysis to build the new expression.
3912 /// Subclasses may override this routine to provide different behavior.
3913 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3914 MutableArrayRef<ObjCDictionaryElement> Elements) {
3915 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3916 }
3917
3918 /// Build a new Objective-C \@encode expression.
3919 ///
3920 /// By default, performs semantic analysis to build the new expression.
3921 /// Subclasses may override this routine to provide different behavior.
3922 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3923 TypeSourceInfo *EncodeTypeInfo,
3924 SourceLocation RParenLoc) {
3925 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3926 RParenLoc);
3927 }
3928
3929 /// Build a new Objective-C class message.
3930 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3931 Selector Sel,
3932 ArrayRef<SourceLocation> SelectorLocs,
3933 ObjCMethodDecl *Method,
3934 SourceLocation LBracLoc,
3935 MultiExprArg Args,
3936 SourceLocation RBracLoc) {
3937 return SemaRef.ObjC().BuildClassMessage(
3938 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3939 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3940 RBracLoc, Args);
3941 }
3942
3943 /// Build a new Objective-C instance message.
3944 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3945 Selector Sel,
3946 ArrayRef<SourceLocation> SelectorLocs,
3947 ObjCMethodDecl *Method,
3948 SourceLocation LBracLoc,
3949 MultiExprArg Args,
3950 SourceLocation RBracLoc) {
3951 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3952 /*SuperLoc=*/SuperLoc: SourceLocation(),
3953 Sel, Method, LBracLoc,
3954 SelectorLocs, RBracLoc, Args);
3955 }
3956
3957 /// Build a new Objective-C instance/class message to 'super'.
3958 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3959 Selector Sel,
3960 ArrayRef<SourceLocation> SelectorLocs,
3961 QualType SuperType,
3962 ObjCMethodDecl *Method,
3963 SourceLocation LBracLoc,
3964 MultiExprArg Args,
3965 SourceLocation RBracLoc) {
3966 return Method->isInstanceMethod()
3967 ? SemaRef.ObjC().BuildInstanceMessage(
3968 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3969 SelectorLocs, RBracLoc, Args)
3970 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3971 Sel, Method, LBracLoc,
3972 SelectorLocs, RBracLoc, Args);
3973 }
3974
3975 /// Build a new Objective-C ivar reference expression.
3976 ///
3977 /// By default, performs semantic analysis to build the new expression.
3978 /// Subclasses may override this routine to provide different behavior.
3979 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3980 SourceLocation IvarLoc,
3981 bool IsArrow, bool IsFreeIvar) {
3982 CXXScopeSpec SS;
3983 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3984 ExprResult Result = getSema().BuildMemberReferenceExpr(
3985 BaseArg, BaseArg->getType(),
3986 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3987 /*FirstQualifierInScope=*/nullptr, NameInfo,
3988 /*TemplateArgs=*/nullptr,
3989 /*S=*/nullptr);
3990 if (IsFreeIvar && Result.isUsable())
3991 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3992 return Result;
3993 }
3994
3995 /// Build a new Objective-C property reference expression.
3996 ///
3997 /// By default, performs semantic analysis to build the new expression.
3998 /// Subclasses may override this routine to provide different behavior.
3999 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
4000 ObjCPropertyDecl *Property,
4001 SourceLocation PropertyLoc) {
4002 CXXScopeSpec SS;
4003 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
4004 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4005 /*FIXME:*/PropertyLoc,
4006 /*IsArrow=*/false,
4007 SS, SourceLocation(),
4008 /*FirstQualifierInScope=*/nullptr,
4009 NameInfo,
4010 /*TemplateArgs=*/nullptr,
4011 /*S=*/nullptr);
4012 }
4013
4014 /// Build a new Objective-C property reference expression.
4015 ///
4016 /// By default, performs semantic analysis to build the new expression.
4017 /// Subclasses may override this routine to provide different behavior.
4018 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
4019 ObjCMethodDecl *Getter,
4020 ObjCMethodDecl *Setter,
4021 SourceLocation PropertyLoc) {
4022 // Since these expressions can only be value-dependent, we do not
4023 // need to perform semantic analysis again.
4024 return Owned(
4025 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
4026 VK_LValue, OK_ObjCProperty,
4027 PropertyLoc, Base));
4028 }
4029
4030 /// Build a new Objective-C "isa" expression.
4031 ///
4032 /// By default, performs semantic analysis to build the new expression.
4033 /// Subclasses may override this routine to provide different behavior.
4034 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4035 SourceLocation OpLoc, bool IsArrow) {
4036 CXXScopeSpec SS;
4037 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4038 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4039 OpLoc, IsArrow,
4040 SS, SourceLocation(),
4041 /*FirstQualifierInScope=*/nullptr,
4042 NameInfo,
4043 /*TemplateArgs=*/nullptr,
4044 /*S=*/nullptr);
4045 }
4046
4047 /// Build a new shuffle vector expression.
4048 ///
4049 /// By default, performs semantic analysis to build the new expression.
4050 /// Subclasses may override this routine to provide different behavior.
4051 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4052 MultiExprArg SubExprs,
4053 SourceLocation RParenLoc) {
4054 // Find the declaration for __builtin_shufflevector
4055 const IdentifierInfo &Name
4056 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4057 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4058 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4059 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4060
4061 // Build a reference to the __builtin_shufflevector builtin
4062 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4063 Expr *Callee = new (SemaRef.Context)
4064 DeclRefExpr(SemaRef.Context, Builtin, false,
4065 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4066 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4067 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4068 CK: CK_BuiltinFnToFnPtr).get();
4069
4070 // Build the CallExpr
4071 ExprResult TheCall = CallExpr::Create(
4072 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4073 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4074 FPFeatures: FPOptionsOverride());
4075
4076 // Type-check the __builtin_shufflevector expression.
4077 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4078 }
4079
4080 /// Build a new convert vector expression.
4081 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4082 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4083 SourceLocation RParenLoc) {
4084 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4085 }
4086
4087 /// Build a new template argument pack expansion.
4088 ///
4089 /// By default, performs semantic analysis to build a new pack expansion
4090 /// for a template argument. Subclasses may override this routine to provide
4091 /// different behavior.
4092 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4093 SourceLocation EllipsisLoc,
4094 UnsignedOrNone NumExpansions) {
4095 switch (Pattern.getArgument().getKind()) {
4096 case TemplateArgument::Expression: {
4097 ExprResult Result
4098 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4099 EllipsisLoc, NumExpansions);
4100 if (Result.isInvalid())
4101 return TemplateArgumentLoc();
4102
4103 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4104 /*IsCanonical=*/false),
4105 Result.get());
4106 }
4107
4108 case TemplateArgument::Template:
4109 return TemplateArgumentLoc(
4110 SemaRef.Context,
4111 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4112 NumExpansions),
4113 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4114 Pattern.getTemplateNameLoc(), EllipsisLoc);
4115
4116 case TemplateArgument::Null:
4117 case TemplateArgument::Integral:
4118 case TemplateArgument::Declaration:
4119 case TemplateArgument::StructuralValue:
4120 case TemplateArgument::Pack:
4121 case TemplateArgument::TemplateExpansion:
4122 case TemplateArgument::NullPtr:
4123 llvm_unreachable("Pack expansion pattern has no parameter packs");
4124
4125 case TemplateArgument::Type:
4126 if (TypeSourceInfo *Expansion
4127 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4128 EllipsisLoc,
4129 NumExpansions))
4130 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4131 Expansion);
4132 break;
4133 }
4134
4135 return TemplateArgumentLoc();
4136 }
4137
4138 /// Build a new expression pack expansion.
4139 ///
4140 /// By default, performs semantic analysis to build a new pack expansion
4141 /// for an expression. Subclasses may override this routine to provide
4142 /// different behavior.
4143 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4144 UnsignedOrNone NumExpansions) {
4145 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4146 }
4147
4148 /// Build a new C++1z fold-expression.
4149 ///
4150 /// By default, performs semantic analysis in order to build a new fold
4151 /// expression.
4152 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4153 SourceLocation LParenLoc, Expr *LHS,
4154 BinaryOperatorKind Operator,
4155 SourceLocation EllipsisLoc, Expr *RHS,
4156 SourceLocation RParenLoc,
4157 UnsignedOrNone NumExpansions) {
4158 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4159 EllipsisLoc, RHS, RParenLoc,
4160 NumExpansions);
4161 }
4162
4163 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4164 LambdaScopeInfo *LSI) {
4165 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4166 if (Expr *Init = PVD->getInit())
4167 LSI->ContainsUnexpandedParameterPack |=
4168 Init->containsUnexpandedParameterPack();
4169 else if (PVD->hasUninstantiatedDefaultArg())
4170 LSI->ContainsUnexpandedParameterPack |=
4171 PVD->getUninstantiatedDefaultArg()
4172 ->containsUnexpandedParameterPack();
4173 }
4174 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4175 }
4176
4177 /// Build an empty C++1z fold-expression with the given operator.
4178 ///
4179 /// By default, produces the fallback value for the fold-expression, or
4180 /// produce an error if there is no fallback value.
4181 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4182 BinaryOperatorKind Operator) {
4183 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4184 }
4185
4186 /// Build a new atomic operation expression.
4187 ///
4188 /// By default, performs semantic analysis to build the new expression.
4189 /// Subclasses may override this routine to provide different behavior.
4190 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4191 AtomicExpr::AtomicOp Op,
4192 SourceLocation RParenLoc) {
4193 // Use this for all of the locations, since we don't know the difference
4194 // between the call and the expr at this point.
4195 SourceRange Range{BuiltinLoc, RParenLoc};
4196 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4197 Sema::AtomicArgumentOrder::AST);
4198 }
4199
4200 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4201 ArrayRef<Expr *> SubExprs, QualType Type) {
4202 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4203 }
4204
4205 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4206 SourceLocation BeginLoc,
4207 SourceLocation DirLoc,
4208 SourceLocation EndLoc,
4209 ArrayRef<OpenACCClause *> Clauses,
4210 StmtResult StrBlock) {
4211 return getSema().OpenACC().ActOnEndStmtDirective(
4212 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4213 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4214 }
4215
4216 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4217 SourceLocation DirLoc,
4218 SourceLocation EndLoc,
4219 ArrayRef<OpenACCClause *> Clauses,
4220 StmtResult Loop) {
4221 return getSema().OpenACC().ActOnEndStmtDirective(
4222 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4223 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4224 Clauses, Loop);
4225 }
4226
4227 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4228 SourceLocation BeginLoc,
4229 SourceLocation DirLoc,
4230 SourceLocation EndLoc,
4231 ArrayRef<OpenACCClause *> Clauses,
4232 StmtResult Loop) {
4233 return getSema().OpenACC().ActOnEndStmtDirective(
4234 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4235 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4236 }
4237
4238 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4239 SourceLocation DirLoc,
4240 SourceLocation EndLoc,
4241 ArrayRef<OpenACCClause *> Clauses,
4242 StmtResult StrBlock) {
4243 return getSema().OpenACC().ActOnEndStmtDirective(
4244 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4245 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4246 Clauses, StrBlock);
4247 }
4248
4249 StmtResult
4250 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4251 SourceLocation DirLoc, SourceLocation EndLoc,
4252 ArrayRef<OpenACCClause *> Clauses) {
4253 return getSema().OpenACC().ActOnEndStmtDirective(
4254 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4255 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4256 Clauses, {});
4257 }
4258
4259 StmtResult
4260 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4261 SourceLocation DirLoc, SourceLocation EndLoc,
4262 ArrayRef<OpenACCClause *> Clauses) {
4263 return getSema().OpenACC().ActOnEndStmtDirective(
4264 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4265 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4266 Clauses, {});
4267 }
4268
4269 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4270 SourceLocation DirLoc,
4271 SourceLocation EndLoc,
4272 ArrayRef<OpenACCClause *> Clauses,
4273 StmtResult StrBlock) {
4274 return getSema().OpenACC().ActOnEndStmtDirective(
4275 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4276 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4277 Clauses, StrBlock);
4278 }
4279
4280 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4281 SourceLocation DirLoc,
4282 SourceLocation EndLoc,
4283 ArrayRef<OpenACCClause *> Clauses) {
4284 return getSema().OpenACC().ActOnEndStmtDirective(
4285 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4286 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4287 Clauses, {});
4288 }
4289
4290 StmtResult
4291 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4292 SourceLocation DirLoc, SourceLocation EndLoc,
4293 ArrayRef<OpenACCClause *> Clauses) {
4294 return getSema().OpenACC().ActOnEndStmtDirective(
4295 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4296 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4297 Clauses, {});
4298 }
4299
4300 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4301 SourceLocation DirLoc,
4302 SourceLocation EndLoc,
4303 ArrayRef<OpenACCClause *> Clauses) {
4304 return getSema().OpenACC().ActOnEndStmtDirective(
4305 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4306 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4307 Clauses, {});
4308 }
4309
4310 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4311 SourceLocation DirLoc,
4312 SourceLocation EndLoc,
4313 ArrayRef<OpenACCClause *> Clauses) {
4314 return getSema().OpenACC().ActOnEndStmtDirective(
4315 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4316 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4317 Clauses, {});
4318 }
4319
4320 StmtResult RebuildOpenACCWaitConstruct(
4321 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4322 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4323 SourceLocation RParenLoc, SourceLocation EndLoc,
4324 ArrayRef<OpenACCClause *> Clauses) {
4325 llvm::SmallVector<Expr *> Exprs;
4326 Exprs.push_back(Elt: DevNumExpr);
4327 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4328 return getSema().OpenACC().ActOnEndStmtDirective(
4329 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4330 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4331 }
4332
4333 StmtResult RebuildOpenACCCacheConstruct(
4334 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4335 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4336 SourceLocation RParenLoc, SourceLocation EndLoc) {
4337 return getSema().OpenACC().ActOnEndStmtDirective(
4338 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4339 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4340 }
4341
4342 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4343 SourceLocation DirLoc,
4344 OpenACCAtomicKind AtKind,
4345 SourceLocation EndLoc,
4346 ArrayRef<OpenACCClause *> Clauses,
4347 StmtResult AssociatedStmt) {
4348 return getSema().OpenACC().ActOnEndStmtDirective(
4349 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4350 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4351 AssociatedStmt);
4352 }
4353
4354 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4355 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4356 }
4357
4358 ExprResult
4359 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl, unsigned Index,
4360 QualType ParamType, SourceLocation Loc,
4361 TemplateArgument Arg,
4362 UnsignedOrNone PackIndex, bool Final) {
4363 return getSema().BuildSubstNonTypeTemplateParmExpr(
4364 AssociatedDecl, Index, ParamType, Loc, Arg, PackIndex, Final);
4365 }
4366
4367 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4368 SourceLocation StartLoc,
4369 SourceLocation LParenLoc,
4370 SourceLocation EndLoc) {
4371 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4372 LParenLoc, EndLoc);
4373 }
4374
4375private:
4376 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4377 QualType ObjectType,
4378 NamedDecl *FirstQualifierInScope);
4379
4380 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4381 QualType ObjectType,
4382 NamedDecl *FirstQualifierInScope) {
4383 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4384 return TSInfo;
4385
4386 TypeLocBuilder TLB;
4387 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4388 ObjectType, FirstQualifierInScope);
4389 if (T.isNull())
4390 return nullptr;
4391 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4392 }
4393
4394 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4395 DependentNameTypeLoc TL,
4396 bool DeducibleTSTContext,
4397 QualType ObjectType = QualType(),
4398 NamedDecl *UnqualLookup = nullptr);
4399
4400 llvm::SmallVector<OpenACCClause *>
4401 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4402 ArrayRef<const OpenACCClause *> OldClauses);
4403
4404 OpenACCClause *
4405 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4406 OpenACCDirectiveKind DirKind,
4407 const OpenACCClause *OldClause);
4408};
4409
4410template <typename Derived>
4411StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4412 if (!S)
4413 return S;
4414
4415 switch (S->getStmtClass()) {
4416 case Stmt::NoStmtClass: break;
4417
4418 // Transform individual statement nodes
4419 // Pass SDK into statements that can produce a value
4420#define STMT(Node, Parent) \
4421 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4422#define VALUESTMT(Node, Parent) \
4423 case Stmt::Node##Class: \
4424 return getDerived().Transform##Node(cast<Node>(S), SDK);
4425#define ABSTRACT_STMT(Node)
4426#define EXPR(Node, Parent)
4427#include "clang/AST/StmtNodes.inc"
4428
4429 // Transform expressions by calling TransformExpr.
4430#define STMT(Node, Parent)
4431#define ABSTRACT_STMT(Stmt)
4432#define EXPR(Node, Parent) case Stmt::Node##Class:
4433#include "clang/AST/StmtNodes.inc"
4434 {
4435 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4436
4437 if (SDK == StmtDiscardKind::StmtExprResult)
4438 E = getSema().ActOnStmtExprResult(E);
4439 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4440 }
4441 }
4442
4443 return S;
4444}
4445
4446template<typename Derived>
4447OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4448 if (!S)
4449 return S;
4450
4451 switch (S->getClauseKind()) {
4452 default: break;
4453 // Transform individual clause nodes
4454#define GEN_CLANG_CLAUSE_CLASS
4455#define CLAUSE_CLASS(Enum, Str, Class) \
4456 case Enum: \
4457 return getDerived().Transform##Class(cast<Class>(S));
4458#include "llvm/Frontend/OpenMP/OMP.inc"
4459 }
4460
4461 return S;
4462}
4463
4464
4465template<typename Derived>
4466ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4467 if (!E)
4468 return E;
4469
4470 switch (E->getStmtClass()) {
4471 case Stmt::NoStmtClass: break;
4472#define STMT(Node, Parent) case Stmt::Node##Class: break;
4473#define ABSTRACT_STMT(Stmt)
4474#define EXPR(Node, Parent) \
4475 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4476#include "clang/AST/StmtNodes.inc"
4477 }
4478
4479 return E;
4480}
4481
4482template<typename Derived>
4483ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4484 bool NotCopyInit) {
4485 // Initializers are instantiated like expressions, except that various outer
4486 // layers are stripped.
4487 if (!Init)
4488 return Init;
4489
4490 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4491 Init = FE->getSubExpr();
4492
4493 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4494 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4495 Init = OVE->getSourceExpr();
4496 }
4497
4498 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4499 Init = MTE->getSubExpr();
4500
4501 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4502 Init = Binder->getSubExpr();
4503
4504 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4505 Init = ICE->getSubExprAsWritten();
4506
4507 if (CXXStdInitializerListExpr *ILE =
4508 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4509 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4510
4511 // If this is copy-initialization, we only need to reconstruct
4512 // InitListExprs. Other forms of copy-initialization will be a no-op if
4513 // the initializer is already the right type.
4514 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4515 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4516 return getDerived().TransformExpr(Init);
4517
4518 // Revert value-initialization back to empty parens.
4519 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4520 SourceRange Parens = VIE->getSourceRange();
4521 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4522 Parens.getEnd());
4523 }
4524
4525 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4526 if (isa<ImplicitValueInitExpr>(Val: Init))
4527 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4528 SourceLocation());
4529
4530 // Revert initialization by constructor back to a parenthesized or braced list
4531 // of expressions. Any other form of initializer can just be reused directly.
4532 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4533 return getDerived().TransformExpr(Init);
4534
4535 // If the initialization implicitly converted an initializer list to a
4536 // std::initializer_list object, unwrap the std::initializer_list too.
4537 if (Construct && Construct->isStdInitListInitialization())
4538 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4539
4540 // Enter a list-init context if this was list initialization.
4541 EnterExpressionEvaluationContext Context(
4542 getSema(), EnterExpressionEvaluationContext::InitList,
4543 Construct->isListInitialization());
4544
4545 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4546 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4547 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4548 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4549 SmallVector<Expr*, 8> NewArgs;
4550 bool ArgChanged = false;
4551 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4552 /*IsCall*/true, NewArgs, &ArgChanged))
4553 return ExprError();
4554
4555 // If this was list initialization, revert to syntactic list form.
4556 if (Construct->isListInitialization())
4557 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4558 Construct->getEndLoc(),
4559 /*IsExplicit=*/true);
4560
4561 // Build a ParenListExpr to represent anything else.
4562 SourceRange Parens = Construct->getParenOrBraceRange();
4563 if (Parens.isInvalid()) {
4564 // This was a variable declaration's initialization for which no initializer
4565 // was specified.
4566 assert(NewArgs.empty() &&
4567 "no parens or braces but have direct init with arguments?");
4568 return ExprEmpty();
4569 }
4570 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4571 Parens.getEnd());
4572}
4573
4574template<typename Derived>
4575bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4576 unsigned NumInputs,
4577 bool IsCall,
4578 SmallVectorImpl<Expr *> &Outputs,
4579 bool *ArgChanged) {
4580 for (unsigned I = 0; I != NumInputs; ++I) {
4581 // If requested, drop call arguments that need to be dropped.
4582 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4583 if (ArgChanged)
4584 *ArgChanged = true;
4585
4586 break;
4587 }
4588
4589 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4590 Expr *Pattern = Expansion->getPattern();
4591
4592 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4593 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4594 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4595
4596 // Determine whether the set of unexpanded parameter packs can and should
4597 // be expanded.
4598 bool Expand = true;
4599 bool RetainExpansion = false;
4600 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4601 UnsignedOrNone NumExpansions = OrigNumExpansions;
4602 if (getDerived().TryExpandParameterPacks(
4603 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4604 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4605 RetainExpansion, NumExpansions))
4606 return true;
4607
4608 if (!Expand) {
4609 // The transform has determined that we should perform a simple
4610 // transformation on the pack expansion, producing another pack
4611 // expansion.
4612 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4613 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4614 if (OutPattern.isInvalid())
4615 return true;
4616
4617 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4618 Expansion->getEllipsisLoc(),
4619 NumExpansions);
4620 if (Out.isInvalid())
4621 return true;
4622
4623 if (ArgChanged)
4624 *ArgChanged = true;
4625 Outputs.push_back(Elt: Out.get());
4626 continue;
4627 }
4628
4629 // Record right away that the argument was changed. This needs
4630 // to happen even if the array expands to nothing.
4631 if (ArgChanged) *ArgChanged = true;
4632
4633 // The transform has determined that we should perform an elementwise
4634 // expansion of the pattern. Do so.
4635 for (unsigned I = 0; I != *NumExpansions; ++I) {
4636 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4637 ExprResult Out = getDerived().TransformExpr(Pattern);
4638 if (Out.isInvalid())
4639 return true;
4640
4641 if (Out.get()->containsUnexpandedParameterPack()) {
4642 Out = getDerived().RebuildPackExpansion(
4643 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4644 if (Out.isInvalid())
4645 return true;
4646 }
4647
4648 Outputs.push_back(Elt: Out.get());
4649 }
4650
4651 // If we're supposed to retain a pack expansion, do so by temporarily
4652 // forgetting the partially-substituted parameter pack.
4653 if (RetainExpansion) {
4654 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4655
4656 ExprResult Out = getDerived().TransformExpr(Pattern);
4657 if (Out.isInvalid())
4658 return true;
4659
4660 Out = getDerived().RebuildPackExpansion(
4661 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4662 if (Out.isInvalid())
4663 return true;
4664
4665 Outputs.push_back(Elt: Out.get());
4666 }
4667
4668 continue;
4669 }
4670
4671 ExprResult Result =
4672 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4673 : getDerived().TransformExpr(Inputs[I]);
4674 if (Result.isInvalid())
4675 return true;
4676
4677 if (Result.get() != Inputs[I] && ArgChanged)
4678 *ArgChanged = true;
4679
4680 Outputs.push_back(Elt: Result.get());
4681 }
4682
4683 return false;
4684}
4685
4686template <typename Derived>
4687Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4688 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4689
4690 EnterExpressionEvaluationContext Eval(
4691 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4692 /*LambdaContextDecl=*/nullptr,
4693 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4694 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4695
4696 if (Var) {
4697 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4698 getDerived().TransformDefinition(Var->getLocation(), Var));
4699
4700 if (!ConditionVar)
4701 return Sema::ConditionError();
4702
4703 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4704 }
4705
4706 if (Expr) {
4707 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4708
4709 if (CondExpr.isInvalid())
4710 return Sema::ConditionError();
4711
4712 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4713 /*MissingOK=*/true);
4714 }
4715
4716 return Sema::ConditionResult();
4717}
4718
4719template <typename Derived>
4720NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4721 NestedNameSpecifierLoc NNS, QualType ObjectType,
4722 NamedDecl *FirstQualifierInScope) {
4723 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4724
4725 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4726 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4727 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4728 Qualifiers.push_back(Elt: Qualifier);
4729 };
4730 insertNNS(NNS);
4731
4732 CXXScopeSpec SS;
4733 while (!Qualifiers.empty()) {
4734 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4735 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4736
4737 switch (QNNS.getKind()) {
4738 case NestedNameSpecifier::Kind::Null:
4739 llvm_unreachable("unexpected null nested name specifier");
4740
4741 case NestedNameSpecifier::Kind::Namespace: {
4742 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4743 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4744 QNNS.getAsNamespaceAndPrefix().Namespace)));
4745 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4746 break;
4747 }
4748
4749 case NestedNameSpecifier::Kind::Global:
4750 // There is no meaningful transformation that one could perform on the
4751 // global scope.
4752 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4753 break;
4754
4755 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4756 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4757 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4758 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4759 ColonColonLoc: Q.getEndLoc());
4760 break;
4761 }
4762
4763 case NestedNameSpecifier::Kind::Type: {
4764 assert(SS.isEmpty());
4765 TypeLoc TL = Q.castAsTypeLoc();
4766
4767 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4768 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4769 if (QualifierLoc) {
4770 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4771 QualifierLoc, ObjectType, FirstQualifierInScope);
4772 if (!QualifierLoc)
4773 return NestedNameSpecifierLoc();
4774 ObjectType = QualType();
4775 FirstQualifierInScope = nullptr;
4776 }
4777 SS.Adopt(Other: QualifierLoc);
4778 Sema::NestedNameSpecInfo IdInfo(
4779 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4780 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4781 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4782 EnteringContext: false, SS,
4783 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4784 return NestedNameSpecifierLoc();
4785 return SS.getWithLocInContext(Context&: SemaRef.Context);
4786 }
4787
4788 QualType T = TL.getType();
4789 TypeLocBuilder TLB;
4790 if (!getDerived().AlreadyTransformed(T)) {
4791 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4792 FirstQualifierInScope);
4793 if (T.isNull())
4794 return NestedNameSpecifierLoc();
4795 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4796 }
4797
4798 if (T->isDependentType() || T->isRecordType() ||
4799 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4800 if (T->isEnumeralType())
4801 SemaRef.Diag(Loc: TL.getBeginLoc(),
4802 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4803 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4804 break;
4805 }
4806 // If the nested-name-specifier is an invalid type def, don't emit an
4807 // error because a previous error should have already been emitted.
4808 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4809 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4810 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4811 << T << SS.getRange();
4812 }
4813 return NestedNameSpecifierLoc();
4814 }
4815 }
4816 }
4817
4818 // Don't rebuild the nested-name-specifier if we don't have to.
4819 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4820 !getDerived().AlwaysRebuild())
4821 return NNS;
4822
4823 // If we can re-use the source-location data from the original
4824 // nested-name-specifier, do so.
4825 if (SS.location_size() == NNS.getDataLength() &&
4826 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4827 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4828
4829 // Allocate new nested-name-specifier location information.
4830 return SS.getWithLocInContext(Context&: SemaRef.Context);
4831}
4832
4833template<typename Derived>
4834DeclarationNameInfo
4835TreeTransform<Derived>
4836::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4837 DeclarationName Name = NameInfo.getName();
4838 if (!Name)
4839 return DeclarationNameInfo();
4840
4841 switch (Name.getNameKind()) {
4842 case DeclarationName::Identifier:
4843 case DeclarationName::ObjCZeroArgSelector:
4844 case DeclarationName::ObjCOneArgSelector:
4845 case DeclarationName::ObjCMultiArgSelector:
4846 case DeclarationName::CXXOperatorName:
4847 case DeclarationName::CXXLiteralOperatorName:
4848 case DeclarationName::CXXUsingDirective:
4849 return NameInfo;
4850
4851 case DeclarationName::CXXDeductionGuideName: {
4852 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4853 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4854 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4855 if (!NewTemplate)
4856 return DeclarationNameInfo();
4857
4858 DeclarationNameInfo NewNameInfo(NameInfo);
4859 NewNameInfo.setName(
4860 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4861 return NewNameInfo;
4862 }
4863
4864 case DeclarationName::CXXConstructorName:
4865 case DeclarationName::CXXDestructorName:
4866 case DeclarationName::CXXConversionFunctionName: {
4867 TypeSourceInfo *NewTInfo;
4868 CanQualType NewCanTy;
4869 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4870 NewTInfo = getDerived().TransformType(OldTInfo);
4871 if (!NewTInfo)
4872 return DeclarationNameInfo();
4873 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4874 }
4875 else {
4876 NewTInfo = nullptr;
4877 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4878 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4879 if (NewT.isNull())
4880 return DeclarationNameInfo();
4881 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4882 }
4883
4884 DeclarationName NewName
4885 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4886 Ty: NewCanTy);
4887 DeclarationNameInfo NewNameInfo(NameInfo);
4888 NewNameInfo.setName(NewName);
4889 NewNameInfo.setNamedTypeInfo(NewTInfo);
4890 return NewNameInfo;
4891 }
4892 }
4893
4894 llvm_unreachable("Unknown name kind.");
4895}
4896
4897template <typename Derived>
4898TemplateName TreeTransform<Derived>::RebuildTemplateName(
4899 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4900 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4901 QualType ObjectType, bool AllowInjectedClassName) {
4902 if (const IdentifierInfo *II = IO.getIdentifier())
4903 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4904 ObjectType, AllowInjectedClassName);
4905 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4906 NameLoc, ObjectType,
4907 AllowInjectedClassName);
4908}
4909
4910template <typename Derived>
4911TemplateName TreeTransform<Derived>::TransformTemplateName(
4912 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4913 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4914 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4915 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4916 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4917
4918 if (QualifierLoc) {
4919 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4920 QualifierLoc, ObjectType, FirstQualifierInScope);
4921 if (!QualifierLoc)
4922 return TemplateName();
4923 }
4924
4925 NestedNameSpecifierLoc UnderlyingQualifier;
4926 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4927 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4928 FirstQualifierInScope, AllowInjectedClassName);
4929 if (NewUnderlyingName.isNull())
4930 return TemplateName();
4931 assert(!UnderlyingQualifier && "unexpected qualifier");
4932
4933 if (!getDerived().AlwaysRebuild() &&
4934 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4935 NewUnderlyingName == UnderlyingName)
4936 return Name;
4937 CXXScopeSpec SS;
4938 SS.Adopt(Other: QualifierLoc);
4939 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4940 NewUnderlyingName);
4941 }
4942
4943 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4944 if (QualifierLoc) {
4945 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4946 QualifierLoc, ObjectType, FirstQualifierInScope);
4947 if (!QualifierLoc)
4948 return TemplateName();
4949 // The qualifier-in-scope and object type only apply to the leftmost
4950 // entity.
4951 ObjectType = QualType();
4952 }
4953
4954 if (!getDerived().AlwaysRebuild() &&
4955 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4956 ObjectType.isNull())
4957 return Name;
4958
4959 CXXScopeSpec SS;
4960 SS.Adopt(Other: QualifierLoc);
4961 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4962 NameLoc, ObjectType,
4963 AllowInjectedClassName);
4964 }
4965
4966 if (SubstTemplateTemplateParmStorage *S =
4967 Name.getAsSubstTemplateTemplateParm()) {
4968 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4969
4970 NestedNameSpecifierLoc ReplacementQualifierLoc;
4971 TemplateName ReplacementName = S->getReplacement();
4972 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4973 NestedNameSpecifierLocBuilder Builder;
4974 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4975 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4976 }
4977
4978 TemplateName NewName = getDerived().TransformTemplateName(
4979 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4980 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4981 if (NewName.isNull())
4982 return TemplateName();
4983 Decl *AssociatedDecl =
4984 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4985 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4986 AssociatedDecl == S->getAssociatedDecl())
4987 return Name;
4988 return SemaRef.Context.getSubstTemplateTemplateParm(
4989 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4990 Final: S->getFinal());
4991 }
4992
4993 if (PackIndexingTemplateStorage *PI = Name.getAsPackIndexingTemplate()) {
4994 assert(!QualifierLoc && "Unexpected qualified pack-index-template-name");
4995
4996 ExprResult IndexExpr;
4997 {
4998 EnterExpressionEvaluationContext ConstantContext(
4999 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5000 IndexExpr = getDerived().TransformExpr(PI->getIndexExpr());
5001 if (IndexExpr.isInvalid())
5002 return TemplateName();
5003 }
5004
5005 auto TransformOne = [&](TemplateName N) {
5006 NestedNameSpecifierLoc NoQualifier;
5007 return getDerived().TransformTemplateName(
5008 NoQualifier, TemplateKWLoc, N, NameLoc, ObjectType,
5009 FirstQualifierInScope, AllowInjectedClassName);
5010 };
5011
5012 TemplateName Pattern = PI->getPattern();
5013 SmallVector<TemplateName, 4> SubstitutedNames;
5014 ArrayRef<TemplateName> Names = PI->getExpansions();
5015
5016 bool NotYetExpanded = Names.empty();
5017 bool FullySubstituted = true;
5018
5019 if (Names.empty() && !PI->expandsToEmptyPack())
5020 Names = ArrayRef(&Pattern, 1);
5021
5022 for (TemplateName N : Names) {
5023 if (!N.containsUnexpandedParameterPack()) {
5024 TemplateName Transformed = TransformOne(N);
5025 if (Transformed.isNull())
5026 return TemplateName();
5027 SubstitutedNames.push_back(Elt: Transformed);
5028 continue;
5029 }
5030
5031 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5032 getSema().collectUnexpandedParameterPacks(N, Unexpanded);
5033 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5034
5035 bool ShouldExpand = true;
5036 bool RetainExpansion = false;
5037 UnsignedOrNone NumExpansions = std::nullopt;
5038 if (getDerived().TryExpandParameterPacks(
5039 NameLoc, SourceRange(), Unexpanded,
5040 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
5041 RetainExpansion, NumExpansions))
5042 return TemplateName();
5043
5044 if (!ShouldExpand) {
5045 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5046 TemplateName Pack = TransformOne(N);
5047 if (Pack.isNull())
5048 return TemplateName();
5049 if (NotYetExpanded) {
5050 FullySubstituted = false;
5051 return getDerived().RebuildPackIndexingTemplateName(
5052 Pack, IndexExpr.get(), FullySubstituted);
5053 }
5054 SubstitutedNames.push_back(Elt: Pack);
5055 continue;
5056 }
5057
5058 for (unsigned I = 0; I != *NumExpansions; ++I) {
5059 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5060 TemplateName Out = TransformOne(N);
5061 if (Out.isNull())
5062 return TemplateName();
5063 SubstitutedNames.push_back(Elt: Out);
5064 FullySubstituted &= !Out.containsUnexpandedParameterPack();
5065 }
5066
5067 // If we're supposed to retain a pack expansion, do so by temporarily
5068 // forgetting the partially-substituted parameter pack.
5069 if (RetainExpansion) {
5070 FullySubstituted = false;
5071 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5072 TemplateName Out = TransformOne(N);
5073 if (Out.isNull())
5074 return TemplateName();
5075 SubstitutedNames.push_back(Elt: Out);
5076 }
5077 }
5078
5079 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5080 TemplateName NewPattern = TransformOne(Pattern);
5081 if (NewPattern.isNull())
5082 return TemplateName();
5083
5084 return getDerived().RebuildPackIndexingTemplateName(
5085 NewPattern, IndexExpr.get(), FullySubstituted, SubstitutedNames);
5086 }
5087
5088 assert(!Name.getAsDeducedTemplateName() &&
5089 "DeducedTemplateName should not escape partial ordering");
5090
5091 // FIXME: Preserve UsingTemplateName.
5092 if (auto *Template = Name.getAsTemplateDecl()) {
5093 assert(!QualifierLoc && "Unexpected qualifier");
5094 return TemplateName(cast_or_null<TemplateDecl>(
5095 getDerived().TransformDecl(NameLoc, Template)));
5096 }
5097
5098 if (SubstTemplateTemplateParmPackStorage *SubstPack
5099 = Name.getAsSubstTemplateTemplateParmPack()) {
5100 assert(!QualifierLoc &&
5101 "Unexpected qualified SubstTemplateTemplateParmPack");
5102 return getDerived().RebuildTemplateName(
5103 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
5104 SubstPack->getIndex(), SubstPack->getFinal());
5105 }
5106
5107 // These should be getting filtered out before they reach the AST.
5108 llvm_unreachable("overloaded function decl survived to here");
5109}
5110
5111template <typename Derived>
5112TemplateName
5113TreeTransform<Derived>::TransformConceptTemplateName(TemplateName Name,
5114 SourceLocation NameLoc) {
5115 NestedNameSpecifierLoc QualifierLoc;
5116 return getDerived().TransformTemplateName(
5117 QualifierLoc, /*TemplateKWLoc=*/SourceLocation(), Name, NameLoc);
5118}
5119
5120template <typename Derived>
5121TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
5122 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
5123 TemplateName Name, SourceLocation NameLoc) {
5124 TemplateName TN = getDerived().TransformTemplateName(
5125 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
5126 if (TN.isNull())
5127 return TemplateArgument();
5128 return TemplateArgument(TN);
5129}
5130
5131template<typename Derived>
5132void TreeTransform<Derived>::InventTemplateArgumentLoc(
5133 const TemplateArgument &Arg,
5134 TemplateArgumentLoc &Output) {
5135 Output = getSema().getTrivialTemplateArgumentLoc(
5136 Arg, QualType(), getDerived().getBaseLocation());
5137}
5138
5139template <typename Derived>
5140bool TreeTransform<Derived>::TransformTemplateArgument(
5141 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5142 bool Uneval) {
5143 const TemplateArgument &Arg = Input.getArgument();
5144 switch (Arg.getKind()) {
5145 case TemplateArgument::Null:
5146 case TemplateArgument::Pack:
5147 llvm_unreachable("Unexpected TemplateArgument");
5148
5149 case TemplateArgument::Integral:
5150 case TemplateArgument::NullPtr:
5151 case TemplateArgument::Declaration:
5152 case TemplateArgument::StructuralValue: {
5153 // Transform a resolved template argument straight to a resolved template
5154 // argument. We get here when substituting into an already-substituted
5155 // template type argument during concept satisfaction checking.
5156 QualType T = Arg.getNonTypeTemplateArgumentType();
5157 QualType NewT = getDerived().TransformType(T);
5158 if (NewT.isNull())
5159 return true;
5160
5161 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5162 ? Arg.getAsDecl()
5163 : nullptr;
5164 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5165 getDerived().getBaseLocation(), D))
5166 : nullptr;
5167 if (D && !NewD)
5168 return true;
5169
5170 if (NewT == T && D == NewD)
5171 Output = Input;
5172 else if (Arg.getKind() == TemplateArgument::Integral)
5173 Output = TemplateArgumentLoc(
5174 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5175 TemplateArgumentLocInfo());
5176 else if (Arg.getKind() == TemplateArgument::NullPtr)
5177 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5178 TemplateArgumentLocInfo());
5179 else if (Arg.getKind() == TemplateArgument::Declaration)
5180 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5181 TemplateArgumentLocInfo());
5182 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5183 Output = TemplateArgumentLoc(
5184 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5185 TemplateArgumentLocInfo());
5186 else
5187 llvm_unreachable("unexpected template argument kind");
5188
5189 return false;
5190 }
5191
5192 case TemplateArgument::Type: {
5193 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5194 if (!TSI)
5195 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5196
5197 TSI = getDerived().TransformType(TSI);
5198 if (!TSI)
5199 return true;
5200
5201 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5202 return false;
5203 }
5204
5205 case TemplateArgument::Template: {
5206 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5207
5208 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5209 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5210 Input.getTemplateNameLoc());
5211 if (Out.isNull())
5212 return true;
5213 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5214 QualifierLoc, Input.getTemplateNameLoc());
5215 return false;
5216 }
5217
5218 case TemplateArgument::TemplateExpansion:
5219 llvm_unreachable("Caller should expand pack expansions");
5220
5221 case TemplateArgument::Expression: {
5222 // Template argument expressions are constant expressions.
5223 EnterExpressionEvaluationContext Unevaluated(
5224 getSema(),
5225 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5226 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5227 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5228 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5229
5230 Expr *InputExpr = Input.getSourceExpression();
5231 if (!InputExpr)
5232 InputExpr = Input.getArgument().getAsExpr();
5233
5234 ExprResult E = getDerived().TransformExpr(InputExpr);
5235 E = SemaRef.ActOnConstantExpression(Res: E);
5236 if (E.isInvalid())
5237 return true;
5238 Output = TemplateArgumentLoc(
5239 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5240 return false;
5241 }
5242 }
5243
5244 // Work around bogus GCC warning
5245 return true;
5246}
5247
5248/// Iterator adaptor that invents template argument location information
5249/// for each of the template arguments in its underlying iterator.
5250template<typename Derived, typename InputIterator>
5251class TemplateArgumentLocInventIterator {
5252 TreeTransform<Derived> &Self;
5253 InputIterator Iter;
5254
5255public:
5256 typedef TemplateArgumentLoc value_type;
5257 typedef TemplateArgumentLoc reference;
5258 typedef typename std::iterator_traits<InputIterator>::difference_type
5259 difference_type;
5260 typedef std::input_iterator_tag iterator_category;
5261
5262 class pointer {
5263 TemplateArgumentLoc Arg;
5264
5265 public:
5266 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5267
5268 const TemplateArgumentLoc *operator->() const { return &Arg; }
5269 };
5270
5271 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5272 InputIterator Iter)
5273 : Self(Self), Iter(Iter) { }
5274
5275 TemplateArgumentLocInventIterator &operator++() {
5276 ++Iter;
5277 return *this;
5278 }
5279
5280 TemplateArgumentLocInventIterator operator++(int) {
5281 TemplateArgumentLocInventIterator Old(*this);
5282 ++(*this);
5283 return Old;
5284 }
5285
5286 reference operator*() const {
5287 TemplateArgumentLoc Result;
5288 Self.InventTemplateArgumentLoc(*Iter, Result);
5289 return Result;
5290 }
5291
5292 pointer operator->() const { return pointer(**this); }
5293
5294 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5295 const TemplateArgumentLocInventIterator &Y) {
5296 return X.Iter == Y.Iter;
5297 }
5298
5299 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5300 const TemplateArgumentLocInventIterator &Y) {
5301 return X.Iter != Y.Iter;
5302 }
5303};
5304
5305template<typename Derived>
5306template<typename InputIterator>
5307bool TreeTransform<Derived>::TransformTemplateArguments(
5308 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5309 bool Uneval) {
5310 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5311 TemplateArgumentLoc Out;
5312 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5313 // Unpack argument packs, which we translate them into separate
5314 // arguments.
5315 // FIXME: We could do much better if we could guarantee that the
5316 // TemplateArgumentLocInfo for the pack expansion would be usable for
5317 // all of the template arguments in the argument pack.
5318 typedef TemplateArgumentLocInventIterator<Derived,
5319 TemplateArgument::pack_iterator>
5320 PackLocIterator;
5321
5322 TemplateArgumentListInfo *PackOutput = &Outputs;
5323 TemplateArgumentListInfo New;
5324
5325 if (TransformTemplateArguments(
5326 PackLocIterator(*this, In.getArgument().pack_begin()),
5327 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5328 Uneval))
5329 return true;
5330
5331 continue;
5332 }
5333
5334 if (In.getArgument().isPackExpansion()) {
5335 UnexpandedInfo Info;
5336 TemplateArgumentLoc Prepared;
5337 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5338 return true;
5339 if (!Info.Expand) {
5340 Outputs.addArgument(Loc: Prepared);
5341 continue;
5342 }
5343
5344 // The transform has determined that we should perform an elementwise
5345 // expansion of the pattern. Do so.
5346 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5347 if (Info.ExpandUnderForgetSubstitions)
5348 ForgetSubst.emplace(getDerived());
5349 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5350 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5351
5352 TemplateArgumentLoc Out;
5353 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5354 return true;
5355
5356 if (Out.getArgument().containsUnexpandedParameterPack()) {
5357 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5358 Info.OrigNumExpansions);
5359 if (Out.getArgument().isNull())
5360 return true;
5361 }
5362
5363 Outputs.addArgument(Loc: Out);
5364 }
5365
5366 // If we're supposed to retain a pack expansion, do so by temporarily
5367 // forgetting the partially-substituted parameter pack.
5368 if (Info.RetainExpansion) {
5369 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5370
5371 TemplateArgumentLoc Out;
5372 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5373 return true;
5374
5375 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5376 Info.OrigNumExpansions);
5377 if (Out.getArgument().isNull())
5378 return true;
5379
5380 Outputs.addArgument(Loc: Out);
5381 }
5382
5383 continue;
5384 }
5385
5386 // The simple case:
5387 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5388 return true;
5389
5390 Outputs.addArgument(Loc: Out);
5391 }
5392
5393 return false;
5394}
5395
5396template <typename Derived>
5397template <typename InputIterator>
5398bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5399 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5400 bool Uneval) {
5401
5402 // [C++26][temp.constr.normal]
5403 // any non-dependent concept template argument
5404 // is substituted into the constraint-expression of C.
5405 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5406 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5407 };
5408
5409 for (; First != Last; ++First) {
5410 TemplateArgumentLoc Out;
5411 TemplateArgumentLoc In = *First;
5412
5413 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5414 typedef TemplateArgumentLocInventIterator<Derived,
5415 TemplateArgument::pack_iterator>
5416 PackLocIterator;
5417 if (TransformConceptTemplateArguments(
5418 PackLocIterator(*this, In.getArgument().pack_begin()),
5419 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5420 Uneval))
5421 return true;
5422 continue;
5423 }
5424
5425 if (!isNonDependentConceptArgument(In.getArgument())) {
5426 Outputs.addArgument(Loc: In);
5427 continue;
5428 }
5429
5430 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5431 return true;
5432
5433 Outputs.addArgument(Loc: Out);
5434 }
5435
5436 return false;
5437}
5438
5439// FIXME: Find ways to reduce code duplication for pack expansions.
5440template <typename Derived>
5441bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5442 bool Uneval,
5443 TemplateArgumentLoc &Out,
5444 UnexpandedInfo &Info) {
5445 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5446 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5447 TemplateArgumentLoc &Pattern) {
5448 assert(Arg.getArgument().isPackExpansion());
5449 // We have a pack expansion, for which we will be substituting into the
5450 // pattern.
5451 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5452 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5453 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5454 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5455 if (IsLateExpansionAttempt) {
5456 // Request expansion only when there is an opportunity to expand a pack
5457 // that required a substituion first.
5458 bool SawPackTypes =
5459 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5460 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5461 });
5462 if (!SawPackTypes) {
5463 Info.Expand = false;
5464 return false;
5465 }
5466 }
5467 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5468
5469 // Determine whether the set of unexpanded parameter packs can and
5470 // should be expanded.
5471 Info.Expand = true;
5472 Info.RetainExpansion = false;
5473 Info.NumExpansions = Info.OrigNumExpansions;
5474 return getDerived().TryExpandParameterPacks(
5475 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5476 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5477 Info.RetainExpansion, Info.NumExpansions);
5478 };
5479
5480 TemplateArgumentLoc Pattern;
5481 if (ComputeInfo(In, false, Info, Pattern))
5482 return true;
5483
5484 if (Info.Expand) {
5485 Out = Pattern;
5486 return false;
5487 }
5488
5489 // The transform has determined that we should perform a simple
5490 // transformation on the pack expansion, producing another pack
5491 // expansion.
5492 TemplateArgumentLoc OutPattern;
5493 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5494 std::in_place, getSema(), std::nullopt);
5495 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5496 return true;
5497
5498 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5499 Info.NumExpansions);
5500 if (Out.getArgument().isNull())
5501 return true;
5502 SubstIndex.reset();
5503
5504 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5505 return false;
5506
5507 // Some packs will learn their length after substitution, e.g.
5508 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5509 // value of `T`.
5510 //
5511 // We only expand after we know sizes of all packs, check if this is the case
5512 // or not. However, we avoid a full template substitution and only do
5513 // expanstions after this point.
5514
5515 // E.g. when substituting template arguments of tuple with {T -> int} in the
5516 // following example:
5517 // template <class T>
5518 // struct TupleWithInt {
5519 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5520 // };
5521 // TupleWithInt<int>::type y;
5522 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5523 // length and run `ComputeInfo()` to provide the necessary information to our
5524 // caller.
5525 //
5526 // Note that we may still have situations where builtin is not going to be
5527 // expanded. For example:
5528 // template <class T>
5529 // struct Foo {
5530 // template <class U> using tuple_with_t =
5531 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5532 // tuple_with_t<short>;
5533 // }
5534 // Because the substitution into `type` happens in dependent context, `type`
5535 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5536 // and the caller will not be able to expand it.
5537 ForgetSubstitutionRAII ForgetSubst(getDerived());
5538 if (ComputeInfo(Out, true, Info, OutPattern))
5539 return true;
5540 if (!Info.Expand)
5541 return false;
5542 Out = OutPattern;
5543 Info.ExpandUnderForgetSubstitions = true;
5544 return false;
5545}
5546
5547//===----------------------------------------------------------------------===//
5548// Type transformation
5549//===----------------------------------------------------------------------===//
5550
5551template<typename Derived>
5552QualType TreeTransform<Derived>::TransformType(QualType T) {
5553 if (getDerived().AlreadyTransformed(T))
5554 return T;
5555
5556 // Temporary workaround. All of these transformations should
5557 // eventually turn into transformations on TypeLocs.
5558 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5559 T, getDerived().getBaseLocation());
5560
5561 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5562
5563 if (!NewTSI)
5564 return QualType();
5565
5566 return NewTSI->getType();
5567}
5568
5569template <typename Derived>
5570TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5571 // Refine the base location to the type's location.
5572 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5573 getDerived().getBaseEntity());
5574 if (getDerived().AlreadyTransformed(TSI->getType()))
5575 return TSI;
5576
5577 TypeLocBuilder TLB;
5578
5579 TypeLoc TL = TSI->getTypeLoc();
5580 TLB.reserve(Requested: TL.getFullDataSize());
5581
5582 QualType Result = getDerived().TransformType(TLB, TL);
5583 if (Result.isNull())
5584 return nullptr;
5585
5586 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5587}
5588
5589template<typename Derived>
5590QualType
5591TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5592 switch (T.getTypeLocClass()) {
5593#define ABSTRACT_TYPELOC(CLASS, PARENT)
5594#define TYPELOC(CLASS, PARENT) \
5595 case TypeLoc::CLASS: \
5596 return getDerived().Transform##CLASS##Type(TLB, \
5597 T.castAs<CLASS##TypeLoc>());
5598#include "clang/AST/TypeLocNodes.def"
5599 }
5600
5601 llvm_unreachable("unhandled type loc!");
5602}
5603
5604template<typename Derived>
5605QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5606 if (!isa<DependentNameType>(Val: T))
5607 return TransformType(T);
5608
5609 if (getDerived().AlreadyTransformed(T))
5610 return T;
5611 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5612 T, getDerived().getBaseLocation());
5613 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5614 return NewTSI ? NewTSI->getType() : QualType();
5615}
5616
5617template <typename Derived>
5618TypeSourceInfo *
5619TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5620 if (!isa<DependentNameType>(Val: TSI->getType()))
5621 return TransformType(TSI);
5622
5623 // Refine the base location to the type's location.
5624 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5625 getDerived().getBaseEntity());
5626 if (getDerived().AlreadyTransformed(TSI->getType()))
5627 return TSI;
5628
5629 TypeLocBuilder TLB;
5630
5631 TypeLoc TL = TSI->getTypeLoc();
5632 TLB.reserve(Requested: TL.getFullDataSize());
5633
5634 auto QTL = TL.getAs<QualifiedTypeLoc>();
5635 if (QTL)
5636 TL = QTL.getUnqualifiedLoc();
5637
5638 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5639
5640 QualType Result = getDerived().TransformDependentNameType(
5641 TLB, DNTL, /*DeducedTSTContext*/true);
5642 if (Result.isNull())
5643 return nullptr;
5644
5645 if (QTL) {
5646 Result = getDerived().RebuildQualifiedType(Result, QTL);
5647 if (Result.isNull())
5648 return nullptr;
5649 TLB.TypeWasModifiedSafely(T: Result);
5650 }
5651
5652 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5653}
5654
5655template<typename Derived>
5656QualType
5657TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5658 QualifiedTypeLoc T) {
5659 QualType Result;
5660 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5661 auto SuppressObjCLifetime =
5662 T.getType().getLocalQualifiers().hasObjCLifetime();
5663 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5664 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5665 SuppressObjCLifetime);
5666 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5667 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5668 TLB, STTP, SuppressObjCLifetime);
5669 } else {
5670 Result = getDerived().TransformType(TLB, UnqualTL);
5671 }
5672
5673 if (Result.isNull())
5674 return QualType();
5675
5676 Result = getDerived().RebuildQualifiedType(Result, T);
5677
5678 if (Result.isNull())
5679 return QualType();
5680
5681 // RebuildQualifiedType might have updated the type, but not in a way
5682 // that invalidates the TypeLoc. (There's no location information for
5683 // qualifiers.)
5684 TLB.TypeWasModifiedSafely(T: Result);
5685
5686 return Result;
5687}
5688
5689template <typename Derived>
5690QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5691 QualifiedTypeLoc TL) {
5692
5693 SourceLocation Loc = TL.getBeginLoc();
5694 Qualifiers Quals = TL.getType().getLocalQualifiers();
5695
5696 if ((T.getAddressSpace() != LangAS::Default &&
5697 Quals.getAddressSpace() != LangAS::Default) &&
5698 T.getAddressSpace() != Quals.getAddressSpace()) {
5699 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5700 << TL.getType() << T;
5701 return QualType();
5702 }
5703
5704 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5705 if (LocalPointerAuth.isPresent()) {
5706 if (T.getPointerAuth().isPresent()) {
5707 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5708 return QualType();
5709 }
5710 if (!T->isDependentType()) {
5711 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5712 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5713 return QualType();
5714 }
5715 }
5716 }
5717 // C++ [dcl.fct]p7:
5718 // [When] adding cv-qualifications on top of the function type [...] the
5719 // cv-qualifiers are ignored.
5720 if (T->isFunctionType()) {
5721 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5722 AddressSpace: Quals.getAddressSpace());
5723 return T;
5724 }
5725
5726 // C++ [dcl.ref]p1:
5727 // when the cv-qualifiers are introduced through the use of a typedef-name
5728 // or decltype-specifier [...] the cv-qualifiers are ignored.
5729 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5730 // applied to a reference type.
5731 if (T->isReferenceType()) {
5732 // The only qualifier that applies to a reference type is restrict.
5733 if (!Quals.hasRestrict())
5734 return T;
5735 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5736 }
5737
5738 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5739 // resulting type.
5740 if (Quals.hasObjCLifetime()) {
5741 if (!T->isObjCLifetimeType() && !T->isDependentType())
5742 Quals.removeObjCLifetime();
5743 else if (T.getObjCLifetime()) {
5744 // Objective-C ARC:
5745 // A lifetime qualifier applied to a substituted template parameter
5746 // overrides the lifetime qualifier from the template argument.
5747 const AutoType *AutoTy;
5748 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5749 // 'auto' types behave the same way as template parameters.
5750 QualType Deduced = AutoTy->getDeducedType();
5751 Qualifiers Qs = Deduced.getQualifiers();
5752 Qs.removeObjCLifetime();
5753 Deduced =
5754 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5755 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5756 Keyword: AutoTy->getKeyword(),
5757 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5758 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5759 } else {
5760 // Otherwise, complain about the addition of a qualifier to an
5761 // already-qualified type.
5762 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5763 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5764 Quals.removeObjCLifetime();
5765 }
5766 }
5767 }
5768
5769 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5770}
5771
5772template <typename Derived>
5773QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5774 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5775 NamedDecl *FirstQualifierInScope) {
5776 assert(!getDerived().AlreadyTransformed(TL.getType()));
5777
5778 switch (TL.getTypeLocClass()) {
5779 case TypeLoc::TemplateSpecialization:
5780 return getDerived().TransformTemplateSpecializationType(
5781 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5782 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5783 case TypeLoc::DependentName:
5784 return getDerived().TransformDependentNameType(
5785 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5786 ObjectType, FirstQualifierInScope);
5787 default:
5788 // Any dependent canonical type can appear here, through type alias
5789 // templates.
5790 return getDerived().TransformType(TLB, TL);
5791 }
5792}
5793
5794template <class TyLoc> static inline
5795QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5796 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5797 NewT.setNameLoc(T.getNameLoc());
5798 return T.getType();
5799}
5800
5801template<typename Derived>
5802QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5803 BuiltinTypeLoc T) {
5804 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5805 NewT.setBuiltinLoc(T.getBuiltinLoc());
5806 if (T.needsExtraLocalData())
5807 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5808 return T.getType();
5809}
5810
5811template<typename Derived>
5812QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5813 ComplexTypeLoc T) {
5814 // FIXME: recurse?
5815 return TransformTypeSpecType(TLB, T);
5816}
5817
5818template <typename Derived>
5819QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5820 AdjustedTypeLoc TL) {
5821 // Adjustments applied during transformation are handled elsewhere.
5822 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5823}
5824
5825template<typename Derived>
5826QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5827 DecayedTypeLoc TL) {
5828 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5829 if (OriginalType.isNull())
5830 return QualType();
5831
5832 QualType Result = TL.getType();
5833 if (getDerived().AlwaysRebuild() ||
5834 OriginalType != TL.getOriginalLoc().getType())
5835 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5836 TLB.push<DecayedTypeLoc>(T: Result);
5837 // Nothing to set for DecayedTypeLoc.
5838 return Result;
5839}
5840
5841template <typename Derived>
5842QualType
5843TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5844 ArrayParameterTypeLoc TL) {
5845 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5846 if (OriginalType.isNull())
5847 return QualType();
5848
5849 QualType Result = TL.getType();
5850 if (getDerived().AlwaysRebuild() ||
5851 OriginalType != TL.getElementLoc().getType())
5852 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5853 TLB.push<ArrayParameterTypeLoc>(T: Result);
5854 // Nothing to set for ArrayParameterTypeLoc.
5855 return Result;
5856}
5857
5858template<typename Derived>
5859QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5860 PointerTypeLoc TL) {
5861 QualType PointeeType
5862 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5863 if (PointeeType.isNull())
5864 return QualType();
5865
5866 QualType Result = TL.getType();
5867 if (PointeeType->getAs<ObjCObjectType>()) {
5868 // A dependent pointer type 'T *' has is being transformed such
5869 // that an Objective-C class type is being replaced for 'T'. The
5870 // resulting pointer type is an ObjCObjectPointerType, not a
5871 // PointerType.
5872 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5873
5874 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5875 NewT.setStarLoc(TL.getStarLoc());
5876 return Result;
5877 }
5878
5879 if (getDerived().AlwaysRebuild() ||
5880 PointeeType != TL.getPointeeLoc().getType()) {
5881 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5882 if (Result.isNull())
5883 return QualType();
5884 }
5885
5886 // Objective-C ARC can add lifetime qualifiers to the type that we're
5887 // pointing to.
5888 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5889
5890 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5891 NewT.setSigilLoc(TL.getSigilLoc());
5892 return Result;
5893}
5894
5895template<typename Derived>
5896QualType
5897TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5898 BlockPointerTypeLoc TL) {
5899 QualType PointeeType
5900 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5901 if (PointeeType.isNull())
5902 return QualType();
5903
5904 QualType Result = TL.getType();
5905 if (getDerived().AlwaysRebuild() ||
5906 PointeeType != TL.getPointeeLoc().getType()) {
5907 Result = getDerived().RebuildBlockPointerType(PointeeType,
5908 TL.getSigilLoc());
5909 if (Result.isNull())
5910 return QualType();
5911 }
5912
5913 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5914 NewT.setSigilLoc(TL.getSigilLoc());
5915 return Result;
5916}
5917
5918/// Transforms a reference type. Note that somewhat paradoxically we
5919/// don't care whether the type itself is an l-value type or an r-value
5920/// type; we only care if the type was *written* as an l-value type
5921/// or an r-value type.
5922template<typename Derived>
5923QualType
5924TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5925 ReferenceTypeLoc TL) {
5926 const ReferenceType *T = TL.getTypePtr();
5927
5928 // Note that this works with the pointee-as-written.
5929 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5930 if (PointeeType.isNull())
5931 return QualType();
5932
5933 QualType Result = TL.getType();
5934 if (getDerived().AlwaysRebuild() ||
5935 PointeeType != T->getPointeeTypeAsWritten()) {
5936 Result = getDerived().RebuildReferenceType(PointeeType,
5937 T->isSpelledAsLValue(),
5938 TL.getSigilLoc());
5939 if (Result.isNull())
5940 return QualType();
5941 }
5942
5943 // Objective-C ARC can add lifetime qualifiers to the type that we're
5944 // referring to.
5945 TLB.TypeWasModifiedSafely(
5946 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5947
5948 // r-value references can be rebuilt as l-value references.
5949 ReferenceTypeLoc NewTL;
5950 if (isa<LValueReferenceType>(Val: Result))
5951 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5952 else
5953 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5954 NewTL.setSigilLoc(TL.getSigilLoc());
5955
5956 return Result;
5957}
5958
5959template<typename Derived>
5960QualType
5961TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5962 LValueReferenceTypeLoc TL) {
5963 return TransformReferenceType(TLB, TL);
5964}
5965
5966template<typename Derived>
5967QualType
5968TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5969 RValueReferenceTypeLoc TL) {
5970 return TransformReferenceType(TLB, TL);
5971}
5972
5973template<typename Derived>
5974QualType
5975TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5976 MemberPointerTypeLoc TL) {
5977 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5978 if (PointeeType.isNull())
5979 return QualType();
5980
5981 const MemberPointerType *T = TL.getTypePtr();
5982
5983 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5984 NestedNameSpecifierLoc NewQualifierLoc =
5985 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5986 if (!NewQualifierLoc)
5987 return QualType();
5988
5989 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5990 if (OldCls) {
5991 NewCls = cast_or_null<CXXRecordDecl>(
5992 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5993 if (!NewCls)
5994 return QualType();
5995 }
5996
5997 QualType Result = TL.getType();
5998 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5999 NewQualifierLoc.getNestedNameSpecifier() !=
6000 OldQualifierLoc.getNestedNameSpecifier() ||
6001 NewCls != OldCls) {
6002 CXXScopeSpec SS;
6003 SS.Adopt(Other: NewQualifierLoc);
6004 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
6005 TL.getStarLoc());
6006 if (Result.isNull())
6007 return QualType();
6008 }
6009
6010 // If we had to adjust the pointee type when building a member pointer, make
6011 // sure to push TypeLoc info for it.
6012 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
6013 if (MPT && PointeeType != MPT->getPointeeType()) {
6014 assert(isa<AdjustedType>(MPT->getPointeeType()));
6015 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
6016 }
6017
6018 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
6019 NewTL.setSigilLoc(TL.getSigilLoc());
6020 NewTL.setQualifierLoc(NewQualifierLoc);
6021
6022 return Result;
6023}
6024
6025template<typename Derived>
6026QualType
6027TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
6028 ConstantArrayTypeLoc TL) {
6029 const ConstantArrayType *T = TL.getTypePtr();
6030 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6031 if (ElementType.isNull())
6032 return QualType();
6033
6034 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6035 Expr *OldSize = TL.getSizeExpr();
6036 if (!OldSize)
6037 OldSize = const_cast<Expr*>(T->getSizeExpr());
6038 Expr *NewSize = nullptr;
6039 if (OldSize) {
6040 EnterExpressionEvaluationContext Unevaluated(
6041 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6042 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
6043 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
6044 }
6045
6046 QualType Result = TL.getType();
6047 if (getDerived().AlwaysRebuild() ||
6048 ElementType != T->getElementType() ||
6049 (T->getSizeExpr() && NewSize != OldSize)) {
6050 Result = getDerived().RebuildConstantArrayType(ElementType,
6051 T->getSizeModifier(),
6052 T->getSize(), NewSize,
6053 T->getIndexTypeCVRQualifiers(),
6054 TL.getBracketsRange());
6055 if (Result.isNull())
6056 return QualType();
6057 }
6058
6059 // We might have either a ConstantArrayType or a VariableArrayType now:
6060 // a ConstantArrayType is allowed to have an element type which is a
6061 // VariableArrayType if the type is dependent. Fortunately, all array
6062 // types have the same location layout.
6063 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6064 NewTL.setLBracketLoc(TL.getLBracketLoc());
6065 NewTL.setRBracketLoc(TL.getRBracketLoc());
6066 NewTL.setSizeExpr(NewSize);
6067
6068 return Result;
6069}
6070
6071template<typename Derived>
6072QualType TreeTransform<Derived>::TransformIncompleteArrayType(
6073 TypeLocBuilder &TLB,
6074 IncompleteArrayTypeLoc TL) {
6075 const IncompleteArrayType *T = TL.getTypePtr();
6076 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6077 if (ElementType.isNull())
6078 return QualType();
6079
6080 QualType Result = TL.getType();
6081 if (getDerived().AlwaysRebuild() ||
6082 ElementType != T->getElementType()) {
6083 Result = getDerived().RebuildIncompleteArrayType(ElementType,
6084 T->getSizeModifier(),
6085 T->getIndexTypeCVRQualifiers(),
6086 TL.getBracketsRange());
6087 if (Result.isNull())
6088 return QualType();
6089 }
6090
6091 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
6092 NewTL.setLBracketLoc(TL.getLBracketLoc());
6093 NewTL.setRBracketLoc(TL.getRBracketLoc());
6094 NewTL.setSizeExpr(nullptr);
6095
6096 return Result;
6097}
6098
6099template<typename Derived>
6100QualType
6101TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
6102 VariableArrayTypeLoc TL) {
6103 const VariableArrayType *T = TL.getTypePtr();
6104 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6105 if (ElementType.isNull())
6106 return QualType();
6107
6108 ExprResult SizeResult;
6109 {
6110 EnterExpressionEvaluationContext Context(
6111 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
6112 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
6113 }
6114 if (SizeResult.isInvalid())
6115 return QualType();
6116 SizeResult =
6117 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
6118 if (SizeResult.isInvalid())
6119 return QualType();
6120
6121 Expr *Size = SizeResult.get();
6122
6123 QualType Result = TL.getType();
6124 if (getDerived().AlwaysRebuild() ||
6125 ElementType != T->getElementType() ||
6126 Size != T->getSizeExpr()) {
6127 Result = getDerived().RebuildVariableArrayType(ElementType,
6128 T->getSizeModifier(),
6129 Size,
6130 T->getIndexTypeCVRQualifiers(),
6131 TL.getBracketsRange());
6132 if (Result.isNull())
6133 return QualType();
6134 }
6135
6136 // We might have constant size array now, but fortunately it has the same
6137 // location layout.
6138 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6139 NewTL.setLBracketLoc(TL.getLBracketLoc());
6140 NewTL.setRBracketLoc(TL.getRBracketLoc());
6141 NewTL.setSizeExpr(Size);
6142
6143 return Result;
6144}
6145
6146template<typename Derived>
6147QualType
6148TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6149 DependentSizedArrayTypeLoc TL) {
6150 const DependentSizedArrayType *T = TL.getTypePtr();
6151 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6152 if (ElementType.isNull())
6153 return QualType();
6154
6155 // Array bounds are constant expressions.
6156 EnterExpressionEvaluationContext Unevaluated(
6157 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6158
6159 // If we have a VLA then it won't be a constant.
6160 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6161
6162 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6163 Expr *origSize = TL.getSizeExpr();
6164 if (!origSize) origSize = T->getSizeExpr();
6165
6166 ExprResult sizeResult
6167 = getDerived().TransformExpr(origSize);
6168 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6169 if (sizeResult.isInvalid())
6170 return QualType();
6171
6172 Expr *size = sizeResult.get();
6173
6174 QualType Result = TL.getType();
6175 if (getDerived().AlwaysRebuild() ||
6176 ElementType != T->getElementType() ||
6177 size != origSize) {
6178 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6179 T->getSizeModifier(),
6180 size,
6181 T->getIndexTypeCVRQualifiers(),
6182 TL.getBracketsRange());
6183 if (Result.isNull())
6184 return QualType();
6185 }
6186
6187 // We might have any sort of array type now, but fortunately they
6188 // all have the same location layout.
6189 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6190 NewTL.setLBracketLoc(TL.getLBracketLoc());
6191 NewTL.setRBracketLoc(TL.getRBracketLoc());
6192 NewTL.setSizeExpr(size);
6193
6194 return Result;
6195}
6196
6197template <typename Derived>
6198QualType TreeTransform<Derived>::TransformDependentVectorType(
6199 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6200 const DependentVectorType *T = TL.getTypePtr();
6201 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6202 if (ElementType.isNull())
6203 return QualType();
6204
6205 EnterExpressionEvaluationContext Unevaluated(
6206 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6207
6208 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6209 Size = SemaRef.ActOnConstantExpression(Res: Size);
6210 if (Size.isInvalid())
6211 return QualType();
6212
6213 QualType Result = TL.getType();
6214 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6215 Size.get() != T->getSizeExpr()) {
6216 Result = getDerived().RebuildDependentVectorType(
6217 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6218 if (Result.isNull())
6219 return QualType();
6220 }
6221
6222 // Result might be dependent or not.
6223 if (isa<DependentVectorType>(Val: Result)) {
6224 DependentVectorTypeLoc NewTL =
6225 TLB.push<DependentVectorTypeLoc>(T: Result);
6226 NewTL.setNameLoc(TL.getNameLoc());
6227 } else {
6228 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6229 NewTL.setNameLoc(TL.getNameLoc());
6230 }
6231
6232 return Result;
6233}
6234
6235template<typename Derived>
6236QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6237 TypeLocBuilder &TLB,
6238 DependentSizedExtVectorTypeLoc TL) {
6239 const DependentSizedExtVectorType *T = TL.getTypePtr();
6240
6241 // FIXME: ext vector locs should be nested
6242 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6243 if (ElementType.isNull())
6244 return QualType();
6245
6246 // Vector sizes are constant expressions.
6247 EnterExpressionEvaluationContext Unevaluated(
6248 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6249
6250 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6251 Size = SemaRef.ActOnConstantExpression(Res: Size);
6252 if (Size.isInvalid())
6253 return QualType();
6254
6255 QualType Result = TL.getType();
6256 if (getDerived().AlwaysRebuild() ||
6257 ElementType != T->getElementType() ||
6258 Size.get() != T->getSizeExpr()) {
6259 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6260 Size.get(),
6261 T->getAttributeLoc());
6262 if (Result.isNull())
6263 return QualType();
6264 }
6265
6266 // Result might be dependent or not.
6267 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6268 DependentSizedExtVectorTypeLoc NewTL
6269 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6270 NewTL.setNameLoc(TL.getNameLoc());
6271 } else {
6272 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6273 NewTL.setNameLoc(TL.getNameLoc());
6274 }
6275
6276 return Result;
6277}
6278
6279template <typename Derived>
6280QualType
6281TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6282 ConstantMatrixTypeLoc TL) {
6283 const ConstantMatrixType *T = TL.getTypePtr();
6284 QualType ElementType = getDerived().TransformType(T->getElementType());
6285 if (ElementType.isNull())
6286 return QualType();
6287
6288 QualType Result = TL.getType();
6289 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6290 Result = getDerived().RebuildConstantMatrixType(
6291 ElementType, T->getNumRows(), T->getNumColumns());
6292 if (Result.isNull())
6293 return QualType();
6294 }
6295
6296 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6297 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6298 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6299 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6300 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6301
6302 return Result;
6303}
6304
6305template <typename Derived>
6306QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6307 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6308 const DependentSizedMatrixType *T = TL.getTypePtr();
6309
6310 QualType ElementType = getDerived().TransformType(T->getElementType());
6311 if (ElementType.isNull()) {
6312 return QualType();
6313 }
6314
6315 // Matrix dimensions are constant expressions.
6316 EnterExpressionEvaluationContext Unevaluated(
6317 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6318
6319 Expr *origRows = TL.getAttrRowOperand();
6320 if (!origRows)
6321 origRows = T->getRowExpr();
6322 Expr *origColumns = TL.getAttrColumnOperand();
6323 if (!origColumns)
6324 origColumns = T->getColumnExpr();
6325
6326 ExprResult rowResult = getDerived().TransformExpr(origRows);
6327 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6328 if (rowResult.isInvalid())
6329 return QualType();
6330
6331 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6332 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6333 if (columnResult.isInvalid())
6334 return QualType();
6335
6336 Expr *rows = rowResult.get();
6337 Expr *columns = columnResult.get();
6338
6339 QualType Result = TL.getType();
6340 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6341 rows != origRows || columns != origColumns) {
6342 Result = getDerived().RebuildDependentSizedMatrixType(
6343 ElementType, rows, columns, T->getAttributeLoc());
6344
6345 if (Result.isNull())
6346 return QualType();
6347 }
6348
6349 // We might have any sort of matrix type now, but fortunately they
6350 // all have the same location layout.
6351 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6352 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6353 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6354 NewTL.setAttrRowOperand(rows);
6355 NewTL.setAttrColumnOperand(columns);
6356 return Result;
6357}
6358
6359template <typename Derived>
6360QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6361 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6362 const DependentAddressSpaceType *T = TL.getTypePtr();
6363
6364 QualType pointeeType =
6365 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6366
6367 if (pointeeType.isNull())
6368 return QualType();
6369
6370 // Address spaces are constant expressions.
6371 EnterExpressionEvaluationContext Unevaluated(
6372 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6373
6374 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6375 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6376 if (AddrSpace.isInvalid())
6377 return QualType();
6378
6379 QualType Result = TL.getType();
6380 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6381 AddrSpace.get() != T->getAddrSpaceExpr()) {
6382 Result = getDerived().RebuildDependentAddressSpaceType(
6383 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6384 if (Result.isNull())
6385 return QualType();
6386 }
6387
6388 // Result might be dependent or not.
6389 if (isa<DependentAddressSpaceType>(Val: Result)) {
6390 DependentAddressSpaceTypeLoc NewTL =
6391 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6392
6393 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6394 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6395 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6396
6397 } else {
6398 TLB.TypeWasModifiedSafely(T: Result);
6399 }
6400
6401 return Result;
6402}
6403
6404template <typename Derived>
6405QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6406 VectorTypeLoc TL) {
6407 const VectorType *T = TL.getTypePtr();
6408 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6409 if (ElementType.isNull())
6410 return QualType();
6411
6412 QualType Result = TL.getType();
6413 if (getDerived().AlwaysRebuild() ||
6414 ElementType != T->getElementType()) {
6415 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6416 T->getVectorKind());
6417 if (Result.isNull())
6418 return QualType();
6419 }
6420
6421 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6422 NewTL.setNameLoc(TL.getNameLoc());
6423
6424 return Result;
6425}
6426
6427template<typename Derived>
6428QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6429 ExtVectorTypeLoc TL) {
6430 const VectorType *T = TL.getTypePtr();
6431 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6432 if (ElementType.isNull())
6433 return QualType();
6434
6435 QualType Result = TL.getType();
6436 if (getDerived().AlwaysRebuild() ||
6437 ElementType != T->getElementType()) {
6438 Result = getDerived().RebuildExtVectorType(ElementType,
6439 T->getNumElements(),
6440 /*FIXME*/ SourceLocation());
6441 if (Result.isNull())
6442 return QualType();
6443 }
6444
6445 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6446 NewTL.setNameLoc(TL.getNameLoc());
6447
6448 return Result;
6449}
6450
6451template <typename Derived>
6452ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6453 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6454 bool ExpectParameterPack) {
6455 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6456 TypeSourceInfo *NewTSI = nullptr;
6457
6458 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6459 // If we're substituting into a pack expansion type and we know the
6460 // length we want to expand to, just substitute for the pattern.
6461 TypeLoc OldTL = OldTSI->getTypeLoc();
6462 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6463
6464 TypeLocBuilder TLB;
6465 TypeLoc NewTL = OldTSI->getTypeLoc();
6466 TLB.reserve(Requested: NewTL.getFullDataSize());
6467
6468 QualType Result = getDerived().TransformType(TLB,
6469 OldExpansionTL.getPatternLoc());
6470 if (Result.isNull())
6471 return nullptr;
6472
6473 Result = RebuildPackExpansionType(Pattern: Result,
6474 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6475 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6476 NumExpansions);
6477 if (Result.isNull())
6478 return nullptr;
6479
6480 PackExpansionTypeLoc NewExpansionTL
6481 = TLB.push<PackExpansionTypeLoc>(T: Result);
6482 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6483 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6484 } else
6485 NewTSI = getDerived().TransformType(OldTSI);
6486 if (!NewTSI)
6487 return nullptr;
6488
6489 if (NewTSI == OldTSI && indexAdjustment == 0)
6490 return OldParm;
6491
6492 ParmVarDecl *newParm = ParmVarDecl::Create(
6493 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6494 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6495 TInfo: NewTSI, S: OldParm->getStorageClass(),
6496 /* DefArg */ DefArg: nullptr);
6497 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6498 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6499 getDerived().transformedLocalDecl(OldParm, {newParm});
6500 return newParm;
6501}
6502
6503template <typename Derived>
6504bool TreeTransform<Derived>::TransformFunctionTypeParams(
6505 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6506 const QualType *ParamTypes,
6507 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6508 SmallVectorImpl<QualType> &OutParamTypes,
6509 SmallVectorImpl<ParmVarDecl *> *PVars,
6510 Sema::ExtParameterInfoBuilder &PInfos,
6511 unsigned *LastParamTransformed) {
6512 int indexAdjustment = 0;
6513
6514 unsigned NumParams = Params.size();
6515 for (unsigned i = 0; i != NumParams; ++i) {
6516 if (LastParamTransformed)
6517 *LastParamTransformed = i;
6518 if (ParmVarDecl *OldParm = Params[i]) {
6519 assert(OldParm->getFunctionScopeIndex() == i);
6520
6521 UnsignedOrNone NumExpansions = std::nullopt;
6522 ParmVarDecl *NewParm = nullptr;
6523 if (OldParm->isParameterPack()) {
6524 // We have a function parameter pack that may need to be expanded.
6525 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6526
6527 // Find the parameter packs that could be expanded.
6528 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6529 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6530 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6531 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6532
6533 // Determine whether we should expand the parameter packs.
6534 bool ShouldExpand = false;
6535 bool RetainExpansion = false;
6536 UnsignedOrNone OrigNumExpansions = std::nullopt;
6537 if (Unexpanded.size() > 0) {
6538 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6539 NumExpansions = OrigNumExpansions;
6540 if (getDerived().TryExpandParameterPacks(
6541 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6542 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6543 ShouldExpand, RetainExpansion, NumExpansions)) {
6544 return true;
6545 }
6546 } else {
6547#ifndef NDEBUG
6548 const AutoType *AT =
6549 Pattern.getType().getTypePtr()->getContainedAutoType();
6550 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6551 "Could not find parameter packs or undeduced auto type!");
6552#endif
6553 }
6554
6555 if (ShouldExpand) {
6556 // Expand the function parameter pack into multiple, separate
6557 // parameters.
6558 getDerived().ExpandingFunctionParameterPack(OldParm);
6559 for (unsigned I = 0; I != *NumExpansions; ++I) {
6560 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6561 ParmVarDecl *NewParm
6562 = getDerived().TransformFunctionTypeParam(OldParm,
6563 indexAdjustment++,
6564 OrigNumExpansions,
6565 /*ExpectParameterPack=*/false);
6566 if (!NewParm)
6567 return true;
6568
6569 if (ParamInfos)
6570 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6571 OutParamTypes.push_back(Elt: NewParm->getType());
6572 if (PVars)
6573 PVars->push_back(Elt: NewParm);
6574 }
6575
6576 // If we're supposed to retain a pack expansion, do so by temporarily
6577 // forgetting the partially-substituted parameter pack.
6578 if (RetainExpansion) {
6579 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6580 ParmVarDecl *NewParm
6581 = getDerived().TransformFunctionTypeParam(OldParm,
6582 indexAdjustment++,
6583 OrigNumExpansions,
6584 /*ExpectParameterPack=*/false);
6585 if (!NewParm)
6586 return true;
6587
6588 if (ParamInfos)
6589 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6590 OutParamTypes.push_back(Elt: NewParm->getType());
6591 if (PVars)
6592 PVars->push_back(Elt: NewParm);
6593 }
6594
6595 // The next parameter should have the same adjustment as the
6596 // last thing we pushed, but we post-incremented indexAdjustment
6597 // on every push. Also, if we push nothing, the adjustment should
6598 // go down by one.
6599 indexAdjustment--;
6600
6601 // We're done with the pack expansion.
6602 continue;
6603 }
6604
6605 // We'll substitute the parameter now without expanding the pack
6606 // expansion.
6607 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6608 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6609 indexAdjustment,
6610 NumExpansions,
6611 /*ExpectParameterPack=*/true);
6612 assert(NewParm->isParameterPack() &&
6613 "Parameter pack no longer a parameter pack after "
6614 "transformation.");
6615 } else {
6616 NewParm = getDerived().TransformFunctionTypeParam(
6617 OldParm, indexAdjustment, std::nullopt,
6618 /*ExpectParameterPack=*/false);
6619 }
6620
6621 if (!NewParm)
6622 return true;
6623
6624 if (ParamInfos)
6625 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6626 OutParamTypes.push_back(Elt: NewParm->getType());
6627 if (PVars)
6628 PVars->push_back(Elt: NewParm);
6629 continue;
6630 }
6631
6632 // Deal with the possibility that we don't have a parameter
6633 // declaration for this parameter.
6634 assert(ParamTypes);
6635 QualType OldType = ParamTypes[i];
6636 bool IsPackExpansion = false;
6637 UnsignedOrNone NumExpansions = std::nullopt;
6638 QualType NewType;
6639 if (const PackExpansionType *Expansion
6640 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6641 // We have a function parameter pack that may need to be expanded.
6642 QualType Pattern = Expansion->getPattern();
6643 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6644 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6645
6646 // Determine whether we should expand the parameter packs.
6647 bool ShouldExpand = false;
6648 bool RetainExpansion = false;
6649 if (getDerived().TryExpandParameterPacks(
6650 Loc, SourceRange(), Unexpanded,
6651 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6652 RetainExpansion, NumExpansions)) {
6653 return true;
6654 }
6655
6656 if (ShouldExpand) {
6657 // Expand the function parameter pack into multiple, separate
6658 // parameters.
6659 for (unsigned I = 0; I != *NumExpansions; ++I) {
6660 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6661 QualType NewType = getDerived().TransformType(Pattern);
6662 if (NewType.isNull())
6663 return true;
6664
6665 if (NewType->containsUnexpandedParameterPack()) {
6666 NewType = getSema().getASTContext().getPackExpansionType(
6667 NewType, std::nullopt);
6668
6669 if (NewType.isNull())
6670 return true;
6671 }
6672
6673 if (ParamInfos)
6674 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6675 OutParamTypes.push_back(Elt: NewType);
6676 if (PVars)
6677 PVars->push_back(Elt: nullptr);
6678 }
6679
6680 // We're done with the pack expansion.
6681 continue;
6682 }
6683
6684 // If we're supposed to retain a pack expansion, do so by temporarily
6685 // forgetting the partially-substituted parameter pack.
6686 if (RetainExpansion) {
6687 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6688 QualType NewType = getDerived().TransformType(Pattern);
6689 if (NewType.isNull())
6690 return true;
6691
6692 if (ParamInfos)
6693 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6694 OutParamTypes.push_back(Elt: NewType);
6695 if (PVars)
6696 PVars->push_back(Elt: nullptr);
6697 }
6698
6699 // We'll substitute the parameter now without expanding the pack
6700 // expansion.
6701 OldType = Expansion->getPattern();
6702 IsPackExpansion = true;
6703 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6704 NewType = getDerived().TransformType(OldType);
6705 } else {
6706 NewType = getDerived().TransformType(OldType);
6707 }
6708
6709 if (NewType.isNull())
6710 return true;
6711
6712 if (IsPackExpansion)
6713 NewType = getSema().Context.getPackExpansionType(NewType,
6714 NumExpansions);
6715
6716 if (ParamInfos)
6717 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6718 OutParamTypes.push_back(Elt: NewType);
6719 if (PVars)
6720 PVars->push_back(Elt: nullptr);
6721 }
6722
6723#ifndef NDEBUG
6724 if (PVars) {
6725 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6726 if (ParmVarDecl *parm = (*PVars)[i])
6727 assert(parm->getFunctionScopeIndex() == i);
6728 }
6729#endif
6730
6731 return false;
6732}
6733
6734template<typename Derived>
6735QualType
6736TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6737 FunctionProtoTypeLoc TL) {
6738 SmallVector<QualType, 4> ExceptionStorage;
6739 return getDerived().TransformFunctionProtoType(
6740 TLB, TL, nullptr, Qualifiers(),
6741 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6742 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6743 ExceptionStorage, Changed);
6744 });
6745}
6746
6747template<typename Derived> template<typename Fn>
6748QualType TreeTransform<Derived>::TransformFunctionProtoType(
6749 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6750 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6751
6752 // Transform the parameters and return type.
6753 //
6754 // We are required to instantiate the params and return type in source order.
6755 // When the function has a trailing return type, we instantiate the
6756 // parameters before the return type, since the return type can then refer
6757 // to the parameters themselves (via decltype, sizeof, etc.).
6758 //
6759 SmallVector<QualType, 4> ParamTypes;
6760 SmallVector<ParmVarDecl*, 4> ParamDecls;
6761 Sema::ExtParameterInfoBuilder ExtParamInfos;
6762 const FunctionProtoType *T = TL.getTypePtr();
6763
6764 QualType ResultType;
6765
6766 if (T->hasTrailingReturn()) {
6767 if (getDerived().TransformFunctionTypeParams(
6768 TL.getBeginLoc(), TL.getParams(),
6769 TL.getTypePtr()->param_type_begin(),
6770 T->getExtParameterInfosOrNull(),
6771 ParamTypes, &ParamDecls, ExtParamInfos))
6772 return QualType();
6773
6774 {
6775 // C++11 [expr.prim.general]p3:
6776 // If a declaration declares a member function or member function
6777 // template of a class X, the expression this is a prvalue of type
6778 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6779 // and the end of the function-definition, member-declarator, or
6780 // declarator.
6781 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6782 Sema::CXXThisScopeRAII ThisScope(
6783 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6784
6785 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6786 if (ResultType.isNull())
6787 return QualType();
6788 }
6789 }
6790 else {
6791 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6792 if (ResultType.isNull())
6793 return QualType();
6794
6795 if (getDerived().TransformFunctionTypeParams(
6796 TL.getBeginLoc(), TL.getParams(),
6797 TL.getTypePtr()->param_type_begin(),
6798 T->getExtParameterInfosOrNull(),
6799 ParamTypes, &ParamDecls, ExtParamInfos))
6800 return QualType();
6801 }
6802
6803 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6804
6805 bool EPIChanged = false;
6806 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6807 return QualType();
6808
6809 // Handle extended parameter information.
6810 if (auto NewExtParamInfos =
6811 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6812 if (!EPI.ExtParameterInfos ||
6813 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6814 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6815 EPIChanged = true;
6816 }
6817 EPI.ExtParameterInfos = NewExtParamInfos;
6818 } else if (EPI.ExtParameterInfos) {
6819 EPIChanged = true;
6820 EPI.ExtParameterInfos = nullptr;
6821 }
6822
6823 // Transform any function effects with unevaluated conditions.
6824 // Hold this set in a local for the rest of this function, since EPI
6825 // may need to hold a FunctionEffectsRef pointing into it.
6826 std::optional<FunctionEffectSet> NewFX;
6827 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6828 NewFX.emplace();
6829 EnterExpressionEvaluationContext Unevaluated(
6830 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6831
6832 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6833 FunctionEffectWithCondition NewEC = PrevEC;
6834 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6835 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6836 if (NewExpr.isInvalid())
6837 return QualType();
6838 std::optional<FunctionEffectMode> Mode =
6839 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6840 if (!Mode)
6841 return QualType();
6842
6843 // The condition expression has been transformed, and re-evaluated.
6844 // It may or may not have become constant.
6845 switch (*Mode) {
6846 case FunctionEffectMode::True:
6847 NewEC.Cond = {};
6848 break;
6849 case FunctionEffectMode::False:
6850 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6851 NewEC.Cond = {};
6852 break;
6853 case FunctionEffectMode::Dependent:
6854 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6855 break;
6856 case FunctionEffectMode::None:
6857 llvm_unreachable(
6858 "FunctionEffectMode::None shouldn't be possible here");
6859 }
6860 }
6861 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6862 NewAttrLoc: TL.getBeginLoc())) {
6863 FunctionEffectSet::Conflicts Errs;
6864 NewFX->insert(NewEC, Errs);
6865 assert(Errs.empty());
6866 }
6867 }
6868 EPI.FunctionEffects = *NewFX;
6869 EPIChanged = true;
6870 }
6871
6872 QualType Result = TL.getType();
6873 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6874 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6875 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6876 if (Result.isNull())
6877 return QualType();
6878 }
6879
6880 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6881 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6882 NewTL.setLParenLoc(TL.getLParenLoc());
6883 NewTL.setRParenLoc(TL.getRParenLoc());
6884 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6885 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6886 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6887 NewTL.setParam(i, VD: ParamDecls[i]);
6888
6889 return Result;
6890}
6891
6892template<typename Derived>
6893bool TreeTransform<Derived>::TransformExceptionSpec(
6894 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6895 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6896 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6897
6898 // Instantiate a dynamic noexcept expression, if any.
6899 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6900 // Update this scrope because ContextDecl in Sema will be used in
6901 // TransformExpr.
6902 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6903 Sema::CXXThisScopeRAII ThisScope(
6904 SemaRef, Method ? Method->getParent() : nullptr,
6905 Method ? Method->getMethodQualifiers() : Qualifiers{},
6906 Method != nullptr);
6907 EnterExpressionEvaluationContext Unevaluated(
6908 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6909 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6910 if (NoexceptExpr.isInvalid())
6911 return true;
6912
6913 ExceptionSpecificationType EST = ESI.Type;
6914 NoexceptExpr =
6915 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6916 if (NoexceptExpr.isInvalid())
6917 return true;
6918
6919 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6920 Changed = true;
6921 ESI.NoexceptExpr = NoexceptExpr.get();
6922 ESI.Type = EST;
6923 }
6924
6925 if (ESI.Type != EST_Dynamic)
6926 return false;
6927
6928 // Instantiate a dynamic exception specification's type.
6929 for (QualType T : ESI.Exceptions) {
6930 if (const PackExpansionType *PackExpansion =
6931 T->getAs<PackExpansionType>()) {
6932 Changed = true;
6933
6934 // We have a pack expansion. Instantiate it.
6935 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6936 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6937 Unexpanded);
6938 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6939
6940 // Determine whether the set of unexpanded parameter packs can and
6941 // should
6942 // be expanded.
6943 bool Expand = false;
6944 bool RetainExpansion = false;
6945 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6946 // FIXME: Track the location of the ellipsis (and track source location
6947 // information for the types in the exception specification in general).
6948 if (getDerived().TryExpandParameterPacks(
6949 Loc, SourceRange(), Unexpanded,
6950 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6951 NumExpansions))
6952 return true;
6953
6954 if (!Expand) {
6955 // We can't expand this pack expansion into separate arguments yet;
6956 // just substitute into the pattern and create a new pack expansion
6957 // type.
6958 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6959 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6960 if (U.isNull())
6961 return true;
6962
6963 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6964 Exceptions.push_back(Elt: U);
6965 continue;
6966 }
6967
6968 // Substitute into the pack expansion pattern for each slice of the
6969 // pack.
6970 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6971 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6972
6973 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6974 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6975 return true;
6976
6977 Exceptions.push_back(Elt: U);
6978 }
6979 } else {
6980 QualType U = getDerived().TransformType(T);
6981 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6982 return true;
6983 if (T != U)
6984 Changed = true;
6985
6986 Exceptions.push_back(Elt: U);
6987 }
6988 }
6989
6990 ESI.Exceptions = Exceptions;
6991 if (ESI.Exceptions.empty())
6992 ESI.Type = EST_DynamicNone;
6993 return false;
6994}
6995
6996template<typename Derived>
6997QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6998 TypeLocBuilder &TLB,
6999 FunctionNoProtoTypeLoc TL) {
7000 const FunctionNoProtoType *T = TL.getTypePtr();
7001 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
7002 if (ResultType.isNull())
7003 return QualType();
7004
7005 QualType Result = TL.getType();
7006 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
7007 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
7008
7009 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
7010 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
7011 NewTL.setLParenLoc(TL.getLParenLoc());
7012 NewTL.setRParenLoc(TL.getRParenLoc());
7013 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
7014
7015 return Result;
7016}
7017
7018template <typename Derived>
7019QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
7020 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
7021
7022 const UnresolvedUsingType *T = TL.getTypePtr();
7023 bool Changed = false;
7024
7025 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7026 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7027 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7028 if (!QualifierLoc)
7029 return QualType();
7030 Changed |= QualifierLoc != OldQualifierLoc;
7031 }
7032
7033 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
7034 if (!D)
7035 return QualType();
7036 Changed |= D != T->getDecl();
7037
7038 QualType Result = TL.getType();
7039 if (getDerived().AlwaysRebuild() || Changed) {
7040 Result = getDerived().RebuildUnresolvedUsingType(
7041 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
7042 D);
7043 if (Result.isNull())
7044 return QualType();
7045 }
7046
7047 if (isa<UsingType>(Val: Result))
7048 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7049 QualifierLoc, NameLoc: TL.getNameLoc());
7050 else
7051 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7052 QualifierLoc, NameLoc: TL.getNameLoc());
7053 return Result;
7054}
7055
7056template <typename Derived>
7057QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
7058 UsingTypeLoc TL) {
7059 const UsingType *T = TL.getTypePtr();
7060 bool Changed = false;
7061
7062 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7063 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7064 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7065 if (!QualifierLoc)
7066 return QualType();
7067 Changed |= QualifierLoc != OldQualifierLoc;
7068 }
7069
7070 auto *D = cast_or_null<UsingShadowDecl>(
7071 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7072 if (!D)
7073 return QualType();
7074 Changed |= D != T->getDecl();
7075
7076 QualType UnderlyingType = getDerived().TransformType(T->desugar());
7077 if (UnderlyingType.isNull())
7078 return QualType();
7079 Changed |= UnderlyingType != T->desugar();
7080
7081 QualType Result = TL.getType();
7082 if (getDerived().AlwaysRebuild() || Changed) {
7083 Result = getDerived().RebuildUsingType(
7084 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
7085 UnderlyingType);
7086 if (Result.isNull())
7087 return QualType();
7088 }
7089 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
7090 NameLoc: TL.getNameLoc());
7091 return Result;
7092}
7093
7094template<typename Derived>
7095QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
7096 TypedefTypeLoc TL) {
7097 const TypedefType *T = TL.getTypePtr();
7098 bool Changed = false;
7099
7100 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7101 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7102 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7103 if (!QualifierLoc)
7104 return QualType();
7105 Changed |= QualifierLoc != OldQualifierLoc;
7106 }
7107
7108 auto *Typedef = cast_or_null<TypedefNameDecl>(
7109 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7110 if (!Typedef)
7111 return QualType();
7112 Changed |= Typedef != T->getDecl();
7113
7114 // FIXME: Transform the UnderlyingType if different from decl.
7115
7116 QualType Result = TL.getType();
7117 if (getDerived().AlwaysRebuild() || Changed) {
7118 Result = getDerived().RebuildTypedefType(
7119 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
7120 if (Result.isNull())
7121 return QualType();
7122 }
7123
7124 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7125 QualifierLoc, NameLoc: TL.getNameLoc());
7126 return Result;
7127}
7128
7129template<typename Derived>
7130QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
7131 TypeOfExprTypeLoc TL) {
7132 // typeof expressions are not potentially evaluated contexts
7133 EnterExpressionEvaluationContext Unevaluated(
7134 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7135 Sema::ReuseLambdaContextDecl);
7136
7137 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7138 if (E.isInvalid())
7139 return QualType();
7140
7141 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7142 if (E.isInvalid())
7143 return QualType();
7144
7145 QualType Result = TL.getType();
7146 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7147 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7148 Result =
7149 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7150 if (Result.isNull())
7151 return QualType();
7152 }
7153
7154 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7155 NewTL.setTypeofLoc(TL.getTypeofLoc());
7156 NewTL.setLParenLoc(TL.getLParenLoc());
7157 NewTL.setRParenLoc(TL.getRParenLoc());
7158
7159 return Result;
7160}
7161
7162template<typename Derived>
7163QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7164 TypeOfTypeLoc TL) {
7165 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7166 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7167 if (!New_Under_TI)
7168 return QualType();
7169
7170 QualType Result = TL.getType();
7171 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7172 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7173 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7174 if (Result.isNull())
7175 return QualType();
7176 }
7177
7178 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7179 NewTL.setTypeofLoc(TL.getTypeofLoc());
7180 NewTL.setLParenLoc(TL.getLParenLoc());
7181 NewTL.setRParenLoc(TL.getRParenLoc());
7182 NewTL.setUnmodifiedTInfo(New_Under_TI);
7183
7184 return Result;
7185}
7186
7187template<typename Derived>
7188QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7189 DecltypeTypeLoc TL) {
7190 const DecltypeType *T = TL.getTypePtr();
7191
7192 // decltype expressions are not potentially evaluated contexts
7193 EnterExpressionEvaluationContext Unevaluated(
7194 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7195 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7196
7197 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7198 if (E.isInvalid())
7199 return QualType();
7200
7201 E = getSema().ActOnDecltypeExpression(E.get());
7202 if (E.isInvalid())
7203 return QualType();
7204
7205 QualType Result = TL.getType();
7206 if (getDerived().AlwaysRebuild() ||
7207 E.get() != T->getUnderlyingExpr()) {
7208 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7209 if (Result.isNull())
7210 return QualType();
7211 }
7212 else E.get();
7213
7214 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7215 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7216 NewTL.setRParenLoc(TL.getRParenLoc());
7217 return Result;
7218}
7219
7220template <typename Derived>
7221QualType
7222TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7223 PackIndexingTypeLoc TL) {
7224 // Transform the index
7225 ExprResult IndexExpr;
7226 {
7227 EnterExpressionEvaluationContext ConstantContext(
7228 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7229
7230 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7231 if (IndexExpr.isInvalid())
7232 return QualType();
7233 }
7234 QualType Pattern = TL.getPattern();
7235
7236 const PackIndexingType *PIT = TL.getTypePtr();
7237 SmallVector<QualType, 5> SubtitutedTypes;
7238 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7239
7240 bool NotYetExpanded = Types.empty();
7241 bool FullySubstituted = true;
7242
7243 if (Types.empty() && !PIT->expandsToEmptyPack())
7244 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7245
7246 for (QualType T : Types) {
7247 if (!T->containsUnexpandedParameterPack()) {
7248 QualType Transformed = getDerived().TransformType(T);
7249 if (Transformed.isNull())
7250 return QualType();
7251 SubtitutedTypes.push_back(Elt: Transformed);
7252 continue;
7253 }
7254
7255 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7256 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7257 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7258 // Determine whether the set of unexpanded parameter packs can and should
7259 // be expanded.
7260 bool ShouldExpand = true;
7261 bool RetainExpansion = false;
7262 UnsignedOrNone NumExpansions = std::nullopt;
7263 if (getDerived().TryExpandParameterPacks(
7264 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7265 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7266 RetainExpansion, NumExpansions))
7267 return QualType();
7268 if (!ShouldExpand) {
7269 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7270 // FIXME: should we keep TypeLoc for individual expansions in
7271 // PackIndexingTypeLoc?
7272 TypeSourceInfo *TI =
7273 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7274 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7275 if (Pack.isNull())
7276 return QualType();
7277 if (NotYetExpanded) {
7278 FullySubstituted = false;
7279 QualType Out = getDerived().RebuildPackIndexingType(
7280 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7281 FullySubstituted);
7282 if (Out.isNull())
7283 return QualType();
7284
7285 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7286 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7287 return Out;
7288 }
7289 SubtitutedTypes.push_back(Elt: Pack);
7290 continue;
7291 }
7292 for (unsigned I = 0; I != *NumExpansions; ++I) {
7293 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7294 QualType Out = getDerived().TransformType(T);
7295 if (Out.isNull())
7296 return QualType();
7297 SubtitutedTypes.push_back(Elt: Out);
7298 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7299 }
7300 // If we're supposed to retain a pack expansion, do so by temporarily
7301 // forgetting the partially-substituted parameter pack.
7302 if (RetainExpansion) {
7303 FullySubstituted = false;
7304 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7305 QualType Out = getDerived().TransformType(T);
7306 if (Out.isNull())
7307 return QualType();
7308 SubtitutedTypes.push_back(Elt: Out);
7309 }
7310 }
7311
7312 // A pack indexing type can appear in a larger pack expansion,
7313 // e.g. `Pack...[pack_of_indexes]...`
7314 // so we need to temporarily disable substitution of pack elements
7315 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7316 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7317
7318 QualType Out = getDerived().RebuildPackIndexingType(
7319 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7320 FullySubstituted, SubtitutedTypes);
7321 if (Out.isNull())
7322 return Out;
7323
7324 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7325 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7326 return Out;
7327}
7328
7329template<typename Derived>
7330QualType TreeTransform<Derived>::TransformUnaryTransformType(
7331 TypeLocBuilder &TLB,
7332 UnaryTransformTypeLoc TL) {
7333 QualType Result = TL.getType();
7334 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7335 if (Result->isDependentType()) {
7336 const UnaryTransformType *T = TL.getTypePtr();
7337
7338 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7339 if (!NewBaseTSI)
7340 return QualType();
7341 QualType NewBase = NewBaseTSI->getType();
7342
7343 Result = getDerived().RebuildUnaryTransformType(NewBase,
7344 T->getUTTKind(),
7345 TL.getKWLoc());
7346 if (Result.isNull())
7347 return QualType();
7348 }
7349
7350 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7351 NewTL.setKWLoc(TL.getKWLoc());
7352 NewTL.setParensRange(TL.getParensRange());
7353 NewTL.setUnderlyingTInfo(NewBaseTSI);
7354 return Result;
7355}
7356
7357template<typename Derived>
7358QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7359 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7360 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7361
7362 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7363 TemplateName TemplateName = getDerived().TransformTemplateName(
7364 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7365 TL.getTemplateNameLoc());
7366 if (TemplateName.isNull())
7367 return QualType();
7368
7369 QualType OldDeduced = T->getDeducedType();
7370 QualType NewDeduced;
7371 if (!OldDeduced.isNull()) {
7372 NewDeduced = getDerived().TransformType(OldDeduced);
7373 if (NewDeduced.isNull())
7374 return QualType();
7375 }
7376
7377 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7378 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7379 NewDeduced, T->getKeyword(), TemplateName);
7380 if (Result.isNull())
7381 return QualType();
7382
7383 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7384 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7385 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7386 NewTL.setQualifierLoc(QualifierLoc);
7387 return Result;
7388}
7389
7390template <typename Derived>
7391QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7392 TagTypeLoc TL) {
7393 const TagType *T = TL.getTypePtr();
7394
7395 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7396 if (QualifierLoc) {
7397 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7398 if (!QualifierLoc)
7399 return QualType();
7400 }
7401
7402 auto *TD = cast_or_null<TagDecl>(
7403 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7404 if (!TD)
7405 return QualType();
7406
7407 QualType Result = TL.getType();
7408 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7409 TD != T->getDecl()) {
7410 if (T->isCanonicalUnqualified())
7411 Result = getDerived().RebuildCanonicalTagType(TD);
7412 else
7413 Result = getDerived().RebuildTagType(
7414 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7415 if (Result.isNull())
7416 return QualType();
7417 }
7418
7419 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7420 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7421 NewTL.setQualifierLoc(QualifierLoc);
7422 NewTL.setNameLoc(TL.getNameLoc());
7423
7424 return Result;
7425}
7426
7427template <typename Derived>
7428QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7429 EnumTypeLoc TL) {
7430 return getDerived().TransformTagType(TLB, TL);
7431}
7432
7433template <typename Derived>
7434QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7435 RecordTypeLoc TL) {
7436 return getDerived().TransformTagType(TLB, TL);
7437}
7438
7439template<typename Derived>
7440QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7441 TypeLocBuilder &TLB,
7442 InjectedClassNameTypeLoc TL) {
7443 return getDerived().TransformTagType(TLB, TL);
7444}
7445
7446template<typename Derived>
7447QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7448 TypeLocBuilder &TLB,
7449 TemplateTypeParmTypeLoc TL) {
7450 return getDerived().TransformTemplateTypeParmType(
7451 TLB, TL,
7452 /*SuppressObjCLifetime=*/false);
7453}
7454
7455template <typename Derived>
7456QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7457 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7458 return TransformTypeSpecType(TLB, T: TL);
7459}
7460
7461template<typename Derived>
7462QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7463 TypeLocBuilder &TLB,
7464 SubstTemplateTypeParmTypeLoc TL) {
7465 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7466
7467 Decl *NewReplaced =
7468 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7469
7470 // Substitute into the replacement type, which itself might involve something
7471 // that needs to be transformed. This only tends to occur with default
7472 // template arguments of template template parameters.
7473 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7474 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7475 if (Replacement.isNull())
7476 return QualType();
7477
7478 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7479 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7480 Final: T->getFinal());
7481
7482 // Propagate type-source information.
7483 SubstTemplateTypeParmTypeLoc NewTL
7484 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7485 NewTL.setNameLoc(TL.getNameLoc());
7486 return Result;
7487
7488}
7489template <typename Derived>
7490QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7491 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7492 return TransformTypeSpecType(TLB, T: TL);
7493}
7494
7495template<typename Derived>
7496QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7497 TypeLocBuilder &TLB,
7498 SubstTemplateTypeParmPackTypeLoc TL) {
7499 return getDerived().TransformSubstTemplateTypeParmPackType(
7500 TLB, TL, /*SuppressObjCLifetime=*/false);
7501}
7502
7503template <typename Derived>
7504QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7505 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7506 return TransformTypeSpecType(TLB, T: TL);
7507}
7508
7509template<typename Derived>
7510QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7511 AtomicTypeLoc TL) {
7512 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7513 if (ValueType.isNull())
7514 return QualType();
7515
7516 QualType Result = TL.getType();
7517 if (getDerived().AlwaysRebuild() ||
7518 ValueType != TL.getValueLoc().getType()) {
7519 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7520 if (Result.isNull())
7521 return QualType();
7522 }
7523
7524 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7525 NewTL.setKWLoc(TL.getKWLoc());
7526 NewTL.setLParenLoc(TL.getLParenLoc());
7527 NewTL.setRParenLoc(TL.getRParenLoc());
7528
7529 return Result;
7530}
7531
7532template <typename Derived>
7533QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7534 PipeTypeLoc TL) {
7535 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7536 if (ValueType.isNull())
7537 return QualType();
7538
7539 QualType Result = TL.getType();
7540 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7541 const PipeType *PT = Result->castAs<PipeType>();
7542 bool isReadPipe = PT->isReadOnly();
7543 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7544 if (Result.isNull())
7545 return QualType();
7546 }
7547
7548 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7549 NewTL.setKWLoc(TL.getKWLoc());
7550
7551 return Result;
7552}
7553
7554template <typename Derived>
7555QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7556 BitIntTypeLoc TL) {
7557 const BitIntType *EIT = TL.getTypePtr();
7558 QualType Result = TL.getType();
7559
7560 if (getDerived().AlwaysRebuild()) {
7561 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7562 EIT->getNumBits(), TL.getNameLoc());
7563 if (Result.isNull())
7564 return QualType();
7565 }
7566
7567 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7568 NewTL.setNameLoc(TL.getNameLoc());
7569 return Result;
7570}
7571
7572template <typename Derived>
7573QualType TreeTransform<Derived>::TransformDependentBitIntType(
7574 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7575 const DependentBitIntType *EIT = TL.getTypePtr();
7576
7577 EnterExpressionEvaluationContext Unevaluated(
7578 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7579 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7580 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7581
7582 if (BitsExpr.isInvalid())
7583 return QualType();
7584
7585 QualType Result = TL.getType();
7586
7587 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7588 Result = getDerived().RebuildDependentBitIntType(
7589 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7590
7591 if (Result.isNull())
7592 return QualType();
7593 }
7594
7595 if (isa<DependentBitIntType>(Val: Result)) {
7596 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7597 NewTL.setNameLoc(TL.getNameLoc());
7598 } else {
7599 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7600 NewTL.setNameLoc(TL.getNameLoc());
7601 }
7602 return Result;
7603}
7604
7605template <typename Derived>
7606QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7607 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7608 llvm_unreachable("This type does not need to be transformed.");
7609}
7610
7611 /// Simple iterator that traverses the template arguments in a
7612 /// container that provides a \c getArgLoc() member function.
7613 ///
7614 /// This iterator is intended to be used with the iterator form of
7615 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7616 template<typename ArgLocContainer>
7617 class TemplateArgumentLocContainerIterator {
7618 ArgLocContainer *Container;
7619 unsigned Index;
7620
7621 public:
7622 typedef TemplateArgumentLoc value_type;
7623 typedef TemplateArgumentLoc reference;
7624 typedef int difference_type;
7625 typedef std::input_iterator_tag iterator_category;
7626
7627 class pointer {
7628 TemplateArgumentLoc Arg;
7629
7630 public:
7631 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7632
7633 const TemplateArgumentLoc *operator->() const {
7634 return &Arg;
7635 }
7636 };
7637
7638
7639 TemplateArgumentLocContainerIterator() {}
7640
7641 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7642 unsigned Index)
7643 : Container(&Container), Index(Index) { }
7644
7645 TemplateArgumentLocContainerIterator &operator++() {
7646 ++Index;
7647 return *this;
7648 }
7649
7650 TemplateArgumentLocContainerIterator operator++(int) {
7651 TemplateArgumentLocContainerIterator Old(*this);
7652 ++(*this);
7653 return Old;
7654 }
7655
7656 TemplateArgumentLoc operator*() const {
7657 return Container->getArgLoc(Index);
7658 }
7659
7660 pointer operator->() const {
7661 return pointer(Container->getArgLoc(Index));
7662 }
7663
7664 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7665 const TemplateArgumentLocContainerIterator &Y) {
7666 return X.Container == Y.Container && X.Index == Y.Index;
7667 }
7668
7669 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7670 const TemplateArgumentLocContainerIterator &Y) {
7671 return !(X == Y);
7672 }
7673 };
7674
7675template<typename Derived>
7676QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7677 AutoTypeLoc TL) {
7678 const AutoType *T = TL.getTypePtr();
7679 QualType OldDeduced = T->getDeducedType();
7680 QualType NewDeduced;
7681 if (!OldDeduced.isNull()) {
7682 NewDeduced = getDerived().TransformType(OldDeduced);
7683 if (NewDeduced.isNull())
7684 return QualType();
7685 }
7686
7687 TemplateName NewCD;
7688 TemplateArgumentListInfo NewTemplateArgs;
7689 NestedNameSpecifierLoc NewNestedNameSpec;
7690 if (T->isConstrained()) {
7691 assert(TL.getConceptReference());
7692 NewCD = getDerived().TransformConceptTemplateName(
7693 T->getTypeConstraintConcept(), TL.getConceptNameLoc());
7694 if (NewCD.isNull())
7695 return QualType();
7696
7697 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7698 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7699 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7700 if (getDerived().TransformTemplateArguments(
7701 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7702 NewTemplateArgs))
7703 return QualType();
7704
7705 if (TL.getNestedNameSpecifierLoc()) {
7706 NewNestedNameSpec
7707 = getDerived().TransformNestedNameSpecifierLoc(
7708 TL.getNestedNameSpecifierLoc());
7709 if (!NewNestedNameSpec)
7710 return QualType();
7711 }
7712 }
7713
7714 QualType Result = TL.getType();
7715 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7716 T->isDependentType() || T->isConstrained()) {
7717 // FIXME: Maybe don't rebuild if all template arguments are the same.
7718 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7719 NewArgList.reserve(N: NewTemplateArgs.size());
7720 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7721 NewArgList.push_back(Elt: ArgLoc.getArgument());
7722 Result = getDerived().RebuildAutoType(
7723 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7724 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7725 if (Result.isNull())
7726 return QualType();
7727 }
7728
7729 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7730 NewTL.setNameLoc(TL.getNameLoc());
7731 NewTL.setRParenLoc(TL.getRParenLoc());
7732 NewTL.setConceptReference(nullptr);
7733
7734 if (T->isConstrained()) {
7735 DeclarationName ConceptName =
7736 SemaRef.Context
7737 .getNameForTemplate(Name: TL.getTypePtr()->getTypeConstraintConcept(),
7738 NameLoc: TL.getConceptNameLoc())
7739 .getName();
7740 DeclarationNameInfo DNI =
7741 DeclarationNameInfo(ConceptName, TL.getConceptNameLoc(), ConceptName);
7742 auto *CR = ConceptReference::Create(
7743 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7744 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7745 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7746 NewTL.setConceptReference(CR);
7747 }
7748
7749 return Result;
7750}
7751
7752template <typename Derived>
7753QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7754 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7755 return getDerived().TransformTemplateSpecializationType(
7756 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7757 /*AllowInjectedClassName=*/false);
7758}
7759
7760template <typename Derived>
7761QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7762 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7763 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7764 const TemplateSpecializationType *T = TL.getTypePtr();
7765
7766 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7767 TemplateName Template = getDerived().TransformTemplateName(
7768 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7769 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7770 AllowInjectedClassName);
7771 if (Template.isNull())
7772 return QualType();
7773
7774 TemplateArgumentListInfo NewTemplateArgs;
7775 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7776 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7777 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7778 ArgIterator;
7779 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7780 ArgIterator(TL, TL.getNumArgs()),
7781 NewTemplateArgs))
7782 return QualType();
7783
7784 // This needs to be rebuilt if either the arguments changed, or if the
7785 // original template changed. If the template changed, and even if the
7786 // arguments didn't change, these arguments might not correspond to their
7787 // respective parameters, therefore needing conversions.
7788 QualType Result = getDerived().RebuildTemplateSpecializationType(
7789 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7790 NewTemplateArgs);
7791
7792 if (!Result.isNull()) {
7793 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7794 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7795 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7796 }
7797
7798 return Result;
7799}
7800
7801template <typename Derived>
7802QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7803 AttributedTypeLoc TL) {
7804 const AttributedType *oldType = TL.getTypePtr();
7805 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7806 if (modifiedType.isNull())
7807 return QualType();
7808
7809 // HLSL: re-validate matrix-layout markers after substitution. If the
7810 // post-substitution type is no longer a matrix, diagnose now.
7811 if (SemaRef.getLangOpts().HLSL &&
7812 SemaRef.HLSL().diagnoseMatrixLayoutInstantiation(
7813 K: oldType->getAttrKind(), T: modifiedType,
7814 Loc: TL.getAttr() ? TL.getAttr()->getLocation()
7815 : TL.getModifiedLoc().getBeginLoc()))
7816 return QualType();
7817
7818 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7819 const Attr *oldAttr = TL.getAttr();
7820 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7821 if (oldAttr && !newAttr)
7822 return QualType();
7823
7824 QualType result = TL.getType();
7825
7826 // FIXME: dependent operand expressions?
7827 if (getDerived().AlwaysRebuild() ||
7828 modifiedType != oldType->getModifiedType()) {
7829 // If the equivalent type is equal to the modified type, we don't want to
7830 // transform it as well because:
7831 //
7832 // 1. The transformation would yield the same result and is therefore
7833 // superfluous, and
7834 //
7835 // 2. Transforming the same type twice can cause problems, e.g. if it
7836 // is a FunctionProtoType, we may end up instantiating the function
7837 // parameters twice, which causes an assertion since the parameters
7838 // are already bound to their counterparts in the template for this
7839 // instantiation.
7840 //
7841 QualType equivalentType = modifiedType;
7842 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7843 TypeLocBuilder AuxiliaryTLB;
7844 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7845 equivalentType =
7846 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7847 if (equivalentType.isNull())
7848 return QualType();
7849 }
7850
7851 // Check whether we can add nullability; it is only represented as
7852 // type sugar, and therefore cannot be diagnosed in any other way.
7853 if (auto nullability = oldType->getImmediateNullability()) {
7854 if (!modifiedType->canHaveNullability()) {
7855 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7856 : TL.getModifiedLoc().getBeginLoc()),
7857 DiagID: diag::err_nullability_nonpointer)
7858 << DiagNullabilityKind(*nullability, false) << modifiedType;
7859 return QualType();
7860 }
7861 }
7862
7863 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7864 modifiedType,
7865 equivalentType,
7866 attr: TL.getAttr());
7867 }
7868
7869 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7870 newTL.setAttr(newAttr);
7871 return result;
7872}
7873
7874template <typename Derived>
7875QualType TreeTransform<Derived>::TransformCountAttributedType(
7876 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7877 const CountAttributedType *OldTy = TL.getTypePtr();
7878 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7879 if (InnerTy.isNull())
7880 return QualType();
7881
7882 Expr *OldCount = TL.getCountExpr();
7883 Expr *NewCount = nullptr;
7884 if (OldCount) {
7885 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7886 if (CountResult.isInvalid())
7887 return QualType();
7888 NewCount = CountResult.get();
7889 }
7890
7891 QualType Result = TL.getType();
7892 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7893 OldCount != NewCount) {
7894 // Currently, CountAttributedType can only wrap incomplete array types.
7895 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7896 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7897 }
7898
7899 TLB.push<CountAttributedTypeLoc>(T: Result);
7900 return Result;
7901}
7902
7903template <typename Derived>
7904QualType
7905TreeTransform<Derived>::TransformLateParsedAttrType(TypeLocBuilder &TLB,
7906 LateParsedAttrTypeLoc TL) {
7907 const LateParsedAttrType *OldTy = TL.getTypePtr();
7908 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7909 if (InnerTy.isNull())
7910 return QualType();
7911
7912 QualType Result = TL.getType();
7913 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getWrappedType()) {
7914 Result = SemaRef.Context.getLateParsedAttrType(
7915 Wrapped: InnerTy, LateParsedAttr: OldTy->getLateParsedAttribute());
7916 }
7917
7918 LateParsedAttrTypeLoc newTL = TLB.push<LateParsedAttrTypeLoc>(T: Result);
7919 newTL.setAttrNameLoc(TL.getAttrNameLoc());
7920 return Result;
7921}
7922
7923template <typename Derived>
7924QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7925 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7926 // The BTFTagAttributedType is available for C only.
7927 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7928}
7929
7930template <typename Derived>
7931QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7932 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7933 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7934 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7935 if (InnerTy.isNull())
7936 return QualType();
7937
7938 QualType Result = TL.getType();
7939 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7940 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7941 Wrapped: InnerTy);
7942 if (Result.isNull())
7943 return QualType();
7944 }
7945
7946 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7947 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7948 return Result;
7949}
7950
7951template <typename Derived>
7952QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7953 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7954
7955 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7956
7957 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7958 if (WrappedTy.isNull())
7959 return QualType();
7960
7961 QualType ContainedTy = QualType();
7962 QualType OldContainedTy = oldType->getContainedType();
7963 TypeSourceInfo *ContainedTSI = nullptr;
7964 if (!OldContainedTy.isNull()) {
7965 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7966 if (!oldContainedTSI)
7967 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7968 OldContainedTy, SourceLocation());
7969 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7970 if (!ContainedTSI)
7971 return QualType();
7972 ContainedTy = ContainedTSI->getType();
7973 }
7974
7975 HLSLAttributedResourceType::Attributes Attrs = oldType->getAttrs();
7976 if (Attrs.SampleCountExpr) {
7977 ExprResult SampleCountResult =
7978 getDerived().TransformExpr(Attrs.SampleCountExpr);
7979 if (SampleCountResult.isInvalid())
7980 return QualType();
7981 Attrs.SampleCountExpr = SampleCountResult.get();
7982 }
7983
7984 QualType Result = TL.getType();
7985 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7986 ContainedTy != oldType->getContainedType() ||
7987 Attrs.SampleCountExpr != oldType->getSampleCountExpr()) {
7988 Result = SemaRef.Context.getHLSLAttributedResourceType(Wrapped: WrappedTy,
7989 Contained: ContainedTy, Attrs);
7990 }
7991
7992 HLSLAttributedResourceTypeLoc NewTL =
7993 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7994 NewTL.setSourceRange(TL.getLocalSourceRange());
7995 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7996 return Result;
7997}
7998
7999template <typename Derived>
8000QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
8001 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
8002 // No transformations needed.
8003 return TL.getType();
8004}
8005
8006template<typename Derived>
8007QualType
8008TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
8009 ParenTypeLoc TL) {
8010 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8011 if (Inner.isNull())
8012 return QualType();
8013
8014 QualType Result = TL.getType();
8015 if (getDerived().AlwaysRebuild() ||
8016 Inner != TL.getInnerLoc().getType()) {
8017 Result = getDerived().RebuildParenType(Inner);
8018 if (Result.isNull())
8019 return QualType();
8020 }
8021
8022 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
8023 NewTL.setLParenLoc(TL.getLParenLoc());
8024 NewTL.setRParenLoc(TL.getRParenLoc());
8025 return Result;
8026}
8027
8028template <typename Derived>
8029QualType
8030TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
8031 MacroQualifiedTypeLoc TL) {
8032 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8033 if (Inner.isNull())
8034 return QualType();
8035
8036 QualType Result = TL.getType();
8037 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
8038 Result =
8039 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
8040 if (Result.isNull())
8041 return QualType();
8042 }
8043
8044 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
8045 NewTL.setExpansionLoc(TL.getExpansionLoc());
8046 return Result;
8047}
8048
8049template<typename Derived>
8050QualType TreeTransform<Derived>::TransformDependentNameType(
8051 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
8052 return TransformDependentNameType(TLB, TL, false);
8053}
8054
8055template <typename Derived>
8056QualType TreeTransform<Derived>::TransformDependentNameType(
8057 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
8058 QualType ObjectType, NamedDecl *UnqualLookup) {
8059 const DependentNameType *T = TL.getTypePtr();
8060
8061 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
8062 if (QualifierLoc) {
8063 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
8064 QualifierLoc, ObjectType, UnqualLookup);
8065 if (!QualifierLoc)
8066 return QualType();
8067 } else {
8068 assert((ObjectType.isNull() && !UnqualLookup) &&
8069 "must be transformed by TransformNestedNameSpecifierLoc");
8070 }
8071
8072 QualType Result
8073 = getDerived().RebuildDependentNameType(T->getKeyword(),
8074 TL.getElaboratedKeywordLoc(),
8075 QualifierLoc,
8076 T->getIdentifier(),
8077 TL.getNameLoc(),
8078 DeducedTSTContext);
8079 if (Result.isNull())
8080 return QualType();
8081
8082 if (isa<TagType>(Val: Result)) {
8083 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
8084 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8085 NewTL.setQualifierLoc(QualifierLoc);
8086 NewTL.setNameLoc(TL.getNameLoc());
8087 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
8088 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
8089 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8090 NewTL.setTemplateNameLoc(TL.getNameLoc());
8091 NewTL.setQualifierLoc(QualifierLoc);
8092 } else if (isa<TypedefType>(Val: Result)) {
8093 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
8094 QualifierLoc, NameLoc: TL.getNameLoc());
8095 } else if (isa<UnresolvedUsingType>(Val: Result)) {
8096 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
8097 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
8098 } else {
8099 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
8100 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8101 NewTL.setQualifierLoc(QualifierLoc);
8102 NewTL.setNameLoc(TL.getNameLoc());
8103 }
8104 return Result;
8105}
8106
8107template<typename Derived>
8108QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
8109 PackExpansionTypeLoc TL) {
8110 QualType Pattern
8111 = getDerived().TransformType(TLB, TL.getPatternLoc());
8112 if (Pattern.isNull())
8113 return QualType();
8114
8115 QualType Result = TL.getType();
8116 if (getDerived().AlwaysRebuild() ||
8117 Pattern != TL.getPatternLoc().getType()) {
8118 Result = getDerived().RebuildPackExpansionType(Pattern,
8119 TL.getPatternLoc().getSourceRange(),
8120 TL.getEllipsisLoc(),
8121 TL.getTypePtr()->getNumExpansions());
8122 if (Result.isNull())
8123 return QualType();
8124 }
8125
8126 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
8127 NewT.setEllipsisLoc(TL.getEllipsisLoc());
8128 return Result;
8129}
8130
8131template<typename Derived>
8132QualType
8133TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
8134 ObjCInterfaceTypeLoc TL) {
8135 // ObjCInterfaceType is never dependent.
8136 TLB.pushFullCopy(L: TL);
8137 return TL.getType();
8138}
8139
8140template<typename Derived>
8141QualType
8142TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
8143 ObjCTypeParamTypeLoc TL) {
8144 const ObjCTypeParamType *T = TL.getTypePtr();
8145 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
8146 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
8147 if (!OTP)
8148 return QualType();
8149
8150 QualType Result = TL.getType();
8151 if (getDerived().AlwaysRebuild() ||
8152 OTP != T->getDecl()) {
8153 Result = getDerived().RebuildObjCTypeParamType(
8154 OTP, TL.getProtocolLAngleLoc(),
8155 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8156 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8157 if (Result.isNull())
8158 return QualType();
8159 }
8160
8161 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
8162 if (TL.getNumProtocols()) {
8163 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8164 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8165 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8166 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8167 }
8168 return Result;
8169}
8170
8171template<typename Derived>
8172QualType
8173TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
8174 ObjCObjectTypeLoc TL) {
8175 // Transform base type.
8176 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
8177 if (BaseType.isNull())
8178 return QualType();
8179
8180 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8181
8182 // Transform type arguments.
8183 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8184 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8185 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8186 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8187 QualType TypeArg = TypeArgInfo->getType();
8188 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8189 AnyChanged = true;
8190
8191 // We have a pack expansion. Instantiate it.
8192 const auto *PackExpansion = PackExpansionLoc.getType()
8193 ->castAs<PackExpansionType>();
8194 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8195 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8196 Unexpanded);
8197 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8198
8199 // Determine whether the set of unexpanded parameter packs can
8200 // and should be expanded.
8201 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8202 bool Expand = false;
8203 bool RetainExpansion = false;
8204 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8205 if (getDerived().TryExpandParameterPacks(
8206 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8207 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8208 RetainExpansion, NumExpansions))
8209 return QualType();
8210
8211 if (!Expand) {
8212 // We can't expand this pack expansion into separate arguments yet;
8213 // just substitute into the pattern and create a new pack expansion
8214 // type.
8215 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8216
8217 TypeLocBuilder TypeArgBuilder;
8218 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8219 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8220 PatternLoc);
8221 if (NewPatternType.isNull())
8222 return QualType();
8223
8224 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8225 Pattern: NewPatternType, NumExpansions);
8226 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8227 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8228 NewTypeArgInfos.push_back(
8229 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8230 continue;
8231 }
8232
8233 // Substitute into the pack expansion pattern for each slice of the
8234 // pack.
8235 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8236 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8237
8238 TypeLocBuilder TypeArgBuilder;
8239 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8240
8241 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8242 PatternLoc);
8243 if (NewTypeArg.isNull())
8244 return QualType();
8245
8246 NewTypeArgInfos.push_back(
8247 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8248 }
8249
8250 continue;
8251 }
8252
8253 TypeLocBuilder TypeArgBuilder;
8254 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8255 QualType NewTypeArg =
8256 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8257 if (NewTypeArg.isNull())
8258 return QualType();
8259
8260 // If nothing changed, just keep the old TypeSourceInfo.
8261 if (NewTypeArg == TypeArg) {
8262 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8263 continue;
8264 }
8265
8266 NewTypeArgInfos.push_back(
8267 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8268 AnyChanged = true;
8269 }
8270
8271 QualType Result = TL.getType();
8272 if (getDerived().AlwaysRebuild() || AnyChanged) {
8273 // Rebuild the type.
8274 Result = getDerived().RebuildObjCObjectType(
8275 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8276 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8277 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8278 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8279
8280 if (Result.isNull())
8281 return QualType();
8282 }
8283
8284 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8285 NewT.setHasBaseTypeAsWritten(true);
8286 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8287 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8288 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8289 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8290 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8291 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8292 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8293 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8294 return Result;
8295}
8296
8297template<typename Derived>
8298QualType
8299TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8300 ObjCObjectPointerTypeLoc TL) {
8301 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8302 if (PointeeType.isNull())
8303 return QualType();
8304
8305 QualType Result = TL.getType();
8306 if (getDerived().AlwaysRebuild() ||
8307 PointeeType != TL.getPointeeLoc().getType()) {
8308 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8309 TL.getStarLoc());
8310 if (Result.isNull())
8311 return QualType();
8312 }
8313
8314 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8315 NewT.setStarLoc(TL.getStarLoc());
8316 return Result;
8317}
8318
8319//===----------------------------------------------------------------------===//
8320// Statement transformation
8321//===----------------------------------------------------------------------===//
8322template<typename Derived>
8323StmtResult
8324TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8325 return S;
8326}
8327
8328template<typename Derived>
8329StmtResult
8330TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8331 return getDerived().TransformCompoundStmt(S, false);
8332}
8333
8334template<typename Derived>
8335StmtResult
8336TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8337 bool IsStmtExpr) {
8338 Sema::CompoundScopeRAII CompoundScope(getSema());
8339 Sema::FPFeaturesStateRAII FPSave(getSema());
8340 if (S->hasStoredFPFeatures())
8341 getSema().resetFPOptions(
8342 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8343
8344 bool SubStmtInvalid = false;
8345 bool SubStmtChanged = false;
8346 SmallVector<Stmt*, 8> Statements;
8347 for (auto *B : S->body()) {
8348 StmtResult Result = getDerived().TransformStmt(
8349 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8350 : StmtDiscardKind::Discarded);
8351
8352 if (Result.isInvalid()) {
8353 // Immediately fail if this was a DeclStmt, since it's very
8354 // likely that this will cause problems for future statements.
8355 if (isa<DeclStmt>(Val: B))
8356 return StmtError();
8357
8358 // Otherwise, just keep processing substatements and fail later.
8359 SubStmtInvalid = true;
8360 continue;
8361 }
8362
8363 SubStmtChanged = SubStmtChanged || Result.get() != B;
8364 Statements.push_back(Elt: Result.getAs<Stmt>());
8365 }
8366
8367 if (SubStmtInvalid)
8368 return StmtError();
8369
8370 if (!getDerived().AlwaysRebuild() &&
8371 !SubStmtChanged)
8372 return S;
8373
8374 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8375 Statements,
8376 S->getRBracLoc(),
8377 IsStmtExpr);
8378}
8379
8380template<typename Derived>
8381StmtResult
8382TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8383 ExprResult LHS, RHS;
8384 {
8385 EnterExpressionEvaluationContext Unevaluated(
8386 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8387
8388 // Transform the left-hand case value.
8389 LHS = getDerived().TransformExpr(S->getLHS());
8390 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8391 if (LHS.isInvalid())
8392 return StmtError();
8393
8394 // Transform the right-hand case value (for the GNU case-range extension).
8395 RHS = getDerived().TransformExpr(S->getRHS());
8396 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8397 if (RHS.isInvalid())
8398 return StmtError();
8399 }
8400
8401 // Build the case statement.
8402 // Case statements are always rebuilt so that they will attached to their
8403 // transformed switch statement.
8404 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8405 LHS.get(),
8406 S->getEllipsisLoc(),
8407 RHS.get(),
8408 S->getColonLoc());
8409 if (Case.isInvalid())
8410 return StmtError();
8411
8412 // Transform the statement following the case
8413 StmtResult SubStmt =
8414 getDerived().TransformStmt(S->getSubStmt());
8415 if (SubStmt.isInvalid())
8416 return StmtError();
8417
8418 // Attach the body to the case statement
8419 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8420}
8421
8422template <typename Derived>
8423StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8424 // Transform the statement following the default case
8425 StmtResult SubStmt =
8426 getDerived().TransformStmt(S->getSubStmt());
8427 if (SubStmt.isInvalid())
8428 return StmtError();
8429
8430 // Default statements are always rebuilt
8431 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8432 SubStmt.get());
8433}
8434
8435template<typename Derived>
8436StmtResult
8437TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8438 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8439 if (SubStmt.isInvalid())
8440 return StmtError();
8441
8442 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8443 S->getDecl());
8444 if (!LD)
8445 return StmtError();
8446
8447 // If we're transforming "in-place" (we're not creating new local
8448 // declarations), assume we're replacing the old label statement
8449 // and clear out the reference to it.
8450 if (LD == S->getDecl())
8451 S->getDecl()->setStmt(nullptr);
8452
8453 // FIXME: Pass the real colon location in.
8454 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8455 cast<LabelDecl>(Val: LD), SourceLocation(),
8456 SubStmt.get());
8457}
8458
8459template <typename Derived>
8460const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8461 if (!R)
8462 return R;
8463
8464 switch (R->getKind()) {
8465// Transform attributes by calling TransformXXXAttr.
8466#define ATTR(X) \
8467 case attr::X: \
8468 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8469#include "clang/Basic/AttrList.inc"
8470 }
8471 return R;
8472}
8473
8474template <typename Derived>
8475const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8476 const Stmt *InstS,
8477 const Attr *R) {
8478 if (!R)
8479 return R;
8480
8481 switch (R->getKind()) {
8482// Transform attributes by calling TransformStmtXXXAttr.
8483#define ATTR(X) \
8484 case attr::X: \
8485 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8486#include "clang/Basic/AttrList.inc"
8487 }
8488 return TransformAttr(R);
8489}
8490
8491template <typename Derived>
8492StmtResult
8493TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8494 StmtDiscardKind SDK) {
8495 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8496 if (SubStmt.isInvalid())
8497 return StmtError();
8498
8499 bool AttrsChanged = false;
8500 SmallVector<const Attr *, 1> Attrs;
8501
8502 // Visit attributes and keep track if any are transformed.
8503 for (const auto *I : S->getAttrs()) {
8504 const Attr *R =
8505 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8506 AttrsChanged |= (I != R);
8507 if (R)
8508 Attrs.push_back(Elt: R);
8509 }
8510
8511 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8512 return S;
8513
8514 // If transforming the attributes failed for all of the attributes in the
8515 // statement, don't make an AttributedStmt without attributes.
8516 if (Attrs.empty())
8517 return SubStmt;
8518
8519 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8520 SubStmt.get());
8521}
8522
8523template<typename Derived>
8524StmtResult
8525TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8526 // Transform the initialization statement
8527 StmtResult Init = getDerived().TransformStmt(S->getInit());
8528 if (Init.isInvalid())
8529 return StmtError();
8530
8531 Sema::ConditionResult Cond;
8532 if (!S->isConsteval()) {
8533 // Transform the condition
8534 Cond = getDerived().TransformCondition(
8535 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8536 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8537 : Sema::ConditionKind::Boolean);
8538 if (Cond.isInvalid())
8539 return StmtError();
8540 }
8541
8542 // If this is a constexpr if, determine which arm we should instantiate.
8543 std::optional<bool> ConstexprConditionValue;
8544 if (S->isConstexpr())
8545 ConstexprConditionValue = Cond.getKnownValue();
8546
8547 // Transform the "then" branch.
8548 StmtResult Then;
8549 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8550 EnterExpressionEvaluationContext Ctx(
8551 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8552 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8553 S->isNonNegatedConsteval());
8554
8555 Then = getDerived().TransformStmt(S->getThen());
8556 if (Then.isInvalid())
8557 return StmtError();
8558 } else {
8559 // Discarded branch is replaced with empty CompoundStmt so we can keep
8560 // proper source location for start and end of original branch, so
8561 // subsequent transformations like CoverageMapping work properly
8562 Then = new (getSema().Context)
8563 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8564 }
8565
8566 // Transform the "else" branch.
8567 StmtResult Else;
8568 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8569 EnterExpressionEvaluationContext Ctx(
8570 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8571 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8572 S->isNegatedConsteval());
8573
8574 Else = getDerived().TransformStmt(S->getElse());
8575 if (Else.isInvalid())
8576 return StmtError();
8577 } else if (S->getElse() && ConstexprConditionValue &&
8578 *ConstexprConditionValue) {
8579 // Same thing here as with <then> branch, we are discarding it, we can't
8580 // replace it with NULL nor NullStmt as we need to keep for source location
8581 // range, for CoverageMapping
8582 Else = new (getSema().Context)
8583 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8584 }
8585
8586 if (!getDerived().AlwaysRebuild() &&
8587 Init.get() == S->getInit() &&
8588 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8589 Then.get() == S->getThen() &&
8590 Else.get() == S->getElse())
8591 return S;
8592
8593 return getDerived().RebuildIfStmt(
8594 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8595 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8596}
8597
8598template<typename Derived>
8599StmtResult
8600TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8601 // Transform the initialization statement
8602 StmtResult Init = getDerived().TransformStmt(S->getInit());
8603 if (Init.isInvalid())
8604 return StmtError();
8605
8606 // Transform the condition.
8607 Sema::ConditionResult Cond = getDerived().TransformCondition(
8608 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8609 Sema::ConditionKind::Switch);
8610 if (Cond.isInvalid())
8611 return StmtError();
8612
8613 // Rebuild the switch statement.
8614 StmtResult Switch =
8615 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8616 Init.get(), Cond, S->getRParenLoc());
8617 if (Switch.isInvalid())
8618 return StmtError();
8619
8620 // Transform the body of the switch statement.
8621 StmtResult Body = getDerived().TransformStmt(S->getBody());
8622 if (Body.isInvalid())
8623 return StmtError();
8624
8625 // Complete the switch statement.
8626 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8627 Body.get());
8628}
8629
8630template<typename Derived>
8631StmtResult
8632TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8633 // Transform the condition
8634 Sema::ConditionResult Cond = getDerived().TransformCondition(
8635 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8636 Sema::ConditionKind::Boolean);
8637 if (Cond.isInvalid())
8638 return StmtError();
8639
8640 // OpenACC Restricts a while-loop inside of certain construct/clause
8641 // combinations, so diagnose that here in OpenACC mode.
8642 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8643 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8644
8645 // Transform the body
8646 StmtResult Body = getDerived().TransformStmt(S->getBody());
8647 if (Body.isInvalid())
8648 return StmtError();
8649
8650 if (!getDerived().AlwaysRebuild() &&
8651 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8652 Body.get() == S->getBody())
8653 return Owned(S);
8654
8655 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8656 Cond, S->getRParenLoc(), Body.get());
8657}
8658
8659template<typename Derived>
8660StmtResult
8661TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8662 // OpenACC Restricts a do-loop inside of certain construct/clause
8663 // combinations, so diagnose that here in OpenACC mode.
8664 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8665 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8666
8667 // Transform the body
8668 StmtResult Body = getDerived().TransformStmt(S->getBody());
8669 if (Body.isInvalid())
8670 return StmtError();
8671
8672 // Transform the condition
8673 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8674 if (Cond.isInvalid())
8675 return StmtError();
8676
8677 if (!getDerived().AlwaysRebuild() &&
8678 Cond.get() == S->getCond() &&
8679 Body.get() == S->getBody())
8680 return S;
8681
8682 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8683 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8684 S->getRParenLoc());
8685}
8686
8687template<typename Derived>
8688StmtResult
8689TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8690 if (getSema().getLangOpts().OpenMP)
8691 getSema().OpenMP().startOpenMPLoop();
8692
8693 // Transform the initialization statement
8694 StmtResult Init = getDerived().TransformStmt(S->getInit());
8695 if (Init.isInvalid())
8696 return StmtError();
8697
8698 // In OpenMP loop region loop control variable must be captured and be
8699 // private. Perform analysis of first part (if any).
8700 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8701 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8702 Init.get());
8703
8704 // Transform the condition
8705 Sema::ConditionResult Cond = getDerived().TransformCondition(
8706 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8707 Sema::ConditionKind::Boolean);
8708 if (Cond.isInvalid())
8709 return StmtError();
8710
8711 // Transform the increment
8712 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8713 if (Inc.isInvalid())
8714 return StmtError();
8715
8716 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8717 if (S->getInc() && !FullInc.get())
8718 return StmtError();
8719
8720 // OpenACC Restricts a for-loop inside of certain construct/clause
8721 // combinations, so diagnose that here in OpenACC mode.
8722 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8723 SemaRef.OpenACC().ActOnForStmtBegin(
8724 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8725 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8726
8727 // Transform the body
8728 StmtResult Body = getDerived().TransformStmt(S->getBody());
8729 if (Body.isInvalid())
8730 return StmtError();
8731
8732 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8733
8734 if (!getDerived().AlwaysRebuild() &&
8735 Init.get() == S->getInit() &&
8736 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8737 Inc.get() == S->getInc() &&
8738 Body.get() == S->getBody())
8739 return S;
8740
8741 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8742 Init.get(), Cond, FullInc,
8743 S->getRParenLoc(), Body.get());
8744}
8745
8746template<typename Derived>
8747StmtResult
8748TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8749 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8750 S->getLabel());
8751 if (!LD)
8752 return StmtError();
8753
8754 // Goto statements must always be rebuilt, to resolve the label.
8755 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8756 cast<LabelDecl>(Val: LD));
8757}
8758
8759template<typename Derived>
8760StmtResult
8761TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8762 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8763 if (Target.isInvalid())
8764 return StmtError();
8765 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8766
8767 if (!getDerived().AlwaysRebuild() &&
8768 Target.get() == S->getTarget())
8769 return S;
8770
8771 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8772 Target.get());
8773}
8774
8775template<typename Derived>
8776StmtResult
8777TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8778 if (!S->hasLabelTarget())
8779 return S;
8780
8781 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8782 S->getLabelDecl());
8783 if (!LD)
8784 return StmtError();
8785
8786 return new (SemaRef.Context)
8787 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8788}
8789
8790template<typename Derived>
8791StmtResult
8792TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8793 if (!S->hasLabelTarget())
8794 return S;
8795
8796 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8797 S->getLabelDecl());
8798 if (!LD)
8799 return StmtError();
8800
8801 return new (SemaRef.Context)
8802 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8803}
8804
8805template <typename Derived>
8806StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8807 StmtResult Result = getDerived().TransformStmt(S->getBody());
8808 if (!Result.isUsable())
8809 return StmtError();
8810 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8811}
8812
8813template<typename Derived>
8814StmtResult
8815TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8816 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8817 /*NotCopyInit*/false);
8818 if (Result.isInvalid())
8819 return StmtError();
8820
8821 // FIXME: We always rebuild the return statement because there is no way
8822 // to tell whether the return type of the function has changed.
8823 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8824}
8825
8826template<typename Derived>
8827StmtResult
8828TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8829 bool DeclChanged = false;
8830 SmallVector<Decl *, 4> Decls;
8831 LambdaScopeInfo *LSI = getSema().getCurLambda();
8832 for (auto *D : S->decls()) {
8833 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8834 if (!Transformed)
8835 return StmtError();
8836
8837 if (Transformed != D)
8838 DeclChanged = true;
8839
8840 if (LSI) {
8841 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8842 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8843 LSI->ContainsUnexpandedParameterPack |=
8844 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8845 } else {
8846 LSI->ContainsUnexpandedParameterPack |=
8847 getSema()
8848 .getASTContext()
8849 .getTypeDeclType(TD)
8850 ->containsUnexpandedParameterPack();
8851 }
8852 }
8853 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8854 LSI->ContainsUnexpandedParameterPack |=
8855 VD->getType()->containsUnexpandedParameterPack();
8856 }
8857
8858 Decls.push_back(Elt: Transformed);
8859 }
8860
8861 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8862 return S;
8863
8864 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8865}
8866
8867template<typename Derived>
8868StmtResult
8869TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8870
8871 SmallVector<Expr*, 8> Constraints;
8872 SmallVector<Expr*, 8> Exprs;
8873 SmallVector<IdentifierInfo *, 4> Names;
8874
8875 SmallVector<Expr*, 8> Clobbers;
8876
8877 bool ExprsChanged = false;
8878
8879 auto RebuildString = [&](Expr *E) {
8880 ExprResult Result = getDerived().TransformExpr(E);
8881 if (!Result.isUsable())
8882 return Result;
8883 if (Result.get() != E) {
8884 ExprsChanged = true;
8885 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8886 }
8887 return Result;
8888 };
8889
8890 // Go through the outputs.
8891 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8892 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8893
8894 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8895 if (Result.isInvalid())
8896 return StmtError();
8897
8898 Constraints.push_back(Elt: Result.get());
8899
8900 // Transform the output expr.
8901 Expr *OutputExpr = S->getOutputExpr(i: I);
8902 Result = getDerived().TransformExpr(OutputExpr);
8903 if (Result.isInvalid())
8904 return StmtError();
8905
8906 ExprsChanged |= Result.get() != OutputExpr;
8907
8908 Exprs.push_back(Elt: Result.get());
8909 }
8910
8911 // Go through the inputs.
8912 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8913 Names.push_back(Elt: S->getInputIdentifier(i: I));
8914
8915 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8916 if (Result.isInvalid())
8917 return StmtError();
8918
8919 Constraints.push_back(Elt: Result.get());
8920
8921 // Transform the input expr.
8922 Expr *InputExpr = S->getInputExpr(i: I);
8923 Result = getDerived().TransformExpr(InputExpr);
8924 if (Result.isInvalid())
8925 return StmtError();
8926
8927 ExprsChanged |= Result.get() != InputExpr;
8928
8929 Exprs.push_back(Elt: Result.get());
8930 }
8931
8932 // Go through the Labels.
8933 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8934 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8935
8936 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8937 if (Result.isInvalid())
8938 return StmtError();
8939 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8940 Exprs.push_back(Elt: Result.get());
8941 }
8942
8943 // Go through the clobbers.
8944 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8945 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8946 if (Result.isInvalid())
8947 return StmtError();
8948 Clobbers.push_back(Elt: Result.get());
8949 }
8950
8951 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8952 if (AsmString.isInvalid())
8953 return StmtError();
8954
8955 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8956 return S;
8957
8958 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8959 S->isVolatile(), S->getNumOutputs(),
8960 S->getNumInputs(), Names.data(),
8961 Constraints, Exprs, AsmString.get(),
8962 Clobbers, S->getNumLabels(),
8963 S->getRParenLoc());
8964}
8965
8966template<typename Derived>
8967StmtResult
8968TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8969 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8970
8971 bool HadError = false, HadChange = false;
8972
8973 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8974 SmallVector<Expr*, 8> TransformedExprs;
8975 TransformedExprs.reserve(N: SrcExprs.size());
8976 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8977 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8978 if (!Result.isUsable()) {
8979 HadError = true;
8980 } else {
8981 HadChange |= (Result.get() != SrcExprs[i]);
8982 TransformedExprs.push_back(Elt: Result.get());
8983 }
8984 }
8985
8986 if (HadError) return StmtError();
8987 if (!HadChange && !getDerived().AlwaysRebuild())
8988 return Owned(S);
8989
8990 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8991 AsmToks, S->getAsmString(),
8992 S->getNumOutputs(), S->getNumInputs(),
8993 S->getAllConstraints(), S->getClobbers(),
8994 TransformedExprs, S->getEndLoc());
8995}
8996
8997// C++ Coroutines
8998template<typename Derived>
8999StmtResult
9000TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
9001 auto *ScopeInfo = SemaRef.getCurFunction();
9002 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
9003 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
9004 ScopeInfo->NeedsCoroutineSuspends &&
9005 ScopeInfo->CoroutineSuspends.first == nullptr &&
9006 ScopeInfo->CoroutineSuspends.second == nullptr &&
9007 "expected clean scope info");
9008
9009 // Set that we have (possibly-invalid) suspend points before we do anything
9010 // that may fail.
9011 ScopeInfo->setNeedsCoroutineSuspends(false);
9012
9013 // We re-build the coroutine promise object (and the coroutine parameters its
9014 // type and constructor depend on) based on the types used in our current
9015 // function. We must do so, and set it on the current FunctionScopeInfo,
9016 // before attempting to transform the other parts of the coroutine body
9017 // statement, such as the implicit suspend statements (because those
9018 // statements reference the FunctionScopeInfo::CoroutinePromise).
9019 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
9020 return StmtError();
9021 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
9022 if (!Promise)
9023 return StmtError();
9024 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
9025 ScopeInfo->CoroutinePromise = Promise;
9026
9027 // Transform the implicit coroutine statements constructed using dependent
9028 // types during the previous parse: initial and final suspensions, the return
9029 // object, and others. We also transform the coroutine function's body.
9030 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
9031 if (InitSuspend.isInvalid())
9032 return StmtError();
9033 StmtResult FinalSuspend =
9034 getDerived().TransformStmt(S->getFinalSuspendStmt());
9035 if (FinalSuspend.isInvalid() ||
9036 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
9037 return StmtError();
9038 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
9039 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
9040
9041 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
9042 if (BodyRes.isInvalid())
9043 return StmtError();
9044
9045 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
9046 if (Builder.isInvalid())
9047 return StmtError();
9048
9049 Expr *ReturnObject = S->getReturnValueInit();
9050 assert(ReturnObject && "the return object is expected to be valid");
9051 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
9052 /*NoCopyInit*/ false);
9053 if (Res.isInvalid())
9054 return StmtError();
9055 Builder.ReturnValue = Res.get();
9056
9057 // If during the previous parse the coroutine still had a dependent promise
9058 // statement, we may need to build some implicit coroutine statements
9059 // (such as exception and fallthrough handlers) for the first time.
9060 if (S->hasDependentPromiseType()) {
9061 // We can only build these statements, however, if the current promise type
9062 // is not dependent.
9063 if (!Promise->getType()->isDependentType()) {
9064 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
9065 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
9066 "these nodes should not have been built yet");
9067 if (!Builder.buildDependentStatements())
9068 return StmtError();
9069 }
9070 } else {
9071 if (auto *OnFallthrough = S->getFallthroughHandler()) {
9072 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
9073 if (Res.isInvalid())
9074 return StmtError();
9075 Builder.OnFallthrough = Res.get();
9076 }
9077
9078 if (auto *OnException = S->getExceptionHandler()) {
9079 StmtResult Res = getDerived().TransformStmt(OnException);
9080 if (Res.isInvalid())
9081 return StmtError();
9082 Builder.OnException = Res.get();
9083 }
9084
9085 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
9086 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
9087 if (Res.isInvalid())
9088 return StmtError();
9089 Builder.ReturnStmtOnAllocFailure = Res.get();
9090 }
9091
9092 // Transform any additional statements we may have already built
9093 assert(S->getAllocate() && S->getDeallocate() &&
9094 "allocation and deallocation calls must already be built");
9095 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
9096 if (AllocRes.isInvalid())
9097 return StmtError();
9098 Builder.Allocate = AllocRes.get();
9099
9100 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
9101 if (DeallocRes.isInvalid())
9102 return StmtError();
9103 Builder.Deallocate = DeallocRes.get();
9104
9105 if (auto *ResultDecl = S->getResultDecl()) {
9106 StmtResult Res = getDerived().TransformStmt(ResultDecl);
9107 if (Res.isInvalid())
9108 return StmtError();
9109 Builder.ResultDecl = Res.get();
9110 }
9111
9112 if (auto *ReturnStmt = S->getReturnStmt()) {
9113 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
9114 if (Res.isInvalid())
9115 return StmtError();
9116 Builder.ReturnStmt = Res.get();
9117 }
9118 }
9119
9120 return getDerived().RebuildCoroutineBodyStmt(Builder);
9121}
9122
9123template<typename Derived>
9124StmtResult
9125TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
9126 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
9127 /*NotCopyInit*/false);
9128 if (Result.isInvalid())
9129 return StmtError();
9130
9131 // Always rebuild; we don't know if this needs to be injected into a new
9132 // context or if the promise type has changed.
9133 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
9134 S->isImplicit());
9135}
9136
9137template <typename Derived>
9138ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
9139 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
9140 /*NotCopyInit*/ false);
9141 if (Operand.isInvalid())
9142 return ExprError();
9143
9144 // Rebuild the common-expr from the operand rather than transforming it
9145 // separately.
9146
9147 // FIXME: getCurScope() should not be used during template instantiation.
9148 // We should pick up the set of unqualified lookup results for operator
9149 // co_await during the initial parse.
9150 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
9151 getSema().getCurScope(), E->getKeywordLoc());
9152
9153 // Always rebuild; we don't know if this needs to be injected into a new
9154 // context or if the promise type has changed.
9155 return getDerived().RebuildCoawaitExpr(
9156 E->getKeywordLoc(), Operand.get(),
9157 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
9158}
9159
9160template <typename Derived>
9161ExprResult
9162TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
9163 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
9164 /*NotCopyInit*/ false);
9165 if (OperandResult.isInvalid())
9166 return ExprError();
9167
9168 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
9169 E->getOperatorCoawaitLookup());
9170
9171 if (LookupResult.isInvalid())
9172 return ExprError();
9173
9174 // Always rebuild; we don't know if this needs to be injected into a new
9175 // context or if the promise type has changed.
9176 return getDerived().RebuildDependentCoawaitExpr(
9177 E->getKeywordLoc(), OperandResult.get(),
9178 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
9179}
9180
9181template<typename Derived>
9182ExprResult
9183TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9184 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9185 /*NotCopyInit*/false);
9186 if (Result.isInvalid())
9187 return ExprError();
9188
9189 // Always rebuild; we don't know if this needs to be injected into a new
9190 // context or if the promise type has changed.
9191 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9192}
9193
9194// Objective-C Statements.
9195
9196template<typename Derived>
9197StmtResult
9198TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9199 // Transform the body of the @try.
9200 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9201 if (TryBody.isInvalid())
9202 return StmtError();
9203
9204 // Transform the @catch statements (if present).
9205 bool AnyCatchChanged = false;
9206 SmallVector<Stmt*, 8> CatchStmts;
9207 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9208 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9209 if (Catch.isInvalid())
9210 return StmtError();
9211 if (Catch.get() != S->getCatchStmt(I))
9212 AnyCatchChanged = true;
9213 CatchStmts.push_back(Elt: Catch.get());
9214 }
9215
9216 // Transform the @finally statement (if present).
9217 StmtResult Finally;
9218 if (S->getFinallyStmt()) {
9219 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9220 if (Finally.isInvalid())
9221 return StmtError();
9222 }
9223
9224 // If nothing changed, just retain this statement.
9225 if (!getDerived().AlwaysRebuild() &&
9226 TryBody.get() == S->getTryBody() &&
9227 !AnyCatchChanged &&
9228 Finally.get() == S->getFinallyStmt())
9229 return S;
9230
9231 // Build a new statement.
9232 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9233 CatchStmts, Finally.get());
9234}
9235
9236template<typename Derived>
9237StmtResult
9238TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9239 // Transform the @catch parameter, if there is one.
9240 VarDecl *Var = nullptr;
9241 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9242 TypeSourceInfo *TSInfo = nullptr;
9243 if (FromVar->getTypeSourceInfo()) {
9244 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9245 if (!TSInfo)
9246 return StmtError();
9247 }
9248
9249 QualType T;
9250 if (TSInfo)
9251 T = TSInfo->getType();
9252 else {
9253 T = getDerived().TransformType(FromVar->getType());
9254 if (T.isNull())
9255 return StmtError();
9256 }
9257
9258 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9259 if (!Var)
9260 return StmtError();
9261 }
9262
9263 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9264 if (Body.isInvalid())
9265 return StmtError();
9266
9267 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9268 S->getRParenLoc(),
9269 Var, Body.get());
9270}
9271
9272template<typename Derived>
9273StmtResult
9274TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9275 // Transform the body.
9276 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9277 if (Body.isInvalid())
9278 return StmtError();
9279
9280 // If nothing changed, just retain this statement.
9281 if (!getDerived().AlwaysRebuild() &&
9282 Body.get() == S->getFinallyBody())
9283 return S;
9284
9285 // Build a new statement.
9286 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9287 Body.get());
9288}
9289
9290template<typename Derived>
9291StmtResult
9292TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9293 ExprResult Operand;
9294 if (S->getThrowExpr()) {
9295 Operand = getDerived().TransformExpr(S->getThrowExpr());
9296 if (Operand.isInvalid())
9297 return StmtError();
9298 }
9299
9300 if (!getDerived().AlwaysRebuild() &&
9301 Operand.get() == S->getThrowExpr())
9302 return S;
9303
9304 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9305}
9306
9307template<typename Derived>
9308StmtResult
9309TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9310 ObjCAtSynchronizedStmt *S) {
9311 // Transform the object we are locking.
9312 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9313 if (Object.isInvalid())
9314 return StmtError();
9315 Object =
9316 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9317 Object.get());
9318 if (Object.isInvalid())
9319 return StmtError();
9320
9321 // Transform the body.
9322 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9323 if (Body.isInvalid())
9324 return StmtError();
9325
9326 // If nothing change, just retain the current statement.
9327 if (!getDerived().AlwaysRebuild() &&
9328 Object.get() == S->getSynchExpr() &&
9329 Body.get() == S->getSynchBody())
9330 return S;
9331
9332 // Build a new statement.
9333 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9334 Object.get(), Body.get());
9335}
9336
9337template<typename Derived>
9338StmtResult
9339TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9340 ObjCAutoreleasePoolStmt *S) {
9341 // Transform the body.
9342 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9343 if (Body.isInvalid())
9344 return StmtError();
9345
9346 // If nothing changed, just retain this statement.
9347 if (!getDerived().AlwaysRebuild() &&
9348 Body.get() == S->getSubStmt())
9349 return S;
9350
9351 // Build a new statement.
9352 return getDerived().RebuildObjCAutoreleasePoolStmt(
9353 S->getAtLoc(), Body.get());
9354}
9355
9356template<typename Derived>
9357StmtResult
9358TreeTransform<Derived>::TransformObjCForCollectionStmt(
9359 ObjCForCollectionStmt *S) {
9360 // Transform the element statement.
9361 StmtResult Element = getDerived().TransformStmt(
9362 S->getElement(), StmtDiscardKind::NotDiscarded);
9363 if (Element.isInvalid())
9364 return StmtError();
9365
9366 // Transform the collection expression.
9367 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9368 if (Collection.isInvalid())
9369 return StmtError();
9370
9371 // Transform the body.
9372 StmtResult Body = getDerived().TransformStmt(S->getBody());
9373 if (Body.isInvalid())
9374 return StmtError();
9375
9376 // If nothing changed, just retain this statement.
9377 if (!getDerived().AlwaysRebuild() &&
9378 Element.get() == S->getElement() &&
9379 Collection.get() == S->getCollection() &&
9380 Body.get() == S->getBody())
9381 return S;
9382
9383 // Build a new statement.
9384 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9385 Element.get(),
9386 Collection.get(),
9387 S->getRParenLoc(),
9388 Body.get());
9389}
9390
9391template <typename Derived>
9392StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9393 // Transform the exception declaration, if any.
9394 VarDecl *Var = nullptr;
9395 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9396 TypeSourceInfo *T =
9397 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9398 if (!T)
9399 return StmtError();
9400
9401 Var = getDerived().RebuildExceptionDecl(
9402 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9403 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9404 if (!Var || Var->isInvalidDecl())
9405 return StmtError();
9406 }
9407
9408 // Transform the actual exception handler.
9409 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9410 if (Handler.isInvalid())
9411 return StmtError();
9412
9413 if (!getDerived().AlwaysRebuild() && !Var &&
9414 Handler.get() == S->getHandlerBlock())
9415 return S;
9416
9417 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9418}
9419
9420template <typename Derived>
9421StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9422 // Transform the try block itself.
9423 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9424 if (TryBlock.isInvalid())
9425 return StmtError();
9426
9427 // Transform the handlers.
9428 bool HandlerChanged = false;
9429 SmallVector<Stmt *, 8> Handlers;
9430 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9431 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9432 if (Handler.isInvalid())
9433 return StmtError();
9434
9435 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9436 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9437 }
9438
9439 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9440
9441 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9442 !HandlerChanged)
9443 return S;
9444
9445 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9446 Handlers);
9447}
9448
9449template<typename Derived>
9450StmtResult
9451TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9452 EnterExpressionEvaluationContext ForRangeInitContext(
9453 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9454 /*LambdaContextDecl=*/nullptr,
9455 Sema::ExpressionEvaluationContextRecord::EK_Other,
9456 getSema().getLangOpts().CPlusPlus23);
9457
9458 // P2718R0 - Lifetime extension in range-based for loops.
9459 if (getSema().getLangOpts().CPlusPlus23) {
9460 auto &LastRecord = getSema().currentEvaluationContext();
9461 LastRecord.InLifetimeExtendingContext = true;
9462 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9463 }
9464 StmtResult Init =
9465 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9466 if (Init.isInvalid())
9467 return StmtError();
9468
9469 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9470 if (Range.isInvalid())
9471 return StmtError();
9472
9473 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9474 assert(getSema().getLangOpts().CPlusPlus23 ||
9475 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9476 auto ForRangeLifetimeExtendTemps =
9477 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9478
9479 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9480 if (Begin.isInvalid())
9481 return StmtError();
9482 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9483 if (End.isInvalid())
9484 return StmtError();
9485
9486 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9487 if (Cond.isInvalid())
9488 return StmtError();
9489 if (Cond.get())
9490 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9491 if (Cond.isInvalid())
9492 return StmtError();
9493 if (Cond.get())
9494 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9495
9496 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9497 if (Inc.isInvalid())
9498 return StmtError();
9499 if (Inc.get())
9500 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9501
9502 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9503 if (LoopVar.isInvalid())
9504 return StmtError();
9505
9506 StmtResult NewStmt = S;
9507 if (getDerived().AlwaysRebuild() ||
9508 Init.get() != S->getInit() ||
9509 Range.get() != S->getRangeStmt() ||
9510 Begin.get() != S->getBeginStmt() ||
9511 End.get() != S->getEndStmt() ||
9512 Cond.get() != S->getCond() ||
9513 Inc.get() != S->getInc() ||
9514 LoopVar.get() != S->getLoopVarStmt()) {
9515 NewStmt = getDerived().RebuildCXXForRangeStmt(
9516 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9517 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9518 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9519 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9520 // Might not have attached any initializer to the loop variable.
9521 getSema().ActOnInitializerError(
9522 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9523 return StmtError();
9524 }
9525 }
9526
9527 // OpenACC Restricts a while-loop inside of certain construct/clause
9528 // combinations, so diagnose that here in OpenACC mode.
9529 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9530 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9531
9532 StmtResult Body = getDerived().TransformStmt(S->getBody());
9533 if (Body.isInvalid())
9534 return StmtError();
9535
9536 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9537
9538 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9539 // it now so we have a new statement to attach the body to.
9540 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9541 NewStmt = getDerived().RebuildCXXForRangeStmt(
9542 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9543 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9544 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9545 if (NewStmt.isInvalid())
9546 return StmtError();
9547 }
9548
9549 if (NewStmt.get() == S)
9550 return S;
9551
9552 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9553}
9554
9555template <typename Derived>
9556StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtPattern(
9557 CXXExpansionStmtPattern *S) {
9558 assert(SemaRef.CurContext->isExpansionStmt());
9559
9560 Decl *ESD =
9561 getDerived().TransformDecl(S->getDecl()->getLocation(), S->getDecl());
9562 if (!ESD || ESD->isInvalidDecl())
9563 return StmtError();
9564 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9565
9566 // This is required because some parts of an expansion statement (e.g. the
9567 // init-statement) are not in a dependent context and must thus be transformed
9568 // in the parent context.
9569 auto TransformStmtInParentContext = [&](Stmt *SubStmt) -> StmtResult {
9570 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9571 /*NewThis=*/false);
9572 return getDerived().TransformStmt(SubStmt);
9573 };
9574
9575 Stmt *Init = S->getInit();
9576 if (Init) {
9577 StmtResult SR = TransformStmtInParentContext(Init);
9578 if (SR.isInvalid())
9579 return StmtError();
9580 Init = SR.get();
9581 }
9582
9583 // Collect lifetime-extended temporaries in case this ends up being a
9584 // destructuring or iterating expansion statement.
9585 //
9586 // CWG 3140: Additionally, for iterating expansions statements, we need to
9587 // apply lifetime extension to the initializer of the range.
9588 ExprResult ExpansionInitializer;
9589 StmtResult Range;
9590 SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
9591 if (S->isDependent() || S->isIterating()) {
9592 EnterExpressionEvaluationContext ExprEvalCtx(
9593 SemaRef, SemaRef.currentEvaluationContext().Context);
9594 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9595 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9596
9597 if (S->isDependent()) {
9598 // The expansion initializer should not be in the context of the expansion
9599 // statement because it isn't instantiated when the expansion statement is
9600 // expanded.
9601 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9602 /*NewThis=*/false);
9603 ExpansionInitializer =
9604 getDerived().TransformExpr(S->getExpansionInitializer());
9605 if (ExpansionInitializer.isInvalid())
9606 return StmtError();
9607 } else if (S->isIterating()) {
9608 Range = TransformStmtInParentContext(S->getRangeVarStmt());
9609 if (Range.isInvalid())
9610 return StmtError();
9611 }
9612
9613 ExpansionInitializer =
9614 SemaRef.MaybeCreateExprWithCleanups(SubExpr: ExpansionInitializer);
9615
9616 LifetimeExtendTemps =
9617 SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps;
9618 }
9619
9620 CXXExpansionStmtPattern *NewPattern = nullptr;
9621 if (S->isEnumerating()) {
9622 StmtResult ExpansionVar =
9623 getDerived().TransformStmt(S->getExpansionVarStmt());
9624 if (ExpansionVar.isInvalid())
9625 return StmtError();
9626
9627 NewPattern = CXXExpansionStmtPattern::CreateEnumerating(
9628 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9629 LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(), RParenLoc: S->getRParenLoc());
9630 } else if (S->isIterating()) {
9631 StmtResult Begin = TransformStmtInParentContext(S->getBeginVarStmt());
9632 StmtResult Iter = TransformStmtInParentContext(S->getIterVarStmt());
9633 if (Begin.isInvalid() || Iter.isInvalid())
9634 return StmtError();
9635
9636 // The expansion variable is part of the pattern only and never ends
9637 // up in the instantiations, so keep it in the expansion statement's
9638 // DeclContext.
9639 StmtResult ExpansionVar =
9640 getDerived().TransformStmt(S->getExpansionVarStmt());
9641 if (ExpansionVar.isInvalid())
9642 return StmtError();
9643
9644 NewPattern = CXXExpansionStmtPattern::CreateIterating(
9645 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9646 Range: Range.getAs<DeclStmt>(), Begin: Begin.getAs<DeclStmt>(),
9647 Iter: Iter.getAs<DeclStmt>(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9648 RParenLoc: S->getRParenLoc());
9649
9650 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9651 RangeVar: NewPattern->getRangeVar(), Temporaries: LifetimeExtendTemps);
9652 } else if (S->isDependent()) {
9653 StmtResult ExpansionVar =
9654 getDerived().TransformStmt(S->getExpansionVarStmt());
9655 if (ExpansionVar.isInvalid())
9656 return StmtError();
9657
9658 StmtResult Res = SemaRef.BuildNonEnumeratingCXXExpansionStmtPattern(
9659 ESD: NewESD, Init, ExpansionVarStmt: ExpansionVar.getAs<DeclStmt>(),
9660 ExpansionInitializer: ExpansionInitializer.get(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9661 RParenLoc: S->getRParenLoc(), LifetimeExtendTemps);
9662
9663 if (Res.isInvalid())
9664 return StmtError();
9665
9666 NewPattern = cast<CXXExpansionStmtPattern>(Val: Res.get());
9667 } else {
9668 // The only time we instantiate an expansion statement is if its expansion
9669 // size is dependent (otherwise, we only instantiate the expansions and
9670 // leave the underlying CXXExpansionStmtPattern as-is). Since destructuring
9671 // expansion statements never have a dependent size, we should never get
9672 // here.
9673 llvm_unreachable("destructuring pattern should never be instantiated");
9674 }
9675
9676 StmtResult Body = getDerived().TransformStmt(S->getBody());
9677 if (Body.isInvalid())
9678 return StmtError();
9679
9680 return SemaRef.FinishCXXExpansionStmt(Expansion: NewPattern, Body: Body.get());
9681}
9682
9683template <typename Derived>
9684StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtInstantiation(
9685 CXXExpansionStmtInstantiation *S) {
9686 bool SubStmtChanged = false;
9687 auto TransformStmts = [&](SmallVectorImpl<Stmt *> &NewStmts,
9688 ArrayRef<Stmt *> OldStmts) {
9689 for (Stmt *OldDS : OldStmts) {
9690 StmtResult NewDS = getDerived().TransformStmt(OldDS);
9691 if (NewDS.isInvalid())
9692 return true;
9693
9694 SubStmtChanged |= NewDS.get() != OldDS;
9695 NewStmts.push_back(Elt: NewDS.get());
9696 }
9697
9698 return false;
9699 };
9700
9701 Decl *ESD =
9702 getDerived().TransformDecl(S->getParent()->getLocation(), S->getParent());
9703 if (!ESD || ESD->isInvalidDecl())
9704 return StmtError();
9705 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9706
9707 SmallVector<Stmt *> PreambleStmts;
9708 SmallVector<Stmt *> Instantiations;
9709
9710 // Apply lifetime extension to the preamble statements if this was a
9711 // destructuring expansion statement.
9712 {
9713 EnterExpressionEvaluationContext ExprEvalCtx(
9714 SemaRef, SemaRef.currentEvaluationContext().Context);
9715 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9716 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9717 if (TransformStmts(PreambleStmts, S->getPreambleStmts()))
9718 return StmtError();
9719
9720 if (S->shouldApplyLifetimeExtensionToPreamble()) {
9721 auto *VD =
9722 cast<VarDecl>(Val: cast<DeclStmt>(Val: PreambleStmts.front())->getSingleDecl());
9723 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9724 RangeVar: VD, Temporaries: SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps);
9725 }
9726 }
9727
9728 if (TransformStmts(Instantiations, S->getInstantiations()))
9729 return StmtError();
9730
9731 if (!getDerived().AlwaysRebuild() && !SubStmtChanged)
9732 return S;
9733
9734 return CXXExpansionStmtInstantiation::Create(
9735 C&: SemaRef.Context, Parent: NewESD, Instantiations, PreambleStmts,
9736 ShouldApplyLifetimeExtensionToPreamble: S->shouldApplyLifetimeExtensionToPreamble());
9737}
9738
9739template <typename Derived>
9740ExprResult TreeTransform<Derived>::TransformCXXExpansionSelectExpr(
9741 CXXExpansionSelectExpr *E) {
9742 ExprResult Range = getDerived().TransformExpr(E->getRangeExpr());
9743 ExprResult Idx = getDerived().TransformExpr(E->getIndexExpr());
9744 if (Range.isInvalid() || Idx.isInvalid())
9745 return ExprError();
9746
9747 if (!getDerived().AlwaysRebuild() && Range.get() == E->getRangeExpr() &&
9748 Idx.get() == E->getIndexExpr())
9749 return E;
9750
9751 return SemaRef.BuildCXXExpansionSelectExpr(Range: Range.getAs<InitListExpr>(),
9752 Idx: Idx.get());
9753}
9754
9755template<typename Derived>
9756StmtResult
9757TreeTransform<Derived>::TransformMSDependentExistsStmt(
9758 MSDependentExistsStmt *S) {
9759 // Transform the nested-name-specifier, if any.
9760 NestedNameSpecifierLoc QualifierLoc;
9761 if (S->getQualifierLoc()) {
9762 QualifierLoc
9763 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9764 if (!QualifierLoc)
9765 return StmtError();
9766 }
9767
9768 // Transform the declaration name.
9769 DeclarationNameInfo NameInfo = S->getNameInfo();
9770 if (NameInfo.getName()) {
9771 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9772 if (!NameInfo.getName())
9773 return StmtError();
9774 }
9775
9776 // Check whether anything changed.
9777 if (!getDerived().AlwaysRebuild() &&
9778 QualifierLoc == S->getQualifierLoc() &&
9779 NameInfo.getName() == S->getNameInfo().getName())
9780 return S;
9781
9782 // Determine whether this name exists, if we can.
9783 CXXScopeSpec SS;
9784 SS.Adopt(Other: QualifierLoc);
9785 bool Dependent = false;
9786 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9787 case IfExistsResult::Exists:
9788 if (S->isIfExists())
9789 break;
9790
9791 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9792
9793 case IfExistsResult::DoesNotExist:
9794 if (S->isIfNotExists())
9795 break;
9796
9797 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9798
9799 case IfExistsResult::Dependent:
9800 Dependent = true;
9801 break;
9802
9803 case IfExistsResult::Error:
9804 return StmtError();
9805 }
9806
9807 // We need to continue with the instantiation, so do so now.
9808 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9809 if (SubStmt.isInvalid())
9810 return StmtError();
9811
9812 // If we have resolved the name, just transform to the substatement.
9813 if (!Dependent)
9814 return SubStmt;
9815
9816 // The name is still dependent, so build a dependent expression again.
9817 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9818 S->isIfExists(),
9819 QualifierLoc,
9820 NameInfo,
9821 SubStmt.get());
9822}
9823
9824template<typename Derived>
9825ExprResult
9826TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9827 NestedNameSpecifierLoc QualifierLoc;
9828 if (E->getQualifierLoc()) {
9829 QualifierLoc
9830 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9831 if (!QualifierLoc)
9832 return ExprError();
9833 }
9834
9835 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9836 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9837 if (!PD)
9838 return ExprError();
9839
9840 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9841 if (Base.isInvalid())
9842 return ExprError();
9843
9844 return new (SemaRef.getASTContext())
9845 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9846 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9847 QualifierLoc, E->getMemberLoc());
9848}
9849
9850template <typename Derived>
9851ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9852 MSPropertySubscriptExpr *E) {
9853 auto BaseRes = getDerived().TransformExpr(E->getBase());
9854 if (BaseRes.isInvalid())
9855 return ExprError();
9856 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9857 if (IdxRes.isInvalid())
9858 return ExprError();
9859
9860 if (!getDerived().AlwaysRebuild() &&
9861 BaseRes.get() == E->getBase() &&
9862 IdxRes.get() == E->getIdx())
9863 return E;
9864
9865 return getDerived().RebuildArraySubscriptExpr(
9866 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9867}
9868
9869template <typename Derived>
9870StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9871 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9872 if (TryBlock.isInvalid())
9873 return StmtError();
9874
9875 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9876 if (Handler.isInvalid())
9877 return StmtError();
9878
9879 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9880 Handler.get() == S->getHandler())
9881 return S;
9882
9883 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9884 TryBlock.get(), Handler.get());
9885}
9886
9887template <typename Derived>
9888StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9889 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9890 if (Block.isInvalid())
9891 return StmtError();
9892
9893 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9894}
9895
9896template <typename Derived>
9897StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9898 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9899 if (FilterExpr.isInvalid())
9900 return StmtError();
9901
9902 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9903 if (Block.isInvalid())
9904 return StmtError();
9905
9906 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9907 Block.get());
9908}
9909
9910template <typename Derived>
9911StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9912 if (isa<SEHFinallyStmt>(Val: Handler))
9913 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9914 else
9915 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9916}
9917
9918template<typename Derived>
9919StmtResult
9920TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9921 return S;
9922}
9923
9924//===----------------------------------------------------------------------===//
9925// OpenMP directive transformation
9926//===----------------------------------------------------------------------===//
9927
9928template <typename Derived>
9929StmtResult
9930TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9931 // OMPCanonicalLoops are eliminated during transformation, since they will be
9932 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9933 // after transformation.
9934 return getDerived().TransformStmt(L->getLoopStmt());
9935}
9936
9937template <typename Derived>
9938StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9939 OMPExecutableDirective *D) {
9940
9941 // Transform the clauses
9942 llvm::SmallVector<OMPClause *, 16> TClauses;
9943 ArrayRef<OMPClause *> Clauses = D->clauses();
9944 TClauses.reserve(N: Clauses.size());
9945 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9946 I != E; ++I) {
9947 if (*I) {
9948 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9949 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9950 getDerived().getSema().OpenMP().EndOpenMPClause();
9951 if (Clause)
9952 TClauses.push_back(Elt: Clause);
9953 } else {
9954 TClauses.push_back(Elt: nullptr);
9955 }
9956 }
9957 StmtResult AssociatedStmt;
9958 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9959 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9960 D->getDirectiveKind(),
9961 /*CurScope=*/nullptr);
9962 StmtResult Body;
9963 {
9964 Sema::CompoundScopeRAII CompoundScope(getSema());
9965 Stmt *CS;
9966 if (D->getDirectiveKind() == OMPD_atomic ||
9967 D->getDirectiveKind() == OMPD_critical ||
9968 D->getDirectiveKind() == OMPD_section ||
9969 D->getDirectiveKind() == OMPD_master)
9970 CS = D->getAssociatedStmt();
9971 else
9972 CS = D->getRawStmt();
9973 Body = getDerived().TransformStmt(CS);
9974 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9975 getSema().getLangOpts().OpenMPIRBuilder)
9976 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9977 }
9978 AssociatedStmt =
9979 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9980 if (AssociatedStmt.isInvalid()) {
9981 return StmtError();
9982 }
9983 }
9984 if (TClauses.size() != Clauses.size()) {
9985 return StmtError();
9986 }
9987
9988 // Transform directive name for 'omp critical' directive.
9989 DeclarationNameInfo DirName;
9990 if (D->getDirectiveKind() == OMPD_critical) {
9991 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9992 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9993 }
9994 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9995 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9996 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9997 } else if (D->getDirectiveKind() == OMPD_cancel) {
9998 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9999 }
10000
10001 return getDerived().RebuildOMPExecutableDirective(
10002 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
10003 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
10004}
10005
10006/// This is mostly the same as above, but allows 'informational' class
10007/// directives when rebuilding the stmt. It still takes an
10008/// OMPExecutableDirective-type argument because we're reusing that as the
10009/// superclass for the 'assume' directive at present, instead of defining a
10010/// mostly-identical OMPInformationalDirective parent class.
10011template <typename Derived>
10012StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
10013 OMPExecutableDirective *D) {
10014
10015 // Transform the clauses
10016 llvm::SmallVector<OMPClause *, 16> TClauses;
10017 ArrayRef<OMPClause *> Clauses = D->clauses();
10018 TClauses.reserve(N: Clauses.size());
10019 for (OMPClause *C : Clauses) {
10020 if (C) {
10021 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
10022 OMPClause *Clause = getDerived().TransformOMPClause(C);
10023 getDerived().getSema().OpenMP().EndOpenMPClause();
10024 if (Clause)
10025 TClauses.push_back(Elt: Clause);
10026 } else {
10027 TClauses.push_back(Elt: nullptr);
10028 }
10029 }
10030 StmtResult AssociatedStmt;
10031 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
10032 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
10033 D->getDirectiveKind(),
10034 /*CurScope=*/nullptr);
10035 StmtResult Body;
10036 {
10037 Sema::CompoundScopeRAII CompoundScope(getSema());
10038 assert(D->getDirectiveKind() == OMPD_assume &&
10039 "Unexpected informational directive");
10040 Stmt *CS = D->getAssociatedStmt();
10041 Body = getDerived().TransformStmt(CS);
10042 }
10043 AssociatedStmt =
10044 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
10045 if (AssociatedStmt.isInvalid())
10046 return StmtError();
10047 }
10048 if (TClauses.size() != Clauses.size())
10049 return StmtError();
10050
10051 DeclarationNameInfo DirName;
10052
10053 return getDerived().RebuildOMPInformationalDirective(
10054 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
10055 D->getBeginLoc(), D->getEndLoc());
10056}
10057
10058template <typename Derived>
10059StmtResult
10060TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
10061 // TODO: Fix This
10062 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
10063 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
10064 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
10065 return StmtError();
10066}
10067
10068template <typename Derived>
10069StmtResult
10070TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
10071 DeclarationNameInfo DirName;
10072 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10073 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
10074 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10075 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10076 return Res;
10077}
10078
10079template <typename Derived>
10080StmtResult
10081TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
10082 DeclarationNameInfo DirName;
10083 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10084 OMPD_simd, DirName, nullptr, D->getBeginLoc());
10085 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10086 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10087 return Res;
10088}
10089
10090template <typename Derived>
10091StmtResult
10092TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
10093 DeclarationNameInfo DirName;
10094 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10095 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10096 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10097 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10098 return Res;
10099}
10100
10101template <typename Derived>
10102StmtResult
10103TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
10104 DeclarationNameInfo DirName;
10105 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10106 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10107 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10108 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10109 return Res;
10110}
10111
10112template <typename Derived>
10113StmtResult
10114TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
10115 DeclarationNameInfo DirName;
10116 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10117 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10118 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10119 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10120 return Res;
10121}
10122
10123template <typename Derived>
10124StmtResult
10125TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
10126 DeclarationNameInfo DirName;
10127 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10128 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10129 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10130 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10131 return Res;
10132}
10133
10134template <typename Derived>
10135StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
10136 OMPInterchangeDirective *D) {
10137 DeclarationNameInfo DirName;
10138 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10139 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10140 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10141 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10142 return Res;
10143}
10144
10145template <typename Derived>
10146StmtResult
10147TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) {
10148 DeclarationNameInfo DirName;
10149 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10150 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10151 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10152 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10153 return Res;
10154}
10155
10156template <typename Derived>
10157StmtResult
10158TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
10159 DeclarationNameInfo DirName;
10160 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10161 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10162 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10163 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10164 return Res;
10165}
10166
10167template <typename Derived>
10168StmtResult
10169TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
10170 DeclarationNameInfo DirName;
10171 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10172 OMPD_for, DirName, nullptr, D->getBeginLoc());
10173 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10174 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10175 return Res;
10176}
10177
10178template <typename Derived>
10179StmtResult
10180TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
10181 DeclarationNameInfo DirName;
10182 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10183 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
10184 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10185 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10186 return Res;
10187}
10188
10189template <typename Derived>
10190StmtResult
10191TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
10192 DeclarationNameInfo DirName;
10193 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10194 OMPD_sections, DirName, nullptr, D->getBeginLoc());
10195 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10196 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10197 return Res;
10198}
10199
10200template <typename Derived>
10201StmtResult
10202TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
10203 DeclarationNameInfo DirName;
10204 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10205 OMPD_section, DirName, nullptr, D->getBeginLoc());
10206 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10207 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10208 return Res;
10209}
10210
10211template <typename Derived>
10212StmtResult
10213TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
10214 DeclarationNameInfo DirName;
10215 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10216 OMPD_scope, DirName, nullptr, D->getBeginLoc());
10217 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10218 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10219 return Res;
10220}
10221
10222template <typename Derived>
10223StmtResult
10224TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
10225 DeclarationNameInfo DirName;
10226 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10227 OMPD_single, DirName, nullptr, D->getBeginLoc());
10228 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10229 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10230 return Res;
10231}
10232
10233template <typename Derived>
10234StmtResult
10235TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
10236 DeclarationNameInfo DirName;
10237 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10238 OMPD_master, DirName, nullptr, D->getBeginLoc());
10239 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10240 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10241 return Res;
10242}
10243
10244template <typename Derived>
10245StmtResult
10246TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
10247 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10248 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
10249 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10250 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10251 return Res;
10252}
10253
10254template <typename Derived>
10255StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
10256 OMPParallelForDirective *D) {
10257 DeclarationNameInfo DirName;
10258 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10259 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
10260 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10261 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10262 return Res;
10263}
10264
10265template <typename Derived>
10266StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
10267 OMPParallelForSimdDirective *D) {
10268 DeclarationNameInfo DirName;
10269 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10270 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10271 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10272 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10273 return Res;
10274}
10275
10276template <typename Derived>
10277StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
10278 OMPParallelMasterDirective *D) {
10279 DeclarationNameInfo DirName;
10280 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10281 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
10282 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10283 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10284 return Res;
10285}
10286
10287template <typename Derived>
10288StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
10289 OMPParallelMaskedDirective *D) {
10290 DeclarationNameInfo DirName;
10291 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10292 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
10293 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10294 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10295 return Res;
10296}
10297
10298template <typename Derived>
10299StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
10300 OMPParallelSectionsDirective *D) {
10301 DeclarationNameInfo DirName;
10302 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10303 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
10304 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10305 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10306 return Res;
10307}
10308
10309template <typename Derived>
10310StmtResult
10311TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
10312 DeclarationNameInfo DirName;
10313 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10314 OMPD_task, DirName, nullptr, D->getBeginLoc());
10315 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10316 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10317 return Res;
10318}
10319
10320template <typename Derived>
10321StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
10322 OMPTaskyieldDirective *D) {
10323 DeclarationNameInfo DirName;
10324 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10325 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
10326 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10327 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10328 return Res;
10329}
10330
10331template <typename Derived>
10332StmtResult
10333TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
10334 DeclarationNameInfo DirName;
10335 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10336 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
10337 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10338 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10339 return Res;
10340}
10341
10342template <typename Derived>
10343StmtResult
10344TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
10345 DeclarationNameInfo DirName;
10346 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10347 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
10348 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10349 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10350 return Res;
10351}
10352
10353template <typename Derived>
10354StmtResult
10355TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
10356 DeclarationNameInfo DirName;
10357 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10358 OMPD_assume, DirName, nullptr, D->getBeginLoc());
10359 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
10360 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10361 return Res;
10362}
10363
10364template <typename Derived>
10365StmtResult
10366TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
10367 DeclarationNameInfo DirName;
10368 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10369 OMPD_error, DirName, nullptr, D->getBeginLoc());
10370 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10371 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10372 return Res;
10373}
10374
10375template <typename Derived>
10376StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
10377 OMPTaskgroupDirective *D) {
10378 DeclarationNameInfo DirName;
10379 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10380 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
10381 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10382 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10383 return Res;
10384}
10385
10386template <typename Derived>
10387StmtResult
10388TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
10389 DeclarationNameInfo DirName;
10390 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10391 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10392 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10393 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10394 return Res;
10395}
10396
10397template <typename Derived>
10398StmtResult
10399TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10400 DeclarationNameInfo DirName;
10401 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10402 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10403 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10404 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10405 return Res;
10406}
10407
10408template <typename Derived>
10409StmtResult
10410TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10411 DeclarationNameInfo DirName;
10412 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10413 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10414 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10415 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10416 return Res;
10417}
10418
10419template <typename Derived>
10420StmtResult TreeTransform<Derived>::TransformOMPOrderedStandaloneDirective(
10421 OMPOrderedStandaloneDirective *D) {
10422 DeclarationNameInfo DirName;
10423 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10424 OMPD_ordered_standalone, DirName, nullptr, D->getBeginLoc());
10425 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10426 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10427 return Res;
10428}
10429
10430template <typename Derived>
10431StmtResult TreeTransform<Derived>::TransformOMPOrderedBlockAssocDirective(
10432 OMPOrderedBlockAssocDirective *D) {
10433 DeclarationNameInfo DirName;
10434 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10435 OMPD_ordered_blockassoc, DirName, nullptr, D->getBeginLoc());
10436 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10437 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10438 return Res;
10439}
10440
10441template <typename Derived>
10442StmtResult
10443TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10444 DeclarationNameInfo DirName;
10445 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10446 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10447 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10448 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10449 return Res;
10450}
10451
10452template <typename Derived>
10453StmtResult
10454TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10455 DeclarationNameInfo DirName;
10456 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10457 OMPD_target, DirName, nullptr, D->getBeginLoc());
10458 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10459 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10460 return Res;
10461}
10462
10463template <typename Derived>
10464StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10465 OMPTargetDataDirective *D) {
10466 DeclarationNameInfo DirName;
10467 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10468 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10469 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10470 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10471 return Res;
10472}
10473
10474template <typename Derived>
10475StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10476 OMPTargetEnterDataDirective *D) {
10477 DeclarationNameInfo DirName;
10478 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10479 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10480 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10481 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10482 return Res;
10483}
10484
10485template <typename Derived>
10486StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10487 OMPTargetExitDataDirective *D) {
10488 DeclarationNameInfo DirName;
10489 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10490 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10491 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10492 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10493 return Res;
10494}
10495
10496template <typename Derived>
10497StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10498 OMPTargetParallelDirective *D) {
10499 DeclarationNameInfo DirName;
10500 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10501 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10502 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10503 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10504 return Res;
10505}
10506
10507template <typename Derived>
10508StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10509 OMPTargetParallelForDirective *D) {
10510 DeclarationNameInfo DirName;
10511 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10512 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10513 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10514 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10515 return Res;
10516}
10517
10518template <typename Derived>
10519StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10520 OMPTargetUpdateDirective *D) {
10521 DeclarationNameInfo DirName;
10522 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10523 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10524 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10525 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10526 return Res;
10527}
10528
10529template <typename Derived>
10530StmtResult
10531TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10532 DeclarationNameInfo DirName;
10533 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10534 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10535 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10536 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10537 return Res;
10538}
10539
10540template <typename Derived>
10541StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10542 OMPCancellationPointDirective *D) {
10543 DeclarationNameInfo DirName;
10544 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10545 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10546 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10547 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10548 return Res;
10549}
10550
10551template <typename Derived>
10552StmtResult
10553TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10554 DeclarationNameInfo DirName;
10555 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10556 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10557 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10558 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10559 return Res;
10560}
10561
10562template <typename Derived>
10563StmtResult
10564TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10565 DeclarationNameInfo DirName;
10566 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10567 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10568 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10569 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10570 return Res;
10571}
10572
10573template <typename Derived>
10574StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10575 OMPTaskLoopSimdDirective *D) {
10576 DeclarationNameInfo DirName;
10577 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10578 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10579 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10580 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10581 return Res;
10582}
10583
10584template <typename Derived>
10585StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10586 OMPMasterTaskLoopDirective *D) {
10587 DeclarationNameInfo DirName;
10588 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10589 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10590 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10591 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10592 return Res;
10593}
10594
10595template <typename Derived>
10596StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10597 OMPMaskedTaskLoopDirective *D) {
10598 DeclarationNameInfo DirName;
10599 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10600 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10601 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10602 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10603 return Res;
10604}
10605
10606template <typename Derived>
10607StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10608 OMPMasterTaskLoopSimdDirective *D) {
10609 DeclarationNameInfo DirName;
10610 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10611 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10612 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10613 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10614 return Res;
10615}
10616
10617template <typename Derived>
10618StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10619 OMPMaskedTaskLoopSimdDirective *D) {
10620 DeclarationNameInfo DirName;
10621 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10622 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10623 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10624 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10625 return Res;
10626}
10627
10628template <typename Derived>
10629StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10630 OMPParallelMasterTaskLoopDirective *D) {
10631 DeclarationNameInfo DirName;
10632 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10633 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10634 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10635 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10636 return Res;
10637}
10638
10639template <typename Derived>
10640StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10641 OMPParallelMaskedTaskLoopDirective *D) {
10642 DeclarationNameInfo DirName;
10643 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10644 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10645 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10646 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10647 return Res;
10648}
10649
10650template <typename Derived>
10651StmtResult
10652TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10653 OMPParallelMasterTaskLoopSimdDirective *D) {
10654 DeclarationNameInfo DirName;
10655 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10656 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10657 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10658 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10659 return Res;
10660}
10661
10662template <typename Derived>
10663StmtResult
10664TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10665 OMPParallelMaskedTaskLoopSimdDirective *D) {
10666 DeclarationNameInfo DirName;
10667 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10668 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10669 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10670 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10671 return Res;
10672}
10673
10674template <typename Derived>
10675StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10676 OMPDistributeDirective *D) {
10677 DeclarationNameInfo DirName;
10678 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10679 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10680 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10681 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10682 return Res;
10683}
10684
10685template <typename Derived>
10686StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10687 OMPDistributeParallelForDirective *D) {
10688 DeclarationNameInfo DirName;
10689 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10690 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10691 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10692 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10693 return Res;
10694}
10695
10696template <typename Derived>
10697StmtResult
10698TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10699 OMPDistributeParallelForSimdDirective *D) {
10700 DeclarationNameInfo DirName;
10701 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10702 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10703 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10704 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10705 return Res;
10706}
10707
10708template <typename Derived>
10709StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10710 OMPDistributeSimdDirective *D) {
10711 DeclarationNameInfo DirName;
10712 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10713 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10714 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10715 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10716 return Res;
10717}
10718
10719template <typename Derived>
10720StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10721 OMPTargetParallelForSimdDirective *D) {
10722 DeclarationNameInfo DirName;
10723 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10724 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10725 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10726 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10727 return Res;
10728}
10729
10730template <typename Derived>
10731StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10732 OMPTargetSimdDirective *D) {
10733 DeclarationNameInfo DirName;
10734 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10735 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10736 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10737 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10738 return Res;
10739}
10740
10741template <typename Derived>
10742StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10743 OMPTeamsDistributeDirective *D) {
10744 DeclarationNameInfo DirName;
10745 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10746 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10747 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10748 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10749 return Res;
10750}
10751
10752template <typename Derived>
10753StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10754 OMPTeamsDistributeSimdDirective *D) {
10755 DeclarationNameInfo DirName;
10756 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10757 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10758 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10759 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10760 return Res;
10761}
10762
10763template <typename Derived>
10764StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10765 OMPTeamsDistributeParallelForSimdDirective *D) {
10766 DeclarationNameInfo DirName;
10767 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10768 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10769 D->getBeginLoc());
10770 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10771 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10772 return Res;
10773}
10774
10775template <typename Derived>
10776StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10777 OMPTeamsDistributeParallelForDirective *D) {
10778 DeclarationNameInfo DirName;
10779 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10780 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10781 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10782 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10783 return Res;
10784}
10785
10786template <typename Derived>
10787StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10788 OMPTargetTeamsDirective *D) {
10789 DeclarationNameInfo DirName;
10790 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10791 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10792 auto Res = getDerived().TransformOMPExecutableDirective(D);
10793 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10794 return Res;
10795}
10796
10797template <typename Derived>
10798StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10799 OMPTargetTeamsDistributeDirective *D) {
10800 DeclarationNameInfo DirName;
10801 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10802 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10803 auto Res = getDerived().TransformOMPExecutableDirective(D);
10804 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10805 return Res;
10806}
10807
10808template <typename Derived>
10809StmtResult
10810TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10811 OMPTargetTeamsDistributeParallelForDirective *D) {
10812 DeclarationNameInfo DirName;
10813 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10814 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10815 D->getBeginLoc());
10816 auto Res = getDerived().TransformOMPExecutableDirective(D);
10817 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10818 return Res;
10819}
10820
10821template <typename Derived>
10822StmtResult TreeTransform<Derived>::
10823 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10824 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10825 DeclarationNameInfo DirName;
10826 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10827 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10828 D->getBeginLoc());
10829 auto Res = getDerived().TransformOMPExecutableDirective(D);
10830 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10831 return Res;
10832}
10833
10834template <typename Derived>
10835StmtResult
10836TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10837 OMPTargetTeamsDistributeSimdDirective *D) {
10838 DeclarationNameInfo DirName;
10839 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10840 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10841 auto Res = getDerived().TransformOMPExecutableDirective(D);
10842 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10843 return Res;
10844}
10845
10846template <typename Derived>
10847StmtResult
10848TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10849 DeclarationNameInfo DirName;
10850 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10851 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10852 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10853 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10854 return Res;
10855}
10856
10857template <typename Derived>
10858StmtResult
10859TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10860 DeclarationNameInfo DirName;
10861 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10862 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10863 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10864 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10865 return Res;
10866}
10867
10868template <typename Derived>
10869StmtResult
10870TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10871 DeclarationNameInfo DirName;
10872 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10873 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10874 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10875 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10876 return Res;
10877}
10878
10879template <typename Derived>
10880StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10881 OMPGenericLoopDirective *D) {
10882 DeclarationNameInfo DirName;
10883 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10884 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10885 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10886 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10887 return Res;
10888}
10889
10890template <typename Derived>
10891StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10892 OMPTeamsGenericLoopDirective *D) {
10893 DeclarationNameInfo DirName;
10894 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10895 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10896 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10897 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10898 return Res;
10899}
10900
10901template <typename Derived>
10902StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10903 OMPTargetTeamsGenericLoopDirective *D) {
10904 DeclarationNameInfo DirName;
10905 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10906 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10907 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10908 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10909 return Res;
10910}
10911
10912template <typename Derived>
10913StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10914 OMPParallelGenericLoopDirective *D) {
10915 DeclarationNameInfo DirName;
10916 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10917 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10918 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10919 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10920 return Res;
10921}
10922
10923template <typename Derived>
10924StmtResult
10925TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10926 OMPTargetParallelGenericLoopDirective *D) {
10927 DeclarationNameInfo DirName;
10928 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10929 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10930 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10931 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10932 return Res;
10933}
10934
10935//===----------------------------------------------------------------------===//
10936// OpenMP clause transformation
10937//===----------------------------------------------------------------------===//
10938template <typename Derived>
10939OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10940 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10941 if (Cond.isInvalid())
10942 return nullptr;
10943 return getDerived().RebuildOMPIfClause(
10944 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10945 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10946}
10947
10948template <typename Derived>
10949OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10950 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10951 if (Cond.isInvalid())
10952 return nullptr;
10953 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10954 C->getLParenLoc(), C->getEndLoc());
10955}
10956
10957template <typename Derived>
10958OMPClause *
10959TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10960 llvm::SmallVector<Expr *, 3> Vars;
10961 Vars.reserve(N: C->varlist_size());
10962 for (auto *VE : C->varlist()) {
10963 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10964 if (EVar.isInvalid())
10965 return nullptr;
10966 Vars.push_back(Elt: EVar.get());
10967 }
10968 Expr *DimsModifierExpr = C->getDimsModifierExpr();
10969 if (DimsModifierExpr) {
10970 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: DimsModifierExpr));
10971 if (EVar.isInvalid())
10972 return nullptr;
10973 DimsModifierExpr = EVar.get();
10974 }
10975 return getDerived().RebuildOMPNumThreadsClause(
10976 Vars, C->getPrescriptivenessModifier(),
10977 C->getPrescriptivenessModifierLoc(), C->getDimsModifier(),
10978 DimsModifierExpr, C->getDimsModifierLoc(), C->getBeginLoc(),
10979 C->getLParenLoc(), C->getEndLoc());
10980}
10981
10982template <typename Derived>
10983OMPClause *
10984TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10985 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10986 if (E.isInvalid())
10987 return nullptr;
10988 return getDerived().RebuildOMPSafelenClause(
10989 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10990}
10991
10992template <typename Derived>
10993OMPClause *
10994TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10995 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10996 if (E.isInvalid())
10997 return nullptr;
10998 return getDerived().RebuildOMPAllocatorClause(
10999 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11000}
11001
11002template <typename Derived>
11003OMPClause *
11004TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
11005 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
11006 if (E.isInvalid())
11007 return nullptr;
11008 return getDerived().RebuildOMPSimdlenClause(
11009 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11010}
11011
11012template <typename Derived>
11013OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
11014 SmallVector<Expr *, 4> TransformedSizes;
11015 TransformedSizes.reserve(N: C->getNumSizes());
11016 bool Changed = false;
11017 for (Expr *E : C->getSizesRefs()) {
11018 if (!E) {
11019 TransformedSizes.push_back(Elt: nullptr);
11020 continue;
11021 }
11022
11023 ExprResult T = getDerived().TransformExpr(E);
11024 if (T.isInvalid())
11025 return nullptr;
11026 if (E != T.get())
11027 Changed = true;
11028 TransformedSizes.push_back(Elt: T.get());
11029 }
11030
11031 if (!Changed && !getDerived().AlwaysRebuild())
11032 return C;
11033 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
11034 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11035}
11036
11037template <typename Derived>
11038OMPClause *
11039TreeTransform<Derived>::TransformOMPCountsClause(OMPCountsClause *C) {
11040 SmallVector<Expr *, 4> TransformedCounts;
11041 TransformedCounts.reserve(N: C->getNumCounts());
11042 for (Expr *E : C->getCountsRefs()) {
11043 if (!E) {
11044 TransformedCounts.push_back(Elt: nullptr);
11045 continue;
11046 }
11047
11048 ExprResult T = getDerived().TransformExpr(E);
11049 if (T.isInvalid())
11050 return nullptr;
11051 TransformedCounts.push_back(Elt: T.get());
11052 }
11053
11054 return RebuildOMPCountsClause(Counts: TransformedCounts, StartLoc: C->getBeginLoc(),
11055 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc(),
11056 FillIdx: C->getOmpFillIndex(), FillLoc: C->getOmpFillLoc());
11057}
11058
11059template <typename Derived>
11060OMPClause *
11061TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
11062 SmallVector<Expr *> TransformedArgs;
11063 TransformedArgs.reserve(N: C->getNumLoops());
11064 bool Changed = false;
11065 for (Expr *E : C->getArgsRefs()) {
11066 if (!E) {
11067 TransformedArgs.push_back(Elt: nullptr);
11068 continue;
11069 }
11070
11071 ExprResult T = getDerived().TransformExpr(E);
11072 if (T.isInvalid())
11073 return nullptr;
11074 if (E != T.get())
11075 Changed = true;
11076 TransformedArgs.push_back(Elt: T.get());
11077 }
11078
11079 if (!Changed && !getDerived().AlwaysRebuild())
11080 return C;
11081 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
11082 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11083}
11084
11085template <typename Derived>
11086OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
11087 if (!getDerived().AlwaysRebuild())
11088 return C;
11089 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
11090}
11091
11092template <typename Derived>
11093OMPClause *
11094TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
11095 ExprResult T = getDerived().TransformExpr(C->getFactor());
11096 if (T.isInvalid())
11097 return nullptr;
11098 Expr *Factor = T.get();
11099 bool Changed = Factor != C->getFactor();
11100
11101 if (!Changed && !getDerived().AlwaysRebuild())
11102 return C;
11103 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
11104 EndLoc: C->getEndLoc());
11105}
11106
11107template <typename Derived>
11108OMPClause *
11109TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
11110 ExprResult F = getDerived().TransformExpr(C->getFirst());
11111 if (F.isInvalid())
11112 return nullptr;
11113
11114 ExprResult Cn = getDerived().TransformExpr(C->getCount());
11115 if (Cn.isInvalid())
11116 return nullptr;
11117
11118 Expr *First = F.get();
11119 Expr *Count = Cn.get();
11120
11121 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
11122
11123 // If no changes and AlwaysRebuild() is false, return the original clause
11124 if (!Changed && !getDerived().AlwaysRebuild())
11125 return C;
11126
11127 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
11128 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
11129 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
11130}
11131
11132template <typename Derived>
11133OMPClause *
11134TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
11135 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
11136 if (E.isInvalid())
11137 return nullptr;
11138 return getDerived().RebuildOMPCollapseClause(
11139 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11140}
11141
11142template <typename Derived>
11143OMPClause *
11144TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
11145 return getDerived().RebuildOMPDefaultClause(
11146 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
11147 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
11148 C->getEndLoc());
11149}
11150
11151template <typename Derived>
11152OMPClause *
11153TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
11154 // No need to rebuild this clause, no template-dependent parameters.
11155 return C;
11156}
11157
11158template <typename Derived>
11159OMPClause *
11160TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
11161 Expr *Impex = C->getImpexType();
11162 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
11163
11164 if (TransformedImpex.isInvalid())
11165 return nullptr;
11166
11167 return getDerived().RebuildOMPTransparentClause(
11168 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
11169 C->getEndLoc());
11170}
11171
11172template <typename Derived>
11173OMPClause *
11174TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
11175 return getDerived().RebuildOMPProcBindClause(
11176 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
11177 C->getLParenLoc(), C->getEndLoc());
11178}
11179
11180template <typename Derived>
11181OMPClause *
11182TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
11183 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11184 if (E.isInvalid())
11185 return nullptr;
11186 return getDerived().RebuildOMPScheduleClause(
11187 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
11188 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11189 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
11190 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11191}
11192
11193template <typename Derived>
11194OMPClause *
11195TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
11196 ExprResult E;
11197 if (auto *Num = C->getNumForLoops()) {
11198 E = getDerived().TransformExpr(Num);
11199 if (E.isInvalid())
11200 return nullptr;
11201 }
11202 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
11203 C->getLParenLoc(), E.get());
11204}
11205
11206template <typename Derived>
11207OMPClause *
11208TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
11209 ExprResult E;
11210 if (Expr *Evt = C->getEventHandler()) {
11211 E = getDerived().TransformExpr(Evt);
11212 if (E.isInvalid())
11213 return nullptr;
11214 }
11215 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
11216 C->getLParenLoc(), C->getEndLoc());
11217}
11218
11219template <typename Derived>
11220OMPClause *
11221TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
11222 ExprResult Cond;
11223 if (auto *Condition = C->getCondition()) {
11224 Cond = getDerived().TransformExpr(Condition);
11225 if (Cond.isInvalid())
11226 return nullptr;
11227 }
11228 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
11229 C->getLParenLoc(), C->getEndLoc());
11230}
11231
11232template <typename Derived>
11233OMPClause *
11234TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
11235 // No need to rebuild this clause, no template-dependent parameters.
11236 return C;
11237}
11238
11239template <typename Derived>
11240OMPClause *
11241TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
11242 // No need to rebuild this clause, no template-dependent parameters.
11243 return C;
11244}
11245
11246template <typename Derived>
11247OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
11248 // No need to rebuild this clause, no template-dependent parameters.
11249 return C;
11250}
11251
11252template <typename Derived>
11253OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
11254 // No need to rebuild this clause, no template-dependent parameters.
11255 return C;
11256}
11257
11258template <typename Derived>
11259OMPClause *
11260TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
11261 // No need to rebuild this clause, no template-dependent parameters.
11262 return C;
11263}
11264
11265template <typename Derived>
11266OMPClause *TreeTransform<Derived>::TransformOMPUpdateDependObjectsClause(
11267 OMPUpdateDependObjectsClause *C) {
11268 // No need to rebuild this clause, no template-dependent parameters.
11269 return C;
11270}
11271
11272template <typename Derived>
11273OMPClause *
11274TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
11275 // No need to rebuild this clause, no template-dependent parameters.
11276 return C;
11277}
11278
11279template <typename Derived>
11280OMPClause *
11281TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
11282 // No need to rebuild this clause, no template-dependent parameters.
11283 return C;
11284}
11285
11286template <typename Derived>
11287OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
11288 // No need to rebuild this clause, no template-dependent parameters.
11289 return C;
11290}
11291
11292template <typename Derived>
11293OMPClause *
11294TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
11295 return C;
11296}
11297
11298template <typename Derived>
11299OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
11300 ExprResult E = getDerived().TransformExpr(C->getExpr());
11301 if (E.isInvalid())
11302 return nullptr;
11303 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
11304 C->getLParenLoc(), C->getEndLoc());
11305}
11306
11307template <typename Derived>
11308OMPClause *
11309TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
11310 return C;
11311}
11312
11313template <typename Derived>
11314OMPClause *
11315TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
11316 return C;
11317}
11318template <typename Derived>
11319OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
11320 OMPNoOpenMPRoutinesClause *C) {
11321 return C;
11322}
11323template <typename Derived>
11324OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
11325 OMPNoOpenMPConstructsClause *C) {
11326 return C;
11327}
11328template <typename Derived>
11329OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
11330 OMPNoParallelismClause *C) {
11331 return C;
11332}
11333
11334template <typename Derived>
11335OMPClause *
11336TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
11337 // No need to rebuild this clause, no template-dependent parameters.
11338 return C;
11339}
11340
11341template <typename Derived>
11342OMPClause *
11343TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
11344 // No need to rebuild this clause, no template-dependent parameters.
11345 return C;
11346}
11347
11348template <typename Derived>
11349OMPClause *
11350TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
11351 // No need to rebuild this clause, no template-dependent parameters.
11352 return C;
11353}
11354
11355template <typename Derived>
11356OMPClause *
11357TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
11358 // No need to rebuild this clause, no template-dependent parameters.
11359 return C;
11360}
11361
11362template <typename Derived>
11363OMPClause *
11364TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
11365 // No need to rebuild this clause, no template-dependent parameters.
11366 return C;
11367}
11368
11369template <typename Derived>
11370OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
11371 // No need to rebuild this clause, no template-dependent parameters.
11372 return C;
11373}
11374
11375template <typename Derived>
11376OMPClause *
11377TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
11378 // No need to rebuild this clause, no template-dependent parameters.
11379 return C;
11380}
11381
11382template <typename Derived>
11383OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
11384 // No need to rebuild this clause, no template-dependent parameters.
11385 return C;
11386}
11387
11388template <typename Derived>
11389OMPClause *
11390TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
11391 // No need to rebuild this clause, no template-dependent parameters.
11392 return C;
11393}
11394
11395template <typename Derived>
11396OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
11397 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
11398 if (IVR.isInvalid())
11399 return nullptr;
11400
11401 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
11402 for (OMPInitClause::PrefView P : C->prefs()) {
11403 Expr *NewFr = nullptr;
11404 if (P.Fr) {
11405 ExprResult ER = getDerived().TransformExpr(P.Fr);
11406 if (ER.isInvalid())
11407 return nullptr;
11408 NewFr = ER.get();
11409 }
11410 SmallVector<Expr *, 2> NewAttrs;
11411 NewAttrs.reserve(N: P.Attrs.size());
11412 for (Expr *A : P.Attrs) {
11413 ExprResult ER = getDerived().TransformExpr(A);
11414 if (ER.isInvalid())
11415 return nullptr;
11416 NewAttrs.push_back(Elt: ER.get());
11417 }
11418 InteropInfo.Prefs.emplace_back(Args&: NewFr, Args: std::move(NewAttrs));
11419 }
11420 InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
11421 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
11422 C->getBeginLoc(), C->getLParenLoc(),
11423 C->getVarLoc(), C->getEndLoc());
11424}
11425
11426template <typename Derived>
11427OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
11428 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
11429 if (ER.isInvalid())
11430 return nullptr;
11431 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
11432 C->getLParenLoc(), C->getVarLoc(),
11433 C->getEndLoc());
11434}
11435
11436template <typename Derived>
11437OMPClause *
11438TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
11439 ExprResult ER;
11440 if (Expr *IV = C->getInteropVar()) {
11441 ER = getDerived().TransformExpr(IV);
11442 if (ER.isInvalid())
11443 return nullptr;
11444 }
11445 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
11446 C->getLParenLoc(), C->getVarLoc(),
11447 C->getEndLoc());
11448}
11449
11450template <typename Derived>
11451OMPClause *
11452TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
11453 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11454 if (Cond.isInvalid())
11455 return nullptr;
11456 return getDerived().RebuildOMPNovariantsClause(
11457 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11458}
11459
11460template <typename Derived>
11461OMPClause *
11462TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11463 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11464 if (Cond.isInvalid())
11465 return nullptr;
11466 return getDerived().RebuildOMPNocontextClause(
11467 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11468}
11469
11470template <typename Derived>
11471OMPClause *
11472TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11473 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11474 if (ThreadID.isInvalid())
11475 return nullptr;
11476 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11477 C->getLParenLoc(), C->getEndLoc());
11478}
11479
11480template <typename Derived>
11481OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11482 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11483 if (E.isInvalid())
11484 return nullptr;
11485 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11486 C->getLParenLoc(), C->getEndLoc());
11487}
11488
11489template <typename Derived>
11490OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11491 OMPUnifiedAddressClause *C) {
11492 llvm_unreachable("unified_address clause cannot appear in dependent context");
11493}
11494
11495template <typename Derived>
11496OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11497 OMPUnifiedSharedMemoryClause *C) {
11498 llvm_unreachable(
11499 "unified_shared_memory clause cannot appear in dependent context");
11500}
11501
11502template <typename Derived>
11503OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11504 OMPReverseOffloadClause *C) {
11505 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11506}
11507
11508template <typename Derived>
11509OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11510 OMPDynamicAllocatorsClause *C) {
11511 llvm_unreachable(
11512 "dynamic_allocators clause cannot appear in dependent context");
11513}
11514
11515template <typename Derived>
11516OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11517 OMPAtomicDefaultMemOrderClause *C) {
11518 llvm_unreachable(
11519 "atomic_default_mem_order clause cannot appear in dependent context");
11520}
11521
11522template <typename Derived>
11523OMPClause *
11524TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11525 llvm_unreachable("self_maps clause cannot appear in dependent context");
11526}
11527
11528template <typename Derived>
11529OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11530 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11531 C->getBeginLoc(), C->getLParenLoc(),
11532 C->getEndLoc());
11533}
11534
11535template <typename Derived>
11536OMPClause *
11537TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11538 return getDerived().RebuildOMPSeverityClause(
11539 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11540 C->getLParenLoc(), C->getEndLoc());
11541}
11542
11543template <typename Derived>
11544OMPClause *
11545TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11546 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11547 if (E.isInvalid())
11548 return nullptr;
11549 return getDerived().RebuildOMPMessageClause(
11550 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11551}
11552
11553template <typename Derived>
11554OMPClause *
11555TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11556 llvm::SmallVector<Expr *, 16> Vars;
11557 Vars.reserve(N: C->varlist_size());
11558 for (auto *VE : C->varlist()) {
11559 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11560 if (EVar.isInvalid())
11561 return nullptr;
11562 Vars.push_back(Elt: EVar.get());
11563 }
11564 return getDerived().RebuildOMPPrivateClause(
11565 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11566}
11567
11568template <typename Derived>
11569OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11570 OMPFirstprivateClause *C) {
11571 llvm::SmallVector<Expr *, 16> Vars;
11572 Vars.reserve(N: C->varlist_size());
11573 for (auto *VE : C->varlist()) {
11574 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11575 if (EVar.isInvalid())
11576 return nullptr;
11577 Vars.push_back(Elt: EVar.get());
11578 }
11579 return getDerived().RebuildOMPFirstprivateClause(
11580 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11581}
11582
11583template <typename Derived>
11584OMPClause *
11585TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11586 llvm::SmallVector<Expr *, 16> Vars;
11587 Vars.reserve(N: C->varlist_size());
11588 for (auto *VE : C->varlist()) {
11589 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11590 if (EVar.isInvalid())
11591 return nullptr;
11592 Vars.push_back(Elt: EVar.get());
11593 }
11594 return getDerived().RebuildOMPLastprivateClause(
11595 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11596 C->getLParenLoc(), C->getEndLoc());
11597}
11598
11599template <typename Derived>
11600OMPClause *
11601TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11602 llvm::SmallVector<Expr *, 16> Vars;
11603 Vars.reserve(N: C->varlist_size());
11604 for (auto *VE : C->varlist()) {
11605 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11606 if (EVar.isInvalid())
11607 return nullptr;
11608 Vars.push_back(Elt: EVar.get());
11609 }
11610 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11611 C->getLParenLoc(), C->getEndLoc());
11612}
11613
11614template <typename Derived>
11615OMPClause *
11616TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11617 llvm::SmallVector<Expr *, 16> Vars;
11618 Vars.reserve(N: C->varlist_size());
11619 for (auto *VE : C->varlist()) {
11620 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11621 if (EVar.isInvalid())
11622 return nullptr;
11623 Vars.push_back(Elt: EVar.get());
11624 }
11625 CXXScopeSpec ReductionIdScopeSpec;
11626 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11627
11628 DeclarationNameInfo NameInfo = C->getNameInfo();
11629 if (NameInfo.getName()) {
11630 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11631 if (!NameInfo.getName())
11632 return nullptr;
11633 }
11634 // Build a list of all UDR decls with the same names ranged by the Scopes.
11635 // The Scope boundary is a duplication of the previous decl.
11636 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11637 for (auto *E : C->reduction_ops()) {
11638 // Transform all the decls.
11639 if (E) {
11640 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11641 UnresolvedSet<8> Decls;
11642 for (auto *D : ULE->decls()) {
11643 NamedDecl *InstD =
11644 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11645 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11646 }
11647 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11648 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11649 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11650 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11651 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11652 } else
11653 UnresolvedReductions.push_back(Elt: nullptr);
11654 }
11655 return getDerived().RebuildOMPReductionClause(
11656 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11657 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11658 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11659}
11660
11661template <typename Derived>
11662OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11663 OMPTaskReductionClause *C) {
11664 llvm::SmallVector<Expr *, 16> Vars;
11665 Vars.reserve(N: C->varlist_size());
11666 for (auto *VE : C->varlist()) {
11667 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11668 if (EVar.isInvalid())
11669 return nullptr;
11670 Vars.push_back(Elt: EVar.get());
11671 }
11672 CXXScopeSpec ReductionIdScopeSpec;
11673 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11674
11675 DeclarationNameInfo NameInfo = C->getNameInfo();
11676 if (NameInfo.getName()) {
11677 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11678 if (!NameInfo.getName())
11679 return nullptr;
11680 }
11681 // Build a list of all UDR decls with the same names ranged by the Scopes.
11682 // The Scope boundary is a duplication of the previous decl.
11683 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11684 for (auto *E : C->reduction_ops()) {
11685 // Transform all the decls.
11686 if (E) {
11687 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11688 UnresolvedSet<8> Decls;
11689 for (auto *D : ULE->decls()) {
11690 NamedDecl *InstD =
11691 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11692 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11693 }
11694 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11695 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11696 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11697 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11698 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11699 } else
11700 UnresolvedReductions.push_back(Elt: nullptr);
11701 }
11702 return getDerived().RebuildOMPTaskReductionClause(
11703 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11704 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11705}
11706
11707template <typename Derived>
11708OMPClause *
11709TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11710 llvm::SmallVector<Expr *, 16> Vars;
11711 Vars.reserve(N: C->varlist_size());
11712 for (auto *VE : C->varlist()) {
11713 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11714 if (EVar.isInvalid())
11715 return nullptr;
11716 Vars.push_back(Elt: EVar.get());
11717 }
11718 CXXScopeSpec ReductionIdScopeSpec;
11719 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11720
11721 DeclarationNameInfo NameInfo = C->getNameInfo();
11722 if (NameInfo.getName()) {
11723 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11724 if (!NameInfo.getName())
11725 return nullptr;
11726 }
11727 // Build a list of all UDR decls with the same names ranged by the Scopes.
11728 // The Scope boundary is a duplication of the previous decl.
11729 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11730 for (auto *E : C->reduction_ops()) {
11731 // Transform all the decls.
11732 if (E) {
11733 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11734 UnresolvedSet<8> Decls;
11735 for (auto *D : ULE->decls()) {
11736 NamedDecl *InstD =
11737 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11738 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11739 }
11740 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11741 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11742 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11743 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11744 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11745 } else
11746 UnresolvedReductions.push_back(Elt: nullptr);
11747 }
11748 return getDerived().RebuildOMPInReductionClause(
11749 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11750 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11751}
11752
11753template <typename Derived>
11754OMPClause *
11755TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11756 llvm::SmallVector<Expr *, 16> Vars;
11757 Vars.reserve(N: C->varlist_size());
11758 for (auto *VE : C->varlist()) {
11759 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11760 if (EVar.isInvalid())
11761 return nullptr;
11762 Vars.push_back(Elt: EVar.get());
11763 }
11764 ExprResult Step = getDerived().TransformExpr(C->getStep());
11765 if (Step.isInvalid())
11766 return nullptr;
11767 return getDerived().RebuildOMPLinearClause(
11768 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11769 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11770 C->getEndLoc());
11771}
11772
11773template <typename Derived>
11774OMPClause *
11775TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11776 llvm::SmallVector<Expr *, 16> Vars;
11777 Vars.reserve(N: C->varlist_size());
11778 for (auto *VE : C->varlist()) {
11779 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11780 if (EVar.isInvalid())
11781 return nullptr;
11782 Vars.push_back(Elt: EVar.get());
11783 }
11784 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11785 if (Alignment.isInvalid())
11786 return nullptr;
11787 return getDerived().RebuildOMPAlignedClause(
11788 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11789 C->getColonLoc(), C->getEndLoc());
11790}
11791
11792template <typename Derived>
11793OMPClause *
11794TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11795 llvm::SmallVector<Expr *, 16> Vars;
11796 Vars.reserve(N: C->varlist_size());
11797 for (auto *VE : C->varlist()) {
11798 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11799 if (EVar.isInvalid())
11800 return nullptr;
11801 Vars.push_back(Elt: EVar.get());
11802 }
11803 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11804 C->getLParenLoc(), C->getEndLoc());
11805}
11806
11807template <typename Derived>
11808OMPClause *
11809TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11810 llvm::SmallVector<Expr *, 16> Vars;
11811 Vars.reserve(N: C->varlist_size());
11812 for (auto *VE : C->varlist()) {
11813 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11814 if (EVar.isInvalid())
11815 return nullptr;
11816 Vars.push_back(Elt: EVar.get());
11817 }
11818 return getDerived().RebuildOMPCopyprivateClause(
11819 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11820}
11821
11822template <typename Derived>
11823OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11824 llvm::SmallVector<Expr *, 16> Vars;
11825 Vars.reserve(N: C->varlist_size());
11826 for (auto *VE : C->varlist()) {
11827 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11828 if (EVar.isInvalid())
11829 return nullptr;
11830 Vars.push_back(Elt: EVar.get());
11831 }
11832 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11833 C->getLParenLoc(), C->getEndLoc());
11834}
11835
11836template <typename Derived>
11837OMPClause *
11838TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11839 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11840 if (E.isInvalid())
11841 return nullptr;
11842 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11843 C->getLParenLoc(), C->getEndLoc());
11844}
11845
11846template <typename Derived>
11847OMPClause *
11848TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11849 llvm::SmallVector<Expr *, 16> Vars;
11850 Expr *DepModifier = C->getModifier();
11851 if (DepModifier) {
11852 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11853 if (DepModRes.isInvalid())
11854 return nullptr;
11855 DepModifier = DepModRes.get();
11856 }
11857 Vars.reserve(N: C->varlist_size());
11858 for (auto *VE : C->varlist()) {
11859 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11860 if (EVar.isInvalid())
11861 return nullptr;
11862 Vars.push_back(Elt: EVar.get());
11863 }
11864 return getDerived().RebuildOMPDependClause(
11865 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11866 C->getOmpAllMemoryLoc()},
11867 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11868}
11869
11870template <typename Derived>
11871OMPClause *
11872TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11873 ExprResult E = getDerived().TransformExpr(C->getDevice());
11874 if (E.isInvalid())
11875 return nullptr;
11876 return getDerived().RebuildOMPDeviceClause(
11877 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11878 C->getModifierLoc(), C->getEndLoc());
11879}
11880
11881template <typename Derived, class T>
11882bool transformOMPMappableExprListClause(
11883 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11884 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11885 DeclarationNameInfo &MapperIdInfo,
11886 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11887 // Transform expressions in the list.
11888 Vars.reserve(N: C->varlist_size());
11889 for (auto *VE : C->varlist()) {
11890 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11891 if (EVar.isInvalid())
11892 return true;
11893 Vars.push_back(Elt: EVar.get());
11894 }
11895 // Transform mapper scope specifier and identifier.
11896 NestedNameSpecifierLoc QualifierLoc;
11897 if (C->getMapperQualifierLoc()) {
11898 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11899 C->getMapperQualifierLoc());
11900 if (!QualifierLoc)
11901 return true;
11902 }
11903 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11904 MapperIdInfo = C->getMapperIdInfo();
11905 if (MapperIdInfo.getName()) {
11906 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11907 if (!MapperIdInfo.getName())
11908 return true;
11909 }
11910 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11911 // the previous user-defined mapper lookup in dependent environment.
11912 for (auto *E : C->mapperlists()) {
11913 // Transform all the decls.
11914 if (E) {
11915 auto *ULE = cast<UnresolvedLookupExpr>(E);
11916 UnresolvedSet<8> Decls;
11917 for (auto *D : ULE->decls()) {
11918 NamedDecl *InstD =
11919 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11920 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11921 }
11922 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11923 TT.getSema().Context, /*NamingClass=*/nullptr,
11924 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11925 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11926 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11927 } else {
11928 UnresolvedMappers.push_back(Elt: nullptr);
11929 }
11930 }
11931 return false;
11932}
11933
11934template <typename Derived>
11935OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11936 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11937 llvm::SmallVector<Expr *, 16> Vars;
11938 Expr *IteratorModifier = C->getIteratorModifier();
11939 if (IteratorModifier) {
11940 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11941 if (MapModRes.isInvalid())
11942 return nullptr;
11943 IteratorModifier = MapModRes.get();
11944 }
11945 CXXScopeSpec MapperIdScopeSpec;
11946 DeclarationNameInfo MapperIdInfo;
11947 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11948 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11949 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11950 return nullptr;
11951 return getDerived().RebuildOMPMapClause(
11952 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11953 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11954 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11955}
11956
11957template <typename Derived>
11958OMPClause *
11959TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11960 Expr *Allocator = C->getAllocator();
11961 if (Allocator) {
11962 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11963 if (AllocatorRes.isInvalid())
11964 return nullptr;
11965 Allocator = AllocatorRes.get();
11966 }
11967 Expr *Alignment = C->getAlignment();
11968 if (Alignment) {
11969 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11970 if (AlignmentRes.isInvalid())
11971 return nullptr;
11972 Alignment = AlignmentRes.get();
11973 }
11974 llvm::SmallVector<Expr *, 16> Vars;
11975 Vars.reserve(N: C->varlist_size());
11976 for (auto *VE : C->varlist()) {
11977 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11978 if (EVar.isInvalid())
11979 return nullptr;
11980 Vars.push_back(Elt: EVar.get());
11981 }
11982 return getDerived().RebuildOMPAllocateClause(
11983 Allocator, Alignment, C->getFirstAllocateModifier(),
11984 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11985 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11986 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11987}
11988
11989template <typename Derived>
11990OMPClause *
11991TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11992 llvm::SmallVector<Expr *, 3> Vars;
11993 Vars.reserve(N: C->varlist_size());
11994 for (auto *VE : C->varlist()) {
11995 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11996 if (EVar.isInvalid())
11997 return nullptr;
11998 Vars.push_back(Elt: EVar.get());
11999 }
12000 Expr *ModifierExpr = C->getModifierExpr();
12001 if (ModifierExpr) {
12002 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12003 if (EVar.isInvalid())
12004 return nullptr;
12005 ModifierExpr = EVar.get();
12006 }
12007 return getDerived().RebuildOMPNumTeamsClause(
12008 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12009 OMPC_NUMTEAMS_unknown, nullptr, SourceLocation(), C->getBeginLoc(),
12010 C->getLParenLoc(), C->getEndLoc());
12011}
12012
12013template <typename Derived>
12014OMPClause *
12015TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
12016 llvm::SmallVector<Expr *, 3> Vars;
12017 Vars.reserve(N: C->varlist_size());
12018 for (auto *VE : C->varlist()) {
12019 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12020 if (EVar.isInvalid())
12021 return nullptr;
12022 Vars.push_back(Elt: EVar.get());
12023 }
12024 Expr *ModifierExpr = C->getModifierExpr();
12025 if (ModifierExpr) {
12026 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12027 if (EVar.isInvalid())
12028 return nullptr;
12029 ModifierExpr = EVar.get();
12030 }
12031 return getDerived().RebuildOMPThreadLimitClause(
12032 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12033 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12034}
12035
12036template <typename Derived>
12037OMPClause *
12038TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
12039 ExprResult E = getDerived().TransformExpr(C->getPriority());
12040 if (E.isInvalid())
12041 return nullptr;
12042 return getDerived().RebuildOMPPriorityClause(
12043 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12044}
12045
12046template <typename Derived>
12047OMPClause *
12048TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
12049 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
12050 if (E.isInvalid())
12051 return nullptr;
12052 return getDerived().RebuildOMPGrainsizeClause(
12053 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12054 C->getModifierLoc(), C->getEndLoc());
12055}
12056
12057template <typename Derived>
12058OMPClause *
12059TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
12060 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
12061 if (E.isInvalid())
12062 return nullptr;
12063 return getDerived().RebuildOMPNumTasksClause(
12064 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12065 C->getModifierLoc(), C->getEndLoc());
12066}
12067
12068template <typename Derived>
12069OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
12070 ExprResult E = getDerived().TransformExpr(C->getHint());
12071 if (E.isInvalid())
12072 return nullptr;
12073 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
12074 C->getLParenLoc(), C->getEndLoc());
12075}
12076
12077template <typename Derived>
12078OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
12079 OMPDistScheduleClause *C) {
12080 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
12081 if (E.isInvalid())
12082 return nullptr;
12083 return getDerived().RebuildOMPDistScheduleClause(
12084 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12085 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
12086}
12087
12088template <typename Derived>
12089OMPClause *
12090TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
12091 // Rebuild Defaultmap Clause since we need to invoke the checking of
12092 // defaultmap(none:variable-category) after template initialization.
12093 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
12094 C->getDefaultmapKind(),
12095 C->getBeginLoc(),
12096 C->getLParenLoc(),
12097 C->getDefaultmapModifierLoc(),
12098 C->getDefaultmapKindLoc(),
12099 C->getEndLoc());
12100}
12101
12102template <typename Derived>
12103OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
12104 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12105 llvm::SmallVector<Expr *, 16> Vars;
12106 Expr *IteratorModifier = C->getIteratorModifier();
12107 if (IteratorModifier) {
12108 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12109 if (MapModRes.isInvalid())
12110 return nullptr;
12111 IteratorModifier = MapModRes.get();
12112 }
12113 CXXScopeSpec MapperIdScopeSpec;
12114 DeclarationNameInfo MapperIdInfo;
12115 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12116 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
12117 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12118 return nullptr;
12119 return getDerived().RebuildOMPToClause(
12120 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12121 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12122 UnresolvedMappers);
12123}
12124
12125template <typename Derived>
12126OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
12127 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12128 llvm::SmallVector<Expr *, 16> Vars;
12129 Expr *IteratorModifier = C->getIteratorModifier();
12130 if (IteratorModifier) {
12131 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12132 if (MapModRes.isInvalid())
12133 return nullptr;
12134 IteratorModifier = MapModRes.get();
12135 }
12136 CXXScopeSpec MapperIdScopeSpec;
12137 DeclarationNameInfo MapperIdInfo;
12138 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12139 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
12140 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12141 return nullptr;
12142 return getDerived().RebuildOMPFromClause(
12143 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12144 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12145 UnresolvedMappers);
12146}
12147
12148template <typename Derived>
12149OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
12150 OMPUseDevicePtrClause *C) {
12151 llvm::SmallVector<Expr *, 16> Vars;
12152 Vars.reserve(N: C->varlist_size());
12153 for (auto *VE : C->varlist()) {
12154 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12155 if (EVar.isInvalid())
12156 return nullptr;
12157 Vars.push_back(Elt: EVar.get());
12158 }
12159 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12160 return getDerived().RebuildOMPUseDevicePtrClause(
12161 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
12162}
12163
12164template <typename Derived>
12165OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
12166 OMPUseDeviceAddrClause *C) {
12167 llvm::SmallVector<Expr *, 16> Vars;
12168 Vars.reserve(N: C->varlist_size());
12169 for (auto *VE : C->varlist()) {
12170 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12171 if (EVar.isInvalid())
12172 return nullptr;
12173 Vars.push_back(Elt: EVar.get());
12174 }
12175 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12176 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
12177}
12178
12179template <typename Derived>
12180OMPClause *
12181TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
12182 llvm::SmallVector<Expr *, 16> Vars;
12183 Vars.reserve(N: C->varlist_size());
12184 for (auto *VE : C->varlist()) {
12185 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12186 if (EVar.isInvalid())
12187 return nullptr;
12188 Vars.push_back(Elt: EVar.get());
12189 }
12190 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12191 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
12192}
12193
12194template <typename Derived>
12195OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
12196 OMPHasDeviceAddrClause *C) {
12197 llvm::SmallVector<Expr *, 16> Vars;
12198 Vars.reserve(N: C->varlist_size());
12199 for (auto *VE : C->varlist()) {
12200 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12201 if (EVar.isInvalid())
12202 return nullptr;
12203 Vars.push_back(Elt: EVar.get());
12204 }
12205 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12206 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
12207}
12208
12209template <typename Derived>
12210OMPClause *
12211TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
12212 llvm::SmallVector<Expr *, 16> Vars;
12213 Vars.reserve(N: C->varlist_size());
12214 for (auto *VE : C->varlist()) {
12215 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12216 if (EVar.isInvalid())
12217 return nullptr;
12218 Vars.push_back(Elt: EVar.get());
12219 }
12220 return getDerived().RebuildOMPNontemporalClause(
12221 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12222}
12223
12224template <typename Derived>
12225OMPClause *
12226TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
12227 llvm::SmallVector<Expr *, 16> Vars;
12228 Vars.reserve(N: C->varlist_size());
12229 for (auto *VE : C->varlist()) {
12230 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12231 if (EVar.isInvalid())
12232 return nullptr;
12233 Vars.push_back(Elt: EVar.get());
12234 }
12235 return getDerived().RebuildOMPInclusiveClause(
12236 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12237}
12238
12239template <typename Derived>
12240OMPClause *
12241TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
12242 llvm::SmallVector<Expr *, 16> Vars;
12243 Vars.reserve(N: C->varlist_size());
12244 for (auto *VE : C->varlist()) {
12245 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12246 if (EVar.isInvalid())
12247 return nullptr;
12248 Vars.push_back(Elt: EVar.get());
12249 }
12250 return getDerived().RebuildOMPExclusiveClause(
12251 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12252}
12253
12254template <typename Derived>
12255OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
12256 OMPUsesAllocatorsClause *C) {
12257 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
12258 Data.reserve(N: C->getNumberOfAllocators());
12259 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
12260 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
12261 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
12262 if (Allocator.isInvalid())
12263 continue;
12264 ExprResult AllocatorTraits;
12265 if (Expr *AT = D.AllocatorTraits) {
12266 AllocatorTraits = getDerived().TransformExpr(AT);
12267 if (AllocatorTraits.isInvalid())
12268 continue;
12269 }
12270 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
12271 NewD.Allocator = Allocator.get();
12272 NewD.AllocatorTraits = AllocatorTraits.get();
12273 NewD.LParenLoc = D.LParenLoc;
12274 NewD.RParenLoc = D.RParenLoc;
12275 }
12276 return getDerived().RebuildOMPUsesAllocatorsClause(
12277 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12278}
12279
12280template <typename Derived>
12281OMPClause *
12282TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
12283 SmallVector<Expr *, 4> Locators;
12284 Locators.reserve(N: C->varlist_size());
12285 ExprResult ModifierRes;
12286 if (Expr *Modifier = C->getModifier()) {
12287 ModifierRes = getDerived().TransformExpr(Modifier);
12288 if (ModifierRes.isInvalid())
12289 return nullptr;
12290 }
12291 for (Expr *E : C->varlist()) {
12292 ExprResult Locator = getDerived().TransformExpr(E);
12293 if (Locator.isInvalid())
12294 continue;
12295 Locators.push_back(Elt: Locator.get());
12296 }
12297 return getDerived().RebuildOMPAffinityClause(
12298 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
12299 ModifierRes.get(), Locators);
12300}
12301
12302template <typename Derived>
12303OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
12304 return getDerived().RebuildOMPOrderClause(
12305 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
12306 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
12307}
12308
12309template <typename Derived>
12310OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
12311 return getDerived().RebuildOMPBindClause(
12312 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
12313 C->getLParenLoc(), C->getEndLoc());
12314}
12315
12316template <typename Derived>
12317OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
12318 OMPXDynCGroupMemClause *C) {
12319 ExprResult Size = getDerived().TransformExpr(C->getSize());
12320 if (Size.isInvalid())
12321 return nullptr;
12322 return getDerived().RebuildOMPXDynCGroupMemClause(
12323 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12324}
12325
12326template <typename Derived>
12327OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
12328 OMPDynGroupprivateClause *C) {
12329 ExprResult Size = getDerived().TransformExpr(C->getSize());
12330 if (Size.isInvalid())
12331 return nullptr;
12332 return getDerived().RebuildOMPDynGroupprivateClause(
12333 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
12334 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
12335 C->getDynGroupprivateModifierLoc(),
12336 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
12337}
12338
12339template <typename Derived>
12340OMPClause *
12341TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
12342 llvm::SmallVector<Expr *, 16> Vars;
12343 Vars.reserve(N: C->varlist_size());
12344 for (auto *VE : C->varlist()) {
12345 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12346 if (EVar.isInvalid())
12347 return nullptr;
12348 Vars.push_back(Elt: EVar.get());
12349 }
12350 return getDerived().RebuildOMPDoacrossClause(
12351 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
12352 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12353}
12354
12355template <typename Derived>
12356OMPClause *
12357TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
12358 SmallVector<const Attr *> NewAttrs;
12359 for (auto *A : C->getAttrs())
12360 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
12361 return getDerived().RebuildOMPXAttributeClause(
12362 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12363}
12364
12365template <typename Derived>
12366OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
12367 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
12368}
12369
12370//===----------------------------------------------------------------------===//
12371// OpenACC transformation
12372//===----------------------------------------------------------------------===//
12373namespace {
12374template <typename Derived>
12375class OpenACCClauseTransform final
12376 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
12377 TreeTransform<Derived> &Self;
12378 ArrayRef<const OpenACCClause *> ExistingClauses;
12379 SemaOpenACC::OpenACCParsedClause &ParsedClause;
12380 OpenACCClause *NewClause = nullptr;
12381
12382 ExprResult VisitVar(Expr *VarRef) {
12383 ExprResult Res = Self.TransformExpr(VarRef);
12384
12385 if (!Res.isUsable())
12386 return Res;
12387
12388 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12389 ParsedClause.getClauseKind(),
12390 Res.get());
12391
12392 return Res;
12393 }
12394
12395 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
12396 llvm::SmallVector<Expr *> InstantiatedVarList;
12397 for (Expr *CurVar : VarList) {
12398 ExprResult VarRef = VisitVar(VarRef: CurVar);
12399
12400 if (VarRef.isUsable())
12401 InstantiatedVarList.push_back(Elt: VarRef.get());
12402 }
12403
12404 return InstantiatedVarList;
12405 }
12406
12407public:
12408 OpenACCClauseTransform(TreeTransform<Derived> &Self,
12409 ArrayRef<const OpenACCClause *> ExistingClauses,
12410 SemaOpenACC::OpenACCParsedClause &PC)
12411 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
12412
12413 OpenACCClause *CreatedClause() const { return NewClause; }
12414
12415#define VISIT_CLAUSE(CLAUSE_NAME) \
12416 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
12417#include "clang/Basic/OpenACCClauses.def"
12418};
12419
12420template <typename Derived>
12421void OpenACCClauseTransform<Derived>::VisitDefaultClause(
12422 const OpenACCDefaultClause &C) {
12423 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
12424
12425 NewClause = OpenACCDefaultClause::Create(
12426 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
12427 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12428 EndLoc: ParsedClause.getEndLoc());
12429}
12430
12431template <typename Derived>
12432void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
12433 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12434 assert(Cond && "If constructed with invalid Condition");
12435 Sema::ConditionResult Res = Self.TransformCondition(
12436 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
12437
12438 if (Res.isInvalid() || !Res.get().second)
12439 return;
12440
12441 ParsedClause.setConditionDetails(Res.get().second);
12442
12443 NewClause = OpenACCIfClause::Create(
12444 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12445 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
12446 EndLoc: ParsedClause.getEndLoc());
12447}
12448
12449template <typename Derived>
12450void OpenACCClauseTransform<Derived>::VisitSelfClause(
12451 const OpenACCSelfClause &C) {
12452
12453 // If this is an 'update' 'self' clause, this is actually a var list instead.
12454 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
12455 llvm::SmallVector<Expr *> InstantiatedVarList;
12456 for (Expr *CurVar : C.getVarList()) {
12457 ExprResult Res = Self.TransformExpr(CurVar);
12458
12459 if (!Res.isUsable())
12460 continue;
12461
12462 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12463 ParsedClause.getClauseKind(),
12464 Res.get());
12465
12466 if (Res.isUsable())
12467 InstantiatedVarList.push_back(Elt: Res.get());
12468 }
12469
12470 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12471 ModKind: OpenACCModifierKind::Invalid);
12472
12473 NewClause = OpenACCSelfClause::Create(
12474 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12475 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12476 ParsedClause.getEndLoc());
12477 } else {
12478
12479 if (C.hasConditionExpr()) {
12480 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12481 Sema::ConditionResult Res =
12482 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12483 Sema::ConditionKind::Boolean);
12484
12485 if (Res.isInvalid() || !Res.get().second)
12486 return;
12487
12488 ParsedClause.setConditionDetails(Res.get().second);
12489 }
12490
12491 NewClause = OpenACCSelfClause::Create(
12492 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12493 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12494 ParsedClause.getEndLoc());
12495 }
12496}
12497
12498template <typename Derived>
12499void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12500 const OpenACCNumGangsClause &C) {
12501 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12502
12503 for (Expr *CurIntExpr : C.getIntExprs()) {
12504 ExprResult Res = Self.TransformExpr(CurIntExpr);
12505
12506 if (!Res.isUsable())
12507 return;
12508
12509 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12510 C.getClauseKind(),
12511 C.getBeginLoc(), Res.get());
12512 if (!Res.isUsable())
12513 return;
12514
12515 InstantiatedIntExprs.push_back(Elt: Res.get());
12516 }
12517
12518 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12519 NewClause = OpenACCNumGangsClause::Create(
12520 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12521 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12522 EndLoc: ParsedClause.getEndLoc());
12523}
12524
12525template <typename Derived>
12526void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12527 const OpenACCPrivateClause &C) {
12528 llvm::SmallVector<Expr *> InstantiatedVarList;
12529 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12530
12531 for (const auto [RefExpr, InitRecipe] :
12532 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12533 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12534
12535 if (VarRef.isUsable()) {
12536 InstantiatedVarList.push_back(Elt: VarRef.get());
12537
12538 // We only have to create a new one if it is dependent, and Sema won't
12539 // make one of these unless the type is non-dependent.
12540 if (InitRecipe.isSet())
12541 InitRecipes.push_back(Elt: InitRecipe);
12542 else
12543 InitRecipes.push_back(
12544 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12545 }
12546 }
12547 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12548 ModKind: OpenACCModifierKind::Invalid);
12549
12550 NewClause = OpenACCPrivateClause::Create(
12551 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12552 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12553 EndLoc: ParsedClause.getEndLoc());
12554}
12555
12556template <typename Derived>
12557void OpenACCClauseTransform<Derived>::VisitHostClause(
12558 const OpenACCHostClause &C) {
12559 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12560 OpenACCModifierKind::Invalid);
12561
12562 NewClause = OpenACCHostClause::Create(
12563 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12564 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12565 EndLoc: ParsedClause.getEndLoc());
12566}
12567
12568template <typename Derived>
12569void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12570 const OpenACCDeviceClause &C) {
12571 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12572 OpenACCModifierKind::Invalid);
12573
12574 NewClause = OpenACCDeviceClause::Create(
12575 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12576 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12577 EndLoc: ParsedClause.getEndLoc());
12578}
12579
12580template <typename Derived>
12581void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12582 const OpenACCFirstPrivateClause &C) {
12583 llvm::SmallVector<Expr *> InstantiatedVarList;
12584 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12585
12586 for (const auto [RefExpr, InitRecipe] :
12587 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12588 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12589
12590 if (VarRef.isUsable()) {
12591 InstantiatedVarList.push_back(Elt: VarRef.get());
12592
12593 // We only have to create a new one if it is dependent, and Sema won't
12594 // make one of these unless the type is non-dependent.
12595 if (InitRecipe.isSet())
12596 InitRecipes.push_back(Elt: InitRecipe);
12597 else
12598 InitRecipes.push_back(
12599 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12600 VarRef.get()));
12601 }
12602 }
12603 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12604 ModKind: OpenACCModifierKind::Invalid);
12605
12606 NewClause = OpenACCFirstPrivateClause::Create(
12607 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12608 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12609 EndLoc: ParsedClause.getEndLoc());
12610}
12611
12612template <typename Derived>
12613void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12614 const OpenACCNoCreateClause &C) {
12615 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12616 OpenACCModifierKind::Invalid);
12617
12618 NewClause = OpenACCNoCreateClause::Create(
12619 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12620 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12621 EndLoc: ParsedClause.getEndLoc());
12622}
12623
12624template <typename Derived>
12625void OpenACCClauseTransform<Derived>::VisitPresentClause(
12626 const OpenACCPresentClause &C) {
12627 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12628 OpenACCModifierKind::Invalid);
12629
12630 NewClause = OpenACCPresentClause::Create(
12631 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12632 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12633 EndLoc: ParsedClause.getEndLoc());
12634}
12635
12636template <typename Derived>
12637void OpenACCClauseTransform<Derived>::VisitCopyClause(
12638 const OpenACCCopyClause &C) {
12639 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12640 C.getModifierList());
12641
12642 NewClause = OpenACCCopyClause::Create(
12643 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12644 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12645 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12646 EndLoc: ParsedClause.getEndLoc());
12647}
12648
12649template <typename Derived>
12650void OpenACCClauseTransform<Derived>::VisitLinkClause(
12651 const OpenACCLinkClause &C) {
12652 llvm_unreachable("link clause not valid unless a decl transform");
12653}
12654
12655template <typename Derived>
12656void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12657 const OpenACCDeviceResidentClause &C) {
12658 llvm_unreachable("device_resident clause not valid unless a decl transform");
12659}
12660template <typename Derived>
12661void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12662 const OpenACCNoHostClause &C) {
12663 llvm_unreachable("nohost clause not valid unless a decl transform");
12664}
12665template <typename Derived>
12666void OpenACCClauseTransform<Derived>::VisitBindClause(
12667 const OpenACCBindClause &C) {
12668 llvm_unreachable("bind clause not valid unless a decl transform");
12669}
12670
12671template <typename Derived>
12672void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12673 const OpenACCCopyInClause &C) {
12674 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12675 C.getModifierList());
12676
12677 NewClause = OpenACCCopyInClause::Create(
12678 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12679 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12680 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12681 EndLoc: ParsedClause.getEndLoc());
12682}
12683
12684template <typename Derived>
12685void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12686 const OpenACCCopyOutClause &C) {
12687 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12688 C.getModifierList());
12689
12690 NewClause = OpenACCCopyOutClause::Create(
12691 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12692 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12693 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12694 EndLoc: ParsedClause.getEndLoc());
12695}
12696
12697template <typename Derived>
12698void OpenACCClauseTransform<Derived>::VisitCreateClause(
12699 const OpenACCCreateClause &C) {
12700 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12701 C.getModifierList());
12702
12703 NewClause = OpenACCCreateClause::Create(
12704 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12705 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12706 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12707 EndLoc: ParsedClause.getEndLoc());
12708}
12709template <typename Derived>
12710void OpenACCClauseTransform<Derived>::VisitAttachClause(
12711 const OpenACCAttachClause &C) {
12712 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12713
12714 // Ensure each var is a pointer type.
12715 llvm::erase_if(VarList, [&](Expr *E) {
12716 return Self.getSema().OpenACC().CheckVarIsPointerType(
12717 OpenACCClauseKind::Attach, E);
12718 });
12719
12720 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12721 NewClause = OpenACCAttachClause::Create(
12722 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12723 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12724 EndLoc: ParsedClause.getEndLoc());
12725}
12726
12727template <typename Derived>
12728void OpenACCClauseTransform<Derived>::VisitDetachClause(
12729 const OpenACCDetachClause &C) {
12730 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12731
12732 // Ensure each var is a pointer type.
12733 llvm::erase_if(VarList, [&](Expr *E) {
12734 return Self.getSema().OpenACC().CheckVarIsPointerType(
12735 OpenACCClauseKind::Detach, E);
12736 });
12737
12738 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12739 NewClause = OpenACCDetachClause::Create(
12740 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12741 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12742 EndLoc: ParsedClause.getEndLoc());
12743}
12744
12745template <typename Derived>
12746void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12747 const OpenACCDeleteClause &C) {
12748 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12749 OpenACCModifierKind::Invalid);
12750 NewClause = OpenACCDeleteClause::Create(
12751 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12752 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12753 EndLoc: ParsedClause.getEndLoc());
12754}
12755
12756template <typename Derived>
12757void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12758 const OpenACCUseDeviceClause &C) {
12759 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12760 OpenACCModifierKind::Invalid);
12761 NewClause = OpenACCUseDeviceClause::Create(
12762 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12763 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12764 EndLoc: ParsedClause.getEndLoc());
12765}
12766
12767template <typename Derived>
12768void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12769 const OpenACCDevicePtrClause &C) {
12770 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12771
12772 // Ensure each var is a pointer type.
12773 llvm::erase_if(VarList, [&](Expr *E) {
12774 return Self.getSema().OpenACC().CheckVarIsPointerType(
12775 OpenACCClauseKind::DevicePtr, E);
12776 });
12777
12778 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12779 NewClause = OpenACCDevicePtrClause::Create(
12780 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12781 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12782 EndLoc: ParsedClause.getEndLoc());
12783}
12784
12785template <typename Derived>
12786void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12787 const OpenACCNumWorkersClause &C) {
12788 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12789 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12790
12791 ExprResult Res = Self.TransformExpr(IntExpr);
12792 if (!Res.isUsable())
12793 return;
12794
12795 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12796 C.getClauseKind(),
12797 C.getBeginLoc(), Res.get());
12798 if (!Res.isUsable())
12799 return;
12800
12801 ParsedClause.setIntExprDetails(Res.get());
12802 NewClause = OpenACCNumWorkersClause::Create(
12803 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12804 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12805 EndLoc: ParsedClause.getEndLoc());
12806}
12807
12808template <typename Derived>
12809void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12810 const OpenACCDeviceNumClause &C) {
12811 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12812 assert(IntExpr && "device_num clause constructed with invalid int expr");
12813
12814 ExprResult Res = Self.TransformExpr(IntExpr);
12815 if (!Res.isUsable())
12816 return;
12817
12818 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12819 C.getClauseKind(),
12820 C.getBeginLoc(), Res.get());
12821 if (!Res.isUsable())
12822 return;
12823
12824 ParsedClause.setIntExprDetails(Res.get());
12825 NewClause = OpenACCDeviceNumClause::Create(
12826 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12827 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12828 EndLoc: ParsedClause.getEndLoc());
12829}
12830
12831template <typename Derived>
12832void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12833 const OpenACCDefaultAsyncClause &C) {
12834 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12835 assert(IntExpr && "default_async clause constructed with invalid int expr");
12836
12837 ExprResult Res = Self.TransformExpr(IntExpr);
12838 if (!Res.isUsable())
12839 return;
12840
12841 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12842 C.getClauseKind(),
12843 C.getBeginLoc(), Res.get());
12844 if (!Res.isUsable())
12845 return;
12846
12847 ParsedClause.setIntExprDetails(Res.get());
12848 NewClause = OpenACCDefaultAsyncClause::Create(
12849 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12850 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12851 EndLoc: ParsedClause.getEndLoc());
12852}
12853
12854template <typename Derived>
12855void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12856 const OpenACCVectorLengthClause &C) {
12857 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12858 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12859
12860 ExprResult Res = Self.TransformExpr(IntExpr);
12861 if (!Res.isUsable())
12862 return;
12863
12864 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12865 C.getClauseKind(),
12866 C.getBeginLoc(), Res.get());
12867 if (!Res.isUsable())
12868 return;
12869
12870 ParsedClause.setIntExprDetails(Res.get());
12871 NewClause = OpenACCVectorLengthClause::Create(
12872 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12873 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12874 EndLoc: ParsedClause.getEndLoc());
12875}
12876
12877template <typename Derived>
12878void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12879 const OpenACCAsyncClause &C) {
12880 if (C.hasIntExpr()) {
12881 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12882 if (!Res.isUsable())
12883 return;
12884
12885 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12886 C.getClauseKind(),
12887 C.getBeginLoc(), Res.get());
12888 if (!Res.isUsable())
12889 return;
12890 ParsedClause.setIntExprDetails(Res.get());
12891 }
12892
12893 NewClause = OpenACCAsyncClause::Create(
12894 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12895 LParenLoc: ParsedClause.getLParenLoc(),
12896 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12897 : nullptr,
12898 EndLoc: ParsedClause.getEndLoc());
12899}
12900
12901template <typename Derived>
12902void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12903 const OpenACCWorkerClause &C) {
12904 if (C.hasIntExpr()) {
12905 // restrictions on this expression are all "does it exist in certain
12906 // situations" that are not possible to be dependent, so the only check we
12907 // have is that it transforms, and is an int expression.
12908 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12909 if (!Res.isUsable())
12910 return;
12911
12912 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12913 C.getClauseKind(),
12914 C.getBeginLoc(), Res.get());
12915 if (!Res.isUsable())
12916 return;
12917 ParsedClause.setIntExprDetails(Res.get());
12918 }
12919
12920 NewClause = OpenACCWorkerClause::Create(
12921 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12922 LParenLoc: ParsedClause.getLParenLoc(),
12923 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12924 : nullptr,
12925 EndLoc: ParsedClause.getEndLoc());
12926}
12927
12928template <typename Derived>
12929void OpenACCClauseTransform<Derived>::VisitVectorClause(
12930 const OpenACCVectorClause &C) {
12931 if (C.hasIntExpr()) {
12932 // restrictions on this expression are all "does it exist in certain
12933 // situations" that are not possible to be dependent, so the only check we
12934 // have is that it transforms, and is an int expression.
12935 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12936 if (!Res.isUsable())
12937 return;
12938
12939 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12940 C.getClauseKind(),
12941 C.getBeginLoc(), Res.get());
12942 if (!Res.isUsable())
12943 return;
12944 ParsedClause.setIntExprDetails(Res.get());
12945 }
12946
12947 NewClause = OpenACCVectorClause::Create(
12948 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12949 LParenLoc: ParsedClause.getLParenLoc(),
12950 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12951 : nullptr,
12952 EndLoc: ParsedClause.getEndLoc());
12953}
12954
12955template <typename Derived>
12956void OpenACCClauseTransform<Derived>::VisitWaitClause(
12957 const OpenACCWaitClause &C) {
12958 if (C.hasExprs()) {
12959 Expr *DevNumExpr = nullptr;
12960 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12961
12962 // Instantiate devnum expr if it exists.
12963 if (C.getDevNumExpr()) {
12964 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12965 if (!Res.isUsable())
12966 return;
12967 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12968 C.getClauseKind(),
12969 C.getBeginLoc(), Res.get());
12970 if (!Res.isUsable())
12971 return;
12972
12973 DevNumExpr = Res.get();
12974 }
12975
12976 // Instantiate queue ids.
12977 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12978 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12979 if (!Res.isUsable())
12980 return;
12981 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12982 C.getClauseKind(),
12983 C.getBeginLoc(), Res.get());
12984 if (!Res.isUsable())
12985 return;
12986
12987 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12988 }
12989
12990 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12991 IntExprs: std::move(InstantiatedQueueIdExprs));
12992 }
12993
12994 NewClause = OpenACCWaitClause::Create(
12995 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12996 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12997 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12998 EndLoc: ParsedClause.getEndLoc());
12999}
13000
13001template <typename Derived>
13002void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
13003 const OpenACCDeviceTypeClause &C) {
13004 // Nothing to transform here, just create a new version of 'C'.
13005 NewClause = OpenACCDeviceTypeClause::Create(
13006 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
13007 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
13008 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
13009}
13010
13011template <typename Derived>
13012void OpenACCClauseTransform<Derived>::VisitAutoClause(
13013 const OpenACCAutoClause &C) {
13014 // Nothing to do, so just create a new node.
13015 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
13016 BeginLoc: ParsedClause.getBeginLoc(),
13017 EndLoc: ParsedClause.getEndLoc());
13018}
13019
13020template <typename Derived>
13021void OpenACCClauseTransform<Derived>::VisitIndependentClause(
13022 const OpenACCIndependentClause &C) {
13023 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
13024 BeginLoc: ParsedClause.getBeginLoc(),
13025 EndLoc: ParsedClause.getEndLoc());
13026}
13027
13028template <typename Derived>
13029void OpenACCClauseTransform<Derived>::VisitSeqClause(
13030 const OpenACCSeqClause &C) {
13031 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
13032 BeginLoc: ParsedClause.getBeginLoc(),
13033 EndLoc: ParsedClause.getEndLoc());
13034}
13035template <typename Derived>
13036void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
13037 const OpenACCFinalizeClause &C) {
13038 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
13039 BeginLoc: ParsedClause.getBeginLoc(),
13040 EndLoc: ParsedClause.getEndLoc());
13041}
13042
13043template <typename Derived>
13044void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
13045 const OpenACCIfPresentClause &C) {
13046 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
13047 BeginLoc: ParsedClause.getBeginLoc(),
13048 EndLoc: ParsedClause.getEndLoc());
13049}
13050
13051template <typename Derived>
13052void OpenACCClauseTransform<Derived>::VisitReductionClause(
13053 const OpenACCReductionClause &C) {
13054 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
13055 SmallVector<Expr *> ValidVars;
13056 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
13057
13058 for (const auto [Var, OrigRecipe] :
13059 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
13060 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
13061 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
13062 if (Res.isUsable()) {
13063 ValidVars.push_back(Elt: Res.get());
13064
13065 if (OrigRecipe.isSet())
13066 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
13067 else
13068 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
13069 C.getReductionOp(), Res.get()));
13070 }
13071 }
13072
13073 NewClause = Self.getSema().OpenACC().CheckReductionClause(
13074 ExistingClauses, ParsedClause.getDirectiveKind(),
13075 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13076 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
13077}
13078
13079template <typename Derived>
13080void OpenACCClauseTransform<Derived>::VisitCollapseClause(
13081 const OpenACCCollapseClause &C) {
13082 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
13083 assert(LoopCount && "collapse clause constructed with invalid loop count");
13084
13085 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
13086
13087 if (!NewLoopCount.isUsable())
13088 return;
13089
13090 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
13091 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13092 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
13093
13094 // FIXME: It isn't clear whether this is properly tested here, we should
13095 // probably see if we can come up with a test for this.
13096 if (!NewLoopCount.isUsable())
13097 return;
13098
13099 NewLoopCount =
13100 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
13101
13102 // FIXME: It isn't clear whether this is properly tested here, we should
13103 // probably see if we can come up with a test for this.
13104 if (!NewLoopCount.isUsable())
13105 return;
13106
13107 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
13108 NewClause = OpenACCCollapseClause::Create(
13109 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13110 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
13111 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
13112}
13113
13114template <typename Derived>
13115void OpenACCClauseTransform<Derived>::VisitTileClause(
13116 const OpenACCTileClause &C) {
13117
13118 llvm::SmallVector<Expr *> TransformedExprs;
13119
13120 for (Expr *E : C.getSizeExprs()) {
13121 ExprResult NewSizeExpr = Self.TransformExpr(E);
13122
13123 if (!NewSizeExpr.isUsable())
13124 return;
13125
13126 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
13127 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13128 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
13129
13130 // FIXME: It isn't clear whether this is properly tested here, we should
13131 // probably see if we can come up with a test for this.
13132 if (!NewSizeExpr.isUsable())
13133 return;
13134
13135 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
13136
13137 if (!NewSizeExpr.isUsable())
13138 return;
13139 TransformedExprs.push_back(Elt: NewSizeExpr.get());
13140 }
13141
13142 ParsedClause.setIntExprDetails(TransformedExprs);
13143 NewClause = OpenACCTileClause::Create(
13144 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13145 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
13146 EndLoc: ParsedClause.getEndLoc());
13147}
13148template <typename Derived>
13149void OpenACCClauseTransform<Derived>::VisitGangClause(
13150 const OpenACCGangClause &C) {
13151 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
13152 llvm::SmallVector<Expr *> TransformedIntExprs;
13153
13154 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
13155 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
13156 if (!ER.isUsable())
13157 continue;
13158
13159 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
13160 ParsedClause.getDirectiveKind(),
13161 C.getExpr(I).first, ER.get());
13162 if (!ER.isUsable())
13163 continue;
13164 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
13165 TransformedIntExprs.push_back(Elt: ER.get());
13166 }
13167
13168 NewClause = Self.getSema().OpenACC().CheckGangClause(
13169 ParsedClause.getDirectiveKind(), ExistingClauses,
13170 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13171 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
13172}
13173} // namespace
13174template <typename Derived>
13175OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
13176 ArrayRef<const OpenACCClause *> ExistingClauses,
13177 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
13178
13179 SemaOpenACC::OpenACCParsedClause ParsedClause(
13180 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
13181 ParsedClause.setEndLoc(OldClause->getEndLoc());
13182
13183 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
13184 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
13185
13186 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
13187 ParsedClause};
13188 Transform.Visit(OldClause);
13189
13190 return Transform.CreatedClause();
13191}
13192
13193template <typename Derived>
13194llvm::SmallVector<OpenACCClause *>
13195TreeTransform<Derived>::TransformOpenACCClauseList(
13196 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
13197 llvm::SmallVector<OpenACCClause *> TransformedClauses;
13198 for (const auto *Clause : OldClauses) {
13199 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
13200 TransformedClauses, DirKind, Clause))
13201 TransformedClauses.push_back(Elt: TransformedClause);
13202 }
13203 return TransformedClauses;
13204}
13205
13206template <typename Derived>
13207StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
13208 OpenACCComputeConstruct *C) {
13209 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13210
13211 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13212 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13213 C->clauses());
13214
13215 if (getSema().OpenACC().ActOnStartStmtDirective(
13216 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13217 return StmtError();
13218
13219 // Transform Structured Block.
13220 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13221 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13222 C->clauses(), TransformedClauses);
13223 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13224 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13225 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13226
13227 return getDerived().RebuildOpenACCComputeConstruct(
13228 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13229 C->getEndLoc(), TransformedClauses, StrBlock);
13230}
13231
13232template <typename Derived>
13233StmtResult
13234TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
13235
13236 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13237
13238 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13239 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13240 C->clauses());
13241
13242 if (getSema().OpenACC().ActOnStartStmtDirective(
13243 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13244 return StmtError();
13245
13246 // Transform Loop.
13247 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13248 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13249 C->clauses(), TransformedClauses);
13250 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13251 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13252 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13253
13254 return getDerived().RebuildOpenACCLoopConstruct(
13255 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13256 TransformedClauses, Loop);
13257}
13258
13259template <typename Derived>
13260StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
13261 OpenACCCombinedConstruct *C) {
13262 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13263
13264 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13265 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13266 C->clauses());
13267
13268 if (getSema().OpenACC().ActOnStartStmtDirective(
13269 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13270 return StmtError();
13271
13272 // Transform Loop.
13273 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13274 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13275 C->clauses(), TransformedClauses);
13276 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13277 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13278 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13279
13280 return getDerived().RebuildOpenACCCombinedConstruct(
13281 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13282 C->getEndLoc(), TransformedClauses, Loop);
13283}
13284
13285template <typename Derived>
13286StmtResult
13287TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
13288 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13289
13290 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13291 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13292 C->clauses());
13293 if (getSema().OpenACC().ActOnStartStmtDirective(
13294 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13295 return StmtError();
13296
13297 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13298 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13299 C->clauses(), TransformedClauses);
13300 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13301 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13302 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13303
13304 return getDerived().RebuildOpenACCDataConstruct(
13305 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13306 TransformedClauses, StrBlock);
13307}
13308
13309template <typename Derived>
13310StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
13311 OpenACCEnterDataConstruct *C) {
13312 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13313
13314 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13315 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13316 C->clauses());
13317 if (getSema().OpenACC().ActOnStartStmtDirective(
13318 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13319 return StmtError();
13320
13321 return getDerived().RebuildOpenACCEnterDataConstruct(
13322 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13323 TransformedClauses);
13324}
13325
13326template <typename Derived>
13327StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
13328 OpenACCExitDataConstruct *C) {
13329 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13330
13331 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13332 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13333 C->clauses());
13334 if (getSema().OpenACC().ActOnStartStmtDirective(
13335 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13336 return StmtError();
13337
13338 return getDerived().RebuildOpenACCExitDataConstruct(
13339 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13340 TransformedClauses);
13341}
13342
13343template <typename Derived>
13344StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
13345 OpenACCHostDataConstruct *C) {
13346 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13347
13348 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13349 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13350 C->clauses());
13351 if (getSema().OpenACC().ActOnStartStmtDirective(
13352 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13353 return StmtError();
13354
13355 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13356 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13357 C->clauses(), TransformedClauses);
13358 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13359 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13360 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13361
13362 return getDerived().RebuildOpenACCHostDataConstruct(
13363 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13364 TransformedClauses, StrBlock);
13365}
13366
13367template <typename Derived>
13368StmtResult
13369TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
13370 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13371
13372 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13373 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13374 C->clauses());
13375 if (getSema().OpenACC().ActOnStartStmtDirective(
13376 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13377 return StmtError();
13378
13379 return getDerived().RebuildOpenACCInitConstruct(
13380 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13381 TransformedClauses);
13382}
13383
13384template <typename Derived>
13385StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
13386 OpenACCShutdownConstruct *C) {
13387 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13388
13389 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13390 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13391 C->clauses());
13392 if (getSema().OpenACC().ActOnStartStmtDirective(
13393 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13394 return StmtError();
13395
13396 return getDerived().RebuildOpenACCShutdownConstruct(
13397 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13398 TransformedClauses);
13399}
13400template <typename Derived>
13401StmtResult
13402TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
13403 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13404
13405 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13406 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13407 C->clauses());
13408 if (getSema().OpenACC().ActOnStartStmtDirective(
13409 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13410 return StmtError();
13411
13412 return getDerived().RebuildOpenACCSetConstruct(
13413 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13414 TransformedClauses);
13415}
13416
13417template <typename Derived>
13418StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
13419 OpenACCUpdateConstruct *C) {
13420 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13421
13422 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13423 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13424 C->clauses());
13425 if (getSema().OpenACC().ActOnStartStmtDirective(
13426 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13427 return StmtError();
13428
13429 return getDerived().RebuildOpenACCUpdateConstruct(
13430 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13431 TransformedClauses);
13432}
13433
13434template <typename Derived>
13435StmtResult
13436TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
13437 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13438
13439 ExprResult DevNumExpr;
13440 if (C->hasDevNumExpr()) {
13441 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
13442
13443 if (DevNumExpr.isUsable())
13444 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
13445 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
13446 C->getBeginLoc(), DevNumExpr.get());
13447 }
13448
13449 llvm::SmallVector<Expr *> QueueIdExprs;
13450
13451 for (Expr *QE : C->getQueueIdExprs()) {
13452 assert(QE && "Null queue id expr?");
13453 ExprResult NewEQ = getDerived().TransformExpr(QE);
13454
13455 if (!NewEQ.isUsable())
13456 break;
13457 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
13458 OpenACCClauseKind::Invalid,
13459 C->getBeginLoc(), NewEQ.get());
13460 if (NewEQ.isUsable())
13461 QueueIdExprs.push_back(Elt: NewEQ.get());
13462 }
13463
13464 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13465 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13466 C->clauses());
13467
13468 if (getSema().OpenACC().ActOnStartStmtDirective(
13469 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13470 return StmtError();
13471
13472 return getDerived().RebuildOpenACCWaitConstruct(
13473 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13474 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
13475 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
13476}
13477template <typename Derived>
13478StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
13479 OpenACCCacheConstruct *C) {
13480 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13481
13482 llvm::SmallVector<Expr *> TransformedVarList;
13483 for (Expr *Var : C->getVarList()) {
13484 assert(Var && "Null var listexpr?");
13485
13486 ExprResult NewVar = getDerived().TransformExpr(Var);
13487
13488 if (!NewVar.isUsable())
13489 break;
13490
13491 NewVar = getSema().OpenACC().ActOnVar(
13492 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13493 if (!NewVar.isUsable())
13494 break;
13495
13496 TransformedVarList.push_back(Elt: NewVar.get());
13497 }
13498
13499 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13500 C->getBeginLoc(), {}))
13501 return StmtError();
13502
13503 return getDerived().RebuildOpenACCCacheConstruct(
13504 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13505 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13506 C->getEndLoc());
13507}
13508
13509template <typename Derived>
13510StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13511 OpenACCAtomicConstruct *C) {
13512 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13513
13514 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13515 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13516 C->clauses());
13517
13518 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13519 C->getBeginLoc(), {}))
13520 return StmtError();
13521
13522 // Transform Associated Stmt.
13523 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13524 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13525
13526 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13527 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13528 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13529 AssocStmt);
13530
13531 return getDerived().RebuildOpenACCAtomicConstruct(
13532 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13533 C->getEndLoc(), TransformedClauses, AssocStmt);
13534}
13535
13536template <typename Derived>
13537ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13538 OpenACCAsteriskSizeExpr *E) {
13539 if (getDerived().AlwaysRebuild())
13540 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13541 // Nothing can ever change, so there is never anything to transform.
13542 return E;
13543}
13544
13545//===----------------------------------------------------------------------===//
13546// Expression transformation
13547//===----------------------------------------------------------------------===//
13548template<typename Derived>
13549ExprResult
13550TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13551 return TransformExpr(E: E->getSubExpr());
13552}
13553
13554template <typename Derived>
13555ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13556 SYCLUniqueStableNameExpr *E) {
13557 if (!E->isTypeDependent())
13558 return E;
13559
13560 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13561
13562 if (!NewT)
13563 return ExprError();
13564
13565 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13566 return E;
13567
13568 return getDerived().RebuildSYCLUniqueStableNameExpr(
13569 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13570}
13571
13572template <typename Derived>
13573StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13574 UnresolvedSYCLKernelCallStmt *S) {
13575 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13576 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13577 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13578 return StmtError();
13579
13580 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13581 if (IdExpr.isInvalid())
13582 return StmtError();
13583
13584 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13585 if (Body.isInvalid())
13586 return StmtError();
13587
13588 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13589 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13590 LaunchIdExpr: IdExpr.get());
13591 if (SR.isInvalid())
13592 return StmtError();
13593
13594 return SR;
13595}
13596
13597template <typename Derived>
13598ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13599 // TODO(reflection): Implement its transform
13600 assert(false && "not implemented yet");
13601 return ExprError();
13602}
13603
13604template<typename Derived>
13605ExprResult
13606TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13607 if (!E->isTypeDependent())
13608 return E;
13609
13610 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13611 E->getIdentKind());
13612}
13613
13614template<typename Derived>
13615ExprResult
13616TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13617 NestedNameSpecifierLoc QualifierLoc;
13618 if (E->getQualifierLoc()) {
13619 QualifierLoc
13620 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13621 if (!QualifierLoc)
13622 return ExprError();
13623 }
13624
13625 ValueDecl *ND
13626 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13627 E->getDecl()));
13628 if (!ND || ND->isInvalidDecl())
13629 return ExprError();
13630
13631 NamedDecl *Found = ND;
13632 if (E->getFoundDecl() != E->getDecl()) {
13633 Found = cast_or_null<NamedDecl>(
13634 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13635 if (!Found)
13636 return ExprError();
13637 }
13638
13639 DeclarationNameInfo NameInfo = E->getNameInfo();
13640 if (NameInfo.getName()) {
13641 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13642 if (!NameInfo.getName())
13643 return ExprError();
13644 }
13645
13646 if (!getDerived().AlwaysRebuild() &&
13647 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13648 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13649 Found == E->getFoundDecl() &&
13650 NameInfo.getName() == E->getDecl()->getDeclName() &&
13651 !E->hasExplicitTemplateArgs()) {
13652
13653 // Mark it referenced in the new context regardless.
13654 // FIXME: this is a bit instantiation-specific.
13655 SemaRef.MarkDeclRefReferenced(E);
13656
13657 return E;
13658 }
13659
13660 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13661 if (E->hasExplicitTemplateArgs()) {
13662 TemplateArgs = &TransArgs;
13663 TransArgs.setLAngleLoc(E->getLAngleLoc());
13664 TransArgs.setRAngleLoc(E->getRAngleLoc());
13665 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13666 E->getNumTemplateArgs(),
13667 TransArgs))
13668 return ExprError();
13669 }
13670
13671 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13672 Found, TemplateArgs);
13673}
13674
13675template<typename Derived>
13676ExprResult
13677TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13678 return E;
13679}
13680
13681template <typename Derived>
13682ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13683 FixedPointLiteral *E) {
13684 return E;
13685}
13686
13687template<typename Derived>
13688ExprResult
13689TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13690 return E;
13691}
13692
13693template<typename Derived>
13694ExprResult
13695TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13696 return E;
13697}
13698
13699template<typename Derived>
13700ExprResult
13701TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13702 return E;
13703}
13704
13705template<typename Derived>
13706ExprResult
13707TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13708 return E;
13709}
13710
13711template<typename Derived>
13712ExprResult
13713TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13714 return getDerived().TransformCallExpr(E);
13715}
13716
13717template<typename Derived>
13718ExprResult
13719TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13720 ExprResult ControllingExpr;
13721 TypeSourceInfo *ControllingType = nullptr;
13722 if (E->isExprPredicate())
13723 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13724 else
13725 ControllingType = getDerived().TransformType(E->getControllingType());
13726
13727 if (ControllingExpr.isInvalid() && !ControllingType)
13728 return ExprError();
13729
13730 SmallVector<Expr *, 4> AssocExprs;
13731 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13732 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13733 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13734 if (TSI) {
13735 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13736 if (!AssocType)
13737 return ExprError();
13738 AssocTypes.push_back(Elt: AssocType);
13739 } else {
13740 AssocTypes.push_back(Elt: nullptr);
13741 }
13742
13743 ExprResult AssocExpr =
13744 getDerived().TransformExpr(Assoc.getAssociationExpr());
13745 if (AssocExpr.isInvalid())
13746 return ExprError();
13747 AssocExprs.push_back(Elt: AssocExpr.get());
13748 }
13749
13750 if (!ControllingType)
13751 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13752 E->getDefaultLoc(),
13753 E->getRParenLoc(),
13754 ControllingExpr.get(),
13755 AssocTypes,
13756 AssocExprs);
13757 return getDerived().RebuildGenericSelectionExpr(
13758 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13759 ControllingType, AssocTypes, AssocExprs);
13760}
13761
13762template<typename Derived>
13763ExprResult
13764TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13765 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13766 if (SubExpr.isInvalid())
13767 return ExprError();
13768
13769 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13770 return E;
13771
13772 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13773 E->getRParen());
13774}
13775
13776/// The operand of a unary address-of operator has special rules: it's
13777/// allowed to refer to a non-static member of a class even if there's no 'this'
13778/// object available.
13779template<typename Derived>
13780ExprResult
13781TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13782 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13783 return getDerived().TransformDependentScopeDeclRefExpr(
13784 DRE, /*IsAddressOfOperand=*/true, nullptr);
13785 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13786 return getDerived().TransformUnresolvedLookupExpr(
13787 ULE, /*IsAddressOfOperand=*/true);
13788 else
13789 return getDerived().TransformExpr(E);
13790}
13791
13792template<typename Derived>
13793ExprResult
13794TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13795 ExprResult SubExpr;
13796 if (E->getOpcode() == UO_AddrOf)
13797 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13798 else
13799 SubExpr = TransformExpr(E: E->getSubExpr());
13800 if (SubExpr.isInvalid())
13801 return ExprError();
13802
13803 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13804 return E;
13805
13806 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13807 E->getOpcode(),
13808 SubExpr.get());
13809}
13810
13811template<typename Derived>
13812ExprResult
13813TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13814 // Transform the type.
13815 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13816 if (!Type)
13817 return ExprError();
13818
13819 // Transform all of the components into a Designation similar to what the
13820 // parser builds.
13821 // FIXME: It would be slightly more efficient in the non-dependent case to
13822 // just map FieldDecls, rather than requiring the rebuilder to look for
13823 // the fields again. However, __builtin_offsetof is rare enough in
13824 // template code that we don't care.
13825 bool ExprChanged = false;
13826 Designation Desig;
13827 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13828 const OffsetOfNode &ON = E->getComponent(Idx: I);
13829 switch (ON.getKind()) {
13830 case OffsetOfNode::Array: {
13831 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13832 ExprResult Index = getDerived().TransformExpr(FromIndex);
13833 if (Index.isInvalid())
13834 return ExprError();
13835
13836 ExprChanged = ExprChanged || Index.get() != FromIndex;
13837 Designator AD =
13838 Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: ON.getBeginLoc());
13839 AD.setRBracketLoc(ON.getEndLoc());
13840 Desig.AddDesignator(D: AD);
13841 break;
13842 }
13843
13844 case OffsetOfNode::Field:
13845 case OffsetOfNode::Identifier: {
13846 const IdentifierInfo *Name = ON.getFieldName();
13847 if (!Name)
13848 continue;
13849 // The leading designator has no '.'; subsequent ones do.
13850 SourceLocation DotLoc =
13851 Desig.empty() ? SourceLocation() : ON.getBeginLoc();
13852 Desig.AddDesignator(
13853 D: Designator::CreateFieldDesignator(FieldName: Name, DotLoc, FieldLoc: ON.getEndLoc()));
13854 break;
13855 }
13856
13857 case OffsetOfNode::Base:
13858 // Will be recomputed during the rebuild.
13859 continue;
13860 }
13861 }
13862
13863 // If nothing changed, retain the existing expression.
13864 if (!getDerived().AlwaysRebuild() &&
13865 Type == E->getTypeSourceInfo() &&
13866 !ExprChanged)
13867 return E;
13868
13869 // Build a new offsetof expression.
13870 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, Desig,
13871 E->getRParenLoc());
13872}
13873
13874template<typename Derived>
13875ExprResult
13876TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13877 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13878 "opaque value expression requires transformation");
13879 return E;
13880}
13881
13882template <typename Derived>
13883ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13884 llvm::SmallVector<Expr *, 8> Children;
13885 bool Changed = false;
13886 for (Expr *C : E->subExpressions()) {
13887 ExprResult NewC = getDerived().TransformExpr(C);
13888 if (NewC.isInvalid())
13889 return ExprError();
13890 Children.push_back(Elt: NewC.get());
13891
13892 Changed |= NewC.get() != C;
13893 }
13894 if (!getDerived().AlwaysRebuild() && !Changed)
13895 return E;
13896 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13897 Children, E->getType());
13898}
13899
13900template<typename Derived>
13901ExprResult
13902TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13903 // Rebuild the syntactic form. The original syntactic form has
13904 // opaque-value expressions in it, so strip those away and rebuild
13905 // the result. This is a really awful way of doing this, but the
13906 // better solution (rebuilding the semantic expressions and
13907 // rebinding OVEs as necessary) doesn't work; we'd need
13908 // TreeTransform to not strip away implicit conversions.
13909 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13910 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13911 if (result.isInvalid()) return ExprError();
13912
13913 // If that gives us a pseudo-object result back, the pseudo-object
13914 // expression must have been an lvalue-to-rvalue conversion which we
13915 // should reapply.
13916 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13917 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13918
13919 return result;
13920}
13921
13922template<typename Derived>
13923ExprResult
13924TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13925 UnaryExprOrTypeTraitExpr *E) {
13926 if (E->isArgumentType()) {
13927 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13928
13929 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13930 if (!NewT)
13931 return ExprError();
13932
13933 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13934 return E;
13935
13936 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13937 E->getKind(),
13938 E->getSourceRange());
13939 }
13940
13941 // C++0x [expr.sizeof]p1:
13942 // The operand is either an expression, which is an unevaluated operand
13943 // [...]
13944 EnterExpressionEvaluationContext Unevaluated(
13945 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13946 Sema::ReuseLambdaContextDecl);
13947
13948 // Try to recover if we have something like sizeof(T::X) where X is a type.
13949 // Notably, there must be *exactly* one set of parens if X is a type.
13950 TypeSourceInfo *RecoveryTSI = nullptr;
13951 ExprResult SubExpr;
13952 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13953 if (auto *DRE =
13954 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13955 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13956 PE, DRE, false, &RecoveryTSI);
13957 else
13958 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13959
13960 if (RecoveryTSI) {
13961 return getDerived().RebuildUnaryExprOrTypeTrait(
13962 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13963 } else if (SubExpr.isInvalid())
13964 return ExprError();
13965
13966 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13967 return E;
13968
13969 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13970 E->getOperatorLoc(),
13971 E->getKind(),
13972 E->getSourceRange());
13973}
13974
13975template<typename Derived>
13976ExprResult
13977TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13978 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13979 if (LHS.isInvalid())
13980 return ExprError();
13981
13982 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13983 if (RHS.isInvalid())
13984 return ExprError();
13985
13986
13987 if (!getDerived().AlwaysRebuild() &&
13988 LHS.get() == E->getLHS() &&
13989 RHS.get() == E->getRHS())
13990 return E;
13991
13992 return getDerived().RebuildArraySubscriptExpr(
13993 LHS.get(),
13994 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13995}
13996
13997template <typename Derived>
13998ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13999 MatrixSingleSubscriptExpr *E) {
14000 ExprResult Base = getDerived().TransformExpr(E->getBase());
14001 if (Base.isInvalid())
14002 return ExprError();
14003
14004 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14005 if (RowIdx.isInvalid())
14006 return ExprError();
14007
14008 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14009 RowIdx.get() == E->getRowIdx())
14010 return E;
14011
14012 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
14013 E->getRBracketLoc());
14014}
14015
14016template <typename Derived>
14017ExprResult
14018TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
14019 ExprResult Base = getDerived().TransformExpr(E->getBase());
14020 if (Base.isInvalid())
14021 return ExprError();
14022
14023 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14024 if (RowIdx.isInvalid())
14025 return ExprError();
14026
14027 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
14028 if (ColumnIdx.isInvalid())
14029 return ExprError();
14030
14031 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14032 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
14033 return E;
14034
14035 return getDerived().RebuildMatrixSubscriptExpr(
14036 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
14037}
14038
14039template <typename Derived>
14040ExprResult
14041TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
14042 ExprResult Base = getDerived().TransformExpr(E->getBase());
14043 if (Base.isInvalid())
14044 return ExprError();
14045
14046 ExprResult LowerBound;
14047 if (E->getLowerBound()) {
14048 LowerBound = getDerived().TransformExpr(E->getLowerBound());
14049 if (LowerBound.isInvalid())
14050 return ExprError();
14051 }
14052
14053 ExprResult Length;
14054 if (E->getLength()) {
14055 Length = getDerived().TransformExpr(E->getLength());
14056 if (Length.isInvalid())
14057 return ExprError();
14058 }
14059
14060 ExprResult Stride;
14061 if (E->isOMPArraySection()) {
14062 if (Expr *Str = E->getStride()) {
14063 Stride = getDerived().TransformExpr(Str);
14064 if (Stride.isInvalid())
14065 return ExprError();
14066 }
14067 }
14068
14069 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14070 LowerBound.get() == E->getLowerBound() &&
14071 Length.get() == E->getLength() &&
14072 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
14073 return E;
14074
14075 return getDerived().RebuildArraySectionExpr(
14076 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
14077 LowerBound.get(), E->getColonLocFirst(),
14078 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
14079 Length.get(), Stride.get(), E->getRBracketLoc());
14080}
14081
14082template <typename Derived>
14083ExprResult
14084TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
14085 ExprResult Base = getDerived().TransformExpr(E->getBase());
14086 if (Base.isInvalid())
14087 return ExprError();
14088
14089 SmallVector<Expr *, 4> Dims;
14090 bool ErrorFound = false;
14091 for (Expr *Dim : E->getDimensions()) {
14092 ExprResult DimRes = getDerived().TransformExpr(Dim);
14093 if (DimRes.isInvalid()) {
14094 ErrorFound = true;
14095 continue;
14096 }
14097 Dims.push_back(Elt: DimRes.get());
14098 }
14099
14100 if (ErrorFound)
14101 return ExprError();
14102 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
14103 E->getRParenLoc(), Dims,
14104 E->getBracketsRanges());
14105}
14106
14107template <typename Derived>
14108ExprResult
14109TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
14110 unsigned NumIterators = E->numOfIterators();
14111 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
14112
14113 bool ErrorFound = false;
14114 bool NeedToRebuild = getDerived().AlwaysRebuild();
14115 for (unsigned I = 0; I < NumIterators; ++I) {
14116 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
14117 Data[I].DeclIdent = D->getIdentifier();
14118 Data[I].DeclIdentLoc = D->getLocation();
14119 if (D->getLocation() == D->getBeginLoc()) {
14120 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
14121 "Implicit type must be int.");
14122 } else {
14123 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
14124 QualType DeclTy = getDerived().TransformType(D->getType());
14125 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
14126 }
14127 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
14128 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
14129 ExprResult End = getDerived().TransformExpr(Range.End);
14130 ExprResult Step = getDerived().TransformExpr(Range.Step);
14131 ErrorFound = ErrorFound ||
14132 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
14133 !Data[I].Type.get().isNull())) ||
14134 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
14135 if (ErrorFound)
14136 continue;
14137 Data[I].Range.Begin = Begin.get();
14138 Data[I].Range.End = End.get();
14139 Data[I].Range.Step = Step.get();
14140 Data[I].AssignLoc = E->getAssignLoc(I);
14141 Data[I].ColonLoc = E->getColonLoc(I);
14142 Data[I].SecColonLoc = E->getSecondColonLoc(I);
14143 NeedToRebuild =
14144 NeedToRebuild ||
14145 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
14146 D->getType().getTypePtrOrNull()) ||
14147 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
14148 Range.Step != Data[I].Range.Step;
14149 }
14150 if (ErrorFound)
14151 return ExprError();
14152 if (!NeedToRebuild)
14153 return E;
14154
14155 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
14156 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
14157 if (!Res.isUsable())
14158 return Res;
14159 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
14160 for (unsigned I = 0; I < NumIterators; ++I)
14161 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
14162 IE->getIteratorDecl(I));
14163 return Res;
14164}
14165
14166template<typename Derived>
14167ExprResult
14168TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
14169 // Transform the callee.
14170 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14171 if (Callee.isInvalid())
14172 return ExprError();
14173
14174 // Transform arguments.
14175 bool ArgChanged = false;
14176 SmallVector<Expr*, 8> Args;
14177 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14178 &ArgChanged))
14179 return ExprError();
14180
14181 if (!getDerived().AlwaysRebuild() &&
14182 Callee.get() == E->getCallee() &&
14183 !ArgChanged)
14184 return SemaRef.MaybeBindToTemporary(E);
14185
14186 // FIXME: Wrong source location information for the '('.
14187 SourceLocation FakeLParenLoc
14188 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14189
14190 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14191 if (E->hasStoredFPFeatures()) {
14192 FPOptionsOverride NewOverrides = E->getFPFeatures();
14193 getSema().CurFPFeatures =
14194 NewOverrides.applyOverrides(getSema().getLangOpts());
14195 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14196 }
14197
14198 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14199 Args,
14200 E->getRParenLoc());
14201}
14202
14203template<typename Derived>
14204ExprResult
14205TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
14206 ExprResult Base = getDerived().TransformExpr(E->getBase());
14207 if (Base.isInvalid())
14208 return ExprError();
14209
14210 NestedNameSpecifierLoc QualifierLoc;
14211 if (E->hasQualifier()) {
14212 QualifierLoc
14213 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14214
14215 if (!QualifierLoc)
14216 return ExprError();
14217 }
14218 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14219
14220 ValueDecl *Member
14221 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
14222 E->getMemberDecl()));
14223 if (!Member)
14224 return ExprError();
14225
14226 NamedDecl *FoundDecl = E->getFoundDecl();
14227 if (FoundDecl == E->getMemberDecl()) {
14228 FoundDecl = Member;
14229 } else {
14230 FoundDecl = cast_or_null<NamedDecl>(
14231 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
14232 if (!FoundDecl)
14233 return ExprError();
14234 }
14235
14236 if (!getDerived().AlwaysRebuild() &&
14237 Base.get() == E->getBase() &&
14238 QualifierLoc == E->getQualifierLoc() &&
14239 Member == E->getMemberDecl() &&
14240 FoundDecl == E->getFoundDecl() &&
14241 !E->hasExplicitTemplateArgs()) {
14242
14243 // Skip for member expression of (this->f), rebuilt thisi->f is needed
14244 // for Openmp where the field need to be privatizized in the case.
14245 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
14246 getSema().OpenMP().isOpenMPRebuildMemberExpr(
14247 cast<ValueDecl>(Val: Member)))) {
14248 // Mark it referenced in the new context regardless.
14249 // FIXME: this is a bit instantiation-specific.
14250 SemaRef.MarkMemberReferenced(E);
14251 return E;
14252 }
14253 }
14254
14255 TemplateArgumentListInfo TransArgs;
14256 if (E->hasExplicitTemplateArgs()) {
14257 TransArgs.setLAngleLoc(E->getLAngleLoc());
14258 TransArgs.setRAngleLoc(E->getRAngleLoc());
14259 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14260 E->getNumTemplateArgs(),
14261 TransArgs))
14262 return ExprError();
14263 }
14264
14265 // FIXME: Bogus source location for the operator
14266 SourceLocation FakeOperatorLoc =
14267 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
14268
14269 // FIXME: to do this check properly, we will need to preserve the
14270 // first-qualifier-in-scope here, just in case we had a dependent
14271 // base (and therefore couldn't do the check) and a
14272 // nested-name-qualifier (and therefore could do the lookup).
14273 NamedDecl *FirstQualifierInScope = nullptr;
14274 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
14275 if (MemberNameInfo.getName()) {
14276 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
14277 if (!MemberNameInfo.getName())
14278 return ExprError();
14279 }
14280
14281 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
14282 E->isArrow(),
14283 QualifierLoc,
14284 TemplateKWLoc,
14285 MemberNameInfo,
14286 Member,
14287 FoundDecl,
14288 (E->hasExplicitTemplateArgs()
14289 ? &TransArgs : nullptr),
14290 FirstQualifierInScope);
14291}
14292
14293template<typename Derived>
14294ExprResult
14295TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
14296 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14297 if (LHS.isInvalid())
14298 return ExprError();
14299
14300 ExprResult RHS =
14301 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
14302 if (RHS.isInvalid())
14303 return ExprError();
14304
14305 if (!getDerived().AlwaysRebuild() &&
14306 LHS.get() == E->getLHS() &&
14307 RHS.get() == E->getRHS())
14308 return E;
14309
14310 if (E->isCompoundAssignmentOp())
14311 // FPFeatures has already been established from trailing storage
14312 return getDerived().RebuildBinaryOperator(
14313 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
14314 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14315 FPOptionsOverride NewOverrides(E->getFPFeatures());
14316 getSema().CurFPFeatures =
14317 NewOverrides.applyOverrides(getSema().getLangOpts());
14318 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14319 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
14320 LHS.get(), RHS.get());
14321}
14322
14323template <typename Derived>
14324ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
14325 CXXRewrittenBinaryOperator *E) {
14326 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
14327
14328 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
14329 if (LHS.isInvalid())
14330 return ExprError();
14331
14332 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
14333 if (RHS.isInvalid())
14334 return ExprError();
14335
14336 // Extract the already-resolved callee declarations so that we can restrict
14337 // ourselves to using them as the unqualified lookup results when rebuilding.
14338 UnresolvedSet<2> UnqualLookups;
14339 bool ChangedAnyLookups = false;
14340 Expr *PossibleBinOps[] = {E->getSemanticForm(),
14341 const_cast<Expr *>(Decomp.InnerBinOp)};
14342 for (Expr *PossibleBinOp : PossibleBinOps) {
14343 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
14344 if (!Op)
14345 continue;
14346 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
14347 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
14348 continue;
14349
14350 // Transform the callee in case we built a call to a local extern
14351 // declaration.
14352 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
14353 E->getOperatorLoc(), Callee->getFoundDecl()));
14354 if (!Found)
14355 return ExprError();
14356 if (Found != Callee->getFoundDecl())
14357 ChangedAnyLookups = true;
14358 UnqualLookups.addDecl(D: Found);
14359 }
14360
14361 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
14362 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
14363 // Mark all functions used in the rewrite as referenced. Note that when
14364 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
14365 // function calls, and/or there might be a user-defined conversion sequence
14366 // applied to the operands of the <.
14367 // FIXME: this is a bit instantiation-specific.
14368 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
14369 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
14370 return E;
14371 }
14372
14373 return getDerived().RebuildCXXRewrittenBinaryOperator(
14374 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
14375}
14376
14377template<typename Derived>
14378ExprResult
14379TreeTransform<Derived>::TransformCompoundAssignOperator(
14380 CompoundAssignOperator *E) {
14381 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14382 FPOptionsOverride NewOverrides(E->getFPFeatures());
14383 getSema().CurFPFeatures =
14384 NewOverrides.applyOverrides(getSema().getLangOpts());
14385 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14386 return getDerived().TransformBinaryOperator(E);
14387}
14388
14389template<typename Derived>
14390ExprResult TreeTransform<Derived>::
14391TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
14392 // Just rebuild the common and RHS expressions and see whether we
14393 // get any changes.
14394
14395 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
14396 if (commonExpr.isInvalid())
14397 return ExprError();
14398
14399 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
14400 if (rhs.isInvalid())
14401 return ExprError();
14402
14403 if (!getDerived().AlwaysRebuild() &&
14404 commonExpr.get() == e->getCommon() &&
14405 rhs.get() == e->getFalseExpr())
14406 return e;
14407
14408 return getDerived().RebuildConditionalOperator(commonExpr.get(),
14409 e->getQuestionLoc(),
14410 nullptr,
14411 e->getColonLoc(),
14412 rhs.get());
14413}
14414
14415template<typename Derived>
14416ExprResult
14417TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
14418 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14419 if (Cond.isInvalid())
14420 return ExprError();
14421
14422 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14423 if (LHS.isInvalid())
14424 return ExprError();
14425
14426 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14427 if (RHS.isInvalid())
14428 return ExprError();
14429
14430 if (!getDerived().AlwaysRebuild() &&
14431 Cond.get() == E->getCond() &&
14432 LHS.get() == E->getLHS() &&
14433 RHS.get() == E->getRHS())
14434 return E;
14435
14436 return getDerived().RebuildConditionalOperator(Cond.get(),
14437 E->getQuestionLoc(),
14438 LHS.get(),
14439 E->getColonLoc(),
14440 RHS.get());
14441}
14442
14443template<typename Derived>
14444ExprResult
14445TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
14446 // Implicit casts are eliminated during transformation, since they
14447 // will be recomputed by semantic analysis after transformation.
14448 return getDerived().TransformExpr(E->getSubExprAsWritten());
14449}
14450
14451template<typename Derived>
14452ExprResult
14453TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
14454 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14455 if (!Type)
14456 return ExprError();
14457
14458 ExprResult SubExpr
14459 = getDerived().TransformExpr(E->getSubExprAsWritten());
14460 if (SubExpr.isInvalid())
14461 return ExprError();
14462
14463 if (!getDerived().AlwaysRebuild() &&
14464 Type == E->getTypeInfoAsWritten() &&
14465 SubExpr.get() == E->getSubExpr())
14466 return E;
14467
14468 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
14469 Type,
14470 E->getRParenLoc(),
14471 SubExpr.get());
14472}
14473
14474template<typename Derived>
14475ExprResult
14476TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
14477 TypeSourceInfo *OldT = E->getTypeSourceInfo();
14478 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
14479 if (!NewT)
14480 return ExprError();
14481
14482 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
14483 if (Init.isInvalid())
14484 return ExprError();
14485
14486 if (!getDerived().AlwaysRebuild() &&
14487 OldT == NewT &&
14488 Init.get() == E->getInitializer())
14489 return SemaRef.MaybeBindToTemporary(E);
14490
14491 // Note: the expression type doesn't necessarily match the
14492 // type-as-written, but that's okay, because it should always be
14493 // derivable from the initializer.
14494
14495 return getDerived().RebuildCompoundLiteralExpr(
14496 E->getLParenLoc(), NewT,
14497 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14498}
14499
14500template<typename Derived>
14501ExprResult
14502TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14503 ExprResult Base = getDerived().TransformExpr(E->getBase());
14504 if (Base.isInvalid())
14505 return ExprError();
14506
14507 if (!getDerived().AlwaysRebuild() &&
14508 Base.get() == E->getBase())
14509 return E;
14510
14511 // FIXME: Bad source location
14512 SourceLocation FakeOperatorLoc =
14513 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14514 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14515 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14516 E->getAccessor());
14517}
14518
14519template <typename Derived>
14520ExprResult
14521TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14522 ExprResult Base = getDerived().TransformExpr(E->getBase());
14523 if (Base.isInvalid())
14524 return ExprError();
14525
14526 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14527 return E;
14528
14529 // FIXME: Bad source location
14530 SourceLocation FakeOperatorLoc =
14531 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14532 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14533 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14534 E->getAccessor());
14535}
14536
14537template<typename Derived>
14538ExprResult
14539TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14540 if (InitListExpr *Syntactic = E->getSyntacticForm())
14541 E = Syntactic;
14542
14543 bool InitChanged = false;
14544
14545 EnterExpressionEvaluationContext Context(
14546 getSema(), EnterExpressionEvaluationContext::InitList);
14547
14548 SmallVector<Expr*, 4> Inits;
14549 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14550 Inits, &InitChanged))
14551 return ExprError();
14552
14553 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14554 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14555 // in some cases. We can't reuse it in general, because the syntactic and
14556 // semantic forms are linked, and we can't know that semantic form will
14557 // match even if the syntactic form does.
14558 }
14559
14560 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14561 E->getRBraceLoc(), E->isExplicit());
14562}
14563
14564template<typename Derived>
14565ExprResult
14566TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14567 Designation Desig;
14568
14569 // transform the initializer value
14570 ExprResult Init = getDerived().TransformExpr(E->getInit());
14571 if (Init.isInvalid())
14572 return ExprError();
14573
14574 // transform the designators.
14575 SmallVector<Expr*, 4> ArrayExprs;
14576 bool ExprChanged = false;
14577 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14578 if (D.isFieldDesignator()) {
14579 if (D.getFieldDecl()) {
14580 FieldDecl *Field = cast_or_null<FieldDecl>(
14581 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14582 if (Field != D.getFieldDecl())
14583 // Rebuild the expression when the transformed FieldDecl is
14584 // different to the already assigned FieldDecl.
14585 ExprChanged = true;
14586 if (Field->isAnonymousStructOrUnion())
14587 continue;
14588 } else {
14589 // Ensure that the designator expression is rebuilt when there isn't
14590 // a resolved FieldDecl in the designator as we don't want to assign
14591 // a FieldDecl to a pattern designator that will be instantiated again.
14592 ExprChanged = true;
14593 }
14594 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14595 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14596 continue;
14597 }
14598
14599 if (D.isArrayDesignator()) {
14600 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14601 if (Index.isInvalid())
14602 return ExprError();
14603
14604 Desig.AddDesignator(
14605 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14606
14607 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14608 ArrayExprs.push_back(Elt: Index.get());
14609 continue;
14610 }
14611
14612 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14613 ExprResult Start
14614 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14615 if (Start.isInvalid())
14616 return ExprError();
14617
14618 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14619 if (End.isInvalid())
14620 return ExprError();
14621
14622 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14623 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14624
14625 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14626 End.get() != E->getArrayRangeEnd(D);
14627
14628 ArrayExprs.push_back(Elt: Start.get());
14629 ArrayExprs.push_back(Elt: End.get());
14630 }
14631
14632 if (!getDerived().AlwaysRebuild() &&
14633 Init.get() == E->getInit() &&
14634 !ExprChanged)
14635 return E;
14636
14637 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14638 E->getEqualOrColonLoc(),
14639 E->usesGNUSyntax(), Init.get());
14640}
14641
14642// Seems that if TransformInitListExpr() only works on the syntactic form of an
14643// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14644template<typename Derived>
14645ExprResult
14646TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14647 DesignatedInitUpdateExpr *E) {
14648 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14649 "initializer");
14650 return ExprError();
14651}
14652
14653template<typename Derived>
14654ExprResult
14655TreeTransform<Derived>::TransformNoInitExpr(
14656 NoInitExpr *E) {
14657 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14658 return ExprError();
14659}
14660
14661template<typename Derived>
14662ExprResult
14663TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14664 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14665 return ExprError();
14666}
14667
14668template<typename Derived>
14669ExprResult
14670TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14671 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14672 return ExprError();
14673}
14674
14675template<typename Derived>
14676ExprResult
14677TreeTransform<Derived>::TransformImplicitValueInitExpr(
14678 ImplicitValueInitExpr *E) {
14679 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14680
14681 // FIXME: Will we ever have proper type location here? Will we actually
14682 // need to transform the type?
14683 QualType T = getDerived().TransformType(E->getType());
14684 if (T.isNull())
14685 return ExprError();
14686
14687 if (!getDerived().AlwaysRebuild() &&
14688 T == E->getType())
14689 return E;
14690
14691 return getDerived().RebuildImplicitValueInitExpr(T);
14692}
14693
14694template<typename Derived>
14695ExprResult
14696TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14697 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14698 if (!TInfo)
14699 return ExprError();
14700
14701 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14702 if (SubExpr.isInvalid())
14703 return ExprError();
14704
14705 if (!getDerived().AlwaysRebuild() &&
14706 TInfo == E->getWrittenTypeInfo() &&
14707 SubExpr.get() == E->getSubExpr())
14708 return E;
14709
14710 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14711 TInfo, E->getRParenLoc());
14712}
14713
14714template<typename Derived>
14715ExprResult
14716TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14717 bool ArgumentChanged = false;
14718 SmallVector<Expr*, 4> Inits;
14719 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14720 ArgChanged: &ArgumentChanged))
14721 return ExprError();
14722
14723 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14724 Inits,
14725 E->getRParenLoc());
14726}
14727
14728/// Transform an address-of-label expression.
14729///
14730/// By default, the transformation of an address-of-label expression always
14731/// rebuilds the expression, so that the label identifier can be resolved to
14732/// the corresponding label statement by semantic analysis.
14733template<typename Derived>
14734ExprResult
14735TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14736 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14737 E->getLabel());
14738 if (!LD)
14739 return ExprError();
14740
14741 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14742 cast<LabelDecl>(Val: LD));
14743}
14744
14745template<typename Derived>
14746ExprResult
14747TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14748 SemaRef.ActOnStartStmtExpr();
14749 StmtResult SubStmt
14750 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14751 if (SubStmt.isInvalid()) {
14752 SemaRef.ActOnStmtExprError();
14753 return ExprError();
14754 }
14755
14756 unsigned OldDepth = E->getTemplateDepth();
14757 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14758
14759 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14760 SubStmt.get() == E->getSubStmt()) {
14761 // Calling this an 'error' is unintuitive, but it does the right thing.
14762 SemaRef.ActOnStmtExprError();
14763 return SemaRef.MaybeBindToTemporary(E);
14764 }
14765
14766 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14767 E->getRParenLoc(), NewDepth);
14768}
14769
14770template<typename Derived>
14771ExprResult
14772TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14773 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14774 if (Cond.isInvalid())
14775 return ExprError();
14776
14777 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14778 if (LHS.isInvalid())
14779 return ExprError();
14780
14781 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14782 if (RHS.isInvalid())
14783 return ExprError();
14784
14785 if (!getDerived().AlwaysRebuild() &&
14786 Cond.get() == E->getCond() &&
14787 LHS.get() == E->getLHS() &&
14788 RHS.get() == E->getRHS())
14789 return E;
14790
14791 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14792 Cond.get(), LHS.get(), RHS.get(),
14793 E->getRParenLoc());
14794}
14795
14796template<typename Derived>
14797ExprResult
14798TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14799 return E;
14800}
14801
14802template<typename Derived>
14803ExprResult
14804TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14805 switch (E->getOperator()) {
14806 case OO_New:
14807 case OO_Delete:
14808 case OO_Array_New:
14809 case OO_Array_Delete:
14810 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14811
14812 case OO_Subscript:
14813 case OO_Call: {
14814 // This is a call to an object's operator().
14815 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14816
14817 // Transform the object itself.
14818 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14819 if (Object.isInvalid())
14820 return ExprError();
14821
14822 // FIXME: Poor location information. Also, if the location for the end of
14823 // the token is within a macro expansion, getLocForEndOfToken() will return
14824 // an invalid source location. If that happens and we have an otherwise
14825 // valid end location, use the valid one instead of the invalid one.
14826 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14827 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14828 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14829 FakeLParenLoc = EndLoc;
14830
14831 // Transform the call arguments.
14832 SmallVector<Expr*, 8> Args;
14833 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14834 Args))
14835 return ExprError();
14836
14837 if (E->getOperator() == OO_Subscript)
14838 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14839 Args, E->getEndLoc());
14840
14841 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14842 E->getEndLoc());
14843 }
14844
14845#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14846 case OO_##Name: \
14847 break;
14848
14849#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14850#include "clang/Basic/OperatorKinds.def"
14851
14852 case OO_Conditional:
14853 llvm_unreachable("conditional operator is not actually overloadable");
14854
14855 case OO_None:
14856 case NUM_OVERLOADED_OPERATORS:
14857 llvm_unreachable("not an overloaded operator?");
14858 }
14859
14860 ExprResult First;
14861 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14862 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14863 else
14864 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14865 if (First.isInvalid())
14866 return ExprError();
14867
14868 ExprResult Second;
14869 if (E->getNumArgs() == 2) {
14870 Second =
14871 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14872 if (Second.isInvalid())
14873 return ExprError();
14874 }
14875
14876 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14877 FPOptionsOverride NewOverrides(E->getFPFeatures());
14878 getSema().CurFPFeatures =
14879 NewOverrides.applyOverrides(getSema().getLangOpts());
14880 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14881
14882 Expr *Callee = E->getCallee();
14883 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14884 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14885 Sema::LookupOrdinaryName);
14886 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14887 return ExprError();
14888
14889 return getDerived().RebuildCXXOperatorCallExpr(
14890 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14891 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14892 }
14893
14894 UnresolvedSet<1> Functions;
14895 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14896 Callee = ICE->getSubExprAsWritten();
14897 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14898 ValueDecl *VD = cast_or_null<ValueDecl>(
14899 getDerived().TransformDecl(DR->getLocation(), DR));
14900 if (!VD)
14901 return ExprError();
14902
14903 if (!isa<CXXMethodDecl>(Val: VD))
14904 Functions.addDecl(D: VD);
14905
14906 return getDerived().RebuildCXXOperatorCallExpr(
14907 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14908 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14909}
14910
14911template<typename Derived>
14912ExprResult
14913TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14914 return getDerived().TransformCallExpr(E);
14915}
14916
14917template <typename Derived>
14918ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14919 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14920 getSema().CurContext != E->getParentContext();
14921
14922 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14923 return E;
14924
14925 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14926 E->getBeginLoc(), E->getEndLoc(),
14927 getSema().CurContext);
14928}
14929
14930template <typename Derived>
14931ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14932 return E;
14933}
14934
14935template<typename Derived>
14936ExprResult
14937TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14938 // Transform the callee.
14939 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14940 if (Callee.isInvalid())
14941 return ExprError();
14942
14943 // Transform exec config.
14944 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14945 if (EC.isInvalid())
14946 return ExprError();
14947
14948 // Transform arguments.
14949 bool ArgChanged = false;
14950 SmallVector<Expr*, 8> Args;
14951 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14952 &ArgChanged))
14953 return ExprError();
14954
14955 if (!getDerived().AlwaysRebuild() &&
14956 Callee.get() == E->getCallee() &&
14957 !ArgChanged)
14958 return SemaRef.MaybeBindToTemporary(E);
14959
14960 // FIXME: Wrong source location information for the '('.
14961 SourceLocation FakeLParenLoc
14962 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14963 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14964 Args,
14965 E->getRParenLoc(), EC.get());
14966}
14967
14968template<typename Derived>
14969ExprResult
14970TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14971 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14972 if (!Type)
14973 return ExprError();
14974
14975 ExprResult SubExpr
14976 = getDerived().TransformExpr(E->getSubExprAsWritten());
14977 if (SubExpr.isInvalid())
14978 return ExprError();
14979
14980 if (!getDerived().AlwaysRebuild() &&
14981 Type == E->getTypeInfoAsWritten() &&
14982 SubExpr.get() == E->getSubExpr())
14983 return E;
14984 return getDerived().RebuildCXXNamedCastExpr(
14985 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14986 Type, E->getAngleBrackets().getEnd(),
14987 // FIXME. this should be '(' location
14988 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14989}
14990
14991template<typename Derived>
14992ExprResult
14993TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14994 TypeSourceInfo *TSI =
14995 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14996 if (!TSI)
14997 return ExprError();
14998
14999 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
15000 if (Sub.isInvalid())
15001 return ExprError();
15002
15003 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
15004 Sub.get(), BCE->getEndLoc());
15005}
15006
15007template<typename Derived>
15008ExprResult
15009TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
15010 return getDerived().TransformCXXNamedCastExpr(E);
15011}
15012
15013template<typename Derived>
15014ExprResult
15015TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
15016 return getDerived().TransformCXXNamedCastExpr(E);
15017}
15018
15019template<typename Derived>
15020ExprResult
15021TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
15022 CXXReinterpretCastExpr *E) {
15023 return getDerived().TransformCXXNamedCastExpr(E);
15024}
15025
15026template<typename Derived>
15027ExprResult
15028TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
15029 return getDerived().TransformCXXNamedCastExpr(E);
15030}
15031
15032template<typename Derived>
15033ExprResult
15034TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
15035 return getDerived().TransformCXXNamedCastExpr(E);
15036}
15037
15038template<typename Derived>
15039ExprResult
15040TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
15041 CXXFunctionalCastExpr *E) {
15042 TypeSourceInfo *Type =
15043 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
15044 if (!Type)
15045 return ExprError();
15046
15047 ExprResult SubExpr
15048 = getDerived().TransformExpr(E->getSubExprAsWritten());
15049 if (SubExpr.isInvalid())
15050 return ExprError();
15051
15052 if (!getDerived().AlwaysRebuild() &&
15053 Type == E->getTypeInfoAsWritten() &&
15054 SubExpr.get() == E->getSubExpr())
15055 return E;
15056
15057 return getDerived().RebuildCXXFunctionalCastExpr(Type,
15058 E->getLParenLoc(),
15059 SubExpr.get(),
15060 E->getRParenLoc(),
15061 E->isListInitialization());
15062}
15063
15064template<typename Derived>
15065ExprResult
15066TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
15067 if (E->isTypeOperand()) {
15068 TypeSourceInfo *TInfo
15069 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15070 if (!TInfo)
15071 return ExprError();
15072
15073 if (!getDerived().AlwaysRebuild() &&
15074 TInfo == E->getTypeOperandSourceInfo())
15075 return E;
15076
15077 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15078 TInfo, E->getEndLoc());
15079 }
15080
15081 // Typeid's operand is an unevaluated context, unless it's a polymorphic
15082 // type. We must not unilaterally enter unevaluated context here, as then
15083 // semantic processing can re-transform an already transformed operand.
15084 Expr *Op = E->getExprOperand();
15085 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
15086 if (E->isGLValue()) {
15087 QualType OpType = Op->getType();
15088 if (auto *RD = OpType->getAsCXXRecordDecl()) {
15089 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
15090 DiagID: diag::err_incomplete_typeid))
15091 return ExprError();
15092
15093 if (RD->isPolymorphic())
15094 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
15095 }
15096 }
15097
15098 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
15099 Sema::ReuseLambdaContextDecl);
15100
15101 ExprResult SubExpr = getDerived().TransformExpr(Op);
15102 if (SubExpr.isInvalid())
15103 return ExprError();
15104
15105 if (!getDerived().AlwaysRebuild() &&
15106 SubExpr.get() == E->getExprOperand())
15107 return E;
15108
15109 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15110 SubExpr.get(), E->getEndLoc());
15111}
15112
15113template<typename Derived>
15114ExprResult
15115TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
15116 if (E->isTypeOperand()) {
15117 TypeSourceInfo *TInfo
15118 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15119 if (!TInfo)
15120 return ExprError();
15121
15122 if (!getDerived().AlwaysRebuild() &&
15123 TInfo == E->getTypeOperandSourceInfo())
15124 return E;
15125
15126 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15127 TInfo, E->getEndLoc());
15128 }
15129
15130 EnterExpressionEvaluationContext Unevaluated(
15131 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15132
15133 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
15134 if (SubExpr.isInvalid())
15135 return ExprError();
15136
15137 if (!getDerived().AlwaysRebuild() &&
15138 SubExpr.get() == E->getExprOperand())
15139 return E;
15140
15141 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15142 SubExpr.get(), E->getEndLoc());
15143}
15144
15145template<typename Derived>
15146ExprResult
15147TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
15148 return E;
15149}
15150
15151template<typename Derived>
15152ExprResult
15153TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
15154 CXXNullPtrLiteralExpr *E) {
15155 return E;
15156}
15157
15158template<typename Derived>
15159ExprResult
15160TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
15161
15162 // In lambdas, the qualifiers of the type depends of where in
15163 // the call operator `this` appear, and we do not have a good way to
15164 // rebuild this information, so we transform the type.
15165 //
15166 // In other contexts, the type of `this` may be overrided
15167 // for type deduction, so we need to recompute it.
15168 //
15169 // Always recompute the type if we're in the body of a lambda, and
15170 // 'this' is dependent on a lambda's explicit object parameter; we
15171 // also need to always rebuild the expression in this case to clear
15172 // the flag.
15173 QualType T = [&]() {
15174 auto &S = getSema();
15175 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
15176 return S.getCurrentThisType();
15177 if (S.getCurLambda())
15178 return getDerived().TransformType(E->getType());
15179 return S.getCurrentThisType();
15180 }();
15181
15182 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
15183 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
15184 // Mark it referenced in the new context regardless.
15185 // FIXME: this is a bit instantiation-specific.
15186 getSema().MarkThisReferenced(E);
15187 return E;
15188 }
15189
15190 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
15191}
15192
15193template<typename Derived>
15194ExprResult
15195TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
15196 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15197 if (SubExpr.isInvalid())
15198 return ExprError();
15199
15200 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
15201
15202 if (!getDerived().AlwaysRebuild() &&
15203 SubExpr.get() == E->getSubExpr())
15204 return E;
15205
15206 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
15207 E->isThrownVariableInScope());
15208}
15209
15210template<typename Derived>
15211ExprResult
15212TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
15213 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
15214 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
15215 if (!Param)
15216 return ExprError();
15217
15218 ExprResult InitRes;
15219 if (E->hasRewrittenInit()) {
15220 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15221 if (InitRes.isInvalid())
15222 return ExprError();
15223 }
15224
15225 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
15226 E->getUsedContext() == SemaRef.CurContext &&
15227 InitRes.get() == E->getRewrittenExpr())
15228 return E;
15229
15230 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
15231 InitRes.get());
15232}
15233
15234template<typename Derived>
15235ExprResult
15236TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
15237 FieldDecl *Field = cast_or_null<FieldDecl>(
15238 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
15239 if (!Field)
15240 return ExprError();
15241
15242 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
15243 E->getUsedContext() == SemaRef.CurContext)
15244 return E;
15245
15246 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
15247}
15248
15249template<typename Derived>
15250ExprResult
15251TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
15252 CXXScalarValueInitExpr *E) {
15253 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
15254 if (!T)
15255 return ExprError();
15256
15257 if (!getDerived().AlwaysRebuild() &&
15258 T == E->getTypeSourceInfo())
15259 return E;
15260
15261 return getDerived().RebuildCXXScalarValueInitExpr(T,
15262 /*FIXME:*/T->getTypeLoc().getEndLoc(),
15263 E->getRParenLoc());
15264}
15265
15266template<typename Derived>
15267ExprResult
15268TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
15269 // Transform the type that we're allocating
15270 TypeSourceInfo *AllocTypeInfo =
15271 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
15272 if (!AllocTypeInfo)
15273 return ExprError();
15274
15275 // Transform the size of the array we're allocating (if any).
15276 std::optional<Expr *> ArraySize;
15277 if (E->isArray()) {
15278 ExprResult NewArraySize;
15279 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
15280 NewArraySize = getDerived().TransformExpr(*OldArraySize);
15281 if (NewArraySize.isInvalid())
15282 return ExprError();
15283 }
15284 ArraySize = NewArraySize.get();
15285 }
15286
15287 // Transform the placement arguments (if any).
15288 bool ArgumentChanged = false;
15289 SmallVector<Expr*, 8> PlacementArgs;
15290 if (getDerived().TransformExprs(E->getPlacementArgs(),
15291 E->getNumPlacementArgs(), true,
15292 PlacementArgs, &ArgumentChanged))
15293 return ExprError();
15294
15295 // Transform the initializer (if any).
15296 Expr *OldInit = E->getInitializer();
15297 ExprResult NewInit;
15298 if (OldInit)
15299 NewInit = getDerived().TransformInitializer(OldInit, true);
15300 if (NewInit.isInvalid())
15301 return ExprError();
15302
15303 // Transform new operator and delete operator.
15304 FunctionDecl *OperatorNew = nullptr;
15305 if (E->getOperatorNew()) {
15306 OperatorNew = cast_or_null<FunctionDecl>(
15307 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
15308 if (!OperatorNew)
15309 return ExprError();
15310 }
15311
15312 FunctionDecl *OperatorDelete = nullptr;
15313 if (E->getOperatorDelete()) {
15314 OperatorDelete = cast_or_null<FunctionDecl>(
15315 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15316 if (!OperatorDelete)
15317 return ExprError();
15318 }
15319
15320 if (!getDerived().AlwaysRebuild() &&
15321 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
15322 ArraySize == E->getArraySize() &&
15323 NewInit.get() == OldInit &&
15324 OperatorNew == E->getOperatorNew() &&
15325 OperatorDelete == E->getOperatorDelete() &&
15326 !ArgumentChanged) {
15327 // Mark any declarations we need as referenced.
15328 // FIXME: instantiation-specific.
15329 if (OperatorNew)
15330 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
15331 if (OperatorDelete)
15332 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15333
15334 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
15335 QualType ElementType
15336 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
15337 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
15338 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
15339 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
15340 }
15341 }
15342
15343 return E;
15344 }
15345
15346 QualType AllocType = AllocTypeInfo->getType();
15347 if (!ArraySize) {
15348 // If no array size was specified, but the new expression was
15349 // instantiated with an array type (e.g., "new T" where T is
15350 // instantiated with "int[4]"), extract the outer bound from the
15351 // array type as our array size. We do this with constant and
15352 // dependently-sized array types.
15353 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
15354 if (!ArrayT) {
15355 // Do nothing
15356 } else if (const ConstantArrayType *ConsArrayT
15357 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
15358 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
15359 type: SemaRef.Context.getSizeType(),
15360 /*FIXME:*/ l: E->getBeginLoc());
15361 AllocType = ConsArrayT->getElementType();
15362 } else if (const DependentSizedArrayType *DepArrayT
15363 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
15364 if (DepArrayT->getSizeExpr()) {
15365 ArraySize = DepArrayT->getSizeExpr();
15366 AllocType = DepArrayT->getElementType();
15367 }
15368 }
15369 }
15370
15371 return getDerived().RebuildCXXNewExpr(
15372 E->getBeginLoc(), E->isGlobalNew(),
15373 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
15374 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
15375 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
15376}
15377
15378template<typename Derived>
15379ExprResult
15380TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
15381 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
15382 if (Operand.isInvalid())
15383 return ExprError();
15384
15385 // Transform the delete operator, if known.
15386 FunctionDecl *OperatorDelete = nullptr;
15387 if (E->getOperatorDelete()) {
15388 OperatorDelete = cast_or_null<FunctionDecl>(
15389 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15390 if (!OperatorDelete)
15391 return ExprError();
15392 }
15393
15394 if (!getDerived().AlwaysRebuild() &&
15395 Operand.get() == E->getArgument() &&
15396 OperatorDelete == E->getOperatorDelete()) {
15397 // Mark any declarations we need as referenced.
15398 // FIXME: instantiation-specific.
15399 if (OperatorDelete)
15400 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15401
15402 if (!E->getArgument()->isTypeDependent()) {
15403 QualType Destroyed = SemaRef.Context.getBaseElementType(
15404 QT: E->getDestroyedType());
15405 if (auto *Record = Destroyed->getAsCXXRecordDecl())
15406 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15407 Func: SemaRef.LookupDestructor(Class: Record));
15408 }
15409
15410 return E;
15411 }
15412
15413 return getDerived().RebuildCXXDeleteExpr(
15414 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
15415}
15416
15417template<typename Derived>
15418ExprResult
15419TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
15420 CXXPseudoDestructorExpr *E) {
15421 ExprResult Base = getDerived().TransformExpr(E->getBase());
15422 if (Base.isInvalid())
15423 return ExprError();
15424
15425 ParsedType ObjectTypePtr;
15426 bool MayBePseudoDestructor = false;
15427 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15428 OpLoc: E->getOperatorLoc(),
15429 OpKind: E->isArrow()? tok::arrow : tok::period,
15430 ObjectType&: ObjectTypePtr,
15431 MayBePseudoDestructor);
15432 if (Base.isInvalid())
15433 return ExprError();
15434
15435 QualType ObjectType = ObjectTypePtr.get();
15436 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
15437 if (QualifierLoc) {
15438 QualifierLoc
15439 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
15440 if (!QualifierLoc)
15441 return ExprError();
15442 }
15443 CXXScopeSpec SS;
15444 SS.Adopt(Other: QualifierLoc);
15445
15446 PseudoDestructorTypeStorage Destroyed;
15447 if (E->getDestroyedTypeInfo()) {
15448 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
15449 E->getDestroyedTypeInfo(), ObjectType,
15450 /*FirstQualifierInScope=*/nullptr);
15451 if (!DestroyedTypeInfo)
15452 return ExprError();
15453 Destroyed = DestroyedTypeInfo;
15454 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
15455 // We aren't likely to be able to resolve the identifier down to a type
15456 // now anyway, so just retain the identifier.
15457 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
15458 E->getDestroyedTypeLoc());
15459 } else {
15460 // Look for a destructor known with the given name.
15461 ParsedType T = SemaRef.getDestructorName(
15462 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
15463 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
15464 if (!T)
15465 return ExprError();
15466
15467 Destroyed
15468 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
15469 Loc: E->getDestroyedTypeLoc());
15470 }
15471
15472 TypeSourceInfo *ScopeTypeInfo = nullptr;
15473 if (E->getScopeTypeInfo()) {
15474 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
15475 E->getScopeTypeInfo(), ObjectType, nullptr);
15476 if (!ScopeTypeInfo)
15477 return ExprError();
15478 }
15479
15480 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
15481 E->getOperatorLoc(),
15482 E->isArrow(),
15483 SS,
15484 ScopeTypeInfo,
15485 E->getColonColonLoc(),
15486 E->getTildeLoc(),
15487 Destroyed);
15488}
15489
15490template <typename Derived>
15491bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
15492 bool RequiresADL,
15493 LookupResult &R) {
15494 // Transform all the decls.
15495 bool AllEmptyPacks = true;
15496 for (auto *OldD : Old->decls()) {
15497 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15498 if (!InstD) {
15499 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15500 // This can happen because of dependent hiding.
15501 if (isa<UsingShadowDecl>(Val: OldD))
15502 continue;
15503 else {
15504 R.clear();
15505 return true;
15506 }
15507 }
15508
15509 // Expand using pack declarations.
15510 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15511 ArrayRef<NamedDecl*> Decls = SingleDecl;
15512 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15513 Decls = UPD->expansions();
15514
15515 // Expand using declarations.
15516 for (auto *D : Decls) {
15517 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15518 for (auto *SD : UD->shadows())
15519 R.addDecl(D: SD);
15520 } else {
15521 R.addDecl(D);
15522 }
15523 }
15524
15525 AllEmptyPacks &= Decls.empty();
15526 }
15527
15528 // C++ [temp.res]/8.4.2:
15529 // The program is ill-formed, no diagnostic required, if [...] lookup for
15530 // a name in the template definition found a using-declaration, but the
15531 // lookup in the corresponding scope in the instantiation odoes not find
15532 // any declarations because the using-declaration was a pack expansion and
15533 // the corresponding pack is empty
15534 if (AllEmptyPacks && !RequiresADL) {
15535 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15536 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15537 return true;
15538 }
15539
15540 // Resolve a kind, but don't do any further analysis. If it's
15541 // ambiguous, the callee needs to deal with it.
15542 R.resolveKind();
15543
15544 if (Old->hasTemplateKeyword() && !R.empty()) {
15545 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15546 getSema().FilterAcceptableTemplateNames(R,
15547 /*AllowFunctionTemplates=*/true,
15548 /*AllowDependent=*/true);
15549 if (R.empty()) {
15550 // If a 'template' keyword was used, a lookup that finds only non-template
15551 // names is an error.
15552 getSema().Diag(R.getNameLoc(),
15553 diag::err_template_kw_refers_to_non_template)
15554 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15555 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15556 getSema().Diag(FoundDecl->getLocation(),
15557 diag::note_template_kw_refers_to_non_template)
15558 << R.getLookupName();
15559 return true;
15560 }
15561 }
15562
15563 return false;
15564}
15565
15566template <typename Derived>
15567ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15568 UnresolvedLookupExpr *Old) {
15569 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15570}
15571
15572template <typename Derived>
15573ExprResult
15574TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15575 bool IsAddressOfOperand) {
15576 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15577 Sema::LookupOrdinaryName);
15578
15579 // Transform the declaration set.
15580 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15581 return ExprError();
15582
15583 // Rebuild the nested-name qualifier, if present.
15584 CXXScopeSpec SS;
15585 if (Old->getQualifierLoc()) {
15586 NestedNameSpecifierLoc QualifierLoc
15587 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15588 if (!QualifierLoc)
15589 return ExprError();
15590
15591 SS.Adopt(Other: QualifierLoc);
15592 }
15593
15594 if (Old->getNamingClass()) {
15595 CXXRecordDecl *NamingClass
15596 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15597 Old->getNameLoc(),
15598 Old->getNamingClass()));
15599 if (!NamingClass) {
15600 R.clear();
15601 return ExprError();
15602 }
15603
15604 R.setNamingClass(NamingClass);
15605 }
15606
15607 // Rebuild the template arguments, if any.
15608 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15609 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15610 if (Old->hasExplicitTemplateArgs() &&
15611 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15612 Old->getNumTemplateArgs(),
15613 TransArgs)) {
15614 R.clear();
15615 return ExprError();
15616 }
15617
15618 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15619 // a non-static data member is named in an unevaluated operand, or when
15620 // a member is named in a dependent class scope function template explicit
15621 // specialization that is neither declared static nor with an explicit object
15622 // parameter.
15623 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15624 return SemaRef.BuildPossibleImplicitMemberExpr(
15625 SS, TemplateKWLoc, R,
15626 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15627 /*S=*/S: nullptr);
15628
15629 // If we have neither explicit template arguments, nor the template keyword,
15630 // it's a normal declaration name or member reference.
15631 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15632 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15633
15634 // If we have template arguments, then rebuild the template-id expression.
15635 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15636 Old->requiresADL(), &TransArgs);
15637}
15638
15639template<typename Derived>
15640ExprResult
15641TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15642 bool ArgChanged = false;
15643 SmallVector<TypeSourceInfo *, 4> Args;
15644 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15645 TypeSourceInfo *From = E->getArg(I);
15646 TypeLoc FromTL = From->getTypeLoc();
15647 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15648 TypeLocBuilder TLB;
15649 TLB.reserve(Requested: FromTL.getFullDataSize());
15650 QualType To = getDerived().TransformType(TLB, FromTL);
15651 if (To.isNull())
15652 return ExprError();
15653
15654 if (To == From->getType())
15655 Args.push_back(Elt: From);
15656 else {
15657 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15658 ArgChanged = true;
15659 }
15660 continue;
15661 }
15662
15663 ArgChanged = true;
15664
15665 // We have a pack expansion. Instantiate it.
15666 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15667 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15668 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15669 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15670
15671 // Determine whether the set of unexpanded parameter packs can and should
15672 // be expanded.
15673 bool Expand = true;
15674 bool RetainExpansion = false;
15675 UnsignedOrNone OrigNumExpansions =
15676 ExpansionTL.getTypePtr()->getNumExpansions();
15677 UnsignedOrNone NumExpansions = OrigNumExpansions;
15678 if (getDerived().TryExpandParameterPacks(
15679 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15680 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15681 RetainExpansion, NumExpansions))
15682 return ExprError();
15683
15684 if (!Expand) {
15685 // The transform has determined that we should perform a simple
15686 // transformation on the pack expansion, producing another pack
15687 // expansion.
15688 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15689
15690 TypeLocBuilder TLB;
15691 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15692
15693 QualType To = getDerived().TransformType(TLB, PatternTL);
15694 if (To.isNull())
15695 return ExprError();
15696
15697 To = getDerived().RebuildPackExpansionType(To,
15698 PatternTL.getSourceRange(),
15699 ExpansionTL.getEllipsisLoc(),
15700 NumExpansions);
15701 if (To.isNull())
15702 return ExprError();
15703
15704 PackExpansionTypeLoc ToExpansionTL
15705 = TLB.push<PackExpansionTypeLoc>(T: To);
15706 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15707 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15708 continue;
15709 }
15710
15711 // Expand the pack expansion by substituting for each argument in the
15712 // pack(s).
15713 for (unsigned I = 0; I != *NumExpansions; ++I) {
15714 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15715 TypeLocBuilder TLB;
15716 TLB.reserve(Requested: PatternTL.getFullDataSize());
15717 QualType To = getDerived().TransformType(TLB, PatternTL);
15718 if (To.isNull())
15719 return ExprError();
15720
15721 if (To->containsUnexpandedParameterPack()) {
15722 To = getDerived().RebuildPackExpansionType(To,
15723 PatternTL.getSourceRange(),
15724 ExpansionTL.getEllipsisLoc(),
15725 NumExpansions);
15726 if (To.isNull())
15727 return ExprError();
15728
15729 PackExpansionTypeLoc ToExpansionTL
15730 = TLB.push<PackExpansionTypeLoc>(T: To);
15731 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15732 }
15733
15734 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15735 }
15736
15737 if (!RetainExpansion)
15738 continue;
15739
15740 // If we're supposed to retain a pack expansion, do so by temporarily
15741 // forgetting the partially-substituted parameter pack.
15742 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15743
15744 TypeLocBuilder TLB;
15745 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15746
15747 QualType To = getDerived().TransformType(TLB, PatternTL);
15748 if (To.isNull())
15749 return ExprError();
15750
15751 To = getDerived().RebuildPackExpansionType(To,
15752 PatternTL.getSourceRange(),
15753 ExpansionTL.getEllipsisLoc(),
15754 NumExpansions);
15755 if (To.isNull())
15756 return ExprError();
15757
15758 PackExpansionTypeLoc ToExpansionTL
15759 = TLB.push<PackExpansionTypeLoc>(T: To);
15760 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15761 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15762 }
15763
15764 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15765 return E;
15766
15767 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15768 E->getEndLoc());
15769}
15770
15771template<typename Derived>
15772ExprResult
15773TreeTransform<Derived>::TransformConceptSpecializationExpr(
15774 ConceptSpecializationExpr *E) {
15775 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15776 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15777 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15778 Old->NumTemplateArgs, TransArgs))
15779 return ExprError();
15780
15781 return getDerived().RebuildConceptSpecializationExpr(
15782 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15783 E->getConceptNameInfo(), E->getFoundDecl(), E->getConceptDecl(),
15784 &TransArgs);
15785}
15786
15787template<typename Derived>
15788ExprResult
15789TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15790 SmallVector<ParmVarDecl*, 4> TransParams;
15791 SmallVector<QualType, 4> TransParamTypes;
15792 Sema::ExtParameterInfoBuilder ExtParamInfos;
15793
15794 // C++2a [expr.prim.req]p2
15795 // Expressions appearing within a requirement-body are unevaluated operands.
15796 EnterExpressionEvaluationContext Ctx(
15797 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15798 Sema::ReuseLambdaContextDecl);
15799
15800 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15801 C&: getSema().Context, DC: getSema().CurContext,
15802 StartLoc: E->getBody()->getBeginLoc());
15803
15804 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15805
15806 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15807 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15808 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15809
15810 for (ParmVarDecl *Param : TransParams)
15811 if (Param)
15812 Param->setDeclContext(Body);
15813
15814 // On failure to transform, TransformRequiresTypeParams returns an expression
15815 // in the event that the transformation of the type params failed in some way.
15816 // It is expected that this will result in a 'not satisfied' Requires clause
15817 // when instantiating.
15818 if (!TypeParamResult.isUnset())
15819 return TypeParamResult;
15820
15821 SmallVector<concepts::Requirement *, 4> TransReqs;
15822 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15823 TransReqs))
15824 return ExprError();
15825
15826 for (concepts::Requirement *Req : TransReqs) {
15827 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15828 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15829 ER->getReturnTypeRequirement()
15830 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15831 ->setDeclContext(Body);
15832 }
15833 }
15834 }
15835
15836 return getDerived().RebuildRequiresExpr(
15837 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15838 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15839}
15840
15841template<typename Derived>
15842bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15843 ArrayRef<concepts::Requirement *> Reqs,
15844 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15845 for (concepts::Requirement *Req : Reqs) {
15846 concepts::Requirement *TransReq = nullptr;
15847 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15848 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15849 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15850 TransReq = getDerived().TransformExprRequirement(ExprReq);
15851 else
15852 TransReq = getDerived().TransformNestedRequirement(
15853 cast<concepts::NestedRequirement>(Val: Req));
15854 if (!TransReq)
15855 return true;
15856 Transformed.push_back(Elt: TransReq);
15857 }
15858 return false;
15859}
15860
15861template<typename Derived>
15862concepts::TypeRequirement *
15863TreeTransform<Derived>::TransformTypeRequirement(
15864 concepts::TypeRequirement *Req) {
15865 if (Req->isSubstitutionFailure()) {
15866 if (getDerived().AlwaysRebuild())
15867 return getDerived().RebuildTypeRequirement(
15868 Req->getSubstitutionDiagnostic());
15869 return Req;
15870 }
15871 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15872 if (!TransType)
15873 return nullptr;
15874 return getDerived().RebuildTypeRequirement(TransType);
15875}
15876
15877template<typename Derived>
15878concepts::ExprRequirement *
15879TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15880 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15881 if (Req->isExprSubstitutionFailure())
15882 TransExpr = Req->getExprSubstitutionDiagnostic();
15883 else {
15884 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15885 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15886 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15887 if (TransExprRes.isInvalid())
15888 return nullptr;
15889 TransExpr = TransExprRes.get();
15890 }
15891
15892 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15893 const auto &RetReq = Req->getReturnTypeRequirement();
15894 if (RetReq.isEmpty())
15895 TransRetReq.emplace();
15896 else if (RetReq.isSubstitutionFailure())
15897 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15898 else if (RetReq.isTypeConstraint()) {
15899 TemplateParameterList *OrigTPL =
15900 RetReq.getTypeConstraintTemplateParameterList();
15901 TemplateParameterList *TPL =
15902 getDerived().TransformTemplateParameterList(OrigTPL);
15903 if (!TPL)
15904 return nullptr;
15905 TransRetReq.emplace(args&: TPL);
15906 }
15907 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15908 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15909 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15910 Req->getNoexceptLoc(),
15911 std::move(*TransRetReq));
15912 return getDerived().RebuildExprRequirement(
15913 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15914 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15915}
15916
15917template<typename Derived>
15918concepts::NestedRequirement *
15919TreeTransform<Derived>::TransformNestedRequirement(
15920 concepts::NestedRequirement *Req) {
15921 if (Req->hasInvalidConstraint()) {
15922 if (getDerived().AlwaysRebuild())
15923 return getDerived().RebuildNestedRequirement(
15924 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15925 return Req;
15926 }
15927 ExprResult TransConstraint =
15928 getDerived().TransformExpr(Req->getConstraintExpr());
15929 if (TransConstraint.isInvalid())
15930 return nullptr;
15931 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15932}
15933
15934template<typename Derived>
15935ExprResult
15936TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15937 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15938 if (!T)
15939 return ExprError();
15940
15941 if (!getDerived().AlwaysRebuild() &&
15942 T == E->getQueriedTypeSourceInfo())
15943 return E;
15944
15945 ExprResult SubExpr;
15946 {
15947 EnterExpressionEvaluationContext Unevaluated(
15948 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15949 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15950 if (SubExpr.isInvalid())
15951 return ExprError();
15952 }
15953
15954 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15955 SubExpr.get(), E->getEndLoc());
15956}
15957
15958template<typename Derived>
15959ExprResult
15960TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15961 ExprResult SubExpr;
15962 {
15963 EnterExpressionEvaluationContext Unevaluated(
15964 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15965 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15966 if (SubExpr.isInvalid())
15967 return ExprError();
15968
15969 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15970 return E;
15971 }
15972
15973 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15974 SubExpr.get(), E->getEndLoc());
15975}
15976
15977template <typename Derived>
15978ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15979 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15980 TypeSourceInfo **RecoveryTSI) {
15981 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15982 DRE, AddrTaken, RecoveryTSI);
15983
15984 // Propagate both errors and recovered types, which return ExprEmpty.
15985 if (!NewDRE.isUsable())
15986 return NewDRE;
15987
15988 // We got an expr, wrap it up in parens.
15989 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15990 return PE;
15991 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15992 PE->getRParen());
15993}
15994
15995template <typename Derived>
15996ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15997 DependentScopeDeclRefExpr *E) {
15998 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15999 nullptr);
16000}
16001
16002template <typename Derived>
16003ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16004 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
16005 TypeSourceInfo **RecoveryTSI) {
16006 assert(E->getQualifierLoc());
16007 NestedNameSpecifierLoc QualifierLoc =
16008 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
16009 if (!QualifierLoc)
16010 return ExprError();
16011 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16012
16013 // TODO: If this is a conversion-function-id, verify that the
16014 // destination type name (if present) resolves the same way after
16015 // instantiation as it did in the local scope.
16016
16017 DeclarationNameInfo NameInfo =
16018 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
16019 if (!NameInfo.getName())
16020 return ExprError();
16021
16022 if (!E->hasExplicitTemplateArgs()) {
16023 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
16024 // Note: it is sufficient to compare the Name component of NameInfo:
16025 // if name has not changed, DNLoc has not changed either.
16026 NameInfo.getName() == E->getDeclName())
16027 return E;
16028
16029 return getDerived().RebuildDependentScopeDeclRefExpr(
16030 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
16031 IsAddressOfOperand, RecoveryTSI);
16032 }
16033
16034 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16035 if (getDerived().TransformTemplateArguments(
16036 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
16037 return ExprError();
16038
16039 return getDerived().RebuildDependentScopeDeclRefExpr(
16040 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
16041 RecoveryTSI);
16042}
16043
16044template<typename Derived>
16045ExprResult
16046TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
16047 // CXXConstructExprs other than for list-initialization and
16048 // CXXTemporaryObjectExpr are always implicit, so when we have
16049 // a 1-argument construction we just transform that argument.
16050 if (getDerived().AllowSkippingCXXConstructExpr() &&
16051 ((E->getNumArgs() == 1 ||
16052 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
16053 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
16054 !E->isListInitialization()))
16055 return getDerived().TransformInitializer(E->getArg(Arg: 0),
16056 /*DirectInit*/ false);
16057
16058 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
16059
16060 QualType T = getDerived().TransformType(E->getType());
16061 if (T.isNull())
16062 return ExprError();
16063
16064 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16065 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16066 if (!Constructor)
16067 return ExprError();
16068
16069 bool ArgumentChanged = false;
16070 SmallVector<Expr*, 8> Args;
16071 {
16072 EnterExpressionEvaluationContext Context(
16073 getSema(), EnterExpressionEvaluationContext::InitList,
16074 E->isListInitialization());
16075 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
16076 &ArgumentChanged))
16077 return ExprError();
16078 }
16079
16080 if (!getDerived().AlwaysRebuild() &&
16081 T == E->getType() &&
16082 Constructor == E->getConstructor() &&
16083 !ArgumentChanged) {
16084 // Mark the constructor as referenced.
16085 // FIXME: Instantiation-specific
16086 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16087 return E;
16088 }
16089
16090 return getDerived().RebuildCXXConstructExpr(
16091 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
16092 E->hadMultipleCandidates(), E->isListInitialization(),
16093 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
16094 E->getConstructionKind(), E->getParenOrBraceRange());
16095}
16096
16097template<typename Derived>
16098ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
16099 CXXInheritedCtorInitExpr *E) {
16100 QualType T = getDerived().TransformType(E->getType());
16101 if (T.isNull())
16102 return ExprError();
16103
16104 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16105 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16106 if (!Constructor)
16107 return ExprError();
16108
16109 if (!getDerived().AlwaysRebuild() &&
16110 T == E->getType() &&
16111 Constructor == E->getConstructor()) {
16112 // Mark the constructor as referenced.
16113 // FIXME: Instantiation-specific
16114 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16115 return E;
16116 }
16117
16118 return getDerived().RebuildCXXInheritedCtorInitExpr(
16119 T, E->getLocation(), Constructor,
16120 E->constructsVBase(), E->inheritedFromVBase());
16121}
16122
16123/// Transform a C++ temporary-binding expression.
16124///
16125/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
16126/// transform the subexpression and return that.
16127template<typename Derived>
16128ExprResult
16129TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
16130 if (auto *Dtor = E->getTemporary()->getDestructor())
16131 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
16132 Func: const_cast<CXXDestructorDecl *>(Dtor));
16133 return getDerived().TransformExpr(E->getSubExpr());
16134}
16135
16136/// Transform a C++ expression that contains cleanups that should
16137/// be run after the expression is evaluated.
16138///
16139/// Since ExprWithCleanups nodes are implicitly generated, we
16140/// just transform the subexpression and return that.
16141template<typename Derived>
16142ExprResult
16143TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
16144 return getDerived().TransformExpr(E->getSubExpr());
16145}
16146
16147template<typename Derived>
16148ExprResult
16149TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
16150 CXXTemporaryObjectExpr *E) {
16151 TypeSourceInfo *T =
16152 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16153 if (!T)
16154 return ExprError();
16155
16156 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16157 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16158 if (!Constructor)
16159 return ExprError();
16160
16161 bool ArgumentChanged = false;
16162 SmallVector<Expr*, 8> Args;
16163 Args.reserve(N: E->getNumArgs());
16164 {
16165 EnterExpressionEvaluationContext Context(
16166 getSema(), EnterExpressionEvaluationContext::InitList,
16167 E->isListInitialization());
16168 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
16169 ArgChanged: &ArgumentChanged))
16170 return ExprError();
16171
16172 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
16173 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc(),
16174 /*IsExplicit=*/IsExplicit: true);
16175 if (Res.isInvalid())
16176 return ExprError();
16177 Args = {Res.get()};
16178 }
16179 }
16180
16181 if (!getDerived().AlwaysRebuild() &&
16182 T == E->getTypeSourceInfo() &&
16183 Constructor == E->getConstructor() &&
16184 !ArgumentChanged) {
16185 // FIXME: Instantiation-specific
16186 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16187 return SemaRef.MaybeBindToTemporary(E);
16188 }
16189
16190 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
16191 return getDerived().RebuildCXXTemporaryObjectExpr(
16192 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
16193}
16194
16195template<typename Derived>
16196ExprResult
16197TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
16198 // Transform any init-capture expressions before entering the scope of the
16199 // lambda body, because they are not semantically within that scope.
16200 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
16201 struct TransformedInitCapture {
16202 // The location of the ... if the result is retaining a pack expansion.
16203 SourceLocation EllipsisLoc;
16204 // Zero or more expansions of the init-capture.
16205 SmallVector<InitCaptureInfoTy, 4> Expansions;
16206 };
16207 SmallVector<TransformedInitCapture, 4> InitCaptures;
16208 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
16209 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16210 CEnd = E->capture_end();
16211 C != CEnd; ++C) {
16212 if (!E->isInitCapture(Capture: C))
16213 continue;
16214
16215 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
16216 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16217
16218 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
16219 UnsignedOrNone NumExpansions) {
16220 ExprResult NewExprInitResult = getDerived().TransformInitializer(
16221 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
16222
16223 if (NewExprInitResult.isInvalid()) {
16224 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
16225 return;
16226 }
16227 Expr *NewExprInit = NewExprInitResult.get();
16228
16229 QualType NewInitCaptureType =
16230 getSema().buildLambdaInitCaptureInitialization(
16231 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
16232 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
16233 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
16234 VarDecl::CInit,
16235 NewExprInit);
16236 Result.Expansions.push_back(
16237 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
16238 };
16239
16240 // If this is an init-capture pack, consider expanding the pack now.
16241 if (OldVD->isParameterPack()) {
16242 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
16243 ->getTypeLoc()
16244 .castAs<PackExpansionTypeLoc>();
16245 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16246 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
16247
16248 // Determine whether the set of unexpanded parameter packs can and should
16249 // be expanded.
16250 bool Expand = true;
16251 bool RetainExpansion = false;
16252 UnsignedOrNone OrigNumExpansions =
16253 ExpansionTL.getTypePtr()->getNumExpansions();
16254 UnsignedOrNone NumExpansions = OrigNumExpansions;
16255 if (getDerived().TryExpandParameterPacks(
16256 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
16257 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
16258 RetainExpansion, NumExpansions))
16259 return ExprError();
16260 assert(!RetainExpansion && "Should not need to retain expansion after a "
16261 "capture since it cannot be extended");
16262 if (Expand) {
16263 for (unsigned I = 0; I != *NumExpansions; ++I) {
16264 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16265 SubstInitCapture(SourceLocation(), std::nullopt);
16266 }
16267 } else {
16268 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
16269 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
16270 }
16271 } else {
16272 SubstInitCapture(SourceLocation(), std::nullopt);
16273 }
16274 }
16275
16276 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
16277 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
16278
16279 // Create the local class that will describe the lambda.
16280
16281 // FIXME: DependencyKind below is wrong when substituting inside a templated
16282 // context that isn't a DeclContext (such as a variable template), or when
16283 // substituting an unevaluated lambda inside of a function's parameter's type
16284 // - as parameter types are not instantiated from within a function's DC. We
16285 // use evaluation contexts to distinguish the function parameter case.
16286 CXXRecordDecl::LambdaDependencyKind DependencyKind =
16287 CXXRecordDecl::LDK_Unknown;
16288 DeclContext *DC = getSema().CurContext;
16289 // A RequiresExprBodyDecl is not interesting for dependencies.
16290 // For the following case,
16291 //
16292 // template <typename>
16293 // concept C = requires { [] {}; };
16294 //
16295 // template <class F>
16296 // struct Widget;
16297 //
16298 // template <C F>
16299 // struct Widget<F> {};
16300 //
16301 // While we are substituting Widget<F>, the parent of DC would be
16302 // the template specialization itself. Thus, the lambda expression
16303 // will be deemed as dependent even if there are no dependent template
16304 // arguments.
16305 // (A ClassTemplateSpecializationDecl is always a dependent context.)
16306 while (DC->isRequiresExprBody() || isa<CXXExpansionStmtDecl>(Val: DC))
16307 DC = DC->getParent();
16308 if ((getSema().isUnevaluatedContext() ||
16309 getSema().isConstantEvaluatedContext()) &&
16310 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
16311 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
16312 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
16313 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
16314
16315 CXXRecordDecl *OldClass = E->getLambdaClass();
16316 CXXRecordDecl *Class = getSema().createLambdaClosureType(
16317 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
16318 E->getCaptureDefault());
16319 getDerived().transformedLocalDecl(OldClass, {Class});
16320
16321 CXXMethodDecl *NewCallOperator =
16322 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
16323
16324 // Enter the scope of the lambda.
16325 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
16326 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
16327 E->hasExplicitParameters(), E->isMutable());
16328
16329 // Introduce the context of the call operator.
16330 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
16331 /*NewThisContext*/false);
16332
16333 bool Invalid = false;
16334
16335 // Transform captures.
16336 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16337 CEnd = E->capture_end();
16338 C != CEnd; ++C) {
16339 // When we hit the first implicit capture, tell Sema that we've finished
16340 // the list of explicit captures.
16341 if (C->isImplicit())
16342 break;
16343
16344 // Capturing 'this' is trivial.
16345 if (C->capturesThis()) {
16346 // If this is a lambda that is part of a default member initialiser
16347 // and which we're instantiating outside the class that 'this' is
16348 // supposed to refer to, adjust the type of 'this' accordingly.
16349 //
16350 // Otherwise, leave the type of 'this' as-is.
16351 Sema::CXXThisScopeRAII ThisScope(
16352 getSema(),
16353 dyn_cast_if_present<CXXRecordDecl>(
16354 getSema().getFunctionLevelDeclContext()),
16355 Qualifiers());
16356 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16357 /*BuildAndDiagnose*/ true, nullptr,
16358 C->getCaptureKind() == LCK_StarThis);
16359 continue;
16360 }
16361 // Captured expression will be recaptured during captured variables
16362 // rebuilding.
16363 if (C->capturesVLAType())
16364 continue;
16365
16366 // Rebuild init-captures, including the implied field declaration.
16367 if (E->isInitCapture(Capture: C)) {
16368 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
16369
16370 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16371 llvm::SmallVector<Decl*, 4> NewVDs;
16372
16373 for (InitCaptureInfoTy &Info : NewC.Expansions) {
16374 ExprResult Init = Info.first;
16375 QualType InitQualType = Info.second;
16376 if (Init.isInvalid() || InitQualType.isNull()) {
16377 Invalid = true;
16378 break;
16379 }
16380 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
16381 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
16382 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
16383 getSema().CurContext);
16384 if (!NewVD) {
16385 Invalid = true;
16386 break;
16387 }
16388 NewVDs.push_back(Elt: NewVD);
16389 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
16390 // Cases we want to tackle:
16391 // ([C(Pack)] {}, ...)
16392 // But rule out cases e.g.
16393 // [...C = Pack()] {}
16394 if (NewC.EllipsisLoc.isInvalid())
16395 LSI->ContainsUnexpandedParameterPack |=
16396 Init.get()->containsUnexpandedParameterPack();
16397 }
16398
16399 if (Invalid)
16400 break;
16401
16402 getDerived().transformedLocalDecl(OldVD, NewVDs);
16403 continue;
16404 }
16405
16406 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16407
16408 // Determine the capture kind for Sema.
16409 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
16410 : C->getCaptureKind() == LCK_ByCopy
16411 ? TryCaptureKind::ExplicitByVal
16412 : TryCaptureKind::ExplicitByRef;
16413 SourceLocation EllipsisLoc;
16414 if (C->isPackExpansion()) {
16415 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
16416 bool ShouldExpand = false;
16417 bool RetainExpansion = false;
16418 UnsignedOrNone NumExpansions = std::nullopt;
16419 if (getDerived().TryExpandParameterPacks(
16420 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
16421 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16422 RetainExpansion, NumExpansions)) {
16423 Invalid = true;
16424 continue;
16425 }
16426
16427 if (ShouldExpand) {
16428 // The transform has determined that we should perform an expansion;
16429 // transform and capture each of the arguments.
16430 // expansion of the pattern. Do so.
16431 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
16432 for (unsigned I = 0; I != *NumExpansions; ++I) {
16433 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16434 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
16435 getDerived().TransformDecl(C->getLocation(), Pack));
16436 if (!CapturedVar) {
16437 Invalid = true;
16438 continue;
16439 }
16440
16441 // Capture the transformed variable.
16442 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
16443 }
16444
16445 // FIXME: Retain a pack expansion if RetainExpansion is true.
16446
16447 continue;
16448 }
16449
16450 EllipsisLoc = C->getEllipsisLoc();
16451 }
16452
16453 // Transform the captured variable.
16454 auto *CapturedVar = cast_or_null<ValueDecl>(
16455 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16456 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
16457 Invalid = true;
16458 continue;
16459 }
16460
16461 // This is not an init-capture; however it contains an unexpanded pack e.g.
16462 // ([Pack] {}(), ...)
16463 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
16464 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
16465
16466 // Capture the transformed variable.
16467 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
16468 EllipsisLoc);
16469 }
16470 getSema().finishLambdaExplicitCaptures(LSI);
16471
16472 // Transform the template parameters, and add them to the current
16473 // instantiation scope. The null case is handled correctly.
16474 auto TPL = getDerived().TransformTemplateParameterList(
16475 E->getTemplateParameterList());
16476 LSI->GLTemplateParameterList = TPL;
16477 if (TPL) {
16478 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
16479 TPL);
16480 LSI->ContainsUnexpandedParameterPack |=
16481 TPL->containsUnexpandedParameterPack();
16482 }
16483
16484 TypeLocBuilder NewCallOpTLBuilder;
16485 TypeLoc OldCallOpTypeLoc =
16486 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
16487 QualType NewCallOpType =
16488 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
16489 if (NewCallOpType.isNull())
16490 return ExprError();
16491 LSI->ContainsUnexpandedParameterPack |=
16492 NewCallOpType->containsUnexpandedParameterPack();
16493 TypeSourceInfo *NewCallOpTSI =
16494 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16495
16496 // The type may be an AttributedType or some other kind of sugar;
16497 // get the actual underlying FunctionProtoType.
16498 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16499 assert(FPTL && "Not a FunctionProtoType?");
16500
16501 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16502 if (TRC) {
16503 ExprResult E = getDerived().TransformLambdaConstraint(
16504 const_cast<Expr *>(TRC.ConstraintExpr));
16505 if (E.isInvalid())
16506 return E;
16507 TRC.ConstraintExpr = E.get();
16508 }
16509
16510 LSI->BeforeCompoundStatement = false;
16511 getSema().CompleteLambdaCallOperator(
16512 NewCallOperator, E->getCallOperator()->getLocation(),
16513 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16514 E->getCallOperator()->getConstexprKind(),
16515 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16516 E->hasExplicitResultType());
16517
16518 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16519 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16520
16521 {
16522 // Number the lambda for linkage purposes if necessary.
16523 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16524
16525 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16526 if (getDerived().ReplacingOriginal()) {
16527 Numbering = OldClass->getLambdaNumbering();
16528 }
16529
16530 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16531 }
16532
16533 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16534 // evaluation context even if we're not transforming the function body.
16535 getSema().PushExpressionEvaluationContextForFunction(
16536 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16537 E->getCallOperator());
16538
16539 StmtResult Body;
16540 {
16541 Sema::NonSFINAEContext _(getSema());
16542 Sema::CodeSynthesisContext C;
16543 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16544 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16545 getSema().pushCodeSynthesisContext(C);
16546
16547 // Instantiate the body of the lambda expression.
16548 Body = Invalid ? StmtError()
16549 : getDerived().TransformLambdaBody(E, E->getBody());
16550
16551 getSema().popCodeSynthesisContext();
16552 }
16553
16554 // ActOnLambda* will pop the function scope for us.
16555 FuncScopeCleanup.disable();
16556
16557 if (Body.isInvalid()) {
16558 SavedContext.pop();
16559 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16560 /*IsInstantiation=*/true);
16561 return ExprError();
16562 }
16563
16564 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16565 /*IsInstantiation=*/true,
16566 /*RetainFunctionScopeInfo=*/true);
16567 SavedContext.pop();
16568
16569 // Recompute the dependency of the lambda so that we can defer the lambda call
16570 // construction until after we have all the necessary template arguments. For
16571 // example, given
16572 //
16573 // template <class> struct S {
16574 // template <class U>
16575 // using Type = decltype([](U){}(42.0));
16576 // };
16577 // void foo() {
16578 // using T = S<int>::Type<float>;
16579 // ^~~~~~
16580 // }
16581 //
16582 // We would end up here from instantiating S<int> when ensuring its
16583 // completeness. That would transform the lambda call expression regardless of
16584 // the absence of the corresponding argument for U.
16585 //
16586 // Going ahead with unsubstituted type U makes things worse: we would soon
16587 // compare the argument type (which is float) against the parameter U
16588 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16589 // error suggesting unmatched types 'U' and 'float'!
16590 //
16591 // That said, everything will be fine if we defer that semantic checking.
16592 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16593 // dependent. Since the CallExpr's dependency boils down to the lambda's
16594 // dependency in this case, we can harness that by recomputing the dependency
16595 // from the instantiation arguments.
16596 //
16597 // FIXME: Creating the type of a lambda requires us to have a dependency
16598 // value, which happens before its substitution. We update its dependency
16599 // *after* the substitution in case we can't decide the dependency
16600 // so early, e.g. because we want to see if any of the *substituted*
16601 // parameters are dependent.
16602 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16603 Class->setLambdaDependencyKind(DependencyKind);
16604
16605 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16606 Body.get()->getEndLoc(), LSI);
16607}
16608
16609template<typename Derived>
16610StmtResult
16611TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16612 return TransformStmt(S);
16613}
16614
16615template<typename Derived>
16616StmtResult
16617TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16618 // Transform captures.
16619 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16620 CEnd = E->capture_end();
16621 C != CEnd; ++C) {
16622 // When we hit the first implicit capture, tell Sema that we've finished
16623 // the list of explicit captures.
16624 if (!C->isImplicit())
16625 continue;
16626
16627 // Capturing 'this' is trivial.
16628 if (C->capturesThis()) {
16629 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16630 /*BuildAndDiagnose*/ true, nullptr,
16631 C->getCaptureKind() == LCK_StarThis);
16632 continue;
16633 }
16634 // Captured expression will be recaptured during captured variables
16635 // rebuilding.
16636 if (C->capturesVLAType())
16637 continue;
16638
16639 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16640 assert(!E->isInitCapture(C) && "implicit init-capture?");
16641
16642 // Transform the captured variable.
16643 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16644 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16645 if (!CapturedVar || CapturedVar->isInvalidDecl())
16646 return StmtError();
16647
16648 // Capture the transformed variable.
16649 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16650 }
16651
16652 return S;
16653}
16654
16655template<typename Derived>
16656ExprResult
16657TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16658 CXXUnresolvedConstructExpr *E) {
16659 TypeSourceInfo *T =
16660 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16661 if (!T)
16662 return ExprError();
16663
16664 bool ArgumentChanged = false;
16665 SmallVector<Expr*, 8> Args;
16666 Args.reserve(N: E->getNumArgs());
16667 {
16668 EnterExpressionEvaluationContext Context(
16669 getSema(), EnterExpressionEvaluationContext::InitList,
16670 E->isListInitialization());
16671 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16672 &ArgumentChanged))
16673 return ExprError();
16674 }
16675
16676 if (!getDerived().AlwaysRebuild() &&
16677 T == E->getTypeSourceInfo() &&
16678 !ArgumentChanged)
16679 return E;
16680
16681 // FIXME: we're faking the locations of the commas
16682 return getDerived().RebuildCXXUnresolvedConstructExpr(
16683 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16684}
16685
16686template <typename Derived>
16687ExprResult TreeTransform<Derived>::TransformDependentTemplateIdExpr(
16688 DependentTemplateIdExpr *E) {
16689
16690 TemplateName Name = getDerived().TransformConceptTemplateName(
16691 E->getTemplateName(), E->getNameLoc());
16692 if (Name.isNull())
16693 return ExprError();
16694
16695 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16696 if (getDerived().TransformTemplateArguments(
16697 E->template_arguments().data(), E->getNumTemplateArgs(), TransArgs))
16698 return ExprError();
16699
16700 TemplateDecl *TD = Name.getAsTemplateDecl();
16701 if (!TD)
16702 return SemaRef.CheckVarOrConceptTemplateTemplateId(NameInfo: E->getNameInfo(), Template: Name,
16703 TemplateArgs: &TransArgs);
16704
16705 CXXScopeSpec SS;
16706
16707 LookupResult R(SemaRef, E->getNameInfo(), Sema::LookupOrdinaryName);
16708 R.addDecl(D: TD);
16709 R.resolveKind();
16710 return getDerived().RebuildTemplateIdExpr(
16711 SS, /*Template Keyword=*/SourceLocation(), R,
16712 /*RequiresADL=*/false, &TransArgs);
16713}
16714
16715template<typename Derived>
16716ExprResult
16717TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16718 CXXDependentScopeMemberExpr *E) {
16719 // Transform the base of the expression.
16720 ExprResult Base((Expr*) nullptr);
16721 Expr *OldBase;
16722 QualType BaseType;
16723 QualType ObjectType;
16724 if (!E->isImplicitAccess()) {
16725 OldBase = E->getBase();
16726 Base = getDerived().TransformExpr(OldBase);
16727 if (Base.isInvalid())
16728 return ExprError();
16729
16730 // Start the member reference and compute the object's type.
16731 ParsedType ObjectTy;
16732 bool MayBePseudoDestructor = false;
16733 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16734 OpLoc: E->getOperatorLoc(),
16735 OpKind: E->isArrow()? tok::arrow : tok::period,
16736 ObjectType&: ObjectTy,
16737 MayBePseudoDestructor);
16738 if (Base.isInvalid())
16739 return ExprError();
16740
16741 ObjectType = ObjectTy.get();
16742 BaseType = ((Expr*) Base.get())->getType();
16743 } else {
16744 OldBase = nullptr;
16745 BaseType = getDerived().TransformType(E->getBaseType());
16746 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16747 }
16748
16749 // Transform the first part of the nested-name-specifier that qualifies
16750 // the member name.
16751 NamedDecl *FirstQualifierInScope
16752 = getDerived().TransformFirstQualifierInScope(
16753 E->getFirstQualifierFoundInScope(),
16754 E->getQualifierLoc().getBeginLoc());
16755
16756 NestedNameSpecifierLoc QualifierLoc;
16757 if (E->getQualifier()) {
16758 QualifierLoc
16759 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16760 ObjectType,
16761 FirstQualifierInScope);
16762 if (!QualifierLoc)
16763 return ExprError();
16764 }
16765
16766 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16767
16768 // TODO: If this is a conversion-function-id, verify that the
16769 // destination type name (if present) resolves the same way after
16770 // instantiation as it did in the local scope.
16771
16772 DeclarationNameInfo NameInfo
16773 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16774 if (!NameInfo.getName())
16775 return ExprError();
16776
16777 if (!E->hasExplicitTemplateArgs()) {
16778 // This is a reference to a member without an explicitly-specified
16779 // template argument list. Optimize for this common case.
16780 if (!getDerived().AlwaysRebuild() &&
16781 Base.get() == OldBase &&
16782 BaseType == E->getBaseType() &&
16783 QualifierLoc == E->getQualifierLoc() &&
16784 NameInfo.getName() == E->getMember() &&
16785 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16786 return E;
16787
16788 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16789 BaseType,
16790 E->isArrow(),
16791 E->getOperatorLoc(),
16792 QualifierLoc,
16793 TemplateKWLoc,
16794 FirstQualifierInScope,
16795 NameInfo,
16796 /*TemplateArgs*/nullptr);
16797 }
16798
16799 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16800 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16801 E->getNumTemplateArgs(),
16802 TransArgs))
16803 return ExprError();
16804
16805 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16806 BaseType,
16807 E->isArrow(),
16808 E->getOperatorLoc(),
16809 QualifierLoc,
16810 TemplateKWLoc,
16811 FirstQualifierInScope,
16812 NameInfo,
16813 &TransArgs);
16814}
16815
16816template <typename Derived>
16817ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16818 UnresolvedMemberExpr *Old) {
16819 // Transform the base of the expression.
16820 ExprResult Base((Expr *)nullptr);
16821 QualType BaseType;
16822 if (!Old->isImplicitAccess()) {
16823 Base = getDerived().TransformExpr(Old->getBase());
16824 if (Base.isInvalid())
16825 return ExprError();
16826 Base =
16827 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16828 if (Base.isInvalid())
16829 return ExprError();
16830 BaseType = Base.get()->getType();
16831 } else {
16832 BaseType = getDerived().TransformType(Old->getBaseType());
16833 }
16834
16835 NestedNameSpecifierLoc QualifierLoc;
16836 if (Old->getQualifierLoc()) {
16837 QualifierLoc =
16838 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16839 if (!QualifierLoc)
16840 return ExprError();
16841 }
16842
16843 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16844
16845 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16846
16847 // Transform the declaration set.
16848 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16849 return ExprError();
16850
16851 // Determine the naming class.
16852 if (Old->getNamingClass()) {
16853 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16854 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16855 if (!NamingClass)
16856 return ExprError();
16857
16858 R.setNamingClass(NamingClass);
16859 }
16860
16861 TemplateArgumentListInfo TransArgs;
16862 if (Old->hasExplicitTemplateArgs()) {
16863 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16864 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16865 if (getDerived().TransformTemplateArguments(
16866 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16867 return ExprError();
16868 }
16869
16870 // FIXME: to do this check properly, we will need to preserve the
16871 // first-qualifier-in-scope here, just in case we had a dependent
16872 // base (and therefore couldn't do the check) and a
16873 // nested-name-qualifier (and therefore could do the lookup).
16874 NamedDecl *FirstQualifierInScope = nullptr;
16875
16876 return getDerived().RebuildUnresolvedMemberExpr(
16877 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16878 TemplateKWLoc, FirstQualifierInScope, R,
16879 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16880}
16881
16882template<typename Derived>
16883ExprResult
16884TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16885 EnterExpressionEvaluationContext Unevaluated(
16886 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16887 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16888 if (SubExpr.isInvalid())
16889 return ExprError();
16890
16891 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16892 return E;
16893
16894 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16895}
16896
16897template<typename Derived>
16898ExprResult
16899TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16900 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16901 if (Pattern.isInvalid())
16902 return ExprError();
16903
16904 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16905 return E;
16906
16907 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16908 E->getNumExpansions());
16909}
16910
16911template <typename Derived>
16912UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16913 ArrayRef<TemplateArgument> PackArgs) {
16914 UnsignedOrNone Result = 0u;
16915 for (const TemplateArgument &Arg : PackArgs) {
16916 if (!Arg.isPackExpansion()) {
16917 Result = *Result + 1;
16918 continue;
16919 }
16920
16921 TemplateArgumentLoc ArgLoc;
16922 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16923
16924 // Find the pattern of the pack expansion.
16925 SourceLocation Ellipsis;
16926 UnsignedOrNone OrigNumExpansions = std::nullopt;
16927 TemplateArgumentLoc Pattern =
16928 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16929 OrigNumExpansions);
16930
16931 // Substitute under the pack expansion. Do not expand the pack (yet).
16932 TemplateArgumentLoc OutPattern;
16933 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16934 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16935 /*Uneval*/ true))
16936 return 1u;
16937
16938 // See if we can determine the number of arguments from the result.
16939 UnsignedOrNone NumExpansions =
16940 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16941 if (!NumExpansions) {
16942 // No: we must be in an alias template expansion, and we're going to
16943 // need to actually expand the packs.
16944 Result = std::nullopt;
16945 break;
16946 }
16947
16948 Result = *Result + *NumExpansions;
16949 }
16950 return Result;
16951}
16952
16953template<typename Derived>
16954ExprResult
16955TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16956 // If E is not value-dependent, then nothing will change when we transform it.
16957 // Note: This is an instantiation-centric view.
16958 if (!E->isValueDependent())
16959 return E;
16960
16961 EnterExpressionEvaluationContext Unevaluated(
16962 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16963
16964 ArrayRef<TemplateArgument> PackArgs;
16965 TemplateArgument ArgStorage;
16966
16967 // Find the argument list to transform.
16968 if (E->isPartiallySubstituted()) {
16969 PackArgs = E->getPartialArguments();
16970 } else if (E->isValueDependent()) {
16971 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16972 bool ShouldExpand = false;
16973 bool RetainExpansion = false;
16974 UnsignedOrNone NumExpansions = std::nullopt;
16975 if (getDerived().TryExpandParameterPacks(
16976 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16977 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16978 RetainExpansion, NumExpansions))
16979 return ExprError();
16980
16981 // If we need to expand the pack, build a template argument from it and
16982 // expand that.
16983 if (ShouldExpand) {
16984 auto *Pack = E->getPack();
16985 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16986 ArgStorage = getSema().Context.getPackExpansionType(
16987 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16988 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16989 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16990 } else {
16991 auto *VD = cast<ValueDecl>(Val: Pack);
16992 ExprResult DRE = getSema().BuildDeclRefExpr(
16993 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16994 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16995 E->getPackLoc());
16996 if (DRE.isInvalid())
16997 return ExprError();
16998 ArgStorage = TemplateArgument(
16999 new (getSema().Context)
17000 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
17001 /*IsCanonical=*/false);
17002 }
17003 PackArgs = ArgStorage;
17004 }
17005 }
17006
17007 // If we're not expanding the pack, just transform the decl.
17008 if (!PackArgs.size()) {
17009 auto *Pack = cast_or_null<NamedDecl>(
17010 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
17011 if (!Pack)
17012 return ExprError();
17013 return getDerived().RebuildSizeOfPackExpr(
17014 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
17015 std::nullopt, {});
17016 }
17017
17018 // Try to compute the result without performing a partial substitution.
17019 UnsignedOrNone Result =
17020 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
17021
17022 // Common case: we could determine the number of expansions without
17023 // substituting.
17024 if (Result)
17025 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
17026 E->getPackLoc(),
17027 E->getRParenLoc(), *Result, {});
17028
17029 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
17030 E->getPackLoc());
17031 {
17032 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
17033 typedef TemplateArgumentLocInventIterator<
17034 Derived, const TemplateArgument*> PackLocIterator;
17035 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
17036 PackLocIterator(*this, PackArgs.end()),
17037 TransformedPackArgs, /*Uneval*/true))
17038 return ExprError();
17039 }
17040
17041 // Check whether we managed to fully-expand the pack.
17042 // FIXME: Is it possible for us to do so and not hit the early exit path?
17043 SmallVector<TemplateArgument, 8> Args;
17044 bool PartialSubstitution = false;
17045 for (auto &Loc : TransformedPackArgs.arguments()) {
17046 Args.push_back(Elt: Loc.getArgument());
17047 if (Loc.getArgument().isPackExpansion())
17048 PartialSubstitution = true;
17049 }
17050
17051 if (PartialSubstitution)
17052 return getDerived().RebuildSizeOfPackExpr(
17053 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17054 std::nullopt, Args);
17055
17056 return getDerived().RebuildSizeOfPackExpr(
17057 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17058 /*Length=*/static_cast<unsigned>(Args.size()),
17059 /*PartialArgs=*/{});
17060}
17061
17062template <typename Derived>
17063ExprResult
17064TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
17065 if (!E->isValueDependent())
17066 return E;
17067
17068 // Transform the index
17069 ExprResult IndexExpr;
17070 {
17071 EnterExpressionEvaluationContext ConstantContext(
17072 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
17073 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
17074 if (IndexExpr.isInvalid())
17075 return ExprError();
17076 }
17077
17078 SmallVector<Expr *, 5> ExpandedExprs;
17079 bool FullySubstituted = true;
17080 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
17081 Expr *Pattern = E->getPackIdExpression();
17082 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17083 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
17084 Unexpanded);
17085 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17086
17087 // Determine whether the set of unexpanded parameter packs can and should
17088 // be expanded.
17089 bool ShouldExpand = true;
17090 bool RetainExpansion = false;
17091 UnsignedOrNone OrigNumExpansions = std::nullopt,
17092 NumExpansions = std::nullopt;
17093 if (getDerived().TryExpandParameterPacks(
17094 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17095 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
17096 RetainExpansion, NumExpansions))
17097 return true;
17098 if (!ShouldExpand) {
17099 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17100 ExprResult Pack = getDerived().TransformExpr(Pattern);
17101 if (Pack.isInvalid())
17102 return ExprError();
17103 return getDerived().RebuildPackIndexingExpr(
17104 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
17105 {}, /*FullySubstituted=*/false);
17106 }
17107 for (unsigned I = 0; I != *NumExpansions; ++I) {
17108 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17109 ExprResult Out = getDerived().TransformExpr(Pattern);
17110 if (Out.isInvalid())
17111 return true;
17112 if (Out.get()->containsUnexpandedParameterPack()) {
17113 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17114 OrigNumExpansions);
17115 if (Out.isInvalid())
17116 return true;
17117 FullySubstituted = false;
17118 }
17119 ExpandedExprs.push_back(Elt: Out.get());
17120 }
17121 // If we're supposed to retain a pack expansion, do so by temporarily
17122 // forgetting the partially-substituted parameter pack.
17123 if (RetainExpansion) {
17124 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17125
17126 ExprResult Out = getDerived().TransformExpr(Pattern);
17127 if (Out.isInvalid())
17128 return true;
17129
17130 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17131 OrigNumExpansions);
17132 if (Out.isInvalid())
17133 return true;
17134 FullySubstituted = false;
17135 ExpandedExprs.push_back(Elt: Out.get());
17136 }
17137 } else if (!E->expandsToEmptyPack()) {
17138 if (getDerived().TransformExprs(E->getExpressions().data(),
17139 E->getExpressions().size(), false,
17140 ExpandedExprs))
17141 return ExprError();
17142 }
17143
17144 return getDerived().RebuildPackIndexingExpr(
17145 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
17146 IndexExpr.get(), ExpandedExprs, FullySubstituted);
17147}
17148
17149template <typename Derived>
17150ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
17151 SubstNonTypeTemplateParmPackExpr *E) {
17152 if (!getSema().ArgPackSubstIndex)
17153 // We aren't expanding the parameter pack, so just return ourselves.
17154 return E;
17155
17156 TemplateArgument Pack = E->getArgumentPack();
17157 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
17158 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17159 E->getAssociatedDecl(), E->getParameterPack()->getPosition(),
17160 E->getParameterPack()->getType(), E->getParameterPackLocation(), Arg,
17161 SemaRef.getPackIndex(Pack), E->getFinal());
17162}
17163
17164template <typename Derived>
17165ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
17166 SubstNonTypeTemplateParmExpr *E) {
17167 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
17168
17169 // Insert a constant-evaluated context for the transform.
17170 // Otherwise, when a normalized constraint places the replacement inside
17171 // an unevaluated operand (e.g. decltype), entities it refers to are not
17172 // odr-used, and the constant evaluation performed by CheckTemplateArgument
17173 // below can spuriously fail for otherwise valid replacements,
17174 // e.g. when a call materializes a function parameter of class type whose
17175 // special members were never instantiated.
17176 EnterExpressionEvaluationContext ConstantEvaluated(
17177 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
17178 Sema::ReuseLambdaContextDecl,
17179 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
17180
17181 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
17182 if (Replacement.isInvalid())
17183 return true;
17184
17185 Decl *AssociatedDecl =
17186 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
17187 if (!AssociatedDecl)
17188 return true;
17189
17190 QualType ParamType = TransformType(E->getParameterType());
17191 if (ParamType.isNull())
17192 return true;
17193
17194 if (Replacement.get() == OrigReplacement &&
17195 AssociatedDecl == E->getAssociatedDecl() &&
17196 ParamType == E->getParameterType())
17197 return E;
17198
17199 if (Replacement.get() != OrigReplacement ||
17200 ParamType != E->getParameterType()) {
17201 auto *Param = cast<NonTypeTemplateParmDecl>(Val: std::get<0>(
17202 t: getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex())));
17203 // When transforming the replacement expression previously, all Sema
17204 // specific annotations, such as implicit casts, are discarded. Calling the
17205 // corresponding sema action is necessary to recover those. Otherwise,
17206 // equivalency of the result would be lost.
17207 TemplateArgument SugaredConverted, CanonicalConverted;
17208 Replacement = SemaRef.CheckTemplateArgument(
17209 Param, InstantiatedParamType: ParamType, Arg: Replacement.get(), SugaredConverted,
17210 CanonicalConverted,
17211 /*StrictCheck=*/StrictCheck: false, CTAK: Sema::CTAK_Specified);
17212 if (Replacement.isInvalid())
17213 return true;
17214 } else {
17215 // Otherwise, the same expression would have been produced.
17216 Replacement = E->getReplacement();
17217 }
17218
17219 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17220 AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(),
17221 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
17222 E->getPackIndex(), E->getFinal());
17223}
17224
17225template<typename Derived>
17226ExprResult
17227TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
17228 // Default behavior is to do nothing with this transformation.
17229 return E;
17230}
17231
17232template<typename Derived>
17233ExprResult
17234TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
17235 MaterializeTemporaryExpr *E) {
17236 return getDerived().TransformExpr(E->getSubExpr());
17237}
17238
17239template<typename Derived>
17240ExprResult
17241TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
17242 UnresolvedLookupExpr *Callee = nullptr;
17243 if (Expr *OldCallee = E->getCallee()) {
17244 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
17245 if (CalleeResult.isInvalid())
17246 return ExprError();
17247 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
17248 }
17249
17250 Expr *Pattern = E->getPattern();
17251
17252 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17253 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
17254 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17255
17256 // Determine whether the set of unexpanded parameter packs can and should
17257 // be expanded.
17258 bool Expand = true;
17259 bool RetainExpansion = false;
17260 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
17261 NumExpansions = OrigNumExpansions;
17262 if (getDerived().TryExpandParameterPacks(
17263 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17264 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17265 NumExpansions))
17266 return true;
17267
17268 if (!Expand) {
17269 // Do not expand any packs here, just transform and rebuild a fold
17270 // expression.
17271 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17272
17273 ExprResult LHS =
17274 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
17275 if (LHS.isInvalid())
17276 return true;
17277
17278 ExprResult RHS =
17279 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
17280 if (RHS.isInvalid())
17281 return true;
17282
17283 if (!getDerived().AlwaysRebuild() &&
17284 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
17285 return E;
17286
17287 return getDerived().RebuildCXXFoldExpr(
17288 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
17289 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
17290 }
17291
17292 // Formally a fold expression expands to nested parenthesized expressions.
17293 // Enforce this limit to avoid creating trees so deep we can't safely traverse
17294 // them.
17295 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
17296 SemaRef.Diag(Loc: E->getEllipsisLoc(),
17297 DiagID: clang::diag::err_fold_expression_limit_exceeded)
17298 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
17299 << E->getSourceRange();
17300 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
17301 return ExprError();
17302 }
17303
17304 // The transform has determined that we should perform an elementwise
17305 // expansion of the pattern. Do so.
17306 ExprResult Result = getDerived().TransformExpr(E->getInit());
17307 if (Result.isInvalid())
17308 return true;
17309 bool LeftFold = E->isLeftFold();
17310
17311 // If we're retaining an expansion for a right fold, it is the innermost
17312 // component and takes the init (if any).
17313 if (!LeftFold && RetainExpansion) {
17314 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17315
17316 ExprResult Out = getDerived().TransformExpr(Pattern);
17317 if (Out.isInvalid())
17318 return true;
17319
17320 Result = getDerived().RebuildCXXFoldExpr(
17321 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
17322 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
17323 if (Result.isInvalid())
17324 return true;
17325 }
17326
17327 bool WarnedOnComparison = false;
17328 for (unsigned I = 0; I != *NumExpansions; ++I) {
17329 Sema::ArgPackSubstIndexRAII SubstIndex(
17330 getSema(), LeftFold ? I : *NumExpansions - I - 1);
17331 ExprResult Out = getDerived().TransformExpr(Pattern);
17332 if (Out.isInvalid())
17333 return true;
17334
17335 if (Out.get()->containsUnexpandedParameterPack()) {
17336 // We still have a pack; retain a pack expansion for this slice.
17337 Result = getDerived().RebuildCXXFoldExpr(
17338 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
17339 E->getOperator(), E->getEllipsisLoc(),
17340 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
17341 OrigNumExpansions);
17342 } else if (Result.isUsable()) {
17343 // We've got down to a single element; build a binary operator.
17344 Expr *LHS = LeftFold ? Result.get() : Out.get();
17345 Expr *RHS = LeftFold ? Out.get() : Result.get();
17346 if (Callee) {
17347 UnresolvedSet<16> Functions;
17348 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
17349 Result = getDerived().RebuildCXXOperatorCallExpr(
17350 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
17351 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
17352 Functions, LHS, RHS);
17353 } else {
17354 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
17355 E->getOperator(), LHS, RHS,
17356 /*ForFoldExpresion=*/true);
17357 if (!WarnedOnComparison && Result.isUsable()) {
17358 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
17359 BO && BO->isComparisonOp()) {
17360 WarnedOnComparison = true;
17361 SemaRef.Diag(Loc: BO->getBeginLoc(),
17362 DiagID: diag::warn_comparison_in_fold_expression)
17363 << BO->getOpcodeStr();
17364 }
17365 }
17366 }
17367 } else
17368 Result = Out;
17369
17370 if (Result.isInvalid())
17371 return true;
17372 }
17373
17374 // If we're retaining an expansion for a left fold, it is the outermost
17375 // component and takes the complete expansion so far as its init (if any).
17376 if (LeftFold && RetainExpansion) {
17377 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17378
17379 ExprResult Out = getDerived().TransformExpr(Pattern);
17380 if (Out.isInvalid())
17381 return true;
17382
17383 Result = getDerived().RebuildCXXFoldExpr(
17384 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
17385 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
17386 if (Result.isInvalid())
17387 return true;
17388 }
17389
17390 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
17391 PE->setIsProducedByFoldExpansion();
17392
17393 // If we had no init and an empty pack, and we're not retaining an expansion,
17394 // then produce a fallback value or error.
17395 if (Result.isUnset())
17396 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
17397 E->getOperator());
17398 return Result;
17399}
17400
17401template <typename Derived>
17402ExprResult
17403TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
17404 SmallVector<Expr *, 4> TransformedInits;
17405 ArrayRef<Expr *> InitExprs = E->getInitExprs();
17406
17407 QualType T = getDerived().TransformType(E->getType());
17408
17409 bool ArgChanged = false;
17410
17411 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
17412 TransformedInits, &ArgChanged))
17413 return ExprError();
17414
17415 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
17416 return E;
17417
17418 return getDerived().RebuildCXXParenListInitExpr(
17419 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
17420 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
17421}
17422
17423template<typename Derived>
17424ExprResult
17425TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
17426 CXXStdInitializerListExpr *E) {
17427 return getDerived().TransformExpr(E->getSubExpr());
17428}
17429
17430template<typename Derived>
17431ExprResult
17432TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
17433 return SemaRef.MaybeBindToTemporary(E);
17434}
17435
17436template<typename Derived>
17437ExprResult
17438TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
17439 return E;
17440}
17441
17442template<typename Derived>
17443ExprResult
17444TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
17445 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
17446 if (SubExpr.isInvalid())
17447 return ExprError();
17448
17449 if (!getDerived().AlwaysRebuild() &&
17450 SubExpr.get() == E->getSubExpr())
17451 return E;
17452
17453 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
17454}
17455
17456template<typename Derived>
17457ExprResult
17458TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
17459 // Transform each of the elements.
17460 SmallVector<Expr *, 8> Elements;
17461 bool ArgChanged = false;
17462 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
17463 /*IsCall=*/false, Elements, &ArgChanged))
17464 return ExprError();
17465
17466 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17467 return SemaRef.MaybeBindToTemporary(E);
17468
17469 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
17470 Elements.data(),
17471 Elements.size());
17472}
17473
17474template<typename Derived>
17475ExprResult
17476TreeTransform<Derived>::TransformObjCDictionaryLiteral(
17477 ObjCDictionaryLiteral *E) {
17478 // Transform each of the elements.
17479 SmallVector<ObjCDictionaryElement, 8> Elements;
17480 bool ArgChanged = false;
17481 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
17482 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
17483
17484 if (OrigElement.isPackExpansion()) {
17485 // This key/value element is a pack expansion.
17486 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17487 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
17488 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
17489 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17490
17491 // Determine whether the set of unexpanded parameter packs can
17492 // and should be expanded.
17493 bool Expand = true;
17494 bool RetainExpansion = false;
17495 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
17496 UnsignedOrNone NumExpansions = OrigNumExpansions;
17497 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
17498 OrigElement.Value->getEndLoc());
17499 if (getDerived().TryExpandParameterPacks(
17500 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
17501 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17502 NumExpansions))
17503 return ExprError();
17504
17505 if (!Expand) {
17506 // The transform has determined that we should perform a simple
17507 // transformation on the pack expansion, producing another pack
17508 // expansion.
17509 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17510 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17511 if (Key.isInvalid())
17512 return ExprError();
17513
17514 if (Key.get() != OrigElement.Key)
17515 ArgChanged = true;
17516
17517 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17518 if (Value.isInvalid())
17519 return ExprError();
17520
17521 if (Value.get() != OrigElement.Value)
17522 ArgChanged = true;
17523
17524 ObjCDictionaryElement Expansion = {
17525 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
17526 };
17527 Elements.push_back(Elt: Expansion);
17528 continue;
17529 }
17530
17531 // Record right away that the argument was changed. This needs
17532 // to happen even if the array expands to nothing.
17533 ArgChanged = true;
17534
17535 // The transform has determined that we should perform an elementwise
17536 // expansion of the pattern. Do so.
17537 for (unsigned I = 0; I != *NumExpansions; ++I) {
17538 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17539 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17540 if (Key.isInvalid())
17541 return ExprError();
17542
17543 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17544 if (Value.isInvalid())
17545 return ExprError();
17546
17547 ObjCDictionaryElement Element = {
17548 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17549 };
17550
17551 // If any unexpanded parameter packs remain, we still have a
17552 // pack expansion.
17553 // FIXME: Can this really happen?
17554 if (Key.get()->containsUnexpandedParameterPack() ||
17555 Value.get()->containsUnexpandedParameterPack())
17556 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17557
17558 Elements.push_back(Elt: Element);
17559 }
17560
17561 // FIXME: Retain a pack expansion if RetainExpansion is true.
17562
17563 // We've finished with this pack expansion.
17564 continue;
17565 }
17566
17567 // Transform and check key.
17568 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17569 if (Key.isInvalid())
17570 return ExprError();
17571
17572 if (Key.get() != OrigElement.Key)
17573 ArgChanged = true;
17574
17575 // Transform and check value.
17576 ExprResult Value
17577 = getDerived().TransformExpr(OrigElement.Value);
17578 if (Value.isInvalid())
17579 return ExprError();
17580
17581 if (Value.get() != OrigElement.Value)
17582 ArgChanged = true;
17583
17584 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17585 .NumExpansions: std::nullopt};
17586 Elements.push_back(Elt: Element);
17587 }
17588
17589 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17590 return SemaRef.MaybeBindToTemporary(E);
17591
17592 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17593 Elements);
17594}
17595
17596template<typename Derived>
17597ExprResult
17598TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17599 TypeSourceInfo *EncodedTypeInfo
17600 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17601 if (!EncodedTypeInfo)
17602 return ExprError();
17603
17604 if (!getDerived().AlwaysRebuild() &&
17605 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17606 return E;
17607
17608 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17609 EncodedTypeInfo,
17610 E->getRParenLoc());
17611}
17612
17613template<typename Derived>
17614ExprResult TreeTransform<Derived>::
17615TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17616 // This is a kind of implicit conversion, and it needs to get dropped
17617 // and recomputed for the same general reasons that ImplicitCastExprs
17618 // do, as well a more specific one: this expression is only valid when
17619 // it appears *immediately* as an argument expression.
17620 return getDerived().TransformExpr(E->getSubExpr());
17621}
17622
17623template<typename Derived>
17624ExprResult TreeTransform<Derived>::
17625TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17626 TypeSourceInfo *TSInfo
17627 = getDerived().TransformType(E->getTypeInfoAsWritten());
17628 if (!TSInfo)
17629 return ExprError();
17630
17631 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17632 if (Result.isInvalid())
17633 return ExprError();
17634
17635 if (!getDerived().AlwaysRebuild() &&
17636 TSInfo == E->getTypeInfoAsWritten() &&
17637 Result.get() == E->getSubExpr())
17638 return E;
17639
17640 return SemaRef.ObjC().BuildObjCBridgedCast(
17641 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17642 SubExpr: Result.get());
17643}
17644
17645template <typename Derived>
17646ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17647 ObjCAvailabilityCheckExpr *E) {
17648 return E;
17649}
17650
17651template<typename Derived>
17652ExprResult
17653TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17654 // Transform arguments.
17655 bool ArgChanged = false;
17656 SmallVector<Expr*, 8> Args;
17657 Args.reserve(N: E->getNumArgs());
17658 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17659 &ArgChanged))
17660 return ExprError();
17661
17662 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17663 // Class message: transform the receiver type.
17664 TypeSourceInfo *ReceiverTypeInfo
17665 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17666 if (!ReceiverTypeInfo)
17667 return ExprError();
17668
17669 // If nothing changed, just retain the existing message send.
17670 if (!getDerived().AlwaysRebuild() &&
17671 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17672 return SemaRef.MaybeBindToTemporary(E);
17673
17674 // Build a new class message send.
17675 SmallVector<SourceLocation, 16> SelLocs;
17676 E->getSelectorLocs(SelLocs);
17677 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17678 E->getSelector(),
17679 SelLocs,
17680 E->getMethodDecl(),
17681 E->getLeftLoc(),
17682 Args,
17683 E->getRightLoc());
17684 }
17685 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17686 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17687 if (!E->getMethodDecl())
17688 return ExprError();
17689
17690 // Build a new class message send to 'super'.
17691 SmallVector<SourceLocation, 16> SelLocs;
17692 E->getSelectorLocs(SelLocs);
17693 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17694 E->getSelector(),
17695 SelLocs,
17696 E->getReceiverType(),
17697 E->getMethodDecl(),
17698 E->getLeftLoc(),
17699 Args,
17700 E->getRightLoc());
17701 }
17702
17703 // Instance message: transform the receiver
17704 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17705 "Only class and instance messages may be instantiated");
17706 ExprResult Receiver
17707 = getDerived().TransformExpr(E->getInstanceReceiver());
17708 if (Receiver.isInvalid())
17709 return ExprError();
17710
17711 // If nothing changed, just retain the existing message send.
17712 if (!getDerived().AlwaysRebuild() &&
17713 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17714 return SemaRef.MaybeBindToTemporary(E);
17715
17716 // Build a new instance message send.
17717 SmallVector<SourceLocation, 16> SelLocs;
17718 E->getSelectorLocs(SelLocs);
17719 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17720 E->getSelector(),
17721 SelLocs,
17722 E->getMethodDecl(),
17723 E->getLeftLoc(),
17724 Args,
17725 E->getRightLoc());
17726}
17727
17728template<typename Derived>
17729ExprResult
17730TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17731 return E;
17732}
17733
17734template<typename Derived>
17735ExprResult
17736TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17737 return E;
17738}
17739
17740template<typename Derived>
17741ExprResult
17742TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17743 // Transform the base expression.
17744 ExprResult Base = getDerived().TransformExpr(E->getBase());
17745 if (Base.isInvalid())
17746 return ExprError();
17747
17748 // We don't need to transform the ivar; it will never change.
17749
17750 // If nothing changed, just retain the existing expression.
17751 if (!getDerived().AlwaysRebuild() &&
17752 Base.get() == E->getBase())
17753 return E;
17754
17755 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17756 E->getLocation(),
17757 E->isArrow(), E->isFreeIvar());
17758}
17759
17760template<typename Derived>
17761ExprResult
17762TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17763 // 'super' and types never change. Property never changes. Just
17764 // retain the existing expression.
17765 if (!E->isObjectReceiver())
17766 return E;
17767
17768 // Transform the base expression.
17769 ExprResult Base = getDerived().TransformExpr(E->getBase());
17770 if (Base.isInvalid())
17771 return ExprError();
17772
17773 // We don't need to transform the property; it will never change.
17774
17775 // If nothing changed, just retain the existing expression.
17776 if (!getDerived().AlwaysRebuild() &&
17777 Base.get() == E->getBase())
17778 return E;
17779
17780 if (E->isExplicitProperty())
17781 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17782 E->getExplicitProperty(),
17783 E->getLocation());
17784
17785 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17786 SemaRef.Context.PseudoObjectTy,
17787 E->getImplicitPropertyGetter(),
17788 E->getImplicitPropertySetter(),
17789 E->getLocation());
17790}
17791
17792template<typename Derived>
17793ExprResult
17794TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17795 // Transform the base expression.
17796 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17797 if (Base.isInvalid())
17798 return ExprError();
17799
17800 // Transform the key expression.
17801 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17802 if (Key.isInvalid())
17803 return ExprError();
17804
17805 // If nothing changed, just retain the existing expression.
17806 if (!getDerived().AlwaysRebuild() &&
17807 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17808 return E;
17809
17810 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17811 Base.get(), Key.get(),
17812 E->getAtIndexMethodDecl(),
17813 E->setAtIndexMethodDecl());
17814}
17815
17816template<typename Derived>
17817ExprResult
17818TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17819 // Transform the base expression.
17820 ExprResult Base = getDerived().TransformExpr(E->getBase());
17821 if (Base.isInvalid())
17822 return ExprError();
17823
17824 // If nothing changed, just retain the existing expression.
17825 if (!getDerived().AlwaysRebuild() &&
17826 Base.get() == E->getBase())
17827 return E;
17828
17829 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17830 E->getOpLoc(),
17831 E->isArrow());
17832}
17833
17834template<typename Derived>
17835ExprResult
17836TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17837 bool ArgumentChanged = false;
17838 SmallVector<Expr*, 8> SubExprs;
17839 SubExprs.reserve(N: E->getNumSubExprs());
17840 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17841 SubExprs, &ArgumentChanged))
17842 return ExprError();
17843
17844 if (!getDerived().AlwaysRebuild() &&
17845 !ArgumentChanged)
17846 return E;
17847
17848 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17849 SubExprs,
17850 E->getRParenLoc());
17851}
17852
17853template<typename Derived>
17854ExprResult
17855TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17856 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17857 if (SrcExpr.isInvalid())
17858 return ExprError();
17859
17860 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17861 if (!Type)
17862 return ExprError();
17863
17864 if (!getDerived().AlwaysRebuild() &&
17865 Type == E->getTypeSourceInfo() &&
17866 SrcExpr.get() == E->getSrcExpr())
17867 return E;
17868
17869 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17870 SrcExpr.get(), Type,
17871 E->getRParenLoc());
17872}
17873
17874template<typename Derived>
17875ExprResult
17876TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17877 BlockDecl *oldBlock = E->getBlockDecl();
17878
17879 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17880 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17881
17882 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17883 blockScope->TheDecl->setBlockMissingReturnType(
17884 oldBlock->blockMissingReturnType());
17885
17886 SmallVector<ParmVarDecl*, 4> params;
17887 SmallVector<QualType, 4> paramTypes;
17888
17889 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17890
17891 // Parameter substitution.
17892 Sema::ExtParameterInfoBuilder extParamInfos;
17893 if (getDerived().TransformFunctionTypeParams(
17894 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17895 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17896 extParamInfos)) {
17897 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17898 return ExprError();
17899 }
17900
17901 QualType exprResultType =
17902 getDerived().TransformType(exprFunctionType->getReturnType());
17903
17904 auto epi = exprFunctionType->getExtProtoInfo();
17905 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17906
17907 QualType functionType =
17908 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17909 blockScope->FunctionType = functionType;
17910
17911 // Set the parameters on the block decl.
17912 if (!params.empty())
17913 blockScope->TheDecl->setParams(params);
17914
17915 if (!oldBlock->blockMissingReturnType()) {
17916 blockScope->HasImplicitReturnType = false;
17917 blockScope->ReturnType = exprResultType;
17918 }
17919
17920 // Transform the body
17921 StmtResult body = getDerived().TransformStmt(E->getBody());
17922 if (body.isInvalid()) {
17923 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17924 return ExprError();
17925 }
17926
17927#ifndef NDEBUG
17928 // In builds with assertions, make sure that we captured everything we
17929 // captured before.
17930 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17931 for (const auto &I : oldBlock->captures()) {
17932 VarDecl *oldCapture = I.getVariable();
17933
17934 // Ignore parameter packs.
17935 if (oldCapture->isParameterPack())
17936 continue;
17937
17938 VarDecl *newCapture =
17939 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17940 oldCapture));
17941 assert(blockScope->CaptureMap.count(newCapture));
17942 }
17943
17944 // The this pointer may not be captured by the instantiated block, even when
17945 // it's captured by the original block, if the expression causing the
17946 // capture is in the discarded branch of a constexpr if statement.
17947 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17948 "this pointer isn't captured in the old block");
17949 }
17950#endif
17951
17952 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17953 /*Scope=*/CurScope: nullptr);
17954}
17955
17956template<typename Derived>
17957ExprResult
17958TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17959 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17960 if (SrcExpr.isInvalid())
17961 return ExprError();
17962
17963 QualType Type = getDerived().TransformType(E->getType());
17964
17965 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17966 RParenLoc: E->getRParenLoc());
17967}
17968
17969template<typename Derived>
17970ExprResult
17971TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17972 bool ArgumentChanged = false;
17973 SmallVector<Expr*, 8> SubExprs;
17974 SubExprs.reserve(N: E->getNumSubExprs());
17975 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17976 SubExprs, &ArgumentChanged))
17977 return ExprError();
17978
17979 if (!getDerived().AlwaysRebuild() &&
17980 !ArgumentChanged)
17981 return E;
17982
17983 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17984 E->getOp(), E->getRParenLoc());
17985}
17986
17987//===----------------------------------------------------------------------===//
17988// Type reconstruction
17989//===----------------------------------------------------------------------===//
17990
17991template<typename Derived>
17992QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17993 SourceLocation Star) {
17994 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17995 Entity: getDerived().getBaseEntity());
17996}
17997
17998template<typename Derived>
17999QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
18000 SourceLocation Star) {
18001 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
18002 Entity: getDerived().getBaseEntity());
18003}
18004
18005template<typename Derived>
18006QualType
18007TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
18008 bool WrittenAsLValue,
18009 SourceLocation Sigil) {
18010 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
18011 Loc: Sigil, Entity: getDerived().getBaseEntity());
18012}
18013
18014template <typename Derived>
18015QualType TreeTransform<Derived>::RebuildMemberPointerType(
18016 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
18017 SourceLocation Sigil) {
18018 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
18019 Entity: getDerived().getBaseEntity());
18020}
18021
18022template<typename Derived>
18023QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
18024 const ObjCTypeParamDecl *Decl,
18025 SourceLocation ProtocolLAngleLoc,
18026 ArrayRef<ObjCProtocolDecl *> Protocols,
18027 ArrayRef<SourceLocation> ProtocolLocs,
18028 SourceLocation ProtocolRAngleLoc) {
18029 return SemaRef.ObjC().BuildObjCTypeParamType(
18030 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18031 /*FailOnError=*/FailOnError: true);
18032}
18033
18034template<typename Derived>
18035QualType TreeTransform<Derived>::RebuildObjCObjectType(
18036 QualType BaseType,
18037 SourceLocation Loc,
18038 SourceLocation TypeArgsLAngleLoc,
18039 ArrayRef<TypeSourceInfo *> TypeArgs,
18040 SourceLocation TypeArgsRAngleLoc,
18041 SourceLocation ProtocolLAngleLoc,
18042 ArrayRef<ObjCProtocolDecl *> Protocols,
18043 ArrayRef<SourceLocation> ProtocolLocs,
18044 SourceLocation ProtocolRAngleLoc) {
18045 return SemaRef.ObjC().BuildObjCObjectType(
18046 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
18047 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18048 /*FailOnError=*/FailOnError: true,
18049 /*Rebuilding=*/Rebuilding: true);
18050}
18051
18052template<typename Derived>
18053QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
18054 QualType PointeeType,
18055 SourceLocation Star) {
18056 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
18057}
18058
18059template <typename Derived>
18060QualType TreeTransform<Derived>::RebuildArrayType(
18061 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
18062 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18063 if (SizeExpr || !Size)
18064 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
18065 Quals: IndexTypeQuals, Brackets: BracketsRange,
18066 Entity: getDerived().getBaseEntity());
18067
18068 QualType Types[] = {
18069 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
18070 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
18071 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
18072 };
18073 QualType SizeType;
18074 for (const auto &T : Types)
18075 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
18076 SizeType = T;
18077 break;
18078 }
18079
18080 // Note that we can return a VariableArrayType here in the case where
18081 // the element type was a dependent VariableArrayType.
18082 IntegerLiteral *ArraySize
18083 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
18084 /*FIXME*/l: BracketsRange.getBegin());
18085 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
18086 Quals: IndexTypeQuals, Brackets: BracketsRange,
18087 Entity: getDerived().getBaseEntity());
18088}
18089
18090template <typename Derived>
18091QualType TreeTransform<Derived>::RebuildConstantArrayType(
18092 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
18093 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18094 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
18095 IndexTypeQuals, BracketsRange);
18096}
18097
18098template <typename Derived>
18099QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
18100 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
18101 SourceRange BracketsRange) {
18102 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
18103 IndexTypeQuals, BracketsRange);
18104}
18105
18106template <typename Derived>
18107QualType TreeTransform<Derived>::RebuildVariableArrayType(
18108 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18109 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18110 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18111 SizeExpr,
18112 IndexTypeQuals, BracketsRange);
18113}
18114
18115template <typename Derived>
18116QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
18117 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18118 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18119 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18120 SizeExpr,
18121 IndexTypeQuals, BracketsRange);
18122}
18123
18124template <typename Derived>
18125QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
18126 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
18127 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
18128 AttrLoc: AttributeLoc);
18129}
18130
18131template <typename Derived>
18132QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
18133 unsigned NumElements,
18134 VectorKind VecKind) {
18135 // FIXME: semantic checking!
18136 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
18137}
18138
18139template <typename Derived>
18140QualType TreeTransform<Derived>::RebuildDependentVectorType(
18141 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
18142 VectorKind VecKind) {
18143 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
18144}
18145
18146template<typename Derived>
18147QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
18148 unsigned NumElements,
18149 SourceLocation AttributeLoc) {
18150 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18151 NumElements, true);
18152 IntegerLiteral *VectorSize
18153 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
18154 l: AttributeLoc);
18155 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
18156}
18157
18158template<typename Derived>
18159QualType
18160TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
18161 Expr *SizeExpr,
18162 SourceLocation AttributeLoc) {
18163 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
18164}
18165
18166template <typename Derived>
18167QualType TreeTransform<Derived>::RebuildConstantMatrixType(
18168 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
18169 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
18170 NumColumns);
18171}
18172
18173template <typename Derived>
18174QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
18175 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
18176 SourceLocation AttributeLoc) {
18177 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
18178 AttrLoc: AttributeLoc);
18179}
18180
18181template <typename Derived>
18182QualType TreeTransform<Derived>::RebuildFunctionProtoType(
18183 QualType T, MutableArrayRef<QualType> ParamTypes,
18184 const FunctionProtoType::ExtProtoInfo &EPI) {
18185 return SemaRef.BuildFunctionType(T, ParamTypes,
18186 Loc: getDerived().getBaseLocation(),
18187 Entity: getDerived().getBaseEntity(),
18188 EPI);
18189}
18190
18191template<typename Derived>
18192QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
18193 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
18194}
18195
18196template <typename Derived>
18197QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
18198 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
18199 SourceLocation NameLoc, Decl *D) {
18200 assert(D && "no decl found");
18201 if (D->isInvalidDecl()) return QualType();
18202
18203 // FIXME: Doesn't account for ObjCInterfaceDecl!
18204 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
18205 // A valid resolved using typename pack expansion decl can have multiple
18206 // UsingDecls, but they must each have exactly one type, and it must be
18207 // the same type in every case. But we must have at least one expansion!
18208 if (UPD->expansions().empty()) {
18209 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
18210 << UPD->isCXXClassMember() << UPD;
18211 return QualType();
18212 }
18213
18214 // We might still have some unresolved types. Try to pick a resolved type
18215 // if we can. The final instantiation will check that the remaining
18216 // unresolved types instantiate to the type we pick.
18217 QualType FallbackT;
18218 QualType T;
18219 for (auto *E : UPD->expansions()) {
18220 QualType ThisT =
18221 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
18222 if (ThisT.isNull())
18223 continue;
18224 if (ThisT->getAs<UnresolvedUsingType>())
18225 FallbackT = ThisT;
18226 else if (T.isNull())
18227 T = ThisT;
18228 else
18229 assert(getSema().Context.hasSameType(ThisT, T) &&
18230 "mismatched resolved types in using pack expansion");
18231 }
18232 return T.isNull() ? FallbackT : T;
18233 }
18234 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
18235 assert(Using->hasTypename() &&
18236 "UnresolvedUsingTypenameDecl transformed to non-typename using");
18237
18238 // A valid resolved using typename decl points to exactly one type decl.
18239 assert(++Using->shadow_begin() == Using->shadow_end());
18240
18241 UsingShadowDecl *Shadow = *Using->shadow_begin();
18242 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
18243 return QualType();
18244 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
18245 }
18246 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
18247 "UnresolvedUsingTypenameDecl transformed to non-using decl");
18248 return SemaRef.Context.getUnresolvedUsingType(
18249 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
18250}
18251
18252template <typename Derived>
18253QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
18254 TypeOfKind Kind) {
18255 return SemaRef.BuildTypeofExprType(E, Kind);
18256}
18257
18258template<typename Derived>
18259QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
18260 TypeOfKind Kind) {
18261 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
18262}
18263
18264template <typename Derived>
18265QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
18266 return SemaRef.BuildDecltypeType(E);
18267}
18268
18269template <typename Derived>
18270QualType TreeTransform<Derived>::RebuildPackIndexingType(
18271 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
18272 SourceLocation EllipsisLoc, bool FullySubstituted,
18273 ArrayRef<QualType> Expansions) {
18274 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
18275 FullySubstituted, Expansions);
18276}
18277
18278template<typename Derived>
18279QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
18280 UnaryTransformType::UTTKind UKind,
18281 SourceLocation Loc) {
18282 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
18283}
18284
18285template <typename Derived>
18286QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
18287 ElaboratedTypeKeyword Keyword, TemplateName Template,
18288 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
18289 return SemaRef.CheckTemplateIdType(
18290 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
18291 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
18292}
18293
18294template<typename Derived>
18295QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
18296 SourceLocation KWLoc) {
18297 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
18298}
18299
18300template<typename Derived>
18301QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
18302 SourceLocation KWLoc,
18303 bool isReadPipe) {
18304 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
18305 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
18306}
18307
18308template <typename Derived>
18309QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
18310 unsigned NumBits,
18311 SourceLocation Loc) {
18312 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18313 NumBits, true);
18314 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
18315 type: SemaRef.Context.IntTy, l: Loc);
18316 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
18317}
18318
18319template <typename Derived>
18320QualType TreeTransform<Derived>::RebuildDependentBitIntType(
18321 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
18322 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
18323}
18324
18325template <typename Derived>
18326TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18327 bool TemplateKW,
18328 TemplateName Name) {
18329 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
18330 Template: Name);
18331}
18332
18333template <typename Derived>
18334TemplateName TreeTransform<Derived>::RebuildTemplateName(
18335 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
18336 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
18337 UnqualifiedId TemplateName;
18338 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
18339 Sema::TemplateTy Template;
18340 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
18341 TemplateName, ParsedType::make(P: ObjectType),
18342 /*EnteringContext=*/false, Template,
18343 AllowInjectedClassName);
18344 return Template.get();
18345}
18346
18347template<typename Derived>
18348TemplateName
18349TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18350 SourceLocation TemplateKWLoc,
18351 OverloadedOperatorKind Operator,
18352 SourceLocation NameLoc,
18353 QualType ObjectType,
18354 bool AllowInjectedClassName) {
18355 UnqualifiedId Name;
18356 // FIXME: Bogus location information.
18357 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
18358 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
18359 Sema::TemplateTy Template;
18360 getSema().ActOnTemplateName(
18361 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
18362 /*EnteringContext=*/false, Template, AllowInjectedClassName);
18363 return Template.get();
18364}
18365
18366template <typename Derived>
18367ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
18368 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
18369 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
18370 Expr *Second) {
18371 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
18372
18373 if (First->getObjectKind() == OK_ObjCProperty) {
18374 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18375 if (BinaryOperator::isAssignmentOp(Opc))
18376 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
18377 Opcode: Opc, LHS: First, RHS: Second);
18378 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
18379 if (Result.isInvalid())
18380 return ExprError();
18381 First = Result.get();
18382 }
18383
18384 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
18385 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
18386 if (Result.isInvalid())
18387 return ExprError();
18388 Second = Result.get();
18389 }
18390
18391 // Determine whether this should be a builtin operation.
18392 if (Op == OO_Subscript) {
18393 if (!First->getType()->isOverloadableType() &&
18394 !Second->getType()->isOverloadableType())
18395 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
18396 OpLoc);
18397 } else if (Op == OO_Arrow) {
18398 // It is possible that the type refers to a RecoveryExpr created earlier
18399 // in the tree transformation.
18400 if (First->getType()->isDependentType())
18401 return ExprError();
18402 // -> is never a builtin operation.
18403 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
18404 } else if (Second == nullptr || isPostIncDec) {
18405 if (!First->getType()->isOverloadableType() ||
18406 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
18407 // The argument is not of overloadable type, or this is an expression
18408 // of the form &Class::member, so try to create a built-in unary
18409 // operation.
18410 UnaryOperatorKind Opc
18411 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18412
18413 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
18414 }
18415 } else {
18416 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
18417 !First->getType()->isOverloadableType() &&
18418 !Second->getType()->isOverloadableType()) {
18419 // Neither of the arguments is type-dependent or has an overloadable
18420 // type, so try to create a built-in binary operation.
18421 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18422 ExprResult Result
18423 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
18424 if (Result.isInvalid())
18425 return ExprError();
18426
18427 return Result;
18428 }
18429 }
18430
18431 // Create the overloaded operator invocation for unary operators.
18432 if (!Second || isPostIncDec) {
18433 UnaryOperatorKind Opc
18434 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18435 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
18436 RequiresADL);
18437 }
18438
18439 // Create the overloaded operator invocation for binary operators.
18440 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18441 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
18442 LHS: First, RHS: Second, RequiresADL);
18443 if (Result.isInvalid())
18444 return ExprError();
18445
18446 return Result;
18447}
18448
18449template<typename Derived>
18450ExprResult
18451TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
18452 SourceLocation OperatorLoc,
18453 bool isArrow,
18454 CXXScopeSpec &SS,
18455 TypeSourceInfo *ScopeType,
18456 SourceLocation CCLoc,
18457 SourceLocation TildeLoc,
18458 PseudoDestructorTypeStorage Destroyed) {
18459 QualType CanonicalBaseType = Base->getType().getCanonicalType();
18460 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
18461 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
18462 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
18463 !cast<PointerType>(Val&: CanonicalBaseType)
18464 ->getPointeeType()
18465 ->getAsCanonical<RecordType>())) {
18466 // This pseudo-destructor expression is still a pseudo-destructor.
18467 return SemaRef.BuildPseudoDestructorExpr(
18468 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
18469 CCLoc, TildeLoc, DestroyedType: Destroyed);
18470 }
18471
18472 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
18473 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
18474 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
18475 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
18476 NameInfo.setNamedTypeInfo(DestroyedType);
18477
18478 // The scope type is now known to be a valid nested name specifier
18479 // component. Tack it on to the nested name specifier.
18480 if (ScopeType) {
18481 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
18482 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
18483 diag::err_expected_class_or_namespace)
18484 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
18485 return ExprError();
18486 }
18487 SS.clear();
18488 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
18489 }
18490
18491 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
18492 return getSema().BuildMemberReferenceExpr(
18493 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
18494 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
18495 /*TemplateArgs*/ nullptr,
18496 /*S*/ nullptr);
18497}
18498
18499template<typename Derived>
18500StmtResult
18501TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
18502 SourceLocation Loc = S->getBeginLoc();
18503 CapturedDecl *CD = S->getCapturedDecl();
18504 unsigned NumParams = CD->getNumParams();
18505 unsigned ContextParamPos = CD->getContextParamPosition();
18506 SmallVector<Sema::CapturedParamNameType, 4> Params;
18507 for (unsigned I = 0; I < NumParams; ++I) {
18508 if (I != ContextParamPos) {
18509 Params.push_back(
18510 Elt: std::make_pair(
18511 CD->getParam(i: I)->getName(),
18512 getDerived().TransformType(CD->getParam(i: I)->getType())));
18513 } else {
18514 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
18515 }
18516 }
18517 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
18518 S->getCapturedRegionKind(), Params);
18519 StmtResult Body;
18520 {
18521 Sema::CompoundScopeRAII CompoundScope(getSema());
18522 Body = getDerived().TransformStmt(S->getCapturedStmt());
18523 }
18524
18525 if (Body.isInvalid()) {
18526 getSema().ActOnCapturedRegionError();
18527 return StmtError();
18528 }
18529
18530 return getSema().ActOnCapturedRegionEnd(Body.get());
18531}
18532
18533template <typename Derived>
18534StmtResult
18535TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18536 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18537 // function definition or instantiation of a function template specialization
18538 // and will therefore never appear in a dependent context.
18539 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18540 "context");
18541}
18542
18543template <typename Derived>
18544ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18545 // We can transform the base expression and allow argument resolution to fill
18546 // in the rest.
18547 return getDerived().TransformExpr(E->getArgLValue());
18548}
18549
18550} // end namespace clang
18551
18552#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18553