1//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a semantic tree transformation that takes a given
9// AST and rebuilds it, possibly transforming some nodes in the process.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
16#include "CoroutineStmtBuilder.h"
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
23#include "clang/AST/ExprConcepts.h"
24#include "clang/AST/ExprObjC.h"
25#include "clang/AST/ExprOpenMP.h"
26#include "clang/AST/OpenMPClause.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
30#include "clang/AST/StmtOpenACC.h"
31#include "clang/AST/StmtOpenMP.h"
32#include "clang/AST/StmtSYCL.h"
33#include "clang/Basic/DiagnosticParse.h"
34#include "clang/Basic/OpenMPKinds.h"
35#include "clang/Sema/Designator.h"
36#include "clang/Sema/EnterExpressionEvaluationContext.h"
37#include "clang/Sema/Lookup.h"
38#include "clang/Sema/Ownership.h"
39#include "clang/Sema/ParsedTemplate.h"
40#include "clang/Sema/ScopeInfo.h"
41#include "clang/Sema/SemaDiagnostic.h"
42#include "clang/Sema/SemaHLSL.h"
43#include "clang/Sema/SemaInternal.h"
44#include "clang/Sema/SemaObjC.h"
45#include "clang/Sema/SemaOpenACC.h"
46#include "clang/Sema/SemaOpenMP.h"
47#include "clang/Sema/SemaPseudoObject.h"
48#include "clang/Sema/SemaSYCL.h"
49#include "clang/Sema/Template.h"
50#include "llvm/ADT/ArrayRef.h"
51#include "llvm/Support/ErrorHandling.h"
52#include <algorithm>
53#include <optional>
54
55using namespace llvm::omp;
56
57namespace clang {
58using namespace sema;
59
60// This helper class is used to facilitate pack expansion during tree transform.
61struct UnexpandedInfo {
62 SourceLocation Ellipsis;
63 UnsignedOrNone OrigNumExpansions = std::nullopt;
64
65 bool Expand = false;
66 bool RetainExpansion = false;
67 UnsignedOrNone NumExpansions = std::nullopt;
68 bool ExpandUnderForgetSubstitions = false;
69};
70
71/// A semantic tree transformation that allows one to transform one
72/// abstract syntax tree into another.
73///
74/// A new tree transformation is defined by creating a new subclass \c X of
75/// \c TreeTransform<X> and then overriding certain operations to provide
76/// behavior specific to that transformation. For example, template
77/// instantiation is implemented as a tree transformation where the
78/// transformation of TemplateTypeParmType nodes involves substituting the
79/// template arguments for their corresponding template parameters; a similar
80/// transformation is performed for non-type template parameters and
81/// template template parameters.
82///
83/// This tree-transformation template uses static polymorphism to allow
84/// subclasses to customize any of its operations. Thus, a subclass can
85/// override any of the transformation or rebuild operators by providing an
86/// operation with the same signature as the default implementation. The
87/// overriding function should not be virtual.
88///
89/// Semantic tree transformations are split into two stages, either of which
90/// can be replaced by a subclass. The "transform" step transforms an AST node
91/// or the parts of an AST node using the various transformation functions,
92/// then passes the pieces on to the "rebuild" step, which constructs a new AST
93/// node of the appropriate kind from the pieces. The default transformation
94/// routines recursively transform the operands to composite AST nodes (e.g.,
95/// the pointee type of a PointerType node) and, if any of those operand nodes
96/// were changed by the transformation, invokes the rebuild operation to create
97/// a new AST node.
98///
99/// Subclasses can customize the transformation at various levels. The
100/// most coarse-grained transformations involve replacing TransformType(),
101/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
102/// TransformTemplateName(), or TransformTemplateArgument() with entirely
103/// new implementations.
104///
105/// For more fine-grained transformations, subclasses can replace any of the
106/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
107/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
108/// replacing TransformTemplateTypeParmType() allows template instantiation
109/// to substitute template arguments for their corresponding template
110/// parameters. Additionally, subclasses can override the \c RebuildXXX
111/// functions to control how AST nodes are rebuilt when their operands change.
112/// By default, \c TreeTransform will invoke semantic analysis to rebuild
113/// AST nodes. However, certain other tree transformations (e.g, cloning) may
114/// be able to use more efficient rebuild steps.
115///
116/// There are a handful of other functions that can be overridden, allowing one
117/// to avoid traversing nodes that don't need any transformation
118/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
119/// operands have not changed (\c AlwaysRebuild()), and customize the
120/// default locations and entity names used for type-checking
121/// (\c getBaseLocation(), \c getBaseEntity()).
122template<typename Derived>
123class TreeTransform {
124 /// Private RAII object that helps us forget and then re-remember
125 /// the template argument corresponding to a partially-substituted parameter
126 /// pack.
127 class ForgetPartiallySubstitutedPackRAII {
128 Derived &Self;
129 TemplateArgument Old;
130 // Set the pack expansion index to -1 to avoid pack substitution and
131 // indicate that parameter packs should be instantiated as themselves.
132 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
133
134 public:
135 ForgetPartiallySubstitutedPackRAII(Derived &Self)
136 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
137 Old = Self.ForgetPartiallySubstitutedPack();
138 }
139
140 ~ForgetPartiallySubstitutedPackRAII() {
141 Self.RememberPartiallySubstitutedPack(Old);
142 }
143 ForgetPartiallySubstitutedPackRAII(
144 const ForgetPartiallySubstitutedPackRAII &) = delete;
145 ForgetPartiallySubstitutedPackRAII &
146 operator=(const ForgetPartiallySubstitutedPackRAII &) = delete;
147 };
148
149protected:
150 Sema &SemaRef;
151
152 /// The set of local declarations that have been transformed, for
153 /// cases where we are forced to build new declarations within the transformer
154 /// rather than in the subclass (e.g., lambda closure types).
155 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
156
157public:
158 /// Initializes a new tree transformer.
159 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
160
161 /// Retrieves a reference to the derived class.
162 Derived &getDerived() { return static_cast<Derived&>(*this); }
163
164 /// Retrieves a reference to the derived class.
165 const Derived &getDerived() const {
166 return static_cast<const Derived&>(*this);
167 }
168
169 static inline ExprResult Owned(Expr *E) { return E; }
170 static inline StmtResult Owned(Stmt *S) { return S; }
171
172 /// Retrieves a reference to the semantic analysis object used for
173 /// this tree transform.
174 Sema &getSema() const { return SemaRef; }
175
176 /// Whether the transformation should always rebuild AST nodes, even
177 /// if none of the children have changed.
178 ///
179 /// Subclasses may override this function to specify when the transformation
180 /// should rebuild all AST nodes.
181 ///
182 /// We must always rebuild all AST nodes when performing variadic template
183 /// pack expansion, in order to avoid violating the AST invariant that each
184 /// statement node appears at most once in its containing declaration.
185 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
186
187 /// Whether the transformation is forming an expression or statement that
188 /// replaces the original. In this case, we'll reuse mangling numbers from
189 /// existing lambdas.
190 bool ReplacingOriginal() { return false; }
191
192 /// Wether CXXConstructExpr can be skipped when they are implicit.
193 /// They will be reconstructed when used if needed.
194 /// This is useful when the user that cause rebuilding of the
195 /// CXXConstructExpr is outside of the expression at which the TreeTransform
196 /// started.
197 bool AllowSkippingCXXConstructExpr() { return true; }
198
199 /// Returns the location of the entity being transformed, if that
200 /// information was not available elsewhere in the AST.
201 ///
202 /// By default, returns no source-location information. Subclasses can
203 /// provide an alternative implementation that provides better location
204 /// information.
205 SourceLocation getBaseLocation() { return SourceLocation(); }
206
207 /// Returns the name of the entity being transformed, if that
208 /// information was not available elsewhere in the AST.
209 ///
210 /// By default, returns an empty name. Subclasses can provide an alternative
211 /// implementation with a more precise name.
212 DeclarationName getBaseEntity() { return DeclarationName(); }
213
214 /// Sets the "base" location and entity when that
215 /// information is known based on another transformation.
216 ///
217 /// By default, the source location and entity are ignored. Subclasses can
218 /// override this function to provide a customized implementation.
219 void setBase(SourceLocation Loc, DeclarationName Entity) { }
220
221 /// RAII object that temporarily sets the base location and entity
222 /// used for reporting diagnostics in types.
223 class TemporaryBase {
224 TreeTransform &Self;
225 SourceLocation OldLocation;
226 DeclarationName OldEntity;
227
228 public:
229 TemporaryBase(TreeTransform &Self, SourceLocation Location,
230 DeclarationName Entity) : Self(Self) {
231 OldLocation = Self.getDerived().getBaseLocation();
232 OldEntity = Self.getDerived().getBaseEntity();
233
234 if (Location.isValid())
235 Self.getDerived().setBase(Location, Entity);
236 }
237
238 ~TemporaryBase() {
239 Self.getDerived().setBase(OldLocation, OldEntity);
240 }
241 TemporaryBase(const TemporaryBase &) = delete;
242 TemporaryBase &operator=(const TemporaryBase &) = delete;
243 };
244
245 /// Determine whether the given type \p T has already been
246 /// transformed.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine
249 /// to short-circuit evaluation when it is known that a given type will
250 /// not change. For example, template instantiation need not traverse
251 /// non-dependent types.
252 bool AlreadyTransformed(QualType T) {
253 return T.isNull();
254 }
255
256 /// Transform a template parameter depth level.
257 ///
258 /// During a transformation that transforms template parameters, this maps
259 /// an old template parameter depth to a new depth.
260 unsigned TransformTemplateDepth(unsigned Depth) {
261 return Depth;
262 }
263
264 /// Determine whether the given call argument should be dropped, e.g.,
265 /// because it is a default argument.
266 ///
267 /// Subclasses can provide an alternative implementation of this routine to
268 /// determine which kinds of call arguments get dropped. By default,
269 /// CXXDefaultArgument nodes are dropped (prior to transformation).
270 bool DropCallArgument(Expr *E) {
271 return E->isDefaultArgument();
272 }
273
274 /// Determine whether we should expand a pack expansion with the
275 /// given set of parameter packs into separate arguments by repeatedly
276 /// transforming the pattern.
277 ///
278 /// By default, the transformer never tries to expand pack expansions.
279 /// Subclasses can override this routine to provide different behavior.
280 ///
281 /// \param EllipsisLoc The location of the ellipsis that identifies the
282 /// pack expansion.
283 ///
284 /// \param PatternRange The source range that covers the entire pattern of
285 /// the pack expansion.
286 ///
287 /// \param Unexpanded The set of unexpanded parameter packs within the
288 /// pattern.
289 ///
290 /// \param ShouldExpand Will be set to \c true if the transformer should
291 /// expand the corresponding pack expansions into separate arguments. When
292 /// set, \c NumExpansions must also be set.
293 ///
294 /// \param RetainExpansion Whether the caller should add an unexpanded
295 /// pack expansion after all of the expanded arguments. This is used
296 /// when extending explicitly-specified template argument packs per
297 /// C++0x [temp.arg.explicit]p9.
298 ///
299 /// \param NumExpansions The number of separate arguments that will be in
300 /// the expanded form of the corresponding pack expansion. This is both an
301 /// input and an output parameter, which can be set by the caller if the
302 /// number of expansions is known a priori (e.g., due to a prior substitution)
303 /// and will be set by the callee when the number of expansions is known.
304 /// The callee must set this value when \c ShouldExpand is \c true; it may
305 /// set this value in other cases.
306 ///
307 /// \returns true if an error occurred (e.g., because the parameter packs
308 /// are to be instantiated with arguments of different lengths), false
309 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
310 /// must be set.
311 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
312 SourceRange PatternRange,
313 ArrayRef<UnexpandedParameterPack> Unexpanded,
314 bool FailOnPackProducingTemplates,
315 bool &ShouldExpand, bool &RetainExpansion,
316 UnsignedOrNone &NumExpansions) {
317 ShouldExpand = false;
318 return false;
319 }
320
321 /// "Forget" about the partially-substituted pack template argument,
322 /// when performing an instantiation that must preserve the parameter pack
323 /// use.
324 ///
325 /// This routine is meant to be overridden by the template instantiator.
326 TemplateArgument ForgetPartiallySubstitutedPack() {
327 return TemplateArgument();
328 }
329
330 /// "Remember" the partially-substituted pack template argument
331 /// after performing an instantiation that must preserve the parameter pack
332 /// use.
333 ///
334 /// This routine is meant to be overridden by the template instantiator.
335 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
336
337 /// "Forget" the template substitution to allow transforming the AST without
338 /// any template instantiations. This is used to expand template packs when
339 /// their size is not known in advance (e.g. for builtins that produce type
340 /// packs).
341 MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }
342 void RememberSubstitution(MultiLevelTemplateArgumentList) {}
343
344private:
345 struct ForgetSubstitutionRAII {
346 Derived &Self;
347 MultiLevelTemplateArgumentList Old;
348
349 public:
350 ForgetSubstitutionRAII(Derived &Self) : Self(Self) {
351 Old = Self.ForgetSubstitution();
352 }
353
354 ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }
355 };
356
357public:
358 /// Note to the derived class when a function parameter pack is
359 /// being expanded.
360 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
361
362 /// Transforms the given type into another type.
363 ///
364 /// By default, this routine transforms a type by creating a
365 /// TypeSourceInfo for it and delegating to the appropriate
366 /// function. This is expensive, but we don't mind, because
367 /// this method is deprecated anyway; all users should be
368 /// switched to storing TypeSourceInfos.
369 ///
370 /// \returns the transformed type.
371 QualType TransformType(QualType T);
372
373 /// Transforms the given type-with-location into a new
374 /// type-with-location.
375 ///
376 /// By default, this routine transforms a type by delegating to the
377 /// appropriate TransformXXXType to build a new type. Subclasses
378 /// may override this function (to take over all type
379 /// transformations) or some set of the TransformXXXType functions
380 /// to alter the transformation.
381 TypeSourceInfo *TransformType(TypeSourceInfo *TSI);
382
383 /// Transform the given type-with-location into a new
384 /// type, collecting location information in the given builder
385 /// as necessary.
386 ///
387 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
388
389 /// Transform a type that is permitted to produce a
390 /// DeducedTemplateSpecializationType.
391 ///
392 /// This is used in the (relatively rare) contexts where it is acceptable
393 /// for transformation to produce a class template type with deduced
394 /// template arguments.
395 /// @{
396 QualType TransformTypeWithDeducedTST(QualType T);
397 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *TSI);
398 /// @}
399
400 /// The reason why the value of a statement is not discarded, if any.
401 enum class StmtDiscardKind {
402 Discarded,
403 NotDiscarded,
404 StmtExprResult,
405 };
406
407 /// Transform the given statement.
408 ///
409 /// By default, this routine transforms a statement by delegating to the
410 /// appropriate TransformXXXStmt function to transform a specific kind of
411 /// statement or the TransformExpr() function to transform an expression.
412 /// Subclasses may override this function to transform statements using some
413 /// other mechanism.
414 ///
415 /// \returns the transformed statement.
416 StmtResult TransformStmt(Stmt *S,
417 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
418
419 /// Transform the given statement.
420 ///
421 /// By default, this routine transforms a statement by delegating to the
422 /// appropriate TransformOMPXXXClause function to transform a specific kind
423 /// of clause. Subclasses may override this function to transform statements
424 /// using some other mechanism.
425 ///
426 /// \returns the transformed OpenMP clause.
427 OMPClause *TransformOMPClause(OMPClause *S);
428
429 /// Transform the given attribute.
430 ///
431 /// By default, this routine transforms a statement by delegating to the
432 /// appropriate TransformXXXAttr function to transform a specific kind
433 /// of attribute. Subclasses may override this function to transform
434 /// attributed statements/types using some other mechanism.
435 ///
436 /// \returns the transformed attribute
437 const Attr *TransformAttr(const Attr *S);
438
439 // Transform the given statement attribute.
440 //
441 // Delegates to the appropriate TransformXXXAttr function to transform a
442 // specific kind of statement attribute. Unlike the non-statement taking
443 // version of this, this implements all attributes, not just pragmas.
444 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
445 const Attr *A);
446
447 // Transform the specified attribute.
448 //
449 // Subclasses should override the transformation of attributes with a pragma
450 // spelling to transform expressions stored within the attribute.
451 //
452 // \returns the transformed attribute.
453#define ATTR(X) \
454 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
455#include "clang/Basic/AttrList.inc"
456
457 // Transform the specified attribute.
458 //
459 // Subclasses should override the transformation of attributes to do
460 // transformation and checking of statement attributes. By default, this
461 // delegates to the non-statement taking version.
462 //
463 // \returns the transformed attribute.
464#define ATTR(X) \
465 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
466 const X##Attr *A) { \
467 return getDerived().Transform##X##Attr(A); \
468 }
469#include "clang/Basic/AttrList.inc"
470
471 /// Transform the given expression.
472 ///
473 /// By default, this routine transforms an expression by delegating to the
474 /// appropriate TransformXXXExpr function to build a new expression.
475 /// Subclasses may override this function to transform expressions using some
476 /// other mechanism.
477 ///
478 /// \returns the transformed expression.
479 ExprResult TransformExpr(Expr *E);
480
481 /// Transform the given initializer.
482 ///
483 /// By default, this routine transforms an initializer by stripping off the
484 /// semantic nodes added by initialization, then passing the result to
485 /// TransformExpr or TransformExprs.
486 ///
487 /// \returns the transformed initializer.
488 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
489
490 /// Transform the given list of expressions.
491 ///
492 /// This routine transforms a list of expressions by invoking
493 /// \c TransformExpr() for each subexpression. However, it also provides
494 /// support for variadic templates by expanding any pack expansions (if the
495 /// derived class permits such expansion) along the way. When pack expansions
496 /// are present, the number of outputs may not equal the number of inputs.
497 ///
498 /// \param Inputs The set of expressions to be transformed.
499 ///
500 /// \param NumInputs The number of expressions in \c Inputs.
501 ///
502 /// \param IsCall If \c true, then this transform is being performed on
503 /// function-call arguments, and any arguments that should be dropped, will
504 /// be.
505 ///
506 /// \param Outputs The transformed input expressions will be added to this
507 /// vector.
508 ///
509 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
510 /// due to transformation.
511 ///
512 /// \returns true if an error occurred, false otherwise.
513 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
514 SmallVectorImpl<Expr *> &Outputs,
515 bool *ArgChanged = nullptr);
516
517 /// Transform the given declaration, which is referenced from a type
518 /// or expression.
519 ///
520 /// By default, acts as the identity function on declarations, unless the
521 /// transformer has had to transform the declaration itself. Subclasses
522 /// may override this function to provide alternate behavior.
523 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
524 llvm::DenseMap<Decl *, Decl *>::iterator Known
525 = TransformedLocalDecls.find(Val: D);
526 if (Known != TransformedLocalDecls.end())
527 return Known->second;
528
529 return D;
530 }
531
532 /// Transform the specified condition.
533 ///
534 /// By default, this transforms the variable and expression and rebuilds
535 /// the condition.
536 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
537 Expr *Expr,
538 Sema::ConditionKind Kind);
539
540 /// Transform the attributes associated with the given declaration and
541 /// place them on the new declaration.
542 ///
543 /// By default, this operation does nothing. Subclasses may override this
544 /// behavior to transform attributes.
545 void transformAttrs(Decl *Old, Decl *New) { }
546
547 /// Note that a local declaration has been transformed by this
548 /// transformer.
549 ///
550 /// Local declarations are typically transformed via a call to
551 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
552 /// the transformer itself has to transform the declarations. This routine
553 /// can be overridden by a subclass that keeps track of such mappings.
554 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
555 assert(New.size() == 1 &&
556 "must override transformedLocalDecl if performing pack expansion");
557 TransformedLocalDecls[Old] = New.front();
558 }
559
560 /// Transform the definition of the given declaration.
561 ///
562 /// By default, invokes TransformDecl() to transform the declaration.
563 /// Subclasses may override this function to provide alternate behavior.
564 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
565 return getDerived().TransformDecl(Loc, D);
566 }
567
568 /// Transform the given declaration, which was the first part of a
569 /// nested-name-specifier in a member access expression.
570 ///
571 /// This specific declaration transformation only applies to the first
572 /// identifier in a nested-name-specifier of a member access expression, e.g.,
573 /// the \c T in \c x->T::member
574 ///
575 /// By default, invokes TransformDecl() to transform the declaration.
576 /// Subclasses may override this function to provide alternate behavior.
577 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
578 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
579 }
580
581 /// Transform the set of declarations in an OverloadExpr.
582 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
583 LookupResult &R);
584
585 /// Transform the given nested-name-specifier with source-location
586 /// information.
587 ///
588 /// By default, transforms all of the types and declarations within the
589 /// nested-name-specifier. Subclasses may override this function to provide
590 /// alternate behavior.
591 NestedNameSpecifierLoc
592 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
593 QualType ObjectType = QualType(),
594 NamedDecl *FirstQualifierInScope = nullptr);
595
596 /// Transform the given declaration name.
597 ///
598 /// By default, transforms the types of conversion function, constructor,
599 /// and destructor names and then (if needed) rebuilds the declaration name.
600 /// Identifiers and selectors are returned unmodified. Subclasses may
601 /// override this function to provide alternate behavior.
602 DeclarationNameInfo
603 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
604
605 bool TransformRequiresExprRequirements(
606 ArrayRef<concepts::Requirement *> Reqs,
607 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
608 concepts::TypeRequirement *
609 TransformTypeRequirement(concepts::TypeRequirement *Req);
610 concepts::ExprRequirement *
611 TransformExprRequirement(concepts::ExprRequirement *Req);
612 concepts::NestedRequirement *
613 TransformNestedRequirement(concepts::NestedRequirement *Req);
614
615 /// Transform the given template name.
616 ///
617 /// \param SS The nested-name-specifier that qualifies the template
618 /// name. This nested-name-specifier must already have been transformed.
619 ///
620 /// \param Name The template name to transform.
621 ///
622 /// \param NameLoc The source location of the template name.
623 ///
624 /// \param ObjectType If we're translating a template name within a member
625 /// access expression, this is the type of the object whose member template
626 /// is being referenced.
627 ///
628 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
629 /// also refers to a name within the current (lexical) scope, this is the
630 /// declaration it refers to.
631 ///
632 /// By default, transforms the template name by transforming the declarations
633 /// and nested-name-specifiers that occur within the template name.
634 /// Subclasses may override this function to provide alternate behavior.
635 TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
636 SourceLocation TemplateKWLoc,
637 TemplateName Name, SourceLocation NameLoc,
638 QualType ObjectType = QualType(),
639 NamedDecl *FirstQualifierInScope = nullptr,
640 bool AllowInjectedClassName = false);
641
642 TemplateName TransformConceptTemplateName(TemplateName Name,
643 SourceLocation NameLoc);
644
645 /// Transform the given template argument.
646 ///
647 /// By default, this operation transforms the type, expression, or
648 /// declaration stored within the template argument and constructs a
649 /// new template argument from the transformed result. Subclasses may
650 /// override this function to provide alternate behavior.
651 ///
652 /// Returns true if there was an error.
653 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
654 TemplateArgumentLoc &Output,
655 bool Uneval = false);
656
657 TemplateArgument TransformNamedTemplateTemplateArgument(
658 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
659 TemplateName Name, SourceLocation NameLoc);
660
661 /// Transform the given set of template arguments.
662 ///
663 /// By default, this operation transforms all of the template arguments
664 /// in the input set using \c TransformTemplateArgument(), and appends
665 /// the transformed arguments to the output list.
666 ///
667 /// Note that this overload of \c TransformTemplateArguments() is merely
668 /// a convenience function. Subclasses that wish to override this behavior
669 /// should override the iterator-based member template version.
670 ///
671 /// \param Inputs The set of template arguments to be transformed.
672 ///
673 /// \param NumInputs The number of template arguments in \p Inputs.
674 ///
675 /// \param Outputs The set of transformed template arguments output by this
676 /// routine.
677 ///
678 /// Returns true if an error occurred.
679 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
680 unsigned NumInputs,
681 TemplateArgumentListInfo &Outputs,
682 bool Uneval = false) {
683 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
684 Uneval);
685 }
686
687 /// Transform the given set of template arguments.
688 ///
689 /// By default, this operation transforms all of the template arguments
690 /// in the input set using \c TransformTemplateArgument(), and appends
691 /// the transformed arguments to the output list.
692 ///
693 /// \param First An iterator to the first template argument.
694 ///
695 /// \param Last An iterator one step past the last template argument.
696 ///
697 /// \param Outputs The set of transformed template arguments output by this
698 /// routine.
699 ///
700 /// Returns true if an error occurred.
701 template<typename InputIterator>
702 bool TransformTemplateArguments(InputIterator First,
703 InputIterator Last,
704 TemplateArgumentListInfo &Outputs,
705 bool Uneval = false);
706
707 template <typename InputIterator>
708 bool TransformConceptTemplateArguments(InputIterator First,
709 InputIterator Last,
710 TemplateArgumentListInfo &Outputs,
711 bool Uneval = false);
712
713 /// Checks if the argument pack from \p In will need to be expanded and does
714 /// the necessary prework.
715 /// Whether the expansion is needed is captured in Info.Expand.
716 ///
717 /// - When the expansion is required, \p Out will be a template pattern that
718 /// would need to be expanded.
719 /// - When the expansion must not happen, \p Out will be a pack that must be
720 /// returned to the outputs directly.
721 ///
722 /// \return true iff the error occurred
723 bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
724 TemplateArgumentLoc &Out, UnexpandedInfo &Info);
725
726 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
727 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
728 TemplateArgumentLoc &ArgLoc);
729
730 /// Fakes up a TypeSourceInfo for a type.
731 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
732 return SemaRef.Context.getTrivialTypeSourceInfo(T,
733 Loc: getDerived().getBaseLocation());
734 }
735
736#define ABSTRACT_TYPELOC(CLASS, PARENT)
737#define TYPELOC(CLASS, PARENT) \
738 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
739#include "clang/AST/TypeLocNodes.def"
740
741 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
742 TemplateTypeParmTypeLoc TL,
743 bool SuppressObjCLifetime);
744 QualType
745 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
746 SubstTemplateTypeParmPackTypeLoc TL,
747 bool SuppressObjCLifetime);
748
749 template<typename Fn>
750 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
751 FunctionProtoTypeLoc TL,
752 CXXRecordDecl *ThisContext,
753 Qualifiers ThisTypeQuals,
754 Fn TransformExceptionSpec);
755
756 bool TransformExceptionSpec(SourceLocation Loc,
757 FunctionProtoType::ExceptionSpecInfo &ESI,
758 SmallVectorImpl<QualType> &Exceptions,
759 bool &Changed);
760
761 StmtResult TransformSEHHandler(Stmt *Handler);
762
763 QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,
764 TemplateSpecializationTypeLoc TL,
765 QualType ObjectType,
766 NamedDecl *FirstQualifierInScope,
767 bool AllowInjectedClassName);
768
769 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);
770
771 /// Transforms the parameters of a function type into the
772 /// given vectors.
773 ///
774 /// The result vectors should be kept in sync; null entries in the
775 /// variables vector are acceptable.
776 ///
777 /// LastParamTransformed, if non-null, will be set to the index of the last
778 /// parameter on which transformation was started. In the event of an error,
779 /// this will contain the parameter which failed to instantiate.
780 ///
781 /// Return true on error.
782 bool TransformFunctionTypeParams(
783 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
784 const QualType *ParamTypes,
785 const FunctionProtoType::ExtParameterInfo *ParamInfos,
786 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
787 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
788
789 bool TransformFunctionTypeParams(
790 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
791 const QualType *ParamTypes,
792 const FunctionProtoType::ExtParameterInfo *ParamInfos,
793 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
794 Sema::ExtParameterInfoBuilder &PInfos) {
795 return getDerived().TransformFunctionTypeParams(
796 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
797 }
798
799 /// Transforms the parameters of a requires expresison into the given vectors.
800 ///
801 /// The result vectors should be kept in sync; null entries in the
802 /// variables vector are acceptable.
803 ///
804 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
805 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
806 /// which are cases where transformation shouldn't continue.
807 ExprResult TransformRequiresTypeParams(
808 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
809 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
810 SmallVectorImpl<QualType> &PTypes,
811 SmallVectorImpl<ParmVarDecl *> &TransParams,
812 Sema::ExtParameterInfoBuilder &PInfos) {
813 if (getDerived().TransformFunctionTypeParams(
814 KWLoc, Params, /*ParamTypes=*/nullptr,
815 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
816 return ExprError();
817
818 return ExprResult{};
819 }
820
821 /// Transforms a single function-type parameter. Return null
822 /// on error.
823 ///
824 /// \param indexAdjustment - A number to add to the parameter's
825 /// scope index; can be negative
826 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
827 int indexAdjustment,
828 UnsignedOrNone NumExpansions,
829 bool ExpectParameterPack);
830
831 /// Transform the body of a lambda-expression.
832 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
833 /// Alternative implementation of TransformLambdaBody that skips transforming
834 /// the body.
835 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
836
837 CXXRecordDecl::LambdaDependencyKind
838 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
839 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
840 LSI->Lambda->getLambdaDependencyKind());
841 }
842
843 ExprResult TransformLambdaConstraint(Expr *AC) { return AC; }
844
845 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
846
847 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
848 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
849
850 TemplateParameterList *TransformTemplateParameterList(
851 TemplateParameterList *TPL) {
852 return TPL;
853 }
854
855 ExprResult TransformAddressOfOperand(Expr *E);
856
857 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
858 bool IsAddressOfOperand,
859 TypeSourceInfo **RecoveryTSI);
860
861 ExprResult TransformParenDependentScopeDeclRefExpr(
862 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
863 TypeSourceInfo **RecoveryTSI);
864
865 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
866 bool IsAddressOfOperand);
867
868 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
869
870 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
871
872// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
873// amount of stack usage with clang.
874#define STMT(Node, Parent) \
875 LLVM_ATTRIBUTE_NOINLINE \
876 StmtResult Transform##Node(Node *S);
877#define VALUESTMT(Node, Parent) \
878 LLVM_ATTRIBUTE_NOINLINE \
879 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
880#define EXPR(Node, Parent) \
881 LLVM_ATTRIBUTE_NOINLINE \
882 ExprResult Transform##Node(Node *E);
883#define ABSTRACT_STMT(Stmt)
884#include "clang/AST/StmtNodes.inc"
885
886#define GEN_CLANG_CLAUSE_CLASS
887#define CLAUSE_CLASS(Enum, Str, Class) \
888 LLVM_ATTRIBUTE_NOINLINE \
889 OMPClause *Transform##Class(Class *S);
890#include "llvm/Frontend/OpenMP/OMP.inc"
891
892 /// Build a new qualified type given its unqualified type and type location.
893 ///
894 /// By default, this routine adds type qualifiers only to types that can
895 /// have qualifiers, and silently suppresses those qualifiers that are not
896 /// permitted. Subclasses may override this routine to provide different
897 /// behavior.
898 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
899
900 /// Build a new pointer type given its pointee type.
901 ///
902 /// By default, performs semantic analysis when building the pointer type.
903 /// Subclasses may override this routine to provide different behavior.
904 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
905
906 /// Build a new block pointer type given its pointee type.
907 ///
908 /// By default, performs semantic analysis when building the block pointer
909 /// type. Subclasses may override this routine to provide different behavior.
910 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
911
912 /// Build a new reference type given the type it references.
913 ///
914 /// By default, performs semantic analysis when building the
915 /// reference type. Subclasses may override this routine to provide
916 /// different behavior.
917 ///
918 /// \param LValue whether the type was written with an lvalue sigil
919 /// or an rvalue sigil.
920 QualType RebuildReferenceType(QualType ReferentType,
921 bool LValue,
922 SourceLocation Sigil);
923
924 /// Build a new member pointer type given the pointee type and the
925 /// qualifier it refers into.
926 ///
927 /// By default, performs semantic analysis when building the member pointer
928 /// type. Subclasses may override this routine to provide different behavior.
929 QualType RebuildMemberPointerType(QualType PointeeType,
930 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
931 SourceLocation Sigil);
932
933 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
934 SourceLocation ProtocolLAngleLoc,
935 ArrayRef<ObjCProtocolDecl *> Protocols,
936 ArrayRef<SourceLocation> ProtocolLocs,
937 SourceLocation ProtocolRAngleLoc);
938
939 /// Build an Objective-C object type.
940 ///
941 /// By default, performs semantic analysis when building the object type.
942 /// Subclasses may override this routine to provide different behavior.
943 QualType RebuildObjCObjectType(QualType BaseType,
944 SourceLocation Loc,
945 SourceLocation TypeArgsLAngleLoc,
946 ArrayRef<TypeSourceInfo *> TypeArgs,
947 SourceLocation TypeArgsRAngleLoc,
948 SourceLocation ProtocolLAngleLoc,
949 ArrayRef<ObjCProtocolDecl *> Protocols,
950 ArrayRef<SourceLocation> ProtocolLocs,
951 SourceLocation ProtocolRAngleLoc);
952
953 /// Build a new Objective-C object pointer type given the pointee type.
954 ///
955 /// By default, directly builds the pointer type, with no additional semantic
956 /// analysis.
957 QualType RebuildObjCObjectPointerType(QualType PointeeType,
958 SourceLocation Star);
959
960 /// Build a new array type given the element type, size
961 /// modifier, size of the array (if known), size expression, and index type
962 /// qualifiers.
963 ///
964 /// By default, performs semantic analysis when building the array type.
965 /// Subclasses may override this routine to provide different behavior.
966 /// Also by default, all of the other Rebuild*Array
967 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
968 const llvm::APInt *Size, Expr *SizeExpr,
969 unsigned IndexTypeQuals, SourceRange BracketsRange);
970
971 /// Build a new constant array type given the element type, size
972 /// modifier, (known) size of the array, and index type qualifiers.
973 ///
974 /// By default, performs semantic analysis when building the array type.
975 /// Subclasses may override this routine to provide different behavior.
976 QualType RebuildConstantArrayType(QualType ElementType,
977 ArraySizeModifier SizeMod,
978 const llvm::APInt &Size, Expr *SizeExpr,
979 unsigned IndexTypeQuals,
980 SourceRange BracketsRange);
981
982 /// Build a new incomplete array type given the element type, size
983 /// modifier, and index type qualifiers.
984 ///
985 /// By default, performs semantic analysis when building the array type.
986 /// Subclasses may override this routine to provide different behavior.
987 QualType RebuildIncompleteArrayType(QualType ElementType,
988 ArraySizeModifier SizeMod,
989 unsigned IndexTypeQuals,
990 SourceRange BracketsRange);
991
992 /// Build a new variable-length array type given the element type,
993 /// size modifier, size expression, and index type qualifiers.
994 ///
995 /// By default, performs semantic analysis when building the array type.
996 /// Subclasses may override this routine to provide different behavior.
997 QualType RebuildVariableArrayType(QualType ElementType,
998 ArraySizeModifier SizeMod, Expr *SizeExpr,
999 unsigned IndexTypeQuals,
1000 SourceRange BracketsRange);
1001
1002 /// Build a new dependent-sized array type given the element type,
1003 /// size modifier, size expression, and index type qualifiers.
1004 ///
1005 /// By default, performs semantic analysis when building the array type.
1006 /// Subclasses may override this routine to provide different behavior.
1007 QualType RebuildDependentSizedArrayType(QualType ElementType,
1008 ArraySizeModifier SizeMod,
1009 Expr *SizeExpr,
1010 unsigned IndexTypeQuals,
1011 SourceRange BracketsRange);
1012
1013 /// Build a new vector type given the element type and
1014 /// number of elements.
1015 ///
1016 /// By default, performs semantic analysis when building the vector type.
1017 /// Subclasses may override this routine to provide different behavior.
1018 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
1019 VectorKind VecKind);
1020
1021 /// Build a new potentially dependently-sized extended vector type
1022 /// given the element type and number of elements.
1023 ///
1024 /// By default, performs semantic analysis when building the vector type.
1025 /// Subclasses may override this routine to provide different behavior.
1026 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
1027 SourceLocation AttributeLoc, VectorKind);
1028
1029 /// Build a new extended vector type given the element type and
1030 /// number of elements.
1031 ///
1032 /// By default, performs semantic analysis when building the vector type.
1033 /// Subclasses may override this routine to provide different behavior.
1034 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
1035 SourceLocation AttributeLoc);
1036
1037 /// Build a new potentially dependently-sized extended vector type
1038 /// given the element type and number of elements.
1039 ///
1040 /// By default, performs semantic analysis when building the vector type.
1041 /// Subclasses may override this routine to provide different behavior.
1042 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
1043 Expr *SizeExpr,
1044 SourceLocation AttributeLoc);
1045
1046 /// Build a new matrix type given the element type and dimensions.
1047 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
1048 unsigned NumColumns,
1049 SourceLocation AttributeLoc);
1050
1051 /// Build a new matrix type given the type and dependently-defined
1052 /// dimensions.
1053 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1054 Expr *ColumnExpr,
1055 SourceLocation AttributeLoc);
1056
1057 /// Build a new DependentAddressSpaceType or return the pointee
1058 /// type variable with the correct address space (retrieved from
1059 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1060 /// where the address space remains dependent.
1061 ///
1062 /// By default, performs semantic analysis when building the type with address
1063 /// space applied. Subclasses may override this routine to provide different
1064 /// behavior.
1065 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1066 Expr *AddrSpaceExpr,
1067 SourceLocation AttributeLoc);
1068
1069 /// Build a new function type.
1070 ///
1071 /// By default, performs semantic analysis when building the function type.
1072 /// Subclasses may override this routine to provide different behavior.
1073 QualType RebuildFunctionProtoType(QualType T,
1074 MutableArrayRef<QualType> ParamTypes,
1075 const FunctionProtoType::ExtProtoInfo &EPI);
1076
1077 /// Build a new unprototyped function type.
1078 QualType RebuildFunctionNoProtoType(QualType ResultType);
1079
1080 /// Rebuild an unresolved typename type, given the decl that
1081 /// the UnresolvedUsingTypenameDecl was transformed to.
1082 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1083 NestedNameSpecifier Qualifier,
1084 SourceLocation NameLoc, Decl *D);
1085
1086 /// Build a new type found via an alias.
1087 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1088 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1089 QualType UnderlyingType) {
1090 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1091 }
1092
1093 /// Build a new typedef type.
1094 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1095 NestedNameSpecifier Qualifier,
1096 TypedefNameDecl *Typedef) {
1097 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1098 }
1099
1100 /// Build a new MacroDefined type.
1101 QualType RebuildMacroQualifiedType(QualType T,
1102 const IdentifierInfo *MacroII) {
1103 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1104 }
1105
1106 /// Build a new class/struct/union/enum type.
1107 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1108 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1109 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1110 /*OwnsTag=*/OwnsTag: false);
1111 }
1112 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1113 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1114 }
1115
1116 /// Build a new typeof(expr) type.
1117 ///
1118 /// By default, performs semantic analysis when building the typeof type.
1119 /// Subclasses may override this routine to provide different behavior.
1120 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1121 TypeOfKind Kind);
1122
1123 /// Build a new typeof(type) type.
1124 ///
1125 /// By default, builds a new TypeOfType with the given underlying type.
1126 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1127
1128 /// Build a new unary transform type.
1129 QualType RebuildUnaryTransformType(QualType BaseType,
1130 UnaryTransformType::UTTKind UKind,
1131 SourceLocation Loc);
1132
1133 /// Build a new C++11 decltype type.
1134 ///
1135 /// By default, performs semantic analysis when building the decltype type.
1136 /// Subclasses may override this routine to provide different behavior.
1137 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1138
1139 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1140 SourceLocation Loc, bool FullySubstituted,
1141 ArrayRef<QualType> Expansions = {});
1142
1143 /// Build a new C++11 auto type.
1144 ///
1145 /// By default, builds a new AutoType with the given deduced type.
1146 QualType RebuildAutoType(DeducedKind DK, QualType DeducedAsType,
1147 AutoTypeKeyword Keyword,
1148 TemplateName TypeConstraintConcept,
1149 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1150 return SemaRef.Context.getAutoType(
1151 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1152 }
1153
1154 /// By default, builds a new DeducedTemplateSpecializationType with the given
1155 /// deduced type.
1156 QualType RebuildDeducedTemplateSpecializationType(
1157 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1158 TemplateName Template) {
1159 return SemaRef.Context.getDeducedTemplateSpecializationType(
1160 DK, DeducedAsType, Keyword, Template);
1161 }
1162
1163 /// Build a new template specialization type.
1164 ///
1165 /// By default, performs semantic analysis when building the template
1166 /// specialization type. Subclasses may override this routine to provide
1167 /// different behavior.
1168 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1169 TemplateName Template,
1170 SourceLocation TemplateLoc,
1171 TemplateArgumentListInfo &Args);
1172
1173 /// Build a new parenthesized type.
1174 ///
1175 /// By default, builds a new ParenType type from the inner type.
1176 /// Subclasses may override this routine to provide different behavior.
1177 QualType RebuildParenType(QualType InnerType) {
1178 return SemaRef.BuildParenType(T: InnerType);
1179 }
1180
1181 /// Build a new typename type that refers to an identifier.
1182 ///
1183 /// By default, performs semantic analysis when building the typename type
1184 /// (or elaborated type). Subclasses may override this routine to provide
1185 /// different behavior.
1186 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1187 SourceLocation KeywordLoc,
1188 NestedNameSpecifierLoc QualifierLoc,
1189 const IdentifierInfo *Id,
1190 SourceLocation IdLoc,
1191 bool DeducedTSTContext) {
1192 CXXScopeSpec SS;
1193 SS.Adopt(Other: QualifierLoc);
1194
1195 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1196 // If the name is still dependent, just build a new dependent name type.
1197 if (!SemaRef.computeDeclContext(SS))
1198 return SemaRef.Context.getDependentNameType(Keyword,
1199 NNS: QualifierLoc.getNestedNameSpecifier(),
1200 Name: Id);
1201 }
1202
1203 if (Keyword == ElaboratedTypeKeyword::None ||
1204 Keyword == ElaboratedTypeKeyword::Typename) {
1205 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1206 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1207 }
1208
1209 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1210
1211 // We had a dependent elaborated-type-specifier that has been transformed
1212 // into a non-dependent elaborated-type-specifier. Find the tag we're
1213 // referring to.
1214 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1215 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1216 if (!DC)
1217 return QualType();
1218
1219 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1220 return QualType();
1221
1222 TagDecl *Tag = nullptr;
1223 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1224 switch (Result.getResultKind()) {
1225 case LookupResultKind::NotFound:
1226 case LookupResultKind::NotFoundInCurrentInstantiation:
1227 break;
1228
1229 case LookupResultKind::Found:
1230 Tag = Result.getAsSingle<TagDecl>();
1231 break;
1232
1233 case LookupResultKind::FoundOverloaded:
1234 case LookupResultKind::FoundUnresolvedValue:
1235 llvm_unreachable("Tag lookup cannot find non-tags");
1236
1237 case LookupResultKind::Ambiguous:
1238 // Let the LookupResult structure handle ambiguities.
1239 return QualType();
1240 }
1241
1242 if (!Tag) {
1243 // Check where the name exists but isn't a tag type and use that to emit
1244 // better diagnostics.
1245 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1246 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1247 switch (Result.getResultKind()) {
1248 case LookupResultKind::Found:
1249 case LookupResultKind::FoundOverloaded:
1250 case LookupResultKind::FoundUnresolvedValue: {
1251 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1252 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1253 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1254 << SomeDecl << NTK << Kind;
1255 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1256 break;
1257 }
1258 default:
1259 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1260 << Kind << Id << DC << QualifierLoc.getSourceRange();
1261 break;
1262 }
1263 return QualType();
1264 }
1265 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1266 NewTagLoc: IdLoc, Name: Id)) {
1267 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1268 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1269 return QualType();
1270 }
1271 return getDerived().RebuildTagType(
1272 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1273 }
1274
1275 /// Build a new pack expansion type.
1276 ///
1277 /// By default, builds a new PackExpansionType type from the given pattern.
1278 /// Subclasses may override this routine to provide different behavior.
1279 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1280 SourceLocation EllipsisLoc,
1281 UnsignedOrNone NumExpansions) {
1282 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1283 NumExpansions);
1284 }
1285
1286 /// Build a new atomic type given its value type.
1287 ///
1288 /// By default, performs semantic analysis when building the atomic type.
1289 /// Subclasses may override this routine to provide different behavior.
1290 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1291
1292 /// Build a new pipe type given its value type.
1293 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1294 bool isReadPipe);
1295
1296 /// Build a bit-precise int given its value type.
1297 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1298 SourceLocation Loc);
1299
1300 /// Build a dependent bit-precise int given its value type.
1301 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1302 SourceLocation Loc);
1303
1304 /// Build a new template name given a nested name specifier, a flag
1305 /// indicating whether the "template" keyword was provided, and the template
1306 /// that the template name refers to.
1307 ///
1308 /// By default, builds the new template name directly. Subclasses may override
1309 /// this routine to provide different behavior.
1310 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1311 TemplateName Name);
1312
1313 /// Build a new template name given a nested name specifier and the
1314 /// name that is referred to as a template.
1315 ///
1316 /// By default, performs semantic analysis to determine whether the name can
1317 /// be resolved to a specific template, then builds the appropriate kind of
1318 /// template name. Subclasses may override this routine to provide different
1319 /// behavior.
1320 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1321 SourceLocation TemplateKWLoc,
1322 const IdentifierInfo &Name,
1323 SourceLocation NameLoc, QualType ObjectType,
1324 bool AllowInjectedClassName);
1325
1326 /// Build a new template name given a nested name specifier and the
1327 /// overloaded operator name that is referred to as a template.
1328 ///
1329 /// By default, performs semantic analysis to determine whether the name can
1330 /// be resolved to a specific template, then builds the appropriate kind of
1331 /// template name. Subclasses may override this routine to provide different
1332 /// behavior.
1333 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1334 SourceLocation TemplateKWLoc,
1335 OverloadedOperatorKind Operator,
1336 SourceLocation NameLoc, QualType ObjectType,
1337 bool AllowInjectedClassName);
1338
1339 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1340 SourceLocation TemplateKWLoc,
1341 IdentifierOrOverloadedOperator IO,
1342 SourceLocation NameLoc, QualType ObjectType,
1343 bool AllowInjectedClassName);
1344
1345 /// Build a new template name given a template template parameter pack
1346 /// and the
1347 ///
1348 /// By default, performs semantic analysis to determine whether the name can
1349 /// be resolved to a specific template, then builds the appropriate kind of
1350 /// template name. Subclasses may override this routine to provide different
1351 /// behavior.
1352 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1353 Decl *AssociatedDecl, unsigned Index,
1354 bool Final) {
1355 return getSema().Context.getSubstTemplateTemplateParmPack(
1356 ArgPack, AssociatedDecl, Index, Final);
1357 }
1358
1359 /// Build a new pack-index-template-name ([temp.names]).
1360 ///
1361 /// By default, performs semantic analysis to build the new template name.
1362 /// Subclasses may override this routine to provide different behavior.
1363 TemplateName
1364 RebuildPackIndexingTemplateName(TemplateName Pattern, Expr *IndexExpr,
1365 bool FullySubstituted,
1366 ArrayRef<TemplateName> Expansions = {}) {
1367 return getSema().BuildPackIndexingTemplateName(
1368 Pattern, IndexExpr, FullySubstituted, Expansions);
1369 }
1370
1371 /// Build a new compound statement.
1372 ///
1373 /// By default, performs semantic analysis to build the new statement.
1374 /// Subclasses may override this routine to provide different behavior.
1375 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1376 MultiStmtArg Statements,
1377 SourceLocation RBraceLoc,
1378 bool IsStmtExpr) {
1379 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1380 IsStmtExpr);
1381 }
1382
1383 /// Build a new case statement.
1384 ///
1385 /// By default, performs semantic analysis to build the new statement.
1386 /// Subclasses may override this routine to provide different behavior.
1387 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1388 Expr *LHS,
1389 SourceLocation EllipsisLoc,
1390 Expr *RHS,
1391 SourceLocation ColonLoc) {
1392 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1393 ColonLoc);
1394 }
1395
1396 /// Attach the body to a new case statement.
1397 ///
1398 /// By default, performs semantic analysis to build the new statement.
1399 /// Subclasses may override this routine to provide different behavior.
1400 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1401 getSema().ActOnCaseStmtBody(S, Body);
1402 return S;
1403 }
1404
1405 /// Build a new default statement.
1406 ///
1407 /// By default, performs semantic analysis to build the new statement.
1408 /// Subclasses may override this routine to provide different behavior.
1409 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1410 SourceLocation ColonLoc,
1411 Stmt *SubStmt) {
1412 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1413 /*CurScope=*/nullptr);
1414 }
1415
1416 /// Build a new label statement.
1417 ///
1418 /// By default, performs semantic analysis to build the new statement.
1419 /// Subclasses may override this routine to provide different behavior.
1420 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1421 SourceLocation ColonLoc, Stmt *SubStmt) {
1422 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1423 }
1424
1425 /// Build a new attributed statement.
1426 ///
1427 /// By default, performs semantic analysis to build the new statement.
1428 /// Subclasses may override this routine to provide different behavior.
1429 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1430 ArrayRef<const Attr *> Attrs,
1431 Stmt *SubStmt) {
1432 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1433 return StmtError();
1434 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1435 }
1436
1437 /// Build a new "if" statement.
1438 ///
1439 /// By default, performs semantic analysis to build the new statement.
1440 /// Subclasses may override this routine to provide different behavior.
1441 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1442 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1443 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1444 SourceLocation ElseLoc, Stmt *Else) {
1445 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1446 Then, ElseLoc, Else);
1447 }
1448
1449 /// Start building a new switch statement.
1450 ///
1451 /// By default, performs semantic analysis to build the new statement.
1452 /// Subclasses may override this routine to provide different behavior.
1453 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1454 SourceLocation LParenLoc, Stmt *Init,
1455 Sema::ConditionResult Cond,
1456 SourceLocation RParenLoc) {
1457 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1458 RParenLoc);
1459 }
1460
1461 /// Attach the body to the switch statement.
1462 ///
1463 /// By default, performs semantic analysis to build the new statement.
1464 /// Subclasses may override this routine to provide different behavior.
1465 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1466 Stmt *Switch, Stmt *Body) {
1467 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1468 }
1469
1470 /// Build a new while statement.
1471 ///
1472 /// By default, performs semantic analysis to build the new statement.
1473 /// Subclasses may override this routine to provide different behavior.
1474 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1475 Sema::ConditionResult Cond,
1476 SourceLocation RParenLoc, Stmt *Body) {
1477 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1478 }
1479
1480 /// Build a new do-while statement.
1481 ///
1482 /// By default, performs semantic analysis to build the new statement.
1483 /// Subclasses may override this routine to provide different behavior.
1484 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1485 SourceLocation WhileLoc, SourceLocation LParenLoc,
1486 Expr *Cond, SourceLocation RParenLoc) {
1487 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1488 Cond, RParenLoc);
1489 }
1490
1491 /// Build a new for statement.
1492 ///
1493 /// By default, performs semantic analysis to build the new statement.
1494 /// Subclasses may override this routine to provide different behavior.
1495 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1496 Stmt *Init, Sema::ConditionResult Cond,
1497 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1498 Stmt *Body) {
1499 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1500 Inc, RParenLoc, Body);
1501 }
1502
1503 /// Build a new goto statement.
1504 ///
1505 /// By default, performs semantic analysis to build the new statement.
1506 /// Subclasses may override this routine to provide different behavior.
1507 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1508 LabelDecl *Label) {
1509 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1510 }
1511
1512 /// Build a new indirect goto statement.
1513 ///
1514 /// By default, performs semantic analysis to build the new statement.
1515 /// Subclasses may override this routine to provide different behavior.
1516 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1517 SourceLocation StarLoc,
1518 Expr *Target) {
1519 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1520 }
1521
1522 /// Build a new return statement.
1523 ///
1524 /// By default, performs semantic analysis to build the new statement.
1525 /// Subclasses may override this routine to provide different behavior.
1526 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1527 return getSema().BuildReturnStmt(ReturnLoc, Result);
1528 }
1529
1530 /// Build a new declaration statement.
1531 ///
1532 /// By default, performs semantic analysis to build the new statement.
1533 /// Subclasses may override this routine to provide different behavior.
1534 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1535 SourceLocation StartLoc, SourceLocation EndLoc) {
1536 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1537 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1538 }
1539
1540 /// Build a new inline asm statement.
1541 ///
1542 /// By default, performs semantic analysis to build the new statement.
1543 /// Subclasses may override this routine to provide different behavior.
1544 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1545 bool IsVolatile, unsigned NumOutputs,
1546 unsigned NumInputs, IdentifierInfo **Names,
1547 MultiExprArg Constraints, MultiExprArg Exprs,
1548 Expr *AsmString, MultiExprArg Clobbers,
1549 unsigned NumLabels,
1550 SourceLocation RParenLoc) {
1551 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1552 NumInputs, Names, Constraints, Exprs,
1553 AsmString, Clobbers, NumLabels, RParenLoc);
1554 }
1555
1556 /// Build a new MS style inline asm statement.
1557 ///
1558 /// By default, performs semantic analysis to build the new statement.
1559 /// Subclasses may override this routine to provide different behavior.
1560 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1561 ArrayRef<Token> AsmToks,
1562 StringRef AsmString,
1563 unsigned NumOutputs, unsigned NumInputs,
1564 ArrayRef<StringRef> Constraints,
1565 ArrayRef<StringRef> Clobbers,
1566 ArrayRef<Expr*> Exprs,
1567 SourceLocation EndLoc) {
1568 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1569 NumOutputs, NumInputs,
1570 Constraints, Clobbers, Exprs, EndLoc);
1571 }
1572
1573 /// Build a new co_return statement.
1574 ///
1575 /// By default, performs semantic analysis to build the new statement.
1576 /// Subclasses may override this routine to provide different behavior.
1577 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1578 bool IsImplicit) {
1579 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1580 }
1581
1582 /// Build a new co_await expression.
1583 ///
1584 /// By default, performs semantic analysis to build the new expression.
1585 /// Subclasses may override this routine to provide different behavior.
1586 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1587 UnresolvedLookupExpr *OpCoawaitLookup,
1588 bool IsImplicit) {
1589 // This function rebuilds a coawait-expr given its operator.
1590 // For an explicit coawait-expr, the rebuild involves the full set
1591 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1592 // including calling await_transform().
1593 // For an implicit coawait-expr, we need to rebuild the "operator
1594 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1595 // This mirrors how the implicit CoawaitExpr is originally created
1596 // in Sema::ActOnCoroutineBodyStart().
1597 if (IsImplicit) {
1598 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1599 CoawaitLoc, Operand, OpCoawaitLookup);
1600 if (Suspend.isInvalid())
1601 return ExprError();
1602 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1603 Suspend.get(), true);
1604 }
1605
1606 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1607 OpCoawaitLookup);
1608 }
1609
1610 /// Build a new co_await expression.
1611 ///
1612 /// By default, performs semantic analysis to build the new expression.
1613 /// Subclasses may override this routine to provide different behavior.
1614 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1615 Expr *Result,
1616 UnresolvedLookupExpr *Lookup) {
1617 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1618 }
1619
1620 /// Build a new co_yield expression.
1621 ///
1622 /// By default, performs semantic analysis to build the new expression.
1623 /// Subclasses may override this routine to provide different behavior.
1624 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1625 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1626 }
1627
1628 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1629 return getSema().BuildCoroutineBodyStmt(Args);
1630 }
1631
1632 /// Build a new Objective-C \@try statement.
1633 ///
1634 /// By default, performs semantic analysis to build the new statement.
1635 /// Subclasses may override this routine to provide different behavior.
1636 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1637 Stmt *TryBody,
1638 MultiStmtArg CatchStmts,
1639 Stmt *Finally) {
1640 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1641 Finally);
1642 }
1643
1644 /// Rebuild an Objective-C exception declaration.
1645 ///
1646 /// By default, performs semantic analysis to build the new declaration.
1647 /// Subclasses may override this routine to provide different behavior.
1648 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1649 TypeSourceInfo *TInfo, QualType T) {
1650 return getSema().ObjC().BuildObjCExceptionDecl(
1651 TInfo, T, ExceptionDecl->getInnerLocStart(),
1652 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1653 }
1654
1655 /// Build a new Objective-C \@catch statement.
1656 ///
1657 /// By default, performs semantic analysis to build the new statement.
1658 /// Subclasses may override this routine to provide different behavior.
1659 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1660 SourceLocation RParenLoc,
1661 VarDecl *Var,
1662 Stmt *Body) {
1663 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1664 }
1665
1666 /// Build a new Objective-C \@finally statement.
1667 ///
1668 /// By default, performs semantic analysis to build the new statement.
1669 /// Subclasses may override this routine to provide different behavior.
1670 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1671 Stmt *Body) {
1672 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1673 }
1674
1675 /// Build a new Objective-C \@throw statement.
1676 ///
1677 /// By default, performs semantic analysis to build the new statement.
1678 /// Subclasses may override this routine to provide different behavior.
1679 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1680 Expr *Operand) {
1681 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1682 }
1683
1684 /// Build a new OpenMP Canonical loop.
1685 ///
1686 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1687 /// OMPCanonicalLoop.
1688 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1689 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1690 }
1691
1692 /// Build a new OpenMP executable directive.
1693 ///
1694 /// By default, performs semantic analysis to build the new statement.
1695 /// Subclasses may override this routine to provide different behavior.
1696 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1697 DeclarationNameInfo DirName,
1698 OpenMPDirectiveKind CancelRegion,
1699 ArrayRef<OMPClause *> Clauses,
1700 Stmt *AStmt, SourceLocation StartLoc,
1701 SourceLocation EndLoc) {
1702
1703 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1704 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1705 }
1706
1707 /// Build a new OpenMP informational directive.
1708 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1709 DeclarationNameInfo DirName,
1710 ArrayRef<OMPClause *> Clauses,
1711 Stmt *AStmt,
1712 SourceLocation StartLoc,
1713 SourceLocation EndLoc) {
1714
1715 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1716 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1717 }
1718
1719 /// Build a new OpenMP 'if' clause.
1720 ///
1721 /// By default, performs semantic analysis to build the new OpenMP clause.
1722 /// Subclasses may override this routine to provide different behavior.
1723 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1724 Expr *Condition, SourceLocation StartLoc,
1725 SourceLocation LParenLoc,
1726 SourceLocation NameModifierLoc,
1727 SourceLocation ColonLoc,
1728 SourceLocation EndLoc) {
1729 return getSema().OpenMP().ActOnOpenMPIfClause(
1730 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1731 EndLoc);
1732 }
1733
1734 /// Build a new OpenMP 'final' clause.
1735 ///
1736 /// By default, performs semantic analysis to build the new OpenMP clause.
1737 /// Subclasses may override this routine to provide different behavior.
1738 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1739 SourceLocation LParenLoc,
1740 SourceLocation EndLoc) {
1741 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1742 LParenLoc, EndLoc);
1743 }
1744
1745 /// Build a new OpenMP 'num_threads' clause.
1746 ///
1747 /// By default, performs semantic analysis to build the new OpenMP clause.
1748 /// Subclasses may override this routine to provide different behavior.
1749 OMPClause *RebuildOMPNumThreadsClause(
1750 ArrayRef<Expr *> VarList,
1751 OpenMPNumThreadsClauseModifier PrescriptivenessModifier,
1752 SourceLocation PrescriptivenessModifierLoc,
1753 OpenMPNumThreadsClauseModifier DimsModifier, Expr *DimsModifierExpr,
1754 SourceLocation DimsModifierLoc, SourceLocation StartLoc,
1755 SourceLocation LParenLoc, SourceLocation EndLoc) {
1756 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1757 VarList, PrescriptivenessModifier, PrescriptivenessModifierLoc,
1758 DimsModifier, DimsModifierExpr, DimsModifierLoc, StartLoc, LParenLoc,
1759 EndLoc);
1760 }
1761
1762 /// Build a new OpenMP 'safelen' clause.
1763 ///
1764 /// By default, performs semantic analysis to build the new OpenMP clause.
1765 /// Subclasses may override this routine to provide different behavior.
1766 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1767 SourceLocation LParenLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1770 EndLoc);
1771 }
1772
1773 /// Build a new OpenMP 'simdlen' clause.
1774 ///
1775 /// By default, performs semantic analysis to build the new OpenMP clause.
1776 /// Subclasses may override this routine to provide different behavior.
1777 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1778 SourceLocation LParenLoc,
1779 SourceLocation EndLoc) {
1780 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1781 EndLoc);
1782 }
1783
1784 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1785 SourceLocation StartLoc,
1786 SourceLocation LParenLoc,
1787 SourceLocation EndLoc) {
1788 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1789 EndLoc);
1790 }
1791
1792 OMPClause *RebuildOMPCountsClause(ArrayRef<Expr *> Counts,
1793 SourceLocation StartLoc,
1794 SourceLocation LParenLoc,
1795 SourceLocation EndLoc,
1796 std::optional<unsigned> FillIdx,
1797 SourceLocation FillLoc) {
1798 unsigned FillCount = FillIdx ? 1 : 0;
1799 return getSema().OpenMP().ActOnOpenMPCountsClause(
1800 Counts, StartLoc, LParenLoc, EndLoc, FillIdx, FillLoc, FillCount);
1801 }
1802
1803 /// Build a new OpenMP 'permutation' clause.
1804 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1805 SourceLocation StartLoc,
1806 SourceLocation LParenLoc,
1807 SourceLocation EndLoc) {
1808 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1809 LParenLoc, EndLoc);
1810 }
1811
1812 /// Build a new OpenMP 'full' clause.
1813 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1814 SourceLocation EndLoc) {
1815 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1816 }
1817
1818 /// Build a new OpenMP 'partial' clause.
1819 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1820 SourceLocation LParenLoc,
1821 SourceLocation EndLoc) {
1822 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1823 LParenLoc, EndLoc);
1824 }
1825
1826 /// Build a new OpenMP 'depth' clause.
1827 OMPClause *RebuildOMPDepthClause(Expr *Depth, SourceLocation StartLoc,
1828 SourceLocation LParenLoc,
1829 SourceLocation EndLoc) {
1830 return getSema().OpenMP().ActOnOpenMPDepthClause(Depth, StartLoc, LParenLoc,
1831 EndLoc);
1832 }
1833
1834 OMPClause *
1835 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1836 SourceLocation LParenLoc, SourceLocation FirstLoc,
1837 SourceLocation CountLoc, SourceLocation EndLoc) {
1838 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1839 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1840 }
1841
1842 /// Build a new OpenMP 'allocator' clause.
1843 ///
1844 /// By default, performs semantic analysis to build the new OpenMP clause.
1845 /// Subclasses may override this routine to provide different behavior.
1846 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1847 SourceLocation LParenLoc,
1848 SourceLocation EndLoc) {
1849 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1850 EndLoc);
1851 }
1852
1853 /// Build a new OpenMP 'collapse' clause.
1854 ///
1855 /// By default, performs semantic analysis to build the new OpenMP clause.
1856 /// Subclasses may override this routine to provide different behavior.
1857 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1858 SourceLocation LParenLoc,
1859 SourceLocation EndLoc) {
1860 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1861 LParenLoc, EndLoc);
1862 }
1863
1864 /// Build a new OpenMP 'default' clause.
1865 ///
1866 /// By default, performs semantic analysis to build the new OpenMP clause.
1867 /// Subclasses may override this routine to provide different behavior.
1868 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1869 OpenMPDefaultClauseVariableCategory VCKind,
1870 SourceLocation VCLoc,
1871 SourceLocation StartLoc,
1872 SourceLocation LParenLoc,
1873 SourceLocation EndLoc) {
1874 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1875 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1876 }
1877
1878 /// Build a new OpenMP 'proc_bind' clause.
1879 ///
1880 /// By default, performs semantic analysis to build the new OpenMP clause.
1881 /// Subclasses may override this routine to provide different behavior.
1882 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1883 SourceLocation KindKwLoc,
1884 SourceLocation StartLoc,
1885 SourceLocation LParenLoc,
1886 SourceLocation EndLoc) {
1887 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1888 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1889 }
1890 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1891 SourceLocation StartLoc,
1892 SourceLocation LParenLoc,
1893 SourceLocation EndLoc) {
1894 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1895 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1896 }
1897
1898 /// Build a new OpenMP 'schedule' clause.
1899 ///
1900 /// By default, performs semantic analysis to build the new OpenMP clause.
1901 /// Subclasses may override this routine to provide different behavior.
1902 OMPClause *RebuildOMPScheduleClause(
1903 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1904 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1905 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1906 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1907 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1908 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1909 CommaLoc, EndLoc);
1910 }
1911
1912 /// Build a new OpenMP 'ordered' clause.
1913 ///
1914 /// By default, performs semantic analysis to build the new OpenMP clause.
1915 /// Subclasses may override this routine to provide different behavior.
1916 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1917 SourceLocation EndLoc,
1918 SourceLocation LParenLoc, Expr *Num) {
1919 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1920 LParenLoc, Num);
1921 }
1922
1923 /// Build a new OpenMP 'nowait' clause.
1924 ///
1925 /// By default, performs semantic analysis to build the new OpenMP clause.
1926 /// Subclasses may override this routine to provide different behavior.
1927 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1928 SourceLocation LParenLoc,
1929 SourceLocation EndLoc) {
1930 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1931 LParenLoc, Condition);
1932 }
1933
1934 /// Build a new OpenMP 'private' clause.
1935 ///
1936 /// By default, performs semantic analysis to build the new OpenMP clause.
1937 /// Subclasses may override this routine to provide different behavior.
1938 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1939 SourceLocation StartLoc,
1940 SourceLocation LParenLoc,
1941 SourceLocation EndLoc) {
1942 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1943 LParenLoc, EndLoc);
1944 }
1945
1946 /// Build a new OpenMP 'firstprivate' clause.
1947 ///
1948 /// By default, performs semantic analysis to build the new OpenMP clause.
1949 /// Subclasses may override this routine to provide different behavior.
1950 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1951 SourceLocation StartLoc,
1952 SourceLocation LParenLoc,
1953 SourceLocation EndLoc) {
1954 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1955 LParenLoc, EndLoc);
1956 }
1957
1958 /// Build a new OpenMP 'lastprivate' clause.
1959 ///
1960 /// By default, performs semantic analysis to build the new OpenMP clause.
1961 /// Subclasses may override this routine to provide different behavior.
1962 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1963 OpenMPLastprivateModifier LPKind,
1964 SourceLocation LPKindLoc,
1965 SourceLocation ColonLoc,
1966 SourceLocation StartLoc,
1967 SourceLocation LParenLoc,
1968 SourceLocation EndLoc) {
1969 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1970 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1971 }
1972
1973 /// Build a new OpenMP 'shared' clause.
1974 ///
1975 /// By default, performs semantic analysis to build the new OpenMP clause.
1976 /// Subclasses may override this routine to provide different behavior.
1977 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1978 SourceLocation StartLoc,
1979 SourceLocation LParenLoc,
1980 SourceLocation EndLoc) {
1981 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1982 LParenLoc, EndLoc);
1983 }
1984
1985 /// Build a new OpenMP 'reduction' clause.
1986 ///
1987 /// By default, performs semantic analysis to build the new statement.
1988 /// Subclasses may override this routine to provide different behavior.
1989 OMPClause *RebuildOMPReductionClause(
1990 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1991 OpenMPOriginalSharingModifier OriginalSharingModifier,
1992 SourceLocation StartLoc, SourceLocation LParenLoc,
1993 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1994 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1995 const DeclarationNameInfo &ReductionId,
1996 ArrayRef<Expr *> UnresolvedReductions) {
1997 return getSema().OpenMP().ActOnOpenMPReductionClause(
1998 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1999 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
2000 UnresolvedReductions);
2001 }
2002
2003 /// Build a new OpenMP 'task_reduction' clause.
2004 ///
2005 /// By default, performs semantic analysis to build the new statement.
2006 /// Subclasses may override this routine to provide different behavior.
2007 OMPClause *RebuildOMPTaskReductionClause(
2008 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2009 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
2010 CXXScopeSpec &ReductionIdScopeSpec,
2011 const DeclarationNameInfo &ReductionId,
2012 ArrayRef<Expr *> UnresolvedReductions) {
2013 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
2014 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2015 ReductionId, UnresolvedReductions);
2016 }
2017
2018 /// Build a new OpenMP 'in_reduction' clause.
2019 ///
2020 /// By default, performs semantic analysis to build the new statement.
2021 /// Subclasses may override this routine to provide different behavior.
2022 OMPClause *
2023 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2024 SourceLocation LParenLoc, SourceLocation ColonLoc,
2025 SourceLocation EndLoc,
2026 CXXScopeSpec &ReductionIdScopeSpec,
2027 const DeclarationNameInfo &ReductionId,
2028 ArrayRef<Expr *> UnresolvedReductions) {
2029 return getSema().OpenMP().ActOnOpenMPInReductionClause(
2030 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2031 ReductionId, UnresolvedReductions);
2032 }
2033
2034 /// Build a new OpenMP 'linear' clause.
2035 ///
2036 /// By default, performs semantic analysis to build the new OpenMP clause.
2037 /// Subclasses may override this routine to provide different behavior.
2038 OMPClause *RebuildOMPLinearClause(
2039 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2040 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2041 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2042 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2043 return getSema().OpenMP().ActOnOpenMPLinearClause(
2044 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2045 StepModifierLoc, EndLoc);
2046 }
2047
2048 /// Build a new OpenMP 'aligned' clause.
2049 ///
2050 /// By default, performs semantic analysis to build the new OpenMP clause.
2051 /// Subclasses may override this routine to provide different behavior.
2052 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2053 SourceLocation StartLoc,
2054 SourceLocation LParenLoc,
2055 SourceLocation ColonLoc,
2056 SourceLocation EndLoc) {
2057 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2058 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2059 }
2060
2061 /// Build a new OpenMP 'copyin' clause.
2062 ///
2063 /// By default, performs semantic analysis to build the new OpenMP clause.
2064 /// Subclasses may override this routine to provide different behavior.
2065 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2066 SourceLocation StartLoc,
2067 SourceLocation LParenLoc,
2068 SourceLocation EndLoc) {
2069 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2070 LParenLoc, EndLoc);
2071 }
2072
2073 /// Build a new OpenMP 'copyprivate' clause.
2074 ///
2075 /// By default, performs semantic analysis to build the new OpenMP clause.
2076 /// Subclasses may override this routine to provide different behavior.
2077 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2078 SourceLocation StartLoc,
2079 SourceLocation LParenLoc,
2080 SourceLocation EndLoc) {
2081 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2082 LParenLoc, EndLoc);
2083 }
2084
2085 /// Build a new OpenMP 'flush' pseudo clause.
2086 ///
2087 /// By default, performs semantic analysis to build the new OpenMP clause.
2088 /// Subclasses may override this routine to provide different behavior.
2089 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2090 SourceLocation StartLoc,
2091 SourceLocation LParenLoc,
2092 SourceLocation EndLoc) {
2093 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2094 LParenLoc, EndLoc);
2095 }
2096
2097 /// Build a new OpenMP 'depobj' pseudo clause.
2098 ///
2099 /// By default, performs semantic analysis to build the new OpenMP clause.
2100 /// Subclasses may override this routine to provide different behavior.
2101 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2102 SourceLocation LParenLoc,
2103 SourceLocation EndLoc) {
2104 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2105 LParenLoc, EndLoc);
2106 }
2107
2108 /// Build a new OpenMP 'depend' pseudo clause.
2109 ///
2110 /// By default, performs semantic analysis to build the new OpenMP clause.
2111 /// Subclasses may override this routine to provide different behavior.
2112 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2113 Expr *DepModifier, ArrayRef<Expr *> VarList,
2114 SourceLocation StartLoc,
2115 SourceLocation LParenLoc,
2116 SourceLocation EndLoc) {
2117 return getSema().OpenMP().ActOnOpenMPDependClause(
2118 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2119 }
2120
2121 /// Build a new OpenMP 'device' clause.
2122 ///
2123 /// By default, performs semantic analysis to build the new statement.
2124 /// Subclasses may override this routine to provide different behavior.
2125 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2126 Expr *Device, SourceLocation StartLoc,
2127 SourceLocation LParenLoc,
2128 SourceLocation ModifierLoc,
2129 SourceLocation EndLoc) {
2130 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2131 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2132 }
2133
2134 /// Build a new OpenMP 'map' clause.
2135 ///
2136 /// By default, performs semantic analysis to build the new OpenMP clause.
2137 /// Subclasses may override this routine to provide different behavior.
2138 OMPClause *RebuildOMPMapClause(
2139 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2140 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2141 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2142 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2143 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2144 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2145 return getSema().OpenMP().ActOnOpenMPMapClause(
2146 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2147 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2148 ColonLoc, VarList, Locs,
2149 /*NoDiagnose=*/false, UnresolvedMappers);
2150 }
2151
2152 /// Build a new OpenMP 'allocate' clause.
2153 ///
2154 /// By default, performs semantic analysis to build the new OpenMP clause.
2155 /// Subclasses may override this routine to provide different behavior.
2156 OMPClause *
2157 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2158 OpenMPAllocateClauseModifier FirstModifier,
2159 SourceLocation FirstModifierLoc,
2160 OpenMPAllocateClauseModifier SecondModifier,
2161 SourceLocation SecondModifierLoc,
2162 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2163 SourceLocation LParenLoc, SourceLocation ColonLoc,
2164 SourceLocation EndLoc) {
2165 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2166 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2167 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2168 }
2169
2170 /// Build a new OpenMP 'num_teams' clause.
2171 ///
2172 /// By default, performs semantic analysis to build the new statement.
2173 /// Subclasses may override this routine to provide different behavior.
2174 OMPClause *RebuildOMPNumTeamsClause(
2175 ArrayRef<Expr *> VarList, OpenMPNumTeamsClauseModifier Modifier,
2176 Expr *ModifierExpr, SourceLocation ModifierLoc,
2177 OpenMPNumTeamsClauseModifier ModifierExtra, Expr *ModifierExtraExpr,
2178 SourceLocation ModifierExtraLoc, SourceLocation StartLoc,
2179 SourceLocation LParenLoc, SourceLocation EndLoc) {
2180 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(
2181 VarList, Modifier, ModifierExpr, ModifierLoc, ModifierExtra,
2182 ModifierExtraExpr, ModifierExtraLoc, StartLoc, LParenLoc, EndLoc);
2183 }
2184
2185 /// Build a new OpenMP 'thread_limit' clause.
2186 ///
2187 /// By default, performs semantic analysis to build the new statement.
2188 /// Subclasses may override this routine to provide different behavior.
2189 OMPClause *RebuildOMPThreadLimitClause(
2190 ArrayRef<Expr *> VarList, OpenMPThreadLimitClauseModifier Modifier,
2191 Expr *ModifierExpr, SourceLocation ModifierLoc, SourceLocation StartLoc,
2192 SourceLocation LParenLoc, SourceLocation EndLoc) {
2193 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(
2194 VarList, Modifier, ModifierExpr, ModifierLoc, StartLoc, LParenLoc,
2195 EndLoc);
2196 }
2197
2198 /// Build a new OpenMP 'priority' clause.
2199 ///
2200 /// By default, performs semantic analysis to build the new statement.
2201 /// Subclasses may override this routine to provide different behavior.
2202 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2203 SourceLocation LParenLoc,
2204 SourceLocation EndLoc) {
2205 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2206 LParenLoc, EndLoc);
2207 }
2208
2209 /// Build a new OpenMP 'grainsize' clause.
2210 ///
2211 /// By default, performs semantic analysis to build the new statement.
2212 /// Subclasses may override this routine to provide different behavior.
2213 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2214 Expr *Device, SourceLocation StartLoc,
2215 SourceLocation LParenLoc,
2216 SourceLocation ModifierLoc,
2217 SourceLocation EndLoc) {
2218 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2219 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2220 }
2221
2222 /// Build a new OpenMP 'num_tasks' clause.
2223 ///
2224 /// By default, performs semantic analysis to build the new statement.
2225 /// Subclasses may override this routine to provide different behavior.
2226 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2227 Expr *NumTasks, SourceLocation StartLoc,
2228 SourceLocation LParenLoc,
2229 SourceLocation ModifierLoc,
2230 SourceLocation EndLoc) {
2231 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2232 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2233 }
2234
2235 /// Build a new OpenMP 'hint' clause.
2236 ///
2237 /// By default, performs semantic analysis to build the new statement.
2238 /// Subclasses may override this routine to provide different behavior.
2239 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2240 SourceLocation LParenLoc,
2241 SourceLocation EndLoc) {
2242 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2243 EndLoc);
2244 }
2245
2246 /// Build a new OpenMP 'detach' clause.
2247 ///
2248 /// By default, performs semantic analysis to build the new statement.
2249 /// Subclasses may override this routine to provide different behavior.
2250 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2251 SourceLocation LParenLoc,
2252 SourceLocation EndLoc) {
2253 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2254 EndLoc);
2255 }
2256
2257 /// Build a new OpenMP 'dist_schedule' clause.
2258 ///
2259 /// By default, performs semantic analysis to build the new OpenMP clause.
2260 /// Subclasses may override this routine to provide different behavior.
2261 OMPClause *
2262 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2263 Expr *ChunkSize, SourceLocation StartLoc,
2264 SourceLocation LParenLoc, SourceLocation KindLoc,
2265 SourceLocation CommaLoc, SourceLocation EndLoc) {
2266 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2267 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2268 }
2269
2270 /// Build a new OpenMP 'to' clause.
2271 ///
2272 /// By default, performs semantic analysis to build the new statement.
2273 /// Subclasses may override this routine to provide different behavior.
2274 OMPClause *
2275 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2276 ArrayRef<SourceLocation> MotionModifiersLoc,
2277 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2278 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2279 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2280 ArrayRef<Expr *> UnresolvedMappers) {
2281 return getSema().OpenMP().ActOnOpenMPToClause(
2282 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2283 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2284 UnresolvedMappers);
2285 }
2286
2287 /// Build a new OpenMP 'from' clause.
2288 ///
2289 /// By default, performs semantic analysis to build the new statement.
2290 /// Subclasses may override this routine to provide different behavior.
2291 OMPClause *
2292 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2293 ArrayRef<SourceLocation> MotionModifiersLoc,
2294 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2295 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2296 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2297 ArrayRef<Expr *> UnresolvedMappers) {
2298 return getSema().OpenMP().ActOnOpenMPFromClause(
2299 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2300 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2301 UnresolvedMappers);
2302 }
2303
2304 /// Build a new OpenMP 'use_device_ptr' clause.
2305 ///
2306 /// By default, performs semantic analysis to build the new OpenMP clause.
2307 /// Subclasses may override this routine to provide different behavior.
2308 OMPClause *RebuildOMPUseDevicePtrClause(
2309 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2310 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2311 SourceLocation FallbackModifierLoc) {
2312 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2313 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2314 }
2315
2316 /// Build a new OpenMP 'use_device_addr' clause.
2317 ///
2318 /// By default, performs semantic analysis to build the new OpenMP clause.
2319 /// Subclasses may override this routine to provide different behavior.
2320 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2321 const OMPVarListLocTy &Locs) {
2322 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2323 }
2324
2325 /// Build a new OpenMP 'is_device_ptr' clause.
2326 ///
2327 /// By default, performs semantic analysis to build the new OpenMP clause.
2328 /// Subclasses may override this routine to provide different behavior.
2329 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2330 const OMPVarListLocTy &Locs) {
2331 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2332 }
2333
2334 /// Build a new OpenMP 'has_device_addr' clause.
2335 ///
2336 /// By default, performs semantic analysis to build the new OpenMP clause.
2337 /// Subclasses may override this routine to provide different behavior.
2338 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2339 const OMPVarListLocTy &Locs) {
2340 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2341 }
2342
2343 /// Build a new OpenMP 'defaultmap' clause.
2344 ///
2345 /// By default, performs semantic analysis to build the new OpenMP clause.
2346 /// Subclasses may override this routine to provide different behavior.
2347 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2348 OpenMPDefaultmapClauseKind Kind,
2349 SourceLocation StartLoc,
2350 SourceLocation LParenLoc,
2351 SourceLocation MLoc,
2352 SourceLocation KindLoc,
2353 SourceLocation EndLoc) {
2354 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2355 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2356 }
2357
2358 /// Build a new OpenMP 'nontemporal' clause.
2359 ///
2360 /// By default, performs semantic analysis to build the new OpenMP clause.
2361 /// Subclasses may override this routine to provide different behavior.
2362 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2363 SourceLocation StartLoc,
2364 SourceLocation LParenLoc,
2365 SourceLocation EndLoc) {
2366 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2367 LParenLoc, EndLoc);
2368 }
2369
2370 /// Build a new OpenMP 'inclusive' clause.
2371 ///
2372 /// By default, performs semantic analysis to build the new OpenMP clause.
2373 /// Subclasses may override this routine to provide different behavior.
2374 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2375 SourceLocation StartLoc,
2376 SourceLocation LParenLoc,
2377 SourceLocation EndLoc) {
2378 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2379 LParenLoc, EndLoc);
2380 }
2381
2382 /// Build a new OpenMP 'exclusive' clause.
2383 ///
2384 /// By default, performs semantic analysis to build the new OpenMP clause.
2385 /// Subclasses may override this routine to provide different behavior.
2386 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2387 SourceLocation StartLoc,
2388 SourceLocation LParenLoc,
2389 SourceLocation EndLoc) {
2390 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2391 LParenLoc, EndLoc);
2392 }
2393
2394 /// Build a new OpenMP 'uses_allocators' clause.
2395 ///
2396 /// By default, performs semantic analysis to build the new OpenMP clause.
2397 /// Subclasses may override this routine to provide different behavior.
2398 OMPClause *RebuildOMPUsesAllocatorsClause(
2399 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2400 SourceLocation LParenLoc, SourceLocation EndLoc) {
2401 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2402 StartLoc, LParenLoc, EndLoc, Data);
2403 }
2404
2405 /// Build a new OpenMP 'affinity' clause.
2406 ///
2407 /// By default, performs semantic analysis to build the new OpenMP clause.
2408 /// Subclasses may override this routine to provide different behavior.
2409 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2410 SourceLocation LParenLoc,
2411 SourceLocation ColonLoc,
2412 SourceLocation EndLoc, Expr *Modifier,
2413 ArrayRef<Expr *> Locators) {
2414 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2415 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2416 }
2417
2418 /// Build a new OpenMP 'order' clause.
2419 ///
2420 /// By default, performs semantic analysis to build the new OpenMP clause.
2421 /// Subclasses may override this routine to provide different behavior.
2422 OMPClause *RebuildOMPOrderClause(
2423 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2424 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2425 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2426 return getSema().OpenMP().ActOnOpenMPOrderClause(
2427 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2428 }
2429
2430 /// Build a new OpenMP 'init' clause.
2431 ///
2432 /// By default, performs semantic analysis to build the new OpenMP clause.
2433 /// Subclasses may override this routine to provide different behavior.
2434 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2435 SourceLocation StartLoc,
2436 SourceLocation LParenLoc,
2437 SourceLocation VarLoc,
2438 SourceLocation EndLoc) {
2439 return getSema().OpenMP().ActOnOpenMPInitClause(
2440 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2441 }
2442
2443 /// Build a new OpenMP 'use' clause.
2444 ///
2445 /// By default, performs semantic analysis to build the new OpenMP clause.
2446 /// Subclasses may override this routine to provide different behavior.
2447 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2448 SourceLocation LParenLoc,
2449 SourceLocation VarLoc, SourceLocation EndLoc) {
2450 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2451 LParenLoc, VarLoc, EndLoc);
2452 }
2453
2454 /// Build a new OpenMP 'destroy' clause.
2455 ///
2456 /// By default, performs semantic analysis to build the new OpenMP clause.
2457 /// Subclasses may override this routine to provide different behavior.
2458 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2459 SourceLocation LParenLoc,
2460 SourceLocation VarLoc,
2461 SourceLocation EndLoc) {
2462 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2463 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2464 }
2465
2466 /// Build a new OpenMP 'novariants' clause.
2467 ///
2468 /// By default, performs semantic analysis to build the new OpenMP clause.
2469 /// Subclasses may override this routine to provide different behavior.
2470 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2471 SourceLocation StartLoc,
2472 SourceLocation LParenLoc,
2473 SourceLocation EndLoc) {
2474 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2475 LParenLoc, EndLoc);
2476 }
2477
2478 /// Build a new OpenMP 'nocontext' clause.
2479 ///
2480 /// By default, performs semantic analysis to build the new OpenMP clause.
2481 /// Subclasses may override this routine to provide different behavior.
2482 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2483 SourceLocation LParenLoc,
2484 SourceLocation EndLoc) {
2485 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2486 LParenLoc, EndLoc);
2487 }
2488
2489 /// Build a new OpenMP 'filter' clause.
2490 ///
2491 /// By default, performs semantic analysis to build the new OpenMP clause.
2492 /// Subclasses may override this routine to provide different behavior.
2493 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2494 SourceLocation LParenLoc,
2495 SourceLocation EndLoc) {
2496 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2497 LParenLoc, EndLoc);
2498 }
2499
2500 /// Build a new OpenMP 'bind' clause.
2501 ///
2502 /// By default, performs semantic analysis to build the new OpenMP clause.
2503 /// Subclasses may override this routine to provide different behavior.
2504 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2505 SourceLocation KindLoc,
2506 SourceLocation StartLoc,
2507 SourceLocation LParenLoc,
2508 SourceLocation EndLoc) {
2509 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2510 LParenLoc, EndLoc);
2511 }
2512
2513 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2514 ///
2515 /// By default, performs semantic analysis to build the new OpenMP clause.
2516 /// Subclasses may override this routine to provide different behavior.
2517 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2518 SourceLocation LParenLoc,
2519 SourceLocation EndLoc) {
2520 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2521 LParenLoc, EndLoc);
2522 }
2523
2524 /// Build a new OpenMP 'dyn_groupprivate' clause.
2525 ///
2526 /// By default, performs semantic analysis to build the new OpenMP clause.
2527 /// Subclasses may override this routine to provide different behavior.
2528 OMPClause *RebuildOMPDynGroupprivateClause(
2529 OpenMPDynGroupprivateClauseModifier M1,
2530 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2531 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2532 SourceLocation M2Loc, SourceLocation EndLoc) {
2533 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2534 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2535 }
2536
2537 /// Build a new OpenMP 'ompx_attribute' clause.
2538 ///
2539 /// By default, performs semantic analysis to build the new OpenMP clause.
2540 /// Subclasses may override this routine to provide different behavior.
2541 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2542 SourceLocation StartLoc,
2543 SourceLocation LParenLoc,
2544 SourceLocation EndLoc) {
2545 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2546 LParenLoc, EndLoc);
2547 }
2548
2549 /// Build a new OpenMP 'ompx_bare' clause.
2550 ///
2551 /// By default, performs semantic analysis to build the new OpenMP clause.
2552 /// Subclasses may override this routine to provide different behavior.
2553 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2554 SourceLocation EndLoc) {
2555 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2556 }
2557
2558 /// Build a new OpenMP 'align' clause.
2559 ///
2560 /// By default, performs semantic analysis to build the new OpenMP clause.
2561 /// Subclasses may override this routine to provide different behavior.
2562 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2563 SourceLocation LParenLoc,
2564 SourceLocation EndLoc) {
2565 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2566 EndLoc);
2567 }
2568
2569 /// Build a new OpenMP 'at' clause.
2570 ///
2571 /// By default, performs semantic analysis to build the new OpenMP clause.
2572 /// Subclasses may override this routine to provide different behavior.
2573 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2574 SourceLocation StartLoc,
2575 SourceLocation LParenLoc,
2576 SourceLocation EndLoc) {
2577 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2578 LParenLoc, EndLoc);
2579 }
2580
2581 /// Build a new OpenMP 'severity' clause.
2582 ///
2583 /// By default, performs semantic analysis to build the new OpenMP clause.
2584 /// Subclasses may override this routine to provide different behavior.
2585 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2586 SourceLocation KwLoc,
2587 SourceLocation StartLoc,
2588 SourceLocation LParenLoc,
2589 SourceLocation EndLoc) {
2590 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2591 LParenLoc, EndLoc);
2592 }
2593
2594 /// Build a new OpenMP 'message' clause.
2595 ///
2596 /// By default, performs semantic analysis to build the new OpenMP clause.
2597 /// Subclasses may override this routine to provide different behavior.
2598 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2599 SourceLocation LParenLoc,
2600 SourceLocation EndLoc) {
2601 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2602 EndLoc);
2603 }
2604
2605 /// Build a new OpenMP 'doacross' clause.
2606 ///
2607 /// By default, performs semantic analysis to build the new OpenMP clause.
2608 /// Subclasses may override this routine to provide different behavior.
2609 OMPClause *
2610 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2611 SourceLocation DepLoc, SourceLocation ColonLoc,
2612 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2613 SourceLocation LParenLoc, SourceLocation EndLoc) {
2614 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2615 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2616 }
2617
2618 /// Build a new OpenMP 'holds' clause.
2619 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2620 SourceLocation LParenLoc,
2621 SourceLocation EndLoc) {
2622 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2623 EndLoc);
2624 }
2625
2626 /// Rebuild the operand to an Objective-C \@synchronized statement.
2627 ///
2628 /// By default, performs semantic analysis to build the new statement.
2629 /// Subclasses may override this routine to provide different behavior.
2630 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2631 Expr *object) {
2632 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2633 }
2634
2635 /// Build a new Objective-C \@synchronized statement.
2636 ///
2637 /// By default, performs semantic analysis to build the new statement.
2638 /// Subclasses may override this routine to provide different behavior.
2639 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2640 Expr *Object, Stmt *Body) {
2641 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2642 }
2643
2644 /// Build a new Objective-C \@autoreleasepool statement.
2645 ///
2646 /// By default, performs semantic analysis to build the new statement.
2647 /// Subclasses may override this routine to provide different behavior.
2648 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2649 Stmt *Body) {
2650 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2651 }
2652
2653 /// Build a new Objective-C fast enumeration statement.
2654 ///
2655 /// By default, performs semantic analysis to build the new statement.
2656 /// Subclasses may override this routine to provide different behavior.
2657 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2658 Stmt *Element,
2659 Expr *Collection,
2660 SourceLocation RParenLoc,
2661 Stmt *Body) {
2662 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2663 ForLoc, Element, Collection, RParenLoc);
2664 if (ForEachStmt.isInvalid())
2665 return StmtError();
2666
2667 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2668 Body);
2669 }
2670
2671 /// Build a new C++ exception declaration.
2672 ///
2673 /// By default, performs semantic analysis to build the new decaration.
2674 /// Subclasses may override this routine to provide different behavior.
2675 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2676 TypeSourceInfo *Declarator,
2677 SourceLocation StartLoc,
2678 SourceLocation IdLoc,
2679 IdentifierInfo *Id) {
2680 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2681 StartLoc, IdLoc, Id);
2682 if (Var)
2683 getSema().CurContext->addDecl(Var);
2684 return Var;
2685 }
2686
2687 /// Build a new C++ catch statement.
2688 ///
2689 /// By default, performs semantic analysis to build the new statement.
2690 /// Subclasses may override this routine to provide different behavior.
2691 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2692 VarDecl *ExceptionDecl,
2693 Stmt *Handler) {
2694 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2695 Handler));
2696 }
2697
2698 /// Build a new C++ try statement.
2699 ///
2700 /// By default, performs semantic analysis to build the new statement.
2701 /// Subclasses may override this routine to provide different behavior.
2702 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2703 ArrayRef<Stmt *> Handlers) {
2704 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2705 }
2706
2707 /// Build a new C++0x range-based for statement.
2708 ///
2709 /// By default, performs semantic analysis to build the new statement.
2710 /// Subclasses may override this routine to provide different behavior.
2711 StmtResult RebuildCXXForRangeStmt(
2712 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2713 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2714 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2715 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2716 // If we've just learned that the range is actually an Objective-C
2717 // collection, treat this as an Objective-C fast enumeration loop.
2718 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2719 if (RangeStmt->isSingleDecl()) {
2720 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2721 if (RangeVar->isInvalidDecl())
2722 return StmtError();
2723
2724 Expr *RangeExpr = RangeVar->getInit();
2725 if (!RangeExpr->isTypeDependent() &&
2726 RangeExpr->getType()->isObjCObjectPointerType()) {
2727 // FIXME: Support init-statements in Objective-C++20 ranged for
2728 // statement.
2729 if (Init) {
2730 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2731 DiagID: diag::err_objc_for_range_init_stmt)
2732 << Init->getSourceRange();
2733 }
2734 return getSema().ObjC().ActOnObjCForCollectionStmt(
2735 ForLoc, LoopVar, RangeExpr, RParenLoc);
2736 }
2737 }
2738 }
2739 }
2740
2741 return getSema().BuildCXXForRangeStmt(
2742 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2743 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2744 }
2745
2746 /// Build a new C++0x range-based for statement.
2747 ///
2748 /// By default, performs semantic analysis to build the new statement.
2749 /// Subclasses may override this routine to provide different behavior.
2750 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2751 bool IsIfExists,
2752 NestedNameSpecifierLoc QualifierLoc,
2753 DeclarationNameInfo NameInfo,
2754 Stmt *Nested) {
2755 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2756 QualifierLoc, NameInfo, Nested);
2757 }
2758
2759 /// Attach body to a C++0x range-based for statement.
2760 ///
2761 /// By default, performs semantic analysis to finish the new statement.
2762 /// Subclasses may override this routine to provide different behavior.
2763 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2764 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2765 }
2766
2767 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2768 Stmt *TryBlock, Stmt *Handler) {
2769 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2770 }
2771
2772 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2773 Stmt *Block) {
2774 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2775 }
2776
2777 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2778 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2779 }
2780
2781 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2782 SourceLocation LParen,
2783 SourceLocation RParen,
2784 TypeSourceInfo *TSI) {
2785 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2786 TSI);
2787 }
2788
2789 /// Build a new predefined expression.
2790 ///
2791 /// By default, performs semantic analysis to build the new expression.
2792 /// Subclasses may override this routine to provide different behavior.
2793 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2794 return getSema().BuildPredefinedExpr(Loc, IK);
2795 }
2796
2797 /// Build a new expression that references a declaration.
2798 ///
2799 /// By default, performs semantic analysis to build the new expression.
2800 /// Subclasses may override this routine to provide different behavior.
2801 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2802 LookupResult &R,
2803 bool RequiresADL) {
2804 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2805 }
2806
2807
2808 /// Build a new expression that references a declaration.
2809 ///
2810 /// By default, performs semantic analysis to build the new expression.
2811 /// Subclasses may override this routine to provide different behavior.
2812 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2813 ValueDecl *VD,
2814 const DeclarationNameInfo &NameInfo,
2815 NamedDecl *Found,
2816 TemplateArgumentListInfo *TemplateArgs) {
2817 CXXScopeSpec SS;
2818 SS.Adopt(Other: QualifierLoc);
2819 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2820 TemplateArgs);
2821 }
2822
2823 /// Build a new expression in parentheses.
2824 ///
2825 /// By default, performs semantic analysis to build the new expression.
2826 /// Subclasses may override this routine to provide different behavior.
2827 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2828 SourceLocation RParen) {
2829 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2830 }
2831
2832 /// Build a new pseudo-destructor expression.
2833 ///
2834 /// By default, performs semantic analysis to build the new expression.
2835 /// Subclasses may override this routine to provide different behavior.
2836 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2837 SourceLocation OperatorLoc,
2838 bool isArrow,
2839 CXXScopeSpec &SS,
2840 TypeSourceInfo *ScopeType,
2841 SourceLocation CCLoc,
2842 SourceLocation TildeLoc,
2843 PseudoDestructorTypeStorage Destroyed);
2844
2845 /// Build a new unary operator expression.
2846 ///
2847 /// By default, performs semantic analysis to build the new expression.
2848 /// Subclasses may override this routine to provide different behavior.
2849 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2850 UnaryOperatorKind Opc,
2851 Expr *SubExpr) {
2852 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2853 }
2854
2855 /// Build a new builtin offsetof expression.
2856 ///
2857 /// By default, performs semantic analysis to build the new expression.
2858 /// Subclasses may override this routine to provide different behavior.
2859 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2860 TypeSourceInfo *Type, const Designation &Desig,
2861 SourceLocation RParenLoc) {
2862 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Desig, RParenLoc);
2863 }
2864
2865 /// Build a new sizeof, alignof or vec_step expression with a
2866 /// type argument.
2867 ///
2868 /// By default, performs semantic analysis to build the new expression.
2869 /// Subclasses may override this routine to provide different behavior.
2870 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2871 SourceLocation OpLoc,
2872 UnaryExprOrTypeTrait ExprKind,
2873 SourceRange R) {
2874 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2875 }
2876
2877 /// Build a new sizeof, alignof or vec step expression with an
2878 /// expression argument.
2879 ///
2880 /// By default, performs semantic analysis to build the new expression.
2881 /// Subclasses may override this routine to provide different behavior.
2882 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2883 UnaryExprOrTypeTrait ExprKind,
2884 SourceRange R) {
2885 ExprResult Result
2886 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2887 if (Result.isInvalid())
2888 return ExprError();
2889
2890 return Result;
2891 }
2892
2893 /// Build a new array subscript expression.
2894 ///
2895 /// By default, performs semantic analysis to build the new expression.
2896 /// Subclasses may override this routine to provide different behavior.
2897 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2898 SourceLocation LBracketLoc,
2899 Expr *RHS,
2900 SourceLocation RBracketLoc) {
2901 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2902 LBracketLoc, RHS,
2903 RBracketLoc);
2904 }
2905
2906 /// Build a new matrix single subscript expression.
2907 ///
2908 /// By default, performs semantic analysis to build the new expression.
2909 /// Subclasses may override this routine to provide different behavior.
2910 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2911 SourceLocation RBracketLoc) {
2912 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2913 RBracketLoc);
2914 }
2915
2916 /// Build a new matrix subscript expression.
2917 ///
2918 /// By default, performs semantic analysis to build the new expression.
2919 /// Subclasses may override this routine to provide different behavior.
2920 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2921 Expr *ColumnIdx,
2922 SourceLocation RBracketLoc) {
2923 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2924 RBracketLoc);
2925 }
2926
2927 /// Build a new array section expression.
2928 ///
2929 /// By default, performs semantic analysis to build the new expression.
2930 /// Subclasses may override this routine to provide different behavior.
2931 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2932 SourceLocation LBracketLoc,
2933 Expr *LowerBound,
2934 SourceLocation ColonLocFirst,
2935 SourceLocation ColonLocSecond,
2936 Expr *Length, Expr *Stride,
2937 SourceLocation RBracketLoc) {
2938 if (IsOMPArraySection)
2939 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2940 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2941 Stride, RBracketLoc);
2942
2943 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2944 "Stride/second colon not allowed for OpenACC");
2945
2946 return getSema().OpenACC().ActOnArraySectionExpr(
2947 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2948 }
2949
2950 /// Build a new array shaping expression.
2951 ///
2952 /// By default, performs semantic analysis to build the new expression.
2953 /// Subclasses may override this routine to provide different behavior.
2954 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2955 SourceLocation RParenLoc,
2956 ArrayRef<Expr *> Dims,
2957 ArrayRef<SourceRange> BracketsRanges) {
2958 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2959 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2960 }
2961
2962 /// Build a new iterator expression.
2963 ///
2964 /// By default, performs semantic analysis to build the new expression.
2965 /// Subclasses may override this routine to provide different behavior.
2966 ExprResult
2967 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2968 SourceLocation RLoc,
2969 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2970 return getSema().OpenMP().ActOnOMPIteratorExpr(
2971 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2972 }
2973
2974 /// Build a new call expression.
2975 ///
2976 /// By default, performs semantic analysis to build the new expression.
2977 /// Subclasses may override this routine to provide different behavior.
2978 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2979 MultiExprArg Args,
2980 SourceLocation RParenLoc,
2981 Expr *ExecConfig = nullptr) {
2982 return getSema().ActOnCallExpr(
2983 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2984 }
2985
2986 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2987 MultiExprArg Args,
2988 SourceLocation RParenLoc) {
2989 return getSema().ActOnArraySubscriptExpr(
2990 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2991 }
2992
2993 /// Build a new member access expression.
2994 ///
2995 /// By default, performs semantic analysis to build the new expression.
2996 /// Subclasses may override this routine to provide different behavior.
2997 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2998 bool isArrow,
2999 NestedNameSpecifierLoc QualifierLoc,
3000 SourceLocation TemplateKWLoc,
3001 const DeclarationNameInfo &MemberNameInfo,
3002 ValueDecl *Member,
3003 NamedDecl *FoundDecl,
3004 const TemplateArgumentListInfo *ExplicitTemplateArgs,
3005 NamedDecl *FirstQualifierInScope) {
3006 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
3007 isArrow);
3008 if (!Member->getDeclName()) {
3009 // We have a reference to an unnamed field. This is always the
3010 // base of an anonymous struct/union member access, i.e. the
3011 // field is always of record type.
3012 assert(Member->getType()->isRecordType() &&
3013 "unnamed member not of record type?");
3014
3015 BaseResult =
3016 getSema().PerformObjectMemberConversion(BaseResult.get(),
3017 QualifierLoc.getNestedNameSpecifier(),
3018 FoundDecl, Member);
3019 if (BaseResult.isInvalid())
3020 return ExprError();
3021 Base = BaseResult.get();
3022
3023 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
3024 // from the AST, so we need to re-insert them if needed (since
3025 // `BuildFieldRefereneExpr()` doesn't do this).
3026 if (!isArrow && Base->isPRValue()) {
3027 BaseResult = getSema().TemporaryMaterializationConversion(Base);
3028 if (BaseResult.isInvalid())
3029 return ExprError();
3030 Base = BaseResult.get();
3031 }
3032
3033 CXXScopeSpec EmptySS;
3034 return getSema().BuildFieldReferenceExpr(
3035 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
3036 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
3037 MemberNameInfo);
3038 }
3039
3040 CXXScopeSpec SS;
3041 SS.Adopt(Other: QualifierLoc);
3042
3043 Base = BaseResult.get();
3044 if (Base->containsErrors())
3045 return ExprError();
3046
3047 QualType BaseType = Base->getType();
3048
3049 if (isArrow && !BaseType->isPointerType())
3050 return ExprError();
3051
3052 // FIXME: this involves duplicating earlier analysis in a lot of
3053 // cases; we should avoid this when possible.
3054 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3055 R.addDecl(D: FoundDecl);
3056 R.resolveKind();
3057
3058 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3059 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3060 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3061 ->getType()
3062 ->getPointeeType()
3063 ->getAsCXXRecordDecl()) {
3064 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3065 // In unevaluated contexts, an expression supposed to be a member access
3066 // might reference a member in an unrelated class.
3067 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3068 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3069 VK_LValue, Member->getLocation());
3070 }
3071 }
3072
3073 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3074 SS, TemplateKWLoc,
3075 FirstQualifierInScope,
3076 R, ExplicitTemplateArgs,
3077 /*S*/nullptr);
3078 }
3079
3080 /// Build a new binary operator expression.
3081 ///
3082 /// By default, performs semantic analysis to build the new expression.
3083 /// Subclasses may override this routine to provide different behavior.
3084 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3085 Expr *LHS, Expr *RHS,
3086 bool ForFoldExpression = false) {
3087 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3088 ForFoldExpression);
3089 }
3090
3091 /// Build a new rewritten operator expression.
3092 ///
3093 /// By default, performs semantic analysis to build the new expression.
3094 /// Subclasses may override this routine to provide different behavior.
3095 ExprResult RebuildCXXRewrittenBinaryOperator(
3096 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3097 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3098 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3099 RHS, /*RequiresADL*/false);
3100 }
3101
3102 /// Build a new conditional operator expression.
3103 ///
3104 /// By default, performs semantic analysis to build the new expression.
3105 /// Subclasses may override this routine to provide different behavior.
3106 ExprResult RebuildConditionalOperator(Expr *Cond,
3107 SourceLocation QuestionLoc,
3108 Expr *LHS,
3109 SourceLocation ColonLoc,
3110 Expr *RHS) {
3111 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3112 LHS, RHS);
3113 }
3114
3115 /// Build a new C-style cast expression.
3116 ///
3117 /// By default, performs semantic analysis to build the new expression.
3118 /// Subclasses may override this routine to provide different behavior.
3119 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3120 TypeSourceInfo *TInfo,
3121 SourceLocation RParenLoc,
3122 Expr *SubExpr) {
3123 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3124 SubExpr);
3125 }
3126
3127 /// Build a new compound literal expression.
3128 ///
3129 /// By default, performs semantic analysis to build the new expression.
3130 /// Subclasses may override this routine to provide different behavior.
3131 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3132 TypeSourceInfo *TInfo,
3133 SourceLocation RParenLoc,
3134 Expr *Init) {
3135 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3136 Init);
3137 }
3138
3139 /// Build a new extended vector or matrix element access expression.
3140 ///
3141 /// By default, performs semantic analysis to build the new expression.
3142 /// Subclasses may override this routine to provide different behavior.
3143 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3144 SourceLocation OpLoc,
3145 bool IsArrow,
3146 SourceLocation AccessorLoc,
3147 IdentifierInfo &Accessor) {
3148
3149 CXXScopeSpec SS;
3150 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3151 return getSema().BuildMemberReferenceExpr(
3152 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3153 /*FirstQualifierInScope*/ nullptr, NameInfo,
3154 /* TemplateArgs */ nullptr,
3155 /*S*/ nullptr);
3156 }
3157
3158 /// Build a new initializer list expression.
3159 ///
3160 /// By default, performs semantic analysis to build the new expression.
3161 /// Subclasses may override this routine to provide different behavior.
3162 ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits,
3163 SourceLocation RBraceLoc, bool IsExplicit) {
3164 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc, IsExplicit);
3165 }
3166
3167 /// Build a new designated initializer expression.
3168 ///
3169 /// By default, performs semantic analysis to build the new expression.
3170 /// Subclasses may override this routine to provide different behavior.
3171 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3172 MultiExprArg ArrayExprs,
3173 SourceLocation EqualOrColonLoc,
3174 bool GNUSyntax,
3175 Expr *Init) {
3176 ExprResult Result
3177 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3178 Init);
3179 if (Result.isInvalid())
3180 return ExprError();
3181
3182 return Result;
3183 }
3184
3185 /// Build a new value-initialized expression.
3186 ///
3187 /// By default, builds the implicit value initialization without performing
3188 /// any semantic analysis. Subclasses may override this routine to provide
3189 /// different behavior.
3190 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3191 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3192 }
3193
3194 /// Build a new \c va_arg expression.
3195 ///
3196 /// By default, performs semantic analysis to build the new expression.
3197 /// Subclasses may override this routine to provide different behavior.
3198 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3199 Expr *SubExpr, TypeSourceInfo *TInfo,
3200 SourceLocation RParenLoc) {
3201 return getSema().BuildVAArgExpr(BuiltinLoc,
3202 SubExpr, TInfo,
3203 RParenLoc);
3204 }
3205
3206 /// Build a new expression list in parentheses.
3207 ///
3208 /// By default, performs semantic analysis to build the new expression.
3209 /// Subclasses may override this routine to provide different behavior.
3210 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3211 MultiExprArg SubExprs,
3212 SourceLocation RParenLoc) {
3213 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3214 }
3215
3216 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3217 unsigned NumUserSpecifiedExprs,
3218 SourceLocation InitLoc,
3219 SourceLocation LParenLoc,
3220 SourceLocation RParenLoc) {
3221 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3222 InitLoc, LParenLoc, RParenLoc);
3223 }
3224
3225 /// Build a new address-of-label expression.
3226 ///
3227 /// By default, performs semantic analysis, using the name of the label
3228 /// rather than attempting to map the label statement itself.
3229 /// Subclasses may override this routine to provide different behavior.
3230 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3231 SourceLocation LabelLoc, LabelDecl *Label) {
3232 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3233 }
3234
3235 /// Build a new GNU statement expression.
3236 ///
3237 /// By default, performs semantic analysis to build the new expression.
3238 /// Subclasses may override this routine to provide different behavior.
3239 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3240 SourceLocation RParenLoc, unsigned TemplateDepth) {
3241 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3242 TemplateDepth);
3243 }
3244
3245 /// Build a new __builtin_choose_expr expression.
3246 ///
3247 /// By default, performs semantic analysis to build the new expression.
3248 /// Subclasses may override this routine to provide different behavior.
3249 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3250 Expr *Cond, Expr *LHS, Expr *RHS,
3251 SourceLocation RParenLoc) {
3252 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3253 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3254 RPLoc: RParenLoc);
3255 }
3256
3257 /// Build a new generic selection expression with an expression predicate.
3258 ///
3259 /// By default, performs semantic analysis to build the new expression.
3260 /// Subclasses may override this routine to provide different behavior.
3261 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3262 SourceLocation DefaultLoc,
3263 SourceLocation RParenLoc,
3264 Expr *ControllingExpr,
3265 ArrayRef<TypeSourceInfo *> Types,
3266 ArrayRef<Expr *> Exprs) {
3267 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3268 /*PredicateIsExpr=*/true,
3269 ControllingExpr, Types, Exprs);
3270 }
3271
3272 /// Build a new generic selection expression with a type predicate.
3273 ///
3274 /// By default, performs semantic analysis to build the new expression.
3275 /// Subclasses may override this routine to provide different behavior.
3276 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3277 SourceLocation DefaultLoc,
3278 SourceLocation RParenLoc,
3279 TypeSourceInfo *ControllingType,
3280 ArrayRef<TypeSourceInfo *> Types,
3281 ArrayRef<Expr *> Exprs) {
3282 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3283 /*PredicateIsExpr=*/false,
3284 ControllingType, Types, Exprs);
3285 }
3286
3287 /// Build a new overloaded operator call expression.
3288 ///
3289 /// By default, performs semantic analysis to build the new expression.
3290 /// The semantic analysis provides the behavior of template instantiation,
3291 /// copying with transformations that turn what looks like an overloaded
3292 /// operator call into a use of a builtin operator, performing
3293 /// argument-dependent lookup, etc. Subclasses may override this routine to
3294 /// provide different behavior.
3295 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3296 SourceLocation OpLoc,
3297 SourceLocation CalleeLoc,
3298 bool RequiresADL,
3299 const UnresolvedSetImpl &Functions,
3300 Expr *First, Expr *Second);
3301
3302 /// Build a new C++ "named" cast expression, such as static_cast or
3303 /// reinterpret_cast.
3304 ///
3305 /// By default, this routine dispatches to one of the more-specific routines
3306 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3307 /// Subclasses may override this routine to provide different behavior.
3308 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3309 Stmt::StmtClass Class,
3310 SourceLocation LAngleLoc,
3311 TypeSourceInfo *TInfo,
3312 SourceLocation RAngleLoc,
3313 SourceLocation LParenLoc,
3314 Expr *SubExpr,
3315 SourceLocation RParenLoc) {
3316 switch (Class) {
3317 case Stmt::CXXStaticCastExprClass:
3318 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3319 RAngleLoc, LParenLoc,
3320 SubExpr, RParenLoc);
3321
3322 case Stmt::CXXDynamicCastExprClass:
3323 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3324 RAngleLoc, LParenLoc,
3325 SubExpr, RParenLoc);
3326
3327 case Stmt::CXXReinterpretCastExprClass:
3328 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3329 RAngleLoc, LParenLoc,
3330 SubExpr,
3331 RParenLoc);
3332
3333 case Stmt::CXXConstCastExprClass:
3334 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3335 RAngleLoc, LParenLoc,
3336 SubExpr, RParenLoc);
3337
3338 case Stmt::CXXAddrspaceCastExprClass:
3339 return getDerived().RebuildCXXAddrspaceCastExpr(
3340 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3341
3342 default:
3343 llvm_unreachable("Invalid C++ named cast");
3344 }
3345 }
3346
3347 /// Build a new C++ static_cast expression.
3348 ///
3349 /// By default, performs semantic analysis to build the new expression.
3350 /// Subclasses may override this routine to provide different behavior.
3351 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3352 SourceLocation LAngleLoc,
3353 TypeSourceInfo *TInfo,
3354 SourceLocation RAngleLoc,
3355 SourceLocation LParenLoc,
3356 Expr *SubExpr,
3357 SourceLocation RParenLoc) {
3358 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3359 TInfo, SubExpr,
3360 SourceRange(LAngleLoc, RAngleLoc),
3361 SourceRange(LParenLoc, RParenLoc));
3362 }
3363
3364 /// Build a new C++ dynamic_cast expression.
3365 ///
3366 /// By default, performs semantic analysis to build the new expression.
3367 /// Subclasses may override this routine to provide different behavior.
3368 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3369 SourceLocation LAngleLoc,
3370 TypeSourceInfo *TInfo,
3371 SourceLocation RAngleLoc,
3372 SourceLocation LParenLoc,
3373 Expr *SubExpr,
3374 SourceLocation RParenLoc) {
3375 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3376 TInfo, SubExpr,
3377 SourceRange(LAngleLoc, RAngleLoc),
3378 SourceRange(LParenLoc, RParenLoc));
3379 }
3380
3381 /// Build a new C++ reinterpret_cast expression.
3382 ///
3383 /// By default, performs semantic analysis to build the new expression.
3384 /// Subclasses may override this routine to provide different behavior.
3385 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3386 SourceLocation LAngleLoc,
3387 TypeSourceInfo *TInfo,
3388 SourceLocation RAngleLoc,
3389 SourceLocation LParenLoc,
3390 Expr *SubExpr,
3391 SourceLocation RParenLoc) {
3392 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3393 TInfo, SubExpr,
3394 SourceRange(LAngleLoc, RAngleLoc),
3395 SourceRange(LParenLoc, RParenLoc));
3396 }
3397
3398 /// Build a new C++ const_cast expression.
3399 ///
3400 /// By default, performs semantic analysis to build the new expression.
3401 /// Subclasses may override this routine to provide different behavior.
3402 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3403 SourceLocation LAngleLoc,
3404 TypeSourceInfo *TInfo,
3405 SourceLocation RAngleLoc,
3406 SourceLocation LParenLoc,
3407 Expr *SubExpr,
3408 SourceLocation RParenLoc) {
3409 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3410 TInfo, SubExpr,
3411 SourceRange(LAngleLoc, RAngleLoc),
3412 SourceRange(LParenLoc, RParenLoc));
3413 }
3414
3415 ExprResult
3416 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3417 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3418 SourceLocation LParenLoc, Expr *SubExpr,
3419 SourceLocation RParenLoc) {
3420 return getSema().BuildCXXNamedCast(
3421 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3422 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3423 }
3424
3425 /// Build a new C++ functional-style cast expression.
3426 ///
3427 /// By default, performs semantic analysis to build the new expression.
3428 /// Subclasses may override this routine to provide different behavior.
3429 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3430 SourceLocation LParenLoc,
3431 Expr *Sub,
3432 SourceLocation RParenLoc,
3433 bool ListInitialization) {
3434 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3435 // CXXParenListInitExpr. Pass its expanded arguments so that the
3436 // CXXParenListInitExpr can be rebuilt.
3437 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3438 return getSema().BuildCXXTypeConstructExpr(
3439 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3440 RParenLoc, ListInitialization);
3441
3442 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3443 return getSema().BuildCXXTypeConstructExpr(
3444 TInfo, LParenLoc, PLE->getUserSpecifiedInitExprs(), RParenLoc,
3445 ListInitialization);
3446
3447 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3448 MultiExprArg(&Sub, 1), RParenLoc,
3449 ListInitialization);
3450 }
3451
3452 /// Build a new C++ __builtin_bit_cast expression.
3453 ///
3454 /// By default, performs semantic analysis to build the new expression.
3455 /// Subclasses may override this routine to provide different behavior.
3456 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3457 TypeSourceInfo *TSI, Expr *Sub,
3458 SourceLocation RParenLoc) {
3459 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3460 }
3461
3462 /// Build a new C++ typeid(type) expression.
3463 ///
3464 /// By default, performs semantic analysis to build the new expression.
3465 /// Subclasses may override this routine to provide different behavior.
3466 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3467 SourceLocation TypeidLoc,
3468 TypeSourceInfo *Operand,
3469 SourceLocation RParenLoc) {
3470 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3471 RParenLoc);
3472 }
3473
3474
3475 /// Build a new C++ typeid(expr) expression.
3476 ///
3477 /// By default, performs semantic analysis to build the new expression.
3478 /// Subclasses may override this routine to provide different behavior.
3479 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3480 SourceLocation TypeidLoc,
3481 Expr *Operand,
3482 SourceLocation RParenLoc) {
3483 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3484 RParenLoc);
3485 }
3486
3487 /// Build a new C++ __uuidof(type) expression.
3488 ///
3489 /// By default, performs semantic analysis to build the new expression.
3490 /// Subclasses may override this routine to provide different behavior.
3491 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3492 TypeSourceInfo *Operand,
3493 SourceLocation RParenLoc) {
3494 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3495 }
3496
3497 /// Build a new C++ __uuidof(expr) expression.
3498 ///
3499 /// By default, performs semantic analysis to build the new expression.
3500 /// Subclasses may override this routine to provide different behavior.
3501 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3502 Expr *Operand, SourceLocation RParenLoc) {
3503 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3504 }
3505
3506 /// Build a new C++ "this" expression.
3507 ///
3508 /// By default, performs semantic analysis to build a new "this" expression.
3509 /// Subclasses may override this routine to provide different behavior.
3510 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3511 QualType ThisType,
3512 bool isImplicit) {
3513 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3514 return ExprError();
3515 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3516 }
3517
3518 /// Build a new C++ throw expression.
3519 ///
3520 /// By default, performs semantic analysis to build the new expression.
3521 /// Subclasses may override this routine to provide different behavior.
3522 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3523 bool IsThrownVariableInScope) {
3524 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3525 }
3526
3527 /// Build a new C++ default-argument expression.
3528 ///
3529 /// By default, builds a new default-argument expression, which does not
3530 /// require any semantic analysis. Subclasses may override this routine to
3531 /// provide different behavior.
3532 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3533 Expr *RewrittenExpr) {
3534 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3535 RewrittenExpr, UsedContext: getSema().CurContext);
3536 }
3537
3538 /// Build a new C++11 default-initialization expression.
3539 ///
3540 /// By default, builds a new default field initialization expression, which
3541 /// does not require any semantic analysis. Subclasses may override this
3542 /// routine to provide different behavior.
3543 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field,
3544 Expr *RewrittenInit) {
3545 return CXXDefaultInitExpr::Create(Ctx: getSema().Context, Loc, Field,
3546 UsedContext: getSema().CurContext, RewrittenInitExpr: RewrittenInit);
3547 }
3548
3549 /// Build a new C++ zero-initialization expression.
3550 ///
3551 /// By default, performs semantic analysis to build the new expression.
3552 /// Subclasses may override this routine to provide different behavior.
3553 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3554 SourceLocation LParenLoc,
3555 SourceLocation RParenLoc) {
3556 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3557 /*ListInitialization=*/false);
3558 }
3559
3560 /// Build a new C++ "new" expression.
3561 ///
3562 /// By default, performs semantic analysis to build the new expression.
3563 /// Subclasses may override this routine to provide different behavior.
3564 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3565 SourceLocation PlacementLParen,
3566 MultiExprArg PlacementArgs,
3567 SourceLocation PlacementRParen,
3568 SourceRange TypeIdParens, QualType AllocatedType,
3569 TypeSourceInfo *AllocatedTypeInfo,
3570 std::optional<Expr *> ArraySize,
3571 SourceRange DirectInitRange, Expr *Initializer) {
3572 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3573 PlacementLParen,
3574 PlacementArgs,
3575 PlacementRParen,
3576 TypeIdParens,
3577 AllocatedType,
3578 AllocatedTypeInfo,
3579 ArraySize,
3580 DirectInitRange,
3581 Initializer);
3582 }
3583
3584 /// Build a new C++ "delete" expression.
3585 ///
3586 /// By default, performs semantic analysis to build the new expression.
3587 /// Subclasses may override this routine to provide different behavior.
3588 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3589 bool IsGlobalDelete,
3590 bool IsArrayForm,
3591 Expr *Operand) {
3592 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3593 Operand);
3594 }
3595
3596 /// Build a new type trait expression.
3597 ///
3598 /// By default, performs semantic analysis to build the new expression.
3599 /// Subclasses may override this routine to provide different behavior.
3600 ExprResult RebuildTypeTrait(TypeTrait Trait,
3601 SourceLocation StartLoc,
3602 ArrayRef<TypeSourceInfo *> Args,
3603 SourceLocation RParenLoc) {
3604 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3605 }
3606
3607 /// Build a new array type trait expression.
3608 ///
3609 /// By default, performs semantic analysis to build the new expression.
3610 /// Subclasses may override this routine to provide different behavior.
3611 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3612 SourceLocation StartLoc,
3613 TypeSourceInfo *TSInfo,
3614 Expr *DimExpr,
3615 SourceLocation RParenLoc) {
3616 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3617 }
3618
3619 /// Build a new expression trait expression.
3620 ///
3621 /// By default, performs semantic analysis to build the new expression.
3622 /// Subclasses may override this routine to provide different behavior.
3623 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3624 SourceLocation StartLoc,
3625 Expr *Queried,
3626 SourceLocation RParenLoc) {
3627 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3628 }
3629
3630 /// Build a new (previously unresolved) declaration reference
3631 /// expression.
3632 ///
3633 /// By default, performs semantic analysis to build the new expression.
3634 /// Subclasses may override this routine to provide different behavior.
3635 ExprResult RebuildDependentScopeDeclRefExpr(
3636 NestedNameSpecifierLoc QualifierLoc,
3637 SourceLocation TemplateKWLoc,
3638 const DeclarationNameInfo &NameInfo,
3639 const TemplateArgumentListInfo *TemplateArgs,
3640 bool IsAddressOfOperand,
3641 TypeSourceInfo **RecoveryTSI) {
3642 CXXScopeSpec SS;
3643 SS.Adopt(Other: QualifierLoc);
3644
3645 if (TemplateArgs || TemplateKWLoc.isValid())
3646 return getSema().BuildQualifiedTemplateIdExpr(
3647 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3648
3649 return getSema().BuildQualifiedDeclarationNameExpr(
3650 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3651 }
3652
3653 /// Build a new template-id expression.
3654 ///
3655 /// By default, performs semantic analysis to build the new expression.
3656 /// Subclasses may override this routine to provide different behavior.
3657 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3658 SourceLocation TemplateKWLoc,
3659 LookupResult &R,
3660 bool RequiresADL,
3661 const TemplateArgumentListInfo *TemplateArgs) {
3662 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3663 TemplateArgs);
3664 }
3665
3666 /// Build a new object-construction expression.
3667 ///
3668 /// By default, performs semantic analysis to build the new expression.
3669 /// Subclasses may override this routine to provide different behavior.
3670 ExprResult RebuildCXXConstructExpr(
3671 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3672 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3673 bool ListInitialization, bool StdInitListInitialization,
3674 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3675 SourceRange ParenRange) {
3676 // Reconstruct the constructor we originally found, which might be
3677 // different if this is a call to an inherited constructor.
3678 CXXConstructorDecl *FoundCtor = Constructor;
3679 if (Constructor->isInheritingConstructor())
3680 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3681
3682 SmallVector<Expr *, 8> ConvertedArgs;
3683 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3684 ConvertedArgs))
3685 return ExprError();
3686
3687 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3688 IsElidable,
3689 ConvertedArgs,
3690 HadMultipleCandidates,
3691 ListInitialization,
3692 StdInitListInitialization,
3693 RequiresZeroInit, ConstructKind,
3694 ParenRange);
3695 }
3696
3697 /// Build a new implicit construction via inherited constructor
3698 /// expression.
3699 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3700 CXXConstructorDecl *Constructor,
3701 bool ConstructsVBase,
3702 bool InheritedFromVBase) {
3703 return new (getSema().Context) CXXInheritedCtorInitExpr(
3704 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3705 }
3706
3707 /// Build a new object-construction expression.
3708 ///
3709 /// By default, performs semantic analysis to build the new expression.
3710 /// Subclasses may override this routine to provide different behavior.
3711 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3712 SourceLocation LParenOrBraceLoc,
3713 MultiExprArg Args,
3714 SourceLocation RParenOrBraceLoc,
3715 bool ListInitialization) {
3716 return getSema().BuildCXXTypeConstructExpr(
3717 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3718 }
3719
3720 /// Build a new object-construction expression.
3721 ///
3722 /// By default, performs semantic analysis to build the new expression.
3723 /// Subclasses may override this routine to provide different behavior.
3724 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3725 SourceLocation LParenLoc,
3726 MultiExprArg Args,
3727 SourceLocation RParenLoc,
3728 bool ListInitialization) {
3729 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3730 RParenLoc, ListInitialization);
3731 }
3732
3733 /// Build a new member reference expression.
3734 ///
3735 /// By default, performs semantic analysis to build the new expression.
3736 /// Subclasses may override this routine to provide different behavior.
3737 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3738 QualType BaseType,
3739 bool IsArrow,
3740 SourceLocation OperatorLoc,
3741 NestedNameSpecifierLoc QualifierLoc,
3742 SourceLocation TemplateKWLoc,
3743 NamedDecl *FirstQualifierInScope,
3744 const DeclarationNameInfo &MemberNameInfo,
3745 const TemplateArgumentListInfo *TemplateArgs) {
3746 CXXScopeSpec SS;
3747 SS.Adopt(Other: QualifierLoc);
3748
3749 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3750 OpLoc: OperatorLoc, IsArrow,
3751 SS, TemplateKWLoc,
3752 FirstQualifierInScope,
3753 NameInfo: MemberNameInfo,
3754 TemplateArgs, /*S*/S: nullptr);
3755 }
3756
3757 /// Build a new member reference expression.
3758 ///
3759 /// By default, performs semantic analysis to build the new expression.
3760 /// Subclasses may override this routine to provide different behavior.
3761 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3762 SourceLocation OperatorLoc,
3763 bool IsArrow,
3764 NestedNameSpecifierLoc QualifierLoc,
3765 SourceLocation TemplateKWLoc,
3766 NamedDecl *FirstQualifierInScope,
3767 LookupResult &R,
3768 const TemplateArgumentListInfo *TemplateArgs) {
3769 CXXScopeSpec SS;
3770 SS.Adopt(Other: QualifierLoc);
3771
3772 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3773 OpLoc: OperatorLoc, IsArrow,
3774 SS, TemplateKWLoc,
3775 FirstQualifierInScope,
3776 R, TemplateArgs, /*S*/S: nullptr);
3777 }
3778
3779 /// Build a new noexcept expression.
3780 ///
3781 /// By default, performs semantic analysis to build the new expression.
3782 /// Subclasses may override this routine to provide different behavior.
3783 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3784 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3785 }
3786
3787 UnsignedOrNone
3788 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3789
3790 /// Build a new expression to compute the length of a parameter pack.
3791 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3792 SourceLocation PackLoc,
3793 SourceLocation RParenLoc,
3794 UnsignedOrNone Length,
3795 ArrayRef<TemplateArgument> PartialArgs) {
3796 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3797 RParenLoc, Length, PartialArgs);
3798 }
3799
3800 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3801 SourceLocation RSquareLoc,
3802 Expr *PackIdExpression, Expr *IndexExpr,
3803 ArrayRef<Expr *> ExpandedExprs,
3804 bool FullySubstituted = false) {
3805 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3806 IndexExpr, RSquareLoc, ExpandedExprs,
3807 FullySubstituted);
3808 }
3809
3810 /// Build a new expression representing a call to a source location
3811 /// builtin.
3812 ///
3813 /// By default, performs semantic analysis to build the new expression.
3814 /// Subclasses may override this routine to provide different behavior.
3815 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3816 SourceLocation BuiltinLoc,
3817 SourceLocation RPLoc,
3818 DeclContext *ParentContext) {
3819 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3820 ParentContext);
3821 }
3822
3823 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3824 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3825 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3826 TemplateArgumentListInfo *TALI) {
3827 CXXScopeSpec SS;
3828 SS.Adopt(Other: NNS);
3829 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3830 ConceptNameInfo,
3831 FoundDecl,
3832 NamedConcept, TALI);
3833 if (Result.isInvalid())
3834 return ExprError();
3835 return Result;
3836 }
3837
3838 /// \brief Build a new requires expression.
3839 ///
3840 /// By default, performs semantic analysis to build the new expression.
3841 /// Subclasses may override this routine to provide different behavior.
3842 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3843 RequiresExprBodyDecl *Body,
3844 SourceLocation LParenLoc,
3845 ArrayRef<ParmVarDecl *> LocalParameters,
3846 SourceLocation RParenLoc,
3847 ArrayRef<concepts::Requirement *> Requirements,
3848 SourceLocation ClosingBraceLoc) {
3849 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3850 LocalParameters, RParenLoc, Requirements,
3851 RBraceLoc: ClosingBraceLoc);
3852 }
3853
3854 concepts::TypeRequirement *
3855 RebuildTypeRequirement(
3856 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3857 return SemaRef.BuildTypeRequirement(SubstDiag);
3858 }
3859
3860 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3861 return SemaRef.BuildTypeRequirement(Type: T);
3862 }
3863
3864 concepts::ExprRequirement *
3865 RebuildExprRequirement(
3866 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3867 SourceLocation NoexceptLoc,
3868 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3869 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3870 ReturnTypeRequirement: std::move(Ret));
3871 }
3872
3873 concepts::ExprRequirement *
3874 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3875 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3876 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3877 ReturnTypeRequirement: std::move(Ret));
3878 }
3879
3880 concepts::NestedRequirement *
3881 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3882 const ASTConstraintSatisfaction &Satisfaction) {
3883 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3884 Satisfaction);
3885 }
3886
3887 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3888 return SemaRef.BuildNestedRequirement(E: Constraint);
3889 }
3890
3891 /// \brief Build a new Objective-C boxed expression.
3892 ///
3893 /// By default, performs semantic analysis to build the new expression.
3894 /// Subclasses may override this routine to provide different behavior.
3895 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3896 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3897 }
3898
3899 /// Build a new Objective-C array literal.
3900 ///
3901 /// By default, performs semantic analysis to build the new expression.
3902 /// Subclasses may override this routine to provide different behavior.
3903 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3904 Expr **Elements, unsigned NumElements) {
3905 return getSema().ObjC().BuildObjCArrayLiteral(
3906 Range, MultiExprArg(Elements, NumElements));
3907 }
3908
3909 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3910 Expr *Base, Expr *Key,
3911 ObjCMethodDecl *getterMethod,
3912 ObjCMethodDecl *setterMethod) {
3913 return getSema().ObjC().BuildObjCSubscriptExpression(
3914 RB, Base, Key, getterMethod, setterMethod);
3915 }
3916
3917 /// Build a new Objective-C dictionary literal.
3918 ///
3919 /// By default, performs semantic analysis to build the new expression.
3920 /// Subclasses may override this routine to provide different behavior.
3921 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3922 MutableArrayRef<ObjCDictionaryElement> Elements) {
3923 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3924 }
3925
3926 /// Build a new Objective-C \@encode expression.
3927 ///
3928 /// By default, performs semantic analysis to build the new expression.
3929 /// Subclasses may override this routine to provide different behavior.
3930 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3931 TypeSourceInfo *EncodeTypeInfo,
3932 SourceLocation RParenLoc) {
3933 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3934 RParenLoc);
3935 }
3936
3937 /// Build a new Objective-C class message.
3938 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3939 Selector Sel,
3940 ArrayRef<SourceLocation> SelectorLocs,
3941 ObjCMethodDecl *Method,
3942 SourceLocation LBracLoc,
3943 MultiExprArg Args,
3944 SourceLocation RBracLoc) {
3945 return SemaRef.ObjC().BuildClassMessage(
3946 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3947 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3948 RBracLoc, Args);
3949 }
3950
3951 /// Build a new Objective-C instance message.
3952 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3953 Selector Sel,
3954 ArrayRef<SourceLocation> SelectorLocs,
3955 ObjCMethodDecl *Method,
3956 SourceLocation LBracLoc,
3957 MultiExprArg Args,
3958 SourceLocation RBracLoc) {
3959 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3960 /*SuperLoc=*/SuperLoc: SourceLocation(),
3961 Sel, Method, LBracLoc,
3962 SelectorLocs, RBracLoc, Args);
3963 }
3964
3965 /// Build a new Objective-C instance/class message to 'super'.
3966 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3967 Selector Sel,
3968 ArrayRef<SourceLocation> SelectorLocs,
3969 QualType SuperType,
3970 ObjCMethodDecl *Method,
3971 SourceLocation LBracLoc,
3972 MultiExprArg Args,
3973 SourceLocation RBracLoc) {
3974 return Method->isInstanceMethod()
3975 ? SemaRef.ObjC().BuildInstanceMessage(
3976 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3977 SelectorLocs, RBracLoc, Args)
3978 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3979 Sel, Method, LBracLoc,
3980 SelectorLocs, RBracLoc, Args);
3981 }
3982
3983 /// Build a new Objective-C ivar reference expression.
3984 ///
3985 /// By default, performs semantic analysis to build the new expression.
3986 /// Subclasses may override this routine to provide different behavior.
3987 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3988 SourceLocation IvarLoc,
3989 bool IsArrow, bool IsFreeIvar) {
3990 CXXScopeSpec SS;
3991 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3992 ExprResult Result = getSema().BuildMemberReferenceExpr(
3993 BaseArg, BaseArg->getType(),
3994 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3995 /*FirstQualifierInScope=*/nullptr, NameInfo,
3996 /*TemplateArgs=*/nullptr,
3997 /*S=*/nullptr);
3998 if (IsFreeIvar && Result.isUsable())
3999 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
4000 return Result;
4001 }
4002
4003 /// Build a new Objective-C property reference expression.
4004 ///
4005 /// By default, performs semantic analysis to build the new expression.
4006 /// Subclasses may override this routine to provide different behavior.
4007 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
4008 ObjCPropertyDecl *Property,
4009 SourceLocation PropertyLoc) {
4010 CXXScopeSpec SS;
4011 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
4012 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4013 /*FIXME:*/PropertyLoc,
4014 /*IsArrow=*/false,
4015 SS, SourceLocation(),
4016 /*FirstQualifierInScope=*/nullptr,
4017 NameInfo,
4018 /*TemplateArgs=*/nullptr,
4019 /*S=*/nullptr);
4020 }
4021
4022 /// Build a new Objective-C property reference expression.
4023 ///
4024 /// By default, performs semantic analysis to build the new expression.
4025 /// Subclasses may override this routine to provide different behavior.
4026 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
4027 ObjCMethodDecl *Getter,
4028 ObjCMethodDecl *Setter,
4029 SourceLocation PropertyLoc) {
4030 // Since these expressions can only be value-dependent, we do not
4031 // need to perform semantic analysis again.
4032 return Owned(
4033 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
4034 VK_LValue, OK_ObjCProperty,
4035 PropertyLoc, Base));
4036 }
4037
4038 /// Build a new Objective-C "isa" expression.
4039 ///
4040 /// By default, performs semantic analysis to build the new expression.
4041 /// Subclasses may override this routine to provide different behavior.
4042 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4043 SourceLocation OpLoc, bool IsArrow) {
4044 CXXScopeSpec SS;
4045 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4046 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4047 OpLoc, IsArrow,
4048 SS, SourceLocation(),
4049 /*FirstQualifierInScope=*/nullptr,
4050 NameInfo,
4051 /*TemplateArgs=*/nullptr,
4052 /*S=*/nullptr);
4053 }
4054
4055 /// Build a new shuffle vector expression.
4056 ///
4057 /// By default, performs semantic analysis to build the new expression.
4058 /// Subclasses may override this routine to provide different behavior.
4059 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4060 MultiExprArg SubExprs,
4061 SourceLocation RParenLoc) {
4062 // Find the declaration for __builtin_shufflevector
4063 const IdentifierInfo &Name
4064 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4065 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4066 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4067 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4068
4069 // Build a reference to the __builtin_shufflevector builtin
4070 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4071 Expr *Callee = new (SemaRef.Context)
4072 DeclRefExpr(SemaRef.Context, Builtin, false,
4073 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4074 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4075 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4076 CK: CK_BuiltinFnToFnPtr).get();
4077
4078 // Build the CallExpr
4079 ExprResult TheCall = CallExpr::Create(
4080 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4081 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4082 FPFeatures: FPOptionsOverride());
4083
4084 // Type-check the __builtin_shufflevector expression.
4085 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4086 }
4087
4088 /// Build a new convert vector expression.
4089 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4090 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4091 SourceLocation RParenLoc) {
4092 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4093 }
4094
4095 /// Build a new template argument pack expansion.
4096 ///
4097 /// By default, performs semantic analysis to build a new pack expansion
4098 /// for a template argument. Subclasses may override this routine to provide
4099 /// different behavior.
4100 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4101 SourceLocation EllipsisLoc,
4102 UnsignedOrNone NumExpansions) {
4103 switch (Pattern.getArgument().getKind()) {
4104 case TemplateArgument::Expression: {
4105 ExprResult Result
4106 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4107 EllipsisLoc, NumExpansions);
4108 if (Result.isInvalid())
4109 return TemplateArgumentLoc();
4110
4111 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4112 /*IsCanonical=*/false),
4113 Result.get());
4114 }
4115
4116 case TemplateArgument::Template:
4117 return TemplateArgumentLoc(
4118 SemaRef.Context,
4119 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4120 NumExpansions),
4121 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4122 Pattern.getTemplateNameLoc(), EllipsisLoc);
4123
4124 case TemplateArgument::Null:
4125 case TemplateArgument::Integral:
4126 case TemplateArgument::Declaration:
4127 case TemplateArgument::StructuralValue:
4128 case TemplateArgument::Pack:
4129 case TemplateArgument::TemplateExpansion:
4130 case TemplateArgument::NullPtr:
4131 llvm_unreachable("Pack expansion pattern has no parameter packs");
4132
4133 case TemplateArgument::Type:
4134 if (TypeSourceInfo *Expansion
4135 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4136 EllipsisLoc,
4137 NumExpansions))
4138 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4139 Expansion);
4140 break;
4141 }
4142
4143 return TemplateArgumentLoc();
4144 }
4145
4146 /// Build a new expression pack expansion.
4147 ///
4148 /// By default, performs semantic analysis to build a new pack expansion
4149 /// for an expression. Subclasses may override this routine to provide
4150 /// different behavior.
4151 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4152 UnsignedOrNone NumExpansions) {
4153 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4154 }
4155
4156 /// Build a new C++1z fold-expression.
4157 ///
4158 /// By default, performs semantic analysis in order to build a new fold
4159 /// expression.
4160 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4161 SourceLocation LParenLoc, Expr *LHS,
4162 BinaryOperatorKind Operator,
4163 SourceLocation EllipsisLoc, Expr *RHS,
4164 SourceLocation RParenLoc,
4165 UnsignedOrNone NumExpansions) {
4166 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4167 EllipsisLoc, RHS, RParenLoc,
4168 NumExpansions);
4169 }
4170
4171 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4172 LambdaScopeInfo *LSI) {
4173 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4174 if (Expr *Init = PVD->getInit())
4175 LSI->ContainsUnexpandedParameterPack |=
4176 Init->containsUnexpandedParameterPack();
4177 else if (PVD->hasUninstantiatedDefaultArg())
4178 LSI->ContainsUnexpandedParameterPack |=
4179 PVD->getUninstantiatedDefaultArg()
4180 ->containsUnexpandedParameterPack();
4181 }
4182 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4183 }
4184
4185 /// Build an empty C++1z fold-expression with the given operator.
4186 ///
4187 /// By default, produces the fallback value for the fold-expression, or
4188 /// produce an error if there is no fallback value.
4189 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4190 BinaryOperatorKind Operator) {
4191 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4192 }
4193
4194 /// Build a new atomic operation expression.
4195 ///
4196 /// By default, performs semantic analysis to build the new expression.
4197 /// Subclasses may override this routine to provide different behavior.
4198 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4199 AtomicExpr::AtomicOp Op,
4200 SourceLocation RParenLoc) {
4201 // Use this for all of the locations, since we don't know the difference
4202 // between the call and the expr at this point.
4203 SourceRange Range{BuiltinLoc, RParenLoc};
4204 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4205 Sema::AtomicArgumentOrder::AST);
4206 }
4207
4208 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4209 ArrayRef<Expr *> SubExprs, QualType Type) {
4210 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4211 }
4212
4213 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4214 SourceLocation BeginLoc,
4215 SourceLocation DirLoc,
4216 SourceLocation EndLoc,
4217 ArrayRef<OpenACCClause *> Clauses,
4218 StmtResult StrBlock) {
4219 return getSema().OpenACC().ActOnEndStmtDirective(
4220 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4221 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4222 }
4223
4224 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4225 SourceLocation DirLoc,
4226 SourceLocation EndLoc,
4227 ArrayRef<OpenACCClause *> Clauses,
4228 StmtResult Loop) {
4229 return getSema().OpenACC().ActOnEndStmtDirective(
4230 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4231 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4232 Clauses, Loop);
4233 }
4234
4235 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4236 SourceLocation BeginLoc,
4237 SourceLocation DirLoc,
4238 SourceLocation EndLoc,
4239 ArrayRef<OpenACCClause *> Clauses,
4240 StmtResult Loop) {
4241 return getSema().OpenACC().ActOnEndStmtDirective(
4242 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4243 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4244 }
4245
4246 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4247 SourceLocation DirLoc,
4248 SourceLocation EndLoc,
4249 ArrayRef<OpenACCClause *> Clauses,
4250 StmtResult StrBlock) {
4251 return getSema().OpenACC().ActOnEndStmtDirective(
4252 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4253 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4254 Clauses, StrBlock);
4255 }
4256
4257 StmtResult
4258 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4259 SourceLocation DirLoc, SourceLocation EndLoc,
4260 ArrayRef<OpenACCClause *> Clauses) {
4261 return getSema().OpenACC().ActOnEndStmtDirective(
4262 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4263 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4264 Clauses, {});
4265 }
4266
4267 StmtResult
4268 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4269 SourceLocation DirLoc, SourceLocation EndLoc,
4270 ArrayRef<OpenACCClause *> Clauses) {
4271 return getSema().OpenACC().ActOnEndStmtDirective(
4272 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4273 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4274 Clauses, {});
4275 }
4276
4277 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4278 SourceLocation DirLoc,
4279 SourceLocation EndLoc,
4280 ArrayRef<OpenACCClause *> Clauses,
4281 StmtResult StrBlock) {
4282 return getSema().OpenACC().ActOnEndStmtDirective(
4283 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4284 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4285 Clauses, StrBlock);
4286 }
4287
4288 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4289 SourceLocation DirLoc,
4290 SourceLocation EndLoc,
4291 ArrayRef<OpenACCClause *> Clauses) {
4292 return getSema().OpenACC().ActOnEndStmtDirective(
4293 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4294 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4295 Clauses, {});
4296 }
4297
4298 StmtResult
4299 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4300 SourceLocation DirLoc, SourceLocation EndLoc,
4301 ArrayRef<OpenACCClause *> Clauses) {
4302 return getSema().OpenACC().ActOnEndStmtDirective(
4303 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4304 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4305 Clauses, {});
4306 }
4307
4308 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4309 SourceLocation DirLoc,
4310 SourceLocation EndLoc,
4311 ArrayRef<OpenACCClause *> Clauses) {
4312 return getSema().OpenACC().ActOnEndStmtDirective(
4313 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4314 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4315 Clauses, {});
4316 }
4317
4318 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4319 SourceLocation DirLoc,
4320 SourceLocation EndLoc,
4321 ArrayRef<OpenACCClause *> Clauses) {
4322 return getSema().OpenACC().ActOnEndStmtDirective(
4323 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4324 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4325 Clauses, {});
4326 }
4327
4328 StmtResult RebuildOpenACCWaitConstruct(
4329 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4330 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4331 SourceLocation RParenLoc, SourceLocation EndLoc,
4332 ArrayRef<OpenACCClause *> Clauses) {
4333 llvm::SmallVector<Expr *> Exprs;
4334 Exprs.push_back(Elt: DevNumExpr);
4335 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4336 return getSema().OpenACC().ActOnEndStmtDirective(
4337 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4338 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4339 }
4340
4341 StmtResult RebuildOpenACCCacheConstruct(
4342 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4343 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4344 SourceLocation RParenLoc, SourceLocation EndLoc) {
4345 return getSema().OpenACC().ActOnEndStmtDirective(
4346 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4347 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4348 }
4349
4350 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4351 SourceLocation DirLoc,
4352 OpenACCAtomicKind AtKind,
4353 SourceLocation EndLoc,
4354 ArrayRef<OpenACCClause *> Clauses,
4355 StmtResult AssociatedStmt) {
4356 return getSema().OpenACC().ActOnEndStmtDirective(
4357 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4358 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4359 AssociatedStmt);
4360 }
4361
4362 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4363 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4364 }
4365
4366 ExprResult
4367 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl, unsigned Index,
4368 QualType ParamType, SourceLocation Loc,
4369 TemplateArgument Arg,
4370 UnsignedOrNone PackIndex, bool Final) {
4371 return getSema().BuildSubstNonTypeTemplateParmExpr(
4372 AssociatedDecl, Index, ParamType, Loc, Arg, PackIndex, Final);
4373 }
4374
4375 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4376 SourceLocation StartLoc,
4377 SourceLocation LParenLoc,
4378 SourceLocation EndLoc) {
4379 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4380 LParenLoc, EndLoc);
4381 }
4382
4383private:
4384 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4385 QualType ObjectType,
4386 NamedDecl *FirstQualifierInScope);
4387
4388 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4389 QualType ObjectType,
4390 NamedDecl *FirstQualifierInScope) {
4391 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4392 return TSInfo;
4393
4394 TypeLocBuilder TLB;
4395 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4396 ObjectType, FirstQualifierInScope);
4397 if (T.isNull())
4398 return nullptr;
4399 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4400 }
4401
4402 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4403 DependentNameTypeLoc TL,
4404 bool DeducibleTSTContext,
4405 QualType ObjectType = QualType(),
4406 NamedDecl *UnqualLookup = nullptr);
4407
4408 llvm::SmallVector<OpenACCClause *>
4409 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4410 ArrayRef<const OpenACCClause *> OldClauses);
4411
4412 OpenACCClause *
4413 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4414 OpenACCDirectiveKind DirKind,
4415 const OpenACCClause *OldClause);
4416};
4417
4418template <typename Derived>
4419StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4420 if (!S)
4421 return S;
4422
4423 switch (S->getStmtClass()) {
4424 case Stmt::NoStmtClass: break;
4425
4426 // Transform individual statement nodes
4427 // Pass SDK into statements that can produce a value
4428#define STMT(Node, Parent) \
4429 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4430#define VALUESTMT(Node, Parent) \
4431 case Stmt::Node##Class: \
4432 return getDerived().Transform##Node(cast<Node>(S), SDK);
4433#define ABSTRACT_STMT(Node)
4434#define EXPR(Node, Parent)
4435#include "clang/AST/StmtNodes.inc"
4436
4437 // Transform expressions by calling TransformExpr.
4438#define STMT(Node, Parent)
4439#define ABSTRACT_STMT(Stmt)
4440#define EXPR(Node, Parent) case Stmt::Node##Class:
4441#include "clang/AST/StmtNodes.inc"
4442 {
4443 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4444
4445 if (SDK == StmtDiscardKind::StmtExprResult)
4446 E = getSema().ActOnStmtExprResult(E);
4447 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4448 }
4449 }
4450
4451 return S;
4452}
4453
4454template<typename Derived>
4455OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4456 if (!S)
4457 return S;
4458
4459 switch (S->getClauseKind()) {
4460 default: break;
4461 // Transform individual clause nodes
4462#define GEN_CLANG_CLAUSE_CLASS
4463#define CLAUSE_CLASS(Enum, Str, Class) \
4464 case Enum: \
4465 return getDerived().Transform##Class(cast<Class>(S));
4466#include "llvm/Frontend/OpenMP/OMP.inc"
4467 }
4468
4469 return S;
4470}
4471
4472
4473template<typename Derived>
4474ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4475 if (!E)
4476 return E;
4477
4478 switch (E->getStmtClass()) {
4479 case Stmt::NoStmtClass: break;
4480#define STMT(Node, Parent) case Stmt::Node##Class: break;
4481#define ABSTRACT_STMT(Stmt)
4482#define EXPR(Node, Parent) \
4483 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4484#include "clang/AST/StmtNodes.inc"
4485 }
4486
4487 return E;
4488}
4489
4490template<typename Derived>
4491ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4492 bool NotCopyInit) {
4493 // Initializers are instantiated like expressions, except that various outer
4494 // layers are stripped.
4495 if (!Init)
4496 return Init;
4497
4498 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4499 Init = FE->getSubExpr();
4500
4501 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4502 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4503 Init = OVE->getSourceExpr();
4504 }
4505
4506 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4507 Init = MTE->getSubExpr();
4508
4509 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4510 Init = Binder->getSubExpr();
4511
4512 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4513 Init = ICE->getSubExprAsWritten();
4514
4515 if (CXXStdInitializerListExpr *ILE =
4516 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4517 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4518
4519 // If this is copy-initialization, we only need to reconstruct
4520 // InitListExprs. Other forms of copy-initialization will be a no-op if
4521 // the initializer is already the right type.
4522 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4523 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4524 return getDerived().TransformExpr(Init);
4525
4526 // Revert value-initialization back to empty parens.
4527 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4528 SourceRange Parens = VIE->getSourceRange();
4529 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4530 Parens.getEnd());
4531 }
4532
4533 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4534 if (isa<ImplicitValueInitExpr>(Val: Init))
4535 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4536 SourceLocation());
4537
4538 // Revert initialization by constructor back to a parenthesized or braced list
4539 // of expressions. Any other form of initializer can just be reused directly.
4540 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4541 return getDerived().TransformExpr(Init);
4542
4543 // If the initialization implicitly converted an initializer list to a
4544 // std::initializer_list object, unwrap the std::initializer_list too.
4545 if (Construct && Construct->isStdInitListInitialization())
4546 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4547
4548 // Enter a list-init context if this was list initialization.
4549 EnterExpressionEvaluationContext Context(
4550 getSema(), EnterExpressionEvaluationContext::InitList,
4551 Construct->isListInitialization());
4552
4553 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4554 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4555 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4556 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4557 SmallVector<Expr*, 8> NewArgs;
4558 bool ArgChanged = false;
4559 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4560 /*IsCall*/true, NewArgs, &ArgChanged))
4561 return ExprError();
4562
4563 // If this was list initialization, revert to syntactic list form.
4564 if (Construct->isListInitialization())
4565 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4566 Construct->getEndLoc(),
4567 /*IsExplicit=*/true);
4568
4569 // Build a ParenListExpr to represent anything else.
4570 SourceRange Parens = Construct->getParenOrBraceRange();
4571 if (Parens.isInvalid()) {
4572 // This was a variable declaration's initialization for which no initializer
4573 // was specified.
4574 assert(NewArgs.empty() &&
4575 "no parens or braces but have direct init with arguments?");
4576 return ExprEmpty();
4577 }
4578 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4579 Parens.getEnd());
4580}
4581
4582template<typename Derived>
4583bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4584 unsigned NumInputs,
4585 bool IsCall,
4586 SmallVectorImpl<Expr *> &Outputs,
4587 bool *ArgChanged) {
4588 for (unsigned I = 0; I != NumInputs; ++I) {
4589 // If requested, drop call arguments that need to be dropped.
4590 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4591 if (ArgChanged)
4592 *ArgChanged = true;
4593
4594 break;
4595 }
4596
4597 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4598 Expr *Pattern = Expansion->getPattern();
4599
4600 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4601 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4602 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4603
4604 // Determine whether the set of unexpanded parameter packs can and should
4605 // be expanded.
4606 bool Expand = true;
4607 bool RetainExpansion = false;
4608 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4609 UnsignedOrNone NumExpansions = OrigNumExpansions;
4610 if (getDerived().TryExpandParameterPacks(
4611 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4612 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4613 RetainExpansion, NumExpansions))
4614 return true;
4615
4616 if (!Expand) {
4617 // The transform has determined that we should perform a simple
4618 // transformation on the pack expansion, producing another pack
4619 // expansion.
4620 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4621 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4622 if (OutPattern.isInvalid())
4623 return true;
4624
4625 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4626 Expansion->getEllipsisLoc(),
4627 NumExpansions);
4628 if (Out.isInvalid())
4629 return true;
4630
4631 if (ArgChanged)
4632 *ArgChanged = true;
4633 Outputs.push_back(Elt: Out.get());
4634 continue;
4635 }
4636
4637 // Record right away that the argument was changed. This needs
4638 // to happen even if the array expands to nothing.
4639 if (ArgChanged) *ArgChanged = true;
4640
4641 // The transform has determined that we should perform an elementwise
4642 // expansion of the pattern. Do so.
4643 for (unsigned I = 0; I != *NumExpansions; ++I) {
4644 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4645 ExprResult Out = getDerived().TransformExpr(Pattern);
4646 if (Out.isInvalid())
4647 return true;
4648
4649 if (Out.get()->containsUnexpandedParameterPack()) {
4650 Out = getDerived().RebuildPackExpansion(
4651 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4652 if (Out.isInvalid())
4653 return true;
4654 }
4655
4656 Outputs.push_back(Elt: Out.get());
4657 }
4658
4659 // If we're supposed to retain a pack expansion, do so by temporarily
4660 // forgetting the partially-substituted parameter pack.
4661 if (RetainExpansion) {
4662 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4663
4664 ExprResult Out = getDerived().TransformExpr(Pattern);
4665 if (Out.isInvalid())
4666 return true;
4667
4668 Out = getDerived().RebuildPackExpansion(
4669 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4670 if (Out.isInvalid())
4671 return true;
4672
4673 Outputs.push_back(Elt: Out.get());
4674 }
4675
4676 continue;
4677 }
4678
4679 ExprResult Result =
4680 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4681 : getDerived().TransformExpr(Inputs[I]);
4682 if (Result.isInvalid())
4683 return true;
4684
4685 if (Result.get() != Inputs[I] && ArgChanged)
4686 *ArgChanged = true;
4687
4688 Outputs.push_back(Elt: Result.get());
4689 }
4690
4691 return false;
4692}
4693
4694template <typename Derived>
4695Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4696 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4697
4698 EnterExpressionEvaluationContext Eval(
4699 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4700 /*LambdaContextDecl=*/nullptr,
4701 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4702 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4703
4704 if (Var) {
4705 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4706 getDerived().TransformDefinition(Var->getLocation(), Var));
4707
4708 if (!ConditionVar)
4709 return Sema::ConditionError();
4710
4711 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4712 }
4713
4714 if (Expr) {
4715 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4716
4717 if (CondExpr.isInvalid())
4718 return Sema::ConditionError();
4719
4720 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4721 /*MissingOK=*/true);
4722 }
4723
4724 return Sema::ConditionResult();
4725}
4726
4727template <typename Derived>
4728NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4729 NestedNameSpecifierLoc NNS, QualType ObjectType,
4730 NamedDecl *FirstQualifierInScope) {
4731 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4732
4733 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4734 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4735 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4736 Qualifiers.push_back(Elt: Qualifier);
4737 };
4738 insertNNS(NNS);
4739
4740 CXXScopeSpec SS;
4741 while (!Qualifiers.empty()) {
4742 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4743 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4744
4745 switch (QNNS.getKind()) {
4746 case NestedNameSpecifier::Kind::Null:
4747 llvm_unreachable("unexpected null nested name specifier");
4748
4749 case NestedNameSpecifier::Kind::Namespace: {
4750 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4751 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4752 QNNS.getAsNamespaceAndPrefix().Namespace)));
4753 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4754 break;
4755 }
4756
4757 case NestedNameSpecifier::Kind::Global:
4758 // There is no meaningful transformation that one could perform on the
4759 // global scope.
4760 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4761 break;
4762
4763 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4764 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4765 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4766 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4767 ColonColonLoc: Q.getEndLoc());
4768 break;
4769 }
4770
4771 case NestedNameSpecifier::Kind::Type: {
4772 assert(SS.isEmpty());
4773 TypeLoc TL = Q.castAsTypeLoc();
4774
4775 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4776 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4777 if (QualifierLoc) {
4778 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4779 QualifierLoc, ObjectType, FirstQualifierInScope);
4780 if (!QualifierLoc)
4781 return NestedNameSpecifierLoc();
4782 ObjectType = QualType();
4783 FirstQualifierInScope = nullptr;
4784 }
4785 SS.Adopt(Other: QualifierLoc);
4786 Sema::NestedNameSpecInfo IdInfo(
4787 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4788 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4789 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4790 EnteringContext: false, SS,
4791 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4792 return NestedNameSpecifierLoc();
4793 return SS.getWithLocInContext(Context&: SemaRef.Context);
4794 }
4795
4796 QualType T = TL.getType();
4797 TypeLocBuilder TLB;
4798 if (!getDerived().AlreadyTransformed(T)) {
4799 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4800 FirstQualifierInScope);
4801 if (T.isNull())
4802 return NestedNameSpecifierLoc();
4803 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4804 }
4805
4806 if (T->isDependentType() || T->isRecordType() ||
4807 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4808 if (T->isEnumeralType())
4809 SemaRef.Diag(Loc: TL.getBeginLoc(),
4810 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4811 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4812 break;
4813 }
4814 // If the nested-name-specifier is an invalid type def, don't emit an
4815 // error because a previous error should have already been emitted.
4816 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4817 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4818 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4819 << T << SS.getRange();
4820 }
4821 return NestedNameSpecifierLoc();
4822 }
4823 }
4824 }
4825
4826 // Don't rebuild the nested-name-specifier if we don't have to.
4827 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4828 !getDerived().AlwaysRebuild())
4829 return NNS;
4830
4831 // If we can re-use the source-location data from the original
4832 // nested-name-specifier, do so.
4833 if (SS.location_size() == NNS.getDataLength() &&
4834 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4835 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4836
4837 // Allocate new nested-name-specifier location information.
4838 return SS.getWithLocInContext(Context&: SemaRef.Context);
4839}
4840
4841template<typename Derived>
4842DeclarationNameInfo
4843TreeTransform<Derived>
4844::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4845 DeclarationName Name = NameInfo.getName();
4846 if (!Name)
4847 return DeclarationNameInfo();
4848
4849 switch (Name.getNameKind()) {
4850 case DeclarationName::Identifier:
4851 case DeclarationName::ObjCZeroArgSelector:
4852 case DeclarationName::ObjCOneArgSelector:
4853 case DeclarationName::ObjCMultiArgSelector:
4854 case DeclarationName::CXXOperatorName:
4855 case DeclarationName::CXXLiteralOperatorName:
4856 case DeclarationName::CXXUsingDirective:
4857 return NameInfo;
4858
4859 case DeclarationName::CXXDeductionGuideName: {
4860 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4861 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4862 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4863 if (!NewTemplate)
4864 return DeclarationNameInfo();
4865
4866 DeclarationNameInfo NewNameInfo(NameInfo);
4867 NewNameInfo.setName(
4868 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4869 return NewNameInfo;
4870 }
4871
4872 case DeclarationName::CXXConstructorName:
4873 case DeclarationName::CXXDestructorName:
4874 case DeclarationName::CXXConversionFunctionName: {
4875 TypeSourceInfo *NewTInfo;
4876 CanQualType NewCanTy;
4877 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4878 NewTInfo = getDerived().TransformType(OldTInfo);
4879 if (!NewTInfo)
4880 return DeclarationNameInfo();
4881 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4882 }
4883 else {
4884 NewTInfo = nullptr;
4885 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4886 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4887 if (NewT.isNull())
4888 return DeclarationNameInfo();
4889 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4890 }
4891
4892 DeclarationName NewName
4893 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4894 Ty: NewCanTy);
4895 DeclarationNameInfo NewNameInfo(NameInfo);
4896 NewNameInfo.setName(NewName);
4897 NewNameInfo.setNamedTypeInfo(NewTInfo);
4898 return NewNameInfo;
4899 }
4900 }
4901
4902 llvm_unreachable("Unknown name kind.");
4903}
4904
4905template <typename Derived>
4906TemplateName TreeTransform<Derived>::RebuildTemplateName(
4907 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4908 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4909 QualType ObjectType, bool AllowInjectedClassName) {
4910 if (const IdentifierInfo *II = IO.getIdentifier())
4911 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4912 ObjectType, AllowInjectedClassName);
4913 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4914 NameLoc, ObjectType,
4915 AllowInjectedClassName);
4916}
4917
4918template <typename Derived>
4919TemplateName TreeTransform<Derived>::TransformTemplateName(
4920 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4921 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4922 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4923 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4924 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4925
4926 if (QualifierLoc) {
4927 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4928 QualifierLoc, ObjectType, FirstQualifierInScope);
4929 if (!QualifierLoc)
4930 return TemplateName();
4931 }
4932
4933 NestedNameSpecifierLoc UnderlyingQualifier;
4934 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4935 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4936 FirstQualifierInScope, AllowInjectedClassName);
4937 if (NewUnderlyingName.isNull())
4938 return TemplateName();
4939 assert(!UnderlyingQualifier && "unexpected qualifier");
4940
4941 if (!getDerived().AlwaysRebuild() &&
4942 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4943 NewUnderlyingName == UnderlyingName)
4944 return Name;
4945 CXXScopeSpec SS;
4946 SS.Adopt(Other: QualifierLoc);
4947 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4948 NewUnderlyingName);
4949 }
4950
4951 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4952 if (QualifierLoc) {
4953 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4954 QualifierLoc, ObjectType, FirstQualifierInScope);
4955 if (!QualifierLoc)
4956 return TemplateName();
4957 // The qualifier-in-scope and object type only apply to the leftmost
4958 // entity.
4959 ObjectType = QualType();
4960 }
4961
4962 if (!getDerived().AlwaysRebuild() &&
4963 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4964 ObjectType.isNull())
4965 return Name;
4966
4967 CXXScopeSpec SS;
4968 SS.Adopt(Other: QualifierLoc);
4969 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4970 NameLoc, ObjectType,
4971 AllowInjectedClassName);
4972 }
4973
4974 if (SubstTemplateTemplateParmStorage *S =
4975 Name.getAsSubstTemplateTemplateParm()) {
4976 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4977
4978 NestedNameSpecifierLoc ReplacementQualifierLoc;
4979 TemplateName ReplacementName = S->getReplacement();
4980 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4981 NestedNameSpecifierLocBuilder Builder;
4982 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4983 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4984 }
4985
4986 TemplateName NewName = getDerived().TransformTemplateName(
4987 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4988 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4989 if (NewName.isNull())
4990 return TemplateName();
4991 Decl *AssociatedDecl =
4992 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4993 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4994 AssociatedDecl == S->getAssociatedDecl())
4995 return Name;
4996 return SemaRef.Context.getSubstTemplateTemplateParm(
4997 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4998 Final: S->getFinal());
4999 }
5000
5001 if (PackIndexingTemplateStorage *PI = Name.getAsPackIndexingTemplate()) {
5002 assert(!QualifierLoc && "Unexpected qualified pack-index-template-name");
5003
5004 ExprResult IndexExpr;
5005 {
5006 EnterExpressionEvaluationContext ConstantContext(
5007 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5008 IndexExpr = getDerived().TransformExpr(PI->getIndexExpr());
5009 if (IndexExpr.isInvalid())
5010 return TemplateName();
5011 }
5012
5013 auto TransformOne = [&](TemplateName N) {
5014 NestedNameSpecifierLoc NoQualifier;
5015 return getDerived().TransformTemplateName(
5016 NoQualifier, TemplateKWLoc, N, NameLoc, ObjectType,
5017 FirstQualifierInScope, AllowInjectedClassName);
5018 };
5019
5020 TemplateName Pattern = PI->getPattern();
5021 SmallVector<TemplateName, 4> SubstitutedNames;
5022 ArrayRef<TemplateName> Names = PI->getExpansions();
5023
5024 bool NotYetExpanded = Names.empty();
5025 bool FullySubstituted = true;
5026
5027 if (Names.empty() && !PI->expandsToEmptyPack())
5028 Names = ArrayRef(&Pattern, 1);
5029
5030 for (TemplateName N : Names) {
5031 if (!N.containsUnexpandedParameterPack()) {
5032 TemplateName Transformed = TransformOne(N);
5033 if (Transformed.isNull())
5034 return TemplateName();
5035 SubstitutedNames.push_back(Elt: Transformed);
5036 continue;
5037 }
5038
5039 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5040 getSema().collectUnexpandedParameterPacks(N, Unexpanded);
5041 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5042
5043 bool ShouldExpand = true;
5044 bool RetainExpansion = false;
5045 UnsignedOrNone NumExpansions = std::nullopt;
5046 if (getDerived().TryExpandParameterPacks(
5047 NameLoc, SourceRange(), Unexpanded,
5048 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
5049 RetainExpansion, NumExpansions))
5050 return TemplateName();
5051
5052 if (!ShouldExpand) {
5053 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5054 TemplateName Pack = TransformOne(N);
5055 if (Pack.isNull())
5056 return TemplateName();
5057 if (NotYetExpanded) {
5058 FullySubstituted = false;
5059 return getDerived().RebuildPackIndexingTemplateName(
5060 Pack, IndexExpr.get(), FullySubstituted);
5061 }
5062 SubstitutedNames.push_back(Elt: Pack);
5063 continue;
5064 }
5065
5066 for (unsigned I = 0; I != *NumExpansions; ++I) {
5067 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5068 TemplateName Out = TransformOne(N);
5069 if (Out.isNull())
5070 return TemplateName();
5071 SubstitutedNames.push_back(Elt: Out);
5072 FullySubstituted &= !Out.containsUnexpandedParameterPack();
5073 }
5074
5075 // If we're supposed to retain a pack expansion, do so by temporarily
5076 // forgetting the partially-substituted parameter pack.
5077 if (RetainExpansion) {
5078 FullySubstituted = false;
5079 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5080 TemplateName Out = TransformOne(N);
5081 if (Out.isNull())
5082 return TemplateName();
5083 SubstitutedNames.push_back(Elt: Out);
5084 }
5085 }
5086
5087 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5088 TemplateName NewPattern = TransformOne(Pattern);
5089 if (NewPattern.isNull())
5090 return TemplateName();
5091
5092 return getDerived().RebuildPackIndexingTemplateName(
5093 NewPattern, IndexExpr.get(), FullySubstituted, SubstitutedNames);
5094 }
5095
5096 assert(!Name.getAsDeducedTemplateName() &&
5097 "DeducedTemplateName should not escape partial ordering");
5098
5099 // FIXME: Preserve UsingTemplateName.
5100 if (auto *Template = Name.getAsTemplateDecl()) {
5101 assert(!QualifierLoc && "Unexpected qualifier");
5102 return TemplateName(cast_or_null<TemplateDecl>(
5103 getDerived().TransformDecl(NameLoc, Template)));
5104 }
5105
5106 if (SubstTemplateTemplateParmPackStorage *SubstPack
5107 = Name.getAsSubstTemplateTemplateParmPack()) {
5108 assert(!QualifierLoc &&
5109 "Unexpected qualified SubstTemplateTemplateParmPack");
5110 return getDerived().RebuildTemplateName(
5111 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
5112 SubstPack->getIndex(), SubstPack->getFinal());
5113 }
5114
5115 // These should be getting filtered out before they reach the AST.
5116 llvm_unreachable("overloaded function decl survived to here");
5117}
5118
5119template <typename Derived>
5120TemplateName
5121TreeTransform<Derived>::TransformConceptTemplateName(TemplateName Name,
5122 SourceLocation NameLoc) {
5123 NestedNameSpecifierLoc QualifierLoc;
5124 return getDerived().TransformTemplateName(
5125 QualifierLoc, /*TemplateKWLoc=*/SourceLocation(), Name, NameLoc);
5126}
5127
5128template <typename Derived>
5129TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
5130 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
5131 TemplateName Name, SourceLocation NameLoc) {
5132 TemplateName TN = getDerived().TransformTemplateName(
5133 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
5134 if (TN.isNull())
5135 return TemplateArgument();
5136 return TemplateArgument(TN);
5137}
5138
5139template<typename Derived>
5140void TreeTransform<Derived>::InventTemplateArgumentLoc(
5141 const TemplateArgument &Arg,
5142 TemplateArgumentLoc &Output) {
5143 Output = getSema().getTrivialTemplateArgumentLoc(
5144 Arg, QualType(), getDerived().getBaseLocation());
5145}
5146
5147template <typename Derived>
5148bool TreeTransform<Derived>::TransformTemplateArgument(
5149 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5150 bool Uneval) {
5151 const TemplateArgument &Arg = Input.getArgument();
5152 switch (Arg.getKind()) {
5153 case TemplateArgument::Null:
5154 case TemplateArgument::Pack:
5155 llvm_unreachable("Unexpected TemplateArgument");
5156
5157 case TemplateArgument::Integral:
5158 case TemplateArgument::NullPtr:
5159 case TemplateArgument::Declaration:
5160 case TemplateArgument::StructuralValue: {
5161 // Transform a resolved template argument straight to a resolved template
5162 // argument. We get here when substituting into an already-substituted
5163 // template type argument during concept satisfaction checking.
5164 QualType T = Arg.getNonTypeTemplateArgumentType();
5165 QualType NewT = getDerived().TransformType(T);
5166 if (NewT.isNull())
5167 return true;
5168
5169 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5170 ? Arg.getAsDecl()
5171 : nullptr;
5172 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5173 getDerived().getBaseLocation(), D))
5174 : nullptr;
5175 if (D && !NewD)
5176 return true;
5177
5178 if (NewT == T && D == NewD)
5179 Output = Input;
5180 else if (Arg.getKind() == TemplateArgument::Integral)
5181 Output = TemplateArgumentLoc(
5182 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5183 TemplateArgumentLocInfo());
5184 else if (Arg.getKind() == TemplateArgument::NullPtr)
5185 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5186 TemplateArgumentLocInfo());
5187 else if (Arg.getKind() == TemplateArgument::Declaration)
5188 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5189 TemplateArgumentLocInfo());
5190 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5191 Output = TemplateArgumentLoc(
5192 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5193 TemplateArgumentLocInfo());
5194 else
5195 llvm_unreachable("unexpected template argument kind");
5196
5197 return false;
5198 }
5199
5200 case TemplateArgument::Type: {
5201 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5202 if (!TSI)
5203 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5204
5205 TSI = getDerived().TransformType(TSI);
5206 if (!TSI)
5207 return true;
5208
5209 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5210 return false;
5211 }
5212
5213 case TemplateArgument::Template: {
5214 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5215
5216 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5217 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5218 Input.getTemplateNameLoc());
5219 if (Out.isNull())
5220 return true;
5221 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5222 QualifierLoc, Input.getTemplateNameLoc());
5223 return false;
5224 }
5225
5226 case TemplateArgument::TemplateExpansion:
5227 llvm_unreachable("Caller should expand pack expansions");
5228
5229 case TemplateArgument::Expression: {
5230 // Template argument expressions are constant expressions.
5231 EnterExpressionEvaluationContext Unevaluated(
5232 getSema(),
5233 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5234 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5235 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5236 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5237
5238 Expr *InputExpr = Input.getSourceExpression();
5239 if (!InputExpr)
5240 InputExpr = Input.getArgument().getAsExpr();
5241
5242 ExprResult E = getDerived().TransformExpr(InputExpr);
5243 E = SemaRef.ActOnConstantExpression(Res: E);
5244 if (E.isInvalid())
5245 return true;
5246 Output = TemplateArgumentLoc(
5247 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5248 return false;
5249 }
5250 }
5251
5252 // Work around bogus GCC warning
5253 return true;
5254}
5255
5256/// Iterator adaptor that invents template argument location information
5257/// for each of the template arguments in its underlying iterator.
5258template<typename Derived, typename InputIterator>
5259class TemplateArgumentLocInventIterator {
5260 TreeTransform<Derived> &Self;
5261 InputIterator Iter;
5262
5263public:
5264 typedef TemplateArgumentLoc value_type;
5265 typedef TemplateArgumentLoc reference;
5266 typedef typename std::iterator_traits<InputIterator>::difference_type
5267 difference_type;
5268 typedef std::input_iterator_tag iterator_category;
5269
5270 class pointer {
5271 TemplateArgumentLoc Arg;
5272
5273 public:
5274 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5275
5276 const TemplateArgumentLoc *operator->() const { return &Arg; }
5277 };
5278
5279 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5280 InputIterator Iter)
5281 : Self(Self), Iter(Iter) { }
5282
5283 TemplateArgumentLocInventIterator &operator++() {
5284 ++Iter;
5285 return *this;
5286 }
5287
5288 TemplateArgumentLocInventIterator operator++(int) {
5289 TemplateArgumentLocInventIterator Old(*this);
5290 ++(*this);
5291 return Old;
5292 }
5293
5294 reference operator*() const {
5295 TemplateArgumentLoc Result;
5296 Self.InventTemplateArgumentLoc(*Iter, Result);
5297 return Result;
5298 }
5299
5300 pointer operator->() const { return pointer(**this); }
5301
5302 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5303 const TemplateArgumentLocInventIterator &Y) {
5304 return X.Iter == Y.Iter;
5305 }
5306
5307 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5308 const TemplateArgumentLocInventIterator &Y) {
5309 return X.Iter != Y.Iter;
5310 }
5311};
5312
5313template<typename Derived>
5314template<typename InputIterator>
5315bool TreeTransform<Derived>::TransformTemplateArguments(
5316 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5317 bool Uneval) {
5318 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5319 TemplateArgumentLoc Out;
5320 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5321 // Unpack argument packs, which we translate them into separate
5322 // arguments.
5323 // FIXME: We could do much better if we could guarantee that the
5324 // TemplateArgumentLocInfo for the pack expansion would be usable for
5325 // all of the template arguments in the argument pack.
5326 typedef TemplateArgumentLocInventIterator<Derived,
5327 TemplateArgument::pack_iterator>
5328 PackLocIterator;
5329
5330 TemplateArgumentListInfo *PackOutput = &Outputs;
5331 TemplateArgumentListInfo New;
5332
5333 if (TransformTemplateArguments(
5334 PackLocIterator(*this, In.getArgument().pack_begin()),
5335 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5336 Uneval))
5337 return true;
5338
5339 continue;
5340 }
5341
5342 if (In.getArgument().isPackExpansion()) {
5343 UnexpandedInfo Info;
5344 TemplateArgumentLoc Prepared;
5345 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5346 return true;
5347 if (!Info.Expand) {
5348 Outputs.addArgument(Loc: Prepared);
5349 continue;
5350 }
5351
5352 // The transform has determined that we should perform an elementwise
5353 // expansion of the pattern. Do so.
5354 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5355 if (Info.ExpandUnderForgetSubstitions)
5356 ForgetSubst.emplace(getDerived());
5357 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5358 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5359
5360 TemplateArgumentLoc Out;
5361 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5362 return true;
5363
5364 if (Out.getArgument().containsUnexpandedParameterPack()) {
5365 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5366 Info.OrigNumExpansions);
5367 if (Out.getArgument().isNull())
5368 return true;
5369 }
5370
5371 Outputs.addArgument(Loc: Out);
5372 }
5373
5374 // If we're supposed to retain a pack expansion, do so by temporarily
5375 // forgetting the partially-substituted parameter pack.
5376 if (Info.RetainExpansion) {
5377 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5378
5379 TemplateArgumentLoc Out;
5380 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5381 return true;
5382
5383 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5384 Info.OrigNumExpansions);
5385 if (Out.getArgument().isNull())
5386 return true;
5387
5388 Outputs.addArgument(Loc: Out);
5389 }
5390
5391 continue;
5392 }
5393
5394 // The simple case:
5395 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5396 return true;
5397
5398 Outputs.addArgument(Loc: Out);
5399 }
5400
5401 return false;
5402}
5403
5404template <typename Derived>
5405template <typename InputIterator>
5406bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5407 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5408 bool Uneval) {
5409
5410 // [C++26][temp.constr.normal]
5411 // any non-dependent concept template argument
5412 // is substituted into the constraint-expression of C.
5413 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5414 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5415 };
5416
5417 for (; First != Last; ++First) {
5418 TemplateArgumentLoc Out;
5419 TemplateArgumentLoc In = *First;
5420
5421 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5422 typedef TemplateArgumentLocInventIterator<Derived,
5423 TemplateArgument::pack_iterator>
5424 PackLocIterator;
5425 if (TransformConceptTemplateArguments(
5426 PackLocIterator(*this, In.getArgument().pack_begin()),
5427 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5428 Uneval))
5429 return true;
5430 continue;
5431 }
5432
5433 if (!isNonDependentConceptArgument(In.getArgument())) {
5434 Outputs.addArgument(Loc: In);
5435 continue;
5436 }
5437
5438 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5439 return true;
5440
5441 Outputs.addArgument(Loc: Out);
5442 }
5443
5444 return false;
5445}
5446
5447// FIXME: Find ways to reduce code duplication for pack expansions.
5448template <typename Derived>
5449bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5450 bool Uneval,
5451 TemplateArgumentLoc &Out,
5452 UnexpandedInfo &Info) {
5453 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5454 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5455 TemplateArgumentLoc &Pattern) {
5456 assert(Arg.getArgument().isPackExpansion());
5457 // We have a pack expansion, for which we will be substituting into the
5458 // pattern.
5459 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5460 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5461 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5462 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5463 if (IsLateExpansionAttempt) {
5464 // Request expansion only when there is an opportunity to expand a pack
5465 // that required a substituion first.
5466 bool SawPackTypes =
5467 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5468 return isa<const SubstBuiltinTemplatePackType *>(Val: P.first);
5469 });
5470 if (!SawPackTypes) {
5471 Info.Expand = false;
5472 return false;
5473 }
5474 }
5475 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5476
5477 // Determine whether the set of unexpanded parameter packs can and
5478 // should be expanded.
5479 Info.Expand = true;
5480 Info.RetainExpansion = false;
5481 Info.NumExpansions = Info.OrigNumExpansions;
5482 return getDerived().TryExpandParameterPacks(
5483 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5484 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5485 Info.RetainExpansion, Info.NumExpansions);
5486 };
5487
5488 TemplateArgumentLoc Pattern;
5489 if (ComputeInfo(In, false, Info, Pattern))
5490 return true;
5491
5492 if (Info.Expand) {
5493 Out = Pattern;
5494 return false;
5495 }
5496
5497 // The transform has determined that we should perform a simple
5498 // transformation on the pack expansion, producing another pack
5499 // expansion.
5500 TemplateArgumentLoc OutPattern;
5501 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5502 std::in_place, getSema(), std::nullopt);
5503 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5504 return true;
5505
5506 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5507 Info.NumExpansions);
5508 if (Out.getArgument().isNull())
5509 return true;
5510 SubstIndex.reset();
5511
5512 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5513 return false;
5514
5515 // Some packs will learn their length after substitution, e.g.
5516 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5517 // value of `T`.
5518 //
5519 // We only expand after we know sizes of all packs, check if this is the case
5520 // or not. However, we avoid a full template substitution and only do
5521 // expanstions after this point.
5522
5523 // E.g. when substituting template arguments of tuple with {T -> int} in the
5524 // following example:
5525 // template <class T>
5526 // struct TupleWithInt {
5527 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5528 // };
5529 // TupleWithInt<int>::type y;
5530 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5531 // length and run `ComputeInfo()` to provide the necessary information to our
5532 // caller.
5533 //
5534 // Note that we may still have situations where builtin is not going to be
5535 // expanded. For example:
5536 // template <class T>
5537 // struct Foo {
5538 // template <class U> using tuple_with_t =
5539 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5540 // tuple_with_t<short>;
5541 // }
5542 // Because the substitution into `type` happens in dependent context, `type`
5543 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5544 // and the caller will not be able to expand it.
5545 ForgetSubstitutionRAII ForgetSubst(getDerived());
5546 if (ComputeInfo(Out, true, Info, OutPattern))
5547 return true;
5548 if (!Info.Expand)
5549 return false;
5550 Out = OutPattern;
5551 Info.ExpandUnderForgetSubstitions = true;
5552 return false;
5553}
5554
5555//===----------------------------------------------------------------------===//
5556// Type transformation
5557//===----------------------------------------------------------------------===//
5558
5559template<typename Derived>
5560QualType TreeTransform<Derived>::TransformType(QualType T) {
5561 if (getDerived().AlreadyTransformed(T))
5562 return T;
5563
5564 // Temporary workaround. All of these transformations should
5565 // eventually turn into transformations on TypeLocs.
5566 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5567 T, getDerived().getBaseLocation());
5568
5569 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5570
5571 if (!NewTSI)
5572 return QualType();
5573
5574 return NewTSI->getType();
5575}
5576
5577template <typename Derived>
5578TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5579 // Refine the base location to the type's location.
5580 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5581 getDerived().getBaseEntity());
5582 if (getDerived().AlreadyTransformed(TSI->getType()))
5583 return TSI;
5584
5585 TypeLocBuilder TLB;
5586
5587 TypeLoc TL = TSI->getTypeLoc();
5588 TLB.reserve(Requested: TL.getFullDataSize());
5589
5590 QualType Result = getDerived().TransformType(TLB, TL);
5591 if (Result.isNull())
5592 return nullptr;
5593
5594 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5595}
5596
5597template<typename Derived>
5598QualType
5599TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5600 switch (T.getTypeLocClass()) {
5601#define ABSTRACT_TYPELOC(CLASS, PARENT)
5602#define TYPELOC(CLASS, PARENT) \
5603 case TypeLoc::CLASS: \
5604 return getDerived().Transform##CLASS##Type(TLB, \
5605 T.castAs<CLASS##TypeLoc>());
5606#include "clang/AST/TypeLocNodes.def"
5607 }
5608
5609 llvm_unreachable("unhandled type loc!");
5610}
5611
5612template<typename Derived>
5613QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5614 if (!isa<DependentNameType>(Val: T))
5615 return TransformType(T);
5616
5617 if (getDerived().AlreadyTransformed(T))
5618 return T;
5619 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5620 T, getDerived().getBaseLocation());
5621 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5622 return NewTSI ? NewTSI->getType() : QualType();
5623}
5624
5625template <typename Derived>
5626TypeSourceInfo *
5627TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5628 if (!isa<DependentNameType>(Val: TSI->getType()))
5629 return TransformType(TSI);
5630
5631 // Refine the base location to the type's location.
5632 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5633 getDerived().getBaseEntity());
5634 if (getDerived().AlreadyTransformed(TSI->getType()))
5635 return TSI;
5636
5637 TypeLocBuilder TLB;
5638
5639 TypeLoc TL = TSI->getTypeLoc();
5640 TLB.reserve(Requested: TL.getFullDataSize());
5641
5642 auto QTL = TL.getAs<QualifiedTypeLoc>();
5643 if (QTL)
5644 TL = QTL.getUnqualifiedLoc();
5645
5646 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5647
5648 QualType Result = getDerived().TransformDependentNameType(
5649 TLB, DNTL, /*DeducedTSTContext*/true);
5650 if (Result.isNull())
5651 return nullptr;
5652
5653 if (QTL) {
5654 Result = getDerived().RebuildQualifiedType(Result, QTL);
5655 if (Result.isNull())
5656 return nullptr;
5657 TLB.TypeWasModifiedSafely(T: Result);
5658 }
5659
5660 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5661}
5662
5663template<typename Derived>
5664QualType
5665TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5666 QualifiedTypeLoc T) {
5667 QualType Result;
5668 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5669 auto SuppressObjCLifetime =
5670 T.getType().getLocalQualifiers().hasObjCLifetime();
5671 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5672 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5673 SuppressObjCLifetime);
5674 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5675 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5676 TLB, STTP, SuppressObjCLifetime);
5677 } else {
5678 Result = getDerived().TransformType(TLB, UnqualTL);
5679 }
5680
5681 if (Result.isNull())
5682 return QualType();
5683
5684 Result = getDerived().RebuildQualifiedType(Result, T);
5685
5686 if (Result.isNull())
5687 return QualType();
5688
5689 // RebuildQualifiedType might have updated the type, but not in a way
5690 // that invalidates the TypeLoc. (There's no location information for
5691 // qualifiers.)
5692 TLB.TypeWasModifiedSafely(T: Result);
5693
5694 return Result;
5695}
5696
5697template <typename Derived>
5698QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5699 QualifiedTypeLoc TL) {
5700
5701 SourceLocation Loc = TL.getBeginLoc();
5702 Qualifiers Quals = TL.getType().getLocalQualifiers();
5703
5704 if ((T.getAddressSpace() != LangAS::Default &&
5705 Quals.getAddressSpace() != LangAS::Default) &&
5706 T.getAddressSpace() != Quals.getAddressSpace()) {
5707 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5708 << TL.getType() << T;
5709 return QualType();
5710 }
5711
5712 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5713 if (LocalPointerAuth.isPresent()) {
5714 if (T.getPointerAuth().isPresent()) {
5715 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5716 return QualType();
5717 }
5718 if (!T->isDependentType()) {
5719 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5720 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5721 return QualType();
5722 }
5723 }
5724 }
5725 // C++ [dcl.fct]p7:
5726 // [When] adding cv-qualifications on top of the function type [...] the
5727 // cv-qualifiers are ignored.
5728 if (T->isFunctionType()) {
5729 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5730 AddressSpace: Quals.getAddressSpace());
5731 return T;
5732 }
5733
5734 // C++ [dcl.ref]p1:
5735 // when the cv-qualifiers are introduced through the use of a typedef-name
5736 // or decltype-specifier [...] the cv-qualifiers are ignored.
5737 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5738 // applied to a reference type.
5739 if (T->isReferenceType()) {
5740 // The only qualifier that applies to a reference type is restrict.
5741 if (!Quals.hasRestrict())
5742 return T;
5743 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5744 }
5745
5746 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5747 // resulting type.
5748 if (Quals.hasObjCLifetime()) {
5749 if (!T->isObjCLifetimeType() && !T->isDependentType())
5750 Quals.removeObjCLifetime();
5751 else if (T.getObjCLifetime()) {
5752 // Objective-C ARC:
5753 // A lifetime qualifier applied to a substituted template parameter
5754 // overrides the lifetime qualifier from the template argument.
5755 const AutoType *AutoTy;
5756 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5757 // 'auto' types behave the same way as template parameters.
5758 QualType Deduced = AutoTy->getDeducedType();
5759 Qualifiers Qs = Deduced.getQualifiers();
5760 Qs.removeObjCLifetime();
5761 Deduced =
5762 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5763 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5764 Keyword: AutoTy->getKeyword(),
5765 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5766 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5767 } else {
5768 // Otherwise, complain about the addition of a qualifier to an
5769 // already-qualified type.
5770 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5771 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5772 Quals.removeObjCLifetime();
5773 }
5774 }
5775 }
5776
5777 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5778}
5779
5780template <typename Derived>
5781QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5782 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5783 NamedDecl *FirstQualifierInScope) {
5784 assert(!getDerived().AlreadyTransformed(TL.getType()));
5785
5786 switch (TL.getTypeLocClass()) {
5787 case TypeLoc::TemplateSpecialization:
5788 return getDerived().TransformTemplateSpecializationType(
5789 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5790 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5791 case TypeLoc::DependentName:
5792 return getDerived().TransformDependentNameType(
5793 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5794 ObjectType, FirstQualifierInScope);
5795 default:
5796 // Any dependent canonical type can appear here, through type alias
5797 // templates.
5798 return getDerived().TransformType(TLB, TL);
5799 }
5800}
5801
5802template <class TyLoc> static inline
5803QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5804 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5805 NewT.setNameLoc(T.getNameLoc());
5806 return T.getType();
5807}
5808
5809template<typename Derived>
5810QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5811 BuiltinTypeLoc T) {
5812 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5813 NewT.setBuiltinLoc(T.getBuiltinLoc());
5814 if (T.needsExtraLocalData())
5815 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5816 return T.getType();
5817}
5818
5819template<typename Derived>
5820QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5821 ComplexTypeLoc T) {
5822 // FIXME: recurse?
5823 return TransformTypeSpecType(TLB, T);
5824}
5825
5826template <typename Derived>
5827QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5828 AdjustedTypeLoc TL) {
5829 // Adjustments applied during transformation are handled elsewhere.
5830 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5831}
5832
5833template<typename Derived>
5834QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5835 DecayedTypeLoc TL) {
5836 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5837 if (OriginalType.isNull())
5838 return QualType();
5839
5840 QualType Result = TL.getType();
5841 if (getDerived().AlwaysRebuild() ||
5842 OriginalType != TL.getOriginalLoc().getType())
5843 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5844 TLB.push<DecayedTypeLoc>(T: Result);
5845 // Nothing to set for DecayedTypeLoc.
5846 return Result;
5847}
5848
5849template <typename Derived>
5850QualType
5851TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5852 ArrayParameterTypeLoc TL) {
5853 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5854 if (OriginalType.isNull())
5855 return QualType();
5856
5857 QualType Result = TL.getType();
5858 if (getDerived().AlwaysRebuild() ||
5859 OriginalType != TL.getElementLoc().getType())
5860 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5861 TLB.push<ArrayParameterTypeLoc>(T: Result);
5862 // Nothing to set for ArrayParameterTypeLoc.
5863 return Result;
5864}
5865
5866template<typename Derived>
5867QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5868 PointerTypeLoc TL) {
5869 QualType PointeeType
5870 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5871 if (PointeeType.isNull())
5872 return QualType();
5873
5874 QualType Result = TL.getType();
5875 if (PointeeType->getAs<ObjCObjectType>()) {
5876 // A dependent pointer type 'T *' has is being transformed such
5877 // that an Objective-C class type is being replaced for 'T'. The
5878 // resulting pointer type is an ObjCObjectPointerType, not a
5879 // PointerType.
5880 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5881
5882 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5883 NewT.setStarLoc(TL.getStarLoc());
5884 return Result;
5885 }
5886
5887 if (getDerived().AlwaysRebuild() ||
5888 PointeeType != TL.getPointeeLoc().getType()) {
5889 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5890 if (Result.isNull())
5891 return QualType();
5892 }
5893
5894 // Objective-C ARC can add lifetime qualifiers to the type that we're
5895 // pointing to.
5896 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5897
5898 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5899 NewT.setSigilLoc(TL.getSigilLoc());
5900 return Result;
5901}
5902
5903template<typename Derived>
5904QualType
5905TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5906 BlockPointerTypeLoc TL) {
5907 QualType PointeeType
5908 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5909 if (PointeeType.isNull())
5910 return QualType();
5911
5912 QualType Result = TL.getType();
5913 if (getDerived().AlwaysRebuild() ||
5914 PointeeType != TL.getPointeeLoc().getType()) {
5915 Result = getDerived().RebuildBlockPointerType(PointeeType,
5916 TL.getSigilLoc());
5917 if (Result.isNull())
5918 return QualType();
5919 }
5920
5921 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5922 NewT.setSigilLoc(TL.getSigilLoc());
5923 return Result;
5924}
5925
5926/// Transforms a reference type. Note that somewhat paradoxically we
5927/// don't care whether the type itself is an l-value type or an r-value
5928/// type; we only care if the type was *written* as an l-value type
5929/// or an r-value type.
5930template<typename Derived>
5931QualType
5932TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5933 ReferenceTypeLoc TL) {
5934 const ReferenceType *T = TL.getTypePtr();
5935
5936 // Note that this works with the pointee-as-written.
5937 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5938 if (PointeeType.isNull())
5939 return QualType();
5940
5941 QualType Result = TL.getType();
5942 if (getDerived().AlwaysRebuild() ||
5943 PointeeType != T->getPointeeTypeAsWritten()) {
5944 Result = getDerived().RebuildReferenceType(PointeeType,
5945 T->isSpelledAsLValue(),
5946 TL.getSigilLoc());
5947 if (Result.isNull())
5948 return QualType();
5949 }
5950
5951 // Objective-C ARC can add lifetime qualifiers to the type that we're
5952 // referring to.
5953 TLB.TypeWasModifiedSafely(
5954 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5955
5956 // r-value references can be rebuilt as l-value references.
5957 ReferenceTypeLoc NewTL;
5958 if (isa<LValueReferenceType>(Val: Result))
5959 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5960 else
5961 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5962 NewTL.setSigilLoc(TL.getSigilLoc());
5963
5964 return Result;
5965}
5966
5967template<typename Derived>
5968QualType
5969TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5970 LValueReferenceTypeLoc TL) {
5971 return TransformReferenceType(TLB, TL);
5972}
5973
5974template<typename Derived>
5975QualType
5976TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5977 RValueReferenceTypeLoc TL) {
5978 return TransformReferenceType(TLB, TL);
5979}
5980
5981template<typename Derived>
5982QualType
5983TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5984 MemberPointerTypeLoc TL) {
5985 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5986 if (PointeeType.isNull())
5987 return QualType();
5988
5989 const MemberPointerType *T = TL.getTypePtr();
5990
5991 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5992 NestedNameSpecifierLoc NewQualifierLoc =
5993 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5994 if (!NewQualifierLoc)
5995 return QualType();
5996
5997 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5998 if (OldCls) {
5999 NewCls = cast_or_null<CXXRecordDecl>(
6000 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
6001 if (!NewCls)
6002 return QualType();
6003 }
6004
6005 QualType Result = TL.getType();
6006 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
6007 NewQualifierLoc.getNestedNameSpecifier() !=
6008 OldQualifierLoc.getNestedNameSpecifier() ||
6009 NewCls != OldCls) {
6010 CXXScopeSpec SS;
6011 SS.Adopt(Other: NewQualifierLoc);
6012 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
6013 TL.getStarLoc());
6014 if (Result.isNull())
6015 return QualType();
6016 }
6017
6018 // If we had to adjust the pointee type when building a member pointer, make
6019 // sure to push TypeLoc info for it.
6020 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
6021 if (MPT && PointeeType != MPT->getPointeeType()) {
6022 assert(isa<AdjustedType>(MPT->getPointeeType()));
6023 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
6024 }
6025
6026 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
6027 NewTL.setSigilLoc(TL.getSigilLoc());
6028 NewTL.setQualifierLoc(NewQualifierLoc);
6029
6030 return Result;
6031}
6032
6033template<typename Derived>
6034QualType
6035TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
6036 ConstantArrayTypeLoc TL) {
6037 const ConstantArrayType *T = TL.getTypePtr();
6038 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6039 if (ElementType.isNull())
6040 return QualType();
6041
6042 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6043 Expr *OldSize = TL.getSizeExpr();
6044 if (!OldSize)
6045 OldSize = const_cast<Expr*>(T->getSizeExpr());
6046 Expr *NewSize = nullptr;
6047 if (OldSize) {
6048 EnterExpressionEvaluationContext Unevaluated(
6049 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6050 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
6051 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
6052 }
6053
6054 QualType Result = TL.getType();
6055 if (getDerived().AlwaysRebuild() ||
6056 ElementType != T->getElementType() ||
6057 (T->getSizeExpr() && NewSize != OldSize)) {
6058 Result = getDerived().RebuildConstantArrayType(ElementType,
6059 T->getSizeModifier(),
6060 T->getSize(), NewSize,
6061 T->getIndexTypeCVRQualifiers(),
6062 TL.getBracketsRange());
6063 if (Result.isNull())
6064 return QualType();
6065 }
6066
6067 // We might have either a ConstantArrayType or a VariableArrayType now:
6068 // a ConstantArrayType is allowed to have an element type which is a
6069 // VariableArrayType if the type is dependent. Fortunately, all array
6070 // types have the same location layout.
6071 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6072 NewTL.setLBracketLoc(TL.getLBracketLoc());
6073 NewTL.setRBracketLoc(TL.getRBracketLoc());
6074 NewTL.setSizeExpr(NewSize);
6075
6076 return Result;
6077}
6078
6079template<typename Derived>
6080QualType TreeTransform<Derived>::TransformIncompleteArrayType(
6081 TypeLocBuilder &TLB,
6082 IncompleteArrayTypeLoc TL) {
6083 const IncompleteArrayType *T = TL.getTypePtr();
6084 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6085 if (ElementType.isNull())
6086 return QualType();
6087
6088 QualType Result = TL.getType();
6089 if (getDerived().AlwaysRebuild() ||
6090 ElementType != T->getElementType()) {
6091 Result = getDerived().RebuildIncompleteArrayType(ElementType,
6092 T->getSizeModifier(),
6093 T->getIndexTypeCVRQualifiers(),
6094 TL.getBracketsRange());
6095 if (Result.isNull())
6096 return QualType();
6097 }
6098
6099 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
6100 NewTL.setLBracketLoc(TL.getLBracketLoc());
6101 NewTL.setRBracketLoc(TL.getRBracketLoc());
6102 NewTL.setSizeExpr(nullptr);
6103
6104 return Result;
6105}
6106
6107template<typename Derived>
6108QualType
6109TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
6110 VariableArrayTypeLoc TL) {
6111 const VariableArrayType *T = TL.getTypePtr();
6112 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6113 if (ElementType.isNull())
6114 return QualType();
6115
6116 ExprResult SizeResult;
6117 {
6118 EnterExpressionEvaluationContext Context(
6119 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
6120 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
6121 }
6122 if (SizeResult.isInvalid())
6123 return QualType();
6124 SizeResult =
6125 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
6126 if (SizeResult.isInvalid())
6127 return QualType();
6128
6129 Expr *Size = SizeResult.get();
6130
6131 QualType Result = TL.getType();
6132 if (getDerived().AlwaysRebuild() ||
6133 ElementType != T->getElementType() ||
6134 Size != T->getSizeExpr()) {
6135 Result = getDerived().RebuildVariableArrayType(ElementType,
6136 T->getSizeModifier(),
6137 Size,
6138 T->getIndexTypeCVRQualifiers(),
6139 TL.getBracketsRange());
6140 if (Result.isNull())
6141 return QualType();
6142 }
6143
6144 // We might have constant size array now, but fortunately it has the same
6145 // location layout.
6146 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6147 NewTL.setLBracketLoc(TL.getLBracketLoc());
6148 NewTL.setRBracketLoc(TL.getRBracketLoc());
6149 NewTL.setSizeExpr(Size);
6150
6151 return Result;
6152}
6153
6154template<typename Derived>
6155QualType
6156TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6157 DependentSizedArrayTypeLoc TL) {
6158 const DependentSizedArrayType *T = TL.getTypePtr();
6159 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6160 if (ElementType.isNull())
6161 return QualType();
6162
6163 // Array bounds are constant expressions.
6164 EnterExpressionEvaluationContext Unevaluated(
6165 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6166
6167 // If we have a VLA then it won't be a constant.
6168 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6169
6170 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6171 Expr *origSize = TL.getSizeExpr();
6172 if (!origSize) origSize = T->getSizeExpr();
6173
6174 ExprResult sizeResult
6175 = getDerived().TransformExpr(origSize);
6176 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6177 if (sizeResult.isInvalid())
6178 return QualType();
6179
6180 Expr *size = sizeResult.get();
6181
6182 QualType Result = TL.getType();
6183 if (getDerived().AlwaysRebuild() ||
6184 ElementType != T->getElementType() ||
6185 size != origSize) {
6186 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6187 T->getSizeModifier(),
6188 size,
6189 T->getIndexTypeCVRQualifiers(),
6190 TL.getBracketsRange());
6191 if (Result.isNull())
6192 return QualType();
6193 }
6194
6195 // We might have any sort of array type now, but fortunately they
6196 // all have the same location layout.
6197 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6198 NewTL.setLBracketLoc(TL.getLBracketLoc());
6199 NewTL.setRBracketLoc(TL.getRBracketLoc());
6200 NewTL.setSizeExpr(size);
6201
6202 return Result;
6203}
6204
6205template <typename Derived>
6206QualType TreeTransform<Derived>::TransformDependentVectorType(
6207 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6208 const DependentVectorType *T = TL.getTypePtr();
6209 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6210 if (ElementType.isNull())
6211 return QualType();
6212
6213 EnterExpressionEvaluationContext Unevaluated(
6214 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6215
6216 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6217 Size = SemaRef.ActOnConstantExpression(Res: Size);
6218 if (Size.isInvalid())
6219 return QualType();
6220
6221 QualType Result = TL.getType();
6222 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6223 Size.get() != T->getSizeExpr()) {
6224 Result = getDerived().RebuildDependentVectorType(
6225 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6226 if (Result.isNull())
6227 return QualType();
6228 }
6229
6230 // Result might be dependent or not.
6231 if (isa<DependentVectorType>(Val: Result)) {
6232 DependentVectorTypeLoc NewTL =
6233 TLB.push<DependentVectorTypeLoc>(T: Result);
6234 NewTL.setNameLoc(TL.getNameLoc());
6235 } else {
6236 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6237 NewTL.setNameLoc(TL.getNameLoc());
6238 }
6239
6240 return Result;
6241}
6242
6243template<typename Derived>
6244QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6245 TypeLocBuilder &TLB,
6246 DependentSizedExtVectorTypeLoc TL) {
6247 const DependentSizedExtVectorType *T = TL.getTypePtr();
6248
6249 // FIXME: ext vector locs should be nested
6250 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6251 if (ElementType.isNull())
6252 return QualType();
6253
6254 // Vector sizes are constant expressions.
6255 EnterExpressionEvaluationContext Unevaluated(
6256 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6257
6258 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6259 Size = SemaRef.ActOnConstantExpression(Res: Size);
6260 if (Size.isInvalid())
6261 return QualType();
6262
6263 QualType Result = TL.getType();
6264 if (getDerived().AlwaysRebuild() ||
6265 ElementType != T->getElementType() ||
6266 Size.get() != T->getSizeExpr()) {
6267 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6268 Size.get(),
6269 T->getAttributeLoc());
6270 if (Result.isNull())
6271 return QualType();
6272 }
6273
6274 // Result might be dependent or not.
6275 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6276 DependentSizedExtVectorTypeLoc NewTL
6277 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6278 NewTL.setNameLoc(TL.getNameLoc());
6279 } else {
6280 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6281 NewTL.setNameLoc(TL.getNameLoc());
6282 }
6283
6284 return Result;
6285}
6286
6287template <typename Derived>
6288QualType
6289TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6290 ConstantMatrixTypeLoc TL) {
6291 const ConstantMatrixType *T = TL.getTypePtr();
6292 QualType ElementType = getDerived().TransformType(T->getElementType());
6293 if (ElementType.isNull())
6294 return QualType();
6295
6296 QualType Result = TL.getType();
6297 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6298 Result = getDerived().RebuildConstantMatrixType(
6299 ElementType, T->getNumRows(), T->getNumColumns(), TL.getAttrNameLoc());
6300 if (Result.isNull())
6301 return QualType();
6302 }
6303
6304 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6305 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6306 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6307 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6308 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6309
6310 return Result;
6311}
6312
6313template <typename Derived>
6314QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6315 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6316 const DependentSizedMatrixType *T = TL.getTypePtr();
6317
6318 QualType ElementType = getDerived().TransformType(T->getElementType());
6319 if (ElementType.isNull()) {
6320 return QualType();
6321 }
6322
6323 // Matrix dimensions are constant expressions.
6324 EnterExpressionEvaluationContext Unevaluated(
6325 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6326
6327 Expr *origRows = TL.getAttrRowOperand();
6328 if (!origRows)
6329 origRows = T->getRowExpr();
6330 Expr *origColumns = TL.getAttrColumnOperand();
6331 if (!origColumns)
6332 origColumns = T->getColumnExpr();
6333
6334 ExprResult rowResult = getDerived().TransformExpr(origRows);
6335 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6336 if (rowResult.isInvalid())
6337 return QualType();
6338
6339 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6340 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6341 if (columnResult.isInvalid())
6342 return QualType();
6343
6344 Expr *rows = rowResult.get();
6345 Expr *columns = columnResult.get();
6346
6347 QualType Result = TL.getType();
6348 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6349 rows != origRows || columns != origColumns) {
6350 Result = getDerived().RebuildDependentSizedMatrixType(
6351 ElementType, rows, columns, T->getAttributeLoc());
6352
6353 if (Result.isNull())
6354 return QualType();
6355 }
6356
6357 // We might have any sort of matrix type now, but fortunately they
6358 // all have the same location layout.
6359 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6360 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6361 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6362 NewTL.setAttrRowOperand(rows);
6363 NewTL.setAttrColumnOperand(columns);
6364 return Result;
6365}
6366
6367template <typename Derived>
6368QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6369 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6370 const DependentAddressSpaceType *T = TL.getTypePtr();
6371
6372 QualType pointeeType =
6373 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6374
6375 if (pointeeType.isNull())
6376 return QualType();
6377
6378 // Address spaces are constant expressions.
6379 EnterExpressionEvaluationContext Unevaluated(
6380 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6381
6382 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6383 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6384 if (AddrSpace.isInvalid())
6385 return QualType();
6386
6387 QualType Result = TL.getType();
6388 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6389 AddrSpace.get() != T->getAddrSpaceExpr()) {
6390 Result = getDerived().RebuildDependentAddressSpaceType(
6391 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6392 if (Result.isNull())
6393 return QualType();
6394 }
6395
6396 // Result might be dependent or not.
6397 if (isa<DependentAddressSpaceType>(Val: Result)) {
6398 DependentAddressSpaceTypeLoc NewTL =
6399 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6400
6401 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6402 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6403 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6404
6405 } else {
6406 TLB.TypeWasModifiedSafely(T: Result);
6407 }
6408
6409 return Result;
6410}
6411
6412template <typename Derived>
6413QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6414 VectorTypeLoc TL) {
6415 const VectorType *T = TL.getTypePtr();
6416 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6417 if (ElementType.isNull())
6418 return QualType();
6419
6420 QualType Result = TL.getType();
6421 if (getDerived().AlwaysRebuild() ||
6422 ElementType != T->getElementType()) {
6423 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6424 T->getVectorKind());
6425 if (Result.isNull())
6426 return QualType();
6427 }
6428
6429 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6430 NewTL.setNameLoc(TL.getNameLoc());
6431
6432 return Result;
6433}
6434
6435template<typename Derived>
6436QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6437 ExtVectorTypeLoc TL) {
6438 const VectorType *T = TL.getTypePtr();
6439 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6440 if (ElementType.isNull())
6441 return QualType();
6442
6443 QualType Result = TL.getType();
6444 if (getDerived().AlwaysRebuild() ||
6445 ElementType != T->getElementType()) {
6446 Result = getDerived().RebuildExtVectorType(ElementType,
6447 T->getNumElements(),
6448 /*FIXME*/ SourceLocation());
6449 if (Result.isNull())
6450 return QualType();
6451 }
6452
6453 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6454 NewTL.setNameLoc(TL.getNameLoc());
6455
6456 return Result;
6457}
6458
6459template <typename Derived>
6460ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6461 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6462 bool ExpectParameterPack) {
6463 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6464 TypeSourceInfo *NewTSI = nullptr;
6465
6466 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6467 // If we're substituting into a pack expansion type and we know the
6468 // length we want to expand to, just substitute for the pattern.
6469 TypeLoc OldTL = OldTSI->getTypeLoc();
6470 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6471
6472 TypeLocBuilder TLB;
6473 TypeLoc NewTL = OldTSI->getTypeLoc();
6474 TLB.reserve(Requested: NewTL.getFullDataSize());
6475
6476 QualType Result = getDerived().TransformType(TLB,
6477 OldExpansionTL.getPatternLoc());
6478 if (Result.isNull())
6479 return nullptr;
6480
6481 Result = RebuildPackExpansionType(Pattern: Result,
6482 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6483 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6484 NumExpansions);
6485 if (Result.isNull())
6486 return nullptr;
6487
6488 PackExpansionTypeLoc NewExpansionTL
6489 = TLB.push<PackExpansionTypeLoc>(T: Result);
6490 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6491 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6492 } else
6493 NewTSI = getDerived().TransformType(OldTSI);
6494 if (!NewTSI)
6495 return nullptr;
6496
6497 if (NewTSI == OldTSI && indexAdjustment == 0)
6498 return OldParm;
6499
6500 ParmVarDecl *newParm = ParmVarDecl::Create(
6501 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6502 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6503 TInfo: NewTSI, S: OldParm->getStorageClass(),
6504 /* DefArg */ DefArg: nullptr);
6505 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6506 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6507 getDerived().transformedLocalDecl(OldParm, {newParm});
6508 return newParm;
6509}
6510
6511template <typename Derived>
6512bool TreeTransform<Derived>::TransformFunctionTypeParams(
6513 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6514 const QualType *ParamTypes,
6515 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6516 SmallVectorImpl<QualType> &OutParamTypes,
6517 SmallVectorImpl<ParmVarDecl *> *PVars,
6518 Sema::ExtParameterInfoBuilder &PInfos,
6519 unsigned *LastParamTransformed) {
6520 int indexAdjustment = 0;
6521
6522 unsigned NumParams = Params.size();
6523 for (unsigned i = 0; i != NumParams; ++i) {
6524 if (LastParamTransformed)
6525 *LastParamTransformed = i;
6526 if (ParmVarDecl *OldParm = Params[i]) {
6527 assert(OldParm->getFunctionScopeIndex() == i);
6528
6529 UnsignedOrNone NumExpansions = std::nullopt;
6530 ParmVarDecl *NewParm = nullptr;
6531 if (OldParm->isParameterPack()) {
6532 // We have a function parameter pack that may need to be expanded.
6533 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6534
6535 // Find the parameter packs that could be expanded.
6536 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6537 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6538 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6539 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6540
6541 // Determine whether we should expand the parameter packs.
6542 bool ShouldExpand = false;
6543 bool RetainExpansion = false;
6544 UnsignedOrNone OrigNumExpansions = std::nullopt;
6545 if (Unexpanded.size() > 0) {
6546 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6547 NumExpansions = OrigNumExpansions;
6548 if (getDerived().TryExpandParameterPacks(
6549 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6550 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6551 ShouldExpand, RetainExpansion, NumExpansions)) {
6552 return true;
6553 }
6554 } else {
6555#ifndef NDEBUG
6556 const AutoType *AT =
6557 Pattern.getType().getTypePtr()->getContainedAutoType();
6558 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6559 "Could not find parameter packs or undeduced auto type!");
6560#endif
6561 }
6562
6563 if (ShouldExpand) {
6564 // Expand the function parameter pack into multiple, separate
6565 // parameters.
6566 getDerived().ExpandingFunctionParameterPack(OldParm);
6567 for (unsigned I = 0; I != *NumExpansions; ++I) {
6568 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6569 ParmVarDecl *NewParm
6570 = getDerived().TransformFunctionTypeParam(OldParm,
6571 indexAdjustment++,
6572 OrigNumExpansions,
6573 /*ExpectParameterPack=*/false);
6574 if (!NewParm)
6575 return true;
6576
6577 if (ParamInfos)
6578 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6579 OutParamTypes.push_back(Elt: NewParm->getType());
6580 if (PVars)
6581 PVars->push_back(Elt: NewParm);
6582 }
6583
6584 // If we're supposed to retain a pack expansion, do so by temporarily
6585 // forgetting the partially-substituted parameter pack.
6586 if (RetainExpansion) {
6587 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6588 ParmVarDecl *NewParm
6589 = getDerived().TransformFunctionTypeParam(OldParm,
6590 indexAdjustment++,
6591 OrigNumExpansions,
6592 /*ExpectParameterPack=*/false);
6593 if (!NewParm)
6594 return true;
6595
6596 if (ParamInfos)
6597 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6598 OutParamTypes.push_back(Elt: NewParm->getType());
6599 if (PVars)
6600 PVars->push_back(Elt: NewParm);
6601 }
6602
6603 // The next parameter should have the same adjustment as the
6604 // last thing we pushed, but we post-incremented indexAdjustment
6605 // on every push. Also, if we push nothing, the adjustment should
6606 // go down by one.
6607 indexAdjustment--;
6608
6609 // We're done with the pack expansion.
6610 continue;
6611 }
6612
6613 // We'll substitute the parameter now without expanding the pack
6614 // expansion.
6615 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6616 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6617 indexAdjustment,
6618 NumExpansions,
6619 /*ExpectParameterPack=*/true);
6620 assert(NewParm->isParameterPack() &&
6621 "Parameter pack no longer a parameter pack after "
6622 "transformation.");
6623 } else {
6624 NewParm = getDerived().TransformFunctionTypeParam(
6625 OldParm, indexAdjustment, std::nullopt,
6626 /*ExpectParameterPack=*/false);
6627 }
6628
6629 if (!NewParm)
6630 return true;
6631
6632 if (ParamInfos)
6633 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6634 OutParamTypes.push_back(Elt: NewParm->getType());
6635 if (PVars)
6636 PVars->push_back(Elt: NewParm);
6637 continue;
6638 }
6639
6640 // Deal with the possibility that we don't have a parameter
6641 // declaration for this parameter.
6642 assert(ParamTypes);
6643 QualType OldType = ParamTypes[i];
6644 bool IsPackExpansion = false;
6645 UnsignedOrNone NumExpansions = std::nullopt;
6646 QualType NewType;
6647 if (const PackExpansionType *Expansion
6648 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6649 // We have a function parameter pack that may need to be expanded.
6650 QualType Pattern = Expansion->getPattern();
6651 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6652 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6653
6654 // Determine whether we should expand the parameter packs.
6655 bool ShouldExpand = false;
6656 bool RetainExpansion = false;
6657 if (getDerived().TryExpandParameterPacks(
6658 Loc, SourceRange(), Unexpanded,
6659 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6660 RetainExpansion, NumExpansions)) {
6661 return true;
6662 }
6663
6664 if (ShouldExpand) {
6665 // Expand the function parameter pack into multiple, separate
6666 // parameters.
6667 for (unsigned I = 0; I != *NumExpansions; ++I) {
6668 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6669 QualType NewType = getDerived().TransformType(Pattern);
6670 if (NewType.isNull())
6671 return true;
6672
6673 if (NewType->containsUnexpandedParameterPack()) {
6674 NewType = getSema().getASTContext().getPackExpansionType(
6675 NewType, std::nullopt);
6676
6677 if (NewType.isNull())
6678 return true;
6679 }
6680
6681 if (ParamInfos)
6682 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6683 OutParamTypes.push_back(Elt: NewType);
6684 if (PVars)
6685 PVars->push_back(Elt: nullptr);
6686 }
6687
6688 // We're done with the pack expansion.
6689 continue;
6690 }
6691
6692 // If we're supposed to retain a pack expansion, do so by temporarily
6693 // forgetting the partially-substituted parameter pack.
6694 if (RetainExpansion) {
6695 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6696 QualType NewType = getDerived().TransformType(Pattern);
6697 if (NewType.isNull())
6698 return true;
6699
6700 if (ParamInfos)
6701 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6702 OutParamTypes.push_back(Elt: NewType);
6703 if (PVars)
6704 PVars->push_back(Elt: nullptr);
6705 }
6706
6707 // We'll substitute the parameter now without expanding the pack
6708 // expansion.
6709 OldType = Expansion->getPattern();
6710 IsPackExpansion = true;
6711 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6712 NewType = getDerived().TransformType(OldType);
6713 } else {
6714 NewType = getDerived().TransformType(OldType);
6715 }
6716
6717 if (NewType.isNull())
6718 return true;
6719
6720 if (IsPackExpansion)
6721 NewType = getSema().Context.getPackExpansionType(NewType,
6722 NumExpansions);
6723
6724 if (ParamInfos)
6725 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6726 OutParamTypes.push_back(Elt: NewType);
6727 if (PVars)
6728 PVars->push_back(Elt: nullptr);
6729 }
6730
6731#ifndef NDEBUG
6732 if (PVars) {
6733 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6734 if (ParmVarDecl *parm = (*PVars)[i])
6735 assert(parm->getFunctionScopeIndex() == i);
6736 }
6737#endif
6738
6739 return false;
6740}
6741
6742template<typename Derived>
6743QualType
6744TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6745 FunctionProtoTypeLoc TL) {
6746 SmallVector<QualType, 4> ExceptionStorage;
6747 return getDerived().TransformFunctionProtoType(
6748 TLB, TL, nullptr, Qualifiers(),
6749 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6750 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6751 ExceptionStorage, Changed);
6752 });
6753}
6754
6755template<typename Derived> template<typename Fn>
6756QualType TreeTransform<Derived>::TransformFunctionProtoType(
6757 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6758 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6759
6760 // Transform the parameters and return type.
6761 //
6762 // We are required to instantiate the params and return type in source order.
6763 // When the function has a trailing return type, we instantiate the
6764 // parameters before the return type, since the return type can then refer
6765 // to the parameters themselves (via decltype, sizeof, etc.).
6766 //
6767 SmallVector<QualType, 4> ParamTypes;
6768 SmallVector<ParmVarDecl*, 4> ParamDecls;
6769 Sema::ExtParameterInfoBuilder ExtParamInfos;
6770 const FunctionProtoType *T = TL.getTypePtr();
6771
6772 QualType ResultType;
6773
6774 if (T->hasTrailingReturn()) {
6775 if (getDerived().TransformFunctionTypeParams(
6776 TL.getBeginLoc(), TL.getParams(),
6777 TL.getTypePtr()->param_type_begin(),
6778 T->getExtParameterInfosOrNull(),
6779 ParamTypes, &ParamDecls, ExtParamInfos))
6780 return QualType();
6781
6782 {
6783 // C++11 [expr.prim.general]p3:
6784 // If a declaration declares a member function or member function
6785 // template of a class X, the expression this is a prvalue of type
6786 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6787 // and the end of the function-definition, member-declarator, or
6788 // declarator.
6789 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6790 Sema::CXXThisScopeRAII ThisScope(
6791 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6792
6793 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6794 if (ResultType.isNull())
6795 return QualType();
6796 }
6797 }
6798 else {
6799 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6800 if (ResultType.isNull())
6801 return QualType();
6802
6803 if (getDerived().TransformFunctionTypeParams(
6804 TL.getBeginLoc(), TL.getParams(),
6805 TL.getTypePtr()->param_type_begin(),
6806 T->getExtParameterInfosOrNull(),
6807 ParamTypes, &ParamDecls, ExtParamInfos))
6808 return QualType();
6809 }
6810
6811 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6812
6813 bool EPIChanged = false;
6814 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6815 return QualType();
6816
6817 // Handle extended parameter information.
6818 if (auto NewExtParamInfos =
6819 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6820 if (!EPI.ExtParameterInfos ||
6821 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6822 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6823 EPIChanged = true;
6824 }
6825 EPI.ExtParameterInfos = NewExtParamInfos;
6826 } else if (EPI.ExtParameterInfos) {
6827 EPIChanged = true;
6828 EPI.ExtParameterInfos = nullptr;
6829 }
6830
6831 // Transform any function effects with unevaluated conditions.
6832 // Hold this set in a local for the rest of this function, since EPI
6833 // may need to hold a FunctionEffectsRef pointing into it.
6834 std::optional<FunctionEffectSet> NewFX;
6835 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6836 NewFX.emplace();
6837 EnterExpressionEvaluationContext Unevaluated(
6838 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6839
6840 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6841 FunctionEffectWithCondition NewEC = PrevEC;
6842 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6843 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6844 if (NewExpr.isInvalid())
6845 return QualType();
6846 std::optional<FunctionEffectMode> Mode =
6847 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6848 if (!Mode)
6849 return QualType();
6850
6851 // The condition expression has been transformed, and re-evaluated.
6852 // It may or may not have become constant.
6853 switch (*Mode) {
6854 case FunctionEffectMode::True:
6855 NewEC.Cond = {};
6856 break;
6857 case FunctionEffectMode::False:
6858 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6859 NewEC.Cond = {};
6860 break;
6861 case FunctionEffectMode::Dependent:
6862 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6863 break;
6864 case FunctionEffectMode::None:
6865 llvm_unreachable(
6866 "FunctionEffectMode::None shouldn't be possible here");
6867 }
6868 }
6869 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6870 NewAttrLoc: TL.getBeginLoc())) {
6871 FunctionEffectSet::Conflicts Errs;
6872 NewFX->insert(NewEC, Errs);
6873 assert(Errs.empty());
6874 }
6875 }
6876 EPI.FunctionEffects = *NewFX;
6877 EPIChanged = true;
6878 }
6879
6880 QualType Result = TL.getType();
6881 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6882 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6883 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6884 if (Result.isNull())
6885 return QualType();
6886 }
6887
6888 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6889 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6890 NewTL.setLParenLoc(TL.getLParenLoc());
6891 NewTL.setRParenLoc(TL.getRParenLoc());
6892 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6893 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6894 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6895 NewTL.setParam(i, VD: ParamDecls[i]);
6896
6897 return Result;
6898}
6899
6900template<typename Derived>
6901bool TreeTransform<Derived>::TransformExceptionSpec(
6902 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6903 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6904 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6905
6906 // Instantiate a dynamic noexcept expression, if any.
6907 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6908 // Update this scrope because ContextDecl in Sema will be used in
6909 // TransformExpr.
6910 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6911 Sema::CXXThisScopeRAII ThisScope(
6912 SemaRef, Method ? Method->getParent() : nullptr,
6913 Method ? Method->getMethodQualifiers() : Qualifiers{},
6914 Method != nullptr);
6915 EnterExpressionEvaluationContext Unevaluated(
6916 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6917 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6918 if (NoexceptExpr.isInvalid())
6919 return true;
6920
6921 ExceptionSpecificationType EST = ESI.Type;
6922 NoexceptExpr =
6923 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6924 if (NoexceptExpr.isInvalid())
6925 return true;
6926
6927 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6928 Changed = true;
6929 ESI.NoexceptExpr = NoexceptExpr.get();
6930 ESI.Type = EST;
6931 }
6932
6933 if (ESI.Type != EST_Dynamic)
6934 return false;
6935
6936 // Instantiate a dynamic exception specification's type.
6937 for (QualType T : ESI.Exceptions) {
6938 if (const PackExpansionType *PackExpansion =
6939 T->getAs<PackExpansionType>()) {
6940 Changed = true;
6941
6942 // We have a pack expansion. Instantiate it.
6943 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6944 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6945 Unexpanded);
6946 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6947
6948 // Determine whether the set of unexpanded parameter packs can and
6949 // should
6950 // be expanded.
6951 bool Expand = false;
6952 bool RetainExpansion = false;
6953 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6954 // FIXME: Track the location of the ellipsis (and track source location
6955 // information for the types in the exception specification in general).
6956 if (getDerived().TryExpandParameterPacks(
6957 Loc, SourceRange(), Unexpanded,
6958 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6959 NumExpansions))
6960 return true;
6961
6962 if (!Expand) {
6963 // We can't expand this pack expansion into separate arguments yet;
6964 // just substitute into the pattern and create a new pack expansion
6965 // type.
6966 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6967 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6968 if (U.isNull())
6969 return true;
6970
6971 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6972 Exceptions.push_back(Elt: U);
6973 continue;
6974 }
6975
6976 // Substitute into the pack expansion pattern for each slice of the
6977 // pack.
6978 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6979 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6980
6981 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6982 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6983 return true;
6984
6985 Exceptions.push_back(Elt: U);
6986 }
6987 } else {
6988 QualType U = getDerived().TransformType(T);
6989 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6990 return true;
6991 if (T != U)
6992 Changed = true;
6993
6994 Exceptions.push_back(Elt: U);
6995 }
6996 }
6997
6998 ESI.Exceptions = Exceptions;
6999 if (ESI.Exceptions.empty())
7000 ESI.Type = EST_DynamicNone;
7001 return false;
7002}
7003
7004template<typename Derived>
7005QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
7006 TypeLocBuilder &TLB,
7007 FunctionNoProtoTypeLoc TL) {
7008 const FunctionNoProtoType *T = TL.getTypePtr();
7009 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
7010 if (ResultType.isNull())
7011 return QualType();
7012
7013 QualType Result = TL.getType();
7014 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
7015 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
7016
7017 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
7018 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
7019 NewTL.setLParenLoc(TL.getLParenLoc());
7020 NewTL.setRParenLoc(TL.getRParenLoc());
7021 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
7022
7023 return Result;
7024}
7025
7026template <typename Derived>
7027QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
7028 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
7029
7030 const UnresolvedUsingType *T = TL.getTypePtr();
7031 bool Changed = false;
7032
7033 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7034 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7035 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7036 if (!QualifierLoc)
7037 return QualType();
7038 Changed |= QualifierLoc != OldQualifierLoc;
7039 }
7040
7041 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
7042 if (!D)
7043 return QualType();
7044 Changed |= D != T->getDecl();
7045
7046 QualType Result = TL.getType();
7047 if (getDerived().AlwaysRebuild() || Changed) {
7048 Result = getDerived().RebuildUnresolvedUsingType(
7049 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
7050 D);
7051 if (Result.isNull())
7052 return QualType();
7053 }
7054
7055 if (isa<UsingType>(Val: Result))
7056 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7057 QualifierLoc, NameLoc: TL.getNameLoc());
7058 else
7059 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7060 QualifierLoc, NameLoc: TL.getNameLoc());
7061 return Result;
7062}
7063
7064template <typename Derived>
7065QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
7066 UsingTypeLoc TL) {
7067 const UsingType *T = TL.getTypePtr();
7068 bool Changed = false;
7069
7070 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7071 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7072 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7073 if (!QualifierLoc)
7074 return QualType();
7075 Changed |= QualifierLoc != OldQualifierLoc;
7076 }
7077
7078 auto *D = cast_or_null<UsingShadowDecl>(
7079 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7080 if (!D)
7081 return QualType();
7082 Changed |= D != T->getDecl();
7083
7084 QualType UnderlyingType = getDerived().TransformType(T->desugar());
7085 if (UnderlyingType.isNull())
7086 return QualType();
7087 Changed |= UnderlyingType != T->desugar();
7088
7089 QualType Result = TL.getType();
7090 if (getDerived().AlwaysRebuild() || Changed) {
7091 Result = getDerived().RebuildUsingType(
7092 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
7093 UnderlyingType);
7094 if (Result.isNull())
7095 return QualType();
7096 }
7097 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
7098 NameLoc: TL.getNameLoc());
7099 return Result;
7100}
7101
7102template<typename Derived>
7103QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
7104 TypedefTypeLoc TL) {
7105 const TypedefType *T = TL.getTypePtr();
7106 bool Changed = false;
7107
7108 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7109 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7110 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7111 if (!QualifierLoc)
7112 return QualType();
7113 Changed |= QualifierLoc != OldQualifierLoc;
7114 }
7115
7116 auto *Typedef = cast_or_null<TypedefNameDecl>(
7117 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7118 if (!Typedef)
7119 return QualType();
7120 Changed |= Typedef != T->getDecl();
7121
7122 // FIXME: Transform the UnderlyingType if different from decl.
7123
7124 QualType Result = TL.getType();
7125 if (getDerived().AlwaysRebuild() || Changed) {
7126 Result = getDerived().RebuildTypedefType(
7127 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
7128 if (Result.isNull())
7129 return QualType();
7130 }
7131
7132 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7133 QualifierLoc, NameLoc: TL.getNameLoc());
7134 return Result;
7135}
7136
7137template<typename Derived>
7138QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
7139 TypeOfExprTypeLoc TL) {
7140 // typeof expressions are not potentially evaluated contexts
7141 EnterExpressionEvaluationContext Unevaluated(
7142 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7143 Sema::ReuseLambdaContextDecl);
7144
7145 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7146 if (E.isInvalid())
7147 return QualType();
7148
7149 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7150 if (E.isInvalid())
7151 return QualType();
7152
7153 QualType Result = TL.getType();
7154 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7155 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7156 Result =
7157 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7158 if (Result.isNull())
7159 return QualType();
7160 }
7161
7162 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7163 NewTL.setTypeofLoc(TL.getTypeofLoc());
7164 NewTL.setLParenLoc(TL.getLParenLoc());
7165 NewTL.setRParenLoc(TL.getRParenLoc());
7166
7167 return Result;
7168}
7169
7170template<typename Derived>
7171QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7172 TypeOfTypeLoc TL) {
7173 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7174 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7175 if (!New_Under_TI)
7176 return QualType();
7177
7178 QualType Result = TL.getType();
7179 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7180 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7181 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7182 if (Result.isNull())
7183 return QualType();
7184 }
7185
7186 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7187 NewTL.setTypeofLoc(TL.getTypeofLoc());
7188 NewTL.setLParenLoc(TL.getLParenLoc());
7189 NewTL.setRParenLoc(TL.getRParenLoc());
7190 NewTL.setUnmodifiedTInfo(New_Under_TI);
7191
7192 return Result;
7193}
7194
7195template<typename Derived>
7196QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7197 DecltypeTypeLoc TL) {
7198 const DecltypeType *T = TL.getTypePtr();
7199
7200 // decltype expressions are not potentially evaluated contexts
7201 EnterExpressionEvaluationContext Unevaluated(
7202 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7203 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7204
7205 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7206 if (E.isInvalid())
7207 return QualType();
7208
7209 E = getSema().ActOnDecltypeExpression(E.get());
7210 if (E.isInvalid())
7211 return QualType();
7212
7213 QualType Result = TL.getType();
7214 if (getDerived().AlwaysRebuild() ||
7215 E.get() != T->getUnderlyingExpr()) {
7216 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7217 if (Result.isNull())
7218 return QualType();
7219 }
7220 else E.get();
7221
7222 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7223 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7224 NewTL.setRParenLoc(TL.getRParenLoc());
7225 return Result;
7226}
7227
7228template <typename Derived>
7229QualType
7230TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7231 PackIndexingTypeLoc TL) {
7232 // Transform the index
7233 ExprResult IndexExpr;
7234 {
7235 EnterExpressionEvaluationContext ConstantContext(
7236 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7237
7238 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7239 if (IndexExpr.isInvalid())
7240 return QualType();
7241 }
7242 QualType Pattern = TL.getPattern();
7243
7244 const PackIndexingType *PIT = TL.getTypePtr();
7245 SmallVector<QualType, 5> SubtitutedTypes;
7246 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7247
7248 bool NotYetExpanded = Types.empty();
7249 bool FullySubstituted = true;
7250
7251 if (Types.empty() && !PIT->expandsToEmptyPack())
7252 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7253
7254 for (QualType T : Types) {
7255 if (!T->containsUnexpandedParameterPack()) {
7256 QualType Transformed = getDerived().TransformType(T);
7257 if (Transformed.isNull())
7258 return QualType();
7259 SubtitutedTypes.push_back(Elt: Transformed);
7260 continue;
7261 }
7262
7263 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7264 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7265 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7266 // Determine whether the set of unexpanded parameter packs can and should
7267 // be expanded.
7268 bool ShouldExpand = true;
7269 bool RetainExpansion = false;
7270 UnsignedOrNone NumExpansions = std::nullopt;
7271 if (getDerived().TryExpandParameterPacks(
7272 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7273 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7274 RetainExpansion, NumExpansions))
7275 return QualType();
7276 if (!ShouldExpand) {
7277 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7278 // FIXME: should we keep TypeLoc for individual expansions in
7279 // PackIndexingTypeLoc?
7280 TypeSourceInfo *TI =
7281 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7282 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7283 if (Pack.isNull())
7284 return QualType();
7285 if (NotYetExpanded) {
7286 FullySubstituted = false;
7287 QualType Out = getDerived().RebuildPackIndexingType(
7288 Pack, IndexExpr.get(), TL.getBeginLoc(), FullySubstituted);
7289 if (Out.isNull())
7290 return QualType();
7291
7292 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7293 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7294 return Out;
7295 }
7296 SubtitutedTypes.push_back(Elt: Pack);
7297 continue;
7298 }
7299 for (unsigned I = 0; I != *NumExpansions; ++I) {
7300 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7301 QualType Out = getDerived().TransformType(T);
7302 if (Out.isNull())
7303 return QualType();
7304 SubtitutedTypes.push_back(Elt: Out);
7305 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7306 }
7307 // If we're supposed to retain a pack expansion, do so by temporarily
7308 // forgetting the partially-substituted parameter pack.
7309 if (RetainExpansion) {
7310 FullySubstituted = false;
7311 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7312 QualType Out = getDerived().TransformType(T);
7313 if (Out.isNull())
7314 return QualType();
7315 SubtitutedTypes.push_back(Elt: Out);
7316 }
7317 }
7318
7319 // A pack indexing type can appear in a larger pack expansion,
7320 // e.g. `Pack...[pack_of_indexes]...`
7321 // so we need to temporarily disable substitution of pack elements
7322 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7323 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7324
7325 QualType Out = getDerived().RebuildPackIndexingType(
7326 Result, IndexExpr.get(), TL.getBeginLoc(), FullySubstituted,
7327 SubtitutedTypes);
7328 if (Out.isNull())
7329 return Out;
7330
7331 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7332 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7333 return Out;
7334}
7335
7336template<typename Derived>
7337QualType TreeTransform<Derived>::TransformUnaryTransformType(
7338 TypeLocBuilder &TLB,
7339 UnaryTransformTypeLoc TL) {
7340 QualType Result = TL.getType();
7341 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7342 if (Result->isDependentType()) {
7343 const UnaryTransformType *T = TL.getTypePtr();
7344
7345 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7346 if (!NewBaseTSI)
7347 return QualType();
7348 QualType NewBase = NewBaseTSI->getType();
7349
7350 Result = getDerived().RebuildUnaryTransformType(NewBase,
7351 T->getUTTKind(),
7352 TL.getKWLoc());
7353 if (Result.isNull())
7354 return QualType();
7355 }
7356
7357 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7358 NewTL.setKWLoc(TL.getKWLoc());
7359 NewTL.setParensRange(TL.getParensRange());
7360 NewTL.setUnderlyingTInfo(NewBaseTSI);
7361 return Result;
7362}
7363
7364template<typename Derived>
7365QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7366 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7367 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7368
7369 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7370 TemplateName TemplateName = getDerived().TransformTemplateName(
7371 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7372 TL.getTemplateNameLoc());
7373 if (TemplateName.isNull())
7374 return QualType();
7375
7376 QualType OldDeduced = T->getDeducedType();
7377 QualType NewDeduced;
7378 if (!OldDeduced.isNull()) {
7379 NewDeduced = getDerived().TransformType(OldDeduced);
7380 if (NewDeduced.isNull())
7381 return QualType();
7382 }
7383
7384 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7385 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7386 NewDeduced, T->getKeyword(), TemplateName);
7387 if (Result.isNull())
7388 return QualType();
7389
7390 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7391 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7392 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7393 NewTL.setQualifierLoc(QualifierLoc);
7394 return Result;
7395}
7396
7397template <typename Derived>
7398QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7399 TagTypeLoc TL) {
7400 const TagType *T = TL.getTypePtr();
7401
7402 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7403 if (QualifierLoc) {
7404 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7405 if (!QualifierLoc)
7406 return QualType();
7407 }
7408
7409 auto *TD = cast_or_null<TagDecl>(
7410 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7411 if (!TD)
7412 return QualType();
7413
7414 QualType Result = TL.getType();
7415 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7416 TD != T->getDecl()) {
7417 if (T->isCanonicalUnqualified())
7418 Result = getDerived().RebuildCanonicalTagType(TD);
7419 else
7420 Result = getDerived().RebuildTagType(
7421 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7422 if (Result.isNull())
7423 return QualType();
7424 }
7425
7426 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7427 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7428 NewTL.setQualifierLoc(QualifierLoc);
7429 NewTL.setNameLoc(TL.getNameLoc());
7430
7431 return Result;
7432}
7433
7434template <typename Derived>
7435QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7436 EnumTypeLoc TL) {
7437 return getDerived().TransformTagType(TLB, TL);
7438}
7439
7440template <typename Derived>
7441QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7442 RecordTypeLoc TL) {
7443 return getDerived().TransformTagType(TLB, TL);
7444}
7445
7446template<typename Derived>
7447QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7448 TypeLocBuilder &TLB,
7449 InjectedClassNameTypeLoc TL) {
7450 return getDerived().TransformTagType(TLB, TL);
7451}
7452
7453template<typename Derived>
7454QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7455 TypeLocBuilder &TLB,
7456 TemplateTypeParmTypeLoc TL) {
7457 return getDerived().TransformTemplateTypeParmType(
7458 TLB, TL,
7459 /*SuppressObjCLifetime=*/false);
7460}
7461
7462template <typename Derived>
7463QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7464 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7465 return TransformTypeSpecType(TLB, T: TL);
7466}
7467
7468template<typename Derived>
7469QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7470 TypeLocBuilder &TLB,
7471 SubstTemplateTypeParmTypeLoc TL) {
7472 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7473
7474 Decl *NewReplaced =
7475 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7476
7477 // Substitute into the replacement type, which itself might involve something
7478 // that needs to be transformed. This only tends to occur with default
7479 // template arguments of template template parameters.
7480 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7481 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7482 if (Replacement.isNull())
7483 return QualType();
7484
7485 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7486 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7487 Final: T->getFinal());
7488
7489 // Propagate type-source information.
7490 SubstTemplateTypeParmTypeLoc NewTL
7491 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7492 NewTL.setNameLoc(TL.getNameLoc());
7493 return Result;
7494
7495}
7496template <typename Derived>
7497QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7498 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7499 return TransformTypeSpecType(TLB, T: TL);
7500}
7501
7502template<typename Derived>
7503QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7504 TypeLocBuilder &TLB,
7505 SubstTemplateTypeParmPackTypeLoc TL) {
7506 return getDerived().TransformSubstTemplateTypeParmPackType(
7507 TLB, TL, /*SuppressObjCLifetime=*/false);
7508}
7509
7510template <typename Derived>
7511QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7512 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7513 return TransformTypeSpecType(TLB, T: TL);
7514}
7515
7516template<typename Derived>
7517QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7518 AtomicTypeLoc TL) {
7519 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7520 if (ValueType.isNull())
7521 return QualType();
7522
7523 QualType Result = TL.getType();
7524 if (getDerived().AlwaysRebuild() ||
7525 ValueType != TL.getValueLoc().getType()) {
7526 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7527 if (Result.isNull())
7528 return QualType();
7529 }
7530
7531 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7532 NewTL.setKWLoc(TL.getKWLoc());
7533 NewTL.setLParenLoc(TL.getLParenLoc());
7534 NewTL.setRParenLoc(TL.getRParenLoc());
7535
7536 return Result;
7537}
7538
7539template <typename Derived>
7540QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7541 PipeTypeLoc TL) {
7542 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7543 if (ValueType.isNull())
7544 return QualType();
7545
7546 QualType Result = TL.getType();
7547 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7548 const PipeType *PT = Result->castAs<PipeType>();
7549 bool isReadPipe = PT->isReadOnly();
7550 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7551 if (Result.isNull())
7552 return QualType();
7553 }
7554
7555 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7556 NewTL.setKWLoc(TL.getKWLoc());
7557
7558 return Result;
7559}
7560
7561template <typename Derived>
7562QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7563 BitIntTypeLoc TL) {
7564 const BitIntType *EIT = TL.getTypePtr();
7565 QualType Result = TL.getType();
7566
7567 if (getDerived().AlwaysRebuild()) {
7568 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7569 EIT->getNumBits(), TL.getNameLoc());
7570 if (Result.isNull())
7571 return QualType();
7572 }
7573
7574 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7575 NewTL.setNameLoc(TL.getNameLoc());
7576 return Result;
7577}
7578
7579template <typename Derived>
7580QualType TreeTransform<Derived>::TransformDependentBitIntType(
7581 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7582 const DependentBitIntType *EIT = TL.getTypePtr();
7583
7584 EnterExpressionEvaluationContext Unevaluated(
7585 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7586 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7587 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7588
7589 if (BitsExpr.isInvalid())
7590 return QualType();
7591
7592 QualType Result = TL.getType();
7593
7594 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7595 Result = getDerived().RebuildDependentBitIntType(
7596 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7597
7598 if (Result.isNull())
7599 return QualType();
7600 }
7601
7602 if (isa<DependentBitIntType>(Val: Result)) {
7603 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7604 NewTL.setNameLoc(TL.getNameLoc());
7605 } else {
7606 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7607 NewTL.setNameLoc(TL.getNameLoc());
7608 }
7609 return Result;
7610}
7611
7612template <typename Derived>
7613QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7614 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7615 llvm_unreachable("This type does not need to be transformed.");
7616}
7617
7618 /// Simple iterator that traverses the template arguments in a
7619 /// container that provides a \c getArgLoc() member function.
7620 ///
7621 /// This iterator is intended to be used with the iterator form of
7622 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7623 template<typename ArgLocContainer>
7624 class TemplateArgumentLocContainerIterator {
7625 ArgLocContainer *Container;
7626 unsigned Index;
7627
7628 public:
7629 typedef TemplateArgumentLoc value_type;
7630 typedef TemplateArgumentLoc reference;
7631 typedef int difference_type;
7632 typedef std::input_iterator_tag iterator_category;
7633
7634 class pointer {
7635 TemplateArgumentLoc Arg;
7636
7637 public:
7638 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7639
7640 const TemplateArgumentLoc *operator->() const {
7641 return &Arg;
7642 }
7643 };
7644
7645
7646 TemplateArgumentLocContainerIterator() {}
7647
7648 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7649 unsigned Index)
7650 : Container(&Container), Index(Index) { }
7651
7652 TemplateArgumentLocContainerIterator &operator++() {
7653 ++Index;
7654 return *this;
7655 }
7656
7657 TemplateArgumentLocContainerIterator operator++(int) {
7658 TemplateArgumentLocContainerIterator Old(*this);
7659 ++(*this);
7660 return Old;
7661 }
7662
7663 TemplateArgumentLoc operator*() const {
7664 return Container->getArgLoc(Index);
7665 }
7666
7667 pointer operator->() const {
7668 return pointer(Container->getArgLoc(Index));
7669 }
7670
7671 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7672 const TemplateArgumentLocContainerIterator &Y) {
7673 return X.Container == Y.Container && X.Index == Y.Index;
7674 }
7675
7676 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7677 const TemplateArgumentLocContainerIterator &Y) {
7678 return !(X == Y);
7679 }
7680 };
7681
7682template<typename Derived>
7683QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7684 AutoTypeLoc TL) {
7685 const AutoType *T = TL.getTypePtr();
7686 QualType OldDeduced = T->getDeducedType();
7687 QualType NewDeduced;
7688 if (!OldDeduced.isNull()) {
7689 NewDeduced = getDerived().TransformType(OldDeduced);
7690 if (NewDeduced.isNull())
7691 return QualType();
7692 }
7693
7694 TemplateName NewCD;
7695 TemplateArgumentListInfo NewTemplateArgs;
7696 NestedNameSpecifierLoc NewNestedNameSpec;
7697 if (T->isConstrained()) {
7698 assert(TL.getConceptReference());
7699 NewCD = getDerived().TransformConceptTemplateName(
7700 T->getTypeConstraintConcept(), TL.getConceptNameLoc());
7701 if (NewCD.isNull())
7702 return QualType();
7703
7704 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7705 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7706 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7707 if (getDerived().TransformTemplateArguments(
7708 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7709 NewTemplateArgs))
7710 return QualType();
7711
7712 if (TL.getNestedNameSpecifierLoc()) {
7713 NewNestedNameSpec
7714 = getDerived().TransformNestedNameSpecifierLoc(
7715 TL.getNestedNameSpecifierLoc());
7716 if (!NewNestedNameSpec)
7717 return QualType();
7718 }
7719 }
7720
7721 QualType Result = TL.getType();
7722 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7723 T->isDependentType() || T->isConstrained()) {
7724 // FIXME: Maybe don't rebuild if all template arguments are the same.
7725 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7726 NewArgList.reserve(N: NewTemplateArgs.size());
7727 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7728 NewArgList.push_back(Elt: ArgLoc.getArgument());
7729 Result = getDerived().RebuildAutoType(
7730 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7731 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7732 if (Result.isNull())
7733 return QualType();
7734 }
7735
7736 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7737 NewTL.setNameLoc(TL.getNameLoc());
7738 NewTL.setRParenLoc(TL.getRParenLoc());
7739 NewTL.setConceptReference(nullptr);
7740
7741 if (T->isConstrained()) {
7742 DeclarationName ConceptName =
7743 SemaRef.Context
7744 .getNameForTemplate(Name: TL.getTypePtr()->getTypeConstraintConcept(),
7745 NameLoc: TL.getConceptNameLoc())
7746 .getName();
7747 DeclarationNameInfo DNI =
7748 DeclarationNameInfo(ConceptName, TL.getConceptNameLoc(), ConceptName);
7749 auto *CR = ConceptReference::Create(
7750 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7751 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7752 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7753 NewTL.setConceptReference(CR);
7754 }
7755
7756 return Result;
7757}
7758
7759template <typename Derived>
7760QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7761 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7762 return getDerived().TransformTemplateSpecializationType(
7763 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7764 /*AllowInjectedClassName=*/false);
7765}
7766
7767template <typename Derived>
7768QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7769 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7770 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7771 const TemplateSpecializationType *T = TL.getTypePtr();
7772
7773 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7774 TemplateName Template = getDerived().TransformTemplateName(
7775 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7776 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7777 AllowInjectedClassName);
7778 if (Template.isNull())
7779 return QualType();
7780
7781 TemplateArgumentListInfo NewTemplateArgs;
7782 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7783 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7784 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7785 ArgIterator;
7786 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7787 ArgIterator(TL, TL.getNumArgs()),
7788 NewTemplateArgs))
7789 return QualType();
7790
7791 // This needs to be rebuilt if either the arguments changed, or if the
7792 // original template changed. If the template changed, and even if the
7793 // arguments didn't change, these arguments might not correspond to their
7794 // respective parameters, therefore needing conversions.
7795 QualType Result = getDerived().RebuildTemplateSpecializationType(
7796 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7797 NewTemplateArgs);
7798
7799 if (!Result.isNull()) {
7800 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7801 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7802 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7803 }
7804
7805 return Result;
7806}
7807
7808template <typename Derived>
7809QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7810 AttributedTypeLoc TL) {
7811 const AttributedType *oldType = TL.getTypePtr();
7812 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7813 if (modifiedType.isNull())
7814 return QualType();
7815
7816 // HLSL: re-validate matrix-layout markers after substitution. If the
7817 // post-substitution type is no longer a matrix, diagnose now.
7818 if (SemaRef.getLangOpts().HLSL &&
7819 SemaRef.HLSL().diagnoseMatrixLayoutInstantiation(
7820 K: oldType->getAttrKind(), T: modifiedType,
7821 Loc: TL.getAttr() ? TL.getAttr()->getLocation()
7822 : TL.getModifiedLoc().getBeginLoc()))
7823 return QualType();
7824
7825 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7826 const Attr *oldAttr = TL.getAttr();
7827 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7828 if (oldAttr && !newAttr)
7829 return QualType();
7830
7831 QualType result = TL.getType();
7832
7833 // FIXME: dependent operand expressions?
7834 if (getDerived().AlwaysRebuild() ||
7835 modifiedType != oldType->getModifiedType()) {
7836 // If the equivalent type is equal to the modified type, we don't want to
7837 // transform it as well because:
7838 //
7839 // 1. The transformation would yield the same result and is therefore
7840 // superfluous, and
7841 //
7842 // 2. Transforming the same type twice can cause problems, e.g. if it
7843 // is a FunctionProtoType, we may end up instantiating the function
7844 // parameters twice, which causes an assertion since the parameters
7845 // are already bound to their counterparts in the template for this
7846 // instantiation.
7847 //
7848 QualType equivalentType = modifiedType;
7849 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7850 TypeLocBuilder AuxiliaryTLB;
7851 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7852 equivalentType =
7853 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7854 if (equivalentType.isNull())
7855 return QualType();
7856 }
7857
7858 if (SemaRef.getLangOpts().HLSL) {
7859 if (oldType->getAttrKind() == attr::HLSLRowMajor)
7860 equivalentType = SemaRef.Context.getMatrixTypeWithLayout(
7861 T: equivalentType, Layout: MatrixType::LayoutKind::RowMajor);
7862 else if (oldType->getAttrKind() == attr::HLSLColumnMajor)
7863 equivalentType = SemaRef.Context.getMatrixTypeWithLayout(
7864 T: equivalentType, Layout: MatrixType::LayoutKind::ColumnMajor);
7865 }
7866
7867 // Check whether we can add nullability; it is only represented as
7868 // type sugar, and therefore cannot be diagnosed in any other way.
7869 if (auto nullability = oldType->getImmediateNullability()) {
7870 if (!modifiedType->canHaveNullability()) {
7871 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7872 : TL.getModifiedLoc().getBeginLoc()),
7873 DiagID: diag::err_nullability_nonpointer)
7874 << DiagNullabilityKind(*nullability, false) << modifiedType;
7875 return QualType();
7876 }
7877 }
7878
7879 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7880 modifiedType,
7881 equivalentType,
7882 attr: TL.getAttr());
7883 }
7884
7885 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7886 newTL.setAttr(newAttr);
7887 return result;
7888}
7889
7890template <typename Derived>
7891QualType TreeTransform<Derived>::TransformCountAttributedType(
7892 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7893 const CountAttributedType *OldTy = TL.getTypePtr();
7894 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7895 if (InnerTy.isNull())
7896 return QualType();
7897
7898 Expr *OldCount = TL.getCountExpr();
7899 Expr *NewCount = nullptr;
7900 if (OldCount) {
7901 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7902 if (CountResult.isInvalid())
7903 return QualType();
7904 NewCount = CountResult.get();
7905 }
7906
7907 QualType Result = TL.getType();
7908 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7909 OldCount != NewCount) {
7910 // Currently, CountAttributedType can only wrap incomplete array types.
7911 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7912 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7913 }
7914
7915 TLB.push<CountAttributedTypeLoc>(T: Result);
7916 return Result;
7917}
7918
7919template <typename Derived>
7920QualType
7921TreeTransform<Derived>::TransformLateParsedAttrType(TypeLocBuilder &TLB,
7922 LateParsedAttrTypeLoc TL) {
7923 const LateParsedAttrType *OldTy = TL.getTypePtr();
7924 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7925 if (InnerTy.isNull())
7926 return QualType();
7927
7928 QualType Result = TL.getType();
7929 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getWrappedType()) {
7930 Result = SemaRef.Context.getLateParsedAttrType(
7931 Wrapped: InnerTy, LateParsedAttr: OldTy->getLateParsedAttribute());
7932 }
7933
7934 LateParsedAttrTypeLoc newTL = TLB.push<LateParsedAttrTypeLoc>(T: Result);
7935 newTL.setAttrNameLoc(TL.getAttrNameLoc());
7936 return Result;
7937}
7938
7939template <typename Derived>
7940QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7941 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7942 // The BTFTagAttributedType is available for C only.
7943 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7944}
7945
7946template <typename Derived>
7947QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7948 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7949 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7950 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7951 if (InnerTy.isNull())
7952 return QualType();
7953
7954 QualType Result = TL.getType();
7955 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7956 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7957 Wrapped: InnerTy);
7958 if (Result.isNull())
7959 return QualType();
7960 }
7961
7962 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7963 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7964 return Result;
7965}
7966
7967template <typename Derived>
7968QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7969 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7970
7971 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7972
7973 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7974 if (WrappedTy.isNull())
7975 return QualType();
7976
7977 QualType ContainedTy = QualType();
7978 QualType OldContainedTy = oldType->getContainedType();
7979 TypeSourceInfo *ContainedTSI = nullptr;
7980 if (!OldContainedTy.isNull()) {
7981 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7982 if (!oldContainedTSI)
7983 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7984 OldContainedTy, SourceLocation());
7985 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7986 if (!ContainedTSI)
7987 return QualType();
7988 ContainedTy = ContainedTSI->getType();
7989 }
7990
7991 HLSLAttributedResourceType::Attributes Attrs = oldType->getAttrs();
7992 if (Attrs.SampleCountExpr) {
7993 ExprResult SampleCountResult =
7994 getDerived().TransformExpr(Attrs.SampleCountExpr);
7995 if (SampleCountResult.isInvalid())
7996 return QualType();
7997 Attrs.SampleCountExpr = SampleCountResult.get();
7998 }
7999
8000 QualType Result = TL.getType();
8001 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
8002 ContainedTy != oldType->getContainedType() ||
8003 Attrs.SampleCountExpr != oldType->getSampleCountExpr()) {
8004 Result = SemaRef.Context.getHLSLAttributedResourceType(Wrapped: WrappedTy,
8005 Contained: ContainedTy, Attrs);
8006 }
8007
8008 HLSLAttributedResourceTypeLoc NewTL =
8009 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
8010 NewTL.setSourceRange(TL.getLocalSourceRange());
8011 NewTL.setContainedTypeSourceInfo(ContainedTSI);
8012 return Result;
8013}
8014
8015template <typename Derived>
8016QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
8017 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
8018 // No transformations needed.
8019 return TL.getType();
8020}
8021
8022template<typename Derived>
8023QualType
8024TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
8025 ParenTypeLoc TL) {
8026 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8027 if (Inner.isNull())
8028 return QualType();
8029
8030 QualType Result = TL.getType();
8031 if (getDerived().AlwaysRebuild() ||
8032 Inner != TL.getInnerLoc().getType()) {
8033 Result = getDerived().RebuildParenType(Inner);
8034 if (Result.isNull())
8035 return QualType();
8036 }
8037
8038 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
8039 NewTL.setLParenLoc(TL.getLParenLoc());
8040 NewTL.setRParenLoc(TL.getRParenLoc());
8041 return Result;
8042}
8043
8044template <typename Derived>
8045QualType
8046TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
8047 MacroQualifiedTypeLoc TL) {
8048 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8049 if (Inner.isNull())
8050 return QualType();
8051
8052 QualType Result = TL.getType();
8053 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
8054 Result =
8055 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
8056 if (Result.isNull())
8057 return QualType();
8058 }
8059
8060 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
8061 NewTL.setExpansionLoc(TL.getExpansionLoc());
8062 return Result;
8063}
8064
8065template<typename Derived>
8066QualType TreeTransform<Derived>::TransformDependentNameType(
8067 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
8068 return TransformDependentNameType(TLB, TL, false);
8069}
8070
8071template <typename Derived>
8072QualType TreeTransform<Derived>::TransformDependentNameType(
8073 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
8074 QualType ObjectType, NamedDecl *UnqualLookup) {
8075 const DependentNameType *T = TL.getTypePtr();
8076
8077 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
8078 if (QualifierLoc) {
8079 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
8080 QualifierLoc, ObjectType, UnqualLookup);
8081 if (!QualifierLoc)
8082 return QualType();
8083 } else {
8084 assert((ObjectType.isNull() && !UnqualLookup) &&
8085 "must be transformed by TransformNestedNameSpecifierLoc");
8086 }
8087
8088 QualType Result
8089 = getDerived().RebuildDependentNameType(T->getKeyword(),
8090 TL.getElaboratedKeywordLoc(),
8091 QualifierLoc,
8092 T->getIdentifier(),
8093 TL.getNameLoc(),
8094 DeducedTSTContext);
8095 if (Result.isNull())
8096 return QualType();
8097
8098 if (isa<TagType>(Val: Result)) {
8099 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
8100 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8101 NewTL.setQualifierLoc(QualifierLoc);
8102 NewTL.setNameLoc(TL.getNameLoc());
8103 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
8104 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
8105 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8106 NewTL.setTemplateNameLoc(TL.getNameLoc());
8107 NewTL.setQualifierLoc(QualifierLoc);
8108 } else if (isa<TypedefType>(Val: Result)) {
8109 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
8110 QualifierLoc, NameLoc: TL.getNameLoc());
8111 } else if (isa<UnresolvedUsingType>(Val: Result)) {
8112 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
8113 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
8114 } else {
8115 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
8116 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8117 NewTL.setQualifierLoc(QualifierLoc);
8118 NewTL.setNameLoc(TL.getNameLoc());
8119 }
8120 return Result;
8121}
8122
8123template<typename Derived>
8124QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
8125 PackExpansionTypeLoc TL) {
8126 QualType Pattern
8127 = getDerived().TransformType(TLB, TL.getPatternLoc());
8128 if (Pattern.isNull())
8129 return QualType();
8130
8131 QualType Result = TL.getType();
8132 if (getDerived().AlwaysRebuild() ||
8133 Pattern != TL.getPatternLoc().getType()) {
8134 Result = getDerived().RebuildPackExpansionType(Pattern,
8135 TL.getPatternLoc().getSourceRange(),
8136 TL.getEllipsisLoc(),
8137 TL.getTypePtr()->getNumExpansions());
8138 if (Result.isNull())
8139 return QualType();
8140 }
8141
8142 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
8143 NewT.setEllipsisLoc(TL.getEllipsisLoc());
8144 return Result;
8145}
8146
8147template<typename Derived>
8148QualType
8149TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
8150 ObjCInterfaceTypeLoc TL) {
8151 // ObjCInterfaceType is never dependent.
8152 TLB.pushFullCopy(L: TL);
8153 return TL.getType();
8154}
8155
8156template<typename Derived>
8157QualType
8158TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
8159 ObjCTypeParamTypeLoc TL) {
8160 const ObjCTypeParamType *T = TL.getTypePtr();
8161 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
8162 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
8163 if (!OTP)
8164 return QualType();
8165
8166 QualType Result = TL.getType();
8167 if (getDerived().AlwaysRebuild() ||
8168 OTP != T->getDecl()) {
8169 Result = getDerived().RebuildObjCTypeParamType(
8170 OTP, TL.getProtocolLAngleLoc(),
8171 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8172 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8173 if (Result.isNull())
8174 return QualType();
8175 }
8176
8177 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
8178 if (TL.getNumProtocols()) {
8179 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8180 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8181 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8182 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8183 }
8184 return Result;
8185}
8186
8187template<typename Derived>
8188QualType
8189TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
8190 ObjCObjectTypeLoc TL) {
8191 // Transform base type.
8192 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
8193 if (BaseType.isNull())
8194 return QualType();
8195
8196 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8197
8198 // Transform type arguments.
8199 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8200 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8201 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8202 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8203 QualType TypeArg = TypeArgInfo->getType();
8204 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8205 AnyChanged = true;
8206
8207 // We have a pack expansion. Instantiate it.
8208 const auto *PackExpansion = PackExpansionLoc.getType()
8209 ->castAs<PackExpansionType>();
8210 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8211 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8212 Unexpanded);
8213 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8214
8215 // Determine whether the set of unexpanded parameter packs can
8216 // and should be expanded.
8217 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8218 bool Expand = false;
8219 bool RetainExpansion = false;
8220 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8221 if (getDerived().TryExpandParameterPacks(
8222 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8223 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8224 RetainExpansion, NumExpansions))
8225 return QualType();
8226
8227 if (!Expand) {
8228 // We can't expand this pack expansion into separate arguments yet;
8229 // just substitute into the pattern and create a new pack expansion
8230 // type.
8231 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8232
8233 TypeLocBuilder TypeArgBuilder;
8234 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8235 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8236 PatternLoc);
8237 if (NewPatternType.isNull())
8238 return QualType();
8239
8240 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8241 Pattern: NewPatternType, NumExpansions);
8242 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8243 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8244 NewTypeArgInfos.push_back(
8245 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8246 continue;
8247 }
8248
8249 // Substitute into the pack expansion pattern for each slice of the
8250 // pack.
8251 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8252 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8253
8254 TypeLocBuilder TypeArgBuilder;
8255 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8256
8257 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8258 PatternLoc);
8259 if (NewTypeArg.isNull())
8260 return QualType();
8261
8262 NewTypeArgInfos.push_back(
8263 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8264 }
8265
8266 continue;
8267 }
8268
8269 TypeLocBuilder TypeArgBuilder;
8270 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8271 QualType NewTypeArg =
8272 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8273 if (NewTypeArg.isNull())
8274 return QualType();
8275
8276 // If nothing changed, just keep the old TypeSourceInfo.
8277 if (NewTypeArg == TypeArg) {
8278 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8279 continue;
8280 }
8281
8282 NewTypeArgInfos.push_back(
8283 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8284 AnyChanged = true;
8285 }
8286
8287 QualType Result = TL.getType();
8288 if (getDerived().AlwaysRebuild() || AnyChanged) {
8289 // Rebuild the type.
8290 Result = getDerived().RebuildObjCObjectType(
8291 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8292 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8293 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8294 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8295
8296 if (Result.isNull())
8297 return QualType();
8298 }
8299
8300 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8301 NewT.setHasBaseTypeAsWritten(true);
8302 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8303 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8304 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8305 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8306 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8307 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8308 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8309 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8310 return Result;
8311}
8312
8313template<typename Derived>
8314QualType
8315TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8316 ObjCObjectPointerTypeLoc TL) {
8317 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8318 if (PointeeType.isNull())
8319 return QualType();
8320
8321 QualType Result = TL.getType();
8322 if (getDerived().AlwaysRebuild() ||
8323 PointeeType != TL.getPointeeLoc().getType()) {
8324 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8325 TL.getStarLoc());
8326 if (Result.isNull())
8327 return QualType();
8328 }
8329
8330 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8331 NewT.setStarLoc(TL.getStarLoc());
8332 return Result;
8333}
8334
8335//===----------------------------------------------------------------------===//
8336// Statement transformation
8337//===----------------------------------------------------------------------===//
8338template<typename Derived>
8339StmtResult
8340TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8341 return S;
8342}
8343
8344template<typename Derived>
8345StmtResult
8346TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8347 return getDerived().TransformCompoundStmt(S, false);
8348}
8349
8350template<typename Derived>
8351StmtResult
8352TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8353 bool IsStmtExpr) {
8354 Sema::CompoundScopeRAII CompoundScope(getSema());
8355 Sema::FPFeaturesStateRAII FPSave(getSema());
8356 if (S->hasStoredFPFeatures())
8357 getSema().resetFPOptions(
8358 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8359
8360 bool SubStmtInvalid = false;
8361 bool SubStmtChanged = false;
8362 SmallVector<Stmt*, 8> Statements;
8363 for (auto *B : S->body()) {
8364 StmtResult Result = getDerived().TransformStmt(
8365 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8366 : StmtDiscardKind::Discarded);
8367
8368 if (Result.isInvalid()) {
8369 // Immediately fail if this was a DeclStmt, since it's very
8370 // likely that this will cause problems for future statements.
8371 if (isa<DeclStmt>(Val: B))
8372 return StmtError();
8373
8374 // Otherwise, just keep processing substatements and fail later.
8375 SubStmtInvalid = true;
8376 continue;
8377 }
8378
8379 SubStmtChanged = SubStmtChanged || Result.get() != B;
8380 Statements.push_back(Elt: Result.getAs<Stmt>());
8381 }
8382
8383 if (SubStmtInvalid)
8384 return StmtError();
8385
8386 if (!getDerived().AlwaysRebuild() &&
8387 !SubStmtChanged)
8388 return S;
8389
8390 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8391 Statements,
8392 S->getRBracLoc(),
8393 IsStmtExpr);
8394}
8395
8396template<typename Derived>
8397StmtResult
8398TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8399 ExprResult LHS, RHS;
8400 {
8401 EnterExpressionEvaluationContext Unevaluated(
8402 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8403
8404 // Transform the left-hand case value.
8405 LHS = getDerived().TransformExpr(S->getLHS());
8406 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8407 if (LHS.isInvalid())
8408 return StmtError();
8409
8410 // Transform the right-hand case value (for the GNU case-range extension).
8411 RHS = getDerived().TransformExpr(S->getRHS());
8412 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8413 if (RHS.isInvalid())
8414 return StmtError();
8415 }
8416
8417 // Build the case statement.
8418 // Case statements are always rebuilt so that they will attached to their
8419 // transformed switch statement.
8420 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8421 LHS.get(),
8422 S->getEllipsisLoc(),
8423 RHS.get(),
8424 S->getColonLoc());
8425 if (Case.isInvalid())
8426 return StmtError();
8427
8428 // Transform the statement following the case
8429 StmtResult SubStmt =
8430 getDerived().TransformStmt(S->getSubStmt());
8431 if (SubStmt.isInvalid())
8432 return StmtError();
8433
8434 // Attach the body to the case statement
8435 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8436}
8437
8438template <typename Derived>
8439StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8440 // Transform the statement following the default case
8441 StmtResult SubStmt =
8442 getDerived().TransformStmt(S->getSubStmt());
8443 if (SubStmt.isInvalid())
8444 return StmtError();
8445
8446 // Default statements are always rebuilt
8447 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8448 SubStmt.get());
8449}
8450
8451template<typename Derived>
8452StmtResult
8453TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8454 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8455 if (SubStmt.isInvalid())
8456 return StmtError();
8457
8458 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8459 S->getDecl());
8460 if (!LD)
8461 return StmtError();
8462
8463 // If we're transforming "in-place" (we're not creating new local
8464 // declarations), assume we're replacing the old label statement
8465 // and clear out the reference to it.
8466 if (LD == S->getDecl())
8467 S->getDecl()->setStmt(nullptr);
8468
8469 // FIXME: Pass the real colon location in.
8470 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8471 cast<LabelDecl>(Val: LD), SourceLocation(),
8472 SubStmt.get());
8473}
8474
8475template <typename Derived>
8476const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8477 if (!R)
8478 return R;
8479
8480 switch (R->getKind()) {
8481// Transform attributes by calling TransformXXXAttr.
8482#define ATTR(X) \
8483 case attr::X: \
8484 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8485#include "clang/Basic/AttrList.inc"
8486 }
8487 return R;
8488}
8489
8490template <typename Derived>
8491const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8492 const Stmt *InstS,
8493 const Attr *R) {
8494 if (!R)
8495 return R;
8496
8497 switch (R->getKind()) {
8498// Transform attributes by calling TransformStmtXXXAttr.
8499#define ATTR(X) \
8500 case attr::X: \
8501 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8502#include "clang/Basic/AttrList.inc"
8503 }
8504 return TransformAttr(R);
8505}
8506
8507template <typename Derived>
8508StmtResult
8509TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8510 StmtDiscardKind SDK) {
8511 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8512 if (SubStmt.isInvalid())
8513 return StmtError();
8514
8515 bool AttrsChanged = false;
8516 SmallVector<const Attr *, 1> Attrs;
8517
8518 // Visit attributes and keep track if any are transformed.
8519 for (const auto *I : S->getAttrs()) {
8520 const Attr *R =
8521 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8522 AttrsChanged |= (I != R);
8523 if (R)
8524 Attrs.push_back(Elt: R);
8525 }
8526
8527 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8528 return S;
8529
8530 // If transforming the attributes failed for all of the attributes in the
8531 // statement, don't make an AttributedStmt without attributes.
8532 if (Attrs.empty())
8533 return SubStmt;
8534
8535 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8536 SubStmt.get());
8537}
8538
8539template<typename Derived>
8540StmtResult
8541TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8542 // Transform the initialization statement
8543 StmtResult Init = getDerived().TransformStmt(S->getInit());
8544 if (Init.isInvalid())
8545 return StmtError();
8546
8547 Sema::ConditionResult Cond;
8548 if (!S->isConsteval()) {
8549 // Transform the condition
8550 Cond = getDerived().TransformCondition(
8551 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8552 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8553 : Sema::ConditionKind::Boolean);
8554 if (Cond.isInvalid())
8555 return StmtError();
8556 }
8557
8558 // If this is a constexpr if, determine which arm we should instantiate.
8559 std::optional<bool> ConstexprConditionValue;
8560 if (S->isConstexpr())
8561 ConstexprConditionValue = Cond.getKnownValue();
8562
8563 // Transform the "then" branch.
8564 StmtResult Then;
8565 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8566 EnterExpressionEvaluationContext Ctx(
8567 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8568 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8569 S->isNonNegatedConsteval());
8570
8571 Then = getDerived().TransformStmt(S->getThen());
8572 if (Then.isInvalid())
8573 return StmtError();
8574 } else {
8575 // Discarded branch is replaced with empty CompoundStmt so we can keep
8576 // proper source location for start and end of original branch, so
8577 // subsequent transformations like CoverageMapping work properly
8578 Then = new (getSema().Context)
8579 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8580 }
8581
8582 // Transform the "else" branch.
8583 StmtResult Else;
8584 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8585 EnterExpressionEvaluationContext Ctx(
8586 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8587 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8588 S->isNegatedConsteval());
8589
8590 Else = getDerived().TransformStmt(S->getElse());
8591 if (Else.isInvalid())
8592 return StmtError();
8593 } else if (S->getElse() && ConstexprConditionValue &&
8594 *ConstexprConditionValue) {
8595 // Same thing here as with <then> branch, we are discarding it, we can't
8596 // replace it with NULL nor NullStmt as we need to keep for source location
8597 // range, for CoverageMapping
8598 Else = new (getSema().Context)
8599 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8600 }
8601
8602 if (!getDerived().AlwaysRebuild() &&
8603 Init.get() == S->getInit() &&
8604 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8605 Then.get() == S->getThen() &&
8606 Else.get() == S->getElse())
8607 return S;
8608
8609 return getDerived().RebuildIfStmt(
8610 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8611 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8612}
8613
8614template<typename Derived>
8615StmtResult
8616TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8617 // Transform the initialization statement
8618 StmtResult Init = getDerived().TransformStmt(S->getInit());
8619 if (Init.isInvalid())
8620 return StmtError();
8621
8622 // Transform the condition.
8623 Sema::ConditionResult Cond = getDerived().TransformCondition(
8624 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8625 Sema::ConditionKind::Switch);
8626 if (Cond.isInvalid())
8627 return StmtError();
8628
8629 // Rebuild the switch statement.
8630 StmtResult Switch =
8631 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8632 Init.get(), Cond, S->getRParenLoc());
8633 if (Switch.isInvalid())
8634 return StmtError();
8635
8636 // Transform the body of the switch statement.
8637 StmtResult Body = getDerived().TransformStmt(S->getBody());
8638
8639 // Complete the switch statement.
8640 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8641 Body.get());
8642}
8643
8644template<typename Derived>
8645StmtResult
8646TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8647 // Transform the condition
8648 Sema::ConditionResult Cond = getDerived().TransformCondition(
8649 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8650 Sema::ConditionKind::Boolean);
8651 if (Cond.isInvalid())
8652 return StmtError();
8653
8654 // OpenACC Restricts a while-loop inside of certain construct/clause
8655 // combinations, so diagnose that here in OpenACC mode.
8656 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8657 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8658
8659 // Transform the body
8660 StmtResult Body = getDerived().TransformStmt(S->getBody());
8661 if (Body.isInvalid())
8662 return StmtError();
8663
8664 if (!getDerived().AlwaysRebuild() &&
8665 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8666 Body.get() == S->getBody())
8667 return Owned(S);
8668
8669 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8670 Cond, S->getRParenLoc(), Body.get());
8671}
8672
8673template<typename Derived>
8674StmtResult
8675TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8676 // OpenACC Restricts a do-loop inside of certain construct/clause
8677 // combinations, so diagnose that here in OpenACC mode.
8678 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8679 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8680
8681 // Transform the body
8682 StmtResult Body = getDerived().TransformStmt(S->getBody());
8683 if (Body.isInvalid())
8684 return StmtError();
8685
8686 // Transform the condition
8687 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8688 if (Cond.isInvalid())
8689 return StmtError();
8690
8691 if (!getDerived().AlwaysRebuild() &&
8692 Cond.get() == S->getCond() &&
8693 Body.get() == S->getBody())
8694 return S;
8695
8696 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8697 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8698 S->getRParenLoc());
8699}
8700
8701template<typename Derived>
8702StmtResult
8703TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8704 if (getSema().getLangOpts().getOpenMPVersion())
8705 getSema().OpenMP().startOpenMPLoop();
8706
8707 // Transform the initialization statement
8708 StmtResult Init = getDerived().TransformStmt(S->getInit());
8709 if (Init.isInvalid())
8710 return StmtError();
8711
8712 // In OpenMP loop region loop control variable must be captured and be
8713 // private. Perform analysis of first part (if any).
8714 if (getSema().getLangOpts().getOpenMPVersion() && Init.isUsable())
8715 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8716 Init.get());
8717
8718 // Transform the condition
8719 Sema::ConditionResult Cond = getDerived().TransformCondition(
8720 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8721 Sema::ConditionKind::Boolean);
8722 if (Cond.isInvalid())
8723 return StmtError();
8724
8725 // Transform the increment
8726 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8727 if (Inc.isInvalid())
8728 return StmtError();
8729
8730 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8731 if (S->getInc() && !FullInc.get())
8732 return StmtError();
8733
8734 // OpenACC Restricts a for-loop inside of certain construct/clause
8735 // combinations, so diagnose that here in OpenACC mode.
8736 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8737 SemaRef.OpenACC().ActOnForStmtBegin(
8738 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8739 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8740
8741 // Transform the body
8742 StmtResult Body = getDerived().TransformStmt(S->getBody());
8743 if (Body.isInvalid())
8744 return StmtError();
8745
8746 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8747
8748 if (!getDerived().AlwaysRebuild() &&
8749 Init.get() == S->getInit() &&
8750 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8751 Inc.get() == S->getInc() &&
8752 Body.get() == S->getBody())
8753 return S;
8754
8755 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8756 Init.get(), Cond, FullInc,
8757 S->getRParenLoc(), Body.get());
8758}
8759
8760template<typename Derived>
8761StmtResult
8762TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8763 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8764 S->getLabel());
8765 if (!LD)
8766 return StmtError();
8767
8768 // Goto statements must always be rebuilt, to resolve the label.
8769 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8770 cast<LabelDecl>(Val: LD));
8771}
8772
8773template<typename Derived>
8774StmtResult
8775TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8776 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8777 if (Target.isInvalid())
8778 return StmtError();
8779 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8780
8781 if (!getDerived().AlwaysRebuild() &&
8782 Target.get() == S->getTarget())
8783 return S;
8784
8785 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8786 Target.get());
8787}
8788
8789template<typename Derived>
8790StmtResult
8791TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8792 if (!S->hasLabelTarget())
8793 return S;
8794
8795 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8796 S->getLabelDecl());
8797 if (!LD)
8798 return StmtError();
8799
8800 return new (SemaRef.Context)
8801 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8802}
8803
8804template<typename Derived>
8805StmtResult
8806TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8807 if (!S->hasLabelTarget())
8808 return S;
8809
8810 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8811 S->getLabelDecl());
8812 if (!LD)
8813 return StmtError();
8814
8815 return new (SemaRef.Context)
8816 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8817}
8818
8819template <typename Derived>
8820StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8821 StmtResult Result = getDerived().TransformStmt(S->getBody());
8822 if (!Result.isUsable())
8823 return StmtError();
8824 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8825}
8826
8827template<typename Derived>
8828StmtResult
8829TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8830 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8831 /*NotCopyInit*/false);
8832 if (Result.isInvalid())
8833 return StmtError();
8834
8835 // FIXME: We always rebuild the return statement because there is no way
8836 // to tell whether the return type of the function has changed.
8837 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8838}
8839
8840template<typename Derived>
8841StmtResult
8842TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8843 bool DeclChanged = false;
8844 SmallVector<Decl *, 4> Decls;
8845 LambdaScopeInfo *LSI = getSema().getCurLambda();
8846 for (auto *D : S->decls()) {
8847 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8848 if (!Transformed)
8849 return StmtError();
8850
8851 if (Transformed != D)
8852 DeclChanged = true;
8853
8854 if (LSI) {
8855 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8856 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8857 LSI->ContainsUnexpandedParameterPack |=
8858 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8859 } else {
8860 LSI->ContainsUnexpandedParameterPack |=
8861 getSema()
8862 .getASTContext()
8863 .getTypeDeclType(TD)
8864 ->containsUnexpandedParameterPack();
8865 }
8866 }
8867 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8868 LSI->ContainsUnexpandedParameterPack |=
8869 VD->getType()->containsUnexpandedParameterPack();
8870 }
8871
8872 Decls.push_back(Elt: Transformed);
8873 }
8874
8875 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8876 return S;
8877
8878 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8879}
8880
8881template<typename Derived>
8882StmtResult
8883TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8884
8885 SmallVector<Expr*, 8> Constraints;
8886 SmallVector<Expr*, 8> Exprs;
8887 SmallVector<IdentifierInfo *, 4> Names;
8888
8889 SmallVector<Expr*, 8> Clobbers;
8890
8891 bool ExprsChanged = false;
8892
8893 auto RebuildString = [&](Expr *E) {
8894 ExprResult Result = getDerived().TransformExpr(E);
8895 if (!Result.isUsable())
8896 return Result;
8897 if (Result.get() != E) {
8898 ExprsChanged = true;
8899 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8900 }
8901 return Result;
8902 };
8903
8904 // Go through the outputs.
8905 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8906 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8907
8908 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8909 if (Result.isInvalid())
8910 return StmtError();
8911
8912 Constraints.push_back(Elt: Result.get());
8913
8914 // Transform the output expr.
8915 Expr *OutputExpr = S->getOutputExpr(i: I);
8916 Result = getDerived().TransformExpr(OutputExpr);
8917 if (Result.isInvalid())
8918 return StmtError();
8919
8920 ExprsChanged |= Result.get() != OutputExpr;
8921
8922 Exprs.push_back(Elt: Result.get());
8923 }
8924
8925 // Go through the inputs.
8926 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8927 Names.push_back(Elt: S->getInputIdentifier(i: I));
8928
8929 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8930 if (Result.isInvalid())
8931 return StmtError();
8932
8933 Constraints.push_back(Elt: Result.get());
8934
8935 // Transform the input expr.
8936 Expr *InputExpr = S->getInputExpr(i: I);
8937 Result = getDerived().TransformExpr(InputExpr);
8938 if (Result.isInvalid())
8939 return StmtError();
8940
8941 ExprsChanged |= Result.get() != InputExpr;
8942
8943 Exprs.push_back(Elt: Result.get());
8944 }
8945
8946 // Go through the Labels.
8947 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8948 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8949
8950 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8951 if (Result.isInvalid())
8952 return StmtError();
8953 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8954 Exprs.push_back(Elt: Result.get());
8955 }
8956
8957 // Go through the clobbers.
8958 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8959 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8960 if (Result.isInvalid())
8961 return StmtError();
8962 Clobbers.push_back(Elt: Result.get());
8963 }
8964
8965 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8966 if (AsmString.isInvalid())
8967 return StmtError();
8968
8969 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8970 return S;
8971
8972 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8973 S->isVolatile(), S->getNumOutputs(),
8974 S->getNumInputs(), Names.data(),
8975 Constraints, Exprs, AsmString.get(),
8976 Clobbers, S->getNumLabels(),
8977 S->getRParenLoc());
8978}
8979
8980template<typename Derived>
8981StmtResult
8982TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8983 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8984
8985 bool HadError = false, HadChange = false;
8986
8987 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8988 SmallVector<Expr*, 8> TransformedExprs;
8989 TransformedExprs.reserve(N: SrcExprs.size());
8990 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8991 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8992 if (!Result.isUsable()) {
8993 HadError = true;
8994 } else {
8995 HadChange |= (Result.get() != SrcExprs[i]);
8996 TransformedExprs.push_back(Elt: Result.get());
8997 }
8998 }
8999
9000 if (HadError) return StmtError();
9001 if (!HadChange && !getDerived().AlwaysRebuild())
9002 return Owned(S);
9003
9004 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
9005 AsmToks, S->getAsmString(),
9006 S->getNumOutputs(), S->getNumInputs(),
9007 S->getAllConstraints(), S->getClobbers(),
9008 TransformedExprs, S->getEndLoc());
9009}
9010
9011// C++ Coroutines
9012template<typename Derived>
9013StmtResult
9014TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
9015 auto *ScopeInfo = SemaRef.getCurFunction();
9016 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
9017 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
9018 ScopeInfo->NeedsCoroutineSuspends &&
9019 ScopeInfo->CoroutineSuspends.first == nullptr &&
9020 ScopeInfo->CoroutineSuspends.second == nullptr &&
9021 "expected clean scope info");
9022
9023 // Set that we have (possibly-invalid) suspend points before we do anything
9024 // that may fail.
9025 ScopeInfo->setNeedsCoroutineSuspends(false);
9026
9027 // We re-build the coroutine promise object (and the coroutine parameters its
9028 // type and constructor depend on) based on the types used in our current
9029 // function. We must do so, and set it on the current FunctionScopeInfo,
9030 // before attempting to transform the other parts of the coroutine body
9031 // statement, such as the implicit suspend statements (because those
9032 // statements reference the FunctionScopeInfo::CoroutinePromise).
9033 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
9034 return StmtError();
9035 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
9036 if (!Promise)
9037 return StmtError();
9038 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
9039 ScopeInfo->CoroutinePromise = Promise;
9040
9041 // Transform the implicit coroutine statements constructed using dependent
9042 // types during the previous parse: initial and final suspensions, the return
9043 // object, and others. We also transform the coroutine function's body.
9044 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
9045 if (InitSuspend.isInvalid())
9046 return StmtError();
9047 StmtResult FinalSuspend =
9048 getDerived().TransformStmt(S->getFinalSuspendStmt());
9049 if (FinalSuspend.isInvalid() ||
9050 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
9051 return StmtError();
9052 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
9053 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
9054
9055 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
9056 if (BodyRes.isInvalid())
9057 return StmtError();
9058
9059 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
9060 if (Builder.isInvalid())
9061 return StmtError();
9062
9063 Expr *ReturnObject = S->getReturnValueInit();
9064 assert(ReturnObject && "the return object is expected to be valid");
9065 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
9066 /*NoCopyInit*/ false);
9067 if (Res.isInvalid())
9068 return StmtError();
9069 Builder.ReturnValue = Res.get();
9070
9071 // If during the previous parse the coroutine still had a dependent promise
9072 // statement, we may need to build some implicit coroutine statements
9073 // (such as exception and fallthrough handlers) for the first time.
9074 if (S->hasDependentPromiseType()) {
9075 // We can only build these statements, however, if the current promise type
9076 // is not dependent.
9077 if (!Promise->getType()->isDependentType()) {
9078 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
9079 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
9080 "these nodes should not have been built yet");
9081 if (!Builder.buildDependentStatements())
9082 return StmtError();
9083 }
9084 } else {
9085 if (auto *OnFallthrough = S->getFallthroughHandler()) {
9086 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
9087 if (Res.isInvalid())
9088 return StmtError();
9089 Builder.OnFallthrough = Res.get();
9090 }
9091
9092 if (auto *OnException = S->getExceptionHandler()) {
9093 StmtResult Res = getDerived().TransformStmt(OnException);
9094 if (Res.isInvalid())
9095 return StmtError();
9096 Builder.OnException = Res.get();
9097 }
9098
9099 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
9100 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
9101 if (Res.isInvalid())
9102 return StmtError();
9103 Builder.ReturnStmtOnAllocFailure = Res.get();
9104 }
9105
9106 // Transform any additional statements we may have already built
9107 assert(S->getAllocate() && S->getDeallocate() &&
9108 "allocation and deallocation calls must already be built");
9109 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
9110 if (AllocRes.isInvalid())
9111 return StmtError();
9112 Builder.Allocate = AllocRes.get();
9113
9114 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
9115 if (DeallocRes.isInvalid())
9116 return StmtError();
9117 Builder.Deallocate = DeallocRes.get();
9118
9119 if (auto *ResultDecl = S->getResultDecl()) {
9120 StmtResult Res = getDerived().TransformStmt(ResultDecl);
9121 if (Res.isInvalid())
9122 return StmtError();
9123 Builder.ResultDecl = Res.get();
9124 }
9125
9126 if (auto *ReturnStmt = S->getReturnStmt()) {
9127 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
9128 if (Res.isInvalid())
9129 return StmtError();
9130 Builder.ReturnStmt = Res.get();
9131 }
9132 }
9133
9134 return getDerived().RebuildCoroutineBodyStmt(Builder);
9135}
9136
9137template<typename Derived>
9138StmtResult
9139TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
9140 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
9141 /*NotCopyInit*/false);
9142 if (Result.isInvalid())
9143 return StmtError();
9144
9145 // Always rebuild; we don't know if this needs to be injected into a new
9146 // context or if the promise type has changed.
9147 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
9148 S->isImplicit());
9149}
9150
9151template <typename Derived>
9152ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
9153 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
9154 /*NotCopyInit*/ false);
9155 if (Operand.isInvalid())
9156 return ExprError();
9157
9158 // Rebuild the common-expr from the operand rather than transforming it
9159 // separately.
9160
9161 // FIXME: getCurScope() should not be used during template instantiation.
9162 // We should pick up the set of unqualified lookup results for operator
9163 // co_await during the initial parse.
9164 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
9165 getSema().getCurScope(), E->getKeywordLoc());
9166
9167 // Always rebuild; we don't know if this needs to be injected into a new
9168 // context or if the promise type has changed.
9169 return getDerived().RebuildCoawaitExpr(
9170 E->getKeywordLoc(), Operand.get(),
9171 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
9172}
9173
9174template <typename Derived>
9175ExprResult
9176TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
9177 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
9178 /*NotCopyInit*/ false);
9179 if (OperandResult.isInvalid())
9180 return ExprError();
9181
9182 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
9183 E->getOperatorCoawaitLookup());
9184
9185 if (LookupResult.isInvalid())
9186 return ExprError();
9187
9188 // Always rebuild; we don't know if this needs to be injected into a new
9189 // context or if the promise type has changed.
9190 return getDerived().RebuildDependentCoawaitExpr(
9191 E->getKeywordLoc(), OperandResult.get(),
9192 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
9193}
9194
9195template<typename Derived>
9196ExprResult
9197TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9198 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9199 /*NotCopyInit*/false);
9200 if (Result.isInvalid())
9201 return ExprError();
9202
9203 // Always rebuild; we don't know if this needs to be injected into a new
9204 // context or if the promise type has changed.
9205 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9206}
9207
9208// Objective-C Statements.
9209
9210template<typename Derived>
9211StmtResult
9212TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9213 // Transform the body of the @try.
9214 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9215 if (TryBody.isInvalid())
9216 return StmtError();
9217
9218 // Transform the @catch statements (if present).
9219 bool AnyCatchChanged = false;
9220 SmallVector<Stmt*, 8> CatchStmts;
9221 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9222 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9223 if (Catch.isInvalid())
9224 return StmtError();
9225 if (Catch.get() != S->getCatchStmt(I))
9226 AnyCatchChanged = true;
9227 CatchStmts.push_back(Elt: Catch.get());
9228 }
9229
9230 // Transform the @finally statement (if present).
9231 StmtResult Finally;
9232 if (S->getFinallyStmt()) {
9233 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9234 if (Finally.isInvalid())
9235 return StmtError();
9236 }
9237
9238 // If nothing changed, just retain this statement.
9239 if (!getDerived().AlwaysRebuild() &&
9240 TryBody.get() == S->getTryBody() &&
9241 !AnyCatchChanged &&
9242 Finally.get() == S->getFinallyStmt())
9243 return S;
9244
9245 // Build a new statement.
9246 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9247 CatchStmts, Finally.get());
9248}
9249
9250template<typename Derived>
9251StmtResult
9252TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9253 // Transform the @catch parameter, if there is one.
9254 VarDecl *Var = nullptr;
9255 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9256 TypeSourceInfo *TSInfo = nullptr;
9257 if (FromVar->getTypeSourceInfo()) {
9258 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9259 if (!TSInfo)
9260 return StmtError();
9261 }
9262
9263 QualType T;
9264 if (TSInfo)
9265 T = TSInfo->getType();
9266 else {
9267 T = getDerived().TransformType(FromVar->getType());
9268 if (T.isNull())
9269 return StmtError();
9270 }
9271
9272 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9273 if (!Var)
9274 return StmtError();
9275 }
9276
9277 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9278 if (Body.isInvalid())
9279 return StmtError();
9280
9281 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9282 S->getRParenLoc(),
9283 Var, Body.get());
9284}
9285
9286template<typename Derived>
9287StmtResult
9288TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9289 // Transform the body.
9290 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9291 if (Body.isInvalid())
9292 return StmtError();
9293
9294 // If nothing changed, just retain this statement.
9295 if (!getDerived().AlwaysRebuild() &&
9296 Body.get() == S->getFinallyBody())
9297 return S;
9298
9299 // Build a new statement.
9300 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9301 Body.get());
9302}
9303
9304template<typename Derived>
9305StmtResult
9306TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9307 ExprResult Operand;
9308 if (S->getThrowExpr()) {
9309 Operand = getDerived().TransformExpr(S->getThrowExpr());
9310 if (Operand.isInvalid())
9311 return StmtError();
9312 }
9313
9314 if (!getDerived().AlwaysRebuild() &&
9315 Operand.get() == S->getThrowExpr())
9316 return S;
9317
9318 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9319}
9320
9321template<typename Derived>
9322StmtResult
9323TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9324 ObjCAtSynchronizedStmt *S) {
9325 // Transform the object we are locking.
9326 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9327 if (Object.isInvalid())
9328 return StmtError();
9329 Object =
9330 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9331 Object.get());
9332 if (Object.isInvalid())
9333 return StmtError();
9334
9335 // Transform the body.
9336 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9337 if (Body.isInvalid())
9338 return StmtError();
9339
9340 // If nothing change, just retain the current statement.
9341 if (!getDerived().AlwaysRebuild() &&
9342 Object.get() == S->getSynchExpr() &&
9343 Body.get() == S->getSynchBody())
9344 return S;
9345
9346 // Build a new statement.
9347 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9348 Object.get(), Body.get());
9349}
9350
9351template<typename Derived>
9352StmtResult
9353TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9354 ObjCAutoreleasePoolStmt *S) {
9355 // Transform the body.
9356 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9357 if (Body.isInvalid())
9358 return StmtError();
9359
9360 // If nothing changed, just retain this statement.
9361 if (!getDerived().AlwaysRebuild() &&
9362 Body.get() == S->getSubStmt())
9363 return S;
9364
9365 // Build a new statement.
9366 return getDerived().RebuildObjCAutoreleasePoolStmt(
9367 S->getAtLoc(), Body.get());
9368}
9369
9370template<typename Derived>
9371StmtResult
9372TreeTransform<Derived>::TransformObjCForCollectionStmt(
9373 ObjCForCollectionStmt *S) {
9374 // Transform the element statement.
9375 StmtResult Element = getDerived().TransformStmt(
9376 S->getElement(), StmtDiscardKind::NotDiscarded);
9377 if (Element.isInvalid())
9378 return StmtError();
9379
9380 // Transform the collection expression.
9381 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9382 if (Collection.isInvalid())
9383 return StmtError();
9384
9385 // Transform the body.
9386 StmtResult Body = getDerived().TransformStmt(S->getBody());
9387 if (Body.isInvalid())
9388 return StmtError();
9389
9390 // If nothing changed, just retain this statement.
9391 if (!getDerived().AlwaysRebuild() &&
9392 Element.get() == S->getElement() &&
9393 Collection.get() == S->getCollection() &&
9394 Body.get() == S->getBody())
9395 return S;
9396
9397 // Build a new statement.
9398 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9399 Element.get(),
9400 Collection.get(),
9401 S->getRParenLoc(),
9402 Body.get());
9403}
9404
9405template <typename Derived>
9406StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9407 // Transform the exception declaration, if any.
9408 VarDecl *Var = nullptr;
9409 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9410 TypeSourceInfo *T =
9411 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9412 if (!T)
9413 return StmtError();
9414
9415 Var = getDerived().RebuildExceptionDecl(
9416 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9417 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9418 if (!Var || Var->isInvalidDecl())
9419 return StmtError();
9420 }
9421
9422 // Transform the actual exception handler.
9423 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9424 if (Handler.isInvalid())
9425 return StmtError();
9426
9427 if (!getDerived().AlwaysRebuild() && !Var &&
9428 Handler.get() == S->getHandlerBlock())
9429 return S;
9430
9431 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9432}
9433
9434template <typename Derived>
9435StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9436 // Transform the try block itself.
9437 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9438 if (TryBlock.isInvalid())
9439 return StmtError();
9440
9441 // Transform the handlers.
9442 bool HandlerChanged = false;
9443 SmallVector<Stmt *, 8> Handlers;
9444 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9445 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9446 if (Handler.isInvalid())
9447 return StmtError();
9448
9449 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9450 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9451 }
9452
9453 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9454
9455 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9456 !HandlerChanged)
9457 return S;
9458
9459 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9460 Handlers);
9461}
9462
9463template<typename Derived>
9464StmtResult
9465TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9466 EnterExpressionEvaluationContext ForRangeInitContext(
9467 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9468 /*LambdaContextDecl=*/nullptr,
9469 Sema::ExpressionEvaluationContextRecord::EK_Other,
9470 getSema().getLangOpts().CPlusPlus23);
9471
9472 // P2718R0 - Lifetime extension in range-based for loops.
9473 if (getSema().getLangOpts().CPlusPlus23) {
9474 auto &LastRecord = getSema().currentEvaluationContext();
9475 LastRecord.InLifetimeExtendingContext = true;
9476 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9477 }
9478 StmtResult Init =
9479 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9480 if (Init.isInvalid())
9481 return StmtError();
9482
9483 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9484 if (Range.isInvalid())
9485 return StmtError();
9486
9487 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9488 assert(getSema().getLangOpts().CPlusPlus23 ||
9489 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9490 auto ForRangeLifetimeExtendTemps =
9491 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9492
9493 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9494 if (Begin.isInvalid())
9495 return StmtError();
9496 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9497 if (End.isInvalid())
9498 return StmtError();
9499
9500 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9501 if (Cond.isInvalid())
9502 return StmtError();
9503 if (Cond.get())
9504 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9505 if (Cond.isInvalid())
9506 return StmtError();
9507 if (Cond.get())
9508 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9509
9510 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9511 if (Inc.isInvalid())
9512 return StmtError();
9513 if (Inc.get())
9514 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9515
9516 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9517 if (LoopVar.isInvalid())
9518 return StmtError();
9519
9520 StmtResult NewStmt = S;
9521 if (getDerived().AlwaysRebuild() ||
9522 Init.get() != S->getInit() ||
9523 Range.get() != S->getRangeStmt() ||
9524 Begin.get() != S->getBeginStmt() ||
9525 End.get() != S->getEndStmt() ||
9526 Cond.get() != S->getCond() ||
9527 Inc.get() != S->getInc() ||
9528 LoopVar.get() != S->getLoopVarStmt()) {
9529 NewStmt = getDerived().RebuildCXXForRangeStmt(
9530 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9531 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9532 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9533 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9534 // Might not have attached any initializer to the loop variable.
9535 getSema().ActOnInitializerError(
9536 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9537 return StmtError();
9538 }
9539 }
9540
9541 // OpenACC Restricts a while-loop inside of certain construct/clause
9542 // combinations, so diagnose that here in OpenACC mode.
9543 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9544 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9545
9546 StmtResult Body = getDerived().TransformStmt(S->getBody());
9547 if (Body.isInvalid())
9548 return StmtError();
9549
9550 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9551
9552 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9553 // it now so we have a new statement to attach the body to.
9554 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9555 NewStmt = getDerived().RebuildCXXForRangeStmt(
9556 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9557 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9558 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9559 if (NewStmt.isInvalid())
9560 return StmtError();
9561 }
9562
9563 if (NewStmt.get() == S)
9564 return S;
9565
9566 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9567}
9568
9569template <typename Derived>
9570StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtPattern(
9571 CXXExpansionStmtPattern *S) {
9572 assert(SemaRef.CurContext->isExpansionStmt());
9573
9574 Decl *ESD =
9575 getDerived().TransformDecl(S->getDecl()->getLocation(), S->getDecl());
9576 if (!ESD || ESD->isInvalidDecl())
9577 return StmtError();
9578 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9579
9580 // This is required because some parts of an expansion statement (e.g. the
9581 // init-statement) are not in a dependent context and must thus be transformed
9582 // in the parent context.
9583 auto TransformStmtInParentContext = [&](Stmt *SubStmt) -> StmtResult {
9584 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9585 /*NewThis=*/false);
9586 return getDerived().TransformStmt(SubStmt);
9587 };
9588
9589 Stmt *Init = S->getInit();
9590 if (Init) {
9591 StmtResult SR = TransformStmtInParentContext(Init);
9592 if (SR.isInvalid())
9593 return StmtError();
9594 Init = SR.get();
9595 }
9596
9597 // Collect lifetime-extended temporaries in case this ends up being a
9598 // destructuring or iterating expansion statement.
9599 //
9600 // CWG 3140: Additionally, for iterating expansions statements, we need to
9601 // apply lifetime extension to the initializer of the range.
9602 ExprResult ExpansionInitializer;
9603 StmtResult Range;
9604 SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
9605 if (S->isDependent() || S->isIterating()) {
9606 EnterExpressionEvaluationContext ExprEvalCtx(
9607 SemaRef, SemaRef.currentEvaluationContext().Context);
9608 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9609 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9610
9611 if (S->isDependent()) {
9612 // The expansion initializer should not be in the context of the expansion
9613 // statement because it isn't instantiated when the expansion statement is
9614 // expanded.
9615 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9616 /*NewThis=*/false);
9617 ExpansionInitializer =
9618 getDerived().TransformExpr(S->getExpansionInitializer());
9619 if (ExpansionInitializer.isInvalid())
9620 return StmtError();
9621 } else if (S->isIterating()) {
9622 Range = TransformStmtInParentContext(S->getRangeVarStmt());
9623 if (Range.isInvalid())
9624 return StmtError();
9625 }
9626
9627 ExpansionInitializer =
9628 SemaRef.MaybeCreateExprWithCleanups(SubExpr: ExpansionInitializer);
9629
9630 LifetimeExtendTemps =
9631 SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps;
9632 }
9633
9634 CXXExpansionStmtPattern *NewPattern = nullptr;
9635 if (S->isEnumerating()) {
9636 StmtResult ExpansionVar =
9637 getDerived().TransformStmt(S->getExpansionVarStmt());
9638 if (ExpansionVar.isInvalid())
9639 return StmtError();
9640
9641 NewPattern = CXXExpansionStmtPattern::CreateEnumerating(
9642 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9643 LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(), RParenLoc: S->getRParenLoc());
9644 } else if (S->isIterating()) {
9645 StmtResult Begin = TransformStmtInParentContext(S->getBeginVarStmt());
9646 StmtResult Iter = TransformStmtInParentContext(S->getIterVarStmt());
9647 if (Begin.isInvalid() || Iter.isInvalid())
9648 return StmtError();
9649
9650 // The expansion variable is part of the pattern only and never ends
9651 // up in the instantiations, so keep it in the expansion statement's
9652 // DeclContext.
9653 StmtResult ExpansionVar =
9654 getDerived().TransformStmt(S->getExpansionVarStmt());
9655 if (ExpansionVar.isInvalid())
9656 return StmtError();
9657
9658 NewPattern = CXXExpansionStmtPattern::CreateIterating(
9659 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9660 Range: Range.getAs<DeclStmt>(), Begin: Begin.getAs<DeclStmt>(),
9661 Iter: Iter.getAs<DeclStmt>(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9662 RParenLoc: S->getRParenLoc());
9663
9664 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9665 RangeVar: NewPattern->getRangeVar(), Temporaries: LifetimeExtendTemps);
9666 } else if (S->isDependent()) {
9667 StmtResult ExpansionVar =
9668 getDerived().TransformStmt(S->getExpansionVarStmt());
9669 if (ExpansionVar.isInvalid())
9670 return StmtError();
9671
9672 StmtResult Res = SemaRef.BuildNonEnumeratingCXXExpansionStmtPattern(
9673 ESD: NewESD, Init, ExpansionVarStmt: ExpansionVar.getAs<DeclStmt>(),
9674 ExpansionInitializer: ExpansionInitializer.get(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9675 RParenLoc: S->getRParenLoc(), LifetimeExtendTemps);
9676
9677 if (Res.isInvalid())
9678 return StmtError();
9679
9680 NewPattern = cast<CXXExpansionStmtPattern>(Val: Res.get());
9681 } else {
9682 // The only time we instantiate an expansion statement is if its expansion
9683 // size is dependent (otherwise, we only instantiate the expansions and
9684 // leave the underlying CXXExpansionStmtPattern as-is). Since destructuring
9685 // expansion statements never have a dependent size, we should never get
9686 // here.
9687 llvm_unreachable("destructuring pattern should never be instantiated");
9688 }
9689
9690 StmtResult Body = getDerived().TransformStmt(S->getBody());
9691 if (Body.isInvalid())
9692 return StmtError();
9693
9694 return SemaRef.FinishCXXExpansionStmt(Expansion: NewPattern, Body: Body.get());
9695}
9696
9697template <typename Derived>
9698StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtInstantiation(
9699 CXXExpansionStmtInstantiation *S) {
9700 bool SubStmtChanged = false;
9701 auto TransformStmts = [&](SmallVectorImpl<Stmt *> &NewStmts,
9702 ArrayRef<Stmt *> OldStmts) {
9703 for (Stmt *OldDS : OldStmts) {
9704 StmtResult NewDS = getDerived().TransformStmt(OldDS);
9705 if (NewDS.isInvalid())
9706 return true;
9707
9708 SubStmtChanged |= NewDS.get() != OldDS;
9709 NewStmts.push_back(Elt: NewDS.get());
9710 }
9711
9712 return false;
9713 };
9714
9715 Decl *ESD =
9716 getDerived().TransformDecl(S->getParent()->getLocation(), S->getParent());
9717 if (!ESD || ESD->isInvalidDecl())
9718 return StmtError();
9719 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9720
9721 SmallVector<Stmt *> PreambleStmts;
9722 SmallVector<Stmt *> Instantiations;
9723
9724 // Apply lifetime extension to the preamble statements if this was a
9725 // destructuring expansion statement.
9726 {
9727 EnterExpressionEvaluationContext ExprEvalCtx(
9728 SemaRef, SemaRef.currentEvaluationContext().Context);
9729 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9730 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9731 if (TransformStmts(PreambleStmts, S->getPreambleStmts()))
9732 return StmtError();
9733
9734 if (S->shouldApplyLifetimeExtensionToPreamble()) {
9735 auto *VD =
9736 cast<VarDecl>(Val: cast<DeclStmt>(Val: PreambleStmts.front())->getSingleDecl());
9737 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9738 RangeVar: VD, Temporaries: SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps);
9739 }
9740 }
9741
9742 if (TransformStmts(Instantiations, S->getInstantiations()))
9743 return StmtError();
9744
9745 if (!getDerived().AlwaysRebuild() && !SubStmtChanged)
9746 return S;
9747
9748 return CXXExpansionStmtInstantiation::Create(
9749 C&: SemaRef.Context, Parent: NewESD, Instantiations, PreambleStmts,
9750 ShouldApplyLifetimeExtensionToPreamble: S->shouldApplyLifetimeExtensionToPreamble());
9751}
9752
9753template <typename Derived>
9754ExprResult TreeTransform<Derived>::TransformCXXExpansionSelectExpr(
9755 CXXExpansionSelectExpr *E) {
9756 ExprResult Range = getDerived().TransformExpr(E->getRangeExpr());
9757 ExprResult Idx = getDerived().TransformExpr(E->getIndexExpr());
9758 if (Range.isInvalid() || Idx.isInvalid())
9759 return ExprError();
9760
9761 if (!getDerived().AlwaysRebuild() && Range.get() == E->getRangeExpr() &&
9762 Idx.get() == E->getIndexExpr())
9763 return E;
9764
9765 return SemaRef.BuildCXXExpansionSelectExpr(Range: Range.getAs<InitListExpr>(),
9766 Idx: Idx.get());
9767}
9768
9769template<typename Derived>
9770StmtResult
9771TreeTransform<Derived>::TransformMSDependentExistsStmt(
9772 MSDependentExistsStmt *S) {
9773 // Transform the nested-name-specifier, if any.
9774 NestedNameSpecifierLoc QualifierLoc;
9775 if (S->getQualifierLoc()) {
9776 QualifierLoc
9777 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9778 if (!QualifierLoc)
9779 return StmtError();
9780 }
9781
9782 // Transform the declaration name.
9783 DeclarationNameInfo NameInfo = S->getNameInfo();
9784 if (NameInfo.getName()) {
9785 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9786 if (!NameInfo.getName())
9787 return StmtError();
9788 }
9789
9790 // Check whether anything changed.
9791 if (!getDerived().AlwaysRebuild() &&
9792 QualifierLoc == S->getQualifierLoc() &&
9793 NameInfo.getName() == S->getNameInfo().getName())
9794 return S;
9795
9796 // Determine whether this name exists, if we can.
9797 CXXScopeSpec SS;
9798 SS.Adopt(Other: QualifierLoc);
9799 bool Dependent = false;
9800 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9801 case IfExistsResult::Exists:
9802 if (S->isIfExists())
9803 break;
9804
9805 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9806
9807 case IfExistsResult::DoesNotExist:
9808 if (S->isIfNotExists())
9809 break;
9810
9811 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9812
9813 case IfExistsResult::Dependent:
9814 Dependent = true;
9815 break;
9816
9817 case IfExistsResult::Error:
9818 return StmtError();
9819 }
9820
9821 // We need to continue with the instantiation, so do so now.
9822 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9823 if (SubStmt.isInvalid())
9824 return StmtError();
9825
9826 // If we have resolved the name, just transform to the substatement.
9827 if (!Dependent)
9828 return SubStmt;
9829
9830 // The name is still dependent, so build a dependent expression again.
9831 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9832 S->isIfExists(),
9833 QualifierLoc,
9834 NameInfo,
9835 SubStmt.get());
9836}
9837
9838template<typename Derived>
9839ExprResult
9840TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9841 NestedNameSpecifierLoc QualifierLoc;
9842 if (E->getQualifierLoc()) {
9843 QualifierLoc
9844 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9845 if (!QualifierLoc)
9846 return ExprError();
9847 }
9848
9849 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9850 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9851 if (!PD)
9852 return ExprError();
9853
9854 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9855 if (Base.isInvalid())
9856 return ExprError();
9857
9858 return new (SemaRef.getASTContext())
9859 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9860 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9861 QualifierLoc, E->getMemberLoc());
9862}
9863
9864template <typename Derived>
9865ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9866 MSPropertySubscriptExpr *E) {
9867 auto BaseRes = getDerived().TransformExpr(E->getBase());
9868 if (BaseRes.isInvalid())
9869 return ExprError();
9870 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9871 if (IdxRes.isInvalid())
9872 return ExprError();
9873
9874 if (!getDerived().AlwaysRebuild() &&
9875 BaseRes.get() == E->getBase() &&
9876 IdxRes.get() == E->getIdx())
9877 return E;
9878
9879 return getDerived().RebuildArraySubscriptExpr(
9880 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9881}
9882
9883template <typename Derived>
9884StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9885 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9886 if (TryBlock.isInvalid())
9887 return StmtError();
9888
9889 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9890 if (Handler.isInvalid())
9891 return StmtError();
9892
9893 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9894 Handler.get() == S->getHandler())
9895 return S;
9896
9897 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9898 TryBlock.get(), Handler.get());
9899}
9900
9901template <typename Derived>
9902StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9903 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9904 if (Block.isInvalid())
9905 return StmtError();
9906
9907 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9908}
9909
9910template <typename Derived>
9911StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9912 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9913 if (FilterExpr.isInvalid())
9914 return StmtError();
9915
9916 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9917 if (Block.isInvalid())
9918 return StmtError();
9919
9920 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9921 Block.get());
9922}
9923
9924template <typename Derived>
9925StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9926 if (isa<SEHFinallyStmt>(Val: Handler))
9927 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9928 else
9929 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9930}
9931
9932template<typename Derived>
9933StmtResult
9934TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9935 return S;
9936}
9937
9938//===----------------------------------------------------------------------===//
9939// OpenMP directive transformation
9940//===----------------------------------------------------------------------===//
9941
9942template <typename Derived>
9943StmtResult
9944TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9945 // OMPCanonicalLoops are eliminated during transformation, since they will be
9946 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9947 // after transformation.
9948 return getDerived().TransformStmt(L->getLoopStmt());
9949}
9950
9951template <typename Derived>
9952StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9953 OMPExecutableDirective *D) {
9954
9955 // Transform the clauses
9956 llvm::SmallVector<OMPClause *, 16> TClauses;
9957 ArrayRef<OMPClause *> Clauses = D->clauses();
9958 TClauses.reserve(N: Clauses.size());
9959 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9960 I != E; ++I) {
9961 if (*I) {
9962 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9963 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9964 getDerived().getSema().OpenMP().EndOpenMPClause();
9965 if (Clause)
9966 TClauses.push_back(Elt: Clause);
9967 } else {
9968 TClauses.push_back(Elt: nullptr);
9969 }
9970 }
9971 StmtResult AssociatedStmt;
9972 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9973 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9974 D->getDirectiveKind(),
9975 /*CurScope=*/nullptr);
9976 StmtResult Body;
9977 {
9978 Sema::CompoundScopeRAII CompoundScope(getSema());
9979 Stmt *CS;
9980 if (D->getDirectiveKind() == OMPD_atomic ||
9981 D->getDirectiveKind() == OMPD_critical ||
9982 D->getDirectiveKind() == OMPD_section ||
9983 D->getDirectiveKind() == OMPD_master)
9984 CS = D->getAssociatedStmt();
9985 else
9986 CS = D->getRawStmt();
9987 Body = getDerived().TransformStmt(CS);
9988 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9989 getSema().getLangOpts().OpenMPIRBuilder)
9990 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9991 }
9992 AssociatedStmt =
9993 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9994 if (AssociatedStmt.isInvalid()) {
9995 return StmtError();
9996 }
9997 }
9998 if (TClauses.size() != Clauses.size()) {
9999 return StmtError();
10000 }
10001
10002 // Transform directive name for 'omp critical' directive.
10003 DeclarationNameInfo DirName;
10004 if (D->getDirectiveKind() == OMPD_critical) {
10005 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
10006 DirName = getDerived().TransformDeclarationNameInfo(DirName);
10007 }
10008 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
10009 if (D->getDirectiveKind() == OMPD_cancellation_point) {
10010 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
10011 } else if (D->getDirectiveKind() == OMPD_cancel) {
10012 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
10013 }
10014
10015 return getDerived().RebuildOMPExecutableDirective(
10016 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
10017 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
10018}
10019
10020/// This is mostly the same as above, but allows 'informational' class
10021/// directives when rebuilding the stmt. It still takes an
10022/// OMPExecutableDirective-type argument because we're reusing that as the
10023/// superclass for the 'assume' directive at present, instead of defining a
10024/// mostly-identical OMPInformationalDirective parent class.
10025template <typename Derived>
10026StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
10027 OMPExecutableDirective *D) {
10028
10029 // Transform the clauses
10030 llvm::SmallVector<OMPClause *, 16> TClauses;
10031 ArrayRef<OMPClause *> Clauses = D->clauses();
10032 TClauses.reserve(N: Clauses.size());
10033 for (OMPClause *C : Clauses) {
10034 if (C) {
10035 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
10036 OMPClause *Clause = getDerived().TransformOMPClause(C);
10037 getDerived().getSema().OpenMP().EndOpenMPClause();
10038 if (Clause)
10039 TClauses.push_back(Elt: Clause);
10040 } else {
10041 TClauses.push_back(Elt: nullptr);
10042 }
10043 }
10044 StmtResult AssociatedStmt;
10045 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
10046 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
10047 D->getDirectiveKind(),
10048 /*CurScope=*/nullptr);
10049 StmtResult Body;
10050 {
10051 Sema::CompoundScopeRAII CompoundScope(getSema());
10052 assert(D->getDirectiveKind() == OMPD_assume &&
10053 "Unexpected informational directive");
10054 Stmt *CS = D->getAssociatedStmt();
10055 Body = getDerived().TransformStmt(CS);
10056 }
10057 AssociatedStmt =
10058 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
10059 if (AssociatedStmt.isInvalid())
10060 return StmtError();
10061 }
10062 if (TClauses.size() != Clauses.size())
10063 return StmtError();
10064
10065 DeclarationNameInfo DirName;
10066
10067 return getDerived().RebuildOMPInformationalDirective(
10068 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
10069 D->getBeginLoc(), D->getEndLoc());
10070}
10071
10072template <typename Derived>
10073StmtResult
10074TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
10075 // TODO: Fix This
10076 llvm::omp::Version OMPVersion =
10077 getDerived().getSema().getLangOpts().getOpenMPVersion();
10078 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
10079 << getOpenMPDirectiveName(D: D->getDirectiveKind(), V: OMPVersion);
10080 return StmtError();
10081}
10082
10083template <typename Derived>
10084StmtResult
10085TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
10086 DeclarationNameInfo DirName;
10087 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10088 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
10089 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10090 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10091 return Res;
10092}
10093
10094template <typename Derived>
10095StmtResult
10096TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
10097 DeclarationNameInfo DirName;
10098 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10099 OMPD_simd, DirName, nullptr, D->getBeginLoc());
10100 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10101 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10102 return Res;
10103}
10104
10105template <typename Derived>
10106StmtResult
10107TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
10108 DeclarationNameInfo DirName;
10109 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10110 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10111 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10112 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10113 return Res;
10114}
10115
10116template <typename Derived>
10117StmtResult
10118TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
10119 DeclarationNameInfo DirName;
10120 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10121 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10122 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10123 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10124 return Res;
10125}
10126
10127template <typename Derived>
10128StmtResult
10129TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
10130 DeclarationNameInfo DirName;
10131 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10132 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10133 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10134 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10135 return Res;
10136}
10137
10138template <typename Derived>
10139StmtResult
10140TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
10141 DeclarationNameInfo DirName;
10142 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10143 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10144 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10145 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10146 return Res;
10147}
10148
10149template <typename Derived>
10150StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
10151 OMPInterchangeDirective *D) {
10152 DeclarationNameInfo DirName;
10153 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10154 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10155 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10156 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10157 return Res;
10158}
10159
10160template <typename Derived>
10161StmtResult
10162TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) {
10163 DeclarationNameInfo DirName;
10164 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10165 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10166 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10167 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10168 return Res;
10169}
10170
10171template <typename Derived>
10172StmtResult
10173TreeTransform<Derived>::TransformOMPFlattenDirective(OMPFlattenDirective *D) {
10174 DeclarationNameInfo DirName;
10175 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10176 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10177 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10178 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10179 return Res;
10180}
10181
10182template <typename Derived>
10183StmtResult
10184TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
10185 DeclarationNameInfo DirName;
10186 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10187 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10188 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10189 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10190 return Res;
10191}
10192
10193template <typename Derived>
10194StmtResult
10195TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
10196 DeclarationNameInfo DirName;
10197 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10198 OMPD_for, DirName, nullptr, D->getBeginLoc());
10199 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10200 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10201 return Res;
10202}
10203
10204template <typename Derived>
10205StmtResult
10206TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
10207 DeclarationNameInfo DirName;
10208 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10209 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
10210 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10211 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10212 return Res;
10213}
10214
10215template <typename Derived>
10216StmtResult
10217TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
10218 DeclarationNameInfo DirName;
10219 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10220 OMPD_sections, DirName, nullptr, D->getBeginLoc());
10221 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10222 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10223 return Res;
10224}
10225
10226template <typename Derived>
10227StmtResult
10228TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
10229 DeclarationNameInfo DirName;
10230 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10231 OMPD_section, DirName, nullptr, D->getBeginLoc());
10232 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10233 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10234 return Res;
10235}
10236
10237template <typename Derived>
10238StmtResult
10239TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
10240 DeclarationNameInfo DirName;
10241 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10242 OMPD_scope, DirName, nullptr, D->getBeginLoc());
10243 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10244 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10245 return Res;
10246}
10247
10248template <typename Derived>
10249StmtResult
10250TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
10251 DeclarationNameInfo DirName;
10252 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10253 OMPD_single, DirName, nullptr, D->getBeginLoc());
10254 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10255 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10256 return Res;
10257}
10258
10259template <typename Derived>
10260StmtResult
10261TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
10262 DeclarationNameInfo DirName;
10263 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10264 OMPD_master, DirName, nullptr, D->getBeginLoc());
10265 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10266 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10267 return Res;
10268}
10269
10270template <typename Derived>
10271StmtResult
10272TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
10273 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10274 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
10275 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10276 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10277 return Res;
10278}
10279
10280template <typename Derived>
10281StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
10282 OMPParallelForDirective *D) {
10283 DeclarationNameInfo DirName;
10284 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10285 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
10286 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10287 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10288 return Res;
10289}
10290
10291template <typename Derived>
10292StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
10293 OMPParallelForSimdDirective *D) {
10294 DeclarationNameInfo DirName;
10295 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10296 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10297 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10298 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10299 return Res;
10300}
10301
10302template <typename Derived>
10303StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
10304 OMPParallelMasterDirective *D) {
10305 DeclarationNameInfo DirName;
10306 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10307 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
10308 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10309 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10310 return Res;
10311}
10312
10313template <typename Derived>
10314StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
10315 OMPParallelMaskedDirective *D) {
10316 DeclarationNameInfo DirName;
10317 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10318 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
10319 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10320 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10321 return Res;
10322}
10323
10324template <typename Derived>
10325StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
10326 OMPParallelSectionsDirective *D) {
10327 DeclarationNameInfo DirName;
10328 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10329 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
10330 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10331 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10332 return Res;
10333}
10334
10335template <typename Derived>
10336StmtResult
10337TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
10338 DeclarationNameInfo DirName;
10339 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10340 OMPD_task, DirName, nullptr, D->getBeginLoc());
10341 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10342 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10343 return Res;
10344}
10345
10346template <typename Derived>
10347StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
10348 OMPTaskyieldDirective *D) {
10349 DeclarationNameInfo DirName;
10350 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10351 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
10352 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10353 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10354 return Res;
10355}
10356
10357template <typename Derived>
10358StmtResult
10359TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
10360 DeclarationNameInfo DirName;
10361 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10362 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
10363 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10364 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10365 return Res;
10366}
10367
10368template <typename Derived>
10369StmtResult
10370TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
10371 DeclarationNameInfo DirName;
10372 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10373 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
10374 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10375 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10376 return Res;
10377}
10378
10379template <typename Derived>
10380StmtResult
10381TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
10382 DeclarationNameInfo DirName;
10383 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10384 OMPD_assume, DirName, nullptr, D->getBeginLoc());
10385 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
10386 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10387 return Res;
10388}
10389
10390template <typename Derived>
10391StmtResult
10392TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
10393 DeclarationNameInfo DirName;
10394 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10395 OMPD_error, DirName, nullptr, D->getBeginLoc());
10396 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10397 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10398 return Res;
10399}
10400
10401template <typename Derived>
10402StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
10403 OMPTaskgroupDirective *D) {
10404 DeclarationNameInfo DirName;
10405 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10406 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
10407 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10408 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10409 return Res;
10410}
10411
10412template <typename Derived>
10413StmtResult
10414TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
10415 DeclarationNameInfo DirName;
10416 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10417 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10418 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10419 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10420 return Res;
10421}
10422
10423template <typename Derived>
10424StmtResult
10425TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10426 DeclarationNameInfo DirName;
10427 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10428 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10429 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10430 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10431 return Res;
10432}
10433
10434template <typename Derived>
10435StmtResult
10436TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10437 DeclarationNameInfo DirName;
10438 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10439 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10440 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10441 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10442 return Res;
10443}
10444
10445template <typename Derived>
10446StmtResult TreeTransform<Derived>::TransformOMPOrderedStandaloneDirective(
10447 OMPOrderedStandaloneDirective *D) {
10448 DeclarationNameInfo DirName;
10449 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10450 OMPD_ordered_standalone, DirName, nullptr, D->getBeginLoc());
10451 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10452 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10453 return Res;
10454}
10455
10456template <typename Derived>
10457StmtResult TreeTransform<Derived>::TransformOMPOrderedBlockAssocDirective(
10458 OMPOrderedBlockAssocDirective *D) {
10459 DeclarationNameInfo DirName;
10460 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10461 OMPD_ordered_blockassoc, DirName, nullptr, D->getBeginLoc());
10462 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10463 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10464 return Res;
10465}
10466
10467template <typename Derived>
10468StmtResult
10469TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10470 DeclarationNameInfo DirName;
10471 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10472 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10473 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10474 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10475 return Res;
10476}
10477
10478template <typename Derived>
10479StmtResult
10480TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10481 DeclarationNameInfo DirName;
10482 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10483 OMPD_target, DirName, nullptr, D->getBeginLoc());
10484 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10485 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10486 return Res;
10487}
10488
10489template <typename Derived>
10490StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10491 OMPTargetDataDirective *D) {
10492 DeclarationNameInfo DirName;
10493 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10494 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10495 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10496 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10497 return Res;
10498}
10499
10500template <typename Derived>
10501StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10502 OMPTargetEnterDataDirective *D) {
10503 DeclarationNameInfo DirName;
10504 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10505 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10506 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10507 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10508 return Res;
10509}
10510
10511template <typename Derived>
10512StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10513 OMPTargetExitDataDirective *D) {
10514 DeclarationNameInfo DirName;
10515 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10516 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10517 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10518 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10519 return Res;
10520}
10521
10522template <typename Derived>
10523StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10524 OMPTargetParallelDirective *D) {
10525 DeclarationNameInfo DirName;
10526 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10527 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10528 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10529 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10530 return Res;
10531}
10532
10533template <typename Derived>
10534StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10535 OMPTargetParallelForDirective *D) {
10536 DeclarationNameInfo DirName;
10537 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10538 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10539 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10540 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10541 return Res;
10542}
10543
10544template <typename Derived>
10545StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10546 OMPTargetUpdateDirective *D) {
10547 DeclarationNameInfo DirName;
10548 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10549 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10550 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10551 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10552 return Res;
10553}
10554
10555template <typename Derived>
10556StmtResult
10557TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10558 DeclarationNameInfo DirName;
10559 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10560 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10561 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10562 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10563 return Res;
10564}
10565
10566template <typename Derived>
10567StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10568 OMPCancellationPointDirective *D) {
10569 DeclarationNameInfo DirName;
10570 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10571 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10572 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10573 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10574 return Res;
10575}
10576
10577template <typename Derived>
10578StmtResult
10579TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10580 DeclarationNameInfo DirName;
10581 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10582 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10583 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10584 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10585 return Res;
10586}
10587
10588template <typename Derived>
10589StmtResult
10590TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10591 DeclarationNameInfo DirName;
10592 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10593 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10594 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10595 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10596 return Res;
10597}
10598
10599template <typename Derived>
10600StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10601 OMPTaskLoopSimdDirective *D) {
10602 DeclarationNameInfo DirName;
10603 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10604 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10605 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10606 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10607 return Res;
10608}
10609
10610template <typename Derived>
10611StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10612 OMPMasterTaskLoopDirective *D) {
10613 DeclarationNameInfo DirName;
10614 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10615 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10616 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10617 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10618 return Res;
10619}
10620
10621template <typename Derived>
10622StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10623 OMPMaskedTaskLoopDirective *D) {
10624 DeclarationNameInfo DirName;
10625 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10626 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10627 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10628 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10629 return Res;
10630}
10631
10632template <typename Derived>
10633StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10634 OMPMasterTaskLoopSimdDirective *D) {
10635 DeclarationNameInfo DirName;
10636 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10637 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10638 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10639 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10640 return Res;
10641}
10642
10643template <typename Derived>
10644StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10645 OMPMaskedTaskLoopSimdDirective *D) {
10646 DeclarationNameInfo DirName;
10647 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10648 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10649 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10650 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10651 return Res;
10652}
10653
10654template <typename Derived>
10655StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10656 OMPParallelMasterTaskLoopDirective *D) {
10657 DeclarationNameInfo DirName;
10658 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10659 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10660 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10661 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10662 return Res;
10663}
10664
10665template <typename Derived>
10666StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10667 OMPParallelMaskedTaskLoopDirective *D) {
10668 DeclarationNameInfo DirName;
10669 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10670 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10671 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10672 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10673 return Res;
10674}
10675
10676template <typename Derived>
10677StmtResult
10678TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10679 OMPParallelMasterTaskLoopSimdDirective *D) {
10680 DeclarationNameInfo DirName;
10681 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10682 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10683 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10684 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10685 return Res;
10686}
10687
10688template <typename Derived>
10689StmtResult
10690TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10691 OMPParallelMaskedTaskLoopSimdDirective *D) {
10692 DeclarationNameInfo DirName;
10693 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10694 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10695 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10696 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10697 return Res;
10698}
10699
10700template <typename Derived>
10701StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10702 OMPDistributeDirective *D) {
10703 DeclarationNameInfo DirName;
10704 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10705 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10706 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10707 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10708 return Res;
10709}
10710
10711template <typename Derived>
10712StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10713 OMPDistributeParallelForDirective *D) {
10714 DeclarationNameInfo DirName;
10715 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10716 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10717 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10718 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10719 return Res;
10720}
10721
10722template <typename Derived>
10723StmtResult
10724TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10725 OMPDistributeParallelForSimdDirective *D) {
10726 DeclarationNameInfo DirName;
10727 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10728 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10729 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10730 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10731 return Res;
10732}
10733
10734template <typename Derived>
10735StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10736 OMPDistributeSimdDirective *D) {
10737 DeclarationNameInfo DirName;
10738 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10739 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10740 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10741 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10742 return Res;
10743}
10744
10745template <typename Derived>
10746StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10747 OMPTargetParallelForSimdDirective *D) {
10748 DeclarationNameInfo DirName;
10749 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10750 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10751 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10752 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10753 return Res;
10754}
10755
10756template <typename Derived>
10757StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10758 OMPTargetSimdDirective *D) {
10759 DeclarationNameInfo DirName;
10760 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10761 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10762 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10763 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10764 return Res;
10765}
10766
10767template <typename Derived>
10768StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10769 OMPTeamsDistributeDirective *D) {
10770 DeclarationNameInfo DirName;
10771 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10772 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10773 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10774 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10775 return Res;
10776}
10777
10778template <typename Derived>
10779StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10780 OMPTeamsDistributeSimdDirective *D) {
10781 DeclarationNameInfo DirName;
10782 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10783 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10784 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10785 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10786 return Res;
10787}
10788
10789template <typename Derived>
10790StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10791 OMPTeamsDistributeParallelForSimdDirective *D) {
10792 DeclarationNameInfo DirName;
10793 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10794 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10795 D->getBeginLoc());
10796 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10797 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10798 return Res;
10799}
10800
10801template <typename Derived>
10802StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10803 OMPTeamsDistributeParallelForDirective *D) {
10804 DeclarationNameInfo DirName;
10805 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10806 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10807 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10808 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10809 return Res;
10810}
10811
10812template <typename Derived>
10813StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10814 OMPTargetTeamsDirective *D) {
10815 DeclarationNameInfo DirName;
10816 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10817 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10818 auto Res = getDerived().TransformOMPExecutableDirective(D);
10819 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10820 return Res;
10821}
10822
10823template <typename Derived>
10824StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10825 OMPTargetTeamsDistributeDirective *D) {
10826 DeclarationNameInfo DirName;
10827 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10828 OMPD_target_teams_distribute, DirName, nullptr, 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>::TransformOMPTargetTeamsDistributeParallelForDirective(
10837 OMPTargetTeamsDistributeParallelForDirective *D) {
10838 DeclarationNameInfo DirName;
10839 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10840 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10841 D->getBeginLoc());
10842 auto Res = getDerived().TransformOMPExecutableDirective(D);
10843 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10844 return Res;
10845}
10846
10847template <typename Derived>
10848StmtResult TreeTransform<Derived>::
10849 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10850 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10851 DeclarationNameInfo DirName;
10852 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10853 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10854 D->getBeginLoc());
10855 auto Res = getDerived().TransformOMPExecutableDirective(D);
10856 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10857 return Res;
10858}
10859
10860template <typename Derived>
10861StmtResult
10862TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10863 OMPTargetTeamsDistributeSimdDirective *D) {
10864 DeclarationNameInfo DirName;
10865 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10866 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10867 auto Res = getDerived().TransformOMPExecutableDirective(D);
10868 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10869 return Res;
10870}
10871
10872template <typename Derived>
10873StmtResult
10874TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10875 DeclarationNameInfo DirName;
10876 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10877 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10878 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10879 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10880 return Res;
10881}
10882
10883template <typename Derived>
10884StmtResult
10885TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10886 DeclarationNameInfo DirName;
10887 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10888 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10889 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10890 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10891 return Res;
10892}
10893
10894template <typename Derived>
10895StmtResult
10896TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10897 DeclarationNameInfo DirName;
10898 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10899 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10900 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10901 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10902 return Res;
10903}
10904
10905template <typename Derived>
10906StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10907 OMPGenericLoopDirective *D) {
10908 DeclarationNameInfo DirName;
10909 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10910 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10911 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10912 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10913 return Res;
10914}
10915
10916template <typename Derived>
10917StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10918 OMPTeamsGenericLoopDirective *D) {
10919 DeclarationNameInfo DirName;
10920 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10921 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10922 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10923 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10924 return Res;
10925}
10926
10927template <typename Derived>
10928StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10929 OMPTargetTeamsGenericLoopDirective *D) {
10930 DeclarationNameInfo DirName;
10931 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10932 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10933 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10934 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10935 return Res;
10936}
10937
10938template <typename Derived>
10939StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10940 OMPParallelGenericLoopDirective *D) {
10941 DeclarationNameInfo DirName;
10942 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10943 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10944 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10945 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10946 return Res;
10947}
10948
10949template <typename Derived>
10950StmtResult
10951TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10952 OMPTargetParallelGenericLoopDirective *D) {
10953 DeclarationNameInfo DirName;
10954 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10955 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10956 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10957 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10958 return Res;
10959}
10960
10961//===----------------------------------------------------------------------===//
10962// OpenMP clause transformation
10963//===----------------------------------------------------------------------===//
10964template <typename Derived>
10965OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10966 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10967 if (Cond.isInvalid())
10968 return nullptr;
10969 return getDerived().RebuildOMPIfClause(
10970 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10971 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10972}
10973
10974template <typename Derived>
10975OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10976 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10977 if (Cond.isInvalid())
10978 return nullptr;
10979 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10980 C->getLParenLoc(), C->getEndLoc());
10981}
10982
10983template <typename Derived>
10984OMPClause *
10985TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10986 llvm::SmallVector<Expr *, 3> Vars;
10987 Vars.reserve(N: C->varlist_size());
10988 for (auto *VE : C->varlist()) {
10989 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10990 if (EVar.isInvalid())
10991 return nullptr;
10992 Vars.push_back(Elt: EVar.get());
10993 }
10994 Expr *DimsModifierExpr = C->getDimsModifierExpr();
10995 if (DimsModifierExpr) {
10996 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: DimsModifierExpr));
10997 if (EVar.isInvalid())
10998 return nullptr;
10999 DimsModifierExpr = EVar.get();
11000 }
11001 return getDerived().RebuildOMPNumThreadsClause(
11002 Vars, C->getPrescriptivenessModifier(),
11003 C->getPrescriptivenessModifierLoc(), C->getDimsModifier(),
11004 DimsModifierExpr, C->getDimsModifierLoc(), C->getBeginLoc(),
11005 C->getLParenLoc(), C->getEndLoc());
11006}
11007
11008template <typename Derived>
11009OMPClause *
11010TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
11011 ExprResult E = getDerived().TransformExpr(C->getSafelen());
11012 if (E.isInvalid())
11013 return nullptr;
11014 return getDerived().RebuildOMPSafelenClause(
11015 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11016}
11017
11018template <typename Derived>
11019OMPClause *
11020TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
11021 ExprResult E = getDerived().TransformExpr(C->getAllocator());
11022 if (E.isInvalid())
11023 return nullptr;
11024 return getDerived().RebuildOMPAllocatorClause(
11025 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11026}
11027
11028template <typename Derived>
11029OMPClause *
11030TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
11031 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
11032 if (E.isInvalid())
11033 return nullptr;
11034 return getDerived().RebuildOMPSimdlenClause(
11035 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11036}
11037
11038template <typename Derived>
11039OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
11040 SmallVector<Expr *, 4> TransformedSizes;
11041 TransformedSizes.reserve(N: C->getNumSizes());
11042 bool Changed = false;
11043 for (Expr *E : C->getSizesRefs()) {
11044 if (!E) {
11045 TransformedSizes.push_back(Elt: nullptr);
11046 continue;
11047 }
11048
11049 ExprResult T = getDerived().TransformExpr(E);
11050 if (T.isInvalid())
11051 return nullptr;
11052 if (E != T.get())
11053 Changed = true;
11054 TransformedSizes.push_back(Elt: T.get());
11055 }
11056
11057 if (!Changed && !getDerived().AlwaysRebuild())
11058 return C;
11059 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
11060 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11061}
11062
11063template <typename Derived>
11064OMPClause *
11065TreeTransform<Derived>::TransformOMPCountsClause(OMPCountsClause *C) {
11066 SmallVector<Expr *, 4> TransformedCounts;
11067 TransformedCounts.reserve(N: C->getNumCounts());
11068 for (Expr *E : C->getCountsRefs()) {
11069 if (!E) {
11070 TransformedCounts.push_back(Elt: nullptr);
11071 continue;
11072 }
11073
11074 ExprResult T = getDerived().TransformExpr(E);
11075 if (T.isInvalid())
11076 return nullptr;
11077 TransformedCounts.push_back(Elt: T.get());
11078 }
11079
11080 return RebuildOMPCountsClause(Counts: TransformedCounts, StartLoc: C->getBeginLoc(),
11081 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc(),
11082 FillIdx: C->getOmpFillIndex(), FillLoc: C->getOmpFillLoc());
11083}
11084
11085template <typename Derived>
11086OMPClause *
11087TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
11088 SmallVector<Expr *> TransformedArgs;
11089 TransformedArgs.reserve(N: C->getNumLoops());
11090 bool Changed = false;
11091 for (Expr *E : C->getArgsRefs()) {
11092 if (!E) {
11093 TransformedArgs.push_back(Elt: nullptr);
11094 continue;
11095 }
11096
11097 ExprResult T = getDerived().TransformExpr(E);
11098 if (T.isInvalid())
11099 return nullptr;
11100 if (E != T.get())
11101 Changed = true;
11102 TransformedArgs.push_back(Elt: T.get());
11103 }
11104
11105 if (!Changed && !getDerived().AlwaysRebuild())
11106 return C;
11107 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
11108 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11109}
11110
11111template <typename Derived>
11112OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
11113 if (!getDerived().AlwaysRebuild())
11114 return C;
11115 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
11116}
11117
11118template <typename Derived>
11119OMPClause *
11120TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
11121 ExprResult T = getDerived().TransformExpr(C->getFactor());
11122 if (T.isInvalid())
11123 return nullptr;
11124 Expr *Factor = T.get();
11125 bool Changed = Factor != C->getFactor();
11126
11127 if (!Changed && !getDerived().AlwaysRebuild())
11128 return C;
11129 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
11130 EndLoc: C->getEndLoc());
11131}
11132
11133template <typename Derived>
11134OMPClause *TreeTransform<Derived>::TransformOMPDepthClause(OMPDepthClause *C) {
11135 ExprResult T = getDerived().TransformExpr(C->getDepth());
11136 if (T.isInvalid())
11137 return nullptr;
11138 Expr *Depth = T.get();
11139 bool Changed = Depth != C->getDepth();
11140
11141 if (!Changed && !getDerived().AlwaysRebuild())
11142 return C;
11143 return RebuildOMPDepthClause(Depth, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
11144 EndLoc: C->getEndLoc());
11145}
11146
11147template <typename Derived>
11148OMPClause *
11149TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
11150 ExprResult F = getDerived().TransformExpr(C->getFirst());
11151 if (F.isInvalid())
11152 return nullptr;
11153
11154 ExprResult Cn = getDerived().TransformExpr(C->getCount());
11155 if (Cn.isInvalid())
11156 return nullptr;
11157
11158 Expr *First = F.get();
11159 Expr *Count = Cn.get();
11160
11161 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
11162
11163 // If no changes and AlwaysRebuild() is false, return the original clause
11164 if (!Changed && !getDerived().AlwaysRebuild())
11165 return C;
11166
11167 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
11168 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
11169 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
11170}
11171
11172template <typename Derived>
11173OMPClause *
11174TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
11175 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
11176 if (E.isInvalid())
11177 return nullptr;
11178 return getDerived().RebuildOMPCollapseClause(
11179 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11180}
11181
11182template <typename Derived>
11183OMPClause *
11184TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
11185 return getDerived().RebuildOMPDefaultClause(
11186 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
11187 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
11188 C->getEndLoc());
11189}
11190
11191template <typename Derived>
11192OMPClause *
11193TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
11194 // No need to rebuild this clause, no template-dependent parameters.
11195 return C;
11196}
11197
11198template <typename Derived>
11199OMPClause *
11200TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
11201 Expr *Impex = C->getImpexType();
11202 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
11203
11204 if (TransformedImpex.isInvalid())
11205 return nullptr;
11206
11207 return getDerived().RebuildOMPTransparentClause(
11208 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
11209 C->getEndLoc());
11210}
11211
11212template <typename Derived>
11213OMPClause *
11214TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
11215 return getDerived().RebuildOMPProcBindClause(
11216 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
11217 C->getLParenLoc(), C->getEndLoc());
11218}
11219
11220template <typename Derived>
11221OMPClause *
11222TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
11223 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11224 if (E.isInvalid())
11225 return nullptr;
11226 return getDerived().RebuildOMPScheduleClause(
11227 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
11228 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11229 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
11230 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11231}
11232
11233template <typename Derived>
11234OMPClause *
11235TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
11236 ExprResult E;
11237 if (auto *Num = C->getNumForLoops()) {
11238 E = getDerived().TransformExpr(Num);
11239 if (E.isInvalid())
11240 return nullptr;
11241 }
11242 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
11243 C->getLParenLoc(), E.get());
11244}
11245
11246template <typename Derived>
11247OMPClause *
11248TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
11249 ExprResult E;
11250 if (Expr *Evt = C->getEventHandler()) {
11251 E = getDerived().TransformExpr(Evt);
11252 if (E.isInvalid())
11253 return nullptr;
11254 }
11255 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
11256 C->getLParenLoc(), C->getEndLoc());
11257}
11258
11259template <typename Derived>
11260OMPClause *
11261TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
11262 ExprResult Cond;
11263 if (auto *Condition = C->getCondition()) {
11264 Cond = getDerived().TransformExpr(Condition);
11265 if (Cond.isInvalid())
11266 return nullptr;
11267 }
11268 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
11269 C->getLParenLoc(), C->getEndLoc());
11270}
11271
11272template <typename Derived>
11273OMPClause *
11274TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
11275 // No need to rebuild this clause, no template-dependent parameters.
11276 return C;
11277}
11278
11279template <typename Derived>
11280OMPClause *
11281TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
11282 // No need to rebuild this clause, no template-dependent parameters.
11283 return C;
11284}
11285
11286template <typename Derived>
11287OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
11288 // No need to rebuild this clause, no template-dependent parameters.
11289 return C;
11290}
11291
11292template <typename Derived>
11293OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
11294 // No need to rebuild this clause, no template-dependent parameters.
11295 return C;
11296}
11297
11298template <typename Derived>
11299OMPClause *
11300TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
11301 // No need to rebuild this clause, no template-dependent parameters.
11302 return C;
11303}
11304
11305template <typename Derived>
11306OMPClause *TreeTransform<Derived>::TransformOMPUpdateDependObjectsClause(
11307 OMPUpdateDependObjectsClause *C) {
11308 // No need to rebuild this clause, no template-dependent parameters.
11309 return C;
11310}
11311
11312template <typename Derived>
11313OMPClause *
11314TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
11315 // No need to rebuild this clause, no template-dependent parameters.
11316 return C;
11317}
11318
11319template <typename Derived>
11320OMPClause *
11321TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
11322 // No need to rebuild this clause, no template-dependent parameters.
11323 return C;
11324}
11325
11326template <typename Derived>
11327OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
11328 // No need to rebuild this clause, no template-dependent parameters.
11329 return C;
11330}
11331
11332template <typename Derived>
11333OMPClause *
11334TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
11335 return C;
11336}
11337
11338template <typename Derived>
11339OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
11340 ExprResult E = getDerived().TransformExpr(C->getExpr());
11341 if (E.isInvalid())
11342 return nullptr;
11343 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
11344 C->getLParenLoc(), C->getEndLoc());
11345}
11346
11347template <typename Derived>
11348OMPClause *
11349TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
11350 return C;
11351}
11352
11353template <typename Derived>
11354OMPClause *
11355TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
11356 return C;
11357}
11358template <typename Derived>
11359OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
11360 OMPNoOpenMPRoutinesClause *C) {
11361 return C;
11362}
11363template <typename Derived>
11364OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
11365 OMPNoOpenMPConstructsClause *C) {
11366 return C;
11367}
11368template <typename Derived>
11369OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
11370 OMPNoParallelismClause *C) {
11371 return C;
11372}
11373
11374template <typename Derived>
11375OMPClause *
11376TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
11377 // No need to rebuild this clause, no template-dependent parameters.
11378 return C;
11379}
11380
11381template <typename Derived>
11382OMPClause *
11383TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
11384 // No need to rebuild this clause, no template-dependent parameters.
11385 return C;
11386}
11387
11388template <typename Derived>
11389OMPClause *
11390TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
11391 // No need to rebuild this clause, no template-dependent parameters.
11392 return C;
11393}
11394
11395template <typename Derived>
11396OMPClause *
11397TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
11398 // No need to rebuild this clause, no template-dependent parameters.
11399 return C;
11400}
11401
11402template <typename Derived>
11403OMPClause *
11404TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
11405 // No need to rebuild this clause, no template-dependent parameters.
11406 return C;
11407}
11408
11409template <typename Derived>
11410OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
11411 // No need to rebuild this clause, no template-dependent parameters.
11412 return C;
11413}
11414
11415template <typename Derived>
11416OMPClause *
11417TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
11418 // No need to rebuild this clause, no template-dependent parameters.
11419 return C;
11420}
11421
11422template <typename Derived>
11423OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
11424 // No need to rebuild this clause, no template-dependent parameters.
11425 return C;
11426}
11427
11428template <typename Derived>
11429OMPClause *
11430TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
11431 // No need to rebuild this clause, no template-dependent parameters.
11432 return C;
11433}
11434
11435template <typename Derived>
11436OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
11437 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
11438 if (IVR.isInvalid())
11439 return nullptr;
11440
11441 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
11442 for (OMPInitClause::PrefView P : C->prefs()) {
11443 Expr *NewFr = nullptr;
11444 if (P.Fr) {
11445 ExprResult ER = getDerived().TransformExpr(P.Fr);
11446 if (ER.isInvalid())
11447 return nullptr;
11448 NewFr = ER.get();
11449 }
11450 SmallVector<Expr *, 2> NewAttrs;
11451 NewAttrs.reserve(N: P.Attrs.size());
11452 for (Expr *A : P.Attrs) {
11453 ExprResult ER = getDerived().TransformExpr(A);
11454 if (ER.isInvalid())
11455 return nullptr;
11456 NewAttrs.push_back(Elt: ER.get());
11457 }
11458 InteropInfo.Prefs.emplace_back(Args&: NewFr, Args: std::move(NewAttrs));
11459 }
11460 InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
11461 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
11462 C->getBeginLoc(), C->getLParenLoc(),
11463 C->getVarLoc(), C->getEndLoc());
11464}
11465
11466template <typename Derived>
11467OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
11468 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
11469 if (ER.isInvalid())
11470 return nullptr;
11471 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
11472 C->getLParenLoc(), C->getVarLoc(),
11473 C->getEndLoc());
11474}
11475
11476template <typename Derived>
11477OMPClause *
11478TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
11479 ExprResult ER;
11480 if (Expr *IV = C->getInteropVar()) {
11481 ER = getDerived().TransformExpr(IV);
11482 if (ER.isInvalid())
11483 return nullptr;
11484 }
11485 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
11486 C->getLParenLoc(), C->getVarLoc(),
11487 C->getEndLoc());
11488}
11489
11490template <typename Derived>
11491OMPClause *
11492TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
11493 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11494 if (Cond.isInvalid())
11495 return nullptr;
11496 return getDerived().RebuildOMPNovariantsClause(
11497 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11498}
11499
11500template <typename Derived>
11501OMPClause *
11502TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11503 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11504 if (Cond.isInvalid())
11505 return nullptr;
11506 return getDerived().RebuildOMPNocontextClause(
11507 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11508}
11509
11510template <typename Derived>
11511OMPClause *
11512TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11513 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11514 if (ThreadID.isInvalid())
11515 return nullptr;
11516 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11517 C->getLParenLoc(), C->getEndLoc());
11518}
11519
11520template <typename Derived>
11521OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11522 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11523 if (E.isInvalid())
11524 return nullptr;
11525 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11526 C->getLParenLoc(), C->getEndLoc());
11527}
11528
11529template <typename Derived>
11530OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11531 OMPUnifiedAddressClause *C) {
11532 llvm_unreachable("unified_address clause cannot appear in dependent context");
11533}
11534
11535template <typename Derived>
11536OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11537 OMPUnifiedSharedMemoryClause *C) {
11538 llvm_unreachable(
11539 "unified_shared_memory clause cannot appear in dependent context");
11540}
11541
11542template <typename Derived>
11543OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11544 OMPReverseOffloadClause *C) {
11545 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11546}
11547
11548template <typename Derived>
11549OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11550 OMPDynamicAllocatorsClause *C) {
11551 llvm_unreachable(
11552 "dynamic_allocators clause cannot appear in dependent context");
11553}
11554
11555template <typename Derived>
11556OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11557 OMPAtomicDefaultMemOrderClause *C) {
11558 llvm_unreachable(
11559 "atomic_default_mem_order clause cannot appear in dependent context");
11560}
11561
11562template <typename Derived>
11563OMPClause *
11564TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11565 llvm_unreachable("self_maps clause cannot appear in dependent context");
11566}
11567
11568template <typename Derived>
11569OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11570 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11571 C->getBeginLoc(), C->getLParenLoc(),
11572 C->getEndLoc());
11573}
11574
11575template <typename Derived>
11576OMPClause *
11577TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11578 return getDerived().RebuildOMPSeverityClause(
11579 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11580 C->getLParenLoc(), C->getEndLoc());
11581}
11582
11583template <typename Derived>
11584OMPClause *
11585TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11586 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11587 if (E.isInvalid())
11588 return nullptr;
11589 return getDerived().RebuildOMPMessageClause(
11590 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11591}
11592
11593template <typename Derived>
11594OMPClause *
11595TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11596 llvm::SmallVector<Expr *, 16> Vars;
11597 Vars.reserve(N: C->varlist_size());
11598 for (auto *VE : C->varlist()) {
11599 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11600 if (EVar.isInvalid())
11601 return nullptr;
11602 Vars.push_back(Elt: EVar.get());
11603 }
11604 return getDerived().RebuildOMPPrivateClause(
11605 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11606}
11607
11608template <typename Derived>
11609OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11610 OMPFirstprivateClause *C) {
11611 llvm::SmallVector<Expr *, 16> Vars;
11612 Vars.reserve(N: C->varlist_size());
11613 for (auto *VE : C->varlist()) {
11614 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11615 if (EVar.isInvalid())
11616 return nullptr;
11617 Vars.push_back(Elt: EVar.get());
11618 }
11619 return getDerived().RebuildOMPFirstprivateClause(
11620 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11621}
11622
11623template <typename Derived>
11624OMPClause *
11625TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11626 llvm::SmallVector<Expr *, 16> Vars;
11627 Vars.reserve(N: C->varlist_size());
11628 for (auto *VE : C->varlist()) {
11629 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11630 if (EVar.isInvalid())
11631 return nullptr;
11632 Vars.push_back(Elt: EVar.get());
11633 }
11634 return getDerived().RebuildOMPLastprivateClause(
11635 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11636 C->getLParenLoc(), C->getEndLoc());
11637}
11638
11639template <typename Derived>
11640OMPClause *
11641TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11642 llvm::SmallVector<Expr *, 16> Vars;
11643 Vars.reserve(N: C->varlist_size());
11644 for (auto *VE : C->varlist()) {
11645 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11646 if (EVar.isInvalid())
11647 return nullptr;
11648 Vars.push_back(Elt: EVar.get());
11649 }
11650 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11651 C->getLParenLoc(), C->getEndLoc());
11652}
11653
11654template <typename Derived>
11655OMPClause *
11656TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11657 llvm::SmallVector<Expr *, 16> Vars;
11658 Vars.reserve(N: C->varlist_size());
11659 for (auto *VE : C->varlist()) {
11660 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11661 if (EVar.isInvalid())
11662 return nullptr;
11663 Vars.push_back(Elt: EVar.get());
11664 }
11665 CXXScopeSpec ReductionIdScopeSpec;
11666 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11667
11668 DeclarationNameInfo NameInfo = C->getNameInfo();
11669 if (NameInfo.getName()) {
11670 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11671 if (!NameInfo.getName())
11672 return nullptr;
11673 }
11674 // Build a list of all UDR decls with the same names ranged by the Scopes.
11675 // The Scope boundary is a duplication of the previous decl.
11676 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11677 for (auto *E : C->reduction_ops()) {
11678 // Transform all the decls.
11679 if (E) {
11680 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11681 UnresolvedSet<8> Decls;
11682 for (auto *D : ULE->decls()) {
11683 NamedDecl *InstD =
11684 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11685 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11686 }
11687 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11688 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11689 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11690 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11691 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11692 } else
11693 UnresolvedReductions.push_back(Elt: nullptr);
11694 }
11695 return getDerived().RebuildOMPReductionClause(
11696 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11697 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11698 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11699}
11700
11701template <typename Derived>
11702OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11703 OMPTaskReductionClause *C) {
11704 llvm::SmallVector<Expr *, 16> Vars;
11705 Vars.reserve(N: C->varlist_size());
11706 for (auto *VE : C->varlist()) {
11707 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11708 if (EVar.isInvalid())
11709 return nullptr;
11710 Vars.push_back(Elt: EVar.get());
11711 }
11712 CXXScopeSpec ReductionIdScopeSpec;
11713 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11714
11715 DeclarationNameInfo NameInfo = C->getNameInfo();
11716 if (NameInfo.getName()) {
11717 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11718 if (!NameInfo.getName())
11719 return nullptr;
11720 }
11721 // Build a list of all UDR decls with the same names ranged by the Scopes.
11722 // The Scope boundary is a duplication of the previous decl.
11723 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11724 for (auto *E : C->reduction_ops()) {
11725 // Transform all the decls.
11726 if (E) {
11727 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11728 UnresolvedSet<8> Decls;
11729 for (auto *D : ULE->decls()) {
11730 NamedDecl *InstD =
11731 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11732 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11733 }
11734 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11735 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11736 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11737 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11738 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11739 } else
11740 UnresolvedReductions.push_back(Elt: nullptr);
11741 }
11742 return getDerived().RebuildOMPTaskReductionClause(
11743 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11744 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11745}
11746
11747template <typename Derived>
11748OMPClause *
11749TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11750 llvm::SmallVector<Expr *, 16> Vars;
11751 Vars.reserve(N: C->varlist_size());
11752 for (auto *VE : C->varlist()) {
11753 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11754 if (EVar.isInvalid())
11755 return nullptr;
11756 Vars.push_back(Elt: EVar.get());
11757 }
11758 CXXScopeSpec ReductionIdScopeSpec;
11759 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11760
11761 DeclarationNameInfo NameInfo = C->getNameInfo();
11762 if (NameInfo.getName()) {
11763 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11764 if (!NameInfo.getName())
11765 return nullptr;
11766 }
11767 // Build a list of all UDR decls with the same names ranged by the Scopes.
11768 // The Scope boundary is a duplication of the previous decl.
11769 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11770 for (auto *E : C->reduction_ops()) {
11771 // Transform all the decls.
11772 if (E) {
11773 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11774 UnresolvedSet<8> Decls;
11775 for (auto *D : ULE->decls()) {
11776 NamedDecl *InstD =
11777 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11778 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11779 }
11780 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11781 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11782 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11783 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11784 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11785 } else
11786 UnresolvedReductions.push_back(Elt: nullptr);
11787 }
11788 return getDerived().RebuildOMPInReductionClause(
11789 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11790 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11791}
11792
11793template <typename Derived>
11794OMPClause *
11795TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11796 llvm::SmallVector<Expr *, 16> Vars;
11797 Vars.reserve(N: C->varlist_size());
11798 for (auto *VE : C->varlist()) {
11799 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11800 if (EVar.isInvalid())
11801 return nullptr;
11802 Vars.push_back(Elt: EVar.get());
11803 }
11804 ExprResult Step = getDerived().TransformExpr(C->getStep());
11805 if (Step.isInvalid())
11806 return nullptr;
11807 return getDerived().RebuildOMPLinearClause(
11808 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11809 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11810 C->getEndLoc());
11811}
11812
11813template <typename Derived>
11814OMPClause *
11815TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11816 llvm::SmallVector<Expr *, 16> Vars;
11817 Vars.reserve(N: C->varlist_size());
11818 for (auto *VE : C->varlist()) {
11819 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11820 if (EVar.isInvalid())
11821 return nullptr;
11822 Vars.push_back(Elt: EVar.get());
11823 }
11824 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11825 if (Alignment.isInvalid())
11826 return nullptr;
11827 return getDerived().RebuildOMPAlignedClause(
11828 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11829 C->getColonLoc(), C->getEndLoc());
11830}
11831
11832template <typename Derived>
11833OMPClause *
11834TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11835 llvm::SmallVector<Expr *, 16> Vars;
11836 Vars.reserve(N: C->varlist_size());
11837 for (auto *VE : C->varlist()) {
11838 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11839 if (EVar.isInvalid())
11840 return nullptr;
11841 Vars.push_back(Elt: EVar.get());
11842 }
11843 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11844 C->getLParenLoc(), C->getEndLoc());
11845}
11846
11847template <typename Derived>
11848OMPClause *
11849TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11850 llvm::SmallVector<Expr *, 16> Vars;
11851 Vars.reserve(N: C->varlist_size());
11852 for (auto *VE : C->varlist()) {
11853 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11854 if (EVar.isInvalid())
11855 return nullptr;
11856 Vars.push_back(Elt: EVar.get());
11857 }
11858 return getDerived().RebuildOMPCopyprivateClause(
11859 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11860}
11861
11862template <typename Derived>
11863OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11864 llvm::SmallVector<Expr *, 16> Vars;
11865 Vars.reserve(N: C->varlist_size());
11866 for (auto *VE : C->varlist()) {
11867 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11868 if (EVar.isInvalid())
11869 return nullptr;
11870 Vars.push_back(Elt: EVar.get());
11871 }
11872 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11873 C->getLParenLoc(), C->getEndLoc());
11874}
11875
11876template <typename Derived>
11877OMPClause *
11878TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11879 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11880 if (E.isInvalid())
11881 return nullptr;
11882 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11883 C->getLParenLoc(), C->getEndLoc());
11884}
11885
11886template <typename Derived>
11887OMPClause *
11888TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11889 llvm::SmallVector<Expr *, 16> Vars;
11890 Expr *DepModifier = C->getModifier();
11891 if (DepModifier) {
11892 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11893 if (DepModRes.isInvalid())
11894 return nullptr;
11895 DepModifier = DepModRes.get();
11896 }
11897 Vars.reserve(N: C->varlist_size());
11898 for (auto *VE : C->varlist()) {
11899 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11900 if (EVar.isInvalid())
11901 return nullptr;
11902 Vars.push_back(Elt: EVar.get());
11903 }
11904 return getDerived().RebuildOMPDependClause(
11905 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11906 C->getOmpAllMemoryLoc()},
11907 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11908}
11909
11910template <typename Derived>
11911OMPClause *
11912TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11913 ExprResult E = getDerived().TransformExpr(C->getDevice());
11914 if (E.isInvalid())
11915 return nullptr;
11916 return getDerived().RebuildOMPDeviceClause(
11917 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11918 C->getModifierLoc(), C->getEndLoc());
11919}
11920
11921template <typename Derived, class T>
11922bool transformOMPMappableExprListClause(
11923 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11924 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11925 DeclarationNameInfo &MapperIdInfo,
11926 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11927 // Transform expressions in the list.
11928 Vars.reserve(N: C->varlist_size());
11929 for (auto *VE : C->varlist()) {
11930 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11931 if (EVar.isInvalid())
11932 return true;
11933 Vars.push_back(Elt: EVar.get());
11934 }
11935 // Transform mapper scope specifier and identifier.
11936 NestedNameSpecifierLoc QualifierLoc;
11937 if (C->getMapperQualifierLoc()) {
11938 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11939 C->getMapperQualifierLoc());
11940 if (!QualifierLoc)
11941 return true;
11942 }
11943 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11944 MapperIdInfo = C->getMapperIdInfo();
11945 if (MapperIdInfo.getName()) {
11946 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11947 if (!MapperIdInfo.getName())
11948 return true;
11949 }
11950 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11951 // the previous user-defined mapper lookup in dependent environment.
11952 for (auto *E : C->mapperlists()) {
11953 // Transform all the decls.
11954 if (E) {
11955 auto *ULE = cast<UnresolvedLookupExpr>(E);
11956 UnresolvedSet<8> Decls;
11957 for (auto *D : ULE->decls()) {
11958 NamedDecl *InstD =
11959 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11960 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11961 }
11962 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11963 TT.getSema().Context, /*NamingClass=*/nullptr,
11964 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11965 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11966 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11967 } else {
11968 UnresolvedMappers.push_back(Elt: nullptr);
11969 }
11970 }
11971 return false;
11972}
11973
11974template <typename Derived>
11975OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11976 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11977 llvm::SmallVector<Expr *, 16> Vars;
11978 Expr *IteratorModifier = C->getIteratorModifier();
11979 if (IteratorModifier) {
11980 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11981 if (MapModRes.isInvalid())
11982 return nullptr;
11983 IteratorModifier = MapModRes.get();
11984 }
11985 CXXScopeSpec MapperIdScopeSpec;
11986 DeclarationNameInfo MapperIdInfo;
11987 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11988 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11989 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11990 return nullptr;
11991 return getDerived().RebuildOMPMapClause(
11992 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11993 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11994 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11995}
11996
11997template <typename Derived>
11998OMPClause *
11999TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
12000 Expr *Allocator = C->getAllocator();
12001 if (Allocator) {
12002 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
12003 if (AllocatorRes.isInvalid())
12004 return nullptr;
12005 Allocator = AllocatorRes.get();
12006 }
12007 Expr *Alignment = C->getAlignment();
12008 if (Alignment) {
12009 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
12010 if (AlignmentRes.isInvalid())
12011 return nullptr;
12012 Alignment = AlignmentRes.get();
12013 }
12014 llvm::SmallVector<Expr *, 16> Vars;
12015 Vars.reserve(N: C->varlist_size());
12016 for (auto *VE : C->varlist()) {
12017 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12018 if (EVar.isInvalid())
12019 return nullptr;
12020 Vars.push_back(Elt: EVar.get());
12021 }
12022 return getDerived().RebuildOMPAllocateClause(
12023 Allocator, Alignment, C->getFirstAllocateModifier(),
12024 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
12025 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
12026 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
12027}
12028
12029template <typename Derived>
12030OMPClause *
12031TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
12032 llvm::SmallVector<Expr *, 3> Vars;
12033 Vars.reserve(N: C->varlist_size());
12034 for (auto *VE : C->varlist()) {
12035 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12036 if (EVar.isInvalid())
12037 return nullptr;
12038 Vars.push_back(Elt: EVar.get());
12039 }
12040 Expr *ModifierExpr = C->getModifierExpr();
12041 if (ModifierExpr) {
12042 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12043 if (EVar.isInvalid())
12044 return nullptr;
12045 ModifierExpr = EVar.get();
12046 }
12047 return getDerived().RebuildOMPNumTeamsClause(
12048 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12049 OMPC_NUMTEAMS_unknown, nullptr, SourceLocation(), C->getBeginLoc(),
12050 C->getLParenLoc(), C->getEndLoc());
12051}
12052
12053template <typename Derived>
12054OMPClause *
12055TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
12056 llvm::SmallVector<Expr *, 3> Vars;
12057 Vars.reserve(N: C->varlist_size());
12058 for (auto *VE : C->varlist()) {
12059 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12060 if (EVar.isInvalid())
12061 return nullptr;
12062 Vars.push_back(Elt: EVar.get());
12063 }
12064 Expr *ModifierExpr = C->getModifierExpr();
12065 if (ModifierExpr) {
12066 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12067 if (EVar.isInvalid())
12068 return nullptr;
12069 ModifierExpr = EVar.get();
12070 }
12071 return getDerived().RebuildOMPThreadLimitClause(
12072 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12073 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12074}
12075
12076template <typename Derived>
12077OMPClause *
12078TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
12079 ExprResult E = getDerived().TransformExpr(C->getPriority());
12080 if (E.isInvalid())
12081 return nullptr;
12082 return getDerived().RebuildOMPPriorityClause(
12083 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12084}
12085
12086template <typename Derived>
12087OMPClause *
12088TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
12089 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
12090 if (E.isInvalid())
12091 return nullptr;
12092 return getDerived().RebuildOMPGrainsizeClause(
12093 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12094 C->getModifierLoc(), C->getEndLoc());
12095}
12096
12097template <typename Derived>
12098OMPClause *
12099TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
12100 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
12101 if (E.isInvalid())
12102 return nullptr;
12103 return getDerived().RebuildOMPNumTasksClause(
12104 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12105 C->getModifierLoc(), C->getEndLoc());
12106}
12107
12108template <typename Derived>
12109OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
12110 ExprResult E = getDerived().TransformExpr(C->getHint());
12111 if (E.isInvalid())
12112 return nullptr;
12113 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
12114 C->getLParenLoc(), C->getEndLoc());
12115}
12116
12117template <typename Derived>
12118OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
12119 OMPDistScheduleClause *C) {
12120 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
12121 if (E.isInvalid())
12122 return nullptr;
12123 return getDerived().RebuildOMPDistScheduleClause(
12124 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12125 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
12126}
12127
12128template <typename Derived>
12129OMPClause *
12130TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
12131 // Rebuild Defaultmap Clause since we need to invoke the checking of
12132 // defaultmap(none:variable-category) after template initialization.
12133 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
12134 C->getDefaultmapKind(),
12135 C->getBeginLoc(),
12136 C->getLParenLoc(),
12137 C->getDefaultmapModifierLoc(),
12138 C->getDefaultmapKindLoc(),
12139 C->getEndLoc());
12140}
12141
12142template <typename Derived>
12143OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
12144 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12145 llvm::SmallVector<Expr *, 16> Vars;
12146 Expr *IteratorModifier = C->getIteratorModifier();
12147 if (IteratorModifier) {
12148 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12149 if (MapModRes.isInvalid())
12150 return nullptr;
12151 IteratorModifier = MapModRes.get();
12152 }
12153 CXXScopeSpec MapperIdScopeSpec;
12154 DeclarationNameInfo MapperIdInfo;
12155 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12156 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
12157 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12158 return nullptr;
12159 return getDerived().RebuildOMPToClause(
12160 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12161 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12162 UnresolvedMappers);
12163}
12164
12165template <typename Derived>
12166OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
12167 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12168 llvm::SmallVector<Expr *, 16> Vars;
12169 Expr *IteratorModifier = C->getIteratorModifier();
12170 if (IteratorModifier) {
12171 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12172 if (MapModRes.isInvalid())
12173 return nullptr;
12174 IteratorModifier = MapModRes.get();
12175 }
12176 CXXScopeSpec MapperIdScopeSpec;
12177 DeclarationNameInfo MapperIdInfo;
12178 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12179 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
12180 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12181 return nullptr;
12182 return getDerived().RebuildOMPFromClause(
12183 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12184 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12185 UnresolvedMappers);
12186}
12187
12188template <typename Derived>
12189OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
12190 OMPUseDevicePtrClause *C) {
12191 llvm::SmallVector<Expr *, 16> Vars;
12192 Vars.reserve(N: C->varlist_size());
12193 for (auto *VE : C->varlist()) {
12194 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12195 if (EVar.isInvalid())
12196 return nullptr;
12197 Vars.push_back(Elt: EVar.get());
12198 }
12199 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12200 return getDerived().RebuildOMPUseDevicePtrClause(
12201 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
12202}
12203
12204template <typename Derived>
12205OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
12206 OMPUseDeviceAddrClause *C) {
12207 llvm::SmallVector<Expr *, 16> Vars;
12208 Vars.reserve(N: C->varlist_size());
12209 for (auto *VE : C->varlist()) {
12210 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12211 if (EVar.isInvalid())
12212 return nullptr;
12213 Vars.push_back(Elt: EVar.get());
12214 }
12215 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12216 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
12217}
12218
12219template <typename Derived>
12220OMPClause *
12221TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
12222 llvm::SmallVector<Expr *, 16> Vars;
12223 Vars.reserve(N: C->varlist_size());
12224 for (auto *VE : C->varlist()) {
12225 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12226 if (EVar.isInvalid())
12227 return nullptr;
12228 Vars.push_back(Elt: EVar.get());
12229 }
12230 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12231 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
12232}
12233
12234template <typename Derived>
12235OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
12236 OMPHasDeviceAddrClause *C) {
12237 llvm::SmallVector<Expr *, 16> Vars;
12238 Vars.reserve(N: C->varlist_size());
12239 for (auto *VE : C->varlist()) {
12240 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12241 if (EVar.isInvalid())
12242 return nullptr;
12243 Vars.push_back(Elt: EVar.get());
12244 }
12245 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12246 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
12247}
12248
12249template <typename Derived>
12250OMPClause *
12251TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
12252 llvm::SmallVector<Expr *, 16> Vars;
12253 Vars.reserve(N: C->varlist_size());
12254 for (auto *VE : C->varlist()) {
12255 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12256 if (EVar.isInvalid())
12257 return nullptr;
12258 Vars.push_back(Elt: EVar.get());
12259 }
12260 return getDerived().RebuildOMPNontemporalClause(
12261 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12262}
12263
12264template <typename Derived>
12265OMPClause *
12266TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
12267 llvm::SmallVector<Expr *, 16> Vars;
12268 Vars.reserve(N: C->varlist_size());
12269 for (auto *VE : C->varlist()) {
12270 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12271 if (EVar.isInvalid())
12272 return nullptr;
12273 Vars.push_back(Elt: EVar.get());
12274 }
12275 return getDerived().RebuildOMPInclusiveClause(
12276 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12277}
12278
12279template <typename Derived>
12280OMPClause *
12281TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
12282 llvm::SmallVector<Expr *, 16> Vars;
12283 Vars.reserve(N: C->varlist_size());
12284 for (auto *VE : C->varlist()) {
12285 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12286 if (EVar.isInvalid())
12287 return nullptr;
12288 Vars.push_back(Elt: EVar.get());
12289 }
12290 return getDerived().RebuildOMPExclusiveClause(
12291 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12292}
12293
12294template <typename Derived>
12295OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
12296 OMPUsesAllocatorsClause *C) {
12297 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
12298 Data.reserve(N: C->getNumberOfAllocators());
12299 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
12300 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
12301 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
12302 if (Allocator.isInvalid())
12303 continue;
12304 ExprResult AllocatorTraits;
12305 if (Expr *AT = D.AllocatorTraits) {
12306 AllocatorTraits = getDerived().TransformExpr(AT);
12307 if (AllocatorTraits.isInvalid())
12308 continue;
12309 }
12310 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
12311 NewD.Allocator = Allocator.get();
12312 NewD.AllocatorTraits = AllocatorTraits.get();
12313 NewD.LParenLoc = D.LParenLoc;
12314 NewD.RParenLoc = D.RParenLoc;
12315 }
12316 return getDerived().RebuildOMPUsesAllocatorsClause(
12317 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12318}
12319
12320template <typename Derived>
12321OMPClause *
12322TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
12323 SmallVector<Expr *, 4> Locators;
12324 Locators.reserve(N: C->varlist_size());
12325 ExprResult ModifierRes;
12326 if (Expr *Modifier = C->getModifier()) {
12327 ModifierRes = getDerived().TransformExpr(Modifier);
12328 if (ModifierRes.isInvalid())
12329 return nullptr;
12330 }
12331 for (Expr *E : C->varlist()) {
12332 ExprResult Locator = getDerived().TransformExpr(E);
12333 if (Locator.isInvalid())
12334 continue;
12335 Locators.push_back(Elt: Locator.get());
12336 }
12337 return getDerived().RebuildOMPAffinityClause(
12338 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
12339 ModifierRes.get(), Locators);
12340}
12341
12342template <typename Derived>
12343OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
12344 return getDerived().RebuildOMPOrderClause(
12345 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
12346 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
12347}
12348
12349template <typename Derived>
12350OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
12351 return getDerived().RebuildOMPBindClause(
12352 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
12353 C->getLParenLoc(), C->getEndLoc());
12354}
12355
12356template <typename Derived>
12357OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
12358 OMPXDynCGroupMemClause *C) {
12359 ExprResult Size = getDerived().TransformExpr(C->getSize());
12360 if (Size.isInvalid())
12361 return nullptr;
12362 return getDerived().RebuildOMPXDynCGroupMemClause(
12363 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12364}
12365
12366template <typename Derived>
12367OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
12368 OMPDynGroupprivateClause *C) {
12369 ExprResult Size = getDerived().TransformExpr(C->getSize());
12370 if (Size.isInvalid())
12371 return nullptr;
12372 return getDerived().RebuildOMPDynGroupprivateClause(
12373 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
12374 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
12375 C->getDynGroupprivateModifierLoc(),
12376 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
12377}
12378
12379template <typename Derived>
12380OMPClause *
12381TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
12382 llvm::SmallVector<Expr *, 16> Vars;
12383 Vars.reserve(N: C->varlist_size());
12384 for (auto *VE : C->varlist()) {
12385 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12386 if (EVar.isInvalid())
12387 return nullptr;
12388 Vars.push_back(Elt: EVar.get());
12389 }
12390 return getDerived().RebuildOMPDoacrossClause(
12391 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
12392 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12393}
12394
12395template <typename Derived>
12396OMPClause *
12397TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
12398 SmallVector<const Attr *> NewAttrs;
12399 for (auto *A : C->getAttrs())
12400 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
12401 return getDerived().RebuildOMPXAttributeClause(
12402 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12403}
12404
12405template <typename Derived>
12406OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
12407 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
12408}
12409
12410//===----------------------------------------------------------------------===//
12411// OpenACC transformation
12412//===----------------------------------------------------------------------===//
12413namespace {
12414template <typename Derived>
12415class OpenACCClauseTransform final
12416 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
12417 TreeTransform<Derived> &Self;
12418 ArrayRef<const OpenACCClause *> ExistingClauses;
12419 SemaOpenACC::OpenACCParsedClause &ParsedClause;
12420 OpenACCClause *NewClause = nullptr;
12421
12422 ExprResult VisitVar(Expr *VarRef) {
12423 ExprResult Res = Self.TransformExpr(VarRef);
12424
12425 if (!Res.isUsable())
12426 return Res;
12427
12428 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12429 ParsedClause.getClauseKind(),
12430 Res.get());
12431
12432 return Res;
12433 }
12434
12435 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
12436 llvm::SmallVector<Expr *> InstantiatedVarList;
12437 for (Expr *CurVar : VarList) {
12438 ExprResult VarRef = VisitVar(VarRef: CurVar);
12439
12440 if (VarRef.isUsable())
12441 InstantiatedVarList.push_back(Elt: VarRef.get());
12442 }
12443
12444 return InstantiatedVarList;
12445 }
12446
12447public:
12448 OpenACCClauseTransform(TreeTransform<Derived> &Self,
12449 ArrayRef<const OpenACCClause *> ExistingClauses,
12450 SemaOpenACC::OpenACCParsedClause &PC)
12451 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
12452
12453 OpenACCClause *CreatedClause() const { return NewClause; }
12454
12455#define VISIT_CLAUSE(CLAUSE_NAME) \
12456 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
12457#include "clang/Basic/OpenACCClauses.def"
12458};
12459
12460template <typename Derived>
12461void OpenACCClauseTransform<Derived>::VisitDefaultClause(
12462 const OpenACCDefaultClause &C) {
12463 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
12464
12465 NewClause = OpenACCDefaultClause::Create(
12466 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
12467 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12468 EndLoc: ParsedClause.getEndLoc());
12469}
12470
12471template <typename Derived>
12472void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
12473 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12474 assert(Cond && "If constructed with invalid Condition");
12475 Sema::ConditionResult Res = Self.TransformCondition(
12476 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
12477
12478 if (Res.isInvalid() || !Res.get().second)
12479 return;
12480
12481 ParsedClause.setConditionDetails(Res.get().second);
12482
12483 NewClause = OpenACCIfClause::Create(
12484 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12485 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
12486 EndLoc: ParsedClause.getEndLoc());
12487}
12488
12489template <typename Derived>
12490void OpenACCClauseTransform<Derived>::VisitSelfClause(
12491 const OpenACCSelfClause &C) {
12492
12493 // If this is an 'update' 'self' clause, this is actually a var list instead.
12494 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
12495 llvm::SmallVector<Expr *> InstantiatedVarList;
12496 for (Expr *CurVar : C.getVarList()) {
12497 ExprResult Res = Self.TransformExpr(CurVar);
12498
12499 if (!Res.isUsable())
12500 continue;
12501
12502 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12503 ParsedClause.getClauseKind(),
12504 Res.get());
12505
12506 if (Res.isUsable())
12507 InstantiatedVarList.push_back(Elt: Res.get());
12508 }
12509
12510 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12511 ModKind: OpenACCModifierKind::Invalid);
12512
12513 NewClause = OpenACCSelfClause::Create(
12514 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12515 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12516 ParsedClause.getEndLoc());
12517 } else {
12518
12519 if (C.hasConditionExpr()) {
12520 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12521 Sema::ConditionResult Res =
12522 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12523 Sema::ConditionKind::Boolean);
12524
12525 if (Res.isInvalid() || !Res.get().second)
12526 return;
12527
12528 ParsedClause.setConditionDetails(Res.get().second);
12529 }
12530
12531 NewClause = OpenACCSelfClause::Create(
12532 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12533 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12534 ParsedClause.getEndLoc());
12535 }
12536}
12537
12538template <typename Derived>
12539void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12540 const OpenACCNumGangsClause &C) {
12541 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12542
12543 for (Expr *CurIntExpr : C.getIntExprs()) {
12544 ExprResult Res = Self.TransformExpr(CurIntExpr);
12545
12546 if (!Res.isUsable())
12547 return;
12548
12549 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12550 C.getClauseKind(),
12551 C.getBeginLoc(), Res.get());
12552 if (!Res.isUsable())
12553 return;
12554
12555 InstantiatedIntExprs.push_back(Elt: Res.get());
12556 }
12557
12558 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12559 NewClause = OpenACCNumGangsClause::Create(
12560 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12561 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12562 EndLoc: ParsedClause.getEndLoc());
12563}
12564
12565template <typename Derived>
12566void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12567 const OpenACCPrivateClause &C) {
12568 llvm::SmallVector<Expr *> InstantiatedVarList;
12569 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12570
12571 for (const auto [RefExpr, InitRecipe] :
12572 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12573 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12574
12575 if (VarRef.isUsable()) {
12576 InstantiatedVarList.push_back(Elt: VarRef.get());
12577
12578 // We only have to create a new one if it is dependent, and Sema won't
12579 // make one of these unless the type is non-dependent.
12580 if (InitRecipe.isSet())
12581 InitRecipes.push_back(Elt: InitRecipe);
12582 else
12583 InitRecipes.push_back(
12584 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12585 }
12586 }
12587 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12588 ModKind: OpenACCModifierKind::Invalid);
12589
12590 NewClause = OpenACCPrivateClause::Create(
12591 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12592 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12593 EndLoc: ParsedClause.getEndLoc());
12594}
12595
12596template <typename Derived>
12597void OpenACCClauseTransform<Derived>::VisitHostClause(
12598 const OpenACCHostClause &C) {
12599 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12600 OpenACCModifierKind::Invalid);
12601
12602 NewClause = OpenACCHostClause::Create(
12603 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12604 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12605 EndLoc: ParsedClause.getEndLoc());
12606}
12607
12608template <typename Derived>
12609void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12610 const OpenACCDeviceClause &C) {
12611 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12612 OpenACCModifierKind::Invalid);
12613
12614 NewClause = OpenACCDeviceClause::Create(
12615 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12616 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12617 EndLoc: ParsedClause.getEndLoc());
12618}
12619
12620template <typename Derived>
12621void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12622 const OpenACCFirstPrivateClause &C) {
12623 llvm::SmallVector<Expr *> InstantiatedVarList;
12624 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12625
12626 for (const auto [RefExpr, InitRecipe] :
12627 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12628 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12629
12630 if (VarRef.isUsable()) {
12631 InstantiatedVarList.push_back(Elt: VarRef.get());
12632
12633 // We only have to create a new one if it is dependent, and Sema won't
12634 // make one of these unless the type is non-dependent.
12635 if (InitRecipe.isSet())
12636 InitRecipes.push_back(Elt: InitRecipe);
12637 else
12638 InitRecipes.push_back(
12639 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12640 VarRef.get()));
12641 }
12642 }
12643 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12644 ModKind: OpenACCModifierKind::Invalid);
12645
12646 NewClause = OpenACCFirstPrivateClause::Create(
12647 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12648 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12649 EndLoc: ParsedClause.getEndLoc());
12650}
12651
12652template <typename Derived>
12653void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12654 const OpenACCNoCreateClause &C) {
12655 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12656 OpenACCModifierKind::Invalid);
12657
12658 NewClause = OpenACCNoCreateClause::Create(
12659 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12660 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12661 EndLoc: ParsedClause.getEndLoc());
12662}
12663
12664template <typename Derived>
12665void OpenACCClauseTransform<Derived>::VisitPresentClause(
12666 const OpenACCPresentClause &C) {
12667 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12668 OpenACCModifierKind::Invalid);
12669
12670 NewClause = OpenACCPresentClause::Create(
12671 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12672 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12673 EndLoc: ParsedClause.getEndLoc());
12674}
12675
12676template <typename Derived>
12677void OpenACCClauseTransform<Derived>::VisitCopyClause(
12678 const OpenACCCopyClause &C) {
12679 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12680 C.getModifierList());
12681
12682 NewClause = OpenACCCopyClause::Create(
12683 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12684 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12685 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12686 EndLoc: ParsedClause.getEndLoc());
12687}
12688
12689template <typename Derived>
12690void OpenACCClauseTransform<Derived>::VisitLinkClause(
12691 const OpenACCLinkClause &C) {
12692 llvm_unreachable("link clause not valid unless a decl transform");
12693}
12694
12695template <typename Derived>
12696void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12697 const OpenACCDeviceResidentClause &C) {
12698 llvm_unreachable("device_resident clause not valid unless a decl transform");
12699}
12700template <typename Derived>
12701void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12702 const OpenACCNoHostClause &C) {
12703 llvm_unreachable("nohost clause not valid unless a decl transform");
12704}
12705template <typename Derived>
12706void OpenACCClauseTransform<Derived>::VisitBindClause(
12707 const OpenACCBindClause &C) {
12708 llvm_unreachable("bind clause not valid unless a decl transform");
12709}
12710
12711template <typename Derived>
12712void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12713 const OpenACCCopyInClause &C) {
12714 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12715 C.getModifierList());
12716
12717 NewClause = OpenACCCopyInClause::Create(
12718 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12719 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12720 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12721 EndLoc: ParsedClause.getEndLoc());
12722}
12723
12724template <typename Derived>
12725void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12726 const OpenACCCopyOutClause &C) {
12727 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12728 C.getModifierList());
12729
12730 NewClause = OpenACCCopyOutClause::Create(
12731 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12732 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12733 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12734 EndLoc: ParsedClause.getEndLoc());
12735}
12736
12737template <typename Derived>
12738void OpenACCClauseTransform<Derived>::VisitCreateClause(
12739 const OpenACCCreateClause &C) {
12740 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12741 C.getModifierList());
12742
12743 NewClause = OpenACCCreateClause::Create(
12744 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12745 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12746 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12747 EndLoc: ParsedClause.getEndLoc());
12748}
12749template <typename Derived>
12750void OpenACCClauseTransform<Derived>::VisitAttachClause(
12751 const OpenACCAttachClause &C) {
12752 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12753
12754 // Ensure each var is a pointer type.
12755 llvm::erase_if(VarList, [&](Expr *E) {
12756 return Self.getSema().OpenACC().CheckVarIsPointerType(
12757 OpenACCClauseKind::Attach, E);
12758 });
12759
12760 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12761 NewClause = OpenACCAttachClause::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>::VisitDetachClause(
12769 const OpenACCDetachClause &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::Detach, E);
12776 });
12777
12778 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12779 NewClause = OpenACCDetachClause::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>::VisitDeleteClause(
12787 const OpenACCDeleteClause &C) {
12788 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12789 OpenACCModifierKind::Invalid);
12790 NewClause = OpenACCDeleteClause::Create(
12791 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12792 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12793 EndLoc: ParsedClause.getEndLoc());
12794}
12795
12796template <typename Derived>
12797void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12798 const OpenACCUseDeviceClause &C) {
12799 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12800 OpenACCModifierKind::Invalid);
12801 NewClause = OpenACCUseDeviceClause::Create(
12802 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12803 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12804 EndLoc: ParsedClause.getEndLoc());
12805}
12806
12807template <typename Derived>
12808void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12809 const OpenACCDevicePtrClause &C) {
12810 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12811
12812 // Ensure each var is a pointer type.
12813 llvm::erase_if(VarList, [&](Expr *E) {
12814 return Self.getSema().OpenACC().CheckVarIsPointerType(
12815 OpenACCClauseKind::DevicePtr, E);
12816 });
12817
12818 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12819 NewClause = OpenACCDevicePtrClause::Create(
12820 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12821 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12822 EndLoc: ParsedClause.getEndLoc());
12823}
12824
12825template <typename Derived>
12826void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12827 const OpenACCNumWorkersClause &C) {
12828 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12829 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12830
12831 ExprResult Res = Self.TransformExpr(IntExpr);
12832 if (!Res.isUsable())
12833 return;
12834
12835 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12836 C.getClauseKind(),
12837 C.getBeginLoc(), Res.get());
12838 if (!Res.isUsable())
12839 return;
12840
12841 ParsedClause.setIntExprDetails(Res.get());
12842 NewClause = OpenACCNumWorkersClause::Create(
12843 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12844 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12845 EndLoc: ParsedClause.getEndLoc());
12846}
12847
12848template <typename Derived>
12849void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12850 const OpenACCDeviceNumClause &C) {
12851 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12852 assert(IntExpr && "device_num clause constructed with invalid int expr");
12853
12854 ExprResult Res = Self.TransformExpr(IntExpr);
12855 if (!Res.isUsable())
12856 return;
12857
12858 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12859 C.getClauseKind(),
12860 C.getBeginLoc(), Res.get());
12861 if (!Res.isUsable())
12862 return;
12863
12864 ParsedClause.setIntExprDetails(Res.get());
12865 NewClause = OpenACCDeviceNumClause::Create(
12866 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12867 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12868 EndLoc: ParsedClause.getEndLoc());
12869}
12870
12871template <typename Derived>
12872void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12873 const OpenACCDefaultAsyncClause &C) {
12874 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12875 assert(IntExpr && "default_async clause constructed with invalid int expr");
12876
12877 ExprResult Res = Self.TransformExpr(IntExpr);
12878 if (!Res.isUsable())
12879 return;
12880
12881 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12882 C.getClauseKind(),
12883 C.getBeginLoc(), Res.get());
12884 if (!Res.isUsable())
12885 return;
12886
12887 ParsedClause.setIntExprDetails(Res.get());
12888 NewClause = OpenACCDefaultAsyncClause::Create(
12889 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12890 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12891 EndLoc: ParsedClause.getEndLoc());
12892}
12893
12894template <typename Derived>
12895void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12896 const OpenACCVectorLengthClause &C) {
12897 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12898 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12899
12900 ExprResult Res = Self.TransformExpr(IntExpr);
12901 if (!Res.isUsable())
12902 return;
12903
12904 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12905 C.getClauseKind(),
12906 C.getBeginLoc(), Res.get());
12907 if (!Res.isUsable())
12908 return;
12909
12910 ParsedClause.setIntExprDetails(Res.get());
12911 NewClause = OpenACCVectorLengthClause::Create(
12912 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12913 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12914 EndLoc: ParsedClause.getEndLoc());
12915}
12916
12917template <typename Derived>
12918void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12919 const OpenACCAsyncClause &C) {
12920 if (C.hasIntExpr()) {
12921 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12922 if (!Res.isUsable())
12923 return;
12924
12925 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12926 C.getClauseKind(),
12927 C.getBeginLoc(), Res.get());
12928 if (!Res.isUsable())
12929 return;
12930 ParsedClause.setIntExprDetails(Res.get());
12931 }
12932
12933 NewClause = OpenACCAsyncClause::Create(
12934 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12935 LParenLoc: ParsedClause.getLParenLoc(),
12936 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12937 : nullptr,
12938 EndLoc: ParsedClause.getEndLoc());
12939}
12940
12941template <typename Derived>
12942void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12943 const OpenACCWorkerClause &C) {
12944 if (C.hasIntExpr()) {
12945 // restrictions on this expression are all "does it exist in certain
12946 // situations" that are not possible to be dependent, so the only check we
12947 // have is that it transforms, and is an int expression.
12948 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12949 if (!Res.isUsable())
12950 return;
12951
12952 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12953 C.getClauseKind(),
12954 C.getBeginLoc(), Res.get());
12955 if (!Res.isUsable())
12956 return;
12957 ParsedClause.setIntExprDetails(Res.get());
12958 }
12959
12960 NewClause = OpenACCWorkerClause::Create(
12961 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12962 LParenLoc: ParsedClause.getLParenLoc(),
12963 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12964 : nullptr,
12965 EndLoc: ParsedClause.getEndLoc());
12966}
12967
12968template <typename Derived>
12969void OpenACCClauseTransform<Derived>::VisitVectorClause(
12970 const OpenACCVectorClause &C) {
12971 if (C.hasIntExpr()) {
12972 // restrictions on this expression are all "does it exist in certain
12973 // situations" that are not possible to be dependent, so the only check we
12974 // have is that it transforms, and is an int expression.
12975 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12976 if (!Res.isUsable())
12977 return;
12978
12979 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12980 C.getClauseKind(),
12981 C.getBeginLoc(), Res.get());
12982 if (!Res.isUsable())
12983 return;
12984 ParsedClause.setIntExprDetails(Res.get());
12985 }
12986
12987 NewClause = OpenACCVectorClause::Create(
12988 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12989 LParenLoc: ParsedClause.getLParenLoc(),
12990 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12991 : nullptr,
12992 EndLoc: ParsedClause.getEndLoc());
12993}
12994
12995template <typename Derived>
12996void OpenACCClauseTransform<Derived>::VisitWaitClause(
12997 const OpenACCWaitClause &C) {
12998 if (C.hasExprs()) {
12999 Expr *DevNumExpr = nullptr;
13000 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
13001
13002 // Instantiate devnum expr if it exists.
13003 if (C.getDevNumExpr()) {
13004 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
13005 if (!Res.isUsable())
13006 return;
13007 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
13008 C.getClauseKind(),
13009 C.getBeginLoc(), Res.get());
13010 if (!Res.isUsable())
13011 return;
13012
13013 DevNumExpr = Res.get();
13014 }
13015
13016 // Instantiate queue ids.
13017 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
13018 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
13019 if (!Res.isUsable())
13020 return;
13021 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
13022 C.getClauseKind(),
13023 C.getBeginLoc(), Res.get());
13024 if (!Res.isUsable())
13025 return;
13026
13027 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
13028 }
13029
13030 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
13031 IntExprs: std::move(InstantiatedQueueIdExprs));
13032 }
13033
13034 NewClause = OpenACCWaitClause::Create(
13035 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13036 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
13037 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
13038 EndLoc: ParsedClause.getEndLoc());
13039}
13040
13041template <typename Derived>
13042void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
13043 const OpenACCDeviceTypeClause &C) {
13044 // Nothing to transform here, just create a new version of 'C'.
13045 NewClause = OpenACCDeviceTypeClause::Create(
13046 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
13047 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
13048 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
13049}
13050
13051template <typename Derived>
13052void OpenACCClauseTransform<Derived>::VisitAutoClause(
13053 const OpenACCAutoClause &C) {
13054 // Nothing to do, so just create a new node.
13055 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
13056 BeginLoc: ParsedClause.getBeginLoc(),
13057 EndLoc: ParsedClause.getEndLoc());
13058}
13059
13060template <typename Derived>
13061void OpenACCClauseTransform<Derived>::VisitIndependentClause(
13062 const OpenACCIndependentClause &C) {
13063 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
13064 BeginLoc: ParsedClause.getBeginLoc(),
13065 EndLoc: ParsedClause.getEndLoc());
13066}
13067
13068template <typename Derived>
13069void OpenACCClauseTransform<Derived>::VisitSeqClause(
13070 const OpenACCSeqClause &C) {
13071 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
13072 BeginLoc: ParsedClause.getBeginLoc(),
13073 EndLoc: ParsedClause.getEndLoc());
13074}
13075template <typename Derived>
13076void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
13077 const OpenACCFinalizeClause &C) {
13078 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
13079 BeginLoc: ParsedClause.getBeginLoc(),
13080 EndLoc: ParsedClause.getEndLoc());
13081}
13082
13083template <typename Derived>
13084void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
13085 const OpenACCIfPresentClause &C) {
13086 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
13087 BeginLoc: ParsedClause.getBeginLoc(),
13088 EndLoc: ParsedClause.getEndLoc());
13089}
13090
13091template <typename Derived>
13092void OpenACCClauseTransform<Derived>::VisitReductionClause(
13093 const OpenACCReductionClause &C) {
13094 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
13095 SmallVector<Expr *> ValidVars;
13096 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
13097
13098 for (const auto [Var, OrigRecipe] :
13099 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
13100 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
13101 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
13102 if (Res.isUsable()) {
13103 ValidVars.push_back(Elt: Res.get());
13104
13105 if (OrigRecipe.isSet())
13106 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
13107 else
13108 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
13109 C.getReductionOp(), Res.get()));
13110 }
13111 }
13112
13113 NewClause = Self.getSema().OpenACC().CheckReductionClause(
13114 ExistingClauses, ParsedClause.getDirectiveKind(),
13115 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13116 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
13117}
13118
13119template <typename Derived>
13120void OpenACCClauseTransform<Derived>::VisitCollapseClause(
13121 const OpenACCCollapseClause &C) {
13122 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
13123 assert(LoopCount && "collapse clause constructed with invalid loop count");
13124
13125 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
13126
13127 if (!NewLoopCount.isUsable())
13128 return;
13129
13130 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
13131 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13132 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
13133
13134 // FIXME: It isn't clear whether this is properly tested here, we should
13135 // probably see if we can come up with a test for this.
13136 if (!NewLoopCount.isUsable())
13137 return;
13138
13139 NewLoopCount =
13140 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
13141
13142 // FIXME: It isn't clear whether this is properly tested here, we should
13143 // probably see if we can come up with a test for this.
13144 if (!NewLoopCount.isUsable())
13145 return;
13146
13147 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
13148 NewClause = OpenACCCollapseClause::Create(
13149 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13150 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
13151 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
13152}
13153
13154template <typename Derived>
13155void OpenACCClauseTransform<Derived>::VisitTileClause(
13156 const OpenACCTileClause &C) {
13157
13158 llvm::SmallVector<Expr *> TransformedExprs;
13159
13160 for (Expr *E : C.getSizeExprs()) {
13161 ExprResult NewSizeExpr = Self.TransformExpr(E);
13162
13163 if (!NewSizeExpr.isUsable())
13164 return;
13165
13166 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
13167 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13168 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
13169
13170 // FIXME: It isn't clear whether this is properly tested here, we should
13171 // probably see if we can come up with a test for this.
13172 if (!NewSizeExpr.isUsable())
13173 return;
13174
13175 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
13176
13177 if (!NewSizeExpr.isUsable())
13178 return;
13179 TransformedExprs.push_back(Elt: NewSizeExpr.get());
13180 }
13181
13182 ParsedClause.setIntExprDetails(TransformedExprs);
13183 NewClause = OpenACCTileClause::Create(
13184 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13185 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
13186 EndLoc: ParsedClause.getEndLoc());
13187}
13188template <typename Derived>
13189void OpenACCClauseTransform<Derived>::VisitGangClause(
13190 const OpenACCGangClause &C) {
13191 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
13192 llvm::SmallVector<Expr *> TransformedIntExprs;
13193
13194 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
13195 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
13196 if (!ER.isUsable())
13197 continue;
13198
13199 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
13200 ParsedClause.getDirectiveKind(),
13201 C.getExpr(I).first, ER.get());
13202 if (!ER.isUsable())
13203 continue;
13204 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
13205 TransformedIntExprs.push_back(Elt: ER.get());
13206 }
13207
13208 NewClause = Self.getSema().OpenACC().CheckGangClause(
13209 ParsedClause.getDirectiveKind(), ExistingClauses,
13210 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13211 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
13212}
13213} // namespace
13214template <typename Derived>
13215OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
13216 ArrayRef<const OpenACCClause *> ExistingClauses,
13217 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
13218
13219 SemaOpenACC::OpenACCParsedClause ParsedClause(
13220 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
13221 ParsedClause.setEndLoc(OldClause->getEndLoc());
13222
13223 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
13224 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
13225
13226 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
13227 ParsedClause};
13228 Transform.Visit(OldClause);
13229
13230 return Transform.CreatedClause();
13231}
13232
13233template <typename Derived>
13234llvm::SmallVector<OpenACCClause *>
13235TreeTransform<Derived>::TransformOpenACCClauseList(
13236 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
13237 llvm::SmallVector<OpenACCClause *> TransformedClauses;
13238 for (const auto *Clause : OldClauses) {
13239 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
13240 TransformedClauses, DirKind, Clause))
13241 TransformedClauses.push_back(Elt: TransformedClause);
13242 }
13243 return TransformedClauses;
13244}
13245
13246template <typename Derived>
13247StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
13248 OpenACCComputeConstruct *C) {
13249 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13250
13251 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13252 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13253 C->clauses());
13254
13255 if (getSema().OpenACC().ActOnStartStmtDirective(
13256 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13257 return StmtError();
13258
13259 // Transform Structured Block.
13260 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13261 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13262 C->clauses(), TransformedClauses);
13263 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13264 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13265 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13266
13267 return getDerived().RebuildOpenACCComputeConstruct(
13268 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13269 C->getEndLoc(), TransformedClauses, StrBlock);
13270}
13271
13272template <typename Derived>
13273StmtResult
13274TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
13275
13276 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13277
13278 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13279 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13280 C->clauses());
13281
13282 if (getSema().OpenACC().ActOnStartStmtDirective(
13283 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13284 return StmtError();
13285
13286 // Transform Loop.
13287 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13288 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13289 C->clauses(), TransformedClauses);
13290 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13291 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13292 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13293
13294 return getDerived().RebuildOpenACCLoopConstruct(
13295 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13296 TransformedClauses, Loop);
13297}
13298
13299template <typename Derived>
13300StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
13301 OpenACCCombinedConstruct *C) {
13302 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13303
13304 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13305 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13306 C->clauses());
13307
13308 if (getSema().OpenACC().ActOnStartStmtDirective(
13309 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13310 return StmtError();
13311
13312 // Transform Loop.
13313 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13314 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13315 C->clauses(), TransformedClauses);
13316 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13317 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13318 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13319
13320 return getDerived().RebuildOpenACCCombinedConstruct(
13321 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13322 C->getEndLoc(), TransformedClauses, Loop);
13323}
13324
13325template <typename Derived>
13326StmtResult
13327TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
13328 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13329
13330 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13331 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13332 C->clauses());
13333 if (getSema().OpenACC().ActOnStartStmtDirective(
13334 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13335 return StmtError();
13336
13337 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13338 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13339 C->clauses(), TransformedClauses);
13340 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13341 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13342 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13343
13344 return getDerived().RebuildOpenACCDataConstruct(
13345 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13346 TransformedClauses, StrBlock);
13347}
13348
13349template <typename Derived>
13350StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
13351 OpenACCEnterDataConstruct *C) {
13352 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13353
13354 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13355 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13356 C->clauses());
13357 if (getSema().OpenACC().ActOnStartStmtDirective(
13358 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13359 return StmtError();
13360
13361 return getDerived().RebuildOpenACCEnterDataConstruct(
13362 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13363 TransformedClauses);
13364}
13365
13366template <typename Derived>
13367StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
13368 OpenACCExitDataConstruct *C) {
13369 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13370
13371 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13372 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13373 C->clauses());
13374 if (getSema().OpenACC().ActOnStartStmtDirective(
13375 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13376 return StmtError();
13377
13378 return getDerived().RebuildOpenACCExitDataConstruct(
13379 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13380 TransformedClauses);
13381}
13382
13383template <typename Derived>
13384StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
13385 OpenACCHostDataConstruct *C) {
13386 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13387
13388 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13389 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13390 C->clauses());
13391 if (getSema().OpenACC().ActOnStartStmtDirective(
13392 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13393 return StmtError();
13394
13395 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13396 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13397 C->clauses(), TransformedClauses);
13398 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13399 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13400 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13401
13402 return getDerived().RebuildOpenACCHostDataConstruct(
13403 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13404 TransformedClauses, StrBlock);
13405}
13406
13407template <typename Derived>
13408StmtResult
13409TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
13410 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13411
13412 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13413 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13414 C->clauses());
13415 if (getSema().OpenACC().ActOnStartStmtDirective(
13416 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13417 return StmtError();
13418
13419 return getDerived().RebuildOpenACCInitConstruct(
13420 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13421 TransformedClauses);
13422}
13423
13424template <typename Derived>
13425StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
13426 OpenACCShutdownConstruct *C) {
13427 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13428
13429 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13430 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13431 C->clauses());
13432 if (getSema().OpenACC().ActOnStartStmtDirective(
13433 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13434 return StmtError();
13435
13436 return getDerived().RebuildOpenACCShutdownConstruct(
13437 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13438 TransformedClauses);
13439}
13440template <typename Derived>
13441StmtResult
13442TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
13443 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13444
13445 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13446 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13447 C->clauses());
13448 if (getSema().OpenACC().ActOnStartStmtDirective(
13449 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13450 return StmtError();
13451
13452 return getDerived().RebuildOpenACCSetConstruct(
13453 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13454 TransformedClauses);
13455}
13456
13457template <typename Derived>
13458StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
13459 OpenACCUpdateConstruct *C) {
13460 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13461
13462 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13463 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13464 C->clauses());
13465 if (getSema().OpenACC().ActOnStartStmtDirective(
13466 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13467 return StmtError();
13468
13469 return getDerived().RebuildOpenACCUpdateConstruct(
13470 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13471 TransformedClauses);
13472}
13473
13474template <typename Derived>
13475StmtResult
13476TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
13477 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13478
13479 ExprResult DevNumExpr;
13480 if (C->hasDevNumExpr()) {
13481 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
13482
13483 if (DevNumExpr.isUsable())
13484 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
13485 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
13486 C->getBeginLoc(), DevNumExpr.get());
13487 }
13488
13489 llvm::SmallVector<Expr *> QueueIdExprs;
13490
13491 for (Expr *QE : C->getQueueIdExprs()) {
13492 assert(QE && "Null queue id expr?");
13493 ExprResult NewEQ = getDerived().TransformExpr(QE);
13494
13495 if (!NewEQ.isUsable())
13496 break;
13497 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
13498 OpenACCClauseKind::Invalid,
13499 C->getBeginLoc(), NewEQ.get());
13500 if (NewEQ.isUsable())
13501 QueueIdExprs.push_back(Elt: NewEQ.get());
13502 }
13503
13504 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13505 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13506 C->clauses());
13507
13508 if (getSema().OpenACC().ActOnStartStmtDirective(
13509 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13510 return StmtError();
13511
13512 return getDerived().RebuildOpenACCWaitConstruct(
13513 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13514 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
13515 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
13516}
13517template <typename Derived>
13518StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
13519 OpenACCCacheConstruct *C) {
13520 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13521
13522 llvm::SmallVector<Expr *> TransformedVarList;
13523 for (Expr *Var : C->getVarList()) {
13524 assert(Var && "Null var listexpr?");
13525
13526 ExprResult NewVar = getDerived().TransformExpr(Var);
13527
13528 if (!NewVar.isUsable())
13529 break;
13530
13531 NewVar = getSema().OpenACC().ActOnVar(
13532 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13533 if (!NewVar.isUsable())
13534 break;
13535
13536 TransformedVarList.push_back(Elt: NewVar.get());
13537 }
13538
13539 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13540 C->getBeginLoc(), {}))
13541 return StmtError();
13542
13543 return getDerived().RebuildOpenACCCacheConstruct(
13544 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13545 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13546 C->getEndLoc());
13547}
13548
13549template <typename Derived>
13550StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13551 OpenACCAtomicConstruct *C) {
13552 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13553
13554 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13555 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13556 C->clauses());
13557
13558 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13559 C->getBeginLoc(), {}))
13560 return StmtError();
13561
13562 // Transform Associated Stmt.
13563 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13564 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13565
13566 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13567 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13568 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13569 AssocStmt);
13570
13571 return getDerived().RebuildOpenACCAtomicConstruct(
13572 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13573 C->getEndLoc(), TransformedClauses, AssocStmt);
13574}
13575
13576template <typename Derived>
13577ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13578 OpenACCAsteriskSizeExpr *E) {
13579 if (getDerived().AlwaysRebuild())
13580 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13581 // Nothing can ever change, so there is never anything to transform.
13582 return E;
13583}
13584
13585//===----------------------------------------------------------------------===//
13586// Expression transformation
13587//===----------------------------------------------------------------------===//
13588template<typename Derived>
13589ExprResult
13590TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13591 return TransformExpr(E: E->getSubExpr());
13592}
13593
13594template <typename Derived>
13595ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13596 SYCLUniqueStableNameExpr *E) {
13597 if (!E->isTypeDependent())
13598 return E;
13599
13600 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13601
13602 if (!NewT)
13603 return ExprError();
13604
13605 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13606 return E;
13607
13608 return getDerived().RebuildSYCLUniqueStableNameExpr(
13609 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13610}
13611
13612template <typename Derived>
13613StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13614 UnresolvedSYCLKernelCallStmt *S) {
13615 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13616 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13617 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13618 return StmtError();
13619
13620 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13621 if (IdExpr.isInvalid())
13622 return StmtError();
13623
13624 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13625 if (Body.isInvalid())
13626 return StmtError();
13627
13628 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13629 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13630 LaunchIdExpr: IdExpr.get());
13631 if (SR.isInvalid())
13632 return StmtError();
13633
13634 return SR;
13635}
13636
13637template <typename Derived>
13638ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13639 // TODO(reflection): Implement its transform
13640
13641 switch (E->getKind()) {
13642 case ReflectionKind::Type: {
13643 TypeSourceInfo *NewT = getDerived().TransformType(
13644 const_cast<TypeSourceInfo *>(E->getTypeSourceInfo()));
13645 if (!NewT)
13646 return ExprError();
13647 return SemaRef.BuildCXXReflectExpr(OperatorLoc: E->getOperatorLoc(), TSI: NewT);
13648 }
13649 case ReflectionKind::Null:
13650 llvm_unreachable("A null reflection should not reach here");
13651 }
13652
13653 assert(false && "unknown or unimplemented reflection entities");
13654 return ExprError();
13655}
13656
13657template<typename Derived>
13658ExprResult
13659TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13660 if (!E->isTypeDependent())
13661 return E;
13662
13663 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13664 E->getIdentKind());
13665}
13666
13667template<typename Derived>
13668ExprResult
13669TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13670 NestedNameSpecifierLoc QualifierLoc;
13671 if (E->getQualifierLoc()) {
13672 QualifierLoc
13673 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13674 if (!QualifierLoc)
13675 return ExprError();
13676 }
13677
13678 ValueDecl *ND
13679 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13680 E->getDecl()));
13681 if (!ND || ND->isInvalidDecl())
13682 return ExprError();
13683
13684 NamedDecl *Found = ND;
13685 if (E->getFoundDecl() != E->getDecl()) {
13686 Found = cast_or_null<NamedDecl>(
13687 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13688 if (!Found)
13689 return ExprError();
13690 }
13691
13692 DeclarationNameInfo NameInfo = E->getNameInfo();
13693 if (NameInfo.getName()) {
13694 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13695 if (!NameInfo.getName())
13696 return ExprError();
13697 }
13698
13699 if (!getDerived().AlwaysRebuild() &&
13700 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13701 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13702 Found == E->getFoundDecl() &&
13703 NameInfo.getName() == E->getDecl()->getDeclName() &&
13704 !E->hasExplicitTemplateArgs()) {
13705
13706 // Mark it referenced in the new context regardless.
13707 // FIXME: this is a bit instantiation-specific.
13708 SemaRef.MarkDeclRefReferenced(E);
13709
13710 return E;
13711 }
13712
13713 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13714 if (E->hasExplicitTemplateArgs()) {
13715 TemplateArgs = &TransArgs;
13716 TransArgs.setLAngleLoc(E->getLAngleLoc());
13717 TransArgs.setRAngleLoc(E->getRAngleLoc());
13718 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13719 E->getNumTemplateArgs(),
13720 TransArgs))
13721 return ExprError();
13722 }
13723
13724 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13725 Found, TemplateArgs);
13726}
13727
13728template<typename Derived>
13729ExprResult
13730TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13731 return E;
13732}
13733
13734template <typename Derived>
13735ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13736 FixedPointLiteral *E) {
13737 return E;
13738}
13739
13740template<typename Derived>
13741ExprResult
13742TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13743 return E;
13744}
13745
13746template<typename Derived>
13747ExprResult
13748TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13749 return E;
13750}
13751
13752template<typename Derived>
13753ExprResult
13754TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13755 return E;
13756}
13757
13758template<typename Derived>
13759ExprResult
13760TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13761 return E;
13762}
13763
13764template<typename Derived>
13765ExprResult
13766TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13767 return getDerived().TransformCallExpr(E);
13768}
13769
13770template<typename Derived>
13771ExprResult
13772TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13773 ExprResult ControllingExpr;
13774 TypeSourceInfo *ControllingType = nullptr;
13775 if (E->isExprPredicate())
13776 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13777 else
13778 ControllingType = getDerived().TransformType(E->getControllingType());
13779
13780 if (ControllingExpr.isInvalid() && !ControllingType)
13781 return ExprError();
13782
13783 SmallVector<Expr *, 4> AssocExprs;
13784 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13785 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13786 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13787 if (TSI) {
13788 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13789 if (!AssocType)
13790 return ExprError();
13791 AssocTypes.push_back(Elt: AssocType);
13792 } else {
13793 AssocTypes.push_back(Elt: nullptr);
13794 }
13795
13796 ExprResult AssocExpr =
13797 getDerived().TransformExpr(Assoc.getAssociationExpr());
13798 if (AssocExpr.isInvalid())
13799 return ExprError();
13800 AssocExprs.push_back(Elt: AssocExpr.get());
13801 }
13802
13803 if (!ControllingType)
13804 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13805 E->getDefaultLoc(),
13806 E->getRParenLoc(),
13807 ControllingExpr.get(),
13808 AssocTypes,
13809 AssocExprs);
13810 return getDerived().RebuildGenericSelectionExpr(
13811 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13812 ControllingType, AssocTypes, AssocExprs);
13813}
13814
13815template<typename Derived>
13816ExprResult
13817TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13818 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13819 if (SubExpr.isInvalid())
13820 return ExprError();
13821
13822 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13823 return E;
13824
13825 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13826 E->getRParen());
13827}
13828
13829/// The operand of a unary address-of operator has special rules: it's
13830/// allowed to refer to a non-static member of a class even if there's no 'this'
13831/// object available.
13832template<typename Derived>
13833ExprResult
13834TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13835 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13836 return getDerived().TransformDependentScopeDeclRefExpr(
13837 DRE, /*IsAddressOfOperand=*/true, nullptr);
13838 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13839 return getDerived().TransformUnresolvedLookupExpr(
13840 ULE, /*IsAddressOfOperand=*/true);
13841 else
13842 return getDerived().TransformExpr(E);
13843}
13844
13845template<typename Derived>
13846ExprResult
13847TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13848 ExprResult SubExpr;
13849 if (E->getOpcode() == UO_AddrOf)
13850 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13851 else
13852 SubExpr = TransformExpr(E: E->getSubExpr());
13853 if (SubExpr.isInvalid())
13854 return ExprError();
13855
13856 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13857 return E;
13858
13859 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13860 E->getOpcode(),
13861 SubExpr.get());
13862}
13863
13864template<typename Derived>
13865ExprResult
13866TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13867 // Transform the type.
13868 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13869 if (!Type)
13870 return ExprError();
13871
13872 // Transform all of the components into a Designation similar to what the
13873 // parser builds.
13874 // FIXME: It would be slightly more efficient in the non-dependent case to
13875 // just map FieldDecls, rather than requiring the rebuilder to look for
13876 // the fields again. However, __builtin_offsetof is rare enough in
13877 // template code that we don't care.
13878 bool ExprChanged = false;
13879 Designation Desig;
13880 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13881 const OffsetOfNode &ON = E->getComponent(Idx: I);
13882 switch (ON.getKind()) {
13883 case OffsetOfNode::Array: {
13884 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13885 ExprResult Index = getDerived().TransformExpr(FromIndex);
13886 if (Index.isInvalid())
13887 return ExprError();
13888
13889 ExprChanged = ExprChanged || Index.get() != FromIndex;
13890 Designator AD =
13891 Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: ON.getBeginLoc());
13892 AD.setRBracketLoc(ON.getEndLoc());
13893 Desig.AddDesignator(D: AD);
13894 break;
13895 }
13896
13897 case OffsetOfNode::Field:
13898 case OffsetOfNode::Identifier: {
13899 const IdentifierInfo *Name = ON.getFieldName();
13900 if (!Name)
13901 continue;
13902 // The leading designator has no '.'; subsequent ones do.
13903 SourceLocation DotLoc =
13904 Desig.empty() ? SourceLocation() : ON.getBeginLoc();
13905 Desig.AddDesignator(
13906 D: Designator::CreateFieldDesignator(FieldName: Name, DotLoc, FieldLoc: ON.getEndLoc()));
13907 break;
13908 }
13909
13910 case OffsetOfNode::Base:
13911 // Will be recomputed during the rebuild.
13912 continue;
13913 }
13914 }
13915
13916 // If nothing changed, retain the existing expression.
13917 if (!getDerived().AlwaysRebuild() &&
13918 Type == E->getTypeSourceInfo() &&
13919 !ExprChanged)
13920 return E;
13921
13922 // Build a new offsetof expression.
13923 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, Desig,
13924 E->getRParenLoc());
13925}
13926
13927template<typename Derived>
13928ExprResult
13929TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13930 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13931 "opaque value expression requires transformation");
13932 return E;
13933}
13934
13935template <typename Derived>
13936ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13937 llvm::SmallVector<Expr *, 8> Children;
13938 bool Changed = false;
13939 for (Expr *C : E->subExpressions()) {
13940 ExprResult NewC = getDerived().TransformExpr(C);
13941 if (NewC.isInvalid())
13942 return ExprError();
13943 Children.push_back(Elt: NewC.get());
13944
13945 Changed |= NewC.get() != C;
13946 }
13947 if (!getDerived().AlwaysRebuild() && !Changed)
13948 return E;
13949 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13950 Children, E->getType());
13951}
13952
13953template<typename Derived>
13954ExprResult
13955TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13956 // Rebuild the syntactic form. The original syntactic form has
13957 // opaque-value expressions in it, so strip those away and rebuild
13958 // the result. This is a really awful way of doing this, but the
13959 // better solution (rebuilding the semantic expressions and
13960 // rebinding OVEs as necessary) doesn't work; we'd need
13961 // TreeTransform to not strip away implicit conversions.
13962 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13963 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13964 if (result.isInvalid()) return ExprError();
13965
13966 // If that gives us a pseudo-object result back, the pseudo-object
13967 // expression must have been an lvalue-to-rvalue conversion which we
13968 // should reapply.
13969 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13970 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13971
13972 return result;
13973}
13974
13975template<typename Derived>
13976ExprResult
13977TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13978 UnaryExprOrTypeTraitExpr *E) {
13979 if (E->isArgumentType()) {
13980 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13981
13982 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13983 if (!NewT)
13984 return ExprError();
13985
13986 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13987 return E;
13988
13989 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13990 E->getKind(),
13991 E->getSourceRange());
13992 }
13993
13994 // C++0x [expr.sizeof]p1:
13995 // The operand is either an expression, which is an unevaluated operand
13996 // [...]
13997 EnterExpressionEvaluationContext Unevaluated(
13998 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13999 Sema::ReuseLambdaContextDecl);
14000
14001 // Try to recover if we have something like sizeof(T::X) where X is a type.
14002 // Notably, there must be *exactly* one set of parens if X is a type.
14003 TypeSourceInfo *RecoveryTSI = nullptr;
14004 ExprResult SubExpr;
14005 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
14006 if (auto *DRE =
14007 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
14008 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
14009 PE, DRE, false, &RecoveryTSI);
14010 else
14011 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
14012
14013 if (RecoveryTSI) {
14014 return getDerived().RebuildUnaryExprOrTypeTrait(
14015 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
14016 } else if (SubExpr.isInvalid())
14017 return ExprError();
14018
14019 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
14020 return E;
14021
14022 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
14023 E->getOperatorLoc(),
14024 E->getKind(),
14025 E->getSourceRange());
14026}
14027
14028template<typename Derived>
14029ExprResult
14030TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
14031 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14032 if (LHS.isInvalid())
14033 return ExprError();
14034
14035 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14036 if (RHS.isInvalid())
14037 return ExprError();
14038
14039
14040 if (!getDerived().AlwaysRebuild() &&
14041 LHS.get() == E->getLHS() &&
14042 RHS.get() == E->getRHS())
14043 return E;
14044
14045 return getDerived().RebuildArraySubscriptExpr(
14046 LHS.get(),
14047 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
14048}
14049
14050template <typename Derived>
14051ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
14052 MatrixSingleSubscriptExpr *E) {
14053 ExprResult Base = getDerived().TransformExpr(E->getBase());
14054 if (Base.isInvalid())
14055 return ExprError();
14056
14057 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14058 if (RowIdx.isInvalid())
14059 return ExprError();
14060
14061 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14062 RowIdx.get() == E->getRowIdx())
14063 return E;
14064
14065 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
14066 E->getRBracketLoc());
14067}
14068
14069template <typename Derived>
14070ExprResult
14071TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
14072 ExprResult Base = getDerived().TransformExpr(E->getBase());
14073 if (Base.isInvalid())
14074 return ExprError();
14075
14076 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14077 if (RowIdx.isInvalid())
14078 return ExprError();
14079
14080 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
14081 if (ColumnIdx.isInvalid())
14082 return ExprError();
14083
14084 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14085 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
14086 return E;
14087
14088 return getDerived().RebuildMatrixSubscriptExpr(
14089 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
14090}
14091
14092template <typename Derived>
14093ExprResult
14094TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
14095 ExprResult Base = getDerived().TransformExpr(E->getBase());
14096 if (Base.isInvalid())
14097 return ExprError();
14098
14099 ExprResult LowerBound;
14100 if (E->getLowerBound()) {
14101 LowerBound = getDerived().TransformExpr(E->getLowerBound());
14102 if (LowerBound.isInvalid())
14103 return ExprError();
14104 }
14105
14106 ExprResult Length;
14107 if (E->getLength()) {
14108 Length = getDerived().TransformExpr(E->getLength());
14109 if (Length.isInvalid())
14110 return ExprError();
14111 }
14112
14113 ExprResult Stride;
14114 if (E->isOMPArraySection()) {
14115 if (Expr *Str = E->getStride()) {
14116 Stride = getDerived().TransformExpr(Str);
14117 if (Stride.isInvalid())
14118 return ExprError();
14119 }
14120 }
14121
14122 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14123 LowerBound.get() == E->getLowerBound() &&
14124 Length.get() == E->getLength() &&
14125 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
14126 return E;
14127
14128 return getDerived().RebuildArraySectionExpr(
14129 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
14130 LowerBound.get(), E->getColonLocFirst(),
14131 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
14132 Length.get(), Stride.get(), E->getRBracketLoc());
14133}
14134
14135template <typename Derived>
14136ExprResult
14137TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
14138 ExprResult Base = getDerived().TransformExpr(E->getBase());
14139 if (Base.isInvalid())
14140 return ExprError();
14141
14142 SmallVector<Expr *, 4> Dims;
14143 bool ErrorFound = false;
14144 for (Expr *Dim : E->getDimensions()) {
14145 ExprResult DimRes = getDerived().TransformExpr(Dim);
14146 if (DimRes.isInvalid()) {
14147 ErrorFound = true;
14148 continue;
14149 }
14150 Dims.push_back(Elt: DimRes.get());
14151 }
14152
14153 if (ErrorFound)
14154 return ExprError();
14155 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
14156 E->getRParenLoc(), Dims,
14157 E->getBracketsRanges());
14158}
14159
14160template <typename Derived>
14161ExprResult
14162TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
14163 unsigned NumIterators = E->numOfIterators();
14164 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
14165
14166 bool ErrorFound = false;
14167 bool NeedToRebuild = getDerived().AlwaysRebuild();
14168 for (unsigned I = 0; I < NumIterators; ++I) {
14169 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
14170 Data[I].DeclIdent = D->getIdentifier();
14171 Data[I].DeclIdentLoc = D->getLocation();
14172 if (D->getLocation() == D->getBeginLoc()) {
14173 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
14174 "Implicit type must be int.");
14175 } else {
14176 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
14177 QualType DeclTy = getDerived().TransformType(D->getType());
14178 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
14179 }
14180 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
14181 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
14182 ExprResult End = getDerived().TransformExpr(Range.End);
14183 ExprResult Step = getDerived().TransformExpr(Range.Step);
14184 ErrorFound = ErrorFound ||
14185 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
14186 !Data[I].Type.get().isNull())) ||
14187 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
14188 if (ErrorFound)
14189 continue;
14190 Data[I].Range.Begin = Begin.get();
14191 Data[I].Range.End = End.get();
14192 Data[I].Range.Step = Step.get();
14193 Data[I].AssignLoc = E->getAssignLoc(I);
14194 Data[I].ColonLoc = E->getColonLoc(I);
14195 Data[I].SecColonLoc = E->getSecondColonLoc(I);
14196 NeedToRebuild =
14197 NeedToRebuild ||
14198 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
14199 D->getType().getTypePtrOrNull()) ||
14200 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
14201 Range.Step != Data[I].Range.Step;
14202 }
14203 if (ErrorFound)
14204 return ExprError();
14205 if (!NeedToRebuild)
14206 return E;
14207
14208 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
14209 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
14210 if (!Res.isUsable())
14211 return Res;
14212 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
14213 for (unsigned I = 0; I < NumIterators; ++I)
14214 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
14215 IE->getIteratorDecl(I));
14216 return Res;
14217}
14218
14219template<typename Derived>
14220ExprResult
14221TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
14222 // Transform the callee.
14223 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14224 if (Callee.isInvalid())
14225 return ExprError();
14226
14227 // Transform arguments.
14228 bool ArgChanged = false;
14229 SmallVector<Expr*, 8> Args;
14230 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14231 &ArgChanged))
14232 return ExprError();
14233
14234 if (!getDerived().AlwaysRebuild() &&
14235 Callee.get() == E->getCallee() &&
14236 !ArgChanged)
14237 return SemaRef.MaybeBindToTemporary(E);
14238
14239 // FIXME: Wrong source location information for the '('.
14240 SourceLocation FakeLParenLoc
14241 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14242
14243 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14244 if (E->hasStoredFPFeatures()) {
14245 FPOptionsOverride NewOverrides = E->getFPFeatures();
14246 getSema().CurFPFeatures =
14247 NewOverrides.applyOverrides(getSema().getLangOpts());
14248 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14249 }
14250
14251 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14252 Args,
14253 E->getRParenLoc());
14254}
14255
14256template<typename Derived>
14257ExprResult
14258TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
14259 ExprResult Base = getDerived().TransformExpr(E->getBase());
14260 if (Base.isInvalid())
14261 return ExprError();
14262
14263 NestedNameSpecifierLoc QualifierLoc;
14264 if (E->hasQualifier()) {
14265 QualifierLoc
14266 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14267
14268 if (!QualifierLoc)
14269 return ExprError();
14270 }
14271 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14272
14273 ValueDecl *Member
14274 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
14275 E->getMemberDecl()));
14276 if (!Member)
14277 return ExprError();
14278
14279 NamedDecl *FoundDecl = E->getFoundDecl();
14280 if (FoundDecl == E->getMemberDecl()) {
14281 FoundDecl = Member;
14282 } else {
14283 FoundDecl = cast_or_null<NamedDecl>(
14284 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
14285 if (!FoundDecl)
14286 return ExprError();
14287 }
14288
14289 if (!getDerived().AlwaysRebuild() &&
14290 Base.get() == E->getBase() &&
14291 QualifierLoc == E->getQualifierLoc() &&
14292 Member == E->getMemberDecl() &&
14293 FoundDecl == E->getFoundDecl() &&
14294 !E->hasExplicitTemplateArgs()) {
14295
14296 // Skip for member expression of (this->f), rebuilt thisi->f is needed
14297 // for Openmp where the field need to be privatizized in the case.
14298 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
14299 getSema().OpenMP().isOpenMPRebuildMemberExpr(
14300 cast<ValueDecl>(Val: Member)))) {
14301 // Mark it referenced in the new context regardless.
14302 // FIXME: this is a bit instantiation-specific.
14303 SemaRef.MarkMemberReferenced(E);
14304 return E;
14305 }
14306 }
14307
14308 TemplateArgumentListInfo TransArgs;
14309 if (E->hasExplicitTemplateArgs()) {
14310 TransArgs.setLAngleLoc(E->getLAngleLoc());
14311 TransArgs.setRAngleLoc(E->getRAngleLoc());
14312 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14313 E->getNumTemplateArgs(),
14314 TransArgs))
14315 return ExprError();
14316 }
14317
14318 // FIXME: Bogus source location for the operator
14319 SourceLocation FakeOperatorLoc =
14320 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
14321
14322 // FIXME: to do this check properly, we will need to preserve the
14323 // first-qualifier-in-scope here, just in case we had a dependent
14324 // base (and therefore couldn't do the check) and a
14325 // nested-name-qualifier (and therefore could do the lookup).
14326 NamedDecl *FirstQualifierInScope = nullptr;
14327 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
14328 if (MemberNameInfo.getName()) {
14329 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
14330 if (!MemberNameInfo.getName())
14331 return ExprError();
14332 }
14333
14334 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
14335 E->isArrow(),
14336 QualifierLoc,
14337 TemplateKWLoc,
14338 MemberNameInfo,
14339 Member,
14340 FoundDecl,
14341 (E->hasExplicitTemplateArgs()
14342 ? &TransArgs : nullptr),
14343 FirstQualifierInScope);
14344}
14345
14346template<typename Derived>
14347ExprResult
14348TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
14349 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14350 if (LHS.isInvalid())
14351 return ExprError();
14352
14353 ExprResult RHS =
14354 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
14355 if (RHS.isInvalid())
14356 return ExprError();
14357
14358 if (!getDerived().AlwaysRebuild() &&
14359 LHS.get() == E->getLHS() &&
14360 RHS.get() == E->getRHS())
14361 return E;
14362
14363 if (E->isCompoundAssignmentOp())
14364 // FPFeatures has already been established from trailing storage
14365 return getDerived().RebuildBinaryOperator(
14366 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
14367 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14368 FPOptionsOverride NewOverrides(E->getFPFeatures());
14369 getSema().CurFPFeatures =
14370 NewOverrides.applyOverrides(getSema().getLangOpts());
14371 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14372 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
14373 LHS.get(), RHS.get());
14374}
14375
14376template <typename Derived>
14377ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
14378 CXXRewrittenBinaryOperator *E) {
14379 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
14380
14381 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
14382 if (LHS.isInvalid())
14383 return ExprError();
14384
14385 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
14386 if (RHS.isInvalid())
14387 return ExprError();
14388
14389 // Extract the already-resolved callee declarations so that we can restrict
14390 // ourselves to using them as the unqualified lookup results when rebuilding.
14391 UnresolvedSet<2> UnqualLookups;
14392 bool ChangedAnyLookups = false;
14393 Expr *PossibleBinOps[] = {E->getSemanticForm(),
14394 const_cast<Expr *>(Decomp.InnerBinOp)};
14395 for (Expr *PossibleBinOp : PossibleBinOps) {
14396 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
14397 if (!Op)
14398 continue;
14399 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
14400 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
14401 continue;
14402
14403 // Transform the callee in case we built a call to a local extern
14404 // declaration.
14405 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
14406 E->getOperatorLoc(), Callee->getFoundDecl()));
14407 if (!Found)
14408 return ExprError();
14409 if (Found != Callee->getFoundDecl())
14410 ChangedAnyLookups = true;
14411 UnqualLookups.addDecl(D: Found);
14412 }
14413
14414 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
14415 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
14416 // Mark all functions used in the rewrite as referenced. Note that when
14417 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
14418 // function calls, and/or there might be a user-defined conversion sequence
14419 // applied to the operands of the <.
14420 // FIXME: this is a bit instantiation-specific.
14421 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
14422 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
14423 return E;
14424 }
14425
14426 return getDerived().RebuildCXXRewrittenBinaryOperator(
14427 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
14428}
14429
14430template<typename Derived>
14431ExprResult
14432TreeTransform<Derived>::TransformCompoundAssignOperator(
14433 CompoundAssignOperator *E) {
14434 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14435 FPOptionsOverride NewOverrides(E->getFPFeatures());
14436 getSema().CurFPFeatures =
14437 NewOverrides.applyOverrides(getSema().getLangOpts());
14438 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14439 return getDerived().TransformBinaryOperator(E);
14440}
14441
14442template<typename Derived>
14443ExprResult TreeTransform<Derived>::
14444TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
14445 // Just rebuild the common and RHS expressions and see whether we
14446 // get any changes.
14447
14448 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
14449 if (commonExpr.isInvalid())
14450 return ExprError();
14451
14452 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
14453 if (rhs.isInvalid())
14454 return ExprError();
14455
14456 if (!getDerived().AlwaysRebuild() &&
14457 commonExpr.get() == e->getCommon() &&
14458 rhs.get() == e->getFalseExpr())
14459 return e;
14460
14461 return getDerived().RebuildConditionalOperator(commonExpr.get(),
14462 e->getQuestionLoc(),
14463 nullptr,
14464 e->getColonLoc(),
14465 rhs.get());
14466}
14467
14468template<typename Derived>
14469ExprResult
14470TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
14471 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14472 if (Cond.isInvalid())
14473 return ExprError();
14474
14475 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14476 if (LHS.isInvalid())
14477 return ExprError();
14478
14479 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14480 if (RHS.isInvalid())
14481 return ExprError();
14482
14483 if (!getDerived().AlwaysRebuild() &&
14484 Cond.get() == E->getCond() &&
14485 LHS.get() == E->getLHS() &&
14486 RHS.get() == E->getRHS())
14487 return E;
14488
14489 return getDerived().RebuildConditionalOperator(Cond.get(),
14490 E->getQuestionLoc(),
14491 LHS.get(),
14492 E->getColonLoc(),
14493 RHS.get());
14494}
14495
14496template<typename Derived>
14497ExprResult
14498TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
14499 // Implicit casts are eliminated during transformation, since they
14500 // will be recomputed by semantic analysis after transformation.
14501 return getDerived().TransformExpr(E->getSubExprAsWritten());
14502}
14503
14504template<typename Derived>
14505ExprResult
14506TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
14507 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14508 if (!Type)
14509 return ExprError();
14510
14511 ExprResult SubExpr
14512 = getDerived().TransformExpr(E->getSubExprAsWritten());
14513 if (SubExpr.isInvalid())
14514 return ExprError();
14515
14516 if (!getDerived().AlwaysRebuild() &&
14517 Type == E->getTypeInfoAsWritten() &&
14518 SubExpr.get() == E->getSubExpr())
14519 return E;
14520
14521 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
14522 Type,
14523 E->getRParenLoc(),
14524 SubExpr.get());
14525}
14526
14527template<typename Derived>
14528ExprResult
14529TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
14530 TypeSourceInfo *OldT = E->getTypeSourceInfo();
14531 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
14532 if (!NewT)
14533 return ExprError();
14534
14535 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
14536 if (Init.isInvalid())
14537 return ExprError();
14538
14539 if (!getDerived().AlwaysRebuild() &&
14540 OldT == NewT &&
14541 Init.get() == E->getInitializer())
14542 return SemaRef.MaybeBindToTemporary(E);
14543
14544 // Note: the expression type doesn't necessarily match the
14545 // type-as-written, but that's okay, because it should always be
14546 // derivable from the initializer.
14547
14548 return getDerived().RebuildCompoundLiteralExpr(
14549 E->getLParenLoc(), NewT,
14550 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14551}
14552
14553template<typename Derived>
14554ExprResult
14555TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14556 ExprResult Base = getDerived().TransformExpr(E->getBase());
14557 if (Base.isInvalid())
14558 return ExprError();
14559
14560 if (!getDerived().AlwaysRebuild() &&
14561 Base.get() == E->getBase())
14562 return E;
14563
14564 // FIXME: Bad source location
14565 SourceLocation FakeOperatorLoc =
14566 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14567 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14568 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14569 E->getAccessor());
14570}
14571
14572template <typename Derived>
14573ExprResult
14574TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14575 ExprResult Base = getDerived().TransformExpr(E->getBase());
14576 if (Base.isInvalid())
14577 return ExprError();
14578
14579 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14580 return E;
14581
14582 // FIXME: Bad source location
14583 SourceLocation FakeOperatorLoc =
14584 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14585 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14586 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14587 E->getAccessor());
14588}
14589
14590template<typename Derived>
14591ExprResult
14592TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14593 if (InitListExpr *Syntactic = E->getSyntacticForm())
14594 E = Syntactic;
14595
14596 bool InitChanged = false;
14597
14598 EnterExpressionEvaluationContext Context(
14599 getSema(), EnterExpressionEvaluationContext::InitList);
14600
14601 SmallVector<Expr*, 4> Inits;
14602 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14603 Inits, &InitChanged))
14604 return ExprError();
14605
14606 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14607 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14608 // in some cases. We can't reuse it in general, because the syntactic and
14609 // semantic forms are linked, and we can't know that semantic form will
14610 // match even if the syntactic form does.
14611 }
14612
14613 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14614 E->getRBraceLoc(), E->isExplicit());
14615}
14616
14617template<typename Derived>
14618ExprResult
14619TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14620 Designation Desig;
14621
14622 // transform the initializer value
14623 ExprResult Init = getDerived().TransformExpr(E->getInit());
14624 if (Init.isInvalid())
14625 return ExprError();
14626
14627 // transform the designators.
14628 SmallVector<Expr*, 4> ArrayExprs;
14629 bool ExprChanged = false;
14630 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14631 if (D.isFieldDesignator()) {
14632 if (D.getFieldDecl()) {
14633 FieldDecl *Field = cast_or_null<FieldDecl>(
14634 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14635 if (Field != D.getFieldDecl())
14636 // Rebuild the expression when the transformed FieldDecl is
14637 // different to the already assigned FieldDecl.
14638 ExprChanged = true;
14639 if (Field->isAnonymousStructOrUnion())
14640 continue;
14641 } else {
14642 // Ensure that the designator expression is rebuilt when there isn't
14643 // a resolved FieldDecl in the designator as we don't want to assign
14644 // a FieldDecl to a pattern designator that will be instantiated again.
14645 ExprChanged = true;
14646 }
14647 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14648 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14649 continue;
14650 }
14651
14652 if (D.isArrayDesignator()) {
14653 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14654 if (Index.isInvalid())
14655 return ExprError();
14656
14657 Desig.AddDesignator(
14658 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14659
14660 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14661 ArrayExprs.push_back(Elt: Index.get());
14662 continue;
14663 }
14664
14665 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14666 ExprResult Start
14667 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14668 if (Start.isInvalid())
14669 return ExprError();
14670
14671 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14672 if (End.isInvalid())
14673 return ExprError();
14674
14675 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14676 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14677
14678 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14679 End.get() != E->getArrayRangeEnd(D);
14680
14681 ArrayExprs.push_back(Elt: Start.get());
14682 ArrayExprs.push_back(Elt: End.get());
14683 }
14684
14685 if (!getDerived().AlwaysRebuild() &&
14686 Init.get() == E->getInit() &&
14687 !ExprChanged)
14688 return E;
14689
14690 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14691 E->getEqualOrColonLoc(),
14692 E->usesGNUSyntax(), Init.get());
14693}
14694
14695// Seems that if TransformInitListExpr() only works on the syntactic form of an
14696// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14697template<typename Derived>
14698ExprResult
14699TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14700 DesignatedInitUpdateExpr *E) {
14701 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14702 "initializer");
14703 return ExprError();
14704}
14705
14706template<typename Derived>
14707ExprResult
14708TreeTransform<Derived>::TransformNoInitExpr(
14709 NoInitExpr *E) {
14710 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14711 return ExprError();
14712}
14713
14714template<typename Derived>
14715ExprResult
14716TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14717 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14718 return ExprError();
14719}
14720
14721template<typename Derived>
14722ExprResult
14723TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14724 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14725 return ExprError();
14726}
14727
14728template<typename Derived>
14729ExprResult
14730TreeTransform<Derived>::TransformImplicitValueInitExpr(
14731 ImplicitValueInitExpr *E) {
14732 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14733
14734 // FIXME: Will we ever have proper type location here? Will we actually
14735 // need to transform the type?
14736 QualType T = getDerived().TransformType(E->getType());
14737 if (T.isNull())
14738 return ExprError();
14739
14740 if (!getDerived().AlwaysRebuild() &&
14741 T == E->getType())
14742 return E;
14743
14744 return getDerived().RebuildImplicitValueInitExpr(T);
14745}
14746
14747template<typename Derived>
14748ExprResult
14749TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14750 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14751 if (!TInfo)
14752 return ExprError();
14753
14754 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14755 if (SubExpr.isInvalid())
14756 return ExprError();
14757
14758 if (!getDerived().AlwaysRebuild() &&
14759 TInfo == E->getWrittenTypeInfo() &&
14760 SubExpr.get() == E->getSubExpr())
14761 return E;
14762
14763 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14764 TInfo, E->getRParenLoc());
14765}
14766
14767template<typename Derived>
14768ExprResult
14769TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14770 bool ArgumentChanged = false;
14771 SmallVector<Expr*, 4> Inits;
14772 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14773 ArgChanged: &ArgumentChanged))
14774 return ExprError();
14775
14776 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14777 Inits,
14778 E->getRParenLoc());
14779}
14780
14781/// Transform an address-of-label expression.
14782///
14783/// By default, the transformation of an address-of-label expression always
14784/// rebuilds the expression, so that the label identifier can be resolved to
14785/// the corresponding label statement by semantic analysis.
14786template<typename Derived>
14787ExprResult
14788TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14789 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14790 E->getLabel());
14791 if (!LD)
14792 return ExprError();
14793
14794 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14795 cast<LabelDecl>(Val: LD));
14796}
14797
14798template<typename Derived>
14799ExprResult
14800TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14801 SemaRef.ActOnStartStmtExpr();
14802 StmtResult SubStmt
14803 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14804 if (SubStmt.isInvalid()) {
14805 SemaRef.ActOnStmtExprError();
14806 return ExprError();
14807 }
14808
14809 unsigned OldDepth = E->getTemplateDepth();
14810 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14811
14812 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14813 SubStmt.get() == E->getSubStmt()) {
14814 // Calling this an 'error' is unintuitive, but it does the right thing.
14815 SemaRef.ActOnStmtExprError();
14816 return SemaRef.MaybeBindToTemporary(E);
14817 }
14818
14819 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14820 E->getRParenLoc(), NewDepth);
14821}
14822
14823template<typename Derived>
14824ExprResult
14825TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14826 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14827 if (Cond.isInvalid())
14828 return ExprError();
14829
14830 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14831 if (LHS.isInvalid())
14832 return ExprError();
14833
14834 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14835 if (RHS.isInvalid())
14836 return ExprError();
14837
14838 if (!getDerived().AlwaysRebuild() &&
14839 Cond.get() == E->getCond() &&
14840 LHS.get() == E->getLHS() &&
14841 RHS.get() == E->getRHS())
14842 return E;
14843
14844 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14845 Cond.get(), LHS.get(), RHS.get(),
14846 E->getRParenLoc());
14847}
14848
14849template<typename Derived>
14850ExprResult
14851TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14852 return E;
14853}
14854
14855template<typename Derived>
14856ExprResult
14857TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14858 switch (E->getOperator()) {
14859 case OO_New:
14860 case OO_Delete:
14861 case OO_Array_New:
14862 case OO_Array_Delete:
14863 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14864
14865 case OO_Subscript:
14866 case OO_Call: {
14867 // This is a call to an object's operator().
14868 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14869
14870 // Transform the object itself.
14871 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14872 if (Object.isInvalid())
14873 return ExprError();
14874
14875 // FIXME: Poor location information. Also, if the location for the end of
14876 // the token is within a macro expansion, getLocForEndOfToken() will return
14877 // an invalid source location. If that happens and we have an otherwise
14878 // valid end location, use the valid one instead of the invalid one.
14879 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14880 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14881 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14882 FakeLParenLoc = EndLoc;
14883
14884 // Transform the call arguments.
14885 SmallVector<Expr*, 8> Args;
14886 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14887 Args))
14888 return ExprError();
14889
14890 if (E->getOperator() == OO_Subscript)
14891 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14892 Args, E->getEndLoc());
14893
14894 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14895 E->getEndLoc());
14896 }
14897
14898#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14899 case OO_##Name: \
14900 break;
14901
14902#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14903#include "clang/Basic/OperatorKinds.def"
14904
14905 case OO_Conditional:
14906 llvm_unreachable("conditional operator is not actually overloadable");
14907
14908 case OO_None:
14909 case NUM_OVERLOADED_OPERATORS:
14910 llvm_unreachable("not an overloaded operator?");
14911 }
14912
14913 ExprResult First;
14914 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14915 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14916 else
14917 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14918 if (First.isInvalid())
14919 return ExprError();
14920
14921 ExprResult Second;
14922 if (E->getNumArgs() == 2) {
14923 Second =
14924 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14925 if (Second.isInvalid())
14926 return ExprError();
14927 }
14928
14929 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14930 FPOptionsOverride NewOverrides(E->getFPFeatures());
14931 getSema().CurFPFeatures =
14932 NewOverrides.applyOverrides(getSema().getLangOpts());
14933 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14934
14935 Expr *Callee = E->getCallee();
14936 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14937 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14938 Sema::LookupOrdinaryName);
14939 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14940 return ExprError();
14941
14942 return getDerived().RebuildCXXOperatorCallExpr(
14943 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14944 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14945 }
14946
14947 UnresolvedSet<1> Functions;
14948 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14949 Callee = ICE->getSubExprAsWritten();
14950 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14951 ValueDecl *VD = cast_or_null<ValueDecl>(
14952 getDerived().TransformDecl(DR->getLocation(), DR));
14953 if (!VD)
14954 return ExprError();
14955
14956 if (!isa<CXXMethodDecl>(Val: VD))
14957 Functions.addDecl(D: VD);
14958
14959 return getDerived().RebuildCXXOperatorCallExpr(
14960 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14961 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14962}
14963
14964template<typename Derived>
14965ExprResult
14966TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14967 return getDerived().TransformCallExpr(E);
14968}
14969
14970template <typename Derived>
14971ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14972 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14973 getSema().CurContext != E->getParentContext();
14974
14975 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14976 return E;
14977
14978 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14979 E->getBeginLoc(), E->getEndLoc(),
14980 getSema().CurContext);
14981}
14982
14983template <typename Derived>
14984ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14985 return E;
14986}
14987
14988template<typename Derived>
14989ExprResult
14990TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14991 // Transform the callee.
14992 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14993 if (Callee.isInvalid())
14994 return ExprError();
14995
14996 // Transform exec config.
14997 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14998 if (EC.isInvalid())
14999 return ExprError();
15000
15001 // Transform arguments.
15002 bool ArgChanged = false;
15003 SmallVector<Expr*, 8> Args;
15004 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15005 &ArgChanged))
15006 return ExprError();
15007
15008 if (!getDerived().AlwaysRebuild() &&
15009 Callee.get() == E->getCallee() &&
15010 !ArgChanged)
15011 return SemaRef.MaybeBindToTemporary(E);
15012
15013 // FIXME: Wrong source location information for the '('.
15014 SourceLocation FakeLParenLoc
15015 = ((Expr *)Callee.get())->getSourceRange().getBegin();
15016 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
15017 Args,
15018 E->getRParenLoc(), EC.get());
15019}
15020
15021template<typename Derived>
15022ExprResult
15023TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
15024 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
15025 if (!Type)
15026 return ExprError();
15027
15028 ExprResult SubExpr
15029 = getDerived().TransformExpr(E->getSubExprAsWritten());
15030 if (SubExpr.isInvalid())
15031 return ExprError();
15032
15033 if (!getDerived().AlwaysRebuild() &&
15034 Type == E->getTypeInfoAsWritten() &&
15035 SubExpr.get() == E->getSubExpr())
15036 return E;
15037 return getDerived().RebuildCXXNamedCastExpr(
15038 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
15039 Type, E->getAngleBrackets().getEnd(),
15040 // FIXME. this should be '(' location
15041 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
15042}
15043
15044template<typename Derived>
15045ExprResult
15046TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
15047 TypeSourceInfo *TSI =
15048 getDerived().TransformType(BCE->getTypeInfoAsWritten());
15049 if (!TSI)
15050 return ExprError();
15051
15052 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
15053 if (Sub.isInvalid())
15054 return ExprError();
15055
15056 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
15057 Sub.get(), BCE->getEndLoc());
15058}
15059
15060template<typename Derived>
15061ExprResult
15062TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
15063 return getDerived().TransformCXXNamedCastExpr(E);
15064}
15065
15066template<typename Derived>
15067ExprResult
15068TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
15069 return getDerived().TransformCXXNamedCastExpr(E);
15070}
15071
15072template<typename Derived>
15073ExprResult
15074TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
15075 CXXReinterpretCastExpr *E) {
15076 return getDerived().TransformCXXNamedCastExpr(E);
15077}
15078
15079template<typename Derived>
15080ExprResult
15081TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
15082 return getDerived().TransformCXXNamedCastExpr(E);
15083}
15084
15085template<typename Derived>
15086ExprResult
15087TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
15088 return getDerived().TransformCXXNamedCastExpr(E);
15089}
15090
15091template<typename Derived>
15092ExprResult
15093TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
15094 CXXFunctionalCastExpr *E) {
15095 TypeSourceInfo *Type =
15096 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
15097 if (!Type)
15098 return ExprError();
15099
15100 ExprResult SubExpr
15101 = getDerived().TransformExpr(E->getSubExprAsWritten());
15102 if (SubExpr.isInvalid())
15103 return ExprError();
15104
15105 if (!getDerived().AlwaysRebuild() &&
15106 Type == E->getTypeInfoAsWritten() &&
15107 SubExpr.get() == E->getSubExpr())
15108 return E;
15109
15110 return getDerived().RebuildCXXFunctionalCastExpr(Type,
15111 E->getLParenLoc(),
15112 SubExpr.get(),
15113 E->getRParenLoc(),
15114 E->isListInitialization());
15115}
15116
15117template<typename Derived>
15118ExprResult
15119TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
15120 if (E->isTypeOperand()) {
15121 TypeSourceInfo *TInfo
15122 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15123 if (!TInfo)
15124 return ExprError();
15125
15126 if (!getDerived().AlwaysRebuild() &&
15127 TInfo == E->getTypeOperandSourceInfo())
15128 return E;
15129
15130 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15131 TInfo, E->getEndLoc());
15132 }
15133
15134 // Typeid's operand is an unevaluated context, unless it's a polymorphic
15135 // type. We must not unilaterally enter unevaluated context here, as then
15136 // semantic processing can re-transform an already transformed operand.
15137 Expr *Op = E->getExprOperand();
15138 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
15139 if (E->isGLValue()) {
15140 QualType OpType = Op->getType();
15141 if (auto *RD = OpType->getAsCXXRecordDecl()) {
15142 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
15143 DiagID: diag::err_incomplete_typeid))
15144 return ExprError();
15145
15146 if (RD->isPolymorphic())
15147 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
15148 }
15149 }
15150
15151 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
15152 Sema::ReuseLambdaContextDecl);
15153
15154 ExprResult SubExpr = getDerived().TransformExpr(Op);
15155 if (SubExpr.isInvalid())
15156 return ExprError();
15157
15158 if (!getDerived().AlwaysRebuild() &&
15159 SubExpr.get() == E->getExprOperand())
15160 return E;
15161
15162 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15163 SubExpr.get(), E->getEndLoc());
15164}
15165
15166template<typename Derived>
15167ExprResult
15168TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
15169 if (E->isTypeOperand()) {
15170 TypeSourceInfo *TInfo
15171 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15172 if (!TInfo)
15173 return ExprError();
15174
15175 if (!getDerived().AlwaysRebuild() &&
15176 TInfo == E->getTypeOperandSourceInfo())
15177 return E;
15178
15179 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15180 TInfo, E->getEndLoc());
15181 }
15182
15183 EnterExpressionEvaluationContext Unevaluated(
15184 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15185
15186 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
15187 if (SubExpr.isInvalid())
15188 return ExprError();
15189
15190 if (!getDerived().AlwaysRebuild() &&
15191 SubExpr.get() == E->getExprOperand())
15192 return E;
15193
15194 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15195 SubExpr.get(), E->getEndLoc());
15196}
15197
15198template<typename Derived>
15199ExprResult
15200TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
15201 return E;
15202}
15203
15204template<typename Derived>
15205ExprResult
15206TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
15207 CXXNullPtrLiteralExpr *E) {
15208 return E;
15209}
15210
15211template<typename Derived>
15212ExprResult
15213TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
15214
15215 // In lambdas, the qualifiers of the type depends of where in
15216 // the call operator `this` appear, and we do not have a good way to
15217 // rebuild this information, so we transform the type.
15218 //
15219 // In other contexts, the type of `this` may be overrided
15220 // for type deduction, so we need to recompute it.
15221 //
15222 // Always recompute the type if we're in the body of a lambda, and
15223 // 'this' is dependent on a lambda's explicit object parameter; we
15224 // also need to always rebuild the expression in this case to clear
15225 // the flag.
15226 QualType T = [&]() {
15227 auto &S = getSema();
15228 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
15229 return S.getCurrentThisType();
15230 if (S.getCurLambda())
15231 return getDerived().TransformType(E->getType());
15232 return S.getCurrentThisType();
15233 }();
15234
15235 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
15236 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
15237 // Mark it referenced in the new context regardless.
15238 // FIXME: this is a bit instantiation-specific.
15239 getSema().MarkThisReferenced(E);
15240 return E;
15241 }
15242
15243 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
15244}
15245
15246template<typename Derived>
15247ExprResult
15248TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
15249 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15250 if (SubExpr.isInvalid())
15251 return ExprError();
15252
15253 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
15254
15255 if (!getDerived().AlwaysRebuild() &&
15256 SubExpr.get() == E->getSubExpr())
15257 return E;
15258
15259 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
15260 E->isThrownVariableInScope());
15261}
15262
15263template<typename Derived>
15264ExprResult
15265TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
15266 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
15267 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
15268 if (!Param)
15269 return ExprError();
15270
15271 ExprResult InitRes;
15272 if (E->hasRewrittenInit()) {
15273 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15274 if (InitRes.isInvalid())
15275 return ExprError();
15276 }
15277
15278 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
15279 E->getUsedContext() == SemaRef.CurContext &&
15280 InitRes.get() == E->getRewrittenExpr())
15281 return E;
15282
15283 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
15284 InitRes.get());
15285}
15286
15287template<typename Derived>
15288ExprResult
15289TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
15290 FieldDecl *Field = cast_or_null<FieldDecl>(
15291 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
15292 if (!Field)
15293 return ExprError();
15294
15295 ExprResult InitRes;
15296 if (E->hasRewrittenInit()) {
15297 // The initializer can refer to `this` and to other members, so it has to
15298 // be transformed in the scope of the field's class.
15299 Sema::CXXThisScopeRAII ThisScope(SemaRef, Field->getParent(), Qualifiers());
15300 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15301 if (InitRes.isInvalid())
15302 return ExprError();
15303 }
15304
15305 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
15306 E->getUsedContext() == SemaRef.CurContext &&
15307 InitRes.get() == E->getExpr())
15308 return E;
15309
15310 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field,
15311 InitRes.get());
15312}
15313
15314template<typename Derived>
15315ExprResult
15316TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
15317 CXXScalarValueInitExpr *E) {
15318 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
15319 if (!T)
15320 return ExprError();
15321
15322 if (!getDerived().AlwaysRebuild() &&
15323 T == E->getTypeSourceInfo())
15324 return E;
15325
15326 return getDerived().RebuildCXXScalarValueInitExpr(T,
15327 /*FIXME:*/T->getTypeLoc().getEndLoc(),
15328 E->getRParenLoc());
15329}
15330
15331template<typename Derived>
15332ExprResult
15333TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
15334 // Transform the type that we're allocating
15335 TypeSourceInfo *AllocTypeInfo =
15336 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
15337 if (!AllocTypeInfo)
15338 return ExprError();
15339
15340 // Transform the size of the array we're allocating (if any).
15341 std::optional<Expr *> ArraySize;
15342 if (E->isArray()) {
15343 ExprResult NewArraySize;
15344 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
15345 NewArraySize = getDerived().TransformExpr(*OldArraySize);
15346 if (NewArraySize.isInvalid())
15347 return ExprError();
15348 }
15349 ArraySize = NewArraySize.get();
15350 }
15351
15352 // Transform the placement arguments (if any).
15353 bool ArgumentChanged = false;
15354 SmallVector<Expr*, 8> PlacementArgs;
15355 if (getDerived().TransformExprs(E->getPlacementArgs(),
15356 E->getNumPlacementArgs(), true,
15357 PlacementArgs, &ArgumentChanged))
15358 return ExprError();
15359
15360 // Transform the initializer (if any).
15361 Expr *OldInit = E->getInitializer();
15362 ExprResult NewInit;
15363 if (OldInit)
15364 NewInit = getDerived().TransformInitializer(OldInit, true);
15365 if (NewInit.isInvalid())
15366 return ExprError();
15367
15368 // Transform new operator and delete operator.
15369 FunctionDecl *OperatorNew = nullptr;
15370 if (E->getOperatorNew()) {
15371 OperatorNew = cast_or_null<FunctionDecl>(
15372 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
15373 if (!OperatorNew)
15374 return ExprError();
15375 }
15376
15377 FunctionDecl *OperatorDelete = nullptr;
15378 if (E->getOperatorDelete()) {
15379 OperatorDelete = cast_or_null<FunctionDecl>(
15380 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15381 if (!OperatorDelete)
15382 return ExprError();
15383 }
15384
15385 if (!getDerived().AlwaysRebuild() &&
15386 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
15387 ArraySize == E->getArraySize() &&
15388 NewInit.get() == OldInit &&
15389 OperatorNew == E->getOperatorNew() &&
15390 OperatorDelete == E->getOperatorDelete() &&
15391 !ArgumentChanged) {
15392 // Mark any declarations we need as referenced.
15393 // FIXME: instantiation-specific.
15394 if (OperatorNew)
15395 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
15396 if (OperatorDelete)
15397 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15398
15399 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
15400 QualType ElementType
15401 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
15402 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
15403 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
15404 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
15405 }
15406 }
15407
15408 return E;
15409 }
15410
15411 QualType AllocType = AllocTypeInfo->getType();
15412 if (!ArraySize) {
15413 // If no array size was specified, but the new expression was
15414 // instantiated with an array type (e.g., "new T" where T is
15415 // instantiated with "int[4]"), extract the outer bound from the
15416 // array type as our array size. We do this with constant and
15417 // dependently-sized array types.
15418 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
15419 if (!ArrayT) {
15420 // Do nothing
15421 } else if (const ConstantArrayType *ConsArrayT
15422 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
15423 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
15424 type: SemaRef.Context.getSizeType(),
15425 /*FIXME:*/ l: E->getBeginLoc());
15426 AllocType = ConsArrayT->getElementType();
15427 } else if (const DependentSizedArrayType *DepArrayT
15428 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
15429 if (DepArrayT->getSizeExpr()) {
15430 ArraySize = DepArrayT->getSizeExpr();
15431 AllocType = DepArrayT->getElementType();
15432 }
15433 }
15434 }
15435
15436 return getDerived().RebuildCXXNewExpr(
15437 E->getBeginLoc(), E->isGlobalNew(),
15438 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
15439 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
15440 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
15441}
15442
15443template<typename Derived>
15444ExprResult
15445TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
15446 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
15447 if (Operand.isInvalid())
15448 return ExprError();
15449
15450 // Transform the delete operator, if known.
15451 FunctionDecl *OperatorDelete = nullptr;
15452 if (E->getOperatorDelete()) {
15453 OperatorDelete = cast_or_null<FunctionDecl>(
15454 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15455 if (!OperatorDelete)
15456 return ExprError();
15457 }
15458
15459 if (!getDerived().AlwaysRebuild() &&
15460 Operand.get() == E->getArgument() &&
15461 OperatorDelete == E->getOperatorDelete()) {
15462 // Mark any declarations we need as referenced.
15463 // FIXME: instantiation-specific.
15464 if (OperatorDelete)
15465 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15466
15467 if (!E->getArgument()->isTypeDependent()) {
15468 QualType Destroyed = SemaRef.Context.getBaseElementType(
15469 QT: E->getDestroyedType());
15470 if (auto *Record = Destroyed->getAsCXXRecordDecl())
15471 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15472 Func: SemaRef.LookupDestructor(Class: Record));
15473 }
15474
15475 return E;
15476 }
15477
15478 return getDerived().RebuildCXXDeleteExpr(
15479 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
15480}
15481
15482template<typename Derived>
15483ExprResult
15484TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
15485 CXXPseudoDestructorExpr *E) {
15486 ExprResult Base = getDerived().TransformExpr(E->getBase());
15487 if (Base.isInvalid())
15488 return ExprError();
15489
15490 ParsedType ObjectTypePtr;
15491 bool MayBePseudoDestructor = false;
15492 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15493 OpLoc: E->getOperatorLoc(),
15494 OpKind: E->isArrow()? tok::arrow : tok::period,
15495 ObjectType&: ObjectTypePtr,
15496 MayBePseudoDestructor);
15497 if (Base.isInvalid())
15498 return ExprError();
15499
15500 QualType ObjectType = ObjectTypePtr.get();
15501 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
15502 if (QualifierLoc) {
15503 QualifierLoc
15504 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
15505 if (!QualifierLoc)
15506 return ExprError();
15507 }
15508 CXXScopeSpec SS;
15509 SS.Adopt(Other: QualifierLoc);
15510
15511 PseudoDestructorTypeStorage Destroyed;
15512 if (E->getDestroyedTypeInfo()) {
15513 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
15514 E->getDestroyedTypeInfo(), ObjectType,
15515 /*FirstQualifierInScope=*/nullptr);
15516 if (!DestroyedTypeInfo)
15517 return ExprError();
15518 Destroyed = DestroyedTypeInfo;
15519 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
15520 // We aren't likely to be able to resolve the identifier down to a type
15521 // now anyway, so just retain the identifier.
15522 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
15523 E->getDestroyedTypeLoc());
15524 } else {
15525 // Look for a destructor known with the given name.
15526 ParsedType T = SemaRef.getDestructorName(
15527 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
15528 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
15529 if (!T)
15530 return ExprError();
15531
15532 Destroyed
15533 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
15534 Loc: E->getDestroyedTypeLoc());
15535 }
15536
15537 TypeSourceInfo *ScopeTypeInfo = nullptr;
15538 if (E->getScopeTypeInfo()) {
15539 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
15540 E->getScopeTypeInfo(), ObjectType, nullptr);
15541 if (!ScopeTypeInfo)
15542 return ExprError();
15543 }
15544
15545 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
15546 E->getOperatorLoc(),
15547 E->isArrow(),
15548 SS,
15549 ScopeTypeInfo,
15550 E->getColonColonLoc(),
15551 E->getTildeLoc(),
15552 Destroyed);
15553}
15554
15555template <typename Derived>
15556bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
15557 bool RequiresADL,
15558 LookupResult &R) {
15559 // Transform all the decls.
15560 bool AllEmptyPacks = true;
15561 for (auto *OldD : Old->decls()) {
15562 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15563 if (!InstD) {
15564 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15565 // This can happen because of dependent hiding.
15566 if (isa<UsingShadowDecl>(Val: OldD))
15567 continue;
15568 else {
15569 R.clear();
15570 return true;
15571 }
15572 }
15573
15574 // Expand using pack declarations.
15575 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15576 ArrayRef<NamedDecl*> Decls = SingleDecl;
15577 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15578 Decls = UPD->expansions();
15579
15580 // Expand using declarations.
15581 for (auto *D : Decls) {
15582 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15583 for (auto *SD : UD->shadows())
15584 R.addDecl(D: SD);
15585 } else {
15586 R.addDecl(D);
15587 }
15588 }
15589
15590 AllEmptyPacks &= Decls.empty();
15591 }
15592
15593 // C++ [temp.res]/8.4.2:
15594 // The program is ill-formed, no diagnostic required, if [...] lookup for
15595 // a name in the template definition found a using-declaration, but the
15596 // lookup in the corresponding scope in the instantiation odoes not find
15597 // any declarations because the using-declaration was a pack expansion and
15598 // the corresponding pack is empty
15599 if (AllEmptyPacks && !RequiresADL) {
15600 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15601 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15602 return true;
15603 }
15604
15605 // Resolve a kind, but don't do any further analysis. If it's
15606 // ambiguous, the callee needs to deal with it.
15607 R.resolveKind();
15608
15609 if (Old->hasTemplateKeyword() && !R.empty()) {
15610 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15611 getSema().FilterAcceptableTemplateNames(R,
15612 /*AllowFunctionTemplates=*/true,
15613 /*AllowDependent=*/true);
15614 if (R.empty()) {
15615 // If a 'template' keyword was used, a lookup that finds only non-template
15616 // names is an error.
15617 getSema().Diag(R.getNameLoc(),
15618 diag::err_template_kw_refers_to_non_template)
15619 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15620 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15621 getSema().Diag(FoundDecl->getLocation(),
15622 diag::note_template_kw_refers_to_non_template)
15623 << R.getLookupName();
15624 return true;
15625 }
15626 }
15627
15628 return false;
15629}
15630
15631template <typename Derived>
15632ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15633 UnresolvedLookupExpr *Old) {
15634 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15635}
15636
15637template <typename Derived>
15638ExprResult
15639TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15640 bool IsAddressOfOperand) {
15641 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15642 Sema::LookupOrdinaryName);
15643
15644 // Transform the declaration set.
15645 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15646 return ExprError();
15647
15648 // Rebuild the nested-name qualifier, if present.
15649 CXXScopeSpec SS;
15650 if (Old->getQualifierLoc()) {
15651 NestedNameSpecifierLoc QualifierLoc
15652 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15653 if (!QualifierLoc)
15654 return ExprError();
15655
15656 SS.Adopt(Other: QualifierLoc);
15657 }
15658
15659 if (Old->getNamingClass()) {
15660 CXXRecordDecl *NamingClass
15661 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15662 Old->getNameLoc(),
15663 Old->getNamingClass()));
15664 if (!NamingClass) {
15665 R.clear();
15666 return ExprError();
15667 }
15668
15669 R.setNamingClass(NamingClass);
15670 }
15671
15672 // Rebuild the template arguments, if any.
15673 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15674 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15675 if (Old->hasExplicitTemplateArgs() &&
15676 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15677 Old->getNumTemplateArgs(),
15678 TransArgs)) {
15679 R.clear();
15680 return ExprError();
15681 }
15682
15683 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15684 // a non-static data member is named in an unevaluated operand, or when
15685 // a member is named in a dependent class scope function template explicit
15686 // specialization that is neither declared static nor with an explicit object
15687 // parameter.
15688 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15689 return SemaRef.BuildPossibleImplicitMemberExpr(
15690 SS, TemplateKWLoc, R,
15691 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15692 /*S=*/S: nullptr);
15693
15694 // If we have neither explicit template arguments, nor the template keyword,
15695 // it's a normal declaration name or member reference.
15696 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15697 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15698
15699 // If we have template arguments, then rebuild the template-id expression.
15700 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15701 Old->requiresADL(), &TransArgs);
15702}
15703
15704template<typename Derived>
15705ExprResult
15706TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15707 bool ArgChanged = false;
15708 SmallVector<TypeSourceInfo *, 4> Args;
15709 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15710 TypeSourceInfo *From = E->getArg(I);
15711 TypeLoc FromTL = From->getTypeLoc();
15712 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15713 TypeLocBuilder TLB;
15714 TLB.reserve(Requested: FromTL.getFullDataSize());
15715 QualType To = getDerived().TransformType(TLB, FromTL);
15716 if (To.isNull())
15717 return ExprError();
15718
15719 if (To == From->getType())
15720 Args.push_back(Elt: From);
15721 else {
15722 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15723 ArgChanged = true;
15724 }
15725 continue;
15726 }
15727
15728 ArgChanged = true;
15729
15730 // We have a pack expansion. Instantiate it.
15731 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15732 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15733 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15734 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15735
15736 // Determine whether the set of unexpanded parameter packs can and should
15737 // be expanded.
15738 bool Expand = true;
15739 bool RetainExpansion = false;
15740 UnsignedOrNone OrigNumExpansions =
15741 ExpansionTL.getTypePtr()->getNumExpansions();
15742 UnsignedOrNone NumExpansions = OrigNumExpansions;
15743 if (getDerived().TryExpandParameterPacks(
15744 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15745 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15746 RetainExpansion, NumExpansions))
15747 return ExprError();
15748
15749 if (!Expand) {
15750 // The transform has determined that we should perform a simple
15751 // transformation on the pack expansion, producing another pack
15752 // expansion.
15753 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15754
15755 TypeLocBuilder TLB;
15756 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15757
15758 QualType To = getDerived().TransformType(TLB, PatternTL);
15759 if (To.isNull())
15760 return ExprError();
15761
15762 To = getDerived().RebuildPackExpansionType(To,
15763 PatternTL.getSourceRange(),
15764 ExpansionTL.getEllipsisLoc(),
15765 NumExpansions);
15766 if (To.isNull())
15767 return ExprError();
15768
15769 PackExpansionTypeLoc ToExpansionTL
15770 = TLB.push<PackExpansionTypeLoc>(T: To);
15771 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15772 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15773 continue;
15774 }
15775
15776 // Expand the pack expansion by substituting for each argument in the
15777 // pack(s).
15778 for (unsigned I = 0; I != *NumExpansions; ++I) {
15779 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15780 TypeLocBuilder TLB;
15781 TLB.reserve(Requested: PatternTL.getFullDataSize());
15782 QualType To = getDerived().TransformType(TLB, PatternTL);
15783 if (To.isNull())
15784 return ExprError();
15785
15786 if (To->containsUnexpandedParameterPack()) {
15787 To = getDerived().RebuildPackExpansionType(To,
15788 PatternTL.getSourceRange(),
15789 ExpansionTL.getEllipsisLoc(),
15790 NumExpansions);
15791 if (To.isNull())
15792 return ExprError();
15793
15794 PackExpansionTypeLoc ToExpansionTL
15795 = TLB.push<PackExpansionTypeLoc>(T: To);
15796 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15797 }
15798
15799 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15800 }
15801
15802 if (!RetainExpansion)
15803 continue;
15804
15805 // If we're supposed to retain a pack expansion, do so by temporarily
15806 // forgetting the partially-substituted parameter pack.
15807 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15808
15809 TypeLocBuilder TLB;
15810 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15811
15812 QualType To = getDerived().TransformType(TLB, PatternTL);
15813 if (To.isNull())
15814 return ExprError();
15815
15816 To = getDerived().RebuildPackExpansionType(To,
15817 PatternTL.getSourceRange(),
15818 ExpansionTL.getEllipsisLoc(),
15819 NumExpansions);
15820 if (To.isNull())
15821 return ExprError();
15822
15823 PackExpansionTypeLoc ToExpansionTL
15824 = TLB.push<PackExpansionTypeLoc>(T: To);
15825 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15826 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15827 }
15828
15829 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15830 return E;
15831
15832 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15833 E->getEndLoc());
15834}
15835
15836template<typename Derived>
15837ExprResult
15838TreeTransform<Derived>::TransformConceptSpecializationExpr(
15839 ConceptSpecializationExpr *E) {
15840 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15841 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15842 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15843 Old->NumTemplateArgs, TransArgs))
15844 return ExprError();
15845
15846 return getDerived().RebuildConceptSpecializationExpr(
15847 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15848 E->getConceptNameInfo(), E->getFoundDecl(), E->getConceptDecl(),
15849 &TransArgs);
15850}
15851
15852template<typename Derived>
15853ExprResult
15854TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15855 SmallVector<ParmVarDecl*, 4> TransParams;
15856 SmallVector<QualType, 4> TransParamTypes;
15857 Sema::ExtParameterInfoBuilder ExtParamInfos;
15858
15859 // C++2a [expr.prim.req]p2
15860 // Expressions appearing within a requirement-body are unevaluated operands.
15861 EnterExpressionEvaluationContext Ctx(
15862 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15863 Sema::ReuseLambdaContextDecl);
15864
15865 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15866 C&: getSema().Context, DC: getSema().CurContext,
15867 StartLoc: E->getBody()->getBeginLoc());
15868
15869 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15870
15871 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15872 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15873 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15874
15875 for (ParmVarDecl *Param : TransParams)
15876 if (Param)
15877 Param->setDeclContext(Body);
15878
15879 // On failure to transform, TransformRequiresTypeParams returns an expression
15880 // in the event that the transformation of the type params failed in some way.
15881 // It is expected that this will result in a 'not satisfied' Requires clause
15882 // when instantiating.
15883 if (!TypeParamResult.isUnset())
15884 return TypeParamResult;
15885
15886 SmallVector<concepts::Requirement *, 4> TransReqs;
15887 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15888 TransReqs))
15889 return ExprError();
15890
15891 for (concepts::Requirement *Req : TransReqs) {
15892 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15893 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15894 ER->getReturnTypeRequirement()
15895 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15896 ->setDeclContext(Body);
15897 }
15898 }
15899 }
15900
15901 return getDerived().RebuildRequiresExpr(
15902 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15903 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15904}
15905
15906template<typename Derived>
15907bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15908 ArrayRef<concepts::Requirement *> Reqs,
15909 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15910 for (concepts::Requirement *Req : Reqs) {
15911 concepts::Requirement *TransReq = nullptr;
15912 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15913 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15914 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15915 TransReq = getDerived().TransformExprRequirement(ExprReq);
15916 else
15917 TransReq = getDerived().TransformNestedRequirement(
15918 cast<concepts::NestedRequirement>(Val: Req));
15919 if (!TransReq)
15920 return true;
15921 Transformed.push_back(Elt: TransReq);
15922 }
15923 return false;
15924}
15925
15926template<typename Derived>
15927concepts::TypeRequirement *
15928TreeTransform<Derived>::TransformTypeRequirement(
15929 concepts::TypeRequirement *Req) {
15930 if (Req->isSubstitutionFailure()) {
15931 if (getDerived().AlwaysRebuild())
15932 return getDerived().RebuildTypeRequirement(
15933 Req->getSubstitutionDiagnostic());
15934 return Req;
15935 }
15936 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15937 if (!TransType)
15938 return nullptr;
15939 return getDerived().RebuildTypeRequirement(TransType);
15940}
15941
15942template<typename Derived>
15943concepts::ExprRequirement *
15944TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15945 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15946 if (Req->isExprSubstitutionFailure())
15947 TransExpr = Req->getExprSubstitutionDiagnostic();
15948 else {
15949 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15950 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15951 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15952 if (TransExprRes.isInvalid())
15953 return nullptr;
15954 TransExpr = TransExprRes.get();
15955 }
15956
15957 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15958 const auto &RetReq = Req->getReturnTypeRequirement();
15959 if (RetReq.isEmpty())
15960 TransRetReq.emplace();
15961 else if (RetReq.isSubstitutionFailure())
15962 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15963 else if (RetReq.isTypeConstraint()) {
15964 TemplateParameterList *OrigTPL =
15965 RetReq.getTypeConstraintTemplateParameterList();
15966 TemplateParameterList *TPL =
15967 getDerived().TransformTemplateParameterList(OrigTPL);
15968 if (!TPL)
15969 return nullptr;
15970 TransRetReq.emplace(args&: TPL);
15971 }
15972 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15973 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15974 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15975 Req->getNoexceptLoc(),
15976 std::move(*TransRetReq));
15977 return getDerived().RebuildExprRequirement(
15978 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15979 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15980}
15981
15982template<typename Derived>
15983concepts::NestedRequirement *
15984TreeTransform<Derived>::TransformNestedRequirement(
15985 concepts::NestedRequirement *Req) {
15986 if (Req->hasInvalidConstraint()) {
15987 if (getDerived().AlwaysRebuild())
15988 return getDerived().RebuildNestedRequirement(
15989 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15990 return Req;
15991 }
15992 ExprResult TransConstraint =
15993 getDerived().TransformExpr(Req->getConstraintExpr());
15994 if (TransConstraint.isInvalid())
15995 return nullptr;
15996 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15997}
15998
15999template<typename Derived>
16000ExprResult
16001TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
16002 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
16003 if (!T)
16004 return ExprError();
16005
16006 if (!getDerived().AlwaysRebuild() &&
16007 T == E->getQueriedTypeSourceInfo())
16008 return E;
16009
16010 ExprResult SubExpr;
16011 {
16012 EnterExpressionEvaluationContext Unevaluated(
16013 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16014 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
16015 if (SubExpr.isInvalid())
16016 return ExprError();
16017 }
16018
16019 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
16020 SubExpr.get(), E->getEndLoc());
16021}
16022
16023template<typename Derived>
16024ExprResult
16025TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
16026 ExprResult SubExpr;
16027 {
16028 EnterExpressionEvaluationContext Unevaluated(
16029 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16030 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
16031 if (SubExpr.isInvalid())
16032 return ExprError();
16033
16034 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
16035 return E;
16036 }
16037
16038 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
16039 SubExpr.get(), E->getEndLoc());
16040}
16041
16042template <typename Derived>
16043ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
16044 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
16045 TypeSourceInfo **RecoveryTSI) {
16046 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
16047 DRE, AddrTaken, RecoveryTSI);
16048
16049 // Propagate both errors and recovered types, which return ExprEmpty.
16050 if (!NewDRE.isUsable())
16051 return NewDRE;
16052
16053 // We got an expr, wrap it up in parens.
16054 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
16055 return PE;
16056 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
16057 PE->getRParen());
16058}
16059
16060template <typename Derived>
16061ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16062 DependentScopeDeclRefExpr *E) {
16063 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
16064 nullptr);
16065}
16066
16067template <typename Derived>
16068ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16069 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
16070 TypeSourceInfo **RecoveryTSI) {
16071 assert(E->getQualifierLoc());
16072 NestedNameSpecifierLoc QualifierLoc =
16073 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
16074 if (!QualifierLoc)
16075 return ExprError();
16076 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16077
16078 // TODO: If this is a conversion-function-id, verify that the
16079 // destination type name (if present) resolves the same way after
16080 // instantiation as it did in the local scope.
16081
16082 DeclarationNameInfo NameInfo =
16083 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
16084 if (!NameInfo.getName())
16085 return ExprError();
16086
16087 if (!E->hasExplicitTemplateArgs()) {
16088 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
16089 // Note: it is sufficient to compare the Name component of NameInfo:
16090 // if name has not changed, DNLoc has not changed either.
16091 NameInfo.getName() == E->getDeclName())
16092 return E;
16093
16094 return getDerived().RebuildDependentScopeDeclRefExpr(
16095 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
16096 IsAddressOfOperand, RecoveryTSI);
16097 }
16098
16099 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16100 if (getDerived().TransformTemplateArguments(
16101 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
16102 return ExprError();
16103
16104 return getDerived().RebuildDependentScopeDeclRefExpr(
16105 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
16106 RecoveryTSI);
16107}
16108
16109template<typename Derived>
16110ExprResult
16111TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
16112 // CXXConstructExprs other than for list-initialization and
16113 // CXXTemporaryObjectExpr are always implicit, so when we have
16114 // a 1-argument construction we just transform that argument.
16115 if (getDerived().AllowSkippingCXXConstructExpr() &&
16116 ((E->getNumArgs() == 1 ||
16117 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
16118 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
16119 !E->isListInitialization()))
16120 return getDerived().TransformInitializer(E->getArg(Arg: 0),
16121 /*DirectInit*/ false);
16122
16123 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
16124
16125 QualType T = getDerived().TransformType(E->getType());
16126 if (T.isNull())
16127 return ExprError();
16128
16129 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16130 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16131 if (!Constructor)
16132 return ExprError();
16133
16134 bool ArgumentChanged = false;
16135 SmallVector<Expr*, 8> Args;
16136 {
16137 EnterExpressionEvaluationContext Context(
16138 getSema(), EnterExpressionEvaluationContext::InitList,
16139 E->isListInitialization());
16140 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
16141 &ArgumentChanged))
16142 return ExprError();
16143 }
16144
16145 if (!getDerived().AlwaysRebuild() &&
16146 T == E->getType() &&
16147 Constructor == E->getConstructor() &&
16148 !ArgumentChanged) {
16149 // Mark the constructor as referenced.
16150 // FIXME: Instantiation-specific
16151 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16152 return E;
16153 }
16154
16155 return getDerived().RebuildCXXConstructExpr(
16156 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
16157 E->hadMultipleCandidates(), E->isListInitialization(),
16158 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
16159 E->getConstructionKind(), E->getParenOrBraceRange());
16160}
16161
16162template<typename Derived>
16163ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
16164 CXXInheritedCtorInitExpr *E) {
16165 QualType T = getDerived().TransformType(E->getType());
16166 if (T.isNull())
16167 return ExprError();
16168
16169 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16170 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16171 if (!Constructor)
16172 return ExprError();
16173
16174 if (!getDerived().AlwaysRebuild() &&
16175 T == E->getType() &&
16176 Constructor == E->getConstructor()) {
16177 // Mark the constructor as referenced.
16178 // FIXME: Instantiation-specific
16179 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16180 return E;
16181 }
16182
16183 return getDerived().RebuildCXXInheritedCtorInitExpr(
16184 T, E->getLocation(), Constructor,
16185 E->constructsVBase(), E->inheritedFromVBase());
16186}
16187
16188/// Transform a C++ temporary-binding expression.
16189///
16190/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
16191/// transform the subexpression and return that.
16192template<typename Derived>
16193ExprResult
16194TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
16195 if (auto *Dtor = E->getTemporary()->getDestructor())
16196 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
16197 Func: const_cast<CXXDestructorDecl *>(Dtor));
16198 return getDerived().TransformExpr(E->getSubExpr());
16199}
16200
16201/// Transform a C++ expression that contains cleanups that should
16202/// be run after the expression is evaluated.
16203///
16204/// Since ExprWithCleanups nodes are implicitly generated, we
16205/// just transform the subexpression and return that.
16206template<typename Derived>
16207ExprResult
16208TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
16209 return getDerived().TransformExpr(E->getSubExpr());
16210}
16211
16212template<typename Derived>
16213ExprResult
16214TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
16215 CXXTemporaryObjectExpr *E) {
16216 TypeSourceInfo *T =
16217 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16218 if (!T)
16219 return ExprError();
16220
16221 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16222 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16223 if (!Constructor)
16224 return ExprError();
16225
16226 bool ArgumentChanged = false;
16227 SmallVector<Expr*, 8> Args;
16228 Args.reserve(N: E->getNumArgs());
16229 {
16230 EnterExpressionEvaluationContext Context(
16231 getSema(), EnterExpressionEvaluationContext::InitList,
16232 E->isListInitialization());
16233 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
16234 ArgChanged: &ArgumentChanged))
16235 return ExprError();
16236
16237 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
16238 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc(),
16239 /*IsExplicit=*/IsExplicit: true);
16240 if (Res.isInvalid())
16241 return ExprError();
16242 Args = {Res.get()};
16243 }
16244 }
16245
16246 if (!getDerived().AlwaysRebuild() &&
16247 T == E->getTypeSourceInfo() &&
16248 Constructor == E->getConstructor() &&
16249 !ArgumentChanged) {
16250 // FIXME: Instantiation-specific
16251 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16252 return SemaRef.MaybeBindToTemporary(E);
16253 }
16254
16255 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
16256 return getDerived().RebuildCXXTemporaryObjectExpr(
16257 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
16258}
16259
16260template<typename Derived>
16261ExprResult
16262TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
16263 // Transform any init-capture expressions before entering the scope of the
16264 // lambda body, because they are not semantically within that scope.
16265 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
16266 struct TransformedInitCapture {
16267 // The location of the ... if the result is retaining a pack expansion.
16268 SourceLocation EllipsisLoc;
16269 // Zero or more expansions of the init-capture.
16270 SmallVector<InitCaptureInfoTy, 4> Expansions;
16271 };
16272 SmallVector<TransformedInitCapture, 4> InitCaptures;
16273 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
16274 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16275 CEnd = E->capture_end();
16276 C != CEnd; ++C) {
16277 if (!E->isInitCapture(Capture: C))
16278 continue;
16279
16280 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
16281 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16282
16283 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
16284 UnsignedOrNone NumExpansions) {
16285 ExprResult NewExprInitResult = getDerived().TransformInitializer(
16286 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
16287
16288 if (NewExprInitResult.isInvalid()) {
16289 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
16290 return;
16291 }
16292 Expr *NewExprInit = NewExprInitResult.get();
16293
16294 QualType NewInitCaptureType =
16295 getSema().buildLambdaInitCaptureInitialization(
16296 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
16297 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
16298 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
16299 VarDecl::CInit,
16300 NewExprInit);
16301 Result.Expansions.push_back(
16302 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
16303 };
16304
16305 // If this is an init-capture pack, consider expanding the pack now.
16306 if (OldVD->isParameterPack()) {
16307 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
16308 ->getTypeLoc()
16309 .castAs<PackExpansionTypeLoc>();
16310 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16311 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
16312
16313 // Determine whether the set of unexpanded parameter packs can and should
16314 // be expanded.
16315 bool Expand = true;
16316 bool RetainExpansion = false;
16317 UnsignedOrNone OrigNumExpansions =
16318 ExpansionTL.getTypePtr()->getNumExpansions();
16319 UnsignedOrNone NumExpansions = OrigNumExpansions;
16320 if (getDerived().TryExpandParameterPacks(
16321 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
16322 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
16323 RetainExpansion, NumExpansions))
16324 return ExprError();
16325 assert(!RetainExpansion && "Should not need to retain expansion after a "
16326 "capture since it cannot be extended");
16327 if (Expand) {
16328 for (unsigned I = 0; I != *NumExpansions; ++I) {
16329 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16330 SubstInitCapture(SourceLocation(), std::nullopt);
16331 }
16332 } else {
16333 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
16334 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
16335 }
16336 } else {
16337 SubstInitCapture(SourceLocation(), std::nullopt);
16338 }
16339 }
16340
16341 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
16342 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
16343
16344 // Create the local class that will describe the lambda.
16345
16346 // FIXME: DependencyKind below is wrong when substituting inside a templated
16347 // context that isn't a DeclContext (such as a variable template), or when
16348 // substituting an unevaluated lambda inside of a function's parameter's type
16349 // - as parameter types are not instantiated from within a function's DC. We
16350 // use evaluation contexts to distinguish the function parameter case.
16351 CXXRecordDecl::LambdaDependencyKind DependencyKind =
16352 CXXRecordDecl::LDK_Unknown;
16353 DeclContext *DC = getSema().CurContext;
16354 // A RequiresExprBodyDecl is not interesting for dependencies.
16355 // For the following case,
16356 //
16357 // template <typename>
16358 // concept C = requires { [] {}; };
16359 //
16360 // template <class F>
16361 // struct Widget;
16362 //
16363 // template <C F>
16364 // struct Widget<F> {};
16365 //
16366 // While we are substituting Widget<F>, the parent of DC would be
16367 // the template specialization itself. Thus, the lambda expression
16368 // will be deemed as dependent even if there are no dependent template
16369 // arguments.
16370 // (A ClassTemplateSpecializationDecl is always a dependent context.)
16371 while (DC->isRequiresExprBody() || isa<CXXExpansionStmtDecl>(Val: DC))
16372 DC = DC->getParent();
16373 if ((getSema().isUnevaluatedContext() ||
16374 getSema().isConstantEvaluatedContext()) &&
16375 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
16376 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
16377 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
16378 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
16379
16380 CXXRecordDecl *OldClass = E->getLambdaClass();
16381 CXXRecordDecl *Class = getSema().createLambdaClosureType(
16382 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
16383 E->getCaptureDefault());
16384 getDerived().transformedLocalDecl(OldClass, {Class});
16385
16386 CXXMethodDecl *NewCallOperator =
16387 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
16388
16389 // Enter the scope of the lambda.
16390 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
16391 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
16392 E->hasExplicitParameters(), E->isMutable());
16393
16394 // Introduce the context of the call operator.
16395 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
16396 /*NewThisContext*/false);
16397
16398 bool Invalid = false;
16399
16400 // Transform captures.
16401 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16402 CEnd = E->capture_end();
16403 C != CEnd; ++C) {
16404 // When we hit the first implicit capture, tell Sema that we've finished
16405 // the list of explicit captures.
16406 if (C->isImplicit())
16407 break;
16408
16409 // Capturing 'this' is trivial.
16410 if (C->capturesThis()) {
16411 // If this is a lambda that is part of a default member initialiser
16412 // and which we're instantiating outside the class that 'this' is
16413 // supposed to refer to, adjust the type of 'this' accordingly.
16414 //
16415 // Otherwise, leave the type of 'this' as-is.
16416 Sema::CXXThisScopeRAII ThisScope(
16417 getSema(),
16418 dyn_cast_if_present<CXXRecordDecl>(
16419 getSema().getFunctionLevelDeclContext()),
16420 Qualifiers());
16421 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16422 /*BuildAndDiagnose*/ true, nullptr,
16423 C->getCaptureKind() == LCK_StarThis);
16424 continue;
16425 }
16426 // Captured expression will be recaptured during captured variables
16427 // rebuilding.
16428 if (C->capturesVLAType())
16429 continue;
16430
16431 // Rebuild init-captures, including the implied field declaration.
16432 if (E->isInitCapture(Capture: C)) {
16433 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
16434
16435 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16436 llvm::SmallVector<Decl*, 4> NewVDs;
16437
16438 for (InitCaptureInfoTy &Info : NewC.Expansions) {
16439 ExprResult Init = Info.first;
16440 QualType InitQualType = Info.second;
16441 if (Init.isInvalid() || InitQualType.isNull()) {
16442 Invalid = true;
16443 break;
16444 }
16445 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
16446 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
16447 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
16448 getSema().CurContext);
16449 if (!NewVD) {
16450 Invalid = true;
16451 break;
16452 }
16453 NewVDs.push_back(Elt: NewVD);
16454 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
16455 // Cases we want to tackle:
16456 // ([C(Pack)] {}, ...)
16457 // But rule out cases e.g.
16458 // [...C = Pack()] {}
16459 if (NewC.EllipsisLoc.isInvalid())
16460 LSI->ContainsUnexpandedParameterPack |=
16461 Init.get()->containsUnexpandedParameterPack();
16462 }
16463
16464 if (Invalid)
16465 break;
16466
16467 getDerived().transformedLocalDecl(OldVD, NewVDs);
16468 continue;
16469 }
16470
16471 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16472
16473 // Determine the capture kind for Sema.
16474 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
16475 : C->getCaptureKind() == LCK_ByCopy
16476 ? TryCaptureKind::ExplicitByVal
16477 : TryCaptureKind::ExplicitByRef;
16478 SourceLocation EllipsisLoc;
16479 if (C->isPackExpansion()) {
16480 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
16481 bool ShouldExpand = false;
16482 bool RetainExpansion = false;
16483 UnsignedOrNone NumExpansions = std::nullopt;
16484 if (getDerived().TryExpandParameterPacks(
16485 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
16486 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16487 RetainExpansion, NumExpansions)) {
16488 Invalid = true;
16489 continue;
16490 }
16491
16492 if (ShouldExpand) {
16493 // The transform has determined that we should perform an expansion;
16494 // transform and capture each of the arguments.
16495 // expansion of the pattern. Do so.
16496 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
16497 for (unsigned I = 0; I != *NumExpansions; ++I) {
16498 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16499 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
16500 getDerived().TransformDecl(C->getLocation(), Pack));
16501 if (!CapturedVar) {
16502 Invalid = true;
16503 continue;
16504 }
16505
16506 // Capture the transformed variable.
16507 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
16508 }
16509
16510 // FIXME: Retain a pack expansion if RetainExpansion is true.
16511
16512 continue;
16513 }
16514
16515 EllipsisLoc = C->getEllipsisLoc();
16516 }
16517
16518 // Transform the captured variable.
16519 auto *CapturedVar = cast_or_null<ValueDecl>(
16520 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16521 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
16522 Invalid = true;
16523 continue;
16524 }
16525
16526 // This is not an init-capture; however it contains an unexpanded pack e.g.
16527 // ([Pack] {}(), ...)
16528 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
16529 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
16530
16531 // Capture the transformed variable.
16532 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
16533 EllipsisLoc);
16534 }
16535 getSema().finishLambdaExplicitCaptures(LSI);
16536
16537 // Transform the template parameters, and add them to the current
16538 // instantiation scope. The null case is handled correctly.
16539 auto TPL = getDerived().TransformTemplateParameterList(
16540 E->getTemplateParameterList());
16541 LSI->GLTemplateParameterList = TPL;
16542 if (TPL) {
16543 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
16544 TPL);
16545 LSI->ContainsUnexpandedParameterPack |=
16546 TPL->containsUnexpandedParameterPack();
16547 }
16548
16549 TypeLocBuilder NewCallOpTLBuilder;
16550 TypeLoc OldCallOpTypeLoc =
16551 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
16552 QualType NewCallOpType =
16553 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
16554 if (NewCallOpType.isNull())
16555 return ExprError();
16556 LSI->ContainsUnexpandedParameterPack |=
16557 NewCallOpType->containsUnexpandedParameterPack();
16558 TypeSourceInfo *NewCallOpTSI =
16559 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16560
16561 // The type may be an AttributedType or some other kind of sugar;
16562 // get the actual underlying FunctionProtoType.
16563 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16564 assert(FPTL && "Not a FunctionProtoType?");
16565
16566 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16567 if (TRC) {
16568 ExprResult E = getDerived().TransformLambdaConstraint(
16569 const_cast<Expr *>(TRC.ConstraintExpr));
16570 if (E.isInvalid())
16571 return E;
16572 TRC.ConstraintExpr = E.get();
16573 }
16574
16575 LSI->BeforeCompoundStatement = false;
16576 getSema().CompleteLambdaCallOperator(
16577 NewCallOperator, E->getCallOperator()->getLocation(),
16578 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16579 E->getCallOperator()->getConstexprKind(),
16580 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16581 E->hasExplicitResultType());
16582
16583 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16584 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16585
16586 {
16587 // Number the lambda for linkage purposes if necessary.
16588 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16589
16590 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16591 if (getDerived().ReplacingOriginal()) {
16592 Numbering = OldClass->getLambdaNumbering();
16593 }
16594
16595 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16596 }
16597
16598 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16599 // evaluation context even if we're not transforming the function body.
16600 getSema().PushExpressionEvaluationContextForFunction(
16601 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16602 E->getCallOperator());
16603
16604 StmtResult Body;
16605 {
16606 Sema::NonSFINAEContext _(getSema());
16607 Sema::CodeSynthesisContext C;
16608 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16609 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16610 getSema().pushCodeSynthesisContext(C);
16611
16612 // Instantiate the body of the lambda expression.
16613 Body = Invalid ? StmtError()
16614 : getDerived().TransformLambdaBody(E, E->getBody());
16615
16616 getSema().popCodeSynthesisContext();
16617 }
16618
16619 // ActOnLambda* will pop the function scope for us.
16620 FuncScopeCleanup.disable();
16621
16622 if (Body.isInvalid()) {
16623 SavedContext.pop();
16624 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16625 /*IsInstantiation=*/true);
16626 return ExprError();
16627 }
16628
16629 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16630 /*IsInstantiation=*/true,
16631 /*RetainFunctionScopeInfo=*/true);
16632 SavedContext.pop();
16633
16634 // Recompute the dependency of the lambda so that we can defer the lambda call
16635 // construction until after we have all the necessary template arguments. For
16636 // example, given
16637 //
16638 // template <class> struct S {
16639 // template <class U>
16640 // using Type = decltype([](U){}(42.0));
16641 // };
16642 // void foo() {
16643 // using T = S<int>::Type<float>;
16644 // ^~~~~~
16645 // }
16646 //
16647 // We would end up here from instantiating S<int> when ensuring its
16648 // completeness. That would transform the lambda call expression regardless of
16649 // the absence of the corresponding argument for U.
16650 //
16651 // Going ahead with unsubstituted type U makes things worse: we would soon
16652 // compare the argument type (which is float) against the parameter U
16653 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16654 // error suggesting unmatched types 'U' and 'float'!
16655 //
16656 // That said, everything will be fine if we defer that semantic checking.
16657 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16658 // dependent. Since the CallExpr's dependency boils down to the lambda's
16659 // dependency in this case, we can harness that by recomputing the dependency
16660 // from the instantiation arguments.
16661 //
16662 // FIXME: Creating the type of a lambda requires us to have a dependency
16663 // value, which happens before its substitution. We update its dependency
16664 // *after* the substitution in case we can't decide the dependency
16665 // so early, e.g. because we want to see if any of the *substituted*
16666 // parameters are dependent.
16667 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16668 Class->setLambdaDependencyKind(DependencyKind);
16669
16670 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16671 Body.get()->getEndLoc(), LSI);
16672}
16673
16674template<typename Derived>
16675StmtResult
16676TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16677 return TransformStmt(S);
16678}
16679
16680template<typename Derived>
16681StmtResult
16682TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16683 // Transform captures.
16684 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16685 CEnd = E->capture_end();
16686 C != CEnd; ++C) {
16687 // When we hit the first implicit capture, tell Sema that we've finished
16688 // the list of explicit captures.
16689 if (!C->isImplicit())
16690 continue;
16691
16692 // Capturing 'this' is trivial.
16693 if (C->capturesThis()) {
16694 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16695 /*BuildAndDiagnose*/ true, nullptr,
16696 C->getCaptureKind() == LCK_StarThis);
16697 continue;
16698 }
16699 // Captured expression will be recaptured during captured variables
16700 // rebuilding.
16701 if (C->capturesVLAType())
16702 continue;
16703
16704 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16705 assert(!E->isInitCapture(C) && "implicit init-capture?");
16706
16707 // Transform the captured variable.
16708 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16709 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16710 if (!CapturedVar || CapturedVar->isInvalidDecl())
16711 return StmtError();
16712
16713 // Capture the transformed variable.
16714 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16715 }
16716
16717 return S;
16718}
16719
16720template<typename Derived>
16721ExprResult
16722TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16723 CXXUnresolvedConstructExpr *E) {
16724 TypeSourceInfo *T =
16725 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16726 if (!T)
16727 return ExprError();
16728
16729 bool ArgumentChanged = false;
16730 SmallVector<Expr*, 8> Args;
16731 Args.reserve(N: E->getNumArgs());
16732 {
16733 EnterExpressionEvaluationContext Context(
16734 getSema(), EnterExpressionEvaluationContext::InitList,
16735 E->isListInitialization());
16736 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16737 &ArgumentChanged))
16738 return ExprError();
16739 }
16740
16741 if (!getDerived().AlwaysRebuild() &&
16742 T == E->getTypeSourceInfo() &&
16743 !ArgumentChanged)
16744 return E;
16745
16746 // FIXME: we're faking the locations of the commas
16747 return getDerived().RebuildCXXUnresolvedConstructExpr(
16748 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16749}
16750
16751template <typename Derived>
16752ExprResult TreeTransform<Derived>::TransformDependentTemplateIdExpr(
16753 DependentTemplateIdExpr *E) {
16754
16755 TemplateName Name = getDerived().TransformConceptTemplateName(
16756 E->getTemplateName(), E->getNameLoc());
16757 if (Name.isNull())
16758 return ExprError();
16759
16760 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16761 if (getDerived().TransformTemplateArguments(
16762 E->template_arguments().data(), E->getNumTemplateArgs(), TransArgs))
16763 return ExprError();
16764
16765 TemplateDecl *TD = Name.getAsTemplateDecl();
16766 if (!TD)
16767 return SemaRef.CheckVarOrConceptTemplateTemplateId(NameInfo: E->getNameInfo(), Template: Name,
16768 TemplateArgs: &TransArgs);
16769
16770 CXXScopeSpec SS;
16771
16772 LookupResult R(SemaRef, E->getNameInfo(), Sema::LookupOrdinaryName);
16773 R.addDecl(D: TD);
16774 R.resolveKind();
16775 return getDerived().RebuildTemplateIdExpr(
16776 SS, /*Template Keyword=*/SourceLocation(), R,
16777 /*RequiresADL=*/false, &TransArgs);
16778}
16779
16780template<typename Derived>
16781ExprResult
16782TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16783 CXXDependentScopeMemberExpr *E) {
16784 // Transform the base of the expression.
16785 ExprResult Base((Expr*) nullptr);
16786 Expr *OldBase;
16787 QualType BaseType;
16788 QualType ObjectType;
16789 if (!E->isImplicitAccess()) {
16790 OldBase = E->getBase();
16791 Base = getDerived().TransformExpr(OldBase);
16792 if (Base.isInvalid())
16793 return ExprError();
16794
16795 // Start the member reference and compute the object's type.
16796 ParsedType ObjectTy;
16797 bool MayBePseudoDestructor = false;
16798 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16799 OpLoc: E->getOperatorLoc(),
16800 OpKind: E->isArrow()? tok::arrow : tok::period,
16801 ObjectType&: ObjectTy,
16802 MayBePseudoDestructor);
16803 if (Base.isInvalid())
16804 return ExprError();
16805
16806 ObjectType = ObjectTy.get();
16807 BaseType = ((Expr*) Base.get())->getType();
16808 } else {
16809 OldBase = nullptr;
16810 BaseType = getDerived().TransformType(E->getBaseType());
16811 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16812 }
16813
16814 // Transform the first part of the nested-name-specifier that qualifies
16815 // the member name.
16816 NamedDecl *FirstQualifierInScope
16817 = getDerived().TransformFirstQualifierInScope(
16818 E->getFirstQualifierFoundInScope(),
16819 E->getQualifierLoc().getBeginLoc());
16820
16821 NestedNameSpecifierLoc QualifierLoc;
16822 if (E->getQualifier()) {
16823 QualifierLoc
16824 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16825 ObjectType,
16826 FirstQualifierInScope);
16827 if (!QualifierLoc)
16828 return ExprError();
16829 }
16830
16831 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16832
16833 // TODO: If this is a conversion-function-id, verify that the
16834 // destination type name (if present) resolves the same way after
16835 // instantiation as it did in the local scope.
16836
16837 DeclarationNameInfo NameInfo
16838 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16839 if (!NameInfo.getName())
16840 return ExprError();
16841
16842 if (!E->hasExplicitTemplateArgs()) {
16843 // This is a reference to a member without an explicitly-specified
16844 // template argument list. Optimize for this common case.
16845 if (!getDerived().AlwaysRebuild() &&
16846 Base.get() == OldBase &&
16847 BaseType == E->getBaseType() &&
16848 QualifierLoc == E->getQualifierLoc() &&
16849 NameInfo.getName() == E->getMember() &&
16850 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16851 return E;
16852
16853 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16854 BaseType,
16855 E->isArrow(),
16856 E->getOperatorLoc(),
16857 QualifierLoc,
16858 TemplateKWLoc,
16859 FirstQualifierInScope,
16860 NameInfo,
16861 /*TemplateArgs*/nullptr);
16862 }
16863
16864 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16865 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16866 E->getNumTemplateArgs(),
16867 TransArgs))
16868 return ExprError();
16869
16870 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16871 BaseType,
16872 E->isArrow(),
16873 E->getOperatorLoc(),
16874 QualifierLoc,
16875 TemplateKWLoc,
16876 FirstQualifierInScope,
16877 NameInfo,
16878 &TransArgs);
16879}
16880
16881template <typename Derived>
16882ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16883 UnresolvedMemberExpr *Old) {
16884 // Transform the base of the expression.
16885 ExprResult Base((Expr *)nullptr);
16886 QualType BaseType;
16887 if (!Old->isImplicitAccess()) {
16888 Base = getDerived().TransformExpr(Old->getBase());
16889 if (Base.isInvalid())
16890 return ExprError();
16891 Base =
16892 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16893 if (Base.isInvalid())
16894 return ExprError();
16895 BaseType = Base.get()->getType();
16896 } else {
16897 BaseType = getDerived().TransformType(Old->getBaseType());
16898 }
16899
16900 NestedNameSpecifierLoc QualifierLoc;
16901 if (Old->getQualifierLoc()) {
16902 QualifierLoc =
16903 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16904 if (!QualifierLoc)
16905 return ExprError();
16906 }
16907
16908 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16909
16910 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16911
16912 // Transform the declaration set.
16913 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16914 return ExprError();
16915
16916 // Determine the naming class.
16917 if (Old->getNamingClass()) {
16918 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16919 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16920 if (!NamingClass)
16921 return ExprError();
16922
16923 R.setNamingClass(NamingClass);
16924 }
16925
16926 TemplateArgumentListInfo TransArgs;
16927 if (Old->hasExplicitTemplateArgs()) {
16928 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16929 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16930 if (getDerived().TransformTemplateArguments(
16931 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16932 return ExprError();
16933 }
16934
16935 // FIXME: to do this check properly, we will need to preserve the
16936 // first-qualifier-in-scope here, just in case we had a dependent
16937 // base (and therefore couldn't do the check) and a
16938 // nested-name-qualifier (and therefore could do the lookup).
16939 NamedDecl *FirstQualifierInScope = nullptr;
16940
16941 return getDerived().RebuildUnresolvedMemberExpr(
16942 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16943 TemplateKWLoc, FirstQualifierInScope, R,
16944 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16945}
16946
16947template<typename Derived>
16948ExprResult
16949TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16950 EnterExpressionEvaluationContext Unevaluated(
16951 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16952 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16953 if (SubExpr.isInvalid())
16954 return ExprError();
16955
16956 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16957 return E;
16958
16959 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16960}
16961
16962template<typename Derived>
16963ExprResult
16964TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16965 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16966 if (Pattern.isInvalid())
16967 return ExprError();
16968
16969 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16970 return E;
16971
16972 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16973 E->getNumExpansions());
16974}
16975
16976template <typename Derived>
16977UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16978 ArrayRef<TemplateArgument> PackArgs) {
16979 UnsignedOrNone Result = 0u;
16980 for (const TemplateArgument &Arg : PackArgs) {
16981 if (!Arg.isPackExpansion()) {
16982 Result = *Result + 1;
16983 continue;
16984 }
16985
16986 TemplateArgumentLoc ArgLoc;
16987 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16988
16989 // Find the pattern of the pack expansion.
16990 SourceLocation Ellipsis;
16991 UnsignedOrNone OrigNumExpansions = std::nullopt;
16992 TemplateArgumentLoc Pattern =
16993 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16994 OrigNumExpansions);
16995
16996 // Substitute under the pack expansion. Do not expand the pack (yet).
16997 TemplateArgumentLoc OutPattern;
16998 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16999 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
17000 /*Uneval*/ true))
17001 return 1u;
17002
17003 // See if we can determine the number of arguments from the result.
17004 UnsignedOrNone NumExpansions =
17005 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
17006 if (!NumExpansions) {
17007 // No: we must be in an alias template expansion, and we're going to
17008 // need to actually expand the packs.
17009 Result = std::nullopt;
17010 break;
17011 }
17012
17013 Result = *Result + *NumExpansions;
17014 }
17015 return Result;
17016}
17017
17018template<typename Derived>
17019ExprResult
17020TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
17021 // If E is not value-dependent, then nothing will change when we transform it.
17022 // Note: This is an instantiation-centric view.
17023 if (!E->isValueDependent())
17024 return E;
17025
17026 EnterExpressionEvaluationContext Unevaluated(
17027 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
17028
17029 ArrayRef<TemplateArgument> PackArgs;
17030 TemplateArgument ArgStorage;
17031
17032 // Find the argument list to transform.
17033 if (E->isPartiallySubstituted()) {
17034 PackArgs = E->getPartialArguments();
17035 } else if (E->isValueDependent()) {
17036 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
17037 bool ShouldExpand = false;
17038 bool RetainExpansion = false;
17039 UnsignedOrNone NumExpansions = std::nullopt;
17040 if (getDerived().TryExpandParameterPacks(
17041 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
17042 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
17043 RetainExpansion, NumExpansions))
17044 return ExprError();
17045
17046 // If we need to expand the pack, build a template argument from it and
17047 // expand that.
17048 if (ShouldExpand) {
17049 auto *Pack = E->getPack();
17050 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
17051 ArgStorage = getSema().Context.getPackExpansionType(
17052 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
17053 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
17054 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
17055 } else {
17056 auto *VD = cast<ValueDecl>(Val: Pack);
17057 ExprResult DRE = getSema().BuildDeclRefExpr(
17058 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
17059 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
17060 E->getPackLoc());
17061 if (DRE.isInvalid())
17062 return ExprError();
17063 ArgStorage = TemplateArgument(
17064 new (getSema().Context)
17065 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
17066 /*IsCanonical=*/false);
17067 }
17068 PackArgs = ArgStorage;
17069 }
17070 }
17071
17072 // If we're not expanding the pack, just transform the decl.
17073 if (!PackArgs.size()) {
17074 auto *Pack = cast_or_null<NamedDecl>(
17075 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
17076 if (!Pack)
17077 return ExprError();
17078 return getDerived().RebuildSizeOfPackExpr(
17079 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
17080 std::nullopt, {});
17081 }
17082
17083 // Try to compute the result without performing a partial substitution.
17084 UnsignedOrNone Result =
17085 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
17086
17087 // Common case: we could determine the number of expansions without
17088 // substituting.
17089 if (Result)
17090 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
17091 E->getPackLoc(),
17092 E->getRParenLoc(), *Result, {});
17093
17094 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
17095 E->getPackLoc());
17096 {
17097 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
17098 typedef TemplateArgumentLocInventIterator<
17099 Derived, const TemplateArgument*> PackLocIterator;
17100 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
17101 PackLocIterator(*this, PackArgs.end()),
17102 TransformedPackArgs, /*Uneval*/true))
17103 return ExprError();
17104 }
17105
17106 // Check whether we managed to fully-expand the pack.
17107 // FIXME: Is it possible for us to do so and not hit the early exit path?
17108 SmallVector<TemplateArgument, 8> Args;
17109 bool PartialSubstitution = false;
17110 for (auto &Loc : TransformedPackArgs.arguments()) {
17111 Args.push_back(Elt: Loc.getArgument());
17112 if (Loc.getArgument().isPackExpansion())
17113 PartialSubstitution = true;
17114 }
17115
17116 if (PartialSubstitution)
17117 return getDerived().RebuildSizeOfPackExpr(
17118 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17119 std::nullopt, Args);
17120
17121 return getDerived().RebuildSizeOfPackExpr(
17122 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17123 /*Length=*/static_cast<unsigned>(Args.size()),
17124 /*PartialArgs=*/{});
17125}
17126
17127template <typename Derived>
17128ExprResult
17129TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
17130 if (!E->isValueDependent())
17131 return E;
17132
17133 // Transform the index
17134 ExprResult IndexExpr;
17135 {
17136 EnterExpressionEvaluationContext ConstantContext(
17137 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
17138 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
17139 if (IndexExpr.isInvalid())
17140 return ExprError();
17141 }
17142
17143 SmallVector<Expr *, 5> ExpandedExprs;
17144 bool FullySubstituted = true;
17145 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
17146 Expr *Pattern = E->getPackIdExpression();
17147 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17148 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
17149 Unexpanded);
17150 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17151
17152 // Determine whether the set of unexpanded parameter packs can and should
17153 // be expanded.
17154 bool ShouldExpand = true;
17155 bool RetainExpansion = false;
17156 UnsignedOrNone OrigNumExpansions = std::nullopt,
17157 NumExpansions = std::nullopt;
17158 if (getDerived().TryExpandParameterPacks(
17159 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17160 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
17161 RetainExpansion, NumExpansions))
17162 return true;
17163 if (!ShouldExpand) {
17164 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17165 ExprResult Pack = getDerived().TransformExpr(Pattern);
17166 if (Pack.isInvalid())
17167 return ExprError();
17168 return getDerived().RebuildPackIndexingExpr(
17169 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
17170 {}, /*FullySubstituted=*/false);
17171 }
17172 for (unsigned I = 0; I != *NumExpansions; ++I) {
17173 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17174 ExprResult Out = getDerived().TransformExpr(Pattern);
17175 if (Out.isInvalid())
17176 return true;
17177 if (Out.get()->containsUnexpandedParameterPack()) {
17178 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17179 OrigNumExpansions);
17180 if (Out.isInvalid())
17181 return true;
17182 FullySubstituted = false;
17183 }
17184 ExpandedExprs.push_back(Elt: Out.get());
17185 }
17186 // If we're supposed to retain a pack expansion, do so by temporarily
17187 // forgetting the partially-substituted parameter pack.
17188 if (RetainExpansion) {
17189 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17190
17191 ExprResult Out = getDerived().TransformExpr(Pattern);
17192 if (Out.isInvalid())
17193 return true;
17194
17195 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17196 OrigNumExpansions);
17197 if (Out.isInvalid())
17198 return true;
17199 FullySubstituted = false;
17200 ExpandedExprs.push_back(Elt: Out.get());
17201 }
17202 } else if (!E->expandsToEmptyPack()) {
17203 if (getDerived().TransformExprs(E->getExpressions().data(),
17204 E->getExpressions().size(), false,
17205 ExpandedExprs))
17206 return ExprError();
17207 }
17208
17209 return getDerived().RebuildPackIndexingExpr(
17210 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
17211 IndexExpr.get(), ExpandedExprs, FullySubstituted);
17212}
17213
17214template <typename Derived>
17215ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
17216 SubstNonTypeTemplateParmPackExpr *E) {
17217 if (!getSema().ArgPackSubstIndex)
17218 // We aren't expanding the parameter pack, so just return ourselves.
17219 return E;
17220
17221 TemplateArgument Pack = E->getArgumentPack();
17222 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
17223 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17224 E->getAssociatedDecl(), E->getParameterPack()->getPosition(),
17225 E->getParameterPack()->getType(), E->getParameterPackLocation(), Arg,
17226 SemaRef.getPackIndex(Pack), E->getFinal());
17227}
17228
17229template <typename Derived>
17230ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
17231 SubstNonTypeTemplateParmExpr *E) {
17232 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
17233
17234 // Insert a constant-evaluated context for the transform.
17235 // Otherwise, when a normalized constraint places the replacement inside
17236 // an unevaluated operand (e.g. decltype), entities it refers to are not
17237 // odr-used, and the constant evaluation performed by CheckTemplateArgument
17238 // below can spuriously fail for otherwise valid replacements,
17239 // e.g. when a call materializes a function parameter of class type whose
17240 // special members were never instantiated.
17241 EnterExpressionEvaluationContext ConstantEvaluated(
17242 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
17243 Sema::ReuseLambdaContextDecl,
17244 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
17245
17246 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
17247 if (Replacement.isInvalid())
17248 return true;
17249
17250 Decl *AssociatedDecl =
17251 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
17252 if (!AssociatedDecl)
17253 return true;
17254
17255 QualType ParamType = TransformType(E->getParameterType());
17256 if (ParamType.isNull())
17257 return true;
17258
17259 if (Replacement.get() == OrigReplacement &&
17260 AssociatedDecl == E->getAssociatedDecl() &&
17261 ParamType == E->getParameterType())
17262 return E;
17263
17264 if (Replacement.get() != OrigReplacement ||
17265 ParamType != E->getParameterType()) {
17266 auto *Param = cast<NonTypeTemplateParmDecl>(Val: std::get<0>(
17267 t: getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex())));
17268 // When transforming the replacement expression previously, all Sema
17269 // specific annotations, such as implicit casts, are discarded. Calling the
17270 // corresponding sema action is necessary to recover those. Otherwise,
17271 // equivalency of the result would be lost.
17272 TemplateArgument SugaredConverted, CanonicalConverted;
17273 Replacement = SemaRef.CheckTemplateArgument(
17274 Param, InstantiatedParamType: ParamType, Arg: Replacement.get(), SugaredConverted,
17275 CanonicalConverted,
17276 /*StrictCheck=*/StrictCheck: false, CTAK: Sema::CTAK_Specified);
17277 if (Replacement.isInvalid())
17278 return true;
17279 } else {
17280 // Otherwise, the same expression would have been produced.
17281 Replacement = E->getReplacement();
17282 }
17283
17284 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17285 AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(),
17286 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
17287 E->getPackIndex(), E->getFinal());
17288}
17289
17290template<typename Derived>
17291ExprResult
17292TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
17293 // Default behavior is to do nothing with this transformation.
17294 return E;
17295}
17296
17297template<typename Derived>
17298ExprResult
17299TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
17300 MaterializeTemporaryExpr *E) {
17301 return getDerived().TransformExpr(E->getSubExpr());
17302}
17303
17304template<typename Derived>
17305ExprResult
17306TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
17307 UnresolvedLookupExpr *Callee = nullptr;
17308 if (Expr *OldCallee = E->getCallee()) {
17309 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
17310 if (CalleeResult.isInvalid())
17311 return ExprError();
17312 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
17313 }
17314
17315 Expr *Pattern = E->getPattern();
17316
17317 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17318 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
17319 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17320
17321 // Determine whether the set of unexpanded parameter packs can and should
17322 // be expanded.
17323 bool Expand = true;
17324 bool RetainExpansion = false;
17325 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
17326 NumExpansions = OrigNumExpansions;
17327 if (getDerived().TryExpandParameterPacks(
17328 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17329 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17330 NumExpansions))
17331 return true;
17332
17333 if (!Expand) {
17334 // Do not expand any packs here, just transform and rebuild a fold
17335 // expression.
17336 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17337
17338 ExprResult LHS =
17339 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
17340 if (LHS.isInvalid())
17341 return true;
17342
17343 ExprResult RHS =
17344 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
17345 if (RHS.isInvalid())
17346 return true;
17347
17348 if (!getDerived().AlwaysRebuild() &&
17349 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
17350 return E;
17351
17352 return getDerived().RebuildCXXFoldExpr(
17353 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
17354 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
17355 }
17356
17357 // Formally a fold expression expands to nested parenthesized expressions.
17358 // Enforce this limit to avoid creating trees so deep we can't safely traverse
17359 // them.
17360 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
17361 SemaRef.Diag(Loc: E->getEllipsisLoc(),
17362 DiagID: clang::diag::err_fold_expression_limit_exceeded)
17363 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
17364 << E->getSourceRange();
17365 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
17366 return ExprError();
17367 }
17368
17369 // The transform has determined that we should perform an elementwise
17370 // expansion of the pattern. Do so.
17371 ExprResult Result = getDerived().TransformExpr(E->getInit());
17372 if (Result.isInvalid())
17373 return true;
17374 bool LeftFold = E->isLeftFold();
17375
17376 // If we're retaining an expansion for a right fold, it is the innermost
17377 // component and takes the init (if any).
17378 if (!LeftFold && RetainExpansion) {
17379 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17380
17381 ExprResult Out = getDerived().TransformExpr(Pattern);
17382 if (Out.isInvalid())
17383 return true;
17384
17385 Result = getDerived().RebuildCXXFoldExpr(
17386 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
17387 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
17388 if (Result.isInvalid())
17389 return true;
17390 }
17391
17392 bool WarnedOnComparison = false;
17393 for (unsigned I = 0; I != *NumExpansions; ++I) {
17394 Sema::ArgPackSubstIndexRAII SubstIndex(
17395 getSema(), LeftFold ? I : *NumExpansions - I - 1);
17396 ExprResult Out = getDerived().TransformExpr(Pattern);
17397 if (Out.isInvalid())
17398 return true;
17399
17400 if (Out.get()->containsUnexpandedParameterPack()) {
17401 // We still have a pack; retain a pack expansion for this slice.
17402 Result = getDerived().RebuildCXXFoldExpr(
17403 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
17404 E->getOperator(), E->getEllipsisLoc(),
17405 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
17406 OrigNumExpansions);
17407 } else if (Result.isUsable()) {
17408 // We've got down to a single element; build a binary operator.
17409 Expr *LHS = LeftFold ? Result.get() : Out.get();
17410 Expr *RHS = LeftFold ? Out.get() : Result.get();
17411 if (Callee) {
17412 UnresolvedSet<16> Functions;
17413 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
17414 Result = getDerived().RebuildCXXOperatorCallExpr(
17415 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
17416 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
17417 Functions, LHS, RHS);
17418 } else {
17419 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
17420 E->getOperator(), LHS, RHS,
17421 /*ForFoldExpresion=*/true);
17422 if (!WarnedOnComparison && Result.isUsable()) {
17423 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
17424 BO && BO->isComparisonOp()) {
17425 WarnedOnComparison = true;
17426 SemaRef.Diag(Loc: BO->getBeginLoc(),
17427 DiagID: diag::warn_comparison_in_fold_expression)
17428 << BO->getOpcodeStr();
17429 }
17430 }
17431 }
17432 } else
17433 Result = Out;
17434
17435 if (Result.isInvalid())
17436 return true;
17437 }
17438
17439 // If we're retaining an expansion for a left fold, it is the outermost
17440 // component and takes the complete expansion so far as its init (if any).
17441 if (LeftFold && RetainExpansion) {
17442 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17443
17444 ExprResult Out = getDerived().TransformExpr(Pattern);
17445 if (Out.isInvalid())
17446 return true;
17447
17448 Result = getDerived().RebuildCXXFoldExpr(
17449 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
17450 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
17451 if (Result.isInvalid())
17452 return true;
17453 }
17454
17455 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
17456 PE->setIsProducedByFoldExpansion();
17457
17458 // If we had no init and an empty pack, and we're not retaining an expansion,
17459 // then produce a fallback value or error.
17460 if (Result.isUnset())
17461 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
17462 E->getOperator());
17463 return Result;
17464}
17465
17466template <typename Derived>
17467ExprResult
17468TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
17469 SmallVector<Expr *, 4> TransformedInits;
17470 ArrayRef<Expr *> InitExprs = E->getInitExprs();
17471
17472 QualType T = getDerived().TransformType(E->getType());
17473
17474 bool ArgChanged = false;
17475
17476 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
17477 TransformedInits, &ArgChanged))
17478 return ExprError();
17479
17480 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
17481 return E;
17482
17483 return getDerived().RebuildCXXParenListInitExpr(
17484 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
17485 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
17486}
17487
17488template<typename Derived>
17489ExprResult
17490TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
17491 CXXStdInitializerListExpr *E) {
17492 return getDerived().TransformExpr(E->getSubExpr());
17493}
17494
17495template<typename Derived>
17496ExprResult
17497TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
17498 return SemaRef.MaybeBindToTemporary(E);
17499}
17500
17501template<typename Derived>
17502ExprResult
17503TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
17504 return E;
17505}
17506
17507template<typename Derived>
17508ExprResult
17509TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
17510 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
17511 if (SubExpr.isInvalid())
17512 return ExprError();
17513
17514 if (!getDerived().AlwaysRebuild() &&
17515 SubExpr.get() == E->getSubExpr())
17516 return E;
17517
17518 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
17519}
17520
17521template<typename Derived>
17522ExprResult
17523TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
17524 // Transform each of the elements.
17525 SmallVector<Expr *, 8> Elements;
17526 bool ArgChanged = false;
17527 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
17528 /*IsCall=*/false, Elements, &ArgChanged))
17529 return ExprError();
17530
17531 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17532 return SemaRef.MaybeBindToTemporary(E);
17533
17534 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
17535 Elements.data(),
17536 Elements.size());
17537}
17538
17539template<typename Derived>
17540ExprResult
17541TreeTransform<Derived>::TransformObjCDictionaryLiteral(
17542 ObjCDictionaryLiteral *E) {
17543 // Transform each of the elements.
17544 SmallVector<ObjCDictionaryElement, 8> Elements;
17545 bool ArgChanged = false;
17546 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
17547 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
17548
17549 if (OrigElement.isPackExpansion()) {
17550 // This key/value element is a pack expansion.
17551 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17552 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
17553 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
17554 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17555
17556 // Determine whether the set of unexpanded parameter packs can
17557 // and should be expanded.
17558 bool Expand = true;
17559 bool RetainExpansion = false;
17560 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
17561 UnsignedOrNone NumExpansions = OrigNumExpansions;
17562 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
17563 OrigElement.Value->getEndLoc());
17564 if (getDerived().TryExpandParameterPacks(
17565 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
17566 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17567 NumExpansions))
17568 return ExprError();
17569
17570 if (!Expand) {
17571 // The transform has determined that we should perform a simple
17572 // transformation on the pack expansion, producing another pack
17573 // expansion.
17574 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17575 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17576 if (Key.isInvalid())
17577 return ExprError();
17578
17579 if (Key.get() != OrigElement.Key)
17580 ArgChanged = true;
17581
17582 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17583 if (Value.isInvalid())
17584 return ExprError();
17585
17586 if (Value.get() != OrigElement.Value)
17587 ArgChanged = true;
17588
17589 ObjCDictionaryElement Expansion = {
17590 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
17591 };
17592 Elements.push_back(Elt: Expansion);
17593 continue;
17594 }
17595
17596 // Record right away that the argument was changed. This needs
17597 // to happen even if the array expands to nothing.
17598 ArgChanged = true;
17599
17600 // The transform has determined that we should perform an elementwise
17601 // expansion of the pattern. Do so.
17602 for (unsigned I = 0; I != *NumExpansions; ++I) {
17603 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17604 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17605 if (Key.isInvalid())
17606 return ExprError();
17607
17608 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17609 if (Value.isInvalid())
17610 return ExprError();
17611
17612 ObjCDictionaryElement Element = {
17613 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17614 };
17615
17616 // If any unexpanded parameter packs remain, we still have a
17617 // pack expansion.
17618 // FIXME: Can this really happen?
17619 if (Key.get()->containsUnexpandedParameterPack() ||
17620 Value.get()->containsUnexpandedParameterPack())
17621 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17622
17623 Elements.push_back(Elt: Element);
17624 }
17625
17626 // FIXME: Retain a pack expansion if RetainExpansion is true.
17627
17628 // We've finished with this pack expansion.
17629 continue;
17630 }
17631
17632 // Transform and check key.
17633 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17634 if (Key.isInvalid())
17635 return ExprError();
17636
17637 if (Key.get() != OrigElement.Key)
17638 ArgChanged = true;
17639
17640 // Transform and check value.
17641 ExprResult Value
17642 = getDerived().TransformExpr(OrigElement.Value);
17643 if (Value.isInvalid())
17644 return ExprError();
17645
17646 if (Value.get() != OrigElement.Value)
17647 ArgChanged = true;
17648
17649 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17650 .NumExpansions: std::nullopt};
17651 Elements.push_back(Elt: Element);
17652 }
17653
17654 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17655 return SemaRef.MaybeBindToTemporary(E);
17656
17657 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17658 Elements);
17659}
17660
17661template<typename Derived>
17662ExprResult
17663TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17664 TypeSourceInfo *EncodedTypeInfo
17665 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17666 if (!EncodedTypeInfo)
17667 return ExprError();
17668
17669 if (!getDerived().AlwaysRebuild() &&
17670 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17671 return E;
17672
17673 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17674 EncodedTypeInfo,
17675 E->getRParenLoc());
17676}
17677
17678template<typename Derived>
17679ExprResult TreeTransform<Derived>::
17680TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17681 // This is a kind of implicit conversion, and it needs to get dropped
17682 // and recomputed for the same general reasons that ImplicitCastExprs
17683 // do, as well a more specific one: this expression is only valid when
17684 // it appears *immediately* as an argument expression.
17685 return getDerived().TransformExpr(E->getSubExpr());
17686}
17687
17688template<typename Derived>
17689ExprResult TreeTransform<Derived>::
17690TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17691 TypeSourceInfo *TSInfo
17692 = getDerived().TransformType(E->getTypeInfoAsWritten());
17693 if (!TSInfo)
17694 return ExprError();
17695
17696 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17697 if (Result.isInvalid())
17698 return ExprError();
17699
17700 if (!getDerived().AlwaysRebuild() &&
17701 TSInfo == E->getTypeInfoAsWritten() &&
17702 Result.get() == E->getSubExpr())
17703 return E;
17704
17705 return SemaRef.ObjC().BuildObjCBridgedCast(
17706 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17707 SubExpr: Result.get());
17708}
17709
17710template <typename Derived>
17711ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17712 ObjCAvailabilityCheckExpr *E) {
17713 return E;
17714}
17715
17716template<typename Derived>
17717ExprResult
17718TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17719 // Transform arguments.
17720 bool ArgChanged = false;
17721 SmallVector<Expr*, 8> Args;
17722 Args.reserve(N: E->getNumArgs());
17723 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17724 &ArgChanged))
17725 return ExprError();
17726
17727 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17728 // Class message: transform the receiver type.
17729 TypeSourceInfo *ReceiverTypeInfo
17730 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17731 if (!ReceiverTypeInfo)
17732 return ExprError();
17733
17734 // If nothing changed, just retain the existing message send.
17735 if (!getDerived().AlwaysRebuild() &&
17736 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17737 return SemaRef.MaybeBindToTemporary(E);
17738
17739 // Build a new class message send.
17740 SmallVector<SourceLocation, 16> SelLocs;
17741 E->getSelectorLocs(SelLocs);
17742 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17743 E->getSelector(),
17744 SelLocs,
17745 E->getMethodDecl(),
17746 E->getLeftLoc(),
17747 Args,
17748 E->getRightLoc());
17749 }
17750 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17751 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17752 if (!E->getMethodDecl())
17753 return ExprError();
17754
17755 // Build a new class message send to 'super'.
17756 SmallVector<SourceLocation, 16> SelLocs;
17757 E->getSelectorLocs(SelLocs);
17758 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17759 E->getSelector(),
17760 SelLocs,
17761 E->getReceiverType(),
17762 E->getMethodDecl(),
17763 E->getLeftLoc(),
17764 Args,
17765 E->getRightLoc());
17766 }
17767
17768 // Instance message: transform the receiver
17769 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17770 "Only class and instance messages may be instantiated");
17771 ExprResult Receiver
17772 = getDerived().TransformExpr(E->getInstanceReceiver());
17773 if (Receiver.isInvalid())
17774 return ExprError();
17775
17776 // If nothing changed, just retain the existing message send.
17777 if (!getDerived().AlwaysRebuild() &&
17778 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17779 return SemaRef.MaybeBindToTemporary(E);
17780
17781 // Build a new instance message send.
17782 SmallVector<SourceLocation, 16> SelLocs;
17783 E->getSelectorLocs(SelLocs);
17784 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17785 E->getSelector(),
17786 SelLocs,
17787 E->getMethodDecl(),
17788 E->getLeftLoc(),
17789 Args,
17790 E->getRightLoc());
17791}
17792
17793template<typename Derived>
17794ExprResult
17795TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17796 return E;
17797}
17798
17799template<typename Derived>
17800ExprResult
17801TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17802 return E;
17803}
17804
17805template<typename Derived>
17806ExprResult
17807TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17808 // Transform the base expression.
17809 ExprResult Base = getDerived().TransformExpr(E->getBase());
17810 if (Base.isInvalid())
17811 return ExprError();
17812
17813 // We don't need to transform the ivar; it will never change.
17814
17815 // If nothing changed, just retain the existing expression.
17816 if (!getDerived().AlwaysRebuild() &&
17817 Base.get() == E->getBase())
17818 return E;
17819
17820 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17821 E->getLocation(),
17822 E->isArrow(), E->isFreeIvar());
17823}
17824
17825template<typename Derived>
17826ExprResult
17827TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17828 // 'super' and types never change. Property never changes. Just
17829 // retain the existing expression.
17830 if (!E->isObjectReceiver())
17831 return E;
17832
17833 // Transform the base expression.
17834 ExprResult Base = getDerived().TransformExpr(E->getBase());
17835 if (Base.isInvalid())
17836 return ExprError();
17837
17838 // We don't need to transform the property; it will never change.
17839
17840 // If nothing changed, just retain the existing expression.
17841 if (!getDerived().AlwaysRebuild() &&
17842 Base.get() == E->getBase())
17843 return E;
17844
17845 if (E->isExplicitProperty())
17846 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17847 E->getExplicitProperty(),
17848 E->getLocation());
17849
17850 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17851 SemaRef.Context.PseudoObjectTy,
17852 E->getImplicitPropertyGetter(),
17853 E->getImplicitPropertySetter(),
17854 E->getLocation());
17855}
17856
17857template<typename Derived>
17858ExprResult
17859TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17860 // Transform the base expression.
17861 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17862 if (Base.isInvalid())
17863 return ExprError();
17864
17865 // Transform the key expression.
17866 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17867 if (Key.isInvalid())
17868 return ExprError();
17869
17870 // If nothing changed, just retain the existing expression.
17871 if (!getDerived().AlwaysRebuild() &&
17872 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17873 return E;
17874
17875 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17876 Base.get(), Key.get(),
17877 E->getAtIndexMethodDecl(),
17878 E->setAtIndexMethodDecl());
17879}
17880
17881template<typename Derived>
17882ExprResult
17883TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17884 // Transform the base expression.
17885 ExprResult Base = getDerived().TransformExpr(E->getBase());
17886 if (Base.isInvalid())
17887 return ExprError();
17888
17889 // If nothing changed, just retain the existing expression.
17890 if (!getDerived().AlwaysRebuild() &&
17891 Base.get() == E->getBase())
17892 return E;
17893
17894 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17895 E->getOpLoc(),
17896 E->isArrow());
17897}
17898
17899template<typename Derived>
17900ExprResult
17901TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17902 bool ArgumentChanged = false;
17903 SmallVector<Expr*, 8> SubExprs;
17904 SubExprs.reserve(N: E->getNumSubExprs());
17905 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17906 SubExprs, &ArgumentChanged))
17907 return ExprError();
17908
17909 if (!getDerived().AlwaysRebuild() &&
17910 !ArgumentChanged)
17911 return E;
17912
17913 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17914 SubExprs,
17915 E->getRParenLoc());
17916}
17917
17918template<typename Derived>
17919ExprResult
17920TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17921 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17922 if (SrcExpr.isInvalid())
17923 return ExprError();
17924
17925 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17926 if (!Type)
17927 return ExprError();
17928
17929 if (!getDerived().AlwaysRebuild() &&
17930 Type == E->getTypeSourceInfo() &&
17931 SrcExpr.get() == E->getSrcExpr())
17932 return E;
17933
17934 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17935 SrcExpr.get(), Type,
17936 E->getRParenLoc());
17937}
17938
17939template<typename Derived>
17940ExprResult
17941TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17942 BlockDecl *oldBlock = E->getBlockDecl();
17943
17944 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17945 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17946
17947 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17948 blockScope->TheDecl->setBlockMissingReturnType(
17949 oldBlock->blockMissingReturnType());
17950
17951 SmallVector<ParmVarDecl*, 4> params;
17952 SmallVector<QualType, 4> paramTypes;
17953
17954 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17955
17956 // Parameter substitution.
17957 Sema::ExtParameterInfoBuilder extParamInfos;
17958 if (getDerived().TransformFunctionTypeParams(
17959 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17960 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17961 extParamInfos)) {
17962 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17963 return ExprError();
17964 }
17965
17966 QualType exprResultType =
17967 getDerived().TransformType(exprFunctionType->getReturnType());
17968
17969 auto epi = exprFunctionType->getExtProtoInfo();
17970 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17971
17972 QualType functionType =
17973 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17974 blockScope->FunctionType = functionType;
17975
17976 // Set the parameters on the block decl.
17977 if (!params.empty())
17978 blockScope->TheDecl->setParams(params);
17979
17980 if (!oldBlock->blockMissingReturnType()) {
17981 blockScope->HasImplicitReturnType = false;
17982 blockScope->ReturnType = exprResultType;
17983 }
17984
17985 // Transform the body
17986 StmtResult body = getDerived().TransformStmt(E->getBody());
17987 if (body.isInvalid()) {
17988 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17989 return ExprError();
17990 }
17991
17992#ifndef NDEBUG
17993 // In builds with assertions, make sure that we captured everything we
17994 // captured before.
17995 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17996 for (const auto &I : oldBlock->captures()) {
17997 VarDecl *oldCapture = I.getVariable();
17998
17999 // Ignore parameter packs.
18000 if (oldCapture->isParameterPack())
18001 continue;
18002
18003 VarDecl *newCapture =
18004 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
18005 oldCapture));
18006 assert(blockScope->CaptureMap.count(newCapture));
18007 }
18008 }
18009#endif
18010
18011 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
18012 /*Scope=*/CurScope: nullptr);
18013}
18014
18015template<typename Derived>
18016ExprResult
18017TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
18018 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
18019 if (SrcExpr.isInvalid())
18020 return ExprError();
18021
18022 QualType Type = getDerived().TransformType(E->getType());
18023
18024 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
18025 RParenLoc: E->getRParenLoc());
18026}
18027
18028template<typename Derived>
18029ExprResult
18030TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
18031 bool ArgumentChanged = false;
18032 SmallVector<Expr*, 8> SubExprs;
18033 SubExprs.reserve(N: E->getNumSubExprs());
18034 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
18035 SubExprs, &ArgumentChanged))
18036 return ExprError();
18037
18038 if (!getDerived().AlwaysRebuild() &&
18039 !ArgumentChanged)
18040 return E;
18041
18042 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
18043 E->getOp(), E->getRParenLoc());
18044}
18045
18046//===----------------------------------------------------------------------===//
18047// Type reconstruction
18048//===----------------------------------------------------------------------===//
18049
18050template<typename Derived>
18051QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
18052 SourceLocation Star) {
18053 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
18054 Entity: getDerived().getBaseEntity());
18055}
18056
18057template<typename Derived>
18058QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
18059 SourceLocation Star) {
18060 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
18061 Entity: getDerived().getBaseEntity());
18062}
18063
18064template<typename Derived>
18065QualType
18066TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
18067 bool WrittenAsLValue,
18068 SourceLocation Sigil) {
18069 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
18070 Loc: Sigil, Entity: getDerived().getBaseEntity());
18071}
18072
18073template <typename Derived>
18074QualType TreeTransform<Derived>::RebuildMemberPointerType(
18075 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
18076 SourceLocation Sigil) {
18077 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
18078 Entity: getDerived().getBaseEntity());
18079}
18080
18081template<typename Derived>
18082QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
18083 const ObjCTypeParamDecl *Decl,
18084 SourceLocation ProtocolLAngleLoc,
18085 ArrayRef<ObjCProtocolDecl *> Protocols,
18086 ArrayRef<SourceLocation> ProtocolLocs,
18087 SourceLocation ProtocolRAngleLoc) {
18088 return SemaRef.ObjC().BuildObjCTypeParamType(
18089 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18090 /*FailOnError=*/FailOnError: true);
18091}
18092
18093template<typename Derived>
18094QualType TreeTransform<Derived>::RebuildObjCObjectType(
18095 QualType BaseType,
18096 SourceLocation Loc,
18097 SourceLocation TypeArgsLAngleLoc,
18098 ArrayRef<TypeSourceInfo *> TypeArgs,
18099 SourceLocation TypeArgsRAngleLoc,
18100 SourceLocation ProtocolLAngleLoc,
18101 ArrayRef<ObjCProtocolDecl *> Protocols,
18102 ArrayRef<SourceLocation> ProtocolLocs,
18103 SourceLocation ProtocolRAngleLoc) {
18104 return SemaRef.ObjC().BuildObjCObjectType(
18105 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
18106 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18107 /*FailOnError=*/FailOnError: true,
18108 /*Rebuilding=*/Rebuilding: true);
18109}
18110
18111template<typename Derived>
18112QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
18113 QualType PointeeType,
18114 SourceLocation Star) {
18115 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
18116}
18117
18118template <typename Derived>
18119QualType TreeTransform<Derived>::RebuildArrayType(
18120 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
18121 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18122 if (SizeExpr || !Size)
18123 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
18124 Quals: IndexTypeQuals, Brackets: BracketsRange,
18125 Entity: getDerived().getBaseEntity());
18126
18127 QualType Types[] = {
18128 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
18129 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
18130 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
18131 };
18132 QualType SizeType;
18133 for (const auto &T : Types)
18134 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
18135 SizeType = T;
18136 break;
18137 }
18138
18139 // Note that we can return a VariableArrayType here in the case where
18140 // the element type was a dependent VariableArrayType.
18141 IntegerLiteral *ArraySize
18142 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
18143 /*FIXME*/l: BracketsRange.getBegin());
18144 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
18145 Quals: IndexTypeQuals, Brackets: BracketsRange,
18146 Entity: getDerived().getBaseEntity());
18147}
18148
18149template <typename Derived>
18150QualType TreeTransform<Derived>::RebuildConstantArrayType(
18151 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
18152 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18153 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
18154 IndexTypeQuals, BracketsRange);
18155}
18156
18157template <typename Derived>
18158QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
18159 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
18160 SourceRange BracketsRange) {
18161 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
18162 IndexTypeQuals, BracketsRange);
18163}
18164
18165template <typename Derived>
18166QualType TreeTransform<Derived>::RebuildVariableArrayType(
18167 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18168 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18169 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18170 SizeExpr,
18171 IndexTypeQuals, BracketsRange);
18172}
18173
18174template <typename Derived>
18175QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
18176 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18177 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18178 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18179 SizeExpr,
18180 IndexTypeQuals, BracketsRange);
18181}
18182
18183template <typename Derived>
18184QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
18185 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
18186 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
18187 AttrLoc: AttributeLoc);
18188}
18189
18190template <typename Derived>
18191QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
18192 unsigned NumElements,
18193 VectorKind VecKind) {
18194 // FIXME: semantic checking!
18195 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
18196}
18197
18198template <typename Derived>
18199QualType TreeTransform<Derived>::RebuildDependentVectorType(
18200 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
18201 VectorKind VecKind) {
18202 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
18203}
18204
18205template<typename Derived>
18206QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
18207 unsigned NumElements,
18208 SourceLocation AttributeLoc) {
18209 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18210 NumElements, true);
18211 IntegerLiteral *VectorSize
18212 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
18213 l: AttributeLoc);
18214 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
18215}
18216
18217template<typename Derived>
18218QualType
18219TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
18220 Expr *SizeExpr,
18221 SourceLocation AttributeLoc) {
18222 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
18223}
18224
18225template <typename Derived>
18226QualType TreeTransform<Derived>::RebuildConstantMatrixType(
18227 QualType ElementType, unsigned NumRows, unsigned NumColumns,
18228 SourceLocation AttributeLoc) {
18229 ASTContext &Ctx = SemaRef.Context;
18230 QualType SizeTy = Ctx.getSizeType();
18231 unsigned SizeWidth = Ctx.getIntWidth(T: SizeTy);
18232 IntegerLiteral *RowExpr = IntegerLiteral::Create(
18233 C: Ctx, V: llvm::APInt(SizeWidth, NumRows), type: SizeTy, l: AttributeLoc);
18234 IntegerLiteral *ColumnExpr = IntegerLiteral::Create(
18235 C: Ctx, V: llvm::APInt(SizeWidth, NumColumns), type: SizeTy, l: AttributeLoc);
18236 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
18237 AttrLoc: AttributeLoc);
18238}
18239
18240template <typename Derived>
18241QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
18242 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
18243 SourceLocation AttributeLoc) {
18244 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
18245 AttrLoc: AttributeLoc);
18246}
18247
18248template <typename Derived>
18249QualType TreeTransform<Derived>::RebuildFunctionProtoType(
18250 QualType T, MutableArrayRef<QualType> ParamTypes,
18251 const FunctionProtoType::ExtProtoInfo &EPI) {
18252 return SemaRef.BuildFunctionType(T, ParamTypes,
18253 Loc: getDerived().getBaseLocation(),
18254 Entity: getDerived().getBaseEntity(),
18255 EPI);
18256}
18257
18258template<typename Derived>
18259QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
18260 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
18261}
18262
18263template <typename Derived>
18264QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
18265 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
18266 SourceLocation NameLoc, Decl *D) {
18267 assert(D && "no decl found");
18268 if (D->isInvalidDecl()) return QualType();
18269
18270 // FIXME: Doesn't account for ObjCInterfaceDecl!
18271 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
18272 // A valid resolved using typename pack expansion decl can have multiple
18273 // UsingDecls, but they must each have exactly one type, and it must be
18274 // the same type in every case. But we must have at least one expansion!
18275 if (UPD->expansions().empty()) {
18276 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
18277 << UPD->isCXXClassMember() << UPD;
18278 return QualType();
18279 }
18280
18281 // We might still have some unresolved types. Try to pick a resolved type
18282 // if we can. The final instantiation will check that the remaining
18283 // unresolved types instantiate to the type we pick.
18284 QualType FallbackT;
18285 QualType T;
18286 for (auto *E : UPD->expansions()) {
18287 QualType ThisT =
18288 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
18289 if (ThisT.isNull())
18290 continue;
18291 if (ThisT->getAs<UnresolvedUsingType>())
18292 FallbackT = ThisT;
18293 else if (T.isNull())
18294 T = ThisT;
18295 else
18296 assert(getSema().Context.hasSameType(ThisT, T) &&
18297 "mismatched resolved types in using pack expansion");
18298 }
18299 return T.isNull() ? FallbackT : T;
18300 }
18301 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
18302 assert(Using->hasTypename() &&
18303 "UnresolvedUsingTypenameDecl transformed to non-typename using");
18304
18305 // A valid resolved using typename decl points to exactly one type decl.
18306 assert(++Using->shadow_begin() == Using->shadow_end());
18307
18308 UsingShadowDecl *Shadow = *Using->shadow_begin();
18309 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
18310 return QualType();
18311 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
18312 }
18313 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
18314 "UnresolvedUsingTypenameDecl transformed to non-using decl");
18315 return SemaRef.Context.getUnresolvedUsingType(
18316 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
18317}
18318
18319template <typename Derived>
18320QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
18321 TypeOfKind Kind) {
18322 return SemaRef.BuildTypeofExprType(E, Kind);
18323}
18324
18325template<typename Derived>
18326QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
18327 TypeOfKind Kind) {
18328 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
18329}
18330
18331template <typename Derived>
18332QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
18333 return SemaRef.BuildDecltypeType(E);
18334}
18335
18336template <typename Derived>
18337QualType TreeTransform<Derived>::RebuildPackIndexingType(
18338 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
18339 bool FullySubstituted, ArrayRef<QualType> Expansions) {
18340 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc,
18341 FullySubstituted, Expansions);
18342}
18343
18344template<typename Derived>
18345QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
18346 UnaryTransformType::UTTKind UKind,
18347 SourceLocation Loc) {
18348 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
18349}
18350
18351template <typename Derived>
18352QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
18353 ElaboratedTypeKeyword Keyword, TemplateName Template,
18354 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
18355 return SemaRef.CheckTemplateIdType(
18356 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
18357 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
18358}
18359
18360template<typename Derived>
18361QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
18362 SourceLocation KWLoc) {
18363 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
18364}
18365
18366template<typename Derived>
18367QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
18368 SourceLocation KWLoc,
18369 bool isReadPipe) {
18370 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
18371 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
18372}
18373
18374template <typename Derived>
18375QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
18376 unsigned NumBits,
18377 SourceLocation Loc) {
18378 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18379 NumBits, true);
18380 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
18381 type: SemaRef.Context.IntTy, l: Loc);
18382 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
18383}
18384
18385template <typename Derived>
18386QualType TreeTransform<Derived>::RebuildDependentBitIntType(
18387 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
18388 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
18389}
18390
18391template <typename Derived>
18392TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18393 bool TemplateKW,
18394 TemplateName Name) {
18395 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
18396 Template: Name);
18397}
18398
18399template <typename Derived>
18400TemplateName TreeTransform<Derived>::RebuildTemplateName(
18401 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
18402 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
18403 UnqualifiedId TemplateName;
18404 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
18405 Sema::TemplateTy Template;
18406 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
18407 TemplateName, ParsedType::make(P: ObjectType),
18408 /*EnteringContext=*/false, Template,
18409 AllowInjectedClassName);
18410 return Template.get();
18411}
18412
18413template<typename Derived>
18414TemplateName
18415TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18416 SourceLocation TemplateKWLoc,
18417 OverloadedOperatorKind Operator,
18418 SourceLocation NameLoc,
18419 QualType ObjectType,
18420 bool AllowInjectedClassName) {
18421 UnqualifiedId Name;
18422 // FIXME: Bogus location information.
18423 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
18424 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
18425 Sema::TemplateTy Template;
18426 getSema().ActOnTemplateName(
18427 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
18428 /*EnteringContext=*/false, Template, AllowInjectedClassName);
18429 return Template.get();
18430}
18431
18432template <typename Derived>
18433ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
18434 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
18435 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
18436 Expr *Second) {
18437 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
18438
18439 if (First->getObjectKind() == OK_ObjCProperty) {
18440 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18441 if (BinaryOperator::isAssignmentOp(Opc))
18442 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
18443 Opcode: Opc, LHS: First, RHS: Second);
18444 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
18445 if (Result.isInvalid())
18446 return ExprError();
18447 First = Result.get();
18448 }
18449
18450 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
18451 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
18452 if (Result.isInvalid())
18453 return ExprError();
18454 Second = Result.get();
18455 }
18456
18457 // Determine whether this should be a builtin operation.
18458 if (Op == OO_Subscript) {
18459 if (!First->getType()->isOverloadableType() &&
18460 !Second->getType()->isOverloadableType())
18461 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
18462 OpLoc);
18463 } else if (Op == OO_Arrow) {
18464 // It is possible that the type refers to a RecoveryExpr created earlier
18465 // in the tree transformation.
18466 if (First->getType()->isDependentType())
18467 return ExprError();
18468 // -> is never a builtin operation.
18469 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
18470 } else if (Second == nullptr || isPostIncDec) {
18471 if (!First->getType()->isOverloadableType() ||
18472 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
18473 // The argument is not of overloadable type, or this is an expression
18474 // of the form &Class::member, so try to create a built-in unary
18475 // operation.
18476 UnaryOperatorKind Opc
18477 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18478
18479 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
18480 }
18481 } else {
18482 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
18483 !First->getType()->isOverloadableType() &&
18484 !Second->getType()->isOverloadableType()) {
18485 // Neither of the arguments is type-dependent or has an overloadable
18486 // type, so try to create a built-in binary operation.
18487 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18488 ExprResult Result
18489 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
18490 if (Result.isInvalid())
18491 return ExprError();
18492
18493 return Result;
18494 }
18495 }
18496
18497 // Create the overloaded operator invocation for unary operators.
18498 if (!Second || isPostIncDec) {
18499 UnaryOperatorKind Opc
18500 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18501 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
18502 RequiresADL);
18503 }
18504
18505 // Create the overloaded operator invocation for binary operators.
18506 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18507 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
18508 LHS: First, RHS: Second, RequiresADL);
18509 if (Result.isInvalid())
18510 return ExprError();
18511
18512 return Result;
18513}
18514
18515template<typename Derived>
18516ExprResult
18517TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
18518 SourceLocation OperatorLoc,
18519 bool isArrow,
18520 CXXScopeSpec &SS,
18521 TypeSourceInfo *ScopeType,
18522 SourceLocation CCLoc,
18523 SourceLocation TildeLoc,
18524 PseudoDestructorTypeStorage Destroyed) {
18525 QualType CanonicalBaseType = Base->getType().getCanonicalType();
18526 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
18527 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
18528 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
18529 !cast<PointerType>(Val&: CanonicalBaseType)
18530 ->getPointeeType()
18531 ->getAsCanonical<RecordType>())) {
18532 // This pseudo-destructor expression is still a pseudo-destructor.
18533 return SemaRef.BuildPseudoDestructorExpr(
18534 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
18535 CCLoc, TildeLoc, DestroyedType: Destroyed);
18536 }
18537
18538 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
18539 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
18540 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
18541 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
18542 NameInfo.setNamedTypeInfo(DestroyedType);
18543
18544 // The scope type is now known to be a valid nested name specifier
18545 // component. Tack it on to the nested name specifier.
18546 if (ScopeType) {
18547 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
18548 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
18549 diag::err_expected_class_or_namespace)
18550 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
18551 return ExprError();
18552 }
18553 SS.clear();
18554 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
18555 }
18556
18557 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
18558 return getSema().BuildMemberReferenceExpr(
18559 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
18560 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
18561 /*TemplateArgs*/ nullptr,
18562 /*S*/ nullptr);
18563}
18564
18565template<typename Derived>
18566StmtResult
18567TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
18568 SourceLocation Loc = S->getBeginLoc();
18569 CapturedDecl *CD = S->getCapturedDecl();
18570 unsigned NumParams = CD->getNumParams();
18571 unsigned ContextParamPos = CD->getContextParamPosition();
18572 SmallVector<Sema::CapturedParamNameType, 4> Params;
18573 for (unsigned I = 0; I < NumParams; ++I) {
18574 if (I != ContextParamPos) {
18575 Params.push_back(
18576 Elt: std::make_pair(
18577 CD->getParam(i: I)->getName(),
18578 getDerived().TransformType(CD->getParam(i: I)->getType())));
18579 } else {
18580 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
18581 }
18582 }
18583 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
18584 S->getCapturedRegionKind(), Params);
18585 StmtResult Body;
18586 {
18587 Sema::CompoundScopeRAII CompoundScope(getSema());
18588 Body = getDerived().TransformStmt(S->getCapturedStmt());
18589 }
18590
18591 if (Body.isInvalid()) {
18592 getSema().ActOnCapturedRegionError();
18593 return StmtError();
18594 }
18595
18596 return getSema().ActOnCapturedRegionEnd(Body.get());
18597}
18598
18599template <typename Derived>
18600StmtResult
18601TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18602 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18603 // function definition or instantiation of a function template specialization
18604 // and will therefore never appear in a dependent context.
18605 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18606 "context");
18607}
18608
18609template <typename Derived>
18610ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18611 // We can transform the base expression and allow argument resolution to fill
18612 // in the rest.
18613 return getDerived().TransformExpr(E->getArgLValue());
18614}
18615
18616} // end namespace clang
18617
18618#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18619